[SCM] blender/upstream: Imported Upstream version 2.65a+svn53743
mfv-guest at users.alioth.debian.org
mfv-guest at users.alioth.debian.org
Sun Jan 13 16:12:51 UTC 2013
The following commit has been merged in the upstream branch:
commit 537d2a5b960ce94af4cf7a687fb4e8f366222829
Author: Matteo F. Vescovi <mfv.debian at gmail.com>
Date: Sat Jan 12 18:10:05 2013 +0100
Imported Upstream version 2.65a+svn53743
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e1c8fe..ecc3f3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -129,6 +129,8 @@ option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effects)" ON)
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
+option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" )
+mark_as_advanced(WITH_SYSTEM_BULLET)
option(WITH_GAMEENGINE "Enable Game Engine" ON)
option(WITH_PLAYER "Build Player" OFF)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
@@ -149,6 +151,9 @@ mark_as_advanced(WITH_HEADLESS)
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
mark_as_advanced(WITH_AUDASPACE)
+option(WITH_BOOL_COMPAT "Continue defining \"TRUE\" and \"FALSE\" until these can be replaced with \"true\" and \"false\" from stdbool.h" ON)
+mark_as_advanced(WITH_BOOL_COMPAT)
+
# (unix defaults to OpenMP On)
if((UNIX AND NOT APPLE) OR (MINGW))
@@ -264,7 +269,6 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
mark_as_advanced(WITH_ASSERT_ABORT)
-
if(APPLE)
cmake_minimum_required(VERSION 2.8.8)
cmake_policy(VERSION 2.8.8)
@@ -423,6 +427,13 @@ endif()
TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
+TEST_STDBOOL_SUPPORT()
+if(HAVE_STDBOOL_H)
+ add_definitions(-DHAVE_STDBOOL_H)
+endif()
+if(WITH_BOOL_COMPAT)
+ add_definitions(-DWITH_BOOL_COMPAT)
+endif()
#-----------------------------------------------------------------------------
# Check for valid directories
@@ -644,20 +655,15 @@ if(UNIX AND NOT APPLE)
if(WITH_BOOST)
# uses in build instructions to override include and library variables
if(NOT BOOST_CUSTOM)
- # XXX No more lib dir, is this multithread stuff still needed?
if(${WITH_STATIC_LIBS})
set(Boost_USE_STATIC_LIBS ON)
endif()
- if(NOT BOOST_ROOT)
- set(Boost_USE_MULTITHREADED OFF)
- else()
- set(Boost_USE_MULTITHREADED ON)
- endif()
+ set(Boost_USE_MULTITHREADED ON)
set(__boost_packages filesystem regex system thread date_time)
if (WITH_INTERNATIONAL)
list(APPEND __boost_packages locale)
endif()
- find_package(Boost 1.34 COMPONENTS ${__boost_packages})
+ find_package(Boost 1.48 COMPONENTS ${__boost_packages})
if(Boost_USE_STATIC_LIBS AND Boost_USE_ICU)
find_package(IcuLinux)
endif()
@@ -1092,14 +1098,16 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
if(MSVC10)
- set(PYTHON_VERSION 3.2) # CACHE STRING)
+ set(PYTHON_VERSION 3.3) # CACHE STRING)
else()
set(PYTHON_VERSION 3.3) # CACHE STRING)
endif()
set_lib_path(PYTHON "python")
STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
- set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH
+ # Use shared libs for vc2008 and vc2010 until we actually have vc2010 libs
+ set(PYTHON_LIBRARY ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.lib)
+ # set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH
unset(_PYTHON_VERSION_NO_DOTS)
#Shared includes for both vc2008 and vc2010
@@ -1521,7 +1529,8 @@ elseif(APPLE)
endif()
if(WITH_INPUT_NDOF)
- set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient")
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework 3DconnexionClient")
+ set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework/Headers )
endif()
endif()
@@ -1837,6 +1846,20 @@ else()
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
endif()
+
+#-----------------------------------------------------------------------------
+# Configure Bullet
+
+if(WITH_BULLET AND WITH_SYSTEM_BULLET)
+ find_package(Bullet)
+ if(NOT BULLET_FOUND)
+ set(WITH_BULLET OFF)
+ endif()
+else()
+ set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src")
+ # set(BULLET_LIBRARIES "")
+endif()
+
#-----------------------------------------------------------------------------
# Configure Python.
@@ -2141,3 +2164,8 @@ if(FIRST_RUN)
message("${_config_msg}")
endif()
+
+# debug
+message(
+ STATUS "HAVE_STDBOOL_H = ${HAVE_STDBOOL_H}"
+)
diff --git a/SConstruct b/SConstruct
index c2bae04..3b1be71 100644
--- a/SConstruct
+++ b/SConstruct
@@ -14,7 +14,7 @@
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
@@ -275,6 +275,11 @@ if 'blenderlite' in B.targets:
if k not in B.arguments:
env[k] = v
+if 'cudakernels' in B.targets:
+ env['WITH_BF_CYCLES'] = True
+ env['WITH_BF_CYCLES_CUDA_BINARIES'] = True
+ env['WITH_BF_PYTHON'] = False
+
# Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX
if env['OURPLATFORM']=='darwin':
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
@@ -294,7 +299,8 @@ if env['OURPLATFORM']=='darwin':
print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors !
env['WITH_BF_3DMOUSE'] = 0
else:
- env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','3DconnexionClient'])
+ env.Append(LINKFLAGS=['-F/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','3DconnexionClient'])
+ env['BF_3DMOUSE_INC'] = '/Library/Frameworks/3DconnexionClient.framework/Headers'
# for now, Mac builders must download and install the JackOSX framework
# necessary header file lives here when installed:
@@ -304,7 +310,7 @@ if env['OURPLATFORM']=='darwin':
print "JackOSX install not found, disabling WITH_BF_JACK" # avoid build errors !
env['WITH_BF_JACK'] = 0
else:
- env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','Jackmp'])
+ env.Append(LINKFLAGS=['-L/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','Jackmp'])
if env['WITH_BF_CYCLES_OSL'] == 1:
OSX_OSL_LIBPATH = Dir(env.subst(env['BF_OSL_LIBPATH'])).abspath
@@ -372,9 +378,10 @@ if btools.ENDIAN == "big":
else:
env['CPPFLAGS'].append('-D__LITTLE_ENDIAN__')
-# TODO, make optional
+# TODO, make optional (as with CMake)
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
env['CPPFLAGS'].append('-DWITH_AVI')
+env['CPPFLAGS'].append('-DWITH_BOOL_COMPAT')
# 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']
@@ -441,11 +448,12 @@ if env['WITH_BF_PYTHON']:
found_pyconfig_h = True
if not (found_python_h and found_pyconfig_h):
- print("\nMissing: Python.h and/or pyconfig.h in\"" + env.subst('${BF_PYTHON_INC}') + "\",\n"
- " Set 'BF_PYTHON_INC' to point "
- "to valid python include path(s).\n Containing "
- "Python.h and pyconfig.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
+ print("""\nMissing: Python.h and/or pyconfig.h in "%s"
+ Set 'BF_PYTHON_INC' to point to valid include path(s),
+ containing Python.h and pyconfig.h for Python version "%s".
+ Example: python scons/scons.py BF_PYTHON_INC=../Python/include
+ """ % (env.subst('${BF_PYTHON_INC}'), env.subst('${BF_PYTHON_VERSION}')))
Exit()
@@ -531,7 +539,8 @@ data_to_c_simple("release/datafiles/bfont.ttf")
data_to_c_simple("release/datafiles/bmonofont.ttf")
data_to_c_simple("release/datafiles/splash.png")
-data_to_c_simple("release/datafiles/blender_icons.png")
+data_to_c_simple("release/datafiles/blender_icons16.png")
+data_to_c_simple("release/datafiles/blender_icons32.png")
data_to_c_simple("release/datafiles/prvicons.png")
data_to_c_simple("release/datafiles/brushicons/add.png")
@@ -647,6 +656,7 @@ datafileslist = []
datafilestargetlist = []
dottargetlist = []
scriptinstall = []
+cubininstall = []
if env['OURPLATFORM']!='darwin':
dotblenderinstall = []
@@ -736,29 +746,30 @@ if env['OURPLATFORM']!='darwin':
source=['intern/cycles/doc/license/'+s for s in source]
scriptinstall.append(env.Install(dir=dir,source=source))
- # cuda binaries
- if env['WITH_BF_CYCLES_CUDA_BINARIES']:
- dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib')
- for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
- kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
- cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
- scriptinstall.append(env.Install(dir=dir,source=cubin_file))
+ if env['WITH_BF_CYCLES']:
+ # cuda binaries
+ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib')
+ for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
+ kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
+ cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
+ cubininstall.append(env.Install(dir=dir,source=cubin_file))
- # osl shaders
- if env['WITH_BF_CYCLES_OSL']:
- dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
+ # osl shaders
+ if env['WITH_BF_CYCLES_OSL']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
- osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
- oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
+ osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
+ oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
- headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
- source=['intern/cycles/kernel/shaders/'+s for s in headers]
- scriptinstall.append(env.Install(dir=dir,source=source))
+ headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
+ source=['intern/cycles/kernel/shaders/'+s for s in headers]
+ scriptinstall.append(env.Install(dir=dir,source=source))
- for f in os.listdir(osl_source_dir):
- if f.endswith('.osl'):
- oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
- scriptinstall.append(env.Install(dir=dir,source=oso_file))
+ for f in os.listdir(osl_source_dir):
+ if f.endswith('.osl'):
+ oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
+ scriptinstall.append(env.Install(dir=dir,source=oso_file))
if env['WITH_BF_OCIO']:
colormanagement = os.path.join('release', 'datafiles', 'colormanagement')
@@ -853,9 +864,9 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
if env['OURPLATFORM']=='darwin':
allinstall = [blenderinstall, textinstall]
elif env['OURPLATFORM']=='linux':
- allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall]
+ allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall, cubininstall]
else:
- allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall]
+ allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, cubininstall]
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources = []
@@ -985,6 +996,20 @@ buildslave_alias = env.Alias('buildslave', buildslave_cmd)
Depends(buildslave_cmd, allinstall)
+cudakernels_action = env.Action(btools.cudakernels, btools.cudakernels_print)
+cudakernels_cmd = env.Command('cudakernels_exec', None, cudakernels_action)
+cudakernels_alias = env.Alias('cudakernels', cudakernels_cmd)
+
+cudakernel_dir = os.path.join(os.path.abspath(os.path.normpath(B.root_build_dir)), 'intern/cycles/kernel')
+cuda_kernels = []
+
+for x in env['BF_CYCLES_CUDA_BINARIES_ARCH']:
+ cubin = os.path.join(cudakernel_dir, 'kernel_' + x + '.cubin')
+ cuda_kernels.append(cubin)
+
+Depends(cudakernels_cmd, cuda_kernels)
+Depends(cudakernels_cmd, cubininstall)
+
Default(B.program_list)
if not env['WITHOUT_BF_INSTALL']:
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 072e999..97bd94f 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -1,16 +1,37 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# ##### 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 LICENSE BLOCK #####
+
+# A shell script installing/building all needed dependencies to build Blender, for some Linux distributions.
# Parse command line!
ARGS=$( \
getopt \
-o s:i:t:h \
---long source:,install:,threads:,help,with-all,with-osl,all-static,force-all,force-python,\
-force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-ffmpeg,\
-skip-python,skip-boost,skip-ocio,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg \
+--long source:,install:,threads:,help,with-all,with-osl,with-opencollada,all-static,force-all,\
+force-python,force-numpy,force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-opencollada,\
+force-ffmpeg,skip-python,skip-numpy,skip-boost,skip-ocio,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg,\
+skip-opencollada \
-- "$@" \
)
DISTRO=""
+RPM=""
SRC="$HOME/src/blender-deps"
INST="/opt/lib"
CWD=$PWD
@@ -21,6 +42,9 @@ WITH_ALL=false
# Do not yet enable osl, use --with-osl (or --with-all) option to try it.
WITH_OSL=false
+# Do not yet enable opencollada, use --with-opencollada (or --with-all) option to try it.
+WITH_OPENCOLLADA=false
+
# Try to link everything statically. Use this to produce portable versions of blender.
ALL_STATIC=false
@@ -37,8 +61,12 @@ or use --source/--install options, if you want to use other paths!
Number of threads for building: \$THREADS (automatically detected, use --threads=<nbr> to override it).
Full install: \$WITH_ALL (use --with-all option to enable it).
Building OSL: \$WITH_OSL (use --with-osl option to enable it).
+Building OpenCOLLADA: \$WITH_OPENCOLLADA (use --with-opencollada option to enable it).
All static linking: \$ALL_STATIC (use --all-static option to enable it).
+Example:
+Full install without OpenCOLLADA: --with-all --skip-opencollada
+
Use --help to show all available options!\""
ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
@@ -64,6 +92,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
Try to install or build the OpenShadingLanguage libraries (and their dependencies).
Still experimental!
+ --with-opencollada
+ Build and install the OpenCOLLADA libraries.
+
--all-static
Build libraries as statically as possible, to create static builds of Blender.
@@ -73,6 +104,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--force-python
Force the rebuild of Python.
+ --force-numpy
+ Force the rebuild of NumPy.
+
--force-boost
Force the rebuild of Boost.
@@ -88,6 +122,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--force-osl
Force the rebuild of OpenShadingLanguage.
+ --force-opencollada
+ Force the rebuild of OpenCOLLADA.
+
--force-ffmpeg
Force the rebuild of FFMpeg.
@@ -101,6 +138,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--skip-python
Unconditionally skip Python installation/building.
+ --skip-numpy
+ Unconditionally skip NumPy installation/building.
+
--skip-boost
Unconditionally skip Boost installation/building.
@@ -116,6 +156,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--skip-osl
Unconditionally skip OpenShadingLanguage installation/building.
+ --skip-opencollada
+ Unconditionally skip OpenCOLLADA installation/building.
+
--skip-ffmpeg
Unconditionally skip FFMpeg installation/building.\""
@@ -125,6 +168,13 @@ PYTHON_SOURCE="http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSI
PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
+#Could not get numpy-1.6.2 to compile with python-3.3
+NUMPY_VERSION="1.7.0rc1"
+NUMPY_VERSION_MIN="1.7"
+NUMPY_SOURCE="http://sourceforge.net/projects/numpy/files/NumPy/$NUMPY_VERSION/numpy-$NUMPY_VERSION.tar.gz"
+NUMPY_FORCE_REBUILD=false
+NUMPY_SKIP=false
+
BOOST_VERSION="1.51.0"
_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'`
BOOST_SOURCE="http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download"
@@ -158,6 +208,12 @@ OSL_SOURCE="https://github.com/mont29/OpenShadingLanguage/archive/blender-fixes.
OSL_FORCE_REBUILD=false
OSL_SKIP=false
+# Version??
+OPENCOLLADA_VERSION="1.3"
+OPENCOLLADA_SOURCE="https://github.com/KhronosGroup/OpenCOLLADA.git"
+OPENCOLLADA_FORCE_REBUILD=false
+OPENCOLLADA_SKIP=false
+
FFMPEG_VERSION="1.0"
FFMPEG_SOURCE="http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2"
FFMPEG_VERSION_MIN="0.7.6"
@@ -236,22 +292,30 @@ while true; do
--with-osl)
WITH_OSL=true; shift; continue
;;
+ --with-opencollada)
+ WITH_OPENCOLLADA=true; shift; continue
+ ;;
--all-static)
ALL_STATIC=true; shift; continue
;;
--force-all)
PYTHON_FORCE_REBUILD=true
+ NUMPY_FORCE_REBUILD=true
BOOST_FORCE_REBUILD=true
OCIO_FORCE_REBUILD=true
OIIO_FORCE_REBUILD=true
LLVM_FORCE_REBUILD=true
OSL_FORCE_REBUILD=true
+ OPENCOLLADA_FORCE_REBUILD=true
FFMPEG_FORCE_REBUILD=true
shift; continue
;;
--force-python)
PYTHON_FORCE_REBUILD=true; shift; continue
;;
+ --force-numpy)
+ NUMPY_FORCE_REBUILD=true; shift; continue
+ ;;
--force-boost)
BOOST_FORCE_REBUILD=true; shift; continue
;;
@@ -267,12 +331,18 @@ while true; do
--force-osl)
OSL_FORCE_REBUILD=true; shift; continue
;;
+ --force-opencollada)
+ OPENCOLLADA_FORCE_REBUILD=true; shift; continue
+ ;;
--force-ffmpeg)
FFMPEG_FORCE_REBUILD=true; shift; continue
;;
--skip-python)
PYTHON_SKIP=true; shift; continue
;;
+ --skip-numpy)
+ NUMPY_SKIP=true; shift; continue
+ ;;
--skip-boost)
BOOST_SKIP=true; shift; continue
;;
@@ -288,6 +358,9 @@ while true; do
--skip-osl)
OSL_SKIP=true; shift; continue
;;
+ --skip-opencollada)
+ OPENCOLLADA_SKIP=true; shift; continue
+ ;;
--skip-ffmpeg)
FFMPEG_SKIP=true; shift; continue
;;
@@ -308,6 +381,7 @@ done
if $WITH_ALL; then
WITH_OSL=true
+ WITH_OPENCOLLADA=true
fi
# Return 0 if $1 = $2 (i.e. 1.01.0 = 1.1, but 1.1.1 != 1.1), else 1.
@@ -397,10 +471,22 @@ version_match() {
detect_distro() {
if [ -f /etc/debian_version ]; then
DISTRO="DEB"
- elif [ -f /etc/redhat-release ]; then
+ elif [ -f /etc/redhat-release -o /etc/SuSE-release ]; then
DISTRO="RPM"
+ elif [ -f /etc/arch-release ]; then
+ DISTRO="ARCH"
+ fi
+}
+
+rpm_flavour() {
+ if [ -f /etc/redhat-release ]; then
+ if [ "`grep '6\.' /etc/redhat-release`" ]; then
+ RPM="RHEL"
+ else
+ RPM="FEDORA"
+ fi
elif [ -f /etc/SuSE-release ]; then
- DISTRO="SUSE"
+ RPM="SUSE"
fi
}
@@ -483,6 +569,56 @@ compile_Python() {
fi
}
+compile_Numpy() {
+ # To be changed each time we make edits that would modify the compiled result!
+ py_magic=0
+
+ _src=$SRC/numpy-$NUMPY_VERSION
+ _inst=$INST/numpy-$NUMPY_VERSION
+ _python=$INST/python-$PYTHON_VERSION
+ _site=lib/python3.3/site-packages
+
+ # Clean install if needed!
+ magic_compile_check numpy-$NUMPY_VERSION $py_magic
+ if [ $? -eq 1 -o $NUMPY_FORCE_REBUILD == true ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building Numpy-$NUMPY_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ mkdir -p $SRC
+ wget -c $NUMPY_SOURCE -O $_src.tar.gz
+
+ INFO "Unpacking Numpy-$NUMPY_VERSION"
+ tar -C $SRC -xf $_src.tar.gz
+ fi
+
+ cd $_src
+
+ $_python/bin/python3 setup.py install --prefix=$_inst
+
+ if [ -d $_inst ]; then
+ rm -f $_python/$_site/numpy
+ ln -s $_inst/$_site/numpy $_python/$_site/numpy
+ else
+ ERROR "Numpy-$NUMPY_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set numpy-$NUMPY_VERSION $py_magic
+
+ cd $CWD
+ INFO "Done compiling Numpy-$NUMPY_VERSION!"
+ else
+ INFO "Own Numpy-$NUMPY_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, use the --force-numpy option."
+ fi
+}
+
compile_Boost() {
# To be changed each time we make edits that would modify the compiled result!
boost_magic=7
@@ -620,7 +756,7 @@ compile_OCIO() {
compile_OIIO() {
# To be changed each time we make edits that would modify the compiled result!
- oiio_magic=6
+ oiio_magic=7
_src=$SRC/OpenImageIO-$OIIO_VERSION
_inst=$INST/oiio-$OIIO_VERSION
@@ -797,6 +933,7 @@ EOF
cmake_d="-D CMAKE_BUILD_TYPE=Release"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D LLVM_ENABLE_FFI=ON"
+ cmake_d="$cmake_d -D LLVM_TARGETS_TO_BUILD=X86"
if [ -d $_FFI_INCLUDE_DIR ]; then
cmake_d="$cmake_d -D FFI_INCLUDE_DIR=$_FFI_INCLUDE_DIR"
@@ -876,6 +1013,7 @@ compile_OSL() {
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILDSTATIC=ON"
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
+ cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
if [ -d $INST/boost ]; then
cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON"
@@ -919,6 +1057,70 @@ compile_OSL() {
fi
}
+compile_OpenCOLLADA() {
+ # To be changed each time we make edits that would modify the compiled results!
+ opencollada_magic=5
+
+ _src=$SRC/OpenCOLLADA-$OPENCOLLADA_VERSION
+ _inst=$INST/opencollada-$OPENCOLLADA_VERSION
+
+ # Clean install if needed!
+ magic_compile_check opencollada-$OPENCOLLADA_VERSION $opencollada_magic
+ if [ $? -eq 1 -o $OPENCOLLADA_FORCE_REBUILD == true ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building OpenCOLLADA-$OPENCOLLADA_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ mkdir -p $SRC
+ git clone $OPENCOLLADA_SOURCE $_src
+ fi
+
+ cd $_src
+
+ # XXX For now, always update from latest repo...
+ git pull origin
+
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ cmake_d="-D CMAKE_BUILD_TYPE=Release"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
+ cmake_d="$cmake_d -D USE_EXPAT=OFF"
+ cmake_d="$cmake_d -D USE_LIBXML=ON"
+ cmake_d="$cmake_d -D USE_STATIC=ON"
+
+ cmake $cmake_d ../
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/opencollada
+ ln -s opencollada-$OPENCOLLADA_VERSION $INST/opencollada
+ else
+ ERROR "OpenCOLLADA-$OPENCOLLADA_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set opencollada-$OPENCOLLADA_VERSION $opencollada_magic
+
+ cd $CWD
+ INFO "Done compiling OpenCOLLADA-$OPENCOLLADA_VERSION!"
+ else
+ INFO "Own OpenCOLLADA-$OPENCOLLADA_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, use the --force-opencollada option."
+ fi
+}
+
compile_FFmpeg() {
# To be changed each time we make edits that would modify the compiled result!
ffmpeg_magic=3
@@ -991,9 +1193,9 @@ compile_FFmpeg() {
--enable-avfilter --disable-vdpau \
--disable-bzlib --disable-libgsm --disable-libspeex \
--enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
- --disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
- --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
- --disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
+ --disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
+ --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
+ --disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
--disable-outdev=alsa --disable-indev=sdl --disable-indev=alsa --disable-indev=jack \
--disable-indev=lavfi $extra
@@ -1018,6 +1220,8 @@ compile_FFmpeg() {
fi
}
+
+
get_package_version_DEB() {
dpkg-query -W -f '${Version}' $1 | sed -r 's/.*:\s*([0-9]+:)(([0-9]+\.?)+).*/\2/'
}
@@ -1055,7 +1259,7 @@ check_package_version_ge_DEB() {
}
install_packages_DEB() {
- sudo apt-get install -y $@
+ sudo apt-get install -y --force-yes $@
if [ $? -ge 1 ]; then
ERROR "apt-get failed to install requested packages, exiting."
exit 1
@@ -1069,6 +1273,9 @@ install_DEB() {
INFO "`eval _echo "$COMMON_INFO"`"
INFO ""
+ read -p "Do you want to continue (Y/n)?"
+ [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" != "y" ] && exit
+
if [ ! -z "`cat /etc/debian_version | grep ^6`" ]; then
if [ -z "`cat /etc/apt/sources.list | grep backports.debian.org`" ]; then
INFO "Looks like you're using Debian Squeeze which does have broken CMake"
@@ -1094,27 +1301,37 @@ install_DEB() {
fi
sudo apt-get update
-# XXX Why in hell? Let's let this stuff to the user's responsability!!!
-# sudo apt-get -y upgrade
# These libs should always be available in debian/ubuntu official repository...
OPENJPEG_DEV="libopenjpeg-dev"
- SCHRO_DEV="libschroedinger-dev"
VORBIS_DEV="libvorbis-dev"
THEORA_DEV="libtheora-dev"
- _packages="gawk cmake scons build-essential libjpeg-dev libpng-dev libtiff-dev \
+ _packages="gawk cmake cmake-curses-gui scons build-essential libjpeg-dev libpng-dev \
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev \
libncurses5-dev libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV \
- libopenexr-dev libopenal-dev libglew-dev yasm $THEORA_DEV \
- $VORBIS_DEV libsdl1.2-dev libfftw3-dev python-dev patch bzip2"
+ libopenexr-dev libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV \
+ libsdl1.2-dev libfftw3-dev patch bzip2"
+
OPENJPEG_USE=true
VORBIS_USE=true
THEORA_USE=true
+ # Install newest libtiff-dev in debian/ubuntu.
+ TIFF="libtiff5"
+ check_package_DEB $TIFF
+ if [ $? -eq 0 ]; then
+ _packages="$_packages $TIFF-dev"
+ else
+ TIFF="libtiff"
+ check_package_DEB $TIFF
+ if [ $? -eq 0 ]; then
+ _packages="$_packages $TIFF-dev"
+ fi
+ fi
+
if $WITH_ALL; then
- _packages="$_packages $SCHRO_DEV libjack0 libjack-dev"
- SCHRO_USE=true
+ _packages="$_packages libspnav-dev libjack-dev"
fi
INFO ""
@@ -1131,6 +1348,7 @@ install_DEB() {
if $WITH_ALL; then
INFO ""
# Grmpf, debian is libxvidcore-dev and ubuntu libxvidcore4-dev!
+ # Note: not since ubuntu 10.04
XVID_DEV="libxvidcore-dev"
check_package_DEB $XVID_DEV
if [ $? -eq 0 ]; then
@@ -1162,9 +1380,11 @@ install_DEB() {
fi
INFO ""
- check_package_DEB libspnav-dev
+ SCHRO_DEV="libschroedinger-dev"
+ check_package_DEB $SCHRO_DEV
if [ $? -eq 0 ]; then
- install_packages_DEB libspnav-dev
+ install_packages_DEB $SCHRO_DEV
+ SCHRO_USE=true
fi
fi
@@ -1172,11 +1392,28 @@ install_DEB() {
if $PYTHON_SKIP; then
INFO "WARNING! Skipping Python installation, as requested..."
else
- check_package_DEB python3.3-dev
+ check_package_DEB python$PYTHON_VERSION_MIN-dev
if [ $? -eq 0 ]; then
- install_packages_DEB python3.3-dev
+ install_packages_DEB python$PYTHON_VERSION_MIN-dev
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ check_package_DEB python$PYTHON_VERSION_MIN-numpy
+ if [ $? -eq 0 ]; then
+ install_packages_DEB python$PYTHON_VERSION_MIN-numpy
+ else
+ INFO "WARNING! Sorry, using python package but no numpy package available!"
+ fi
+ fi
else
compile_Python
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ compile_Numpy
+ fi
fi
fi
@@ -1236,17 +1473,19 @@ install_DEB() {
INFO ""
check_package_DEB llvm-$LLVM_VERSION-dev
if [ $? -eq 0 ]; then
- install_packages_DEB llvm-$LLVM_VERSION-dev
+ install_packages_DEB llvm-$LLVM_VERSION-dev clang
have_llvm=true
LLVM_VERSION_FOUND=$LLVM_VERSION
else
check_package_DEB llvm-$LLVM_VERSION_MIN-dev
if [ $? -eq 0 ]; then
- install_packages_DEB llvm-$LLVM_VERSION_MIN-dev
+ install_packages_DEB llvm-$LLVM_VERSION_MIN-dev clang
have_llvm=true
LLVM_VERSION_FOUND=$LLVM_VERSION_MIN
else
install_packages_DEB libffi-dev
+ # LLVM can't find the debian ffi header dir
+ _FFI_INCLUDE_DIR=`dpkg -L libffi-dev | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'`
INFO ""
compile_LLVM
have_llvm=true
@@ -1256,12 +1495,11 @@ install_DEB() {
fi
if $OSL_SKIP; then
- INFO ""
INFO "WARNING! Skipping OpenShadingLanguage installation, as requested..."
else
if $have_llvm; then
INFO ""
- install_packages_DEB clang flex bison libtbb-dev git
+ install_packages_DEB flex bison libtbb-dev git
# No package currently!
INFO ""
compile_OSL
@@ -1269,6 +1507,19 @@ install_DEB() {
fi
fi
+ if $WITH_OPENCOLLADA; then
+ if $OPENCOLLADA_SKIP; then
+ INFO "WARNING! Skipping OpenCOLLADA installation, as requested..."
+ else
+ INFO ""
+ install_packages_DEB git libpcre3-dev libxml2-dev
+ # Find path to libxml shared lib...
+ _XML2_LIB=`dpkg -L libxml2-dev | grep -e ".*/libxml2.so"`
+ # No package
+ INFO ""
+ compile_OpenCOLLADA
+ fi
+ fi
INFO ""
if $FFMPEG_SKIP; then
@@ -1293,12 +1544,24 @@ install_DEB() {
fi
}
+
+
get_package_version_RPM() {
- yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+ rpm_flavour
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+ elif [ $RPM = "SUSE" ]; then
+ zypper info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+ fi
}
check_package_RPM() {
- r=`yum info $1 | grep -c 'Summary'`
+ rpm_flavour
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ r=`yum info $1 | grep -c 'Summary'`
+ elif [ $RPM = "SUSE" ]; then
+ r=`zypper info $1 | grep -c 'Summary'`
+ fi
if [ $r -ge 1 ]; then
return 0
@@ -1330,10 +1593,20 @@ check_package_version_ge_RPM() {
}
install_packages_RPM() {
- sudo yum install -y $@
- if [ $? -ge 1 ]; then
- ERROR "yum failed to install requested packages, exiting."
- exit 1
+ rpm_flavour
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ sudo yum install -y $@
+ if [ $? -ge 1 ]; then
+ ERROR "yum failed to install requested packages, exiting."
+ exit 1
+ fi
+
+ elif [ $RPM = "SUSE" ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses $@
+ if [ $? -ge 1 ]; then
+ ERROR "zypper failed to install requested packages, exiting."
+ exit 1
+ fi
fi
}
@@ -1344,48 +1617,138 @@ install_RPM() {
INFO "`eval _echo "$COMMON_INFO"`"
INFO ""
- sudo yum -y update
+ read -p "Do you want to continue (Y/n)?"
+ [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" != "y" ] && exit
- # These libs should always be available in debian/ubuntu official repository...
+ # Enable non-free repositories for all flavours
+ rpm_flavour
+ if [ $RPM = "FEDORA" ]; then
+ sudo yum -y localinstall --nogpgcheck \
+ http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm \
+ http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm
+
+ sudo yum -y update
+
+ # Install cmake now because of difference with RHEL
+ sudo yum -y install cmake
+
+ elif [ $RPM = "RHEL" ]; then
+ sudo yum -y localinstall --nogpgcheck \
+ http://download.fedoraproject.org/pub/epel/6/$(uname -i)/epel-release-6-8.noarch.rpm \
+ http://download1.rpmfusion.org/free/el/updates/6/$(uname -i)/rpmfusion-free-release-6-1.noarch.rpm \
+ http://download1.rpmfusion.org/nonfree/el/updates/6/$(uname -i)/rpmfusion-nonfree-release-6-1.noarch.rpm
+
+ sudo yum -y update
+
+ # Install cmake 2.8 from other repo
+ mkdir -p $SRC
+ if [ -f $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm ]; then
+ INFO ""
+ INFO "Special cmake already installed"
+ else
+ curl -O ftp://ftp.pbone.net/mirror/atrpms.net/el6-$(uname -i)/atrpms/testing/cmake-2.8.8-4.el6.$(uname -m).rpm
+ mv cmake-2.8.8-4.el6.$(uname -m).rpm $SRC/
+ sudo rpm -ihv $SRC/cmake-2.8.8-4.el6.$(uname -m).rpm
+ fi
+
+ elif [ $RPM = "SUSE" ]; then
+ _suse_rel="`grep VERSION /etc/SuSE-release | gawk '{print $3}'`"
+ sudo zypper ar -f http://packman.inode.at/suse/openSUSE_$_suse_rel/ packman
+
+ sudo zypper --non-interactive --gpg-auto-import-keys update --auto-agree-with-licenses
+ fi
+
+ # These libs should always be available in fedora/suse official repository...
OPENJPEG_DEV="openjpeg-devel"
- SCHRO_DEV="schroedinger-devel"
VORBIS_DEV="libvorbis-devel"
THEORA_DEV="libtheora-devel"
- _packages="gawk gcc gcc-c++ cmake scons libpng-devel libtiff-devel freetype-devel \
- libX11-devel libXi-devel wget libsqlite3x-devel ncurses-devel \
- readline-devel $OPENJPEG_DEV openexr-devel openal-soft-devel \
+ _packages="gcc gcc-c++ make scons libpng-devel libtiff-devel \
+ freetype-devel libX11-devel libXi-devel wget ncurses-devel \
+ readline-devel $OPENJPEG_DEV openal-soft-devel \
glew-devel yasm $THEORA_DEV $VORBIS_DEV SDL-devel fftw-devel \
- lame-libs libjpeg-devel patch python-devel"
+ libjpeg-devel patch"
+
OPENJPEG_USE=true
VORBIS_USE=true
THEORA_USE=true
- if $WITH_ALL; then
- _packages="$_packages $SCHRO_DEV jack-audio-connection-kit-devel libspnav-devel"
- SCHRO_USE=true
- fi
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
- INFO ""
- install_packages_RPM $_packages
+ _packages="$_packages libsqlite3-devel openexr-devel"
- INFO ""
- X264_DEV="x264-devel"
- check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
- if [ $? -eq 0 ]; then
- install_packages_RPM $X264_DEV
- X264_USE=true
- fi
+ if $WITH_ALL; then
+ _packages="$_packages jack-audio-connection-kit-devel libspnav-devel"
+ fi
- if $WITH_ALL; then
INFO ""
- XVID_DEV="xvidcore-devel"
- check_package_RPM $XVID_DEV
+ install_packages_RPM $_packages
+
+ INFO ""
+ X264_DEV="x264-devel"
+ check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
if [ $? -eq 0 ]; then
- install_packages_RPM $XVID_DEV
- XVID_USE=true
+ install_packages_RPM $X264_DEV
+ X264_USE=true
+ fi
+
+ if $WITH_ALL; then
+ INFO ""
+ XVID_DEV="xvidcore-devel"
+ check_package_RPM $XVID_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $XVID_DEV
+ XVID_USE=true
+ fi
+
+ INFO ""
+ MP3LAME_DEV="lame-devel"
+ check_package_RPM $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
+ fi
+
+ elif [ $RPM = "SUSE" ]; then
+
+ _packages="$_packages cmake sqlite3-devel libopenexr-devel"
+
+ if $WITH_ALL; then
+ _packages="$_packages libjack-devel libspnav-devel"
+ fi
+
+ INFO ""
+ install_packages_RPM $_packages
+
+ INFO ""
+ X264_DEV="libx264-devel"
+ check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $X264_DEV
+ X264_USE=true
+ fi
+
+ if $WITH_ALL; then
+ INFO ""
+ XVID_DEV="libxvidcore-devel"
+ check_package_RPM $XVID_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $XVID_DEV
+ XVID_USE=true
+ fi
+
+ INFO ""
+ MP3LAME_DEV="libmp3lame-devel"
+ check_package_RPM $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ install_packages_RPM $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
fi
+ fi
+ if $WITH_ALL; then
INFO ""
VPX_DEV="libvpx-devel"
check_package_version_ge_RPM $VPX_DEV $VPX_VERSION_MIN
@@ -1395,14 +1758,14 @@ install_RPM() {
fi
INFO ""
- MP3LAME_DEV="lame-devel"
- check_package_RPM $MP3LAME_DEV
+ SCHRO_DEV="schroedinger-devel"
+ check_package_RPM $SCHRO_DEV
if [ $? -eq 0 ]; then
- install_packages_RPM $MP3LAME_DEV
- MP3LAME_USE=true
+ install_packages_RPM $SCHRO_DEV
+ SCHRO_USE=true
fi
fi
-
+
INFO ""
if $PYTHON_SKIP; then
INFO "WARNING! Skipping Python installation, as requested..."
@@ -1410,8 +1773,25 @@ install_RPM() {
check_package_version_match_RPM python3-devel $PYTHON_VERSION_MIN
if [ $? -eq 0 ]; then
install_packages_RPM python3-devel
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ check_package_version_match_RPM python3-numpy $NUMPY_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ install_packages_RPM python3-numpy
+ else
+ INFO "WARNING! Sorry, using python package but no numpy package available!"
+ fi
+ fi
else
compile_Python
+ INFO ""
+ if $NUMPY_SKIP; then
+ INFO "WARNING! Skipping NumPy installation, as requested..."
+ else
+ compile_Numpy
+ fi
fi
fi
@@ -1419,7 +1799,7 @@ install_RPM() {
if $BOOST_SKIP; then
INFO "WARNING! Skipping Boost installation, as requested..."
else
- check_package_version_ge_RPM boost-devel $BOOST_VERSION_MIN
+ check_package_version_ge_RPM boost-devel $BOOST_VERSION
if [ $? -eq 0 ]; then
install_packages_RPM boost-devel
else
@@ -1460,25 +1840,15 @@ install_RPM() {
else
check_package_RPM llvm-$LLVM_VERSION-devel
if [ $? -eq 0 ]; then
- install_packages_RPM llvm-$LLVM_VERSION-devel
+ install_packages_RPM llvm-$LLVM_VERSION-devel clang
have_llvm=true
LLVM_VERSION_FOUND=$LLVM_VERSION
else
-# check_package_RPM llvm-$LLVM_VERSION_MIN-devel
-# if [ $? -eq 0 ]; then
-# install_packages_RPM llvm-$LLVM_VERSION_MIN-devel
-# have_llvm=true
-# LLVM_VERSION_FOUND=$LLVM_VERSION_MIN
-# else
-# check_package_version_ge_RPM llvm-devel $LLVM_VERSION_MIN
-# if [ $? -eq 0 ]; then
-# install_packages_RPM llvm-devel
-# have_llvm=true
-# LLVM_VERSION_FOUND=`get_package_version_RPM llvm-devel`
-# fi
-# fi
+ #
+ # Better to compile it than use minimum version from repo...
+ #
install_packages_RPM libffi-devel
- # XXX Stupid fedora puts ffi header into a darn stupid dir!
+ # LLVM can't find the fedora ffi header dir...
_FFI_INCLUDE_DIR=`rpm -ql libffi-devel | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'`
INFO ""
compile_LLVM
@@ -1492,211 +1862,29 @@ install_RPM() {
INFO "WARNING! Skipping OpenShadingLanguage installation, as requested..."
else
if $have_llvm; then
- INFO ""
- install_packages_RPM flex bison clang tbb-devel git
# No package currently!
INFO ""
+ install_packages_RPM flex bison git
+ if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
+ install_packages_RPM tbb-devel
+ fi
+ INFO ""
compile_OSL
fi
fi
fi
- INFO ""
- if $FFMPEG_SKIP; then
- INFO "WARNING! Skipping FFMpeg installation, as requested..."
- else
- # Always for now, not sure which packages should be installed
- compile_FFmpeg
- fi
-}
-
-get_package_version_SUSE() {
- zypper info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
-}
-
-check_package_SUSE() {
- r=`zypper info $1 | grep -c 'Summary'`
-
- if [ $r -ge 1 ]; then
- return 0
- else
- return 1
- fi
-}
-
-check_package_version_match_SUSE() {
- v=`get_package_version_SUSE $1`
-
- if [ -z "$v" ]; then
- return 1
- fi
-
- version_match $v $2
- return $?
-}
-
-check_package_version_ge_SUSE() {
- v=`get_package_version_SUSE $1`
-
- if [ -z "$v" ]; then
- return 1
- fi
-
- version_ge $v $2
- return $?
-}
-
-install_packages_SUSE() {
- sudo zypper --non-interactive install --auto-agree-with-licenses $@
- if [ $? -ge 1 ]; then
- ERROR "zypper failed to install requested packages, exiting."
- exit 1
- fi
-}
-
-
-install_SUSE() {
- INFO ""
- INFO "Installing dependencies for SuSE-based distribution"
- INFO ""
- INFO "`eval _echo "$COMMON_INFO"`"
- INFO ""
-
- sudo zypper --non-interactive update --auto-agree-with-licenses
-
- # These libs should always be available in debian/ubuntu official repository...
- OPENJPEG_DEV="openjpeg-devel"
- SCHRO_DEV="schroedinger-devel"
- VORBIS_DEV="libvorbis-devel"
- THEORA_DEV="libtheora-devel"
-
- _packages="gawk gcc gcc-c++ cmake scons libpng12-devel libtiff-devel freetype-devel \
- libX11-devel libXi-devel wget sqlite3-devel ncurses-devel \
- readline-devel $OPENJPEG_DEV libopenexr-devel openal-soft-devel \
- glew-devel yasm $THEORA_DEV $VORBIS_DEV libSDL-devel fftw3-devel \
- libjpeg62-devel patch python-devel"
- OPENJPEG_USE=true
- VORBIS_USE=true
- THEORA_USE=true
-
- if $WITH_ALL; then
- _packages="$_packages $SCHRO_DEV libjack-devel libspnav-devel"
- SCHRO_USE=true
- fi
-
- INFO ""
- install_packages_SUSE $_packages
-
- OPENJPEG_USE=true
- SCHRO_USE=true
- VORBIS_USE=true
- THEORA_USE=true
-
- INFO ""
- X264_DEV="x264-devel"
- check_package_version_ge_SUSE $X264_DEV $X264_VERSION_MIN
- if [ $? -eq 0 ]; then
- install_packages_SUSE $X264_DEV
- X264_USE=true
- fi
-
- if $WITH_ALL; then
- INFO ""
- XVID_DEV="xvidcore-devel"
- check_package_SUSE $XVID_DEV
- if [ $? -eq 0 ]; then
- install_packages_SUSE $XVID_DEV
- XVID_USE=true
- fi
-
- INFO ""
- VPX_DEV="libvpx-devel"
- check_package_version_ge_SUSE $VPX_DEV $VPX_VERSION_MIN
- if [ $? -eq 0 ]; then
- install_packages_SUSE $VPX_DEV
- VPX_USE=true
- fi
-
- INFO ""
- # No mp3 in suse, it seems.
- MP3LAME_DEV="lame-devel"
- check_package_SUSE $MP3LAME_DEV
- if [ $? -eq 0 ]; then
- install_packages_SUSE $MP3LAME_DEV
- MP3LAME_USE=true
- fi
- fi
-
- INFO ""
- if $PYTHON_SKIP; then
- INFO "WARNING! Skipping Python installation, as requested..."
- else
- check_package_version_match_SUSE python3-devel 3.3.
- if [ $? -eq 0 ]; then
- install_packages_SUSE python3-devel
- else
- compile_Python
- fi
- fi
-
- INFO ""
- if $BOOST_SKIP; then
- INFO "WARNING! Skipping Boost installation, as requested..."
- else
- # No boost_locale currently available, so let's build own boost.
- compile_Boost
- fi
-
- INFO ""
- if $OCIO_SKIP; then
- INFO "WARNING! Skipping OpenColorIO installation, as requested..."
- else
- # No ocio currently available, so let's build own boost.
- compile_OCIO
- fi
-
- INFO ""
- if $OIIO_SKIP; then
- INFO "WARNING! Skipping OpenImageIO installation, as requested..."
- else
- # No oiio currently available, so let's build own boost.
- compile_OIIO
- fi
-
- if $WITH_OSL; then
- have_llvm=false
-
- INFO ""
- if $LLVM_SKIP; then
- INFO "WARNING! Skipping LLVM installation, as requested (this also implies skipping OSL!)..."
+ if $WITH_OPENCOLLADA; then
+ if $OPENCOLLADA_SKIP; then
+ INFO "WARNING! Skipping OpenCOLLADA installation, as requested..."
else
- # Suse llvm package *_$SUCKS$_* (tm) !!!
-# check_package_version_ge_SUSE llvm-devel $LLVM_VERSION_MIN
-# if [ $? -eq 0 ]; then
-# install_packages_SUSE llvm-devel
-# have_llvm=true
-# LLVM_VERSION_FOUND=`get_package_version_SUSE llvm-devel`
-# fi
-
- install_packages_SUSE libffi47-devel
INFO ""
- compile_LLVM
- have_llvm=true
- LLVM_VERSION_FOUND=$LLVM_VERSION
- fi
-
- if $OSL_SKIP; then
+ install_packages_RPM pcre-devel libxml2-devel git
+ # Find path to libxml shared lib...
+ _XML2_LIB=`rpm -ql libxml2-devel | grep -e ".*/libxml2.so"`
+ # No package...
INFO ""
- INFO "WARNING! Skipping OpenShaderLanguage installation, as requested..."
- else
- if $have_llvm; then
- INFO ""
- # XXX No tbb lib!
- install_packages_SUSE flex bison git
- # No package currently!
- INFO ""
- compile_OSL
- fi
+ compile_OpenCOLLADA
fi
fi
@@ -1704,11 +1892,13 @@ install_SUSE() {
if $FFMPEG_SKIP; then
INFO "WARNING! Skipping FFMpeg installation, as requested..."
else
- # No ffmpeg currently available, so let's build own boost.
+ # Always for now, not sure which packages should be installed
compile_FFmpeg
fi
}
+
+
print_info_ffmpeglink_DEB() {
if $ALL_STATIC; then
dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
@@ -1718,19 +1908,12 @@ print_info_ffmpeglink_DEB() {
}
print_info_ffmpeglink_RPM() {
- if $ALL_STATIC; then
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
- else
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
- fi
-}
-
-print_info_ffmpeglink_SUSE() {
- if $ALL_STATIC; then
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
- else
- rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
- fi
+# # XXX No static libs...
+# if $ALL_STATIC; then
+# rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
+# else
+ rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
+# fi
}
print_info_ffmpeglink() {
@@ -1771,8 +1954,7 @@ print_info_ffmpeglink() {
_packages="$_packages $OPENJPEG_DEV"
fi
- # XXX At least under Debian, static schro gives problem at blender linking time... :/
- if $SCHRO_USE && ! $ALL_STATIC; then
+ if $SCHRO_USE; then
_packages="$_packages $SCHRO_DEV"
fi
@@ -1780,8 +1962,8 @@ print_info_ffmpeglink() {
print_info_ffmpeglink_DEB
elif [ "$DISTRO" = "RPM" ]; then
print_info_ffmpeglink_RPM
- elif [ "$DISTRO" = "SUSE" ]; then
- print_info_ffmpeglink_SUSE
+# elif [ "$DISTRO" = "ARCH" ]; then
+# print_info_ffmpeglink_ARCH
# XXX TODO!
else INFO "<Could not determine additional link libraries needed for ffmpeg, replace this by valid list of libs...>"
fi
@@ -1791,38 +1973,76 @@ print_info() {
INFO ""
INFO "If you're using CMake add this to your configuration flags:"
+ _buildargs=""
+
if $ALL_STATIC; then
- INFO " -D WITH_STATIC_LIBS=ON"
+ _1="-D WITH_STATIC_LIBS=ON"
+ # XXX Force linking with shared SDL lib!
+ _2="-D SDL_LIBRARY='libSDL.so;-lpthread'"
+ INFO " $_1"
+ INFO " $_2"
+ _buildargs="$_buildargs $_1 $_2"
fi
if [ -d $INST/boost ]; then
- INFO " -D BOOST_ROOT=$INST/boost"
- INFO " -D Boost_NO_SYSTEM_PATHS=ON"
+ _1="-D BOOST_ROOT=$INST/boost"
+ _2="-D Boost_NO_SYSTEM_PATHS=ON"
+ INFO " $_1"
+ INFO " $_2"
+ _buildargs="$_buildargs $_1 $_2"
elif $ALL_STATIC; then
- INFO " -D Boost_USE_ICU=ON"
+ _1="-D Boost_USE_ICU=ON"
+ INFO " $_1"
+ _buildargs="$_buildargs $_1"
fi
if [ -d $INST/osl -a $WITH_OSL == true ]; then
- INFO " -D CYCLES_OSL=$INST/osl"
- INFO " -D WITH_CYCLES_OSL=ON"
- INFO " -D LLVM_VERSION=$LLVM_VERSION_FOUND"
+ _1="-D CYCLES_OSL=$INST/osl"
+ _2="-D WITH_CYCLES_OSL=ON"
+ _3="-D LLVM_VERSION=$LLVM_VERSION_FOUND"
+ INFO " $_1"
+ INFO " $_2"
+ INFO " $_3"
+ _buildargs="$_buildargs $_1 $_2 $_3"
if [ -d $INST/llvm ]; then
- INFO " -D LLVM_DIRECTORY=$INST/llvm"
- INFO " -D LLVM_STATIC=ON"
+ _1="-D LLVM_DIRECTORY=$INST/llvm"
+ _2="-D LLVM_STATIC=ON"
+ INFO " $_1"
+ INFO " $_2"
+ _buildargs="$_buildargs $_1 $_2"
+ fi
+ fi
+
+ if [ -d $INST/opencollada -a $WITH_OPENCOLLADA == true ]; then
+ _1="-D WITH_OPENCOLLADA=ON"
+ INFO " $_1"
+ _buildargs="$_buildargs $_1"
+ if $ALL_STATIC; then
+ _1="-D XML2_LIBRARY=$_XML2_LIB"
+ INFO " $_1"
+ _buildargs="$_buildargs $_1"
fi
fi
if [ -d $INST/ffmpeg ]; then
- INFO " -D WITH_CODEC_FFMPEG=ON"
- INFO " -D FFMPEG=$INST/ffmpeg"
- INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
+ _1="-D WITH_CODEC_FFMPEG=ON"
+ _2="-D FFMPEG=$INST/ffmpeg"
+ _3="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
+ INFO " $_1"
+ INFO " $_2"
+ INFO " $_3"
+ _buildargs="$_buildargs $_1 $_2 $_3"
fi
INFO ""
+ INFO "Or even simpler, just run (in your blender-source dir):"
+ INFO " make -j$THREADS BUILD_CMAKE_ARGS=\"$_buildargs\""
+
+ INFO ""
INFO "If you're using SCons add this to your user-config:"
- if [ -d $INST/python-3.3 ]; then
- INFO "BF_PYTHON = '$INST/python-3.3'"
+ if [ -d $INST/python-$PYTHON_VERSION_MIN ]; then
+ INFO "BF_PYTHON = '$INST/python-$PYTHON_VERSION_MIN'"
INFO "BF_PYTHON_ABI_FLAGS = 'm'"
fi
@@ -1836,6 +2056,7 @@ print_info() {
if [ -d $INST/boost ]; then
INFO "BF_BOOST = '$INST/boost'"
+ INFO "WITH_BF_BOOST = True"
fi
if [ -d $INST/ffmpeg ]; then
@@ -1864,11 +2085,14 @@ elif [ "$DISTRO" = "DEB" ]; then
install_DEB
elif [ "$DISTRO" = "RPM" ]; then
install_RPM
-elif [ "$DISTRO" = "SUSE" ]; then
- install_SUSE
+#elif [ "$DISTRO" = "ARCH" ]; then
+# install_ARCH
fi
-print_info
+print_info | tee BUILD_NOTES.txt
+INFO ""
+INFO "This information has been written to BUILD_NOTES.txt"
+INFO ""
# Switch back to user language.
LANG=LANG_BACK
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
new file mode 100644
index 0000000..e72218e
--- /dev/null
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
@@ -0,0 +1,5 @@
+BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
+BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
+BF_NUMJOBS = 1
+
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
new file mode 100644
index 0000000..10738a1
--- /dev/null
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
@@ -0,0 +1,5 @@
+BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
+BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
+BF_NUMJOBS = 1
+
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index e665657..540416e 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -1,6 +1,7 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
+WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,14 +104,13 @@ WITH_BF_FFTW3 = True
WITH_BF_STATICFFTW3 = True
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+WITH_BF_CYCLES_CUDA_BINARIES = False
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index 420d9ed..c0ba806 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -1,6 +1,7 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
+WITHOUT_BF_OVERWRITE_INSTALL = True
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,14 +104,13 @@ WITH_BF_FFTW3 = True
WITH_BF_STATICFFTW3 = True
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
+WITH_BF_CYCLES_CUDA_BINARIES = False
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py
deleted file mode 100644
index b36196f..0000000
--- a/build_files/buildbot/config/user-config-glibc27-i686.py
+++ /dev/null
@@ -1,149 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-i686'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-i686'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = True
-BF_OPENCOLLADA = '/opt/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib32'
-BF_PCRE_LIB = ''
-BF_EXPAT_LIB = ''
-
-# FFMPEG configuration
-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
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = True
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = True
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Blender player (would be enabled in it's own config)
-WITH_BF_PLAYER = False
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-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'
-
-# FFT
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-
-# JACK
-WITH_BF_JACK = True
-
-# Cycles
-WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-
-WITH_BF_OIIO = True
-WITH_BF_STATICOIIO = True
-BF_OIIO = '/opt/oiio'
-BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-
-WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
-BF_OSL = '/opt/osl'
-BF_OSL_INC = '${BF_OSL}/include'
-# note oslexec would passed via program linkflags, which is needed to
-# make llvm happy with osl_allocate_closure_component
-BF_OSL_LIB = 'oslcomp oslexec oslquery'
-BF_OSL_LIBPATH = '${BF_OSL}/lib'
-BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
-
-WITH_BF_LLVM = True
-WITH_BF_STATICLLVM = False
-BF_LLVM = '/opt/llvm-3.1'
-BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
- 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
- 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
-BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# Ocean Simulation
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py
deleted file mode 100644
index 7359e15..0000000
--- a/build_files/buildbot/config/user-config-glibc27-x86_64.py
+++ /dev/null
@@ -1,149 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = True
-BF_OPENCOLLADA = '/opt/opencollada'
-BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
-BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static'
-BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib64'
-BF_PCRE_LIB = ''
-BF_EXPAT_LIB = ''
-
-# FFMPEG configuration
-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
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = True
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = True
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = True
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Blender player (would be enabled in it's own config)
-WITH_BF_PLAYER = False
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-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'
-
-# FFT
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-
-# JACK
-WITH_BF_JACK = True
-
-# Cycles
-WITH_BF_CYCLES = True
-WITH_BF_CYCLES_CUDA_BINARIES = True
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-
-WITH_BF_OIIO = True
-WITH_BF_STATICOIIO = True
-BF_OIIO = '/opt/oiio'
-BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-
-WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
-BF_OSL = '/opt/osl'
-BF_OSL_INC = '${BF_OSL}/include'
-# note oslexec would passed via program linkflags, which is needed to
-# make llvm happy with osl_allocate_closure_component
-BF_OSL_LIB = 'oslcomp oslexec oslquery'
-BF_OSL_LIBPATH = '${BF_OSL}/lib'
-BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
-
-WITH_BF_LLVM = True
-WITH_BF_STATICLLVM = False
-BF_LLVM = '/opt/llvm-3.1'
-BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
- 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
- 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
-BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# Ocean Simulation
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index 96f2012..a99337f 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -1,6 +1,6 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,7 +103,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
index 75979d0..c17cff2 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -1,6 +1,6 @@
BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
-BF_NUMJOBS = 2
+BF_NUMJOBS = 4
# Python configuration
BF_PYTHON_VERSION = '3.3'
@@ -103,7 +103,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
-WITH_BF_JACK = True
+WITH_BF_JACK = False
WITH_BF_STATICJACK = True
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py
deleted file mode 100644
index 82b105c..0000000
--- a/build_files/buildbot/config/user-config-player-glibc27-i686.py
+++ /dev/null
@@ -1,114 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-i686'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-i686'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = False
-
-# FFMPEG configuration
-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
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = False
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = False
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = False
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Do not build blender when building blenderplayer
-WITH_BF_NOBLENDER = True
-WITH_BF_PLAYER = True
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-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'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# JACK
-WITH_BF_JACK = True
-
-# Motion Tracking
-WITH_BF_LIBMV = False
-
-# Ocean Simulation
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
deleted file mode 100644
index 1e6aa4a..0000000
--- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
+++ /dev/null
@@ -1,114 +0,0 @@
-BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64'
-BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64'
-BF_NUMJOBS = 2
-
-# Python configuration
-BF_PYTHON_VERSION = '3.3'
-BF_PYTHON_ABI_FLAGS = 'm'
-BF_PYTHON = '/opt/python3'
-
-WITH_BF_STATICPYTHON = True
-
-# OpenCollada configuration
-WITH_BF_COLLADA = False
-
-# FFMPEG configuration
-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
-BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a'
-
-WITH_BF_OPENAL = True
-WITH_BF_STATICOPENAL = True
-BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a'
-
-WITH_BF_GETTEXT_STATIC = True
-BF_FREETYPE_LIB_STATIC = True
-
-WITH_BF_OPENEXR = False
-WITH_BF_STATICOPENEXR = True
-
-WITH_BF_TIFF = False
-WITH_BF_STATICTIFF = True
-BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a'
-
-WITH_BF_JPEG = True
-BF_JPEG_LIB = 'libjpeg'
-BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_STATICLIBSAMPLERATE = True
-
-WITH_BF_PNG = True
-BF_PNG_LIB = 'libpng'
-BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
-
-WITH_BF_ZLIB = True
-WITH_BF_STATICZLIB = True
-BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
-
-WITH_BF_SDL = True
-WITH_BF_OGG = False
-
-WITH_BF_OPENMP = True
-
-WITH_BF_GAMEENGINE = True
-WITH_BF_BULLET = True
-
-# Do not build blender when building blenderplayer
-WITH_BF_NOBLENDER = True
-WITH_BF_PLAYER = True
-
-# Use jemalloc memory manager
-WITH_BF_JEMALLOC = True
-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'
-
-# Color management
-WITH_BF_OCIO = True
-WITH_BF_STATICOCIO = True
-BF_OCIO = '/opt/ocio'
-BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-
-WITH_BF_BOOST = True
-WITH_BF_STATICBOOST = True
-BF_BOOST = '/opt/boost'
-BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
-BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
-
-# JACK
-WITH_BF_JACK = True
-
-# Motion Tracking
-WITH_BF_LIBMV = False
-
-# Ocean Simulation
-WITH_BF_FFTW3 = True
-WITH_BF_STATICFFTW3 = True
-WITH_BF_OCEANSIM = True
-
-# Compilation and optimization
-BF_DEBUG = False
-REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
-PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index 90f0c80..9d0839b 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -116,10 +116,10 @@ add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True)
add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder)
add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder)
#add_builder(c, 'linux_x86_64_cmake', '', generic_builder)
-add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder)
+#add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder)
add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder)
#add_builder(c, 'salad_linux_i386_scons', '', generic_builder, 'soc-2011-salad')
-add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder)
+#add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder)
add_builder(c, 'linux_glibc211_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)
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index bedada9..dab8a8e 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -60,6 +60,27 @@ else:
if builder.find('linux') != -1:
import shutil
+ configs = []
+ if builder.endswith('linux_glibc211_x86_64_scons'):
+ configs = ['user-config-player-glibc211-x86_64.py',
+ 'user-config-cuda-glibc211-x86_64.py',
+ 'user-config-glibc211-x86_64.py'
+ ]
+ chroot_name = 'buildbot_squeeze_x86_64'
+ cuda_chroot = 'buildbot_squeeze_x86_64'
+ elif builder.endswith('linux_glibc211_i386_scons'):
+ configs = ['user-config-player-glibc211-i686.py',
+ 'user-config-cuda-glibc211-i686.py',
+ 'user-config-glibc211-i686.py']
+ chroot_name = 'buildbot_squeeze_i686'
+
+ # use 64bit cuda toolkit, so there'll be no memory limit issues
+ cuda_chroot = 'buildbot_squeeze_x86_64'
+
+ # Compilation will happen inside of chroot environment
+ prog_scons_cmd = ['schroot', '-c', chroot_name, '--'] + scons_cmd
+ cuda_scons_cmd = ['schroot', '-c', cuda_chroot, '--'] + scons_cmd
+
# We're using the same rules as release builder, so tweak
# build and install dirs
build_dir = os.path.join('..', 'build', builder)
@@ -74,20 +95,6 @@ else:
buildbot_dir = os.path.dirname(os.path.realpath(__file__))
config_dir = os.path.join(buildbot_dir, 'config')
- configs = []
- if builder.endswith('linux_glibc27_x86_64_scons'):
- configs = ['user-config-player-glibc27-x86_64.py',
- 'user-config-glibc27-x86_64.py']
- elif builder.endswith('linux_glibc27_i386_scons'):
- configs = ['user-config-player-glibc27-i686.py',
- 'user-config-glibc27-i686.py']
- if builder.endswith('linux_glibc211_x86_64_scons'):
- configs = ['user-config-player-glibc211-x86_64.py',
- 'user-config-glibc211-x86_64.py']
- elif builder.endswith('linux_glibc211_i386_scons'):
- configs = ['user-config-player-glibc211-i686.py',
- 'user-config-glibc211-i686.py']
-
for config in configs:
config_fpath = os.path.join(config_dir, config)
@@ -100,14 +107,24 @@ else:
scons_options += common_options
- if config.find('player') == -1:
- scons_options.append('blender')
- else:
+ if config.find('player') != -1:
scons_options.append('blenderplayer')
+ cur_scons_cmd = prog_scons_cmd
+ elif config.find('cuda') != -1:
+ scons_options.append('cudakernels')
+ cur_scons_cmd = cuda_scons_cmd
+
+ if config.find('i686') != -1:
+ scons_options.append('BF_BITNESS=32')
+ elif config.find('x86_64') != -1:
+ scons_options.append('BF_BITNESS=64')
+ else:
+ scons_options.append('blender')
+ cur_scons_cmd = prog_scons_cmd
scons_options.append('BF_CONFIG=' + config_fpath)
- retcode = subprocess.call(scons_cmd + scons_options)
+ retcode = subprocess.call(cur_scons_cmd + scons_options)
if retcode != 0:
print('Error building rules wuth config ' + config)
sys.exit(retcode)
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index b7775ef..3d4f423 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -57,17 +57,13 @@ if builder.find('scons') != -1:
config = None
bits = None
- if builder.endswith('linux_glibc27_x86_64_scons'):
- config = 'user-config-glibc27-x86_64.py'
- bits = 64
- elif builder.endswith('linux_glibc27_i386_scons'):
- config = 'user-config-glibc27-i686.py'
- bits = 32
if builder.endswith('linux_glibc211_x86_64_scons'):
config = 'user-config-glibc211-x86_64.py'
+ chroot_name = 'buildbot_squeeze_x86_64'
bits = 64
elif builder.endswith('linux_glibc211_i386_scons'):
config = 'user-config-glibc211-i686.py'
+ chroot_name = 'buildbot_squeeze_i686'
bits = 32
if config is not None:
@@ -76,7 +72,7 @@ if builder.find('scons') != -1:
blender = os.path.join(install_dir, 'blender')
blenderplayer = os.path.join(install_dir, 'blenderplayer')
- subprocess.call(['strip', '--strip-all', blender, blenderplayer])
+ subprocess.call(['schroot', '-c', chroot_name, '--', 'strip', '--strip-all', blender, blenderplayer])
extra = '/' + os.path.join('home', 'sources', 'release-builder', 'extra')
mesalibs = os.path.join(extra, 'mesalibs' + str(bits) + '.tar.bz2')
@@ -86,7 +82,7 @@ if builder.find('scons') != -1:
os.system('cp %s %s' % (software_gl, install_dir))
os.system('chmod 755 %s' % (os.path.join(install_dir, 'blender-softwaregl')))
- retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
+ retcode = subprocess.call(['schroot', '-c', chroot_name, '--', 'python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
else:
diff --git a/build_files/cmake/Modules/FindOpenCOLLADA.cmake b/build_files/cmake/Modules/FindOpenCOLLADA.cmake
index 169d3a8..84aead5 100644
--- a/build_files/cmake/Modules/FindOpenCOLLADA.cmake
+++ b/build_files/cmake/Modules/FindOpenCOLLADA.cmake
@@ -66,6 +66,7 @@ SET(_opencollada_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/opencollada
)
SET(_opencollada_INCLUDES)
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index b13b0dd..665bc60 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -75,12 +75,12 @@ def is_cmake(filename):
def is_c_header(filename):
ext = splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_c(filename):
ext = splitext(filename)[1]
- return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"))
+ return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
def is_c_any(filename):
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index 2f36cad..17490e3 100755
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -56,6 +56,10 @@ def create_nb_project_main():
pass
else:
includes, defines = cmake_advanced_info()
+
+ if (includes, defines) == (None, None):
+ return
+
# for some reason it doesnt give all internal includes
includes = list(set(includes) | set(dirname(f) for f in files if is_c_header(f)))
includes.sort()
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 86201da..4cf854a 100755
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -81,6 +81,9 @@ def create_qtc_project_main():
else:
includes, defines = cmake_advanced_info()
+ if (includes, defines) == (None, None):
+ return
+
# for some reason it doesnt give all internal includes
includes = list(set(includes) | set(os.path.dirname(f)
for f in files_rel if is_c_header(f)))
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index efa258a..bdd82a4 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -282,7 +282,9 @@ macro(setup_liblinks
if(WITH_SYSTEM_GLEW)
target_link_libraries(${target} ${GLEW_LIBRARY})
endif()
-
+ if(WITH_BULLET AND WITH_SYSTEM_BULLET)
+ target_link_libraries(${target} ${BULLET_LIBRARIES})
+ endif()
if(WITH_OPENAL)
target_link_libraries(${target} ${OPENAL_LIBRARY})
endif()
@@ -441,6 +443,15 @@ macro(TEST_SSE_SUPPORT
unset(CMAKE_REQUIRED_FLAGS)
endmacro()
+macro(TEST_STDBOOL_SUPPORT)
+ # This program will compile correctly if and only if
+ # this C compiler supports C99 stdbool.
+ check_c_source_runs("
+ #include <stdbool.h>
+ int main(void) { return (int)false; }"
+ HAVE_STDBOOL_H)
+endmacro()
+
# when we have warnings as errors applied globally this
# needs to be removed for some external libs which we dont maintain.
diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py
index 34f378a..e73b94a 100755
--- a/build_files/cmake/project_info.py
+++ b/build_files/cmake/project_info.py
@@ -97,7 +97,7 @@ def is_cmake(filename):
def is_c_header(filename):
ext = splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_py(filename):
@@ -149,14 +149,20 @@ def cmake_advanced_info():
raise Exception("Unknown make program %r" % make_exe)
os.system(cmd)
+ return join(CMAKE_DIR, ".cproject")
+
includes = []
defines = []
- create_eclipse_project()
+ project_path = create_eclipse_project()
+
+ if not exists(project_path):
+ print("Generating Eclipse Prokect File Failed: %r not found" % project_path)
+ return None, None
from xml.dom.minidom import parse
- tree = parse(join(CMAKE_DIR, ".cproject"))
+ tree = parse(project_path)
# to check on nicer xml
# f = open(".cproject_pretty", 'w')
diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py
index 10bc36b..69d09b0 100644
--- a/build_files/cmake/project_source_info.py
+++ b/build_files/cmake/project_source_info.py
@@ -43,7 +43,7 @@ SOURCE_DIR = abspath(SOURCE_DIR)
def is_c_header(filename):
ext = os.path.splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_c(filename):
diff --git a/build_files/package_spec/rpm/blender.spec.in b/build_files/package_spec/rpm/blender.spec.in
index a95fce8..e75cc8e 100644
--- a/build_files/package_spec/rpm/blender.spec.in
+++ b/build_files/package_spec/rpm/blender.spec.in
@@ -77,6 +77,7 @@ fi || :
%{_bindir}/%{name}
%{_datadir}/%{name}/%{blender_api}/datafiles/fonts
%{_datadir}/%{name}/%{blender_api}/datafiles/colormanagement
+%{_datadir}/%{name}/%{blender_api}/datafiles/locale/languages
%{_datadir}/%{name}/%{blender_api}/scripts
%{_datadir}/icons/hicolor/*/apps/%{name}.*
%{_datadir}/applications/%{name}.desktop
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index 252a1b1..207ddd3 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -165,7 +165,7 @@ BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
WITH_BF_JACK = True
BF_JACK = '/Library/Frameworks/Jackmp.framework'
BF_JACK_INC = '${BF_JACK}/headers'
-BF_JACK_LIB = 'jack'
+#BF_JACK_LIB = 'jack' # not used due framework
BF_JACK_LIBPATH = '${BF_JACK}'
WITH_BF_SNDFILE = True
diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py
index 038a9bc..db3b369 100644
--- a/build_files/scons/config/linux-config.py
+++ b/build_files/scons/config/linux-config.py
@@ -1,15 +1,5 @@
-# find library directory
-import platform
-import os
from Modules.FindPython import FindPython
-bitness = platform.architecture()[0]
-if bitness == '64bit':
- LCGDIR = '../lib/linux64'
-else:
- LCGDIR = '../lib/linux'
-LIBDIR = "#${LCGDIR}"
-
py = FindPython()
BF_PYTHON_ABI_FLAGS = py['ABI_FLAGS']
@@ -113,7 +103,7 @@ BF_QUICKTIME = '/usr/local'
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
WITH_BF_ICONV = False
-BF_ICONV = LIBDIR + "/iconv"
+BF_ICONV = "/usr"
BF_ICONV_INC = '${BF_ICONV}/include'
BF_ICONV_LIB = 'iconv'
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
@@ -122,18 +112,7 @@ WITH_BF_BINRELOC = True
# enable ffmpeg support
WITH_BF_FFMPEG = True
-BF_FFMPEG = LIBDIR + '/ffmpeg'
-if os.path.exists(LCGDIR + '/ffmpeg'):
- WITH_BF_STATICFFMPEG = True
- 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'
-else:
- BF_FFMPEG = '/usr'
+BF_FFMPEG = '/usr'
BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice'
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
@@ -198,34 +177,30 @@ BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib'
BF_JEMALLOC_LIB = 'jemalloc'
BF_JEMALLOC_LIB_STATIC = '${BF_JEMALLOC_LIBPATH}/libjemalloc.a'
-WITH_BF_OIIO = True
+WITH_BF_OIIO = False
WITH_BF_STATICOIIO = False
-BF_OIIO = LIBDIR + '/oiio'
-if not os.path.exists(LCGDIR + '/oiio'):
- WITH_BF_OIIO = False
- BF_OIIO = '/usr'
+BF_OIIO = '/usr'
BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB = 'OpenImageIO'
+BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
-WITH_BF_OCIO = True
+WITH_BF_OCIO = False
WITH_BF_STATICOCIO = False
-BF_OCIO = LIBDIR + '/ocio'
-if not os.path.exists(LCGDIR + '/ocio'):
- WITH_BF_OCIO = False
- BF_OCIO = '/usr'
+BF_OCIO = '/usr'
BF_OCIO_INC = '${BF_OCIO}/include'
BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml'
+BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
-WITH_BF_BOOST = True
+WITH_BF_BOOST = False
WITH_BF_STATICBOOST = False
-BF_BOOST = LIBDIR + '/boost'
-if not os.path.exists(LCGDIR + '/boost'):
- WITH_BF_BOOST = False
- BF_BOOST = '/usr'
+BF_BOOST = '/usr'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread'
+BF_BOOST_LIB = 'boost_filesystem boost_regex boost_system boost_thread boost_date_time'
+BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
+ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a' + \
+ '${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
@@ -253,8 +228,6 @@ BF_3DMOUSE_LIB_STATIC = '${BF_3DMOUSE_LIBPATH}/libspnav.a'
##
CC = 'gcc'
CXX = 'g++'
-##ifeq ($CPU),alpha)
-## CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -mieee
CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE']
CXXFLAGS = []
@@ -268,22 +241,12 @@ if WITH_BF_FFMPEG:
REL_CFLAGS = []
REL_CXXFLAGS = []
REL_CCFLAGS = ['-DNDEBUG', '-O2']
-##BF_DEPEND = True
-##
-##AR = ar
-##ARFLAGS = ruv
-##ARFLAGSQUIET = ru
-##
+
C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wunused-parameter', '-Wstrict-prototypes', '-Werror=declaration-after-statement', '-Werror=implicit-function-declaration', '-Werror=return-type']
CC_WARN = ['-Wall']
CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
-
-##FIX_STUBS_WARNINGS = -Wno-unused
-
LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++']
-##LOPTS = --dynamic
-##DYNLDFLAGS = -shared $(LDFLAGS)
BF_PROFILE = False
BF_PROFILE_CCFLAGS = ['-pg','-g']
@@ -301,4 +264,3 @@ PLATFORM_LINKFLAGS = ['-pthread']
#Fix for LLVM conflict with Mesa llvmpipe
if WITH_BF_LLVM:
PLATFORM_LINKFLAGS += ['-Wl,--version-script=source/creator/blender.map']
-
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 19f4ac9..2236044 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -47,10 +47,10 @@ def get_version():
if (ver_base is not None) and (ver_char is not None) and (ver_cycle is not None):
# eg '2.56a-beta'
- if ver_cycle:
+ if ver_cycle != "release":
ver_display = "%s%s-%s" % (ver_base, ver_char, ver_cycle)
else:
- ver_display = "%s%s" % (ver_base, ver_char) # assume release
+ ver_display = "%s%s" % (ver_base, ver_char)
return ver_base, ver_display, ver_cycle
@@ -215,7 +215,8 @@ def print_targets(targs, bc):
def validate_targets(targs, bc):
valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin',
'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release',
- 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave']
+ 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave',
+ 'cudakernels']
oklist = []
for t in targs:
if t in valid_list:
@@ -826,6 +827,18 @@ def NSIS_Installer(target=None, source=None, env=None):
print data.strip().split("\n")[-1]
return rv
+def cudakernels_print(target, source, env):
+ return "Running cudakernels target"
+
+def cudakernels(target=None, source=None, env=None):
+ """
+ Builder for cuda kernels compilation. Used by release build environment only
+ """
+
+ # Currently nothing to do, everything is handled by a dependency resolver
+
+ pass
+
def check_environ():
problematic_envvars = ""
for i in os.environ:
diff --git a/doc/python_api/examples/bpy.props.5.py b/doc/python_api/examples/bpy.props.5.py
new file mode 100644
index 0000000..e49d0f2
--- /dev/null
+++ b/doc/python_api/examples/bpy.props.5.py
@@ -0,0 +1,85 @@
+"""
+Get/Set Example
+++++++++++++++
+
+Get/Set functions can be used for boolean, int, float, string and enum properties.
+If these callbacks are defined the property will not be stored in the ID properties
+automatically, instead the get/set functions will be called when the property is
+read or written from the API.
+"""
+
+import bpy
+
+
+# Simple property reading/writing from ID properties.
+# This is what the RNA would do internally.
+def get_float(self):
+ return self["testprop"]
+
+def set_float(self, value):
+ self["testprop"] = value
+
+bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float)
+
+
+# Read-only string property, returns the current date
+def get_date(self):
+ import datetime
+ return str(datetime.datetime.now())
+
+bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date)
+
+
+# Boolean array. Set function stores a single boolean value, returned as the second component.
+# Array getters must return a list or tuple
+# Array size must match the property vector size exactly
+def get_array(self):
+ return (True, self["somebool"])
+
+def set_array(self, values):
+ self["somebool"] = values[0] and values[1]
+
+bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array)
+
+
+# Enum property.
+# Note: the getter/setter callback must use integer identifiers!
+test_items = [
+ ("RED", "Red", "", 1),
+ ("GREEN", "Red", "", 2),
+ ("BLUE", "Red", "", 3),
+ ("YELLOW", "Red", "", 4),
+ ]
+
+def get_enum(self):
+ import random
+ return random.randint(1, 4)
+
+def set_enum(self, value):
+ print("setting value", value)
+
+bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum)
+
+
+# Testing
+
+scene = bpy.context.scene
+
+scene.test_float = 12.34
+print (scene.test_float)
+
+scene.test_array = (True, False)
+print ([x for x in scene.test_array])
+
+#scene.test_date = "blah" # this would fail, property is read-only
+print (scene.test_date)
+
+scene.test_enum = 'BLUE'
+print (scene.test_enum)
+
+
+# >>> 12.34000015258789
+# >>> [True, False]
+# >>> 2013-01-05 16:33:52.135340
+# >>> setting value 3
+# >>> GREEN
diff --git a/doc/python_api/examples/bpy.types.AddonPreferences.1.py b/doc/python_api/examples/bpy.types.AddonPreferences.1.py
new file mode 100644
index 0000000..08de6f4
--- /dev/null
+++ b/doc/python_api/examples/bpy.types.AddonPreferences.1.py
@@ -0,0 +1,70 @@
+bl_info = {
+ "name": "Example Addon Preferences",
+ "author": "Your Name Here",
+ "version": (1, 0),
+ "blender": (2, 65, 0),
+ "location": "SpaceBar Search -> Addon Preferences Example",
+ "description": "Example Addon",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+import bpy
+from bpy.types import Operator, AddonPreferences
+from bpy.props import StringProperty, IntProperty, BoolProperty
+
+
+class ExampleAddonPreferences(AddonPreferences):
+ bl_idname = __name__
+
+ filepath = StringProperty(
+ name="Example File Path",
+ subtype='FILE_PATH',
+ )
+ number = IntProperty(
+ name="Example Number",
+ default=4,
+ )
+ boolean = BoolProperty(
+ name="Example Boolean",
+ default=False,
+ )
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label(text="This is a preferences view for our addon")
+ layout.prop(self, "filepath")
+ layout.prop(self, "number")
+ layout.prop(self, "boolean")
+
+
+class OBJECT_OT_addon_prefs_example(Operator):
+ """Display example preferences"""
+ bl_idname = "object.addon_prefs_example"
+ bl_label = "Addon Preferences Example"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ user_preferences = context.user_preferences
+ addon_prefs = user_preferences.addons[__name__].preferences
+
+ info = ("Path: %s, Number: %d, Boolean %r" %
+ (addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean))
+
+ self.report({'INFO'}, info)
+ print(info)
+
+ return {'FINISHED'}
+
+
+# Registration
+def register():
+ bpy.utils.register_class(OBJECT_OT_addon_prefs_example)
+ bpy.utils.register_class(ExampleAddonPreferences)
+
+
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_addon_prefs_example)
+ bpy.utils.unregister_class(ExampleAddonPreferences)
diff --git a/doc/python_api/examples/bpy.types.UIList.py b/doc/python_api/examples/bpy.types.UIList.py
new file mode 100644
index 0000000..f2017e3
--- /dev/null
+++ b/doc/python_api/examples/bpy.types.UIList.py
@@ -0,0 +1,89 @@
+"""
+Basic UIList Example
++++++++++++++++++++
+This script is the UIList subclass used to show material slots, with a bunch of additional commentaries.
+
+Notice the name of the class, this naming convention is similar as the one for panels or menus.
+
+.. note::
+
+ UIList subclasses must be registered for blender to use them.
+"""
+import bpy
+
+
+class MATERIAL_UL_matslots_example(bpy.types.UIList):
+ # The draw_item function is called for each item of the collection that is visible in the list.
+ # data is the RNA object containing the collection,
+ # item is the current drawn item of the collection,
+ # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
+ # have custom icons ID, which are not available as enum items).
+ # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
+ # active item of the collection).
+ # active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
+ # index is index of the current item in the collection.
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ ob = data
+ slot = item
+ ma = slot.material
+ # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ # You should always start your row layout by a label (icon + text), this will also make the row easily
+ # selectable in the list!
+ # We use icon_value of label, as our given icon is an integer value, not an enum ID.
+ layout.label(ma.name if ma else "", icon_value=icon)
+ # And now we can add other UI stuff...
+ # Here, we add nodes info if this material uses (old!) shading nodes.
+ if ma and not context.scene.render.use_shading_nodes:
+ manode = ma.active_node_material
+ if manode:
+ # The static method UILayout.icon returns the integer value of the icon ID "computed" for the given
+ # RNA object.
+ layout.label("Node %s" % manode.name, icon_value=layout.icon(manode))
+ elif ma.use_nodes:
+ layout.label("Node <none>")
+ else:
+ layout.label("")
+ # 'GRID' layout type should be as compact as possible (typically a single icon!).
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
+# And now we can use this list everywhere in Blender. Here is a small example panel.
+class UIListPanelExample(bpy.types.Panel):
+ """Creates a Panel in the Object properties window"""
+ bl_label = "UIList Panel"
+ bl_idname = "OBJECT_PT_ui_list_example"
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "object"
+
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+
+ # template_list now takes two new args.
+ # The first one is the identifier of the registered UIList to use (if you want only the default list,
+ # with no custom draw code, use "UI_UL_list").
+ layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
+
+ # The second one can usually be left as an empty string. It's an additional ID used to distinguish lists in case you
+ # use the same list several times in a given area.
+ layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
+ obj, "active_material_index", type='COMPACT')
+
+
+def register():
+ bpy.utils.register_class(MATERIAL_UL_matslots_example)
+ bpy.utils.register_class(UIListPanelExample)
+
+
+def unregister():
+ bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
+ bpy.utils.unregister_class(UIListPanelExample)
+
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst
index 7d20aa3..944b1ca 100644
--- a/doc/python_api/rst/bge.logic.rst
+++ b/doc/python_api/rst/bge.logic.rst
@@ -125,6 +125,10 @@ Variables
The current mouse wrapped in an :class:`~bge.types.SCA_PythonMouse` object.
+.. data:: joysticks
+
+ A list of attached joysticks. The list size it he maximum number of supported joysticks. If no joystick is available for a given slot, the slot is set to None.
+
*****************
General functions
*****************
@@ -172,7 +176,7 @@ General functions
Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).
-.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True)
+.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True, async=False)
Converts the all of the datablocks of the given type from the given blend.
@@ -187,7 +191,13 @@ General functions
:arg verbose: Whether or not to print debugging information (e.g., "SceneName: Scene")
:type verbose: bool
:arg load_scripts: Whether or not to load text datablocks as well (can be disabled for some extra security)
- :type load_scripts: bool
+ :type load_scripts: bool
+ :arg async: Whether or not to do the loading asynchronously (in another thread). Only the "Scene" type is currently supported for this feature.
+ :type async: bool
+
+ :rtype: :class:`bge.types.KX_LibLoadStatus`
+
+ .. note:: Asynchronously loaded libraries will not be available immediately after LibLoad() returns. Use the returned KX_LibLoadStatus to figure out when the libraries are ready.
.. function:: LibNew(name, type, data)
diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst
index 8cf9ccb..a86272d 100644
--- a/doc/python_api/rst/bge.types.rst
+++ b/doc/python_api/rst/bge.types.rst
@@ -141,6 +141,74 @@ Types
:type: boolean
+.. class:: SCA_PythonJoystick(PyObjectPlus)
+
+ A Python interface to a joystick.
+
+ .. attribute:: name
+
+ The name assigned to the joystick by the operating system. (read-only)
+
+ :type: string
+
+ .. attribute:: activeButtons
+
+ A list of active button values. (read-only)
+
+ :type: list
+
+ .. attribute:: axisValues
+
+ The state of the joysticks axis as a list of values :data:`numAxis` long. (read-only).
+
+ :type: list of ints.
+
+ Each specifying the value of an axis between -1.0 and 1.0 depending on how far the axis is pushed, 0 for nothing.
+ The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
+
+ * left:[-1.0, 0.0, ...]
+ * right:[1.0, 0.0, ...]
+ * up:[0.0, -1.0, ...]
+ * down:[0.0, 1.0, ...]
+
+ .. attribute:: hatValues
+
+ The state of the joysticks hats as a list of values :data:`numHats` long. (read-only).
+
+ :type: list of ints
+
+ Each specifying the direction of the hat from 1 to 12, 0 when inactive.
+
+ Hat directions are as follows...
+
+ * 0:None
+ * 1:Up
+ * 2:Right
+ * 4:Down
+ * 8:Left
+ * 3:Up - Right
+ * 6:Down - Right
+ * 12:Down - Left
+ * 9:Up - Left
+
+ .. attribute:: numAxis
+
+ The number of axes for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: numButtons
+
+ The number of buttons for the joystick at this index. (read-only).
+
+ :type: integer
+
+ .. attribute:: numHats
+
+ The number of hats for the joystick at this index. (read-only).
+
+ :type: integer
+
.. class:: SCA_IObject(CValue)
This class has no python functions
@@ -1861,6 +1929,44 @@ Types
:type: boolean
+.. class:: KX_LibLoadStatus(PyObjectPlus)
+
+ An object providing information about a LibLoad() operation.
+
+ .. code-block:: python
+
+ # Print a message when an async LibLoad is done
+ import bge
+
+ def finished_cb(status):
+ print("Library (%s) loaded in %.2fms." % (status.libraryName, status.timeTaken))
+
+ bge.logic.LibLoad('myblend.blend', 'Scene', async=True).onFinish = finished_cb
+
+ .. attribute:: onFinish
+
+ A callback that gets called when the lib load is done.
+
+ :type: callable
+
+ .. attribute:: progress
+
+ The current progress of the lib load as a normalized value from 0.0 to 1.0.
+
+ :type: float
+
+ .. attribute:: libraryName
+
+ The name of the library being loaded (the first argument to LibLoad).
+
+ :type: string
+
+ .. attribute:: timeTaken
+
+ The amount of time, in seconds, the lib load took (0 until the operation is complete).
+
+ :type: float
+
.. class:: KX_LightObject(KX_GameObject)
A Light object.
@@ -3643,6 +3749,18 @@ Types
:type: float
+ .. attribute:: maxJumps
+
+ The maximum number of jumps a character can perform before having to touch the ground. By default this is set to 1. 2 allows for a double jump, etc.
+
+ :type: int
+
+ .. attribute:: jumpCount
+
+ The current jump count. This can be used to have different logic for a single jump versus a double jump. For example, a different animation for the second jump.
+
+ :type: int
+
.. method:: jump()
The character jumps based on it's jump speed.
@@ -3977,7 +4095,7 @@ Types
:type: list of ints.
- Each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing.
+ Each specifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing.
The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
* left:[-32767, 0, ...]
@@ -4001,7 +4119,7 @@ Types
:type: list of ints
- Each spesifying the direction of the hat from 1 to 12, 0 when inactive.
+ Each specifying the direction of the hat from 1 to 12, 0 when inactive.
Hat directions are as follows...
diff --git a/doc/python_api/rst/change_log.rst b/doc/python_api/rst/change_log.rst
index c1f3c2e..7579070 100644
--- a/doc/python_api/rst/change_log.rst
+++ b/doc/python_api/rst/change_log.rst
@@ -3896,3 +3896,433 @@ Added
^^^^^
* :class:`bpy.types.LatticePoint.select`
+
+
+2.64 to 2.65
+============
+
+bpy.types.SmokeDomainSettings
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SmokeDomainSettings.adapt_margin`
+* :class:`bpy.types.SmokeDomainSettings.adapt_threshold`
+* :class:`bpy.types.SmokeDomainSettings.additional_res`
+* :class:`bpy.types.SmokeDomainSettings.burning_rate`
+* :class:`bpy.types.SmokeDomainSettings.flame_ignition`
+* :class:`bpy.types.SmokeDomainSettings.flame_max_temp`
+* :class:`bpy.types.SmokeDomainSettings.flame_smoke`
+* :class:`bpy.types.SmokeDomainSettings.flame_smoke_color`
+* :class:`bpy.types.SmokeDomainSettings.flame_vorticity`
+* :class:`bpy.types.SmokeDomainSettings.use_adaptive_domain`
+
+Removed
+^^^^^^^
+
+* **scale**
+
+bpy.types.BezierSplinePoint
+---------------------------
+
+Renamed
+^^^^^^^
+
+* **weight** -> :class:`bpy.types.BezierSplinePoint.weight_softbody`
+
+bpy.types.Material
+------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Material.use_light_group_local`
+
+bpy.types.Curve
+---------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Curve.use_map_taper`
+
+bpy.types.EffectorWeights
+-------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.EffectorWeights.smokeflow`
+
+bpy.types.FieldSettings
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.FieldSettings.source_object`
+* :class:`bpy.types.FieldSettings.use_smoke_density`
+
+bpy.types.GPencilFrame
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GPencilFrame.clear`
+
+bpy.types.UserPreferencesView
+-----------------------------
+
+Renamed
+^^^^^^^
+
+* **quit_dialog** -> :class:`bpy.types.UserPreferencesView.use_quit_dialog`
+
+bpy.types.GreasePencilLayers
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GreasePencilLayers.new`
+* :class:`bpy.types.GreasePencilLayers.remove`
+
+bpy.types.PointCache
+--------------------
+
+Removed
+^^^^^^^
+
+* **use_quick_cache**
+
+bpy.types.KinematicConstraint
+-----------------------------
+
+Removed
+^^^^^^^
+
+* **use_target**
+
+bpy.types.DopeSheet
+-------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.DopeSheet.show_only_errors`
+
+bpy.types.UILayout
+------------------
+
+Renamed
+^^^^^^^
+
+* **template_color_wheel** -> :class:`bpy.types.UILayout.template_color_picker`
+
+bpy.types.GPencilStroke
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GPencilStroke.draw_mode`
+
+bpy.types.UserPreferencesEdit
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesEdit.use_auto_keying_warning`
+
+bpy.types.MovieTrackingObject
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MovieTrackingObject.keyframe_a`
+* :class:`bpy.types.MovieTrackingObject.keyframe_b`
+
+bpy.types.ShrinkwrapModifier
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ShrinkwrapModifier.project_limit`
+
+bpy.types.FileSelectParams
+--------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.FileSelectParams.use_filter_backup`
+
+bpy.types.RenderSettings
+------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.RenderSettings.tile_x`
+* :class:`bpy.types.RenderSettings.tile_y`
+* :class:`bpy.types.RenderSettings.use_persistent_data`
+
+Removed
+^^^^^^^
+
+* **parts_x**
+* **parts_y**
+* **use_sequencer_gl_render**
+
+bpy.types.Sculpt
+----------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Sculpt.show_diffuse_color`
+
+bpy.types.SmokeFlowSettings
+---------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SmokeFlowSettings.density_vertex_group`
+* :class:`bpy.types.SmokeFlowSettings.fuel_amount`
+* :class:`bpy.types.SmokeFlowSettings.noise_texture`
+* :class:`bpy.types.SmokeFlowSettings.smoke_color`
+* :class:`bpy.types.SmokeFlowSettings.smoke_flow_source`
+* :class:`bpy.types.SmokeFlowSettings.smoke_flow_type`
+* :class:`bpy.types.SmokeFlowSettings.surface_distance`
+* :class:`bpy.types.SmokeFlowSettings.texture_map_type`
+* :class:`bpy.types.SmokeFlowSettings.texture_offset`
+* :class:`bpy.types.SmokeFlowSettings.texture_size`
+* :class:`bpy.types.SmokeFlowSettings.use_texture`
+* :class:`bpy.types.SmokeFlowSettings.uv_layer`
+* :class:`bpy.types.SmokeFlowSettings.velocity_normal`
+* :class:`bpy.types.SmokeFlowSettings.velocity_random`
+* :class:`bpy.types.SmokeFlowSettings.volume_density`
+
+Removed
+^^^^^^^
+
+* **use_outflow**
+
+bpy.types.GameObjectSettings
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GameObjectSettings.collision_group`
+* :class:`bpy.types.GameObjectSettings.collision_mask`
+
+bpy.types.SpaceView3D
+---------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SpaceView3D.grid_scale_unit`
+* :class:`bpy.types.SpaceView3D.render_border_max_x`
+* :class:`bpy.types.SpaceView3D.render_border_max_y`
+* :class:`bpy.types.SpaceView3D.render_border_min_x`
+* :class:`bpy.types.SpaceView3D.render_border_min_y`
+* :class:`bpy.types.SpaceView3D.use_render_border`
+
+bpy.types.DupliObject
+---------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.DupliObject.orco`
+* :class:`bpy.types.DupliObject.particle_system`
+* :class:`bpy.types.DupliObject.persistent_id`
+* :class:`bpy.types.DupliObject.type`
+* :class:`bpy.types.DupliObject.uv`
+
+Removed
+^^^^^^^
+
+* **particle_index**
+
+bpy.types.CyclesRenderSettings
+------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.CyclesRenderSettings.use_progressive_refine`
+
+bpy.types.MaterialTextureSlot
+-----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MaterialTextureSlot.use_map_to_bounds`
+
+bpy.types.MovieSequence
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MovieSequence.colorspace_settings`
+
+bpy.types.GPencilLayer
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GPencilLayer.clear`
+
+bpy.types.CYCLES
+----------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.CYCLES.update_script_node`
+
+bpy.types.ImageSequence
+-----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ImageSequence.colorspace_settings`
+
+bpy.types.LatticePoint
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.LatticePoint.weight_softbody`
+
+bpy.types.DecimateModifier
+--------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.DecimateModifier.angle_limit`
+* :class:`bpy.types.DecimateModifier.decimate_type`
+* :class:`bpy.types.DecimateModifier.invert_vertex_group`
+* :class:`bpy.types.DecimateModifier.iterations`
+* :class:`bpy.types.DecimateModifier.use_collapse_triangulate`
+* :class:`bpy.types.DecimateModifier.use_dissolve_boundaries`
+* :class:`bpy.types.DecimateModifier.vertex_group`
+
+bpy.types.UserPreferencesSystem
+-------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesSystem.multi_sample`
+
+Removed
+^^^^^^^
+
+* **use_antialiasing**
+
+bpy.types.Text
+--------------
+
+Removed
+^^^^^^^
+
+* **markers**
+
+bpy.types.GreasePencil
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.GreasePencil.clear`
+
+bpy.types.UserPreferencesFilePaths
+----------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesFilePaths.hide_system_bookmarks`
+
+bpy.types.ToolSettings
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ToolSettings.snap_uv_element`
+
+bpy.types.ShaderNodeTexCoord
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ShaderNodeTexCoord.from_dupli`
+
+bpy.types.RenderEngine
+----------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.RenderEngine.update_memory_stats`
+* :class:`bpy.types.RenderEngine.update_script_node`
+
+bpy.types.MovieTrackingSettings
+-------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MovieTrackingSettings.reconstruction_success_threshold`
+* :class:`bpy.types.MovieTrackingSettings.use_fallback_reconstruction`
+
+Removed
+^^^^^^^
+
+* **keyframe_a**
+* **keyframe_b**
+
+bpy.types.ThemeUserInterface
+----------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ThemeUserInterface.axis_x`
+* :class:`bpy.types.ThemeUserInterface.axis_y`
+* :class:`bpy.types.ThemeUserInterface.axis_z`
+
+bpy.types.BlendDataGreasePencils
+--------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.BlendDataGreasePencils.new`
+* :class:`bpy.types.BlendDataGreasePencils.remove`
+
+bpy.types.Object
+----------------
+
+Function Arguments
+^^^^^^^^^^^^^^^^^^
+
+* :class:`bpy.types.Object.dupli_list_create` (scene, settings), *was (scene)*
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 441a6c0..af6ddac 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -612,6 +612,10 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
'''
function or class method to sphinx
'''
+
+ if type(py_func) == type(bpy.types.Space.draw_handler_add):
+ return
+
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
if not is_class:
diff --git a/doc/sculpt.org b/doc/sculpt.org
new file mode 100644
index 0000000..5f8c1b9
--- /dev/null
+++ b/doc/sculpt.org
@@ -0,0 +1,199 @@
+* Dynamic-Topology Sculpting
+** Undo System
+ Dynamic-topology sculpting is lightly integrated with the existing
+ sculpt undo stack. There are three new undo/redo operations:
+ entering dynamic-topology mode, exiting dynamic-topology mode, and
+ BMLog operations.
+
+*** BMLog
+ BMLog is an undo/redo record tied to BMesh. The source is in
+ bmesh/intern/bmesh_log.c. The BMLog keeps track of the creation
+ and deletion of vertices and faces (which are limited to triangles
+ for now) as well as vertex movement.
+
+*** Entering dynamic-topology mode
+
+
+*** Exiting dynamic-topology mode
+ When exiting dynamic-topology mode, it is important to write out
+ vertices and faces in a consistent order. This is needed because
+ regular sculpt undo only records vertex locations, with the
+ assumption that the order of vertices and faces (and the PBVH node
+ that owns them) remains static.
+
+ To accomplish this, the BMesh elements are reordered by their
+ unique IDs when exiting dynamic-topology mode.
+
+ A slightly different approach is needed when exiting
+ dynamic-topology mode via undo. Again, the mesh needs to have a
+ consistent ordering so as to match any regular sculpt undo
+ nodes. A simple re-ordering isn't enough though because
+ dynamic-topology mode splits all faces into triangles. The
+ simplest solution here is to directly store a full copy of the
+ mesh's vertex and face arrays. When undoing out of
+ dynamic-topology mode, the arrays are directly copied to the mesh
+ rather than doing any conversion from the BMesh.
+
+*** Test Scenarios
+ There are quite a few cases that the undo system has to handle. In
+ the interest of not breaking things when making future changes and
+ fixes, here are some manual testing steps to try. The expected
+ results are not described as they should be fairly obvious
+ (undo/redo results match original, no unfree'd memory, no graphics
+ glitches, etc.)
+
+ Note: when a bug is found in the undo system, this list should be
+ updated with a new test case with steps to reproduce the failure.
+
+**** Test 0
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Undo
+ - Redo
+ - Undo
+ - Redo
+ - Quit Blender
+
+**** Test 1
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Disable dynamic topology
+ - Undo
+ - Undo
+ - Undo
+ - Redo
+ - Redo
+ - Redo
+ - Quit Blender
+
+**** Test 2
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Enter editmode
+ - Quit Blender
+
+**** Test 3
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Disable dynamic topology
+ - Enter editmode
+ - Select all and move the mesh
+ - Enter sculpt mode
+ - Undo
+ - Redo
+ - XXX: this currently gives unexpected results. After undoing, a
+ redo doesn't get you back to the mesh as it was after moving in
+ editmode. It does not, however, crash or leak memory.
+
+**** Test 4
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Disable dynamic topology
+ - Undo
+ - Paint a single brush stroke
+ - Quit Blender
+
+**** Test 5
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Disable dynamic topology
+ - Undo
+ - Paint a single brush stroke
+ - Quit Blender
+
+**** Test 6
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Undo (undoes paint stroke)
+ - Undo (disables dynamic topology)
+ - Undo (used to do global undo, currently disabled though)
+ - Redo
+ - Redo
+ - Redo
+ - Quit Blender
+
+**** Test 7
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Disable dynamic topology
+ - Paint a single brush stroke
+ - Undo
+ - Undo
+ - Undo
+ - Undo
+ - Redo
+ - Redo
+ - Redo
+ - Redo
+ - Quit Blender
+
+**** Test 8
+ - Subdivide default cube
+ - Enter sculpt mode
+ - Paint a single brush stroke
+ - Enable dynamic topology
+ - Undo
+ - Undo
+ - Redo
+ - Redo
+ - Quit Blender
+
+**** Test 9
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Disable dynamic topology
+ - Undo
+ - Symmetrize
+ - Paint a single brush stroke
+ - Quit Blender
+
+**** Test 10
+ - Enter edit mode on default cube
+ - Exit edit mode and enter sculpt mode
+ - Enable dynamic topology
+ - Disable dynamic topology
+ - Undo
+ - Undo
+ - Enter edit mode
+ - Quit Blender
+
+**** Test 11
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Switch to mask brush (MKEY)
+ - Paint a single brush stroke
+ - Disable dynamic topology
+ - Undo
+ - Undo
+ - Undo
+ - Redo
+ - Redo
+ - Redo
+ - Quit Blender
+
+**** Test 13
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Hide part of the mesh (HKEY)
+ - Disable dynamic topology
+ - Undo
+ - Undo
+ - Undo
+ - Redo
+ - Redo
+ - Redo
+ - Quit Blender
+
+**** Test 14
+ - Enter sculpt mode on default cube
+ - Enable dynamic topology
+ - Paint a single brush stroke
+ - Save the file
+ - Undo
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 2640c52..6ad6bdc 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -27,9 +27,12 @@
remove_strict_flags()
add_subdirectory(colamd)
+add_subdirectory(rangetree)
if(WITH_BULLET)
- add_subdirectory(bullet2)
+ if(NOT WITH_SYSTEM_BULLET)
+ add_subdirectory(bullet2)
+ endif()
endif()
# now only available in a branch
diff --git a/extern/SConscript b/extern/SConscript
index 71998ee..6a0ffa3 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -4,6 +4,7 @@ Import('env')
SConscript(['glew/SConscript'])
SConscript(['colamd/SConscript'])
+SConscript(['rangetree/SConscript'])
if env['WITH_BF_GAMEENGINE']:
SConscript(['recastnavigation/SConscript'])
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
new file mode 100644
index 0000000..8d4c355
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
@@ -0,0 +1,98 @@
+#ifndef BT_COMPOUND_FROM_GIMPACT
+#define BT_COMPOUND_FROM_GIMPACT
+
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "btGImpactShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
+
+struct MyCallback : public btTriangleRaycastCallback
+ {
+ int m_ignorePart;
+ int m_ignoreTriangleIndex;
+
+
+ MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex)
+ :btTriangleRaycastCallback(from,to),
+ m_ignorePart(ignorePart),
+ m_ignoreTriangleIndex(ignoreTriangleIndex)
+ {
+
+ }
+ virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
+ {
+ if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex)
+ {
+ if (hitFraction < m_hitFraction)
+ return hitFraction;
+ }
+
+ return m_hitFraction;
+ }
+ };
+ struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback
+ {
+ const btGImpactMeshShape* m_gimpactShape;
+ btCompoundShape* m_colShape;
+ btScalar m_depth;
+
+ MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth)
+ :m_colShape(colShape),
+ m_gimpactShape(meshShape),
+ m_depth(depth)
+ {
+ }
+
+ virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
+ {
+ btVector3 scale = m_gimpactShape->getLocalScaling();
+ btVector3 v0=triangle[0]*scale;
+ btVector3 v1=triangle[1]*scale;
+ btVector3 v2=triangle[2]*scale;
+
+ btVector3 centroid = (v0+v1+v2)/3;
+ btVector3 normal = (v1-v0).cross(v2-v0);
+ normal.normalize();
+ btVector3 rayFrom = centroid;
+ btVector3 rayTo = centroid-normal*m_depth;
+
+ MyCallback cb(rayFrom,rayTo,partId,triangleIndex);
+
+ m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo);
+ if (cb.m_hitFraction<1)
+ {
+ rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction);
+ //rayTo = cb.m_from;
+ //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction);
+ //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0));
+ }
+
+
+
+
+ btConvexHullShape* tet = new btConvexHullShape();
+ tet->addPoint(v0);
+ tet->addPoint(v1);
+ tet->addPoint(v2);
+ tet->addPoint(rayTo);
+ btTransform ident;
+ ident.setIdentity();
+ m_colShape->addChildShape(ident,tet);
+ }
+ };
+
+btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth)
+{
+ btCompoundShape* colShape = new btCompoundShape();
+
+ btTransform tr;
+ tr.setIdentity();
+
+ MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth);
+ btVector3 aabbMin,aabbMax;
+ gimpactMesh->getAabb(tr,aabbMin,aabbMax);
+ gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax);
+
+ return colShape;
+}
+
+#endif //BT_COMPOUND_FROM_GIMPACT
\ No newline at end of file
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
index cd4dfdb..4528758 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
@@ -384,7 +384,7 @@ bool btGImpactQuantizedBvh::rayQuery(
SIMD_FORCE_INLINE bool _quantized_node_collision(
- btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1,
+ const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
int node0 ,int node1, bool complete_primitive_tests)
{
@@ -402,7 +402,7 @@ SIMD_FORCE_INLINE bool _quantized_node_collision(
//stackless recursive collision routine
static void _find_quantized_collision_pairs_recursive(
- btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1,
+ const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
btPairSet * collision_pairs,
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
int node0, int node1, bool complete_primitive_tests)
@@ -501,8 +501,8 @@ static void _find_quantized_collision_pairs_recursive(
}
-void btGImpactQuantizedBvh::find_collision(btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
- btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
+void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
+ const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
btPairSet & collision_pairs)
{
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
index 9c99077..e6e52ff 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
@@ -363,8 +363,8 @@ public:
static float getAverageTreeCollisionTime();
#endif //TRI_COLLISION_PROFILING
- static void find_collision(btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
- btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
+ static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
+ const btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
btPairSet & collision_pairs);
};
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
index cceace5..ac8efdf 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp
@@ -25,6 +25,7 @@ subject to the following restrictions:
#define CALC_EXACT_INERTIA 1
+
void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
lockChildShapes();
@@ -144,6 +145,31 @@ void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayT
{
}
+void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
+{
+ lockChildShapes();
+
+ btAlignedObjectArray<int> collided;
+ btVector3 rayDir(rayTo - rayFrom);
+ rayDir.normalize();
+ m_box_set.rayQuery(rayDir, rayFrom, collided);
+
+ if(collided.size()==0)
+ {
+ unlockChildShapes();
+ return;
+ }
+
+ int part = (int)getPart();
+ btPrimitiveTriangle triangle;
+ int i = collided.size();
+ while(i--)
+ {
+ getPrimitiveTriangle(collided[i],triangle);
+ callback->processTriangle(triangle.m_vertices,part,collided[i]);
+ }
+ unlockChildShapes();
+}
void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
@@ -182,6 +208,15 @@ void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const
}
}
+void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
+{
+ int i = m_mesh_parts.size();
+ while(i--)
+ {
+ m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
+ }
+}
+
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
index 90015bb..3d1f48d 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
@@ -51,6 +51,7 @@ enum eGIMPACT_SHAPE_TYPE
};
+
//! Helper class for tetrahedrons
class btTetrahedronShapeEx:public btBU_Simplex1to4
{
@@ -192,7 +193,7 @@ public:
virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ;
//! gets boxset
- SIMD_FORCE_INLINE btGImpactBoxSet * getBoxSet()
+ SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const
{
return &m_box_set;
}
@@ -288,6 +289,15 @@ public:
(void) callback; (void) aabbMin; (void) aabbMax;
}
+ //! Function for retrieve triangles.
+ /*!
+ It gives the triangles in local space
+ */
+ virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const
+ {
+
+ }
+
//!@}
};
@@ -635,25 +645,25 @@ public:
return (int )numverts;
}
- SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const
+ SIMD_FORCE_INLINE void get_indices(int face_index,unsigned int &i0,unsigned int &i1,unsigned int &i2) const
{
if(indicestype == PHY_SHORT)
{
- short * s_indices = (short *)(indexbase + face_index*indexstride);
+ unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride);
i0 = s_indices[0];
i1 = s_indices[1];
i2 = s_indices[2];
}
else
{
- int * i_indices = (int *)(indexbase + face_index*indexstride);
+ unsigned int * i_indices = (unsigned int *)(indexbase + face_index*indexstride);
i0 = i_indices[0];
i1 = i_indices[1];
i2 = i_indices[2];
}
}
- SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const
+ SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3 & vertex) const
{
if(type == PHY_DOUBLE)
{
@@ -682,7 +692,7 @@ public:
virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
{
- int indices[3];
+ unsigned int indices[3];
get_indices(prim_index,indices[0],indices[1],indices[2]);
get_vertex(indices[0],triangle.m_vertices[0]);
get_vertex(indices[1],triangle.m_vertices[1]);
@@ -692,7 +702,7 @@ public:
SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const
{
- int indices[3];
+ unsigned int indices[3];
get_indices(prim_index,indices[0],indices[1],indices[2]);
get_vertex(indices[0],triangle.m_vertices1[0]);
get_vertex(indices[1],triangle.m_vertices1[1]);
@@ -885,6 +895,7 @@ public:
}
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ virtual void processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const;
};
@@ -1141,6 +1152,8 @@ public:
*/
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ virtual void processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const;
+
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
diff --git a/extern/carve/patches/mingw_w64.patch b/extern/carve/patches/mingw_w64.patch
index 0e3881f..26a30be 100644
--- a/extern/carve/patches/mingw_w64.patch
+++ b/extern/carve/patches/mingw_w64.patch
@@ -1,8 +1,8 @@
-Index: bundle.sh
-===================================================================
---- bundle.sh (revision 45912)
-+++ bundle.sh (working copy)
-@@ -114,7 +114,7 @@
+Index: bundle.sh
+===================================================================
+--- bundle.sh (revision 45912)
++++ bundle.sh (working copy)
+@@ -114,7 +114,7 @@
if env['WITH_BF_BOOST']:
if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'):
# Boost is setting as preferred collections library in the Carve code when using MSVC compiler
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index ebc5953..a51f576 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -47,9 +47,9 @@ set(SRC
libmv/multiview/conditioning.cc
libmv/multiview/euclidean_resection.cc
libmv/multiview/fundamental.cc
+ libmv/multiview/homography.cc
libmv/multiview/projection.cc
libmv/multiview/triangulation.cc
- libmv/multiview/homography.cc
libmv/numeric/numeric.cc
libmv/numeric/poly.cc
libmv/simple_pipeline/bundle.cc
@@ -71,8 +71,8 @@ set(SRC
libmv/tracking/lmicklt_region_tracker.cc
libmv/tracking/pyramid_region_tracker.cc
libmv/tracking/retrack_region_tracker.cc
- libmv/tracking/trklt_region_tracker.cc
libmv/tracking/track_region.cc
+ libmv/tracking/trklt_region_tracker.cc
third_party/fast/fast_10.c
third_party/fast/fast_11.c
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
index 02b79c9..c52d545 100644
--- a/extern/libmv/ChangeLog
+++ b/extern/libmv/ChangeLog
@@ -1,3 +1,487 @@
+commit cfabdfe48df2add3d1f30cf4370efd0b31990ab0
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 20 05:46:53 2012 +0600
+
+ Assorted fixes for keyframe selection:
+
+ - Biggest error was in cost functors used for F and H refirement,
+ they were just wrong.
+
+ - Use natural logarithms, since it's actually makes sense from
+ math papers point of view and error is somewhere else.
+
+ - Disabled rho for GRIC, for now use non-clamped error for tests.
+
+ - Made SymmetricEpipolarDistance returning non-squared distance
+ Keyframe selection is currently the only used of this function
+ and it seems using non-squared distance makes much more sense.
+
+ Also would think to append suffix "Squared" to functions which
+ returns squared distances.
+
+ - Removed templated version of SymmetricEpipolarDistance, since
+ it's not needed actually.
+
+ This is actually even worse working than previous implementation,
+ but commit it needed for further review.
+
+commit 35d8c57626ad74818f155e6e5960c663ea84e032
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 20 03:00:40 2012 +0600
+
+ Euclidean resection cost function didn't use correct constructor
+
+ It was storing a reference to initial rotation passed by value,
+ leading to pointer being pointing to a stack variable, leading to
+ wrong memory access in residuals computing.
+
+ Apparently was visible in optimized builds only with inline
+ substitution allowed.
+
+commit 0798d3162bb49cee7e1c423ceccbca1326ad5650
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 20 02:50:52 2012 +0600
+
+ Automatic keyframe selection based on Pollefeys's criteria
+
+ This commit implements automatic keyframe selection algorithm
+ based on Pollefeys's criteria (F-GRIC is smaller than H-GRIC
+ and correspondence ratio is more then 90%).
+
+ It is implemented as a part of simple pipeline and returns
+ vector of keyframe images for a given Tracks structure.
+
+ For simple pipeline reconstruction two best keyframes are
+ expected to be selected from all detected candidates.
+ Criteria for this selection could be reprojection error of
+ solution from two candidate keyfames.
+
+ Unfortunately, it's not fully workable yet, hopefully would
+ be fixed soon.
+
+commit e943985552f0598ae122252876f305d72c25c2f9
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 17:47:11 2012 +0600
+
+ Camera Tracking: allow fallback to reprojection resection
+ by user demand
+
+ This fixes some "regressions" introduced in previous commit
+ which lead to much worse solution in some cases. Now it's
+ possible to bring old behavior back.
+
+ Perhaps it's more like temporal solution for time being smarter
+ solution is found. But finding such a solution isn't so fast,
+ so let's bring manual control over reprojection usage.
+
+ But anyway, imo it's now nice to have a structure which could
+ be used to pass different settings to the solver.
+
+commit 5a23d01dd531d1e0798298d17ba42a3397effb82
+Author: Keir Mierle <mierle at gmail.com>
+Date: Thu Sep 20 18:55:44 2012 +0000
+
+ Make Euclidean resection "always" succeed.
+
+ The Euclidean resection code had a magical constant, 1e-3, used to
+ compare the results of solving an equation. This failure detection
+ was well-intended, trying to prevent poor solutions from getting
+ made without notifying the caller. Unfortunately in practice, this
+ threshold is too conservative. Furthermore, it is not clear the
+ threshold should exist at all; the purpose of the Euclidean
+ resection is to come up with the best solution it can; other
+ methods (e.g. reprojection error) should be used to compare
+ whether the method succeeded.
+
+ This commit changes the Euclidean EPnP code to always succeed,
+ causing the previous fallback to projective resection to never
+ run. In most cases, this will result in better reconstructions.
+
+ This should, in most cases, fix the dreaded "flipping" problem.
+
+commit 57dad861d2a7f9d058c6d8edde1a2d51d7225a51
+Author: Keir Mierle <mierle at gmail.com>
+Date: Thu Sep 20 02:27:34 2012 +0000
+
+ Fix variable naming in the planar tracker.
+
+commit e9392fd3b46f5668662935696e7d9afac3390ca4
+Author: Keir Mierle <mierle at gmail.com>
+Date: Thu Sep 20 02:10:33 2012 +0000
+
+ Add smarter tolerance checking in the planar tracker.
+
+ The planar tracker uses Ceres for the refinement stage. During
+ refinement, Ceres iteratively updates the parameters with the
+ latest best guess. If the change in the parameters falls below a
+ threshold, Ceres will abort successfully ("converged").
+
+ For the case of pure translation tracking, the parameters are
+ exactly the two pixel shifts (dx, dy), and measuring the change in
+ these parameters gives a meaningful termination criterion.
+ However, for all the other parameterizations like affine, where
+ the parameterization involves affine parameters that have no
+ physical interpretation, Ceres is left with no way to terminate
+ the solver early. With the existing code, often many iterations
+ are run long after Ceres has found a solution sufficiently
+ accurate for all tracking needs. No one needs tracking with
+ a quadrillionth of a pixel accuracy; that time is wasted.
+
+ This patch extends the existing iteration callback that is passed
+ in to Ceres to check if the pattern has fallen out of the search
+ window, to also check if the optimizer has made a tiny step. In
+ particular, if the maximum shift of any patch corner between two
+ successful optimizer steps is less than a threshold (currently
+ 0.005 pixels), the track is declared successful and tracking
+ is terminated.
+
+ This leads to dramatic speed increases in some cases, with little
+ to no loss in track quality. This is especially apparent when
+ tracking patches with affine or perspective motion models. For
+ example, on some tracking cases I tried, the iterations Ceres took
+ went from 50 to 3.
+
+commit 36729c19bf90cb767e9adb96ba7dd48a5ace2be1
+Author: Keir Mierle <mierle at gmail.com>
+Date: Wed Sep 19 22:25:02 2012 +0000
+
+ Detect too-small planar tracking patches.
+
+ The planar tracker did not detect very skinny patches which have
+ effectively zero area and are untrackable. This adds detection and
+ rejection of patterns with zero area. This fixes a crash found by
+ during Mango production.
+
+commit 5cf2bae255a5a0f2e36ea0516670782cb88b589d
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 17:33:53 2012 +0600
+
+ Real fix for previous commit from Keir. He's comment;
+
+ Cleanup for when trackers fall out of the search window.
+
+ Sergey originally left a TODO() here, but his fix is the correct
+ one. I removed the TODO and fixed some comment issues.
+
+commit a11533918720e5b43dc1e95895db0eb36c8c06aa
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 17:31:16 2012 +0600
+
+ Fix crash when tracking in planar motion model (and maybe some other)
+
+ It was an Abort() caused by check for solver result not equal to USER_ABORT.
+
+ In some cases solver returns USER_ABORT due to BoundaryCheckingCallback
+ detects coordinates does not belong to image.
+
+ Somehow this callback wasn't called in previous version of Ceres and
+ in the same case marker was jumping. Now when the callback is called
+ it seems we could simply return failure of tracking without aborting
+ Blender.
+
+ Probably this is in fact some issue somewhere else, would double
+ check with Keir about this.
+
+commit 4be2306bcc664b259aaf7068b9f32ab60124a509
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 17:29:39 2012 +0600
+
+ Resolved some compilation warnings (missed prototypes)
+
+ In some cases it was missed include of header file, in some other
+ cases symbol could be static.
+
+commit bef729ba5c12683d13584d2a728b8b6506b7ca90
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 17:27:17 2012 +0600
+
+ Code cleanup: silence some -Wnarrowing warnings from C++11
+
+commit add1415d896818367087c784a3013dd8f1bb2095
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 17:25:18 2012 +0600
+
+ Changes to SamplePlanarPatch to support mask input and
+ added output for pattern center.
+
+commit daa354c0735b954b0cd7725626e9a3d67416d46b
+Author: Keir Mierle <mierle at gmail.com>
+Date: Sat Jun 9 19:22:39 2012 +0000
+
+ Change libmv's bilinear sampling to assume the same
+ pixel conventions as Blender. This fixes the preview
+ widget in Blender, and should make tracking slightly
+ more accurate.
+
+commit 99b6222873fbfbe248316316956720376a58f438
+Author: Keir Mierle <mierle at gmail.com>
+Date: Sat Jun 9 18:58:51 2012 +0000
+
+ Add new warp regularization scheme for planar tracking.
+
+ This adds a new term to the tracking cost function that
+ restricts how much the optimizer can warp the patch (as
+ opposed to merely adjusting the translation). This should
+ reduce the "jumpiness" that is sometimes seen when doing
+ non-"Loc" tracks.
+
+ It is disabled in this commit; a subsequent commit will add
+ controls to the tracking dialog for this.
+
+commit a1c5a70badd11cba0470700bad2eac2b2bd30c86
+Author: Keir Mierle <mierle at gmail.com>
+Date: Sat Jun 9 06:55:21 2012 +0000
+
+ Planar tracker polish.
+
+ - Fixes the correlation checking code that was broken in the
+ previous commit. The bug was a transpose error.
+ - Fixes a memory leak of the warp functor, found by Sameer.
+ - Various cleanups done at Sameer's suggestion.
+
+ Thanks to Sameer Agarwal for a code review.
+
+commit 2cb784caa854a77cdd43620ab133f26b87ed0d83
+Author: Keir Mierle <mierle at gmail.com>
+Date: Fri Jun 8 17:42:17 2012 +0000
+
+ Make planar tracking much faster.
+
+ - This makes planar tracking around 2-3x or more faster than
+ before, by rearranging how the sampling is done.
+ Previously, the source patch was sampled repeatedly on
+ every optimizer iteration; this was done for
+ implementation speed, but was wasteful in computation.
+
+ - This also contains some additions to Ceres to help
+ deailing with mixed numeric / automatic differentation. In
+ particular, there is now a "Chain::Rule" operator that
+ facilitates calling a function that takes Jet arguments,
+ yet does numeric derivatives internally. This is used to
+ mix the numeric differentation of the images with the warp
+ parameters, passed as jets by Ceres to the warp functor.
+
+ There is also a new "JetOps" object for doing operations
+ on types which may or may not be jets, such as scaling
+ the derivative part only, or extracting the scalar part
+ of a jet.
+
+ This patche is aimed at Ceres upstream.
+
+ - A new function for sampling a patch is now part of the
+ track_region.h API; this will get used to make the preview
+ widget properly show what is getting tracked. Currently
+ the preview widget does not handle perspective tracks.
+
+ Known issues:
+
+ This patch introduces a bug such that the "Minimum
+ Correlation" flag does not work; if it is enabled, tracking
+ aborts immediately. The workaround for now is to disable the
+ correlation checking, and examine your tracks carefully. A
+ fix will get added shortly.
+
+commit 81d028f13738ebe2304287dfce90e91bc782e2cf
+Author: Keir Mierle <mierle at gmail.com>
+Date: Fri May 18 20:04:43 2012 +0000
+
+ Remove an unnecessary template<> line in libmv. Convert debug logs to LG.
+
+commit 238aaba241ef99995d254aadc974db719da04b96
+Author: Keir Mierle <mierle at gmail.com>
+Date: Fri May 18 12:05:10 2012 +0000
+
+ Support normalization in the tracking prepass
+
+ The last tracker commit added normalized tracking. This makes
+ tracking patches undergoing uniform illumination change easier.
+ However, the prepass which computes a quick translation-only
+ estimate of the warp did not take this into account. This commit
+ fixes that.
+
+ This works reasonably well but in some examples the brute
+ initialization fails. I suspect this is due to the warped template
+ estimate in the current frame being too different from the
+ original, so there are multiple peaks in the normalized-SAD
+ correlation function.
+
+ The solution is to use the previous frame for the brute
+ initialization and the keyframe for refinement, but that requires
+ architecture changes.
+
+commit 981ca4f6a679cd9ac3d086eae3cd946ce72ca8a5
+Author: Keir Mierle <mierle at gmail.com>
+Date: Fri May 18 02:12:47 2012 +0000
+
+ Add light-normalized tracking to the planar tracker
+
+ This commit adds the ability to normalize patterns by their
+ average value while tracking, to make them invariant to global
+ illumination changes.
+
+ To see this in action, check out the "Lobby" scene from Hollywood
+ VFX. If you track the markers that are shadowed by the actress,
+ previously they would not track. With the scale adaption on, the
+ tracker would shrink the area to compensate for the changed
+ illumination, losing the track. With "Normalize" turned on, the
+ patch is correctly tracked and scale is maintained.
+
+ A remaining problem is that only the Ceres cost function is
+ updated to handle the normalization. The brute translation search
+ does not take this into account. Perhaps "Prepass" (see below)
+ should get disabled if normalization is enabled until I fix the
+ prepass to normalize as well.
+
+ There are a few other changes:
+
+ - Bail out of the sampling loop early if the mask is zero; this
+ saves expensive samples of the image derivatives.
+
+ - Fix a bug where the mask was ignored when sampling in the cost
+ functor.
+
+commit e9384b15fb2a6a5b81346d5758fa136f0911e945
+Author: Keir Mierle <mierle at gmail.com>
+Date: Thu May 17 23:53:32 2012 +0000
+
+ Implement support for affine tracking in the planar tracker; cleanups.
+
+commit 021d41eed8b4ce6a4e37786ccd357ed5dc83a13f
+Author: Keir Mierle <mierle at gmail.com>
+Date: Thu May 17 21:26:06 2012 +0000
+
+ For the planar tracker, initialize the warp from the four correspondences
+ after brute force translation search.
+
+commit 003d1bf6145cfd30938b35f6e10d43708dbf916c
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 16:56:01 2012 +0600
+
+ Correction to region tracker options initialization.
+
+ Based on patch from Keir to Blender:
+ https://svn.blender.org/svnroot/bf-blender/branches/soc-2011-tomato@46743
+
+commit 6af47b218cfdf5219f0ebb3cb95459817cf9abf2
+Author: Keir Mierle <mierle at gmail.com>
+Date: Thu May 17 02:31:52 2012 +0000
+
+ Add new planar tracker features and use the new planar API
+
+ This commit removes the use of the legacy RegionTracker API from
+ Blender, and replaces it with the new TrackRegion API. This also
+ adds several features to the planar tracker in libmv:
+
+ - Do a brute-force initialization of tracking similar to "Hybrid"
+ mode in the stable release, but using all floats. This is slower
+ but more accurate. It is still necessary to evaluate if the
+ performance loss is worth it. In particular, this change is
+ necessary to support high bit depth imagery.
+
+ - Add support for masks over the search window. This is a step
+ towards supporting user-defined tracker masks. The tracker masks
+ will make it easy for users to make a mask for e.g. a ball.
+
+ - Add Pearson product moment correlation coefficient checking (aka
+ "Correlation" in the UI. This causes tracking failure if the
+ tracked patch is not linearly related to the template.
+
+ - Add support for warping a few points in addition to the supplied
+ points. This is useful because the tracking code deliberately
+ does not expose the underlying warp representation. Instead,
+ warps are specified in an aparametric way via the correspondences.
+
+ - Remove the "num_samples_xy" concept and replace it with
+ automatic determination of the number of samples. This makes the
+ API easier for users.
+
+ - Fix various bugs in the parameterizations.
+
+ There remains a bug with subpixel precision tracking when in
+ "keyframe" mode; this will get fixed shortly.
+
+commit 16a46db104468cec80bd31ca9d5f8bffbe3e003e
+Author: Keir Mierle <mierle at gmail.com>
+Date: Mon May 14 12:15:38 2012 +0000
+
+ "Efficient Second-order Minimization" for the planar tracker
+
+ This implements the "Efficient Second-order Minimization"
+ scheme, as supported by the existing translation tracker.
+ This increases the amount of per-iteration work, but
+ decreases the number of iterations required to converge and
+ also increases the size of the basin of attraction for the
+ optimization.
+
+commit 23243b1b1f3e1ab3ef862b47bca06ee876ac2cf4
+Author: Keir Mierle <mierle at gmail.com>
+Date: Sun May 13 23:08:56 2012 +0000
+
+ Add a planar tracking implementation to libmv
+
+ This adds a new planar tracking implementation to libmv. The
+ tracker is based on Ceres[1], the new nonlinear minimizer that
+ myself and Sameer released from Google as open source. Since
+ the motion model is more involved, the interface is
+ different than the RegionTracker interface used previously
+ in Blender.
+
+ The ESM tracker, also known as the KLT tracker in the UI, is
+ temporarily changed to use the new Ceres-based planar
+ tracker in translation-only mode. Currently it is a bit
+ slower than ESM and also doesn't have all the bells and
+ whistles implemented. Those will come soon. Longer term,
+ both trackers will remain since Ceres is unlikely to be as
+ fast as ESM for pure translation solving, due to its
+ generality.
+
+ The next step is to implement a new tracking UI. The current
+ UI assumes a translational motion model; the new one must
+ support arbitrary perspective transforms of the pattern
+ regions.
+
+ [1] http://code.google.com/p/ceres-solver
+
+commit 52be92b53eb4decb1a316690b162196f227cc441
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Thu Dec 6 16:06:08 2012 +0600
+
+ Initial Ceres integration
+
+ Currently only put sources to src/third_party/ceres and made sure they're
+ not giving compilation issues.
+
+ Used Ceres upstream version 1.3.0.
+
+ Needed to make some modifications to it's CMakeLists.txt also to glog and
+ fglags. They're described in README.libmv of this libraries.
+
+ Basically:
+
+ - Added -fPIC to glog/gflags, so shared ceres library could be linked
+ statically against this libraries.
+
+ - Tweaked Ceres's build rules to use needed libraries from libmv's
+ third_party folder.
+
+commit b13f9d13122e091cb85855c2094386ccdef6e5a4
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Wed Dec 5 19:05:34 2012 +0600
+
+ Update Eigen to version 3.1.2
+
+ Mainly because of lots of warnings generating by gcc-4.7 which are
+ resolved in newer eigen version.
+
+commit 1f0dd94e8e37d3fe2df89282ec16a6a685fdde0b
+Author: Sergey Sharybin <sergey.vfx at gmail.com>
+Date: Fri May 25 16:36:44 2012 +0600
+
+ - Added avutil to qt-tracker linking when building with FFmpeg support.
+ On some platforms it seems to be required
+ - Synchronized QT Creator project for qt-tracker with changes in sources,
+ so no it might be compiled from QT Creator.
+
commit b813dbe3f46bbbc7e73ac791d4665622e4fc7ba5
Author: Sergey Sharybin <sergey.vfx at gmail.com>
Date: Wed May 9 19:01:10 2012 +0600
@@ -238,319 +722,3 @@ Date: Fri Feb 17 20:08:01 2012 +0600
SAD tracker now can deal with pattern size any size,
Very quick implementation came from Blender before Hybrid tracker was added.
Better to be replaced with brute tracker.
-
-commit d547c9cfe37d5d3397d33c8b0e58471e1e1c1634
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 20:03:52 2012 +0600
-
- Just convert end of lines to unix style.
-
-commit eb73ddbaec5b9e1ad30331bbf858a6ebc266c4aa
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 20:02:20 2012 +0600
-
- Made some function static. Resolves possible linking issues when building with MinGW.
-
-commit 2930681fafd86e4f4a958054b1db8bfff29623d1
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 19:59:45 2012 +0600
-
- Missed this in commit with improvements in camera intrinsics.
-
-commit 8d31bc767019b05c5bf8c9f309f9545b3428afa1
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 19:57:51 2012 +0600
-
- Another step of syncing codebase with Blender.
- Mainly fixes for freebsd/osx compilation and aligned memory allocation.
-
-commit 3214a2df5bfd98021f25d0f1a626a86318bb245f
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 19:48:02 2012 +0600
-
- Support compilation on FreeBSD platform
-
-commit 0e5abe96f543687ccfb3a923ec639cb8f45d54f8
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 19:44:18 2012 +0600
-
- Implementation of basic system for progress reporting into callee stuff
-
- Implemented by using simple callbacks classes which are getting invoked from
- places where lots of calculation happens, so applications which are using
- libmv may display nice progress bar.
-
-commit c5e18fe35464618055e0e9761be8d22fae56db49
-Author: Keir Mierle <mierle at gmail.com>
-Date: Fri Feb 17 19:25:45 2012 +0600
-
- Add support for detecting tracking failure in the ESM tracker component of
- libmv. Since both KLT and Hybrid rely on ESM underneath, KLT and Hybrid now
- have a minimum correlation setting to match. With this fix, track failures
- should get detected quicker, with the issue that sometimes the tracker will
- give up too easily. That is fixable by reducing the required correlation (in
- the track properties).
-
-commit ea0fed736ecdcc8c020227aeef8ef4cd3be5e63d
-Author: Keir Mierle <mierle at gmail.com>
-Date: Fri Feb 17 19:23:50 2012 +0600
-
- Add a new hybrid region tracker for motion tracking to libmv, and
- add it as an option (under "Hybrid") in the tracking settings. The
- region tracker is a combination of brute force tracking for coarse
- alignment, then refinement with the ESM/KLT algorithm already in
- libmv that gives excellent subpixel precision (typically 1/50'th
- of a pixel)
-
- This also adds a new "brute force" region tracker which does a
- brute force search through every pixel position in the destination
- for the pattern in the first frame. It leverages SSE if available,
- similar to the SAD tracker, to do this quickly. Currently it does
- some unnecessary conversions to/from floating point that will get
- fixed later.
-
- The hybrid tracker glues the two trackers (brute & ESM) together
- to get an overall better tracker. The algorithm is simple:
-
- 1. Track from frame 1 to frame 2 with the brute force tracker.
- This tries every possible pixel position for the pattern from
- frame 1 in frame 2. The position with the smallest
- sum-of-absolute-differences is chosen. By definition, this
- position is only accurate up to 1 pixel or so.
- 2. Using the result from 1, initialize a track with ESM. This does
- a least-squares fit with subpixel precision.
- 3. If the ESM shift was more than 2 pixels, report failure.
- 4. If the ESM track shifted less than 2 pixels, then the track is
- good and we're done. The rationale here is that if the
- refinement stage shifts more than 1 pixel, then the brute force
- result likely found some random position that's not a good fit.
-
-commit a07fff8431621c01d81ae52595d8dd91a295a776
-Author: Keir Mierle <mierle at gmail.com>
-Date: Fri Feb 17 19:19:58 2012 +0600
-
- Assorted camera tracker improvements
-
- - Add support for refining the camera's intrinsic parameters
- during a solve. Currently, refining supports only the following
- combinations of intrinsic parameters:
-
- f
- f, cx, cy
- f, cx, cy, k1, k2
- f, k1
- f, k1, k2
-
- This is not the same as autocalibration, since the user must
- still make a reasonable initial guess about the focal length and
- other parameters, whereas true autocalibration would eliminate
- the need for the user specify intrinsic parameters at all.
-
- However, the solver works well with only rough guesses for the
- focal length, so perhaps full autocalibation is not that
- important.
-
- Adding support for the last two combinations, (f, k1) and (f,
- k1, k2) required changes to the library libmv depends on for
- bundle adjustment, SSBA. These changes should get ported
- upstream not just to libmv but to SSBA as well.
-
- - Improved the region of convergence for bundle adjustment by
- increasing the number of Levenberg-Marquardt iterations from 50
- to 500. This way, the solver is able to crawl out of the bad
- local minima it gets stuck in when changing from, for example,
- bundling k1 and k2 to just k1 and resetting k2 to 0.
-
- - Add several new region tracker implementations. A region tracker
- is a libmv concept, which refers to tracking a template image
- pattern through frames. The impact to end users is that tracking
- should "just work better". I am reserving a more detailed
- writeup, and maybe a paper, for later.
-
- - Other libmv tweaks, such as detecting that a tracker is headed
- outside of the image bounds.
-
- This includes several changes made directly to the libmv extern
- code rather expecting to get those changes through normal libmv
- channels, because I, the libmv BDFL, decided it was faster to work
- on libmv directly in Blender, then later reverse-port the libmv
- changes from Blender back into libmv trunk. The interesting part
- is that I added a full Levenberg-Marquardt loop to the region
- tracking code, which should lead to a more stable solutions. I
- also added a hacky implementation of "Efficient Second-Order
- Minimization" for tracking, which works nicely. A more detailed
- quantitative evaluation will follow.
-
-commit 0bf66c009d5022eacfc473d247884a73ffeefa8f
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 19:13:49 2012 +0600
-
- Rest of compilation fix with FAST library.
-
-commit 71b578ca2ba34c528363c514cd1fcc85791d01f3
-Author: Keir Mierle <mierle at gmail.com>
-Date: Fri Feb 17 19:00:28 2012 +0600
-
- Improve the KLT tracking behaviour and UI
-
- - Remove the overly-conservative use of libmv's re-track tracker. The re-track
- tracker would take a normal tracker such as TRKLT or KLT or pyramid KLT, and
- track from frame 1 to 2, then back from the position found in 2 back to 1.
- Then, when the reverse-track doesn't match the original track with high
- precision, the track is considered "failed". This is a good approach for
- fully automatic reconstruction, but is too conservative for supervised
- tracking.
-
- The retrack-tracker will return when fully automatic tracking is added.
-
- - Always solve for (dx, dy) in the TRKLT loop even if the linear system is
- ill-conditioned. The client (Blender in this case) can still use the solved
- position, even though it is less reliable.
-
-commit 7d8a8762f2bc2e36f95b0b6f4fb4ca996f9f0db7
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 18:46:24 2012 +0600
-
- Changes in camera intrinsics distortion/undistortion:
-
- - Distortion/undistortion of scaled images wasn't happening right,
- because camera intrinsics are calibrated on an original frame which
- has got some particular resolution and trying to apply this model on
- an image with another resolution gives totally wrong result.
- This is needed to be able to do post-prccessing of render, running
- distortion on a scene which might be rendered with higher resolution
- than footage itself and then be scaled down.
- - Fixed incorrect calculation/applying of precomputed grid when
- distortion is high high enough and produces pixel offset higher
- than 127 pixels. This might be still not very distorted image,
- but if it's a 4K footage "normal" camera will easily give such
- a distortion.
- - Added support of overscan distortion/undistortion.
-
-commit ed080785d63bb8e3a13dde51a2dc94fe59b059bb
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 18:38:51 2012 +0600
-
- Fast headers now can be included from C++ sources.
- Was needed to make it working fine when bundling in Blender but might also
- be needed to bundle into another applications.
-
-commit 5f5a7aa46a2d87b96c8098dfc8682f4d01b5cd40
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 18:36:16 2012 +0600
-
- Bring back FAST detector which seems to be working much nicer than Morravec.
- Both of them are available in API.
-
-commit 2cab13c18216fb684b270cec077f7300262584af
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 18:27:36 2012 +0600
-
- Revert "Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv."
-
- This reverts commit 81613ee0cc94b315f333c9632b18b95d426aad05.
-
- That commit made inverting intrinsics totally unworkable, so reverted this and
- made needed tweaks to qt-tracker project file to make it compilable (was needed
- to make it linking together with glog).
-
- Conflicts:
-
- src/ui/tracker/tracker.cc
- src/ui/tracker/tracker.pro
-
-commit ec46cae041401b17afb4fe4d9c9343d10797090f
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 17:59:55 2012 +0600
-
- Fix compilation error using official MinGW
-
-commit 6fbc370e922c47cfa35381662b6c439f4891ed74
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 17:38:20 2012 +0600
-
- Fix compilation error with MSVC 2010 which is more picky for "missed" STL headers
-
-commit be9e6b63691d83b551a085f0766878bd84220767
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 17:36:18 2012 +0600
-
- Fix compilation with MSVC where snprintf function is declared as unsafe and _snprintf should be used instead.
-
- Better to switch to own implementation will ensure string is correctly NULL-terminated.
-
-commit 1847d9e414ed763cd80668775d7d9f79575fc8ca
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 17:34:45 2012 +0600
-
- Fix compilation error on OSX caused by incorrect access to ucontext
-
-commit 90579b6ffad07672172a1c240499615b30b25549
-Merge: b9aac30 531c79b
-Author: Sergey Sharybin <sergey.vfx at gmail.com>
-Date: Fri Feb 17 18:32:52 2012 +0600
-
- Merge remote-tracking branch 'Matthias-Fauconneau/master' into devel
-
- Conflicts:
- src/libmv/tracking/CMakeLists.txt
-
-commit b9aac30a9ca6bc8362c09a0e191040964f7c6de2
-Merge: 198894e 6969e1a
-Author: Keir Mierle <mierle at gmail.com>
-Date: Sat Nov 5 17:38:30 2011 -0700
-
- Merge pull request #3 from nathanwiegand/master
-
- Just a few tiny cleanups
-
-commit 6969e1a9534291a982749baa5a3672c97bfa506d
-Author: Nathan Wiegand <nathanwiegand at gmail.com>
-Date: Sat Nov 5 14:26:54 2011 -0700
-
- I've added cleaned up a few style issues here an there. Also, I've updated the CMakeLists.txt file so that it can build the image_io library. Note, it's only been tested on OSX 10.6
-
-commit 4763f851299050140757bfaa069107a0cf639e56
-Author: Nathan Wiegand <nathanwiegand at gmail.com>
-Date: Fri Nov 4 23:59:08 2011 -0700
-
- Removed a superfulous comment
-
-commit a44577c0162e273681e4a9a3cc5f5b37d4315b67
-Author: Nathan Wiegand <nathanwiegand at gmail.com>
-Date: Fri Nov 4 23:55:52 2011 -0700
-
- Removed a duplicate entry for an author.
-
-commit 198894e4c4f51c2c1784ad7c02eb45d2d1ada9bc
-Merge: c4c67db 6e797d6
-Author: Keir Mierle <mierle at gmail.com>
-Date: Fri Nov 4 21:47:05 2011 -0700
-
- Merge pull request #2 from nathanwiegand/master
-
- CMake changes for OSX
-
-commit 6e797d678c4c19f6a9e21657d66183f412cc995b
-Author: Nathan Wiegand <nathanwiegand at gmail.com>
-Date: Fri Nov 4 21:43:28 2011 -0700
-
- Uncomment the GUI part of the CMake file
-
-commit 33ef88a33860345d8906f3c9dd22d8dbce3df53e
-Author: Nathan Wiegand <nathanwiegand at gmail.com>
-Date: Fri Nov 4 21:31:22 2011 -0700
-
- Fixed build error on OSX by adding 'glog' to the dependencies in the tracker CMake
-
-commit 531c79bf95fddaaa70707d1abcd4fdafda16bbf0
-Author: Matthias Fauconneau <matthias.fauconneau at gmail.com>
-Date: Sat Aug 20 00:00:42 2011 +0200
-
- Display warped pattern in marker preview.
-
-commit bb5c27e671b6f8eb56ddf490f0795d59bede591b
-Author: Matthias Fauconneau <matthias.fauconneau at gmail.com>
-Date: Fri Aug 19 18:37:48 2011 +0200
-
- Fix CMake build.
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
index 1e386ec..23e90fc 100755
--- a/extern/libmv/bundle.sh
+++ b/extern/libmv/bundle.sh
@@ -136,19 +136,6 @@ set(INC_SYS
\${ZLIB_INCLUDE_DIRS}
)
-
-# XXX - FIXME
-# this is a momentary hack to find unwind.h in 10.6.sdk
-if(APPLE)
- if(\${CMAKE_OSX_DEPLOYMENT_TARGET} STREQUAL "10.6")
- list(APPEND INC_SYS
- \${CMAKE_OSX_SYSROOT}/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include
- )
- endif()
-endif()
-# XXX - END
-
-
set(SRC
libmv-capi.cpp
${sources}
diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt
index 85d09ce..22c5226 100644
--- a/extern/libmv/files.txt
+++ b/extern/libmv/files.txt
@@ -17,6 +17,9 @@ libmv/multiview/euclidean_resection.cc
libmv/multiview/euclidean_resection.h
libmv/multiview/fundamental.cc
libmv/multiview/fundamental.h
+libmv/multiview/homography.cc
+libmv/multiview/homography.h
+libmv/multiview/homography_parameterization.h
libmv/multiview/nviewtriangulation.h
libmv/multiview/projection.cc
libmv/multiview/projection.h
@@ -69,6 +72,8 @@ libmv/tracking/pyramid_region_tracker.h
libmv/tracking/region_tracker.h
libmv/tracking/retrack_region_tracker.cc
libmv/tracking/retrack_region_tracker.h
+libmv/tracking/track_region.cc
+libmv/tracking/track_region.h
libmv/tracking/trklt_region_tracker.cc
libmv/tracking/trklt_region_tracker.h
third_party/fast/fast_10.c
diff --git a/extern/libmv/libmv/multiview/fundamental.cc b/extern/libmv/libmv/multiview/fundamental.cc
index 80f155e..12a611c 100644
--- a/extern/libmv/libmv/multiview/fundamental.cc
+++ b/extern/libmv/libmv/multiview/fundamental.cc
@@ -254,8 +254,8 @@ double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) {
Vec3 Ft_y = F.transpose() * y;
double y_F_x = y.dot(F_x);
- return Square(y_F_x) * ( 1 / F_x.head<2>().squaredNorm()
- + 1 / Ft_y.head<2>().squaredNorm());
+ return y_F_x * ( 1 / F_x.head<2>().norm()
+ + 1 / Ft_y.head<2>().norm());
}
// HZ 9.6 pag 257 (formula 9.12)
diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
index 9c06d1e..84d143b 100644
--- a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
+++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
@@ -31,22 +31,6 @@
namespace libmv {
namespace {
-void CoordinatesForMarkersInImage(const vector<Marker> &markers,
- int image,
- Mat *coordinates) {
- vector<Vec2> coords;
- for (int i = 0; i < markers.size(); ++i) {
- const Marker &marker = markers[i];
- if (markers[i].image == image) {
- coords.push_back(Vec2(marker.x, marker.y));
- }
- }
- coordinates->resize(2, coords.size());
- for (int i = 0; i < coords.size(); i++) {
- coordinates->col(i) = coords[i];
- }
-}
-
void GetImagesInMarkers(const vector<Marker> &markers,
int *image1, int *image2) {
if (markers.size() < 2) {
diff --git a/extern/libmv/libmv/simple_pipeline/tracks.cc b/extern/libmv/libmv/simple_pipeline/tracks.cc
index 3fb8ddb..620f6fc 100644
--- a/extern/libmv/libmv/simple_pipeline/tracks.cc
+++ b/extern/libmv/libmv/simple_pipeline/tracks.cc
@@ -72,6 +72,16 @@ vector<Marker> Tracks::MarkersForTrack(int track) const {
return markers;
}
+vector<Marker> Tracks::MarkersInBothImages(int image1, int image2) const {
+ vector<Marker> markers;
+ for (int i = 0; i < markers_.size(); ++i) {
+ int image = markers_[i].image;
+ if (image == image1 || image == image2)
+ markers.push_back(markers_[i]);
+ }
+ return markers;
+}
+
vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, int image2) const {
std::vector<int> image1_tracks;
std::vector<int> image2_tracks;
@@ -156,4 +166,20 @@ int Tracks::NumMarkers() const {
return markers_.size();
}
+void CoordinatesForMarkersInImage(const vector<Marker> &markers,
+ int image,
+ Mat *coordinates) {
+ vector<Vec2> coords;
+ for (int i = 0; i < markers.size(); ++i) {
+ const Marker &marker = markers[i];
+ if (markers[i].image == image) {
+ coords.push_back(Vec2(marker.x, marker.y));
+ }
+ }
+ coordinates->resize(2, coords.size());
+ for (int i = 0; i < coords.size(); i++) {
+ coordinates->col(i) = coords[i];
+ }
+}
+
} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/tracks.h b/extern/libmv/libmv/simple_pipeline/tracks.h
index aa0fbaa..f9af3ad 100644
--- a/extern/libmv/libmv/simple_pipeline/tracks.h
+++ b/extern/libmv/libmv/simple_pipeline/tracks.h
@@ -22,6 +22,7 @@
#define LIBMV_SIMPLE_PIPELINE_TRACKS_H_
#include "libmv/base/vector.h"
+#include "libmv/numeric/numeric.h"
namespace libmv {
@@ -84,6 +85,9 @@ class Tracks {
/// Returns all the markers visible in \a image.
vector<Marker> MarkersInImage(int image) const;
+ /// Returns all the markers visible in \a image1 and \a image2.
+ vector<Marker> MarkersInBothImages(int image1, int image2) const;
+
/*!
Returns the markers in \a image1 and \a image2 which have a common track.
@@ -114,6 +118,10 @@ class Tracks {
vector<Marker> markers_;
};
+void CoordinatesForMarkersInImage(const vector<Marker> &markers,
+ int image,
+ Mat *coordinates);
+
} // namespace libmv
#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_
diff --git a/extern/libmv/third_party/gflags/README.libmv b/extern/libmv/third_party/gflags/README.libmv
index 673099c..b310c57 100644
--- a/extern/libmv/third_party/gflags/README.libmv
+++ b/extern/libmv/third_party/gflags/README.libmv
@@ -11,4 +11,6 @@ Local modifications:
- Added a poor-man's version of upstream's port.cc/h to make gflags compile on
windows. This isn't sufficient but is a stopgap for now.
+- Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
+
TODO(keir): Import and use gflags for Windows from upstream.
diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv
index 025a70b..345bc9f 100644
--- a/extern/libmv/third_party/glog/README.libmv
+++ b/extern/libmv/third_party/glog/README.libmv
@@ -22,3 +22,4 @@ Upgrading Notes
* Do not define va_copy for MinGW platforms (it's already defined there).
* Patch localtime_r to be working fine with MinGW, disable strerror_r for MinGW because
of lack of needed functions.
+* Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
diff --git a/extern/libopenjpeg/patches/osx.patch b/extern/libopenjpeg/patches/osx.patch
index 78894c2..c518978 100644
--- a/extern/libopenjpeg/patches/osx.patch
+++ b/extern/libopenjpeg/patches/osx.patch
@@ -3,15 +3,15 @@ Index: opj_malloc.h
--- opj_malloc.h (revision 15089)
+++ opj_malloc.h (working copy)
@@ -76,8 +76,10 @@
- #if defined(__sun)
- #define HAVE_MEMALIGN
- #elif defined(__GNUC__)
-- #define HAVE_MEMALIGN
-- #include <malloc.h>
-+ #ifndef __APPLE__
-+ #define HAVE_MEMALIGN
-+ #include <malloc.h>
-+ #endif
- /* Linux x86_64 and OSX always align allocations to 16 bytes */
- #elif !defined(__amd64__) && !defined(__APPLE__)
- /* FIXME: Yes, this is a big assumption */
+ #if defined(__sun)
+ #define HAVE_MEMALIGN
+ #elif defined(__GNUC__)
+- #define HAVE_MEMALIGN
+- #include <malloc.h>
++ #ifndef __APPLE__
++ #define HAVE_MEMALIGN
++ #include <malloc.h>
++ #endif
+ /* Linux x86_64 and OSX always align allocations to 16 bytes */
+ #elif !defined(__amd64__) && !defined(__APPLE__)
+ /* FIXME: Yes, this is a big assumption */
diff --git a/extern/rangetree/CMakeLists.txt b/extern/rangetree/CMakeLists.txt
new file mode 100644
index 0000000..ba68223
--- /dev/null
+++ b/extern/rangetree/CMakeLists.txt
@@ -0,0 +1,31 @@
+# ***** 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 LICENSE BLOCK *****
+
+set(INC
+ .
+)
+
+set(SRC
+ range_tree.hh
+ range_tree_c_api.h
+
+ range_tree_c_api.cc
+)
+
+blender_add_lib(extern_rangetree "${SRC}" "${INC}" "")
+
diff --git a/extern/rangetree/README.org b/extern/rangetree/README.org
new file mode 100644
index 0000000..46a4ced
--- /dev/null
+++ b/extern/rangetree/README.org
@@ -0,0 +1,13 @@
+* Overview
+ Basic class for storing non-overlapping scalar ranges. Underlying
+ representation is a C++ STL set for fast lookups.
+
+* License
+ GPL version 2 or later (see COPYING)
+
+* Author Note
+ This implementation is intended for storing free unique IDs in a new
+ undo system for BMesh in Blender, but could be useful elsewhere.
+
+* Website
+ https://github.com/nicholasbishop/RangeTree
diff --git a/extern/rangetree/SConscript b/extern/rangetree/SConscript
new file mode 100644
index 0000000..787decd
--- /dev/null
+++ b/extern/rangetree/SConscript
@@ -0,0 +1,9 @@
+2#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('*.cc')
+
+incs = '.'
+defs = ''
+
+env.BlenderLib ('extern_rangetree', sources, Split(incs), Split(defs), libtype=['extern'], priority=[100] )
diff --git a/extern/rangetree/range_tree.hh b/extern/rangetree/range_tree.hh
new file mode 100644
index 0000000..2a47c5a
--- /dev/null
+++ b/extern/rangetree/range_tree.hh
@@ -0,0 +1,228 @@
+/* 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.
+*/
+
+#include <cassert>
+#include <climits>
+#include <iostream>
+#include <set>
+
+#ifndef RANGE_TREE_DEBUG_PRINT_FUNCTION
+# define RANGE_TREE_DEBUG_PRINT_FUNCTION 0
+#endif
+
+template <typename T>
+struct RangeTree {
+ struct Range {
+ Range(T min_, T max_)
+ : min(min_), max(max_), single(min_ == max_) {
+ assert(min_ <= max_);
+ }
+
+ Range(T t)
+ : min(t), max(t), single(true)
+ {}
+
+ bool operator<(const Range& v) const {
+ return max < v.min;
+ }
+
+ const T min;
+ const T max;
+ const bool single;
+ };
+
+ typedef std::set<Range> Tree;
+ typedef typename Tree::iterator TreeIter;
+ typedef typename Tree::reverse_iterator TreeIterReverse;
+ typedef typename Tree::const_iterator TreeIterConst;
+
+ /* Initialize with a single range from 'min' to 'max', inclusive. */
+ RangeTree(T min, T max) {
+ tree.insert(Range(min, max));
+ }
+
+ /* Initialize with a single range from 0 to 'max', inclusive. */
+ RangeTree(T max) {
+ tree.insert(Range(0, max));
+ }
+
+ RangeTree(const RangeTree<T>& src) {
+ tree = src.tree;
+ }
+
+ /* Remove 't' from the associated range in the tree. Precondition:
+ a range including 't' must exist in the tree. */
+ void take(T t) {
+ #if RANGE_TREE_DEBUG_PRINT_FUNCTION
+ std::cout << __func__ << "(" << t << ")\n";
+ #endif
+
+ /* Find the range that includes 't' and its neighbors */
+ TreeIter iter = tree.find(Range(t));
+ assert(iter != tree.end());
+ Range cur = *iter;
+ TreeIter prev = iter;
+ TreeIter next = iter;
+ --prev;
+ ++next;
+
+ /* Remove the original range (note that this does not
+ invalidate the prev/next iterators) */
+ tree.erase(iter);
+
+ /* Construct two new ranges that together cover the original
+ range, except for 't' */
+ if (t > cur.min)
+ tree.insert(Range(cur.min, t - 1));
+ if (t + 1 <= cur.max)
+ tree.insert(Range(t + 1, cur.max));
+ }
+
+ /* Take the first element out of the first range in the
+ tree. Precondition: tree must not be empty. */
+ T take_any() {
+ #if RANGE_TREE_DEBUG_PRINT_FUNCTION
+ std::cout << __func__ << "()\n";
+ #endif
+
+ /* Find the first element */
+ TreeIter iter = tree.begin();
+ assert(iter != tree.end());
+ T first = iter->min;
+
+ /* Take the first element */
+ take(first);
+ return first;
+ }
+
+ /* Return 't' to the tree, either expanding/merging existing
+ ranges or adding a range to cover it. Precondition: 't' cannot
+ be in an existing range. */
+ void release(T t) {
+ #if RANGE_TREE_DEBUG_PRINT_FUNCTION
+ std::cout << __func__ << "(" << t << ")\n";
+ #endif
+
+ /* TODO: these cases should be simplified/unified */
+
+ TreeIter right = tree.upper_bound(t);
+ if (right != tree.end()) {
+ TreeIter left = right;
+ if (left != tree.begin())
+ --left;
+
+ if (left == right) {
+ /* 't' lies before any existing ranges */
+ if (t + 1 == left->min) {
+ /* 't' lies directly before the first range,
+ resize and replace that range */
+ const Range r(t, left->max);
+ tree.erase(left);
+ tree.insert(r);
+ }
+ else {
+ /* There's a gap between 't' and the first range,
+ add a new range */
+ tree.insert(Range(t));
+ }
+ }
+ else if ((left->max + 1 == t) &&
+ (t + 1 == right->min)) {
+ /* 't' fills a hole. Remove left and right, and insert a
+ new range that covers both. */
+ const Range r(left->min, right->max);
+ tree.erase(left);
+ tree.erase(right);
+ tree.insert(r);
+ }
+ else if (left->max + 1 == t) {
+ /* 't' lies directly after 'left' range, resize and
+ replace that range */
+ const Range r(left->min, t);
+ tree.erase(left);
+ tree.insert(r);
+ }
+ else if (t + 1 == right->min) {
+ /* 't' lies directly before 'right' range, resize and
+ replace that range */
+ const Range r(t, right->max);
+ tree.erase(right);
+ tree.insert(r);
+ }
+ else {
+ /* There's a gap between 't' and both adjacent ranges,
+ add a new range */
+ tree.insert(Range(t));
+ }
+ }
+ else {
+ /* 't' lies after any existing ranges */
+ right = tree.end();
+ right--;
+ if (right->max + 1 == t) {
+ /* 't' lies directly after last range, resize and
+ replace that range */
+ const Range r(right->min, t);
+ tree.erase(right);
+ tree.insert(r);
+ }
+ else {
+ /* There's a gap between the last range and 't', add a
+ new range */
+ tree.insert(Range(t));
+ }
+ }
+ }
+
+ bool has(T t) const {
+ TreeIterConst iter = tree.find(Range(t));
+ return (iter != tree.end()) && (t <= iter->max);
+ }
+
+ bool has_range(T min, T max) const {
+ TreeIterConst iter = tree.find(Range(min, max));
+ return (iter != tree.end()) && (min == iter->min && max == iter->max);
+ }
+
+ bool empty() const {
+ return tree.empty();
+ }
+
+ int size() const {
+ return tree.size();
+ }
+
+ void print() const {
+ std::cout << "RangeTree:\n";
+ for (TreeIterConst iter = tree.begin(); iter != tree.end(); ++iter) {
+ const Range& r = *iter;
+ if (r.single)
+ std::cout << " [" << r.min << "]\n";
+ else
+ std::cout << " [" << r.min << ", " << r.max << "]\n";
+ }
+ if (empty())
+ std::cout << " <empty>";
+ std::cout << "\n";
+ }
+
+ unsigned int allocation_lower_bound() const {
+ return tree.size() * sizeof(Range);
+ }
+
+private:
+ Tree tree;
+};
diff --git a/extern/rangetree/range_tree_c_api.cc b/extern/rangetree/range_tree_c_api.cc
new file mode 100644
index 0000000..56f2d90
--- /dev/null
+++ b/extern/rangetree/range_tree_c_api.cc
@@ -0,0 +1,86 @@
+/* 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.
+*/
+
+#include "range_tree.hh"
+
+/* Give RangeTreeUInt a real type rather than the opaque struct type
+ defined for external use. */
+#define RANGE_TREE_C_API_INTERNAL
+typedef RangeTree<unsigned> RangeTreeUInt;
+
+#include "range_tree_c_api.h"
+
+RangeTreeUInt *range_tree_uint_alloc(unsigned min, unsigned max)
+{
+ return new RangeTreeUInt(min, max);
+}
+
+RangeTreeUInt *range_tree_uint_copy(RangeTreeUInt *src)
+{
+ return new RangeTreeUInt(*src);
+}
+
+void range_tree_uint_free(RangeTreeUInt *rt)
+{
+ delete rt;
+}
+
+void range_tree_uint_take(RangeTreeUInt *rt, unsigned v)
+{
+ rt->take(v);
+}
+
+unsigned range_tree_uint_take_any(RangeTreeUInt *rt)
+{
+ return rt->take_any();
+}
+
+void range_tree_uint_release(RangeTreeUInt *rt, unsigned v)
+{
+ rt->release(v);
+}
+
+int range_tree_uint_has(const RangeTreeUInt *rt, unsigned v)
+{
+ return rt->has(v);
+}
+
+int range_tree_uint_has_range(const RangeTreeUInt *rt,
+ unsigned vmin,
+ unsigned vmax)
+{
+ return rt->has_range(vmin, vmax);
+}
+
+int range_tree_uint_empty(const RangeTreeUInt *rt)
+{
+ return rt->empty();
+}
+
+unsigned range_tree_uint_size(const RangeTreeUInt *rt)
+{
+ return rt->size();
+}
+
+void range_tree_uint_print(const RangeTreeUInt *rt)
+{
+ rt->print();
+}
+
+unsigned int range_tree_uint_allocation_lower_bound(const RangeTreeUInt *rt)
+{
+ return rt->allocation_lower_bound();
+}
diff --git a/extern/rangetree/range_tree_c_api.h b/extern/rangetree/range_tree_c_api.h
new file mode 100644
index 0000000..af6a7b1
--- /dev/null
+++ b/extern/rangetree/range_tree_c_api.h
@@ -0,0 +1,60 @@
+/* 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.
+*/
+
+#ifndef RANGE_TREE_C_API_H
+#define RANGE_TREE_C_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Simple C-accessible wrapper for RangeTree<unsigned> */
+
+#ifndef RANGE_TREE_C_API_INTERNAL
+typedef struct RangeTreeUInt RangeTreeUInt;
+#endif
+
+RangeTreeUInt *range_tree_uint_alloc(unsigned min, unsigned max);
+
+RangeTreeUInt *range_tree_uint_copy(RangeTreeUInt *src);
+
+void range_tree_uint_free(RangeTreeUInt *rt);
+
+void range_tree_uint_take(RangeTreeUInt *rt, unsigned v);
+
+unsigned range_tree_uint_take_any(RangeTreeUInt *rt);
+
+void range_tree_uint_release(RangeTreeUInt *rt, unsigned v);
+
+int range_tree_uint_has(const RangeTreeUInt *rt, unsigned v);
+
+int range_tree_uint_has_range(const RangeTreeUInt *rt,
+ unsigned vmin,
+ unsigned vmax);
+
+int range_tree_uint_empty(const RangeTreeUInt *rt);
+
+unsigned range_tree_uint_size(const RangeTreeUInt *rt);
+
+void range_tree_uint_print(const RangeTreeUInt *rt);
+
+unsigned int range_tree_uint_allocation_lower_bound(const RangeTreeUInt *rt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DUALCON_H__ */
diff --git a/intern/SConscript b/intern/SConscript
index 5360ce4..a35c99b 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
SConscript(['audaspace/SConscript',
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
index e2b6efa..ba54953 100644
--- a/intern/audaspace/SConscript
+++ b/intern/audaspace/SConscript
@@ -1,4 +1,25 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** BEGIN LGPL LICENSE BLOCK *****
+#
+# Copyright 2009 Jrg Hermann Mller
+#
+# This file is part of AudaSpace.
+#
+# AudaSpace is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# AudaSpace 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+#
+# ***** END LGPL LICENSE BLOCK *****
Import ('env')
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 0a3d0f8..831e199 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -107,7 +107,7 @@ void AUD_FFMPEGReader::init()
m_position = 0;
m_pkgbuf_left = 0;
- if(av_find_stream_info(m_formatCtx)<0)
+ if(avformat_find_stream_info(m_formatCtx, NULL) < 0)
AUD_THROW(AUD_ERROR_FFMPEG, streaminfo_error);
// find audio stream and codec
@@ -133,7 +133,7 @@ void AUD_FFMPEGReader::init()
if(!aCodec)
AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
- if(avcodec_open(m_codecCtx, aCodec)<0)
+ if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0)
AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
// XXX this prints file information to stdout:
@@ -236,14 +236,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer) :
AUD_FFMPEGReader::~AUD_FFMPEGReader()
{
avcodec_close(m_codecCtx);
-
- if(m_aviocontext)
- {
- avformat_close_input(&m_formatCtx);
- av_free(m_aviocontext);
- }
- else
- av_close_input_file(m_formatCtx);
+ avformat_close_input(&m_formatCtx);
}
int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
index 2b34348..55040e4 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
@@ -55,10 +55,15 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
{
static const char* formats[] = { NULL, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
- if(avformat_alloc_output_context2(&m_formatCtx, NULL, formats[format], filename.c_str()))
- AUD_THROW(AUD_ERROR_FFMPEG, context_error);
+ m_formatCtx = avformat_alloc_context();
+ if (!m_formatCtx) AUD_THROW(AUD_ERROR_FFMPEG, context_error);
- m_outputFmt = m_formatCtx->oformat;
+ strcpy(m_formatCtx->filename, filename.c_str());
+ m_outputFmt = m_formatCtx->oformat = av_guess_format(formats[format], filename.c_str(), NULL);
+ if (!m_outputFmt) {
+ avformat_free_context(m_formatCtx);
+ AUD_THROW(AUD_ERROR_FFMPEG, context_error);
+ }
switch(codec)
{
@@ -116,7 +121,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
if(m_outputFmt->audio_codec == CODEC_ID_NONE)
AUD_THROW(AUD_ERROR_SPECS, codec_error);
- m_stream = av_new_stream(m_formatCtx, 0);
+ m_stream = avformat_new_stream(m_formatCtx, NULL);
if(!m_stream)
AUD_THROW(AUD_ERROR_FFMPEG, stream_error);
@@ -164,7 +169,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
if(!codec)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
- if(avcodec_open(m_codecCtx, codec))
+ if(avcodec_open2(m_codecCtx, codec, NULL))
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
diff --git a/intern/bsp/SConscript b/intern/bsp/SConscript
index d3f7cf1..92c8ee4 100644
--- a/intern/bsp/SConscript
+++ b/intern/bsp/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/container/SConscript b/intern/container/SConscript
index 8edf86d..1f94315 100644
--- a/intern/container/SConscript
+++ b/intern/container/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 12829f1..3242acf 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -68,7 +68,7 @@ if(WITH_CYCLES_BLENDER)
add_subdirectory(blender)
endif()
-if(WITH_CYCLES_TEST)
+if(WITH_CYCLES_TEST OR WITH_CYCLES_NETWORK)
add_subdirectory(app)
endif()
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index a0e2650..dcb684c 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
from os import path
Import('env')
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index e6a13e0..f94a29b 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -23,7 +23,9 @@
#include "util_args.h"
#include "util_foreach.h"
#include "util_path.h"
+#include "util_stats.h"
#include "util_string.h"
+#include "util_task.h"
using namespace ccl;
@@ -32,29 +34,29 @@ int main(int argc, const char **argv)
path_init();
/* device types */
- string devices = "";
+ string devicelist = "";
string devicename = "cpu";
bool list = false;
vector<DeviceType>& types = Device::available_types();
foreach(DeviceType type, types) {
- if(devices != "")
- devices += ", ";
+ if(devicelist != "")
+ devicelist += ", ";
- devices += Device::string_from_type(type);
+ devicelist += Device::string_from_type(type);
}
/* parse options */
ArgParse ap;
ap.options ("Usage: cycles_server [options]",
- "--device %s", &devicename, ("Devices to use: " + devices).c_str(),
+ "--device %s", &devicename, ("Devices to use: " + devicelist).c_str(),
"--list-devices", &list, "List information about all available devices",
NULL);
if(ap.parse(argc, argv) < 0) {
- fprintf(stderr, "%s\n", ap.error_message().c_str());
+ fprintf(stderr, "%s\n", ap.geterror().c_str());
ap.usage();
exit(EXIT_FAILURE);
}
@@ -84,13 +86,18 @@ int main(int argc, const char **argv)
}
}
+ TaskScheduler::init();
+
while(1) {
- Device *device = Device::create(device_info);
- printf("Cycles Server with device: %s\n", device->description().c_str());
+ Stats stats;
+ Device *device = Device::create(device_info, stats);
+ printf("Cycles Server with device: %s\n", device->info.description.c_str());
device->server_run();
delete device;
}
+ TaskScheduler::exit();
+
return 0;
}
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 292c37d..710e8ba 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC
blender_mesh.cpp
blender_object.cpp
blender_particles.cpp
+ blender_curves.cpp
blender_python.cpp
blender_session.cpp
blender_shader.cpp
@@ -38,7 +39,6 @@ set(SRC
set(ADDON_FILES
addon/__init__.py
addon/engine.py
- addon/enums.py
addon/osl.py
addon/presets.py
addon/properties.py
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 0fad2ac..dddf7ba 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 6, 3),
+ "blender": (2, 60, 5),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
@@ -31,8 +31,8 @@ bl_info = {
"category": "Render"}
import bpy
-from . import ui, properties, engine, presets
+from . import engine
class CyclesRender(bpy.types.RenderEngine):
bl_idname = 'CYCLES'
@@ -84,6 +84,10 @@ class CyclesRender(bpy.types.RenderEngine):
def register():
+ from . import ui
+ from . import properties
+ from . import presets
+
properties.register()
ui.register()
presets.register()
@@ -91,6 +95,10 @@ def register():
def unregister():
+ from . import ui
+ from . import properties
+ from . import presets
+
ui.unregister()
properties.unregister()
presets.unregister()
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index ca5cbee..9641128 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -18,10 +18,8 @@
# <pep8 compliant>
-import bpy
-
-
def init():
+ import bpy
import _cycles
import os.path
@@ -32,6 +30,7 @@ def init():
def create(engine, data, scene, region=0, v3d=0, rv3d=0):
+ import bpy
import _cycles
data = data.as_pointer()
diff --git a/intern/cycles/blender/addon/enums.py b/intern/cycles/blender/addon/enums.py
deleted file mode 100644
index fa9801e..0000000
--- a/intern/cycles/blender/addon/enums.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Copyright 2011, Blender Foundation.
-#
-# 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.
-#
-
-# <pep8 compliant>
-
-from . import engine
-
-devices = (
- ('CPU', "CPU", "Use CPU for rendering"),
- ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
-
-feature_set = (
- ('SUPPORTED', "Supported", "Only use finished and supported features"),
- ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"),
- )
-
-displacement_methods = (
- ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"),
- ('TRUE', "True", "Use true displacement only, requires fine subdivision"),
- ('BOTH', "Both", "Combination of displacement and bump mapping"),
- )
-
-bvh_types = (
- ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
- ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
- )
-
-filter_types = (
- ('BOX', "Box", "Box filter"),
- ('GAUSSIAN', "Gaussian", "Gaussian filter"),
- )
-
-aperture_types = (
- ('RADIUS', "Radius", "Directly change the size of the aperture"),
- ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"),
- )
-
-panorama_types = (
- ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
- ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
- ('FISHEYE_EQUISOLID', "Fisheye Equisolid",
- "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
- )
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index f6dbf6b..8b90b0b 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -25,10 +25,84 @@ from bpy.props import (BoolProperty,
IntProperty,
PointerProperty)
-import math
-
-from . import enums
-
+# enums
+
+enum_devices = (
+ ('CPU', "CPU", "Use CPU for rendering"),
+ ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"))
+
+enum_feature_set = (
+ ('SUPPORTED', "Supported", "Only use finished and supported features"),
+ ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"),
+ )
+
+enum_displacement_methods = (
+ ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"),
+ ('TRUE', "True", "Use true displacement only, requires fine subdivision"),
+ ('BOTH', "Both", "Combination of displacement and bump mapping"),
+ )
+
+enum_bvh_types = (
+ ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
+ ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
+ )
+
+enum_filter_types = (
+ ('BOX', "Box", "Box filter"),
+ ('GAUSSIAN', "Gaussian", "Gaussian filter"),
+ )
+
+enum_aperture_types = (
+ ('RADIUS', "Radius", "Directly change the size of the aperture"),
+ ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"),
+ )
+
+enum_panorama_types = (
+ ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
+ ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
+ ('FISHEYE_EQUISOLID', "Fisheye Equisolid",
+ "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
+ )
+
+enum_curve_presets = (
+ ('CUSTOM', "Custom", "Set general parameters"),
+ ('TANGENT_SHADING', "Tangent Normal", "Use planar geometry and tangent normals"),
+ ('TRUE_NORMAL', "True Normal", "Use true normals (good for thin strands)"),
+ ('ACCURATE_PRESET', "Accurate", "Use best settings (suitable for glass materials)"),
+ )
+
+enum_curve_primitives = (
+ ('TRIANGLES', "Triangles", "Create triangle geometry around strands"),
+ ('LINE_SEGMENTS', "Line Segments", "Use line segment primitives"),
+ ('CURVE_SEGMENTS', "?Curve Segments?", "Use curve segment primitives (not implemented)"),
+ )
+
+enum_triangle_curves = (
+ ('CAMERA', "Planes", "Create individual triangles forming planes that face camera"),
+ ('RIBBONS', "Ribbons", "Create individual triangles forming ribbon"),
+ ('TESSELLATED', "Tessellated", "Create mesh surrounding each strand"),
+ )
+
+enum_line_curves = (
+ ('ACCURATE', "Accurate", "Always take into consideration strand width for intersections"),
+ ('QT_CORRECTED', "Corrected", "Ignore width for initial intersection and correct later"),
+ ('ENDCORRECTED', "Correct found", "Ignore width for all intersections and only correct closest"),
+ ('QT_UNCORRECTED', "Uncorrected", "Calculate intersections without considering width"),
+ )
+
+enum_curves_interpolation = (
+ ('LINEAR', "Linear interpolation", "Use Linear interpolation between segments"),
+ ('CARDINAL', "Cardinal interpolation", "Use cardinal interpolation between segments"),
+ ('BSPLINE', "B-spline interpolation", "Use b-spline interpolation between segments"),
+ )
+
+enum_tile_order = (
+ ('CENTER', "Center", "Render from center to the edges"),
+ ('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"),
+ ('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"),
+ ('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"),
+ ('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"),
+ )
class CyclesRenderSettings(bpy.types.PropertyGroup):
@classmethod
@@ -41,13 +115,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.device = EnumProperty(
name="Device",
description="Device to use for rendering",
- items=enums.devices,
+ items=enum_devices,
default='CPU',
)
cls.feature_set = EnumProperty(
name="Feature Set",
description="Feature set to use for rendering",
- items=enums.feature_set,
+ items=enum_feature_set,
default='SUPPORTED',
)
cls.shading_system = BoolProperty(
@@ -203,14 +277,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
)
cls.film_transparent = BoolProperty(
name="Transparent",
- description="World background is transparent",
+ description="World background is transparent with premultiplied alpha",
default=False,
)
cls.filter_type = EnumProperty(
name="Filter Type",
description="Pixel filter type",
- items=enums.filter_types,
+ items=enum_filter_types,
default='GAUSSIAN',
)
cls.filter_width = FloatProperty(
@@ -273,7 +347,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.debug_bvh_type = EnumProperty(
name="Viewport BVH Type",
description="Choose between faster updates, or faster render",
- items=enums.bvh_types,
+ items=enum_bvh_types,
default='DYNAMIC_BVH',
)
cls.debug_use_spatial_splits = BoolProperty(
@@ -286,6 +360,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Cache last built BVH to disk for faster re-render if no geometry changed",
default=False,
)
+ cls.tile_order = EnumProperty(
+ name="Tile Order",
+ description="Tile order for rendering",
+ items=enum_tile_order,
+ default='CENTER',
+ )
cls.use_progressive_refine = BoolProperty(
name="Progressive Refine",
description="Instead of rendering each tile until it is finished, "
@@ -303,6 +383,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
class CyclesCameraSettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
+ import math
+
bpy.types.Camera.cycles = PointerProperty(
name="Cycles Camera Settings",
description="Cycles camera settings",
@@ -312,7 +394,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
cls.aperture_type = EnumProperty(
name="Aperture Type",
description="Use F/stop number or aperture radius",
- items=enums.aperture_types,
+ items=enum_aperture_types,
default='RADIUS',
)
cls.aperture_fstop = FloatProperty(
@@ -347,7 +429,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
cls.panorama_type = EnumProperty(
name="Panorama Type",
description="Distortion to use for the calculation",
- items=enums.panorama_types,
+ items=enum_panorama_types,
default='FISHEYE_EQUISOLID',
)
cls.fisheye_fov = FloatProperty(
@@ -516,7 +598,7 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
cls.displacement_method = EnumProperty(
name="Displacement Method",
description="Method to use for the displacement",
- items=enums.displacement_methods,
+ items=enum_displacement_methods,
default='BUMP',
)
cls.use_subdivision = BoolProperty(
@@ -537,6 +619,157 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
del bpy.types.Curve.cycles
del bpy.types.MetaBall.cycles
+class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
+ @classmethod
+ def register(cls):
+ bpy.types.Scene.cycles_curves = PointerProperty(
+ name="Cycles Hair Rendering Settings",
+ description="Cycles hair rendering settings",
+ type=cls,
+ )
+ cls.preset = EnumProperty(
+ name="Mode",
+ description="Hair rendering mode",
+ items=enum_curve_presets,
+ default='TRUE_NORMAL',
+ )
+ cls.primitive = EnumProperty(
+ name="Primitive",
+ description="Type of primitive used for hair rendering",
+ items=enum_curve_primitives,
+ default='LINE_SEGMENTS',
+ )
+ cls.triangle_method = EnumProperty(
+ name="Mesh Geometry",
+ description="Method for creating triangle geometry",
+ items=enum_triangle_curves,
+ default='CAMERA',
+ )
+ cls.line_method = EnumProperty(
+ name="Intersection Method",
+ description="Method for line segment intersection",
+ items=enum_line_curves,
+ default='ACCURATE',
+ )
+ cls.interpolation = EnumProperty(
+ name="Interpolation",
+ description="Interpolation method",
+ items=enum_curves_interpolation,
+ default='BSPLINE',
+ )
+ cls.use_backfacing = BoolProperty(
+ name="Check back-faces",
+ description="Test back-faces of strands",
+ default=False,
+ )
+ cls.use_encasing = BoolProperty(
+ name="Exclude encasing",
+ description="Ignore strands encasing a ray's initial location",
+ default=True,
+ )
+ cls.use_tangent_normal_geometry = BoolProperty(
+ name="Tangent normal geometry",
+ description="Use the tangent normal for actual normal",
+ default=False,
+ )
+ cls.use_tangent_normal = BoolProperty(
+ name="Tangent normal default",
+ description="Use the tangent normal for all normals",
+ default=False,
+ )
+ cls.use_tangent_normal_correction = BoolProperty(
+ name="Strand slope correction",
+ description="Correct the tangent normal for the strand's slope",
+ default=False,
+ )
+ cls.use_cache = BoolProperty(
+ name="Export Cached data",
+ default=True,
+ )
+ cls.use_parents = BoolProperty(
+ name="Use parent strands",
+ description="Use parents with children",
+ default=False,
+ )
+ cls.use_smooth = BoolProperty(
+ name="Smooth Strands",
+ description="Use vertex normals",
+ default=True,
+ )
+ cls.use_joined = BoolProperty(
+ name="Join",
+ description="Fill gaps between segments (requires more memory)",
+ default=False,
+ )
+ cls.use_curves = BoolProperty(
+ name="Use Cycles Hair Rendering",
+ description="Activate Cycles hair rendering for particle system",
+ default=True,
+ )
+ cls.segments = IntProperty(
+ name="Segments",
+ description="Number of segments between path keys (note that this combines with the 'draw step' value)",
+ min=1, max=64,
+ default=1,
+ )
+ cls.resolution = IntProperty(
+ name="Resolution",
+ description="Resolution of generated mesh",
+ min=3, max=64,
+ default=3,
+ )
+ cls.normalmix = FloatProperty(
+ name="Normal mix",
+ description="Scale factor for tangent normal removal (zero gives ray normal)",
+ min=0, max=2.0,
+ default=1,
+ )
+ cls.encasing_ratio = FloatProperty(
+ name="Encasing ratio",
+ description="Scale factor for encasing strand width",
+ min=0, max=100.0,
+ default=1.01,
+ )
+
+ @classmethod
+ def unregister(cls):
+ del bpy.types.Scene.cycles_curves
+
+class CyclesCurveSettings(bpy.types.PropertyGroup):
+ @classmethod
+ def register(cls):
+ bpy.types.ParticleSettings.cycles = PointerProperty(
+ name="Cycles Hair Settings",
+ description="Cycles hair settings",
+ type=cls,
+ )
+ cls.root_width = FloatProperty(
+ name="Root Size Multiplier",
+ description="Multiplier of particle size for the strand's width at root",
+ min=0.0, max=1000.0,
+ default=1.0,
+ )
+ cls.tip_width = FloatProperty(
+ name="Tip Size Multiplier",
+ description="Multiplier of particle size for the strand's width at tip",
+ min=0.0, max=1000.0,
+ default=0.0,
+ )
+ cls.shape = FloatProperty(
+ name="Strand Shape",
+ description="Strand shape parameter",
+ min=-1.0, max=1.0,
+ default=0.0,
+ )
+ cls.use_closetip = BoolProperty(
+ name="Close tip",
+ description="Set tip radius to zero",
+ default=True,
+ )
+
+ @classmethod
+ def unregister(cls):
+ del bpy.types.ParticleSettings.cycles
def register():
bpy.utils.register_class(CyclesRenderSettings)
@@ -546,6 +779,8 @@ def register():
bpy.utils.register_class(CyclesWorldSettings)
bpy.utils.register_class(CyclesVisibilitySettings)
bpy.utils.register_class(CyclesMeshSettings)
+ bpy.utils.register_class(CyclesCurveRenderSettings)
+ bpy.utils.register_class(CyclesCurveSettings)
def unregister():
@@ -556,3 +791,5 @@ def unregister():
bpy.utils.unregister_class(CyclesWorldSettings)
bpy.utils.unregister_class(CyclesMeshSettings)
bpy.utils.unregister_class(CyclesVisibilitySettings)
+ bpy.utils.unregister_class(CyclesCurveRenderSettings)
+ bpy.utils.unregister_class(CyclesCurveSettings)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index ba93146..a24da59 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -22,8 +22,6 @@ import bpy
from bpy.types import Panel, Menu
-from . import enums, engine
-
class CYCLES_MT_integrator_presets(Menu):
bl_label = "Integrator Presets"
@@ -193,7 +191,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
sub.prop(rd, "threads")
sub = col.column(align=True)
- sub.label(text="Tile Size:")
+ sub.label(text="Tiles:")
+ sub.prop(cscene, "tile_order", text="")
sub.prop(rd, "tile_x", text="X")
sub.prop(rd, "tile_y", text="Y")
@@ -233,7 +232,7 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
rd = scene.render
row = layout.row()
- row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
+ row.template_list("RENDER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
@@ -379,7 +378,7 @@ class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
+ row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=2)
col = row.column(align=True)
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
@@ -917,6 +916,120 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
layout.template_color_ramp(mapping, "color_ramp", expand=True)
+class CyclesParticle_PT_textures(CyclesButtonsPanel, Panel):
+ bl_label = "Textures"
+ bl_context = "particle"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ psys = context.particle_system
+ return psys and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = psys.settings
+
+ row = layout.row()
+ row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2)
+
+ col = row.column(align=True)
+ col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
+ col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
+ col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
+
+ if not part.active_texture:
+ layout.template_ID(part, "active_texture", new="texture.new")
+ else:
+ slot = part.texture_slots[part.active_texture_index]
+ layout.template_ID(slot, "texture", new="texture.new")
+
+class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
+ bl_label = "Cycles Hair Rendering"
+ bl_context = "particle"
+
+ @classmethod
+ def poll(cls, context):
+ psys = context.particle_system
+ device_type = context.user_preferences.system.compute_device_type
+ experimental = context.scene.cycles.feature_set == 'EXPERIMENTAL' and (context.scene.cycles.device == 'CPU' or device_type == 'NONE')
+ return CyclesButtonsPanel.poll(context) and experimental and psys
+
+ def draw_header(self, context):
+ cscene = context.scene.cycles_curves
+ self.layout.prop(cscene, "use_curves", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ cscene = scene.cycles_curves
+
+ layout.active = cscene.use_curves
+
+ layout.prop(cscene, "preset", text="Mode")
+
+ if cscene.preset == 'CUSTOM':
+ layout.prop(cscene, "primitive", text="Primitive")
+
+ if cscene.primitive == 'TRIANGLES':
+ layout.prop(cscene, "triangle_method", text="Method")
+ if cscene.triangle_method == 'TESSELLATED':
+ layout.prop(cscene, "resolution", text="Resolution")
+ layout.prop(cscene, "use_smooth", text="Smooth")
+ elif cscene.primitive == 'LINE_SEGMENTS':
+ layout.prop(cscene, "use_backfacing", text="Check back-faces")
+
+ row = layout.row()
+ row.prop(cscene, "use_encasing", text="Exclude encasing")
+ sub = row.row()
+ sub.active = cscene.use_encasing
+ sub.prop(cscene, "encasing_ratio", text="Ratio for encasing")
+
+ layout.prop(cscene, "line_method", text="Method")
+ layout.prop(cscene, "use_tangent_normal", text="Use tangent normal as default")
+ layout.prop(cscene, "use_tangent_normal_geometry", text="Use tangent normal geometry")
+ layout.prop(cscene, "use_tangent_normal_correction", text="Correct tangent normal for slope")
+ layout.prop(cscene, "interpolation", text="Interpolation")
+
+ row = layout.row()
+ row.prop(cscene, "segments", text="Segments")
+ row.prop(cscene, "normalmix", text="Ray Mix")
+
+ row = layout.row()
+ row.prop(cscene, "use_cache", text="Export cache with children")
+ if cscene.use_cache:
+ row.prop(cscene, "use_parents", text="Include parents")
+
+class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
+ bl_label = "Cycles Hair Settings"
+ bl_context = "particle"
+
+ @classmethod
+ def poll(cls, context):
+ use_curves = context.scene.cycles_curves.use_curves and context.particle_system
+ device_type = context.user_preferences.system.compute_device_type
+ experimental = context.scene.cycles.feature_set == 'EXPERIMENTAL' and (context.scene.cycles.device == 'CPU' or device_type == 'NONE')
+ return CyclesButtonsPanel.poll(context) and experimental and use_curves
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_settings
+ cpsys = psys.cycles
+
+ row = layout.row()
+ row.prop(cpsys, "shape", text="Shape")
+ row.prop(cpsys, "use_closetip", text="Close tip")
+
+ layout.label(text="Width multiplier:")
+ row = layout.row()
+ row.prop(cpsys, "root_width", text="Root")
+ row.prop(cpsys, "tip_width", text="Tip")
+
+
class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
bl_label = "Simplify"
bl_context = "scene"
@@ -947,6 +1060,7 @@ def draw_device(self, context):
layout = self.layout
if scene.render.engine == 'CYCLES':
+ from . import engine
cscene = scene.cycles
layout.prop(cscene, "feature_set")
@@ -1028,6 +1142,7 @@ def get_panels():
bpy.types.TEXTURE_PT_pointdensity_turbulence,
bpy.types.TEXTURE_PT_mapping,
bpy.types.TEXTURE_PT_influence,
+ bpy.types.TEXTURE_PT_colors,
bpy.types.PARTICLE_PT_context_particles,
bpy.types.PARTICLE_PT_emission,
bpy.types.PARTICLE_PT_hair_dynamics,
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
new file mode 100644
index 0000000..41e1249
--- /dev/null
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -0,0 +1,1138 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#include "attribute.h"
+#include "mesh.h"
+#include "object.h"
+#include "scene.h"
+#include "curves.h"
+
+#include "blender_sync.h"
+#include "blender_util.h"
+
+#include "util_foreach.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Utilities */
+
+/* Hair curve functions */
+
+void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4]);
+void interp_weights(float t, float data[4], int type);
+float shaperadius(float shape, float root, float tip, float time);
+void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation);
+bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData);
+bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents);
+bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num);
+bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents);
+void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam);
+void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments);
+void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments);
+void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments);
+void ExportCurveTriangleUVs(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, int vert_offset, int resol);
+
+ParticleCurveData::ParticleCurveData()
+{
+}
+
+ParticleCurveData::~ParticleCurveData()
+{
+ psys_firstcurve.clear();
+ psys_curvenum.clear();
+ psys_shader.clear();
+ psys_rootradius.clear();
+ psys_tipradius.clear();
+ psys_shape.clear();
+
+ curve_firstkey.clear();
+ curve_keynum.clear();
+ curve_length.clear();
+ curve_uv.clear();
+ curve_vcol.clear();
+
+ curvekey_co.clear();
+ curvekey_time.clear();
+}
+
+void interp_weights(float t, float data[4], int type)
+{
+ float t2, t3, fc;
+
+ if(type == CURVE_LINEAR) {
+ data[0] = 0.0f;
+ data[1] = -t + 1.0f;
+ data[2] = t;
+ data[3] = 0.0f;
+ }
+ else if(type == CURVE_CARDINAL) {
+ t2 = t * t;
+ t3 = t2 * t;
+ fc = 0.71f;
+
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
+ }
+ else if(type == CURVE_BSPLINE) {
+ t2 = t * t;
+ t3 = t2 * t;
+
+ data[0] = -0.16666666f * t3 + 0.5f * t2 - 0.5f * t + 0.16666666f;
+ data[1] = 0.5f * t3 - t2 + 0.66666666f;
+ data[2] = -0.5f * t3 + 0.5f * t2 + 0.5f * t + 0.16666666f;
+ data[3] = 0.16666666f * t3;
+ }
+}
+
+void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, float3 *v4, const float w[4])
+{
+ p->x = v1->x * w[0] + v2->x * w[1] + v3->x * w[2] + v4->x * w[3];
+ p->y = v1->y * w[0] + v2->y * w[1] + v3->y * w[2] + v4->y * w[3];
+ p->z = v1->z * w[0] + v2->z * w[1] + v3->z * w[2] + v4->z * w[3];
+}
+
+float shaperadius(float shape, float root, float tip, float time)
+{
+ float radius = 1.0f - time;
+ if(shape != 0.0f) {
+ if(shape < 0.0f)
+ radius = (float)pow(1.0f - time, 1.f + shape);
+ else
+ radius = (float)pow(1.0f - time, 1.f / (1.f - shape));
+ }
+ return (radius * (root - tip)) + tip;
+}
+
+/* curve functions */
+
+void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation)
+{
+ float3 ckey_loc1 = CData->curvekey_co[key];
+ float3 ckey_loc2 = ckey_loc1;
+ float3 ckey_loc3 = CData->curvekey_co[key+1];
+ float3 ckey_loc4 = ckey_loc3;
+
+ if(key > CData->curve_firstkey[curve])
+ ckey_loc1 = CData->curvekey_co[key - 1];
+
+ if(key < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)
+ ckey_loc4 = CData->curvekey_co[key + 2];
+
+
+ float time1 = CData->curvekey_time[key]/CData->curve_length[curve];
+ float time2 = CData->curvekey_time[key + 1]/CData->curve_length[curve];
+
+ float dfra = (time2 - time1) / (float)segno;
+
+ if(time)
+ *time = (dfra * seg) + time1;
+
+ float t[4];
+
+ interp_weights((float)seg / (float)segno, t, interpolation);
+
+ if(keyloc)
+ curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t);
+}
+
+bool ObtainParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData)
+{
+
+ int curvenum = 0;
+ int keyno = 0;
+
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+
+ BL::ParticleSystemModifier psmd(b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+
+ int totcurves = b_psys.particles.length();
+
+ if(totcurves == 0)
+ continue;
+
+ PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
+
+ CData->psys_firstcurve.push_back(curvenum);
+ CData->psys_curvenum.push_back(totcurves);
+ CData->psys_shader.push_back(shader);
+
+ float radius = b_psys.settings().particle_size() * 0.5f;
+
+ CData->psys_rootradius.push_back(radius * get_float(cpsys, "root_width"));
+ CData->psys_tipradius.push_back(radius * get_float(cpsys, "tip_width"));
+ CData->psys_shape.push_back(get_float(cpsys, "shape"));
+ CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip"));
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) {
+ CData->curve_firstkey.push_back(keyno);
+
+ int keylength = b_pa->hair_keys.length();
+ CData->curve_keynum.push_back(keylength);
+
+ float curve_length = 0.0f;
+ float3 pcKey;
+ int step_no = 0;
+ BL::Particle::hair_keys_iterator b_cKey;
+ for(b_pa->hair_keys.begin(b_cKey); b_cKey != b_pa->hair_keys.end(); ++b_cKey) {
+ float nco[3];
+ b_cKey->co_object( *b_ob, psmd, *b_pa, nco);
+ float3 cKey = make_float3(nco[0],nco[1],nco[2]);
+ if(step_no > 0)
+ curve_length += len(cKey - pcKey);
+ CData->curvekey_co.push_back(cKey);
+ CData->curvekey_time.push_back(curve_length);
+ pcKey = cKey;
+ keyno++;
+ step_no++;
+ }
+
+ CData->curve_length.push_back(curve_length);
+ /*add uvs*/
+ BL::Mesh::tessface_uv_textures_iterator l;
+ b_mesh->tessface_uv_textures.begin(l);
+
+ float3 uv = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_mesh->tessface_uv_textures.length())
+ b_pa->uv_on_emitter(psmd,&uv.x);
+ CData->curve_uv.push_back(uv);
+
+ curvenum++;
+
+ }
+ }
+ }
+ }
+
+ return true;
+
+}
+
+bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents)
+{
+
+ int curvenum = 0;
+ int keyno = 0;
+
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+ int draw_step = b_psys.settings().draw_step();
+ int ren_step = (int)pow((float)2.0f,(float)draw_step);
+ /*b_psys.settings().render_step(draw_step);*/
+
+ int totparts = b_psys.particles.length();
+ int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100;
+ int totcurves = totchild;
+
+ if(use_parents || b_psys.settings().child_type() == 0)
+ totcurves += totparts;
+
+ if(totcurves == 0)
+ continue;
+
+ PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
+
+ CData->psys_firstcurve.push_back(curvenum);
+ CData->psys_curvenum.push_back(totcurves);
+ CData->psys_shader.push_back(shader);
+
+ float radius = b_psys.settings().particle_size() * 0.5f;
+
+ CData->psys_rootradius.push_back(radius * get_float(cpsys, "root_width"));
+ CData->psys_tipradius.push_back(radius * get_float(cpsys, "tip_width"));
+ CData->psys_shape.push_back(get_float(cpsys, "shape"));
+ CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip"));
+
+ int pa_no = 0;
+ if(!use_parents && !(b_psys.settings().child_type() == 0))
+ pa_no = totparts;
+
+ for(; pa_no < totparts+totchild; pa_no++) {
+
+ CData->curve_firstkey.push_back(keyno);
+ CData->curve_keynum.push_back(ren_step+1);
+
+ float curve_length = 0.0f;
+ float3 pcKey;
+ for(int step_no = 0; step_no <= ren_step; step_no++) {
+ float nco[3];
+ b_psys.co_hair(*b_ob, psmd, pa_no, step_no, nco);
+ float3 cKey = make_float3(nco[0],nco[1],nco[2]);
+ cKey = transform_point(&itfm, cKey);
+ if(step_no > 0)
+ curve_length += len(cKey - pcKey);
+ CData->curvekey_co.push_back(cKey);
+ CData->curvekey_time.push_back(curve_length);
+ pcKey = cKey;
+ keyno++;
+ }
+ CData->curve_length.push_back(curve_length);
+
+ curvenum++;
+
+ }
+ }
+
+ }
+ }
+
+ return true;
+
+}
+
+bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents)
+{
+#if 0
+ int keyno = 0;
+#endif
+
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+#if 0
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+#endif
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+#if 0
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+ int draw_step = b_psys.settings().draw_step();
+ int ren_step = (int)pow((float)2.0f,(float)draw_step);
+ b_psys.settings().render_step(draw_step);
+#endif
+
+ int totparts = b_psys.particles.length();
+ int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100;
+ int totcurves = totchild;
+
+ if (use_parents || b_psys.settings().child_type() == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if(!use_parents && !(b_psys.settings().child_type() == 0))
+ pa_no = totparts;
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for(; pa_no < totparts+totchild; pa_no++) {
+
+ /*add uvs*/
+ BL::Mesh::tessface_uv_textures_iterator l;
+ b_mesh->tessface_uv_textures.begin(l);
+
+ float3 uv = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_mesh->tessface_uv_textures.length())
+ b_psys.uv_on_emitter(psmd, *b_pa, pa_no, &uv.x);
+ CData->curve_uv.push_back(uv);
+
+ if(pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+
+ }
+ }
+
+ }
+ }
+
+ return true;
+
+}
+
+bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num)
+{
+#if 0
+ int keyno = 0;
+#endif
+ if(!(mesh && b_mesh && b_ob && CData))
+ return false;
+
+#if 0
+ Transform tfm = get_transform(b_ob->matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+#endif
+
+ BL::Object::modifiers_iterator b_mod;
+ for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
+
+ BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
+
+ BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+
+ if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) {
+#if 0
+ int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1);
+ int shader = mesh->used_shaders[mi];
+ int draw_step = b_psys.settings().draw_step();
+ int ren_step = (int)pow((float)2.0f,(float)draw_step);
+ b_psys.settings().render_step(draw_step);
+#endif
+ int totparts = b_psys.particles.length();
+ int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100;
+ int totcurves = totchild;
+
+ if (use_parents || b_psys.settings().child_type() == 0)
+ totcurves += totparts;
+
+ if (totcurves == 0)
+ continue;
+
+ int pa_no = 0;
+ if(!use_parents && !(b_psys.settings().child_type() == 0))
+ pa_no = totparts;
+
+ BL::ParticleSystem::particles_iterator b_pa;
+ b_psys.particles.begin(b_pa);
+ for(; pa_no < totparts+totchild; pa_no++) {
+
+ /*add uvs*/
+ BL::Mesh::tessface_vertex_colors_iterator l;
+ b_mesh->tessface_vertex_colors.begin(l);
+
+ float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_mesh->tessface_vertex_colors.length())
+ b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
+ CData->curve_vcol.push_back(vcol);
+
+ if(pa_no < totparts && b_pa != b_psys.particles.end())
+ ++b_pa;
+
+ }
+ }
+
+ }
+ }
+
+ return true;
+
+}
+
+void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam)
+{
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ float3 xbasis;
+
+ float3 v1;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])];
+ else
+ v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1];
+
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) && (subv == segments))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
+
+ xbasis = normalize(cross(v1,RotCam - ickey_loc));
+ float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
+ float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
+ mesh->verts.push_back(ickey_loc_shfl);
+ mesh->verts.push_back(ickey_loc_shfr);
+ if(subv!=0) {
+ mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], use_smooth);
+ }
+ vertexindex += 2;
+ }
+ }
+ }
+ }
+
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
+}
+
+void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments)
+{
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]);
+ if(len_squared(firstxbasis)!= 0.0f)
+ firstxbasis = normalize(firstxbasis);
+ else
+ firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]));
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ float3 xbasis = firstxbasis;
+ float3 v1;
+ float3 v2;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ firstxbasis = normalize(xbasis);
+ break;
+ }
+ }
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ float3 v1;
+ float3 v2;
+ float3 xbasis;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ xbasis = normalize(xbasis);
+ firstxbasis = xbasis;
+ }
+ else
+ xbasis = firstxbasis;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) && (subv == segments))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
+
+ float3 ickey_loc_shfl = ickey_loc - radius * xbasis;
+ float3 ickey_loc_shfr = ickey_loc + radius * xbasis;
+ mesh->verts.push_back(ickey_loc_shfl);
+ mesh->verts.push_back(ickey_loc_shfr);
+ if(subv!=0) {
+ mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], use_smooth);
+ }
+ vertexindex += 2;
+ }
+ }
+ }
+ }
+
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ /* texture coords still needed */
+
+}
+
+void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments)
+{
+ int vertexno = mesh->verts.size();
+ int vertexindex = vertexno;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]);
+ if(len_squared(firstxbasis)!= 0.0f)
+ firstxbasis = normalize(firstxbasis);
+ else
+ firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]));
+
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ float3 xbasis = firstxbasis;
+ float3 v1;
+ float3 v2;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ firstxbasis = normalize(xbasis);
+ break;
+ }
+ }
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ float3 xbasis;
+ float3 ybasis;
+ float3 v1;
+ float3 v2;
+
+ if(curvekey == CData->curve_firstkey[curve]) {
+ subv = 0;
+ v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1];
+ v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ }
+ else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) {
+ v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])];
+ }
+ else {
+ v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey];
+ v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1];
+ }
+
+ xbasis = cross(v1,v2);
+
+ if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) {
+ xbasis = normalize(xbasis);
+ firstxbasis = xbasis;
+ }
+ else
+ xbasis = firstxbasis;
+
+ ybasis = normalize(cross(xbasis,v2));
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f);
+
+ if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) && (subv == segments))
+ radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f);
+
+ float angle = 2 * M_PI_F / (float)resolution;
+ for(int section = 0 ; section < resolution; section++) {
+ float3 ickey_loc_shf = ickey_loc + radius * (cosf(angle * section) * xbasis + sinf(angle * section) * ybasis);
+ mesh->verts.push_back(ickey_loc_shf);
+ }
+
+ if(subv!=0) {
+ for(int section = 0 ; section < resolution - 1; section++) {
+ mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], use_smooth);
+ }
+ mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], use_smooth);
+ mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], use_smooth);
+ }
+ vertexindex += resolution;
+ }
+ }
+ }
+ }
+
+ mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0);
+ mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+ mesh->add_face_normals();
+ mesh->add_vertex_normals();
+ mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
+
+ /* texture coords still needed */
+}
+
+static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments)
+{
+ int num_keys = 0;
+ int num_curves = 0;
+
+ if(!(mesh->curves.empty() && mesh->curve_keys.empty()))
+ return;
+
+ Attribute *attr_uv = NULL, *attr_intercept = NULL;
+
+ if(mesh->need_attribute(scene, ATTR_STD_UV))
+ attr_uv = mesh->curve_attributes.add(ATTR_STD_UV);
+ if(mesh->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
+ attr_intercept = mesh->curve_attributes.add(ATTR_STD_CURVE_INTERCEPT);
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+
+ if(CData->psys_curvenum[sys] == 0)
+ continue;
+
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ if(CData->curve_keynum[curve] <= 1)
+ continue;
+
+ size_t num_curve_keys = 0;
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+ if(curvekey == CData->curve_firstkey[curve])
+ subv = 0;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+ float time = 0.0f;
+
+ if((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0))
+ ickey_loc = CData->curvekey_co[curvekey];
+ else
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time);
+
+ if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2))
+ radius =0.0f;
+
+ mesh->add_curve_key(ickey_loc, radius);
+ if(attr_intercept)
+ attr_intercept->add(time);
+
+ num_curve_keys++;
+ }
+ }
+
+ mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]);
+ if(attr_uv)
+ attr_uv->add(CData->curve_uv[curve]);
+
+ num_keys += num_curve_keys;
+ num_curves++;
+ }
+ }
+
+ /* check allocation*/
+ if((mesh->curve_keys.size() != num_keys) || (mesh->curves.size() != num_curves)) {
+ /* allocation failed -> clear data */
+ mesh->curve_keys.clear();
+ mesh->curves.clear();
+ mesh->curve_attributes.clear();
+ }
+}
+
+void ExportCurveTriangleUVs(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, int vert_offset, int resol)
+{
+ float time = 0.0f;
+ float prevtime = 0.0f;
+
+ Attribute *attr = mesh->attributes.find(ATTR_STD_UV);
+ if (attr == NULL)
+ return;
+
+ float3 *uvdata = attr->data_float3();
+
+ int vertexindex = vert_offset;
+
+ for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) {
+ for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) {
+
+ for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
+
+ int subv = 1;
+
+ if (curvekey == CData->curve_firstkey[curve])
+ subv = 0;
+
+ for (; subv <= segments; subv++) {
+
+ float3 ickey_loc = make_float3(0.0f,0.0f,0.0f);
+
+ InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation);
+
+ if(subv!=0) {
+ for(int section = 0 ; section < resol; section++) {
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = prevtime;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = time;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = prevtime;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = time;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = prevtime;
+ vertexindex++;
+ uvdata[vertexindex] = CData->curve_uv[curve];
+ uvdata[vertexindex].z = time;
+ vertexindex++;
+ }
+ }
+
+ prevtime = time;
+ }
+ }
+ }
+ }
+
+}
+/* Hair Curve Sync */
+
+void BlenderSync::sync_curve_settings()
+{
+ PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves");
+
+ int preset = get_enum(csscene, "preset");
+
+ CurveSystemManager *curve_system_manager = scene->curve_system_manager;
+ CurveSystemManager prev_curve_system_manager = *curve_system_manager;
+
+ curve_system_manager->use_curves = get_boolean(csscene, "use_curves");
+
+ if(preset == CURVE_CUSTOM) {
+ /*custom properties*/
+ curve_system_manager->primitive = get_enum(csscene, "primitive");
+ curve_system_manager->line_method = get_enum(csscene, "line_method");
+ curve_system_manager->interpolation = get_enum(csscene, "interpolation");
+ curve_system_manager->triangle_method = get_enum(csscene, "triangle_method");
+ curve_system_manager->resolution = get_int(csscene, "resolution");
+ curve_system_manager->segments = get_int(csscene, "segments");
+ curve_system_manager->use_smooth = get_boolean(csscene, "use_smooth");
+
+ curve_system_manager->normalmix = get_float(csscene, "normalmix");
+ curve_system_manager->encasing_ratio = get_float(csscene, "encasing_ratio");
+
+ curve_system_manager->use_cache = get_boolean(csscene, "use_cache");
+ curve_system_manager->use_parents = get_boolean(csscene, "use_parents");
+ curve_system_manager->use_encasing = get_boolean(csscene, "use_encasing");
+ curve_system_manager->use_backfacing = get_boolean(csscene, "use_backfacing");
+ curve_system_manager->use_joined = get_boolean(csscene, "use_joined");
+ curve_system_manager->use_tangent_normal = get_boolean(csscene, "use_tangent_normal");
+ curve_system_manager->use_tangent_normal_geometry = get_boolean(csscene, "use_tangent_normal_geometry");
+ curve_system_manager->use_tangent_normal_correction = get_boolean(csscene, "use_tangent_normal_correction");
+ }
+ else {
+ curve_system_manager->primitive = CURVE_LINE_SEGMENTS;
+ curve_system_manager->interpolation = CURVE_CARDINAL;
+ curve_system_manager->normalmix = 1.0f;
+ curve_system_manager->encasing_ratio = 1.01f;
+ curve_system_manager->use_cache = true;
+ curve_system_manager->use_parents = false;
+ curve_system_manager->segments = 1;
+ curve_system_manager->use_joined = false;
+
+ switch(preset) {
+ case CURVE_TANGENT_SHADING:
+ /*tangent shading*/
+ curve_system_manager->line_method = CURVE_UNCORRECTED;
+ curve_system_manager->use_encasing = true;
+ curve_system_manager->use_backfacing = false;
+ curve_system_manager->use_tangent_normal = true;
+ curve_system_manager->use_tangent_normal_geometry = true;
+ curve_system_manager->use_tangent_normal_correction = false;
+ break;
+ case CURVE_TRUE_NORMAL:
+ /*True Normal*/
+ curve_system_manager->line_method = CURVE_CORRECTED;
+ curve_system_manager->use_encasing = true;
+ curve_system_manager->use_backfacing = false;
+ curve_system_manager->use_tangent_normal = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ curve_system_manager->use_tangent_normal_correction = false;
+ break;
+ case CURVE_ACCURATE_PRESET:
+ /*Accurate*/
+ curve_system_manager->line_method = CURVE_ACCURATE;
+ curve_system_manager->use_encasing = false;
+ curve_system_manager->use_backfacing = true;
+ curve_system_manager->use_tangent_normal = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ curve_system_manager->use_tangent_normal_correction = false;
+ break;
+ }
+
+ }
+
+ if(curve_system_manager->modified_mesh(prev_curve_system_manager))
+ {
+ BL::BlendData::objects_iterator b_ob;
+
+ for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
+ if(object_is_mesh(*b_ob)) {
+ BL::Object::particle_systems_iterator b_psys;
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
+ if((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR)) {
+ BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
+ mesh_map.set_recalc(key);
+ object_map.set_recalc(*b_ob);
+ }
+ }
+ }
+ }
+ }
+
+ if(curve_system_manager->modified(prev_curve_system_manager))
+ curve_system_manager->tag_update(scene);
+
+}
+
+void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool object_updated)
+{
+ /* Clear stored curve data */
+ mesh->curve_keys.clear();
+ mesh->curves.clear();
+ mesh->curve_attributes.clear();
+
+ /* obtain general settings */
+ bool use_curves = scene->curve_system_manager->use_curves;
+
+ if(!(use_curves && b_ob.mode() == b_ob.mode_OBJECT)) {
+ mesh->compute_bounds();
+ return;
+ }
+
+ int primitive = scene->curve_system_manager->primitive;
+ int interpolation = scene->curve_system_manager->interpolation;
+ int triangle_method = scene->curve_system_manager->triangle_method;
+ int resolution = scene->curve_system_manager->resolution;
+ int segments = scene->curve_system_manager->segments;
+ bool use_smooth = scene->curve_system_manager->use_smooth;
+ bool use_cache = scene->curve_system_manager->use_cache;
+ bool use_parents = scene->curve_system_manager->use_parents;
+ bool export_tgs = scene->curve_system_manager->use_joined;
+
+ /* extract particle hair data - should be combined with connecting to mesh later*/
+
+ ParticleCurveData CData;
+
+ if(use_cache) {
+ ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents);
+ ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents);
+ }
+ else
+ ObtainParticleData(mesh, &b_mesh, &b_ob, &CData);
+
+ /* attach strands to mesh */
+ BL::Object b_CamOb = b_scene.camera();
+ float3 RotCam = make_float3(0.0f, 0.0f, 0.0f);
+ if(b_CamOb) {
+ Transform ctfm = get_transform(b_CamOb.matrix_world());
+ Transform tfm = get_transform(b_ob.matrix_world());
+ Transform itfm = transform_quick_inverse(tfm);
+ RotCam = transform_point(&itfm, make_float3(ctfm.x.w, ctfm.y.w, ctfm.z.w));
+ }
+
+ if(primitive == CURVE_TRIANGLES){
+ int vert_num = mesh->triangles.size() * 3;
+ if(triangle_method == CURVE_CAMERA) {
+ ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam);
+ ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1);
+ }
+ else if(triangle_method == CURVE_RIBBONS) {
+ ExportCurveTriangleRibbons(mesh, &CData, interpolation, use_smooth, segments);
+ ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, 1);
+ }
+ else {
+ ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments);
+ ExportCurveTriangleUVs(mesh, &CData, interpolation, use_smooth, segments, vert_num, resolution);
+ }
+
+ }
+ else {
+ ExportCurveSegments(scene, mesh, &CData, interpolation, segments);
+ int ckey_num = mesh->curve_keys.size();
+
+ /*export tangents or curve data? - not functional yet*/
+ if(export_tgs && ckey_num > 1) {
+ Attribute *attr_tangent = mesh->curve_attributes.add(ATTR_STD_CURVE_TANGENT);
+ float3 *data_tangent = attr_tangent->data_float3();
+
+ for(int ck = 0; ck < ckey_num; ck++) {
+ float3 tg = normalize(normalize(mesh->curve_keys[min(ck + 1, ckey_num - 1)].co - mesh->curve_keys[ck].co) -
+ normalize(mesh->curve_keys[max(ck - 1, 0)].co - mesh->curve_keys[ck].co));
+
+ data_tangent[ck] = tg;
+ }
+ }
+
+ /* generated coordinates from first key. we should ideally get this from
+ * blender to handle deforming objects */
+ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ Attribute *attr_generated = mesh->curve_attributes.add(ATTR_STD_GENERATED);
+ float3 *generated = attr_generated->data_float3();
+ size_t i = 0;
+
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ float3 co = mesh->curve_keys[curve.first_key].co;
+ generated[i++] = co*size - loc;
+ }
+ }
+
+ /* create vertex color attributes */
+ BL::Mesh::tessface_vertex_colors_iterator l;
+ int vcol_num = 0;
+
+ for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ /*error occurs with more than one vertex colour attribute so avoided*/
+ if(vcol_num!=0)
+ break;
+
+ Attribute *attr_vcol = mesh->curve_attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CURVE);
+
+ ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, use_parents, 0);
+
+ float3 *vcol = attr_vcol->data_float3();
+
+ if(vcol) {
+ for(size_t curve = 0; curve < CData.curve_vcol.size() ;curve++)
+ vcol[curve] = color_srgb_to_scene_linear(CData.curve_vcol[curve]);
+ }
+
+ }
+
+ }
+
+ mesh->compute_bounds();
+}
+
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index c974875..1dd7800 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -147,7 +147,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(active_render)
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
else
- attr = mesh->attributes.add(name, TypeDesc::TypeVector, Attribute::CORNER);
+ attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
float3 *tangent = attr->data_float3();
@@ -161,7 +161,7 @@ static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_la
if(active_render)
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
else
- attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, Attribute::CORNER);
+ attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
tangent_sign = attr_sign->data_float();
}
@@ -223,10 +223,19 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
int shader = used_shaders[mi];
bool smooth = f->use_smooth();
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
-
- if(n == 4)
- mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+ if(n == 4) {
+ if(len_squared(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) == 0.0f ||
+ len_squared(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])) == 0.0f) {
+ mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
+ mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
+ }
+ else {
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+ mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
+ }
+ }
+ else
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
nverts.push_back(n);
}
@@ -240,7 +249,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
continue;
Attribute *attr = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, Attribute::CORNER);
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER);
BL::MeshColorLayer::data_iterator c;
float3 *fdata = attr->data_float3();
@@ -279,7 +288,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
if(active_render)
attr = mesh->attributes.add(std, name);
else
- attr = mesh->attributes.add(name, TypeDesc::TypePoint, Attribute::CORNER);
+ attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
BL::MeshTextureFaceLayer::data_iterator t;
float3 *fdata = attr->data_float3();
@@ -319,14 +328,9 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
* is available in the api. */
if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
- float3 loc = get_float3(b_mesh.texspace_location());
- float3 size = get_float3(b_mesh.texspace_size());
- if(size.x != 0.0f) size.x = 0.5f/size.x;
- if(size.y != 0.0f) size.y = 0.5f/size.y;
- if(size.z != 0.0f) size.z = 0.5f/size.z;
-
- loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
float3 *generated = attr->data_float3();
size_t i = 0;
@@ -376,7 +380,7 @@ static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, con
/* Sync */
-Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
+Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris)
{
/* test if we can instance or if the object is modified */
BL::ID b_ob_data = b_ob.data();
@@ -435,16 +439,24 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");
vector<Mesh::Triangle> oldtriangle = mesh->triangles;
+
+ /* compares curve_keys rather than strands in order to handle quick hair adjustsments in dynamic BVH - other methods could probably do this better*/
+ vector<Mesh::CurveKey> oldcurve_keys = mesh->curve_keys;
mesh->clear();
mesh->used_shaders = used_shaders;
mesh->name = ustring(b_ob_data.name().c_str());
if(b_mesh) {
- if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
- create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
- else
- create_mesh(scene, mesh, b_mesh, used_shaders);
+ if(!(hide_tris && experimental && is_cpu)) {
+ if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
+ create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
+ else
+ create_mesh(scene, mesh, b_mesh, used_shaders);
+ }
+
+ if(experimental && is_cpu)
+ sync_curves(mesh, b_mesh, b_ob, object_updated);
/* free derived mesh */
b_data.meshes.remove(b_mesh);
@@ -471,6 +483,13 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0)
rebuild = true;
}
+
+ if(oldcurve_keys.size() != mesh->curve_keys.size())
+ rebuild = true;
+ else if(oldcurve_keys.size()) {
+ if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(Mesh::CurveKey)*oldcurve_keys.size()) != 0)
+ rebuild = true;
+ }
mesh->tag_update(scene, rebuild);
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 38f27bc..e9bcea7 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -127,8 +127,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
case BL::Lamp::type_AREA: {
BL::AreaLamp b_area_lamp(b_lamp);
light->size = 1.0f;
- light->axisu = make_float3(tfm.x.x, tfm.y.x, tfm.z.x);
- light->axisv = make_float3(tfm.x.y, tfm.y.y, tfm.z.y);
+ light->axisu = transform_get_column(&tfm, 0);
+ light->axisv = transform_get_column(&tfm, 1);
light->sizeu = b_area_lamp.size();
if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE)
light->sizev = b_area_lamp.size_y();
@@ -140,8 +140,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
}
/* location and (inverted!) direction */
- light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
- light->dir = -make_float3(tfm.x.z, tfm.y.z, tfm.z.z);
+ light->co = transform_get_column(&tfm, 3);
+ light->dir = -transform_get_column(&tfm, 2);
/* shader */
vector<uint> used_shaders;
@@ -196,7 +196,7 @@ void BlenderSync::sync_background_light()
/* Object */
-Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion)
+Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, bool hide_tris)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
@@ -247,7 +247,7 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0;
/* mesh sync */
- object->mesh = sync_mesh(b_ob, object_updated);
+ object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
/* sspecial case not tracked by object update flags */
if(use_holdout != object->use_holdout) {
@@ -390,7 +390,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
/* sync object and mesh or light data */
- Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion);
+ Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion, false);
/* sync possible particle data, note particle_id
* starts counting at 1, first is dummy particle */
@@ -412,9 +412,23 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
- if(b_psys->settings().use_render_emitter())
+ bool hair_present = false;
+ bool show_emitter = false;
+ bool hide_tris = false;
+
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
+
+ if((b_psys->settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
+ hair_present = true;
+
+ if(b_psys->settings().use_render_emitter()) {
hide = false;
+ show_emitter = true;
+ }
+ }
+
+ if(hair_present && !show_emitter)
+ hide_tris = true;
/* hide original object for duplis */
BL::Object parent = b_ob->parent();
@@ -424,7 +438,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
if(!hide) {
/* object itself */
Transform tfm = get_transform(b_ob->matrix_world());
- sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion);
+ sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion, hide_tris);
}
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index b8ed942..60dfe37 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -96,7 +96,7 @@ void BlenderSession::create_session()
session->set_pause(BlenderSync::get_session_pause(b_scene, background));
/* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
sync->sync_data(b_v3d, b_engine.camera_override());
if(b_rv3d)
@@ -107,6 +107,13 @@ void BlenderSession::create_session()
/* set buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
+
+ /* setup callbacks for builtin image support */
+ scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2);
+ scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2);
}
void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
@@ -137,18 +144,22 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
session->progress.reset();
scene->reset();
+ session->tile_manager.set_tile_order(session_params.tile_order);
+
/* peak memory usage should show current render peak, not peak for all renders
* made by this render session
*/
session->stats.mem_peak = session->stats.mem_used;
/* sync object should be re-created */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
sync->sync_data(b_v3d, b_engine.camera_override());
sync->sync_camera(b_engine.camera_override(), width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
+
+ b_engine.use_highlight_tiles(session_params.progressive_refine == false);
}
void BlenderSession::free_session()
@@ -252,7 +263,15 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
if (do_update_only) {
/* update only needed */
- update_render_result(b_rr, b_rlay, rtile);
+
+ if (rtile.sample != 0) {
+ /* sample would be zero at initial tile update, which is only needed
+ * to tag tile form blender side as IN PROGRESS for proper highlight
+ * no buffers should be sent to blender yet
+ */
+ update_render_result(b_rr, b_rlay, rtile);
+ }
+
end_render_result(b_engine, b_rr, true);
}
else {
@@ -593,5 +612,69 @@ void BlenderSession::test_cancel()
session->progress.set_cancel("Cancelled");
}
+void BlenderSession::builtin_image_info(const string &name, bool &is_float, int &width, int &height, int &channels)
+{
+ BL::Image b_image = b_data.images[name];
+
+ if(b_image) {
+ is_float = b_image.is_float();
+ width = b_image.size()[0];
+ height = b_image.size()[1];
+ channels = b_image.channels();
+ }
+ else {
+ is_float = false;
+ width = 0;
+ height = 0;
+ channels = 0;
+ }
+}
+
+bool BlenderSession::builtin_image_pixels(const string &name, unsigned char *pixels)
+{
+ BL::Image b_image = b_data.images[name];
+
+ if(b_image) {
+ int width = b_image.size()[0];
+ int height = b_image.size()[1];
+ int channels = b_image.channels();
+
+ BL::DynamicArray<float> pixels_array = b_image.pixels();
+ float *float_pixels = pixels_array.data;
+
+ /* a bit of shame, but Py API currently only returns float array,
+ * which need to be converted back to char buffer
+ */
+ unsigned char *cp = pixels;
+ float *fp = float_pixels;
+ for(int i = 0; i < channels * width * height; i++, cp++, fp++) {
+ *cp = *fp * 255;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool BlenderSession::builtin_image_float_pixels(const string &name, float *pixels)
+{
+ BL::Image b_image = b_data.images[name];
+
+ if(b_image) {
+ int width = b_image.size()[0];
+ int height = b_image.size()[1];
+ int channels = b_image.channels();
+
+ BL::DynamicArray<float> pixels_array = b_image.pixels();
+
+ memcpy(pixels, pixels_array.data, width * height * channels * sizeof(float));
+
+ return true;
+ }
+
+ return false;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 7f3973a..dfa487b 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -93,6 +93,10 @@ public:
protected:
void do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only);
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
+
+ void builtin_image_info(const string &name, bool &is_float, int &width, int &height, int &channels);
+ bool builtin_image_pixels(const string &name, unsigned char *pixels);
+ bool builtin_image_float_pixels(const string &name, float *pixels);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index c9380d8..3bb02bb 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -173,7 +173,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
switch(b_node.type()) {
/* not supported */
- case BL::ShaderNode::type_CURVE_VEC: break;
case BL::ShaderNode::type_GEOMETRY: break;
case BL::ShaderNode::type_MATERIAL: break;
case BL::ShaderNode::type_MATERIAL_EXT: break;
@@ -193,9 +192,18 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
node = proxy;
break;
}
+ case BL::ShaderNode::type_CURVE_VEC: {
+ BL::ShaderNodeVectorCurve b_curve_node(b_node);
+ VectorCurvesNode *curves = new VectorCurvesNode();
+ curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false);
+ node = curves;
+ break;
+ }
case BL::ShaderNode::type_CURVE_RGB: {
- RGBCurvesNode *ramp = new RGBCurvesNode();
- node = ramp;
+ BL::ShaderNodeRGBCurve b_curve_node(b_node);
+ RGBCurvesNode *curves = new RGBCurvesNode();
+ curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, true);
+ node = curves;
break;
}
case BL::ShaderNode::type_VALTORGB: {
@@ -439,6 +447,10 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
node = new ParticleInfoNode();
break;
}
+ case BL::ShaderNode::type_HAIR_INFO: {
+ node = new HairInfoNode();
+ break;
+ }
case BL::ShaderNode::type_BUMP: {
node = new BumpNode();
break;
@@ -499,9 +511,24 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexImage b_image_node(b_node);
BL::Image b_image(b_image_node.image());
ImageTextureNode *image = new ImageTextureNode();
- /* todo: handle generated/builtin images */
+ /* todo: handle movie images */
if(b_image && b_image.source() != BL::Image::source_MOVIE) {
- image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
+ /* builtin images will use callback-based reading because
+ * they could only be loaded correct from blender side
+ */
+ bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED;
+
+ if(is_builtin) {
+ /* for builtin images we're using image datablock name to find an image to read pixels from later */
+ image->filename = b_image.name();
+ image->is_builtin = true;
+ }
+ else {
+ image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
+ image->is_builtin = false;
+ }
+
image->animated = b_image_node.image_user().use_auto_refresh();
}
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
@@ -516,8 +543,17 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::Image b_image(b_env_node.image());
EnvironmentTextureNode *env = new EnvironmentTextureNode();
if(b_image && b_image.source() != BL::Image::source_MOVIE) {
- env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
- env->animated = b_env_node.image_user().use_auto_refresh();
+ bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED;
+
+ if(is_builtin) {
+ env->filename = b_image.name();
+ env->is_builtin = true;
+ }
+ else {
+ env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
+ env->animated = b_env_node.image_user().use_auto_refresh();
+ }
}
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index e78026e..a2a8c23 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -28,6 +28,7 @@
#include "object.h"
#include "scene.h"
#include "shader.h"
+#include "curves.h"
#include "device.h"
@@ -41,7 +42,7 @@ CCL_NAMESPACE_BEGIN
/* Constructor */
-BlenderSync::BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_, Scene *scene_, bool preview_, Progress &progress_)
+BlenderSync::BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::Scene b_scene_, Scene *scene_, bool preview_, Progress &progress_, bool is_cpu_)
: b_engine(b_engine_),
b_data(b_data_), b_scene(b_scene_),
shader_map(&scene_->shaders),
@@ -56,6 +57,7 @@ BlenderSync::BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data_, BL::
{
scene = scene_;
preview = preview_;
+ is_cpu = is_cpu_;
}
BlenderSync::~BlenderSync()
@@ -141,6 +143,7 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const
sync_integrator();
sync_film();
sync_shaders();
+ sync_curve_settings();
sync_objects(b_v3d);
sync_motion(b_v3d, b_override);
}
@@ -331,7 +334,13 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
/* device default CPU */
params.device = devices[0];
- if(RNA_enum_get(&cscene, "device") != 0) {
+ if(RNA_enum_get(&cscene, "device") == 2) {
+ /* find network device */
+ foreach(DeviceInfo& info, devices)
+ if(info.type == DEVICE_NETWORK)
+ params.device = info;
+ }
+ else if(RNA_enum_get(&cscene, "device") == 1) {
/* find GPU device with given id */
PointerRNA systemptr = b_userpref.system().ptr;
PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device");
@@ -387,6 +396,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.tile_size = make_int2(tile_x, tile_y);
}
+
+ params.tile_order = RNA_enum_get(&cscene, "tile_order");
params.start_resolution = get_int(cscene, "preview_start_resolution");
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index d3d21fb..5050743 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -50,7 +50,7 @@ class ShaderNode;
class BlenderSync {
public:
- BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data, BL::Scene b_scene, Scene *scene_, bool preview_, Progress &progress_);
+ BlenderSync(BL::RenderEngine b_engine_, BL::BlendData b_data, BL::Scene b_scene, Scene *scene_, bool preview_, Progress &progress_, bool is_cpu_);
~BlenderSync();
/* sync */
@@ -78,10 +78,12 @@ private:
void sync_world(bool update_all);
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
void sync_shaders();
+ void sync_curve_settings();
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
- Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
- Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion);
+ Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
+ void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool object_updated);
+ Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, bool hide_tris);
void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm);
void sync_background_light();
void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
@@ -113,6 +115,7 @@ private:
Scene *scene;
bool preview;
bool experimental;
+ bool is_cpu;
struct RenderLayerInfo {
RenderLayerInfo()
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 0a9f2dd..88c9886 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -52,6 +52,36 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size
}
}
+static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *data, int size, bool rgb_curve)
+{
+ cumap.update();
+
+ BL::CurveMap mapR = cumap.curves[0];
+ BL::CurveMap mapG = cumap.curves[1];
+ BL::CurveMap mapB = cumap.curves[2];
+
+ if(rgb_curve) {
+ BL::CurveMap mapI = cumap.curves[3];
+
+ for(int i = 0; i < size; i++) {
+ float t = i/(float)(size-1);
+
+ data[i][0] = mapR.evaluate(mapI.evaluate(t));
+ data[i][1] = mapG.evaluate(mapI.evaluate(t));
+ data[i][2] = mapB.evaluate(mapI.evaluate(t));
+ }
+ }
+ else {
+ for(int i = 0; i < size; i++) {
+ float t = i/(float)(size-1);
+
+ data[i][0] = mapR.evaluate(t);
+ data[i][1] = mapG.evaluate(t);
+ data[i][2] = mapB.evaluate(t);
+ }
+ }
+}
+
static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview)
{
return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
@@ -212,6 +242,20 @@ static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, co
return path;
}
+/* Texture Space */
+
+static inline void mesh_texture_space(BL::Mesh b_mesh, float3& loc, float3& size)
+{
+ loc = get_float3(b_mesh.texspace_location());
+ size = get_float3(b_mesh.texspace_size());
+
+ if(size.x != 0.0f) size.x = 0.5f/size.x;
+ if(size.y != 0.0f) size.y = 0.5f/size.y;
+ if(size.z != 0.0f) size.z = 0.5f/size.z;
+
+ loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+}
+
/* ID Map
*
* Utility class to keep in sync with blender data.
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index b58a34f..412b440 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -75,6 +75,8 @@ bool BVH::cache_read(CacheData& key)
foreach(Object *ob, objects) {
key.add(ob->mesh->verts);
key.add(ob->mesh->triangles);
+ key.add(ob->mesh->curve_keys);
+ key.add(ob->mesh->curves);
key.add(&ob->bounds, sizeof(ob->bounds));
key.add(&ob->visibility, sizeof(ob->visibility));
key.add(&ob->mesh->transform_applied, sizeof(bool));
@@ -91,6 +93,7 @@ bool BVH::cache_read(CacheData& key)
value.read(pack.nodes);
value.read(pack.object_node);
value.read(pack.tri_woop);
+ value.read(pack.prim_segment);
value.read(pack.prim_visibility);
value.read(pack.prim_index);
value.read(pack.prim_object);
@@ -112,6 +115,7 @@ void BVH::cache_write(CacheData& key)
value.add(pack.nodes);
value.add(pack.object_node);
value.add(pack.tri_woop);
+ value.add(pack.prim_segment);
value.add(pack.prim_visibility);
value.add(pack.prim_index);
value.add(pack.prim_object);
@@ -157,10 +161,11 @@ void BVH::build(Progress& progress)
}
/* build nodes */
+ vector<int> prim_segment;
vector<int> prim_index;
vector<int> prim_object;
- BVHBuild bvh_build(objects, prim_index, prim_object, params, progress);
+ BVHBuild bvh_build(objects, prim_segment, prim_index, prim_object, params, progress);
BVHNode *root = bvh_build.run();
if(progress.get_cancel()) {
@@ -169,6 +174,7 @@ void BVH::build(Progress& progress)
}
/* todo: get rid of this copy */
+ pack.prim_segment = prim_segment;
pack.prim_index = prim_index;
pack.prim_object = prim_object;
@@ -182,8 +188,8 @@ void BVH::build(Progress& progress)
}
/* pack triangles */
- progress.set_substatus("Packing BVH triangles");
- pack_triangles();
+ progress.set_substatus("Packing BVH triangles and strands");
+ pack_primitives();
if(progress.get_cancel()) {
root->deleteSubtree();
@@ -215,8 +221,8 @@ void BVH::build(Progress& progress)
void BVH::refit(Progress& progress)
{
- progress.set_substatus("Packing BVH triangles");
- pack_triangles();
+ progress.set_substatus("Packing BVH primitives");
+ pack_primitives();
if(progress.get_cancel()) return;
@@ -263,7 +269,52 @@ void BVH::pack_triangle(int idx, float4 woop[3])
}
}
-void BVH::pack_triangles()
+/* Curves*/
+
+void BVH::pack_curve_segment(int idx, float4 woop[3])
+{
+ int tob = pack.prim_object[idx];
+ const Mesh *mesh = objects[tob]->mesh;
+ int tidx = pack.prim_index[idx];
+ int segment = pack.prim_segment[idx];
+ int k0 = mesh->curves[tidx].first_key + segment;
+ int k1 = mesh->curves[tidx].first_key + segment + 1;
+ float3 v0 = mesh->curve_keys[k0].co;
+ float3 v1 = mesh->curve_keys[k1].co;
+
+ float3 d0 = v1 - v0;
+ float l = len(d0);
+
+ /*Plan
+ *Transform tfm = make_transform(
+ * location <3> , l,
+ * extra curve data <3> , StrID,
+ * nextkey, flags/tip?, 0, 0);
+ */
+ Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
+ float3 tg0 = make_float3(1.0f, 0.0f, 0.0f);
+ float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
+
+ if(attr_tangent) {
+ const float3 *data_tangent = attr_tangent->data_float3();
+
+ tg0 = data_tangent[k0];
+ tg1 = data_tangent[k1];
+ }
+
+ Transform tfm = make_transform(
+ tg0.x, tg0.y, tg0.z, l,
+ tg1.x, tg1.y, tg1.z, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1);
+
+ woop[0] = tfm.x;
+ woop[1] = tfm.y;
+ woop[2] = tfm.z;
+
+}
+
+void BVH::pack_primitives()
{
int nsize = TRI_NODE_SIZE;
size_t tidx_size = pack.prim_index.size();
@@ -277,7 +328,11 @@ void BVH::pack_triangles()
if(pack.prim_index[i] != -1) {
float4 woop[3];
- pack_triangle(i, woop);
+ if(pack.prim_segment[i] != ~0)
+ pack_curve_segment(i, woop);
+ else
+ pack_triangle(i, woop);
+
memcpy(&pack.tri_woop[i * nsize], woop, sizeof(float4)*3);
int tob = pack.prim_object[i];
@@ -300,11 +355,15 @@ void BVH::pack_instances(size_t nodes_size)
/* adjust primitive index to point to the triangle in the global array, for
* meshes with transform applied and already in the top level BVH */
for(size_t i = 0; i < pack.prim_index.size(); i++)
- if(pack.prim_index[i] != -1)
- pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ if(pack.prim_index[i] != -1) {
+ if(pack.prim_segment[i] != ~0)
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->curve_offset;
+ else
+ pack.prim_index[i] += objects[pack.prim_object[i]]->mesh->tri_offset;
+ }
/* track offsets of instanced BVH data in global array */
- size_t tri_offset = pack.prim_index.size();
+ size_t prim_offset = pack.prim_index.size();
size_t nodes_offset = nodes_size;
/* clear array that gives the node indexes for instanced objects */
@@ -339,6 +398,7 @@ void BVH::pack_instances(size_t nodes_size)
mesh_map.clear();
pack.prim_index.resize(prim_index_size);
+ pack.prim_segment.resize(prim_index_size);
pack.prim_object.resize(prim_index_size);
pack.prim_visibility.resize(prim_index_size);
pack.tri_woop.resize(tri_woop_size);
@@ -346,6 +406,7 @@ void BVH::pack_instances(size_t nodes_size)
pack.object_node.resize(objects.size());
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
+ int *pack_prim_segment = (pack.prim_segment.size())? &pack.prim_segment[0]: NULL;
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
float4 *pack_tri_woop = (pack.tri_woop.size())? &pack.tri_woop[0]: NULL;
@@ -376,6 +437,7 @@ void BVH::pack_instances(size_t nodes_size)
int noffset = nodes_offset/nsize;
int mesh_tri_offset = mesh->tri_offset;
+ int mesh_curve_offset = mesh->curve_offset;
/* fill in node indexes for instances */
if((bvh->pack.is_leaf.size() != 0) && bvh->pack.is_leaf[0])
@@ -389,10 +451,16 @@ void BVH::pack_instances(size_t nodes_size)
if(bvh->pack.prim_index.size()) {
size_t bvh_prim_index_size = bvh->pack.prim_index.size();
int *bvh_prim_index = &bvh->pack.prim_index[0];
+ int *bvh_prim_segment = &bvh->pack.prim_segment[0];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
for(size_t i = 0; i < bvh_prim_index_size; i++) {
- pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+ if(bvh->pack.prim_segment[i] != ~0)
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
+ else
+ pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
+
+ pack_prim_segment[pack_prim_index_offset] = bvh_prim_segment[i];
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
pack_prim_index_offset++;
@@ -401,7 +469,7 @@ void BVH::pack_instances(size_t nodes_size)
/* merge triangle intersection data */
if(bvh->pack.tri_woop.size()) {
- memcpy(pack_tri_woop+pack_tri_woop_offset, &bvh->pack.tri_woop[0],
+ memcpy(pack_tri_woop + pack_tri_woop_offset, &bvh->pack.tri_woop[0],
bvh->pack.tri_woop.size()*sizeof(float4));
pack_tri_woop_offset += bvh->pack.tri_woop.size();
}
@@ -420,8 +488,8 @@ void BVH::pack_instances(size_t nodes_size)
int4 data = bvh_nodes[i + nsize_bbox];
if(bvh_is_leaf && bvh_is_leaf[j]) {
- data.x += tri_offset;
- data.y += tri_offset;
+ data.x += prim_offset;
+ data.y += prim_offset;
}
else {
data.x += (data.x < 0)? -noffset: noffset;
@@ -443,7 +511,7 @@ void BVH::pack_instances(size_t nodes_size)
}
nodes_offset += bvh->pack.nodes.size();
- tri_offset += bvh->pack.prim_index.size();
+ prim_offset += bvh->pack.prim_index.size();
}
}
@@ -544,25 +612,38 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
if(leaf) {
/* refit leaf node */
- for(int tri = c0; tri < c1; tri++) {
- int tidx = pack.prim_index[tri];
- int tob = pack.prim_object[tri];
+ for(int prim = c0; prim < c1; prim++) {
+ int pidx = pack.prim_index[prim];
+ int tob = pack.prim_object[prim];
Object *ob = objects[tob];
- if(tidx == -1) {
+ if(pidx == -1) {
/* object instance */
bbox.grow(ob->bounds);
}
else {
- /* triangles */
+ /* primitives */
const Mesh *mesh = ob->mesh;
- int tri_offset = (params.top_level)? mesh->tri_offset: 0;
- const int *vidx = mesh->triangles[tidx - tri_offset].v;
- const float3 *vpos = &mesh->verts[0];
- bbox.grow(vpos[vidx[0]]);
- bbox.grow(vpos[vidx[1]]);
- bbox.grow(vpos[vidx[2]]);
+ if(pack.prim_segment[prim] != ~0) {
+ /* curves */
+ int str_offset = (params.top_level)? mesh->curve_offset: 0;
+ int k0 = mesh->curves[pidx - str_offset].first_key + pack.prim_segment[prim]; // XXX!
+ int k1 = k0 + 1;
+
+ bbox.grow(mesh->curve_keys[k0].co, mesh->curve_keys[k0].radius);
+ bbox.grow(mesh->curve_keys[k1].co, mesh->curve_keys[k1].radius);
+ }
+ else {
+ /* triangles */
+ int tri_offset = (params.top_level)? mesh->tri_offset: 0;
+ const int *vidx = mesh->triangles[pidx - tri_offset].v;
+ const float3 *vpos = &mesh->verts[0];
+
+ bbox.grow(vpos[vidx[0]]);
+ bbox.grow(vpos[vidx[1]]);
+ bbox.grow(vpos[vidx[2]]);
+ }
}
visibility |= ob->visibility;
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 549f1e3..00c1461 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -51,7 +51,9 @@ struct PackedBVH {
/* object index to BVH node index mapping for instances */
array<int> object_node;
/* precomputed triangle intersection data, one triangle is 4x float4 */
- array<float4> tri_woop;
+ array<float4> tri_woop;
+ /* primitive type - triangle or strand (should be moved to flag?) */
+ array<int> prim_segment;
/* visibility visibilitys for primitives */
array<uint> prim_visibility;
/* mapping from BVH primitive index to true primitive index, as primitives
@@ -101,9 +103,10 @@ protected:
bool cache_read(CacheData& key);
void cache_write(CacheData& key);
- /* triangles */
- void pack_triangles();
+ /* triangles and strands*/
+ void pack_primitives();
void pack_triangle(int idx, float4 woop[3]);
+ void pack_curve_segment(int idx, float4 woop[3]);
/* merge instance BVH's */
void pack_instances(size_t nodes_size);
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 705b805..38fb1a1 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -48,9 +48,10 @@ public:
/* Constructor / Destructor */
BVHBuild::BVHBuild(const vector<Object*>& objects_,
- vector<int>& prim_index_, vector<int>& prim_object_,
+ vector<int>& prim_segment_, vector<int>& prim_index_, vector<int>& prim_object_,
const BVHParams& params_, Progress& progress_)
: objects(objects_),
+ prim_segment(prim_segment_),
prim_index(prim_index_),
prim_object(prim_object_),
params(params_),
@@ -73,25 +74,55 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
BoundBox bounds = BoundBox::empty;
for(int k = 0; k < 3; k++) {
- float3 pt = mesh->verts[t.v[k]];
- bounds.grow(pt);
+ float3 co = mesh->verts[t.v[k]];
+ bounds.grow(co);
}
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i));
+ references.push_back(BVHReference(bounds, j, i, ~0));
root.grow(bounds);
center.grow(bounds.center2());
}
}
+
+ for(uint j = 0; j < mesh->curves.size(); j++) {
+ Mesh::Curve curve = mesh->curves[j];
+
+ for(int k = 0; k < curve.num_keys - 1; k++) {
+ BoundBox bounds = BoundBox::empty;
+
+ float3 co0 = mesh->curve_keys[curve.first_key + k].co;
+ float3 co1 = mesh->curve_keys[curve.first_key + k + 1].co;
+
+ bounds.grow(co0, mesh->curve_keys[curve.first_key + k].radius);
+ bounds.grow(co1, mesh->curve_keys[curve.first_key + k + 1].radius);
+
+ if(bounds.valid()) {
+ references.push_back(BVHReference(bounds, j, i, k));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ }
}
void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
{
- references.push_back(BVHReference(ob->bounds, -1, i));
+ references.push_back(BVHReference(ob->bounds, -1, i, false));
root.grow(ob->bounds);
center.grow(ob->bounds.center2());
}
+static size_t count_curve_segments(Mesh *mesh)
+{
+ size_t num = 0, num_curves = mesh->curves.size();
+
+ for(size_t i = 0; i < num_curves; i++)
+ num += mesh->curves[i].num_keys - 1;
+
+ return num;
+}
+
void BVHBuild::add_references(BVHRange& root)
{
/* reserve space for references */
@@ -99,13 +130,17 @@ void BVHBuild::add_references(BVHRange& root)
foreach(Object *ob, objects) {
if(params.top_level) {
- if(ob->mesh->transform_applied)
+ if(ob->mesh->transform_applied) {
num_alloc_references += ob->mesh->triangles.size();
+ num_alloc_references += count_curve_segments(ob->mesh);
+ }
else
num_alloc_references++;
}
- else
+ else {
num_alloc_references += ob->mesh->triangles.size();
+ num_alloc_references += count_curve_segments(ob->mesh);
+ }
}
references.reserve(num_alloc_references);
@@ -162,6 +197,7 @@ BVHNode* BVHBuild::run()
progress_total = references.size();
progress_original_total = progress_total;
+ prim_segment.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
@@ -319,10 +355,12 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
if(start == prim_index.size()) {
assert(params.use_spatial_split);
+ prim_segment.push_back(ref->prim_segment());
prim_index.push_back(ref->prim_index());
prim_object.push_back(ref->prim_object());
}
else {
+ prim_segment[start] = ref->prim_segment();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
}
@@ -345,6 +383,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
{
+ vector<int>& p_segment = prim_segment;
vector<int>& p_index = prim_index;
vector<int>& p_object = prim_object;
BoundBox bounds = BoundBox::empty;
@@ -358,10 +397,12 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
if(range.start() + num == prim_index.size()) {
assert(params.use_spatial_split);
+ p_segment.push_back(ref.prim_segment());
p_index.push_back(ref.prim_index());
p_object.push_back(ref.prim_object());
}
else {
+ p_segment[range.start() + num] = ref.prim_segment();
p_index[range.start() + num] = ref.prim_index();
p_object[range.start() + num] = ref.prim_object();
}
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index 44ef918..3df4da1 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -44,6 +44,7 @@ public:
/* Constructor/Destructor */
BVHBuild(
const vector<Object*>& objects,
+ vector<int>& prim_segment,
vector<int>& prim_index,
vector<int>& prim_object,
const BVHParams& params,
@@ -87,6 +88,7 @@ protected:
int num_original_references;
/* output primitive indexes and objects */
+ vector<int>& prim_segment;
vector<int>& prim_index;
vector<int>& prim_object;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index a78496d..f7bc79f 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -98,19 +98,22 @@ class BVHReference
public:
__forceinline BVHReference() {}
- __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_)
+ __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_segment)
: rbounds(bounds_)
{
rbounds.min.w = __int_as_float(prim_index_);
rbounds.max.w = __int_as_float(prim_object_);
+ segment = prim_segment;
}
__forceinline const BoundBox& bounds() const { return rbounds; }
__forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
+ __forceinline int prim_segment() const { return segment; }
protected:
BoundBox rbounds;
+ uint segment;
};
/* BVH Range
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index bef384b..91994be 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -43,6 +43,8 @@ public:
else if(ra.prim_object() > rb.prim_object()) return false;
else if(ra.prim_index() < rb.prim_index()) return true;
else if(ra.prim_index() > rb.prim_index()) return false;
+ else if(ra.prim_segment() < rb.prim_segment()) return true;
+ else if(ra.prim_segment() > rb.prim_segment()) return false;
return false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 263c583..03ff69d 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -252,14 +252,41 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
/* loop over vertices/edges. */
Object *ob = builder->objects[ref.prim_object()];
const Mesh *mesh = ob->mesh;
- const int *inds = mesh->triangles[ref.prim_index()].v;
- const float3 *verts = &mesh->verts[0];
- const float3* v1 = &verts[inds[2]];
-
- for(int i = 0; i < 3; i++) {
- const float3* v0 = v1;
- int vindex = inds[i];
- v1 = &verts[vindex];
+
+ if (ref.prim_segment() == ~0) {
+ const int *inds = mesh->triangles[ref.prim_index()].v;
+ const float3 *verts = &mesh->verts[0];
+ const float3* v1 = &verts[inds[2]];
+
+ for(int i = 0; i < 3; i++) {
+ const float3* v0 = v1;
+ int vindex = inds[i];
+ v1 = &verts[vindex];
+ float v0p = (*v0)[dim];
+ float v1p = (*v1)[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if(v0p <= pos)
+ left_bounds.grow(*v0);
+
+ if(v0p >= pos)
+ right_bounds.grow(*v0);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
+ }
+ }
+ else {
+ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
+ const int k0 = mesh->curves[ref.prim_index()].first_key + ref.prim_segment();
+ const int k1 = k0 + 1;
+ const float3* v0 = &mesh->curve_keys[k0].co;
+ const float3* v1 = &mesh->curve_keys[k1].co;
+
float v0p = (*v0)[dim];
float v1p = (*v1)[dim];
@@ -270,6 +297,12 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
if(v0p >= pos)
right_bounds.grow(*v0);
+ if(v1p <= pos)
+ left_bounds.grow(*v1);
+
+ if(v1p >= pos)
+ right_bounds.grow(*v1);
+
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
@@ -284,9 +317,9 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
left_bounds.intersect(ref.bounds());
right_bounds.intersect(ref.bounds());
- /* set referecnes */
- left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object());
- right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object());
+ /* set references */
+ left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
+ right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_segment());
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 0071bbe..661d43a 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -18,11 +18,14 @@ set(SRC
device_cpu.cpp
device_cuda.cpp
device_multi.cpp
- device_network.cpp
device_opencl.cpp
device_task.cpp
)
+if(WITH_NETWORK)
+ list(APPEND SRC device_network.cpp)
+endif()
+
set(SRC_HEADERS
device.h
device_memory.h
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 9840687..7b31b9b 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -84,6 +84,7 @@ public:
/* info */
DeviceInfo info;
virtual const string& error_message() { return error_msg; }
+ bool have_error() { return !error_message().empty(); }
/* statistics */
Stats &stats;
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 14f8cfa..040f304 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -124,7 +124,7 @@ public:
if(error_msg == "") \
error_msg = message; \
fprintf(stderr, "%s\n", message.c_str()); \
- cuda_abort(); \
+ /*cuda_abort();*/ \
} \
}
@@ -326,7 +326,8 @@ public:
void mem_copy_to(device_memory& mem)
{
cuda_push_context();
- cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer), (void*)mem.data_pointer, mem.memory_size()))
+ if(mem.device_pointer)
+ cuda_assert(cuMemcpyHtoD(cuda_device_ptr(mem.device_pointer), (void*)mem.data_pointer, mem.memory_size()))
cuda_pop_context();
}
@@ -336,8 +337,13 @@ public:
size_t size = elem*w*h;
cuda_push_context();
- cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset,
- (CUdeviceptr)((uchar*)mem.device_pointer + offset), size))
+ if(mem.device_pointer) {
+ cuda_assert(cuMemcpyDtoH((uchar*)mem.data_pointer + offset,
+ (CUdeviceptr)((uchar*)mem.device_pointer + offset), size))
+ }
+ else {
+ memset((char*)mem.data_pointer + offset, 0, size);
+ }
cuda_pop_context();
}
@@ -346,7 +352,8 @@ public:
memset((void*)mem.data_pointer, 0, mem.memory_size());
cuda_push_context();
- cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()))
+ if(mem.device_pointer)
+ cuda_assert(cuMemsetD8(cuda_device_ptr(mem.device_pointer), 0, mem.memory_size()))
cuda_pop_context();
}
@@ -390,13 +397,18 @@ public:
default: assert(0); return;
}
- CUtexref texref;
+ CUtexref texref = NULL;
cuda_push_context();
cuda_assert(cuModuleGetTexRef(&texref, cuModule, name))
+ if(!texref) {
+ cuda_pop_context();
+ return;
+ }
+
if(interpolation) {
- CUarray handle;
+ CUarray handle = NULL;
CUDA_ARRAY_DESCRIPTOR desc;
desc.Width = mem.data_width;
@@ -406,6 +418,11 @@ public:
cuda_assert(cuArrayCreate(&handle, &desc))
+ if(!handle) {
+ cuda_pop_context();
+ return;
+ }
+
if(mem.data_height > 1) {
CUDA_MEMCPY2D param;
memset(¶m, 0, sizeof(param));
@@ -481,6 +498,9 @@ public:
void path_trace(RenderTile& rtile, int sample)
{
+ if(have_error())
+ return;
+
cuda_push_context();
CUfunction cuPathTrace;
@@ -546,6 +566,9 @@ public:
void tonemap(DeviceTask& task, device_ptr buffer, device_ptr rgba)
{
+ if(have_error())
+ return;
+
cuda_push_context();
CUfunction cuFilmConvert;
@@ -615,6 +638,9 @@ public:
void shader(DeviceTask& task)
{
+ if(have_error())
+ return;
+
cuda_push_context();
CUfunction cuDisplace;
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index a5e0d39..f5545c3 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -31,6 +31,8 @@ class NetworkDevice : public Device
public:
boost::asio::io_service io_service;
tcp::socket socket;
+ device_ptr mem_counter;
+ DeviceTask the_task; /* todo: handle multiple tasks */
NetworkDevice(Stats &stats, const char *address)
: Device(stats), socket(io_service)
@@ -49,75 +51,72 @@ public:
socket.close();
socket.connect(*endpoint_iterator++, error);
}
+
if(error)
throw boost::system::system_error(error);
+
+ mem_counter = 0;
}
~NetworkDevice()
{
+ RPCSend snd(socket, "stop");
+ snd.write();
}
void mem_alloc(device_memory& mem, MemoryType type)
{
-#if 0
+ mem.device_pointer = ++mem_counter;
+
RPCSend snd(socket, "mem_alloc");
- snd.archive & size & type;
+ snd.add(mem);
+ snd.add(type);
snd.write();
-
- RPCReceive rcv(socket);
-
- device_ptr mem;
- *rcv.archive & mem;
-
- return mem;
-#endif
}
void mem_copy_to(device_memory& mem)
{
-#if 0
RPCSend snd(socket, "mem_copy_to");
- snd.archive & mem & size;
+ snd.add(mem);
snd.write();
- snd.write_buffer(host, size);
-#endif
+ snd.write_buffer((void*)mem.data_pointer, mem.memory_size());
}
void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
{
-#if 0
RPCSend snd(socket, "mem_copy_from");
- snd.archive & mem & offset & size;
+ snd.add(mem);
+ snd.add(y);
+ snd.add(w);
+ snd.add(h);
+ snd.add(elem);
snd.write();
RPCReceive rcv(socket);
- rcv.read_buffer(host, size);
-#endif
+ rcv.read_buffer((void*)mem.data_pointer, mem.memory_size());
}
void mem_zero(device_memory& mem)
{
-#if 0
RPCSend snd(socket, "mem_zero");
- snd.archive & mem & size;
+ snd.add(mem);
snd.write();
-#endif
}
void mem_free(device_memory& mem)
{
-#if 0
- if(mem) {
+ if(mem.device_pointer) {
RPCSend snd(socket, "mem_free");
- snd.archive & mem;
+ snd.add(mem);
snd.write();
+
+ mem.device_pointer = 0;
}
-#endif
}
void const_copy_to(const char *name, void *host, size_t size)
@@ -126,79 +125,107 @@ public:
string name_string(name);
- snd.archive & name_string & size;
+ snd.add(name_string);
+ snd.add(size);
snd.write();
snd.write_buffer(host, size);
}
void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
{
-#if 0
+ mem.device_pointer = ++mem_counter;
+
RPCSend snd(socket, "tex_alloc");
string name_string(name);
- snd.archive & name_string & width & height & datatype & components & interpolation;
+ snd.add(name_string);
+ snd.add(mem);
+ snd.add(interpolation);
+ snd.add(periodic);
snd.write();
-
- size_t size = width*height*components*datatype_size(datatype);
- snd.write_buffer(host, size);
-
- RPCReceive rcv(socket);
-
- device_ptr mem;
- *rcv.archive & mem;
-
- return mem;
-#endif
+ snd.write_buffer((void*)mem.data_pointer, mem.memory_size());
}
void tex_free(device_memory& mem)
{
-#if 0
- if(mem) {
+ if(mem.device_pointer) {
RPCSend snd(socket, "tex_free");
- snd.archive & mem;
+ snd.add(mem);
snd.write();
+
+ mem.device_pointer = 0;
}
-#endif
}
- void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int sample)
+ void task_add(DeviceTask& task)
{
-#if 0
- RPCSend snd(socket, "path_trace");
+ the_task = task;
- snd.archive & x & y & w & h & buffer & rng_state & sample;
+ RPCSend snd(socket, "task_add");
+ snd.add(task);
snd.write();
-#endif
}
- void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int sample, int resolution)
+ void task_wait()
{
-#if 0
- RPCSend snd(socket, "tonemap");
-
- snd.archive & x & y & w & h & rgba & buffer & sample & resolution;
+ RPCSend snd(socket, "task_wait");
snd.write();
-#endif
- }
- void task_add(DeviceTask& task)
- {
- if(task.type == DeviceTask::TONEMAP)
- tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.sample, task.resolution);
- else if(task.type == DeviceTask::PATH_TRACE)
- path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.sample);
+ list<RenderTile> the_tiles;
+
+ /* todo: run this threaded for connecting to multiple clients */
+ for(;;) {
+ RPCReceive rcv(socket);
+ RenderTile tile;
+
+ if(rcv.name == "acquire_tile") {
+ /* todo: watch out for recursive calls! */
+ if(the_task.acquire_tile(this, tile)) { /* write return as bool */
+ the_tiles.push_back(tile);
+
+ RPCSend snd(socket, "acquire_tile");
+ snd.add(tile);
+ snd.write();
+ }
+ else {
+ RPCSend snd(socket, "acquire_tile_none");
+ snd.write();
+ }
+ }
+ else if(rcv.name == "release_tile") {
+ rcv.read(tile);
+
+ for(list<RenderTile>::iterator it = the_tiles.begin(); it != the_tiles.end(); it++) {
+ if(tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample) {
+ tile.buffers = it->buffers;
+ the_tiles.erase(it);
+ break;
+ }
+ }
+
+ assert(tile.buffers != NULL);
+
+ the_task.release_tile(tile);
+
+ RPCSend snd(socket, "release_tile");
+ snd.write();
+ }
+ else if(rcv.name == "task_wait_done")
+ break;
+ }
}
- void task_wait()
+ void task_cancel()
{
+ RPCSend snd(socket, "task_cancel");
+ snd.write();
}
- void task_cancel()
+ bool support_advanced_shading()
{
+ return true; /* todo: get this info from device */
}
};
@@ -219,162 +246,303 @@ void device_network_info(vector<DeviceInfo>& devices)
devices.push_back(info);
}
-void Device::server_run()
-{
- try
+class DeviceServer {
+public:
+ DeviceServer(Device *device_, tcp::socket& socket_)
+ : device(device_), socket(socket_)
{
- /* starts thread that responds to discovery requests */
- ServerDiscovery discovery;
+ }
- for(;;)
- {
+ void listen()
+ {
+ /* receive remote function calls */
+ for(;;) {
+ RPCReceive rcv(socket);
- /* accept connection */
- boost::asio::io_service io_service;
- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
+ if(rcv.name == "stop")
+ break;
- tcp::socket socket(io_service);
- acceptor.accept(socket);
+ process(rcv);
+ }
+ }
- /* receive remote function calls */
- for(;;) {
- RPCReceive rcv(socket);
+protected:
+ void process(RPCReceive& rcv)
+ {
+ // fprintf(stderr, "receive process %s\n", rcv.name.c_str());
- if(rcv.name == "description") {
- string desc = description();
+ if(rcv.name == "mem_alloc") {
+ MemoryType type;
+ network_device_memory mem;
+ device_ptr remote_pointer;
- RPCSend snd(socket);
- snd.archive & desc;
- snd.write();
- }
- else if(rcv.name == "mem_alloc") {
-#if 0
- MemoryType type;
- size_t size;
- device_ptr mem;
+ rcv.read(mem);
+ rcv.read(type);
- *rcv.archive & size & type;
- mem = mem_alloc(size, type);
+ /* todo: CPU needs mem.data_pointer */
- RPCSend snd(socket);
- snd.archive & mem;
- snd.write();
-#endif
- }
- else if(rcv.name == "mem_copy_to") {
-#if 0
- device_ptr mem;
- size_t size;
+ remote_pointer = mem.device_pointer;
- *rcv.archive & mem & size;
+ mem_data[remote_pointer] = vector<uint8_t>();
+ mem_data[remote_pointer].resize(mem.memory_size());
+ if(mem.memory_size())
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ else
+ mem.data_pointer = 0;
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
+ device->mem_alloc(mem, type);
- mem_copy_to(mem, &host_vector[0], size);
-#endif
- }
- else if(rcv.name == "mem_copy_from") {
-#if 0
- device_ptr mem;
- size_t offset, size;
+ ptr_map[remote_pointer] = mem.device_pointer;
+ ptr_imap[mem.device_pointer] = remote_pointer;
+ }
+ else if(rcv.name == "mem_copy_to") {
+ network_device_memory mem;
- *rcv.archive & mem & offset & size;
+ rcv.read(mem);
- vector<char> host_vector(size);
+ device_ptr remote_pointer = mem.device_pointer;
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
- mem_copy_from(&host_vector[0], mem, offset, size);
+ rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
- RPCSend snd(socket);
- snd.write();
- snd.write_buffer(&host_vector[0], size);
-#endif
- }
- else if(rcv.name == "mem_zero") {
-#if 0
- device_ptr mem;
- size_t size;
+ mem.device_pointer = ptr_map[remote_pointer];
- *rcv.archive & mem & size;
- mem_zero(mem, size);
-#endif
- }
- else if(rcv.name == "mem_free") {
-#if 0
- device_ptr mem;
+ device->mem_copy_to(mem);
+ }
+ else if(rcv.name == "mem_copy_from") {
+ network_device_memory mem;
+ int y, w, h, elem;
- *rcv.archive & mem;
- mem_free(mem);
-#endif
- }
- else if(rcv.name == "const_copy_to") {
- string name_string;
- size_t size;
+ rcv.read(mem);
+ rcv.read(y);
+ rcv.read(w);
+ rcv.read(h);
+ rcv.read(elem);
- *rcv.archive & name_string & size;
+ device_ptr remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[remote_pointer];
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
+ device->mem_copy_from(mem, y, w, h, elem);
- const_copy_to(name_string.c_str(), &host_vector[0], size);
- }
- else if(rcv.name == "tex_alloc") {
-#if 0
- string name_string;
- DataType datatype;
- device_ptr mem;
- size_t width, height;
- int components;
- bool interpolation;
+ RPCSend snd(socket);
+ snd.write();
+ snd.write_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+ }
+ else if(rcv.name == "mem_zero") {
+ network_device_memory mem;
+
+ rcv.read(mem);
+ device_ptr remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[mem.device_pointer];
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+
+ device->mem_zero(mem);
+ }
+ else if(rcv.name == "mem_free") {
+ network_device_memory mem;
+ device_ptr remote_pointer;
- *rcv.archive & name_string & width & height & datatype & components & interpolation;
+ rcv.read(mem);
- size_t size = width*height*components*datatype_size(datatype);
+ remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[mem.device_pointer];
+ ptr_map.erase(remote_pointer);
+ ptr_imap.erase(mem.device_pointer);
+ mem_data.erase(remote_pointer);
- vector<char> host_vector(size);
- rcv.read_buffer(&host_vector[0], size);
+ device->mem_free(mem);
+ }
+ else if(rcv.name == "const_copy_to") {
+ string name_string;
+ size_t size;
- mem = tex_alloc(name_string.c_str(), &host_vector[0], width, height, datatype, components, interpolation);
+ rcv.read(name_string);
+ rcv.read(size);
- RPCSend snd(socket);
- snd.archive & mem;
- snd.write();
-#endif
- }
- else if(rcv.name == "tex_free") {
-#if 0
- device_ptr mem;
+ vector<char> host_vector(size);
+ rcv.read_buffer(&host_vector[0], size);
- *rcv.archive & mem;
- tex_free(mem);
-#endif
- }
- else if(rcv.name == "path_trace") {
-#if 0
- device_ptr buffer, rng_state;
- int x, y, w, h;
- int sample;
-
- *rcv.archive & x & y & w & h & buffer & rng_state & sample;
- path_trace(x, y, w, h, buffer, rng_state, sample);
-#endif
- }
- else if(rcv.name == "tonemap") {
-#if 0
- device_ptr rgba, buffer;
- int x, y, w, h;
- int sample, resolution;
-
- *rcv.archive & x & y & w & h & rgba & buffer & sample & resolution;
- tonemap(x, y, w, h, rgba, buffer, sample, resolution);
-#endif
- }
+ device->const_copy_to(name_string.c_str(), &host_vector[0], size);
+ }
+ else if(rcv.name == "tex_alloc") {
+ network_device_memory mem;
+ string name;
+ bool interpolation;
+ bool periodic;
+ device_ptr remote_pointer;
+
+ rcv.read(name);
+ rcv.read(mem);
+ rcv.read(interpolation);
+ rcv.read(periodic);
+
+ remote_pointer = mem.device_pointer;
+
+ mem_data[remote_pointer] = vector<uint8_t>();
+ mem_data[remote_pointer].resize(mem.memory_size());
+ if(mem.memory_size())
+ mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
+ else
+ mem.data_pointer = 0;
+
+ rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
+
+ device->tex_alloc(name.c_str(), mem, interpolation, periodic);
+
+ ptr_map[remote_pointer] = mem.device_pointer;
+ ptr_imap[mem.device_pointer] = remote_pointer;
+ }
+ else if(rcv.name == "tex_free") {
+ network_device_memory mem;
+ device_ptr remote_pointer;
+
+ rcv.read(mem);
+
+ remote_pointer = mem.device_pointer;
+ mem.device_pointer = ptr_map[mem.device_pointer];
+ ptr_map.erase(remote_pointer);
+ ptr_map.erase(mem.device_pointer);
+ mem_data.erase(remote_pointer);
+
+ device->tex_free(mem);
+ }
+ else if(rcv.name == "task_add") {
+ DeviceTask task;
+
+ rcv.read(task);
+
+ if(task.buffer) task.buffer = ptr_map[task.buffer];
+ if(task.rgba) task.rgba = ptr_map[task.rgba];
+ if(task.shader_input) task.shader_input = ptr_map[task.shader_input];
+ if(task.shader_output) task.shader_output = ptr_map[task.shader_output];
+
+ task.acquire_tile = function_bind(&DeviceServer::task_acquire_tile, this, _1, _2);
+ task.release_tile = function_bind(&DeviceServer::task_release_tile, this, _1);
+ task.update_progress_sample = function_bind(&DeviceServer::task_update_progress_sample, this);
+ task.update_tile_sample = function_bind(&DeviceServer::task_update_tile_sample, this, _1);
+ task.get_cancel = function_bind(&DeviceServer::task_get_cancel, this);
+
+ device->task_add(task);
+ }
+ else if(rcv.name == "task_wait") {
+ device->task_wait();
+
+ RPCSend snd(socket, "task_wait_done");
+ snd.write();
+ }
+ else if(rcv.name == "task_cancel") {
+ device->task_cancel();
+ }
+ }
+
+ bool task_acquire_tile(Device *device, RenderTile& tile)
+ {
+ thread_scoped_lock acquire_lock(acquire_mutex);
+
+ bool result = false;
+
+ RPCSend snd(socket, "acquire_tile");
+ snd.write();
+
+ while(1) {
+ RPCReceive rcv(socket);
+
+ if(rcv.name == "acquire_tile") {
+ rcv.read(tile);
+
+ if(tile.buffer) tile.buffer = ptr_map[tile.buffer];
+ if(tile.rng_state) tile.rng_state = ptr_map[tile.rng_state];
+ if(tile.rgba) tile.rgba = ptr_map[tile.rgba];
+
+ result = true;
+ break;
}
+ else if(rcv.name == "acquire_tile_none")
+ break;
+ else
+ process(rcv);
}
+
+ return result;
}
- catch(exception& e)
+
+ void task_update_progress_sample()
{
- cerr << "Network server exception: " << e.what() << endl;
+ ; /* skip */
+ }
+
+ void task_update_tile_sample(RenderTile&)
+ {
+ ; /* skip */
+ }
+
+ void task_release_tile(RenderTile& tile)
+ {
+ thread_scoped_lock acquire_lock(acquire_mutex);
+
+ if(tile.buffer) tile.buffer = ptr_imap[tile.buffer];
+ if(tile.rng_state) tile.rng_state = ptr_imap[tile.rng_state];
+ if(tile.rgba) tile.rgba = ptr_imap[tile.rgba];
+
+ RPCSend snd(socket, "release_tile");
+ snd.add(tile);
+ snd.write();
+
+ while(1) {
+ RPCReceive rcv(socket);
+
+ if(rcv.name == "release_tile")
+ break;
+ else
+ process(rcv);
+ }
+ }
+
+ bool task_get_cancel()
+ {
+ return false;
+ }
+
+ /* properties */
+ Device *device;
+ tcp::socket& socket;
+
+ /* mapping of remote to local pointer */
+ map<device_ptr, device_ptr> ptr_map;
+ map<device_ptr, device_ptr> ptr_imap;
+ map<device_ptr, vector<uint8_t> > mem_data;
+
+ thread_mutex acquire_mutex;
+
+ /* todo: free memory and device (osl) on network error */
+};
+
+void Device::server_run()
+{
+ try {
+ /* starts thread that responds to discovery requests */
+ ServerDiscovery discovery;
+
+ for(;;) {
+ /* accept connection */
+ boost::asio::io_service io_service;
+ tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
+
+ tcp::socket socket(io_service);
+ acceptor.accept(socket);
+
+ string remote_address = socket.remote_endpoint().address().to_string();
+ printf("Connected to remote client at: %s\n", remote_address.c_str());
+
+ DeviceServer server(this, socket);
+ server.listen();
+
+ printf("Disconnected.\n");
+ }
+ }
+ catch(exception& e) {
+ fprintf(stderr, "Network server exception: %s\n", e.what());
}
}
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index e3afe46..b743298 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -31,15 +31,17 @@
#include <iostream>
+#include "buffers.h"
+
#include "util_foreach.h"
#include "util_list.h"
+#include "util_map.h"
#include "util_string.h"
CCL_NAMESPACE_BEGIN
using std::cout;
using std::cerr;
-using std::endl;
using std::hex;
using std::setw;
using std::exception;
@@ -51,13 +53,63 @@ static const int DISCOVER_PORT = 5121;
static const string DISCOVER_REQUEST_MSG = "REQUEST_RENDER_SERVER_IP";
static const string DISCOVER_REPLY_MSG = "REPLY_RENDER_SERVER_IP";
-typedef struct RPCSend {
+/* Serialization of device memory */
+
+class network_device_memory : public device_memory
+{
+public:
+ network_device_memory() {}
+ ~network_device_memory() { device_pointer = 0; };
+
+ vector<char> local_data;
+};
+
+/* Remote procedure call Send */
+
+class RPCSend {
+public:
RPCSend(tcp::socket& socket_, const string& name_ = "")
- : name(name_), socket(socket_), archive(archive_stream)
+ : name(name_), socket(socket_), archive(archive_stream), sent(false)
{
archive & name_;
}
+ ~RPCSend()
+ {
+ if(!sent)
+ fprintf(stderr, "Error: RPC %s not sent\n", name.c_str());
+ }
+
+ void add(const device_memory& mem)
+ {
+ archive & mem.data_type & mem.data_elements & mem.data_size;
+ archive & mem.data_width & mem.data_height & mem.device_pointer;
+ }
+
+ template<typename T> void add(const T& data)
+ {
+ archive & data;
+ }
+
+ void add(const DeviceTask& task)
+ {
+ int type = (int)task.type;
+
+ archive & type & task.x & task.y & task.w & task.h;
+ archive & task.rgba & task.buffer & task.sample & task.num_samples;
+ archive & task.resolution & task.offset & task.stride;
+ archive & task.shader_input & task.shader_output & task.shader_eval_type;
+ archive & task.shader_x & task.shader_w;
+ }
+
+ void add(const RenderTile& tile)
+ {
+ archive & tile.x & tile.y & tile.w & tile.h;
+ archive & tile.start_sample & tile.num_samples & tile.sample;
+ archive & tile.resolution & tile.offset & tile.stride;
+ archive & tile.buffer & tile.rng_state & tile.rgba;
+ }
+
void write()
{
boost::system::error_code error;
@@ -84,6 +136,8 @@ typedef struct RPCSend {
if(error.value())
cout << "Network send error: " << error.message() << "\n";
+
+ sent = true;
}
void write_buffer(void *buffer, size_t size)
@@ -98,13 +152,18 @@ typedef struct RPCSend {
cout << "Network send error: " << error.message() << "\n";
}
+protected:
string name;
tcp::socket& socket;
ostringstream archive_stream;
boost::archive::text_oarchive archive;
-} RPCSend;
+ bool sent;
+};
+
+/* Remote procedure call Receive */
-typedef struct RPCReceive {
+class RPCReceive {
+public:
RPCReceive(tcp::socket& socket_)
: socket(socket_), archive_stream(NULL), archive(NULL)
{
@@ -151,6 +210,19 @@ typedef struct RPCReceive {
delete archive_stream;
}
+ void read(network_device_memory& mem)
+ {
+ *archive & mem.data_type & mem.data_elements & mem.data_size;
+ *archive & mem.data_width & mem.data_height & mem.device_pointer;
+
+ mem.data_pointer = 0;
+ }
+
+ template<typename T> void read(T& data)
+ {
+ *archive & data;
+ }
+
void read_buffer(void *buffer, size_t size)
{
size_t len = boost::asio::read(socket, boost::asio::buffer(buffer, size));
@@ -159,12 +231,39 @@ typedef struct RPCReceive {
cout << "Network receive error: buffer size doesn't match expected size\n";
}
+ void read(DeviceTask& task)
+ {
+ int type;
+
+ *archive & type & task.x & task.y & task.w & task.h;
+ *archive & task.rgba & task.buffer & task.sample & task.num_samples;
+ *archive & task.resolution & task.offset & task.stride;
+ *archive & task.shader_input & task.shader_output & task.shader_eval_type;
+ *archive & task.shader_x & task.shader_w;
+
+ task.type = (DeviceTask::Type)type;
+ }
+
+ void read(RenderTile& tile)
+ {
+ *archive & tile.x & tile.y & tile.w & tile.h;
+ *archive & tile.start_sample & tile.num_samples & tile.sample;
+ *archive & tile.resolution & tile.offset & tile.stride;
+ *archive & tile.buffer & tile.rng_state & tile.rgba;
+
+ tile.buffers = NULL;
+ }
+
string name;
+
+protected:
tcp::socket& socket;
string archive_str;
istringstream *archive_stream;
boost::archive::text_iarchive *archive;
-} RPCReceive;
+};
+
+/* Server auto discovery */
class ServerDiscovery {
public:
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 5a57032..6d5b9a0 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -20,12 +20,12 @@ set(SRC
set(SRC_HEADERS
kernel.h
kernel_accumulate.h
- kernel_attribute.h
kernel_bvh.h
kernel_camera.h
kernel_compat_cpu.h
kernel_compat_cuda.h
kernel_compat_opencl.h
+ kernel_curve.h
kernel_differential.h
kernel_displace.h
kernel_emission.h
@@ -37,6 +37,7 @@ set(SRC_HEADERS
kernel_object.h
kernel_passes.h
kernel_path.h
+ kernel_primitive.h
kernel_projection.h
kernel_random.h
kernel_shader.h
@@ -49,12 +50,15 @@ set(SRC_CLOSURE_HEADERS
closure/bsdf.h
closure/bsdf_ashikhmin_velvet.h
closure/bsdf_diffuse.h
+ closure/bsdf_diffuse_ramp.h
closure/bsdf_microfacet.h
closure/bsdf_oren_nayar.h
closure/bsdf_phong_ramp.h
closure/bsdf_reflection.h
closure/bsdf_refraction.h
+ closure/bsdf_toon.h
closure/bsdf_transparent.h
+ closure/bsdf_util.h
closure/bsdf_ward.h
closure/bsdf_westin.h
closure/emissive.h
@@ -63,7 +67,6 @@ set(SRC_CLOSURE_HEADERS
set(SRC_SVM_HEADERS
svm/svm.h
svm/svm_attribute.h
- svm/svm_bsdf.h
svm/svm_camera.h
svm/svm_closure.h
svm/svm_convert.h
diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript
index 730f758..3a46d10 100644
--- a/intern/cycles/kernel/SConscript
+++ b/intern/cycles/kernel/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
import Blender as B
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index cfb6321..f26aefe 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -1,137 +1,296 @@
/*
- * Adapted from Open Shading Language with this license:
+ * Copyright 2011, Blender Foundation.
*
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
+ * 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.
*
- * Modifications Copyright 2011, Blender Foundation.
+ * 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.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Sony Pictures Imageworks nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
*/
-#ifndef __OSL_BSDF_H__
-#define __OSL_BSDF_H__
+#include "../closure/bsdf_ashikhmin_velvet.h"
+#include "../closure/bsdf_diffuse.h"
+#include "../closure/bsdf_oren_nayar.h"
+#include "../closure/bsdf_phong_ramp.h"
+#include "../closure/bsdf_diffuse_ramp.h"
+#include "../closure/bsdf_microfacet.h"
+#include "../closure/bsdf_reflection.h"
+#include "../closure/bsdf_refraction.h"
+#include "../closure/bsdf_transparent.h"
+#ifdef __ANISOTROPIC__
+#include "../closure/bsdf_ward.h"
+#endif
+#include "../closure/bsdf_westin.h"
CCL_NAMESPACE_BEGIN
-__device float fresnel_dielectric(float eta, const float3 N,
- const float3 I, float3 *R, float3 *T,
-#ifdef __RAY_DIFFERENTIALS__
- const float3 dIdx, const float3 dIdy,
- float3 *dRdx, float3 *dRdy,
- float3 *dTdx, float3 *dTdy,
-#endif
- bool *is_inside)
+__device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
{
- float cos = dot(N, I), neta;
- float3 Nn;
- // compute reflection
- *R = (2 * cos)* N - I;
-#ifdef __RAY_DIFFERENTIALS__
- *dRdx = (2 * dot(N, dIdx)) * N - dIdx;
- *dRdy = (2 * dot(N, dIdy)) * N - dIdy;
+ int label;
+
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
#endif
- // check which side of the surface we are on
- if(cos > 0) {
- // we are on the outside of the surface, going in
- neta = 1 / eta;
- Nn = N;
- *is_inside = false;
- }
- else {
- // we are inside the surface,
- cos = -cos;
- neta = eta;
- Nn = -N;
- *is_inside = true;
- }
- *R = (2 * cos)* Nn - I;
- float arg = 1 -(neta * neta *(1 -(cos * cos)));
- if(arg < 0) {
- *T = make_float3(0.0f, 0.0f, 0.0f);
-#ifdef __RAY_DIFFERENTIALS__
- *dTdx = make_float3(0.0f, 0.0f, 0.0f);
- *dTdy = make_float3(0.0f, 0.0f, 0.0f);
+
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;*/
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
#endif
- return 1; // total internal reflection
- }
- else {
- float dnp = sqrtf(arg);
- float nK = (neta * cos)- dnp;
- *T = -(neta * I)+(nK * Nn);
-#ifdef __RAY_DIFFERENTIALS__
- *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn;
- *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn;
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ break;
#endif
- // compute Fresnel terms
- float cosTheta1 = cos; // N.R
- float cosTheta2 = -dot(Nn, *T);
- float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
- float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
- return 0.5f * (pPara * pPara + pPerp * pPerp);
+ default:
+ label = LABEL_NONE;
+ break;
}
+
+ return label;
}
-__device float fresnel_dielectric_cos(float cosi, float eta)
+__device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
{
- // compute fresnel reflectance without explicitly computing
- // the refracted direction
- float c = fabsf(cosi);
- float g = eta * eta - 1 + c * c;
- if(g > 0) {
- g = sqrtf(g);
- float A = (g - c)/(g + c);
- float B = (c *(g + c)- 1)/(c *(g - c)+ 1);
- return 0.5f * A * A *(1 + B * B);
+ float3 eval;
+
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::bsdf_eval(sd, sc, omega_in, *pdf);
+#endif
+
+ if(dot(sd->Ng, omega_in) >= 0.0f) {
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;*/
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ default:
+ eval = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ }
+ else {
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
+ break;
+#endif
+ default:
+ eval = make_float3(0.0f, 0.0f, 0.0f);
+ break;
+ }
}
- return 1.0f; // TIR(no refracted component)
-}
-__device float fresnel_conductor(float cosi, float eta, float k)
-{
- float tmp_f = eta * eta + k * k;
- float tmp = tmp_f * cosi * cosi;
- float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/
- (tmp + (2.0f * eta * cosi) + 1);
- float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/
- (tmp_f + (2.0f * eta * cosi) + cosi * cosi);
- return(Rparl2 + Rperp2) * 0.5f;
+ return eval;
}
-__device float smooth_step(float edge0, float edge1, float x)
+__device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
{
- float result;
- if(x < edge0) result = 0.0f;
- else if(x >= edge1) result = 1.0f;
- else {
- float t = (x - edge0)/(edge1 - edge0);
- result = (3.0f-2.0f*t)*(t*t);
+#ifdef __OSL__
+ if(kg->osl && sc->prim) {
+ OSLShader::bsdf_blur(sc, roughness);
+ return;
+ }
+#endif
+
+ switch(sc->type) {
+ case CLOSURE_BSDF_DIFFUSE_ID:
+ bsdf_diffuse_blur(sc, roughness);
+ break;
+#ifdef __SVM__
+ case CLOSURE_BSDF_OREN_NAYAR_ID:
+ bsdf_oren_nayar_blur(sc, roughness);
+ break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ bsdf_phong_ramp_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
+ bsdf_diffuse_ramp_blur(sc, roughness);
+ break;*/
+ case CLOSURE_BSDF_TRANSLUCENT_ID:
+ bsdf_translucent_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_REFLECTION_ID:
+ bsdf_reflection_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_REFRACTION_ID:
+ bsdf_refraction_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_TRANSPARENT_ID:
+ bsdf_transparent_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
+ bsdf_microfacet_ggx_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
+ bsdf_microfacet_beckmann_blur(sc, roughness);
+ break;
+#ifdef __ANISOTROPIC__
+ case CLOSURE_BSDF_WARD_ID:
+ bsdf_ward_blur(sc, roughness);
+ break;
+#endif
+ case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
+ bsdf_ashikhmin_velvet_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
+ bsdf_westin_backscatter_blur(sc, roughness);
+ break;
+ case CLOSURE_BSDF_WESTIN_SHEEN_ID:
+ bsdf_westin_sheen_blur(sc, roughness);
+ break;
+#endif
+ default:
+ break;
}
- return result;
}
CCL_NAMESPACE_END
-#endif /* __OSL_BSDF_H__ */
-
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 016fd73..60f8091 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -134,8 +134,6 @@ __device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, fl
// TODO: find a better approximation for the retroreflective bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 88b40e3..46318ec 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -74,8 +74,6 @@ __device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, f
// TODO: find a better approximation for the diffuse bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else
@@ -126,10 +124,8 @@ __device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3
*eval = make_float3(*pdf, *pdf, *pdf);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= -125.0f;
- *domega_in_dy *= -125.0f;
+ *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
+ *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
#endif
}
else {
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
new file mode 100644
index 0000000..8a09979
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -0,0 +1,96 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2012, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BSDF_DIFFUSE_RAMP_H__
+#define __BSDF_DIFFUSE_RAMP_H__
+
+CCL_NAMESPACE_BEGIN
+
+__device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const float3 colors[8], float pos)
+{
+ int MAXCOLORS = 8;
+
+ float npos = pos * (float)(MAXCOLORS - 1);
+ int ipos = (int)npos;
+ if (ipos >= (MAXCOLORS - 1))
+ return colors[MAXCOLORS - 1];
+ float offset = npos - (float)ipos;
+ return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
+}
+
+__device int bsdf_diffuse_ramp_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
+}
+
+__device void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_diffuse_ramp_eval_reflect(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf)
+{
+ float3 N = sc->N;
+
+ float cos_pi = fmaxf(dot(N, omega_in), 0.0f);
+ *pdf = cos_pi * M_1_PI_F;
+ return bsdf_diffuse_ramp_get_color(sc, colors, cos_pi) * M_1_PI_F;
+}
+
+__device float3 bsdf_diffuse_ramp_eval_transmit(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_diffuse_ramp_sample(const ShaderClosure *sc, const float3 colors[8], float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+{
+ float3 N = sc->N;
+
+ // distribution over the hemisphere
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+
+ if(dot(Ng, *omega_in) > 0.0f) {
+ *eval = bsdf_diffuse_ramp_get_color(sc, colors, *pdf * M_PI_F) * M_1_PI_F;
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
+#endif
+ }
+ else
+ *pdf = 0.0f;
+
+ return LABEL_REFLECT|LABEL_DIFFUSE;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __BSDF_DIFFUSE_RAMP_H__ */
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index a564b99..019ec10 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -199,12 +199,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
#endif
}
}
@@ -251,14 +245,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa
// eq. 38 and eq. 17
*pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
*eval = make_float3(out, out, out);
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this refraction, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
-#endif
}
}
}
@@ -430,12 +416,6 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng,
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
*domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
#endif
}
}
@@ -486,14 +466,6 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng,
// eq. 38 and eq. 17
*pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
*eval = make_float3(out, out, out);
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this refraction, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
-#endif
}
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 066937d..770f06d 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -81,8 +81,6 @@ __device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I
// TODO: find a better approximation for the bounce
*domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
*domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else {
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 575a798..2f57fc1 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -119,15 +119,6 @@ __device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors
*pdf = (m_exponent + 1) * common;
float out = cosNI * (m_exponent + 2) * common;
*eval = bsdf_phong_ramp_get_color(sc, colors, cosp) * out;
-
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10;
- *domega_in_dy *= 10;
-#endif
}
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
new file mode 100644
index 0000000..40001bf
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -0,0 +1,206 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BSDF_TOON_H__
+#define __BSDF_TOON_H__
+
+CCL_NAMESPACE_BEGIN
+
+/* DIFFUSE TOON */
+
+__device int bsdf_diffuse_toon_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_DIFFUSE_TOON_ID;
+ sc->data0 = clamp(sc->data0, 0.0f, 1.0f);
+ sc->data1 = clamp(sc->data1, 0.0f, 1.0f);
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+__device void bsdf_diffuse_toon_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
+{
+ float is;
+
+ if(angle < max_angle)
+ is = 1.0f;
+ else if(angle < (max_angle + smooth) && smooth != 0.0f)
+ is = (1.0f - (angle - max_angle)/smooth);
+ else
+ is = 0.0f;
+
+ return make_float3(is, is, is);
+}
+
+__device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
+{
+ return fminf(max_angle + smooth, M_PI_2_F);
+}
+
+__device float3 bsdf_diffuse_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float angle = safe_acosf(fmaxf(dot(sc->N, omega_in), 0.0f));
+
+ float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+
+ if(eval.x > 0.0f) {
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return *pdf * eval;
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device float3 bsdf_diffuse_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_diffuse_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float angle = sample_angle*randu;
+
+ if(sample_angle > 0.0f) {
+ sample_uniform_cone(sc->N, sample_angle, randu, randv, omega_in, pdf);
+
+ if(dot(Ng, *omega_in) > 0.0f) {
+ *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+
+#ifdef __RAY_DIFFERENTIALS__
+ // TODO: find a better approximation for the bounce
+ *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
+#endif
+ }
+ else
+ *pdf = 0.0f;
+ }
+
+ return LABEL_REFLECT | LABEL_DIFFUSE;
+
+}
+
+/* SPECULAR TOON */
+
+__device int bsdf_specular_toon_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_SPECULAR_TOON_ID;
+ sc->data0 = clamp(sc->data0, 0.0f, 1.0f);
+ sc->data1 = clamp(sc->data1, 0.0f, 1.0f);
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+__device void bsdf_specular_toon_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_specular_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float cosNI = dot(sc->N, omega_in);
+ float cosNO = dot(sc->N, I);
+
+ if(cosNI > 0 && cosNO > 0) {
+ /* reflect the view vector */
+ float3 R = (2 * cosNO) * sc->N - I;
+ float cosRI = dot(R, omega_in);
+
+ float angle = safe_acosf(fmaxf(cosRI, 0.0f));
+
+ float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
+ return *pdf * eval;
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device float3 bsdf_specular_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_specular_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+{
+ float max_angle = sc->data0*M_PI_2_F;
+ float smooth = sc->data1*M_PI_2_F;
+ float cosNO = dot(sc->N, I);
+
+ if(cosNO > 0) {
+ /* reflect the view vector */
+ float3 R = (2 * cosNO) * sc->N - I;
+
+ float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
+ float angle = sample_angle*randu;
+
+ sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf);
+
+ if(dot(Ng, *omega_in) > 0.0f) {
+ float cosNI = dot(sc->N, *omega_in);
+
+ /* make sure the direction we chose is still in the right hemisphere */
+ if(cosNI > 0) {
+ *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
+
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2 * dot(sc->N, dIdy)) * sc->N - dIdy;
+#endif
+ }
+ else
+ *pdf = 0.0f;
+ }
+ else
+ *pdf = 0.0f;
+ }
+
+ return LABEL_GLOSSY | LABEL_REFLECT;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __BSDF_TOON_H__ */
+
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf_util.h
similarity index 100%
copy from intern/cycles/kernel/closure/bsdf.h
copy to intern/cycles/kernel/closure/bsdf_util.h
diff --git a/intern/cycles/kernel/closure/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h
index dbddcf2..c95b0e3 100644
--- a/intern/cycles/kernel/closure/bsdf_ward.h
+++ b/intern/cycles/kernel/closure/bsdf_ward.h
@@ -182,12 +182,6 @@ __device int bsdf_ward_sample(const ShaderClosure *sc, float3 Ng, float3 I, floa
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
#endif
}
}
diff --git a/intern/cycles/kernel/closure/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h
index 9681732..29bfa85 100644
--- a/intern/cycles/kernel/closure/bsdf_westin.h
+++ b/intern/cycles/kernel/closure/bsdf_westin.h
@@ -108,14 +108,6 @@ __device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng,
*pdf = 0.5f * M_1_PI_F * powf(cosTheta, m_invroughness);
*pdf = (m_invroughness + 1) * (*pdf);
*eval = make_float3(*pdf, *pdf, *pdf);
-#ifdef __RAY_DIFFERENTIALS__
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- *domega_in_dx *= 10.0f;
- *domega_in_dy *= 10.0f;
-#endif
}
}
}
@@ -176,8 +168,6 @@ __device int bsdf_westin_sheen_sample(const ShaderClosure *sc, float3 Ng, float3
// TODO: find a better approximation for the diffuse bounce
*domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
*domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
- *domega_in_dx *= 125.0f;
- *domega_in_dy *= 125.0f;
#endif
}
else {
diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h
index cbf9d9a..33b1b69 100644
--- a/intern/cycles/kernel/closure/emissive.h
+++ b/intern/cycles/kernel/closure/emissive.h
@@ -49,17 +49,12 @@ __device void emissive_sample(const float3 Ng, float randu, float randv,
/* todo: not implemented and used yet */
}
-__device float3 emissive_eval(const float3 Ng, const float3 I)
+__device float3 emissive_simple_eval(const float3 Ng, const float3 I)
{
float res = emissive_pdf(Ng, I);
return make_float3(res, res, res);
}
-__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
-{
- return emissive_eval(sd->Ng, sd->I);
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 734f911..0b553f3 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -53,8 +53,13 @@ __device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const flo
/* VOLUME CLOSURE */
-__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+__device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::volume_eval_phase(sc, omega_in, omega_out);
+#endif
+
float3 eval;
switch(sc->type) {
diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h
deleted file mode 100644
index b7ad731..0000000
--- a/intern/cycles/kernel/kernel_attribute.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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.
- */
-
-#ifndef __KERNEL_ATTRIBUTE_CL__
-#define __KERNEL_ATTRIBUTE_CL__
-
-CCL_NAMESPACE_BEGIN
-
-/* note: declared in kernel.h, have to add it here because kernel.h is not available */
-bool kernel_osl_use(KernelGlobals *kg);
-
-__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
-{
-#ifdef __OSL__
- if (kg->osl) {
- return OSLShader::find_attribute(kg, sd, id);
- }
- else
-#endif
- {
- /* for SVM, find attribute by unique id */
- uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id)
- attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
-
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- }
-}
-
-CCL_NAMESPACE_END
-
-#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index d70485f..2cb2920 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -205,6 +205,145 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
}
}
+#ifdef __HAIR__
+__device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
+ float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment)
+{
+ /* curve Intersection check */
+
+ int flags = kernel_data.curve_kernel_data.curveflags;
+
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+
+ float l = len(P2 - P1);
+ float r1 = P1.w;
+ float r2 = P2.w;
+ float mr = max(r1,r2);
+ float3 p1 = float4_to_float3(P1);
+ float3 p2 = float4_to_float3(P2);
+ float3 dif = P - p1;
+ float3 dir = 1.0f/idir;
+
+ float sp_r = mr + 0.5f * l;
+ float3 sphere_dif = P - ((p1 + p2) * 0.5f);
+ float sphere_b = dot(dir,sphere_dif);
+ sphere_dif = sphere_dif - sphere_b * dir;
+ sphere_b = dot(dir,sphere_dif);
+ float sdisc = sphere_b * sphere_b - len_squared(sphere_dif) + sp_r * sp_r;
+ if(sdisc < 0.0f)
+ return;
+
+ /* obtain parameters and test midpoint distance for suitable modes*/
+ float3 tg = (p2 - p1) / l;
+ float gd = (r2 - r1) / l;
+ float dirz = dot(dir,tg);
+ float difz = dot(dif,tg);
+
+ float a = 1.0f - (dirz*dirz*(1 + gd*gd));
+ float halfb = (dot(dir,dif) - dirz*(difz + gd*(difz*gd + r1)));
+
+ float tcentre = -halfb/a;
+ float zcentre = difz + (dirz * tcentre);
+
+ if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
+ return;
+ if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
+ return;
+
+ /* test minimum separation*/
+ float3 cprod = cross(tg, dir);
+ float3 cprod2 = cross(tg, dif);
+ float cprodsq = len_squared(cprod);
+ float cprod2sq = len_squared(cprod2);
+ float distscaled = dot(cprod,dif);
+
+ if(cprodsq == 0)
+ distscaled = cprod2sq;
+ else
+ distscaled = (distscaled*distscaled)/cprodsq;
+
+ if(distscaled > mr*mr)
+ return;
+
+ /* calculate true intersection*/
+ float3 tdif = P - p1 + tcentre * dir;
+ float tdifz = dot(tdif,tg);
+ float tb = 2*(dot(dir,tdif) - dirz*(tdifz + gd*(tdifz*gd + r1)));
+ float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - r1*r1 - 2*r1*tdifz*gd;
+ float td = tb*tb - 4*a*tc;
+
+ if (td < 0.0f)
+ return;
+
+ float rootd = 0.0f;
+ float correction = 0.0f;
+ if(flags & CURVE_KN_ACCURATE) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ }
+
+ float t = tcentre + correction;
+
+ if(t < isect->t) {
+
+ if(flags & CURVE_KN_INTERSECTCORRECTION) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ t = tcentre + correction;
+ }
+
+ float z = zcentre + (dirz * correction);
+ bool backface = false;
+
+ if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
+ backface = true;
+ correction = ((-tb + rootd)/(2*a));
+ t = tcentre + correction;
+ z = zcentre + (dirz * correction);
+ }
+
+ if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
+
+ if (flags & CURVE_KN_ENCLOSEFILTER) {
+
+ float enc_ratio = kernel_data.curve_kernel_data.encasing_ratio;
+ if((dot(P - p1, tg) > -r1 * enc_ratio) && (dot(P - p2, tg) < r2 * enc_ratio)) {
+ float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
+ float c2 = dot(dif,dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
+ if(a2*c2 < 0.0f)
+ return;
+ }
+ }
+
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->prim = curveAddr;
+ isect->segment = segment;
+ isect->object = object;
+ isect->u = z/l;
+ isect->v = td/(4*a*a);
+ isect->t = t;
+
+ if(backface)
+ isect->u = -isect->u;
+ }
+ }
+ }
+}
+#endif
+
__device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
{
/* traversal stack in CUDA thread-local memory */
@@ -281,10 +420,16 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint
nodeAddr = traversalStack[stackPtr];
--stackPtr;
- /* triangle intersection */
+ /* primitive intersection */
while(primAddr < primAddr2) {
- /* intersect ray against triangle */
- bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ /* intersect ray against primitive */
+#ifdef __HAIR__
+ uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+ if(segment != ~0)
+ bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ else
+#endif
+ bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
/* shadow ray early termination */
if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0)
@@ -401,10 +546,16 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con
nodeAddr = traversalStack[stackPtr];
--stackPtr;
- /* triangle intersection */
+ /* primitive intersection */
while(primAddr < primAddr2) {
- /* intersect ray against triangle */
- bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ /* intersect ray against primitive */
+#ifdef __HAIR__
+ uint segment = kernel_tex_fetch(__prim_segment, primAddr);
+ if(segment != ~0)
+ bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ else
+#endif
+ bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
/* shadow ray early termination */
if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0)
@@ -457,12 +608,15 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
{
#ifdef __INTERSECTION_REFINE__
const float epsilon_f = 1e-5f;
+ /* ideally this should match epsilon_f, but instancing/mblur
+ * precision makes it problematic */
+ const float epsilon_test = 1e-1f;
const int epsilon_i = 32;
float3 res;
/* x component */
- if(fabsf(P.x) < epsilon_f) {
+ if(fabsf(P.x) < epsilon_test) {
res.x = P.x + Ng.x*epsilon_f;
}
else {
@@ -472,7 +626,7 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
}
/* y component */
- if(fabsf(P.y) < epsilon_f) {
+ if(fabsf(P.y) < epsilon_test) {
res.y = P.y + Ng.y*epsilon_f;
}
else {
@@ -482,7 +636,7 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
}
/* z component */
- if(fabsf(P.z) < epsilon_f) {
+ if(fabsf(P.z) < epsilon_test) {
res.z = P.z + Ng.z*epsilon_f;
}
else {
@@ -542,5 +696,105 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co
#endif
}
+#ifdef __HAIR__
+__device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float t)
+{
+ int flag = kernel_data.curve_kernel_data.curveflags;
+ float3 P = ray->P;
+ float3 D = ray->D;
+
+ if(isect->object != ~0) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D*t);
+ D = normalize_len(D, &t);
+ }
+
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + isect->segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+ float l = len(P2 - P1);
+ float r1 = P1.w;
+ float r2 = P2.w;
+ float3 tg = float4_to_float3(P2 - P1) / l;
+ float3 dif = P - float4_to_float3(P1) + t * D;
+ float gd = ((r2 - r1)/l);
+
+ P = P + D*t;
+
+ dif = P - float4_to_float3(P1);
+
+ #ifdef __UV__
+ sd->u = dot(dif,tg)/l;
+ sd->v = 0.0f;
+ #endif
+
+ if (flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->Ng = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
+ sd->Ng = normalize(sd->Ng);
+ if (flag & CURVE_KN_NORMALCORRECTION)
+ {
+ //sd->Ng = normalize(sd->Ng);
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+ else {
+ sd->Ng = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);
+ if (gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg ;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+
+ sd->N = sd->Ng;
+
+ if (flag & CURVE_KN_TANGENTGNORMAL && !(flag & CURVE_KN_TRUETANGENTGNORMAL)) {
+ sd->N = -(D - tg * (dot(tg,D) * kernel_data.curve_kernel_data.normalmix));
+ sd->N = normalize(sd->N);
+ if (flag & CURVE_KN_NORMALCORRECTION) {
+ //sd->N = normalize(sd->N);
+ sd->N = sd->N - gd * tg;
+ sd->N = normalize(sd->N);
+ }
+ }
+ if (!(flag & CURVE_KN_TANGENTGNORMAL) && flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->N = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd);
+ if (gd != 0.0f) {
+ sd->N = sd->N - gd * tg ;
+ sd->N = normalize(sd->N);
+ }
+ }
+
+ #ifdef __DPDU__
+ /* dPdu/dPdv */
+ sd->dPdu = tg;
+ sd->dPdv = cross(tg,sd->Ng);
+ #endif
+
+ if(isect->object != ~0) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 97d37a8..cd896ff 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -199,7 +199,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D;
-
#endif
}
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 40bae06..9fd065c 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -37,6 +37,7 @@
#define __global
#define __shared __shared__
#define __constant
+#define __may_alias
/* No assert supported for CUDA */
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index a9d1858..abb2f09 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -40,6 +40,7 @@
#define __device
#define __device_inline __device
#define __device_noinline __device __noinline
+#define __may_alias
/* no assert in opencl */
#define kernel_assert(cond)
diff --git a/intern/cycles/kernel/kernel_curve.h b/intern/cycles/kernel/kernel_curve.h
new file mode 100644
index 0000000..e065717
--- /dev/null
+++ b/intern/cycles/kernel/kernel_curve.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __HAIR__
+
+/* curve attributes */
+
+__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE) {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return kernel_tex_fetch(__attributes_float, offset + sd->prim);
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
+
+ float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
+ float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = 0.0f;
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+#endif
+
+ return 0.0f;
+ }
+}
+
+__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+ if(elem == ATTR_ELEMENT_CURVE) {
+ /* idea: we can't derive any useful differentials here, but for tiled
+ * mipmap image caching it would be useful to avoid reading the highest
+ * detail level always. maybe a derivative based on the hair density
+ * could be computed somehow? */
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
+ }
+ else if(elem == ATTR_ELEMENT_CURVE_KEY) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
+
+ float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
+ float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
+
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = sd->du.dx*(f1 - f0);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return (1.0f - sd->u)*f0 + sd->u*f1;
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+/* hair info node functions */
+
+__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
+{
+ float r = 0.0f;
+
+ if(sd->segment != ~0) {
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+ int k0 = __float_as_int(curvedata.x) + sd->segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+ r = (P2.w - P1.w) * sd->u + P1.w;
+ }
+
+ return r*2.0f;
+}
+
+__device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 tgN = make_float3(0.0f,0.0f,0.0f);
+
+ if(sd->segment != ~0) {
+ float normalmix = kernel_data.curve_kernel_data.normalmix;
+
+ tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
+ tgN = normalize(tgN);
+
+ /* need to find suitable scaled gd for corrected normal */
+#if 0
+ if (kernel_data.curve_kernel_data.use_tangent_normal_correction)
+ tgN = normalize(tgN - gd * sd->dPdu);
+#endif
+ }
+
+ return tgN;
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index a55f7a7..fc2be34 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -35,7 +35,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
/* evaluate */
float3 P = sd.P;
- shader_eval_displacement(kg, &sd);
+ shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN);
out = sd.P - P;
}
else { // SHADER_EVAL_BACKGROUND
@@ -63,7 +63,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
/* evaluate */
int flag = 0; /* we can't know which type of BSDF this is for */
- out = shader_eval_background(kg, &sd, flag);
+ out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
}
shader_release(kg, &sd);
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 6d650a0..54bc071 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -42,17 +42,23 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
ray.time = time;
#endif
shader_setup_from_background(kg, &sd, &ray);
- eval = shader_eval_background(kg, &sd, 0);
+ eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
}
else
#endif
{
- shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time);
+#ifdef __HAIR__
+ if(ls->type == LIGHT_STRAND)
+ shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, ls->prim);
+ else
+#endif
+ shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time);
+
ls->Ng = sd.Ng;
/* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */
- shader_eval_surface(kg, &sd, rando, 0);
+ shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
/* evaluate emissive closure */
if(sd.flag & SD_EMISSION)
@@ -60,6 +66,8 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
else
eval = make_float3(0.0f, 0.0f, 0.0f);
}
+
+ eval *= ls->eval_fac;
shader_release(kg, &sd);
@@ -68,29 +76,29 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
__device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
- bool *is_lamp)
+ int *lamp)
{
LightSample ls;
- float pdf = -1.0f;
-
#ifdef __NON_PROGRESSIVE__
if(lindex != -1) {
/* sample position on a specified light */
- light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf);
+ light_select(kg, lindex, randu, randv, sd->P, &ls);
}
else
#endif
{
/* sample a light and position on int */
- light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf);
+ light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls);
}
- /* compute pdf */
- if(pdf < 0.0f)
- pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
+ /* return lamp index for MIS */
+ if(ls.use_mis)
+ *lamp = ls.lamp;
+ else
+ *lamp= ~0;
- if(pdf == 0.0f)
+ if(ls.pdf == 0.0f)
return false;
/* evaluate closure */
@@ -106,13 +114,13 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf);
- if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) {
+ if(ls.use_mis) {
/* multiple importance sampling */
- float mis_weight = power_heuristic(pdf, bsdf_pdf);
+ float mis_weight = power_heuristic(ls.pdf, bsdf_pdf);
light_eval *= mis_weight;
}
- bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf));
+ bsdf_eval_mul(eval, light_eval/ls.pdf);
if(bsdf_eval_is_zero(eval))
return false;
@@ -138,19 +146,21 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
ray->t = 0.0f;
}
- *is_lamp = (ls.prim == ~0);
-
return true;
}
-/* Indirect Emission */
+/* Indirect Primitive Emission */
-__device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
+__device float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
{
/* evaluate emissive closure */
float3 L = shader_emissive_eval(kg, sd);
+#ifdef __HAIR__
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) {
+#else
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
+#endif
/* multiple importance sampling, get triangle light pdf,
* and compute weight with respect to BSDF pdf */
float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
@@ -162,6 +172,35 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
return L;
}
+/* Indirect Lamp Emission */
+
+__device bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission)
+{
+ LightSample ls;
+ int lamp = lamp_light_eval_sample(kg, randt);
+
+ if(lamp == ~0)
+ return false;
+
+ if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
+ return false;
+
+ /* todo: missing texture coordinates */
+ float u = 0.0f;
+ float v = 0.0f;
+ float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ls.t, ray->time);
+
+ if(!(path_flag & PATH_RAY_MIS_SKIP)) {
+ /* multiple importance sampling, get regular light pdf,
+ * and compute weight with respect to BSDF pdf */
+ float mis_weight = power_heuristic(bsdf_pdf, ls.pdf);
+ L *= mis_weight;
+ }
+
+ *emission = L;
+ return true;
+}
+
/* Indirect Background */
__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
@@ -170,7 +209,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag,
/* evaluate background closure */
ShaderData sd;
shader_setup_from_background(kg, &sd, ray);
- float3 L = shader_eval_background(kg, &sd, path_flag);
+ float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
shader_release(kg, &sd);
#ifdef __BACKGROUND_MIS__
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 97ae2d3..e0d0802 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -18,49 +18,27 @@
CCL_NAMESPACE_BEGIN
+/* Light Sample result */
+
typedef struct LightSample {
- float3 P;
- float3 D;
- float3 Ng;
- float t;
- float eval_fac;
- int object;
- int prim;
- int shader;
- LightType type;
+ float3 P; /* position on light, or direction for distant light */
+ float3 Ng; /* normal on light */
+ float3 D; /* direction from shading point to light */
+ float t; /* distance to light (FLT_MAX for distant light) */
+ float pdf; /* light sampling probability density function */
+ float eval_fac; /* intensity multiplier */
+ int object; /* object id for triangle/curve lights */
+ int prim; /* primitive id for triangle/curve ligths */
+ int shader; /* shader id */
+ int lamp; /* lamp id */
+ int use_mis; /* for lamps with size zero */
+ LightType type; /* type of light */
} LightSample;
-/* Regular Light */
-
-__device float3 disk_light_sample(float3 v, float randu, float randv)
-{
- float3 ru, rv;
-
- make_orthonormals(v, &ru, &rv);
- to_unit_disk(&randu, &randv);
-
- return ru*randu + rv*randv;
-}
-
-__device float3 distant_light_sample(float3 D, float size, float randu, float randv)
-{
- return normalize(D + disk_light_sample(D, randu, randv)*size);
-}
-
-__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv)
-{
- return disk_light_sample(normalize(P - center), randu, randv)*size;
-}
-
-__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
-{
- randu = randu - 0.5f;
- randv = randv - 0.5f;
-
- return axisu*randu + axisv*randv;
-}
+/* Background Light */
#ifdef __BACKGROUND_MIS__
+
__device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
{
/* for the following, the CDF values are actually a pair of floats, with the
@@ -169,33 +147,108 @@ __device float background_light_pdf(KernelGlobals *kg, float3 direction)
}
#endif
-__device void regular_light_sample(KernelGlobals *kg, int point,
- float randu, float randv, float3 P, LightSample *ls, float *pdf)
+/* Regular Light */
+
+__device float3 disk_light_sample(float3 v, float randu, float randv)
+{
+ float3 ru, rv;
+
+ make_orthonormals(v, &ru, &rv);
+ to_unit_disk(&randu, &randv);
+
+ return ru*randu + rv*randv;
+}
+
+__device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
+{
+ return normalize(D + disk_light_sample(D, randu, randv)*radius);
+}
+
+__device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
+{
+ return disk_light_sample(normalize(P - center), randu, randv)*radius;
+}
+
+__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
+{
+ randu = randu - 0.5f;
+ randv = randv - 0.5f;
+
+ return axisu*randu + axisv*randv;
+}
+
+__device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)
+{
+ float3 dir = make_float3(data2.y, data2.z, data2.w);
+ float3 I = ls->Ng;
+
+ float spot_angle = data1.w;
+ float spot_smooth = data2.x;
+
+ float attenuation = dot(dir, I);
+
+ if(attenuation <= spot_angle) {
+ attenuation = 0.0f;
+ }
+ else {
+ float t = attenuation - spot_angle;
+
+ if(t < spot_smooth && spot_smooth != 0.0f)
+ attenuation *= smoothstepf(t/spot_smooth);
+ }
+
+ return attenuation;
+}
+
+__device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
{
- float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
- float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
+ float cos_pi = dot(Ng, I);
+
+ if(cos_pi <= 0.0f)
+ return 0.0f;
+
+ return t*t/cos_pi;
+}
+
+__device void lamp_light_sample(KernelGlobals *kg, int lamp,
+ float randu, float randv, float3 P, LightSample *ls)
+{
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
LightType type = (LightType)__float_as_int(data0.x);
ls->type = type;
+#ifdef __LAMP_MIS__
+ ls->use_mis = true;
+#else
+ ls->use_mis = false;
+#endif
if(type == LIGHT_DISTANT) {
/* distant light */
- float3 D = make_float3(data0.y, data0.z, data0.w);
- float size = data1.y;
+ float3 lightD = make_float3(data0.y, data0.z, data0.w);
+ float3 D = lightD;
+ float radius = data1.y;
+ float invarea = data1.w;
- if(size > 0.0f)
- D = distant_light_sample(D, size, randu, randv);
+ if(radius > 0.0f)
+ D = distant_light_sample(D, radius, randu, randv);
+ else
+ ls->use_mis = false;
ls->P = D;
ls->Ng = D;
ls->D = -D;
ls->t = FLT_MAX;
- ls->eval_fac = 1.0f;
+
+ float costheta = dot(lightD, D);
+ ls->pdf = invarea/(costheta*costheta*costheta);
+ ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights;
}
#ifdef __BACKGROUND_MIS__
else if(type == LIGHT_BACKGROUND) {
/* infinite area light (e.g. light dome or env light) */
- float3 D = background_light_sample(kg, randu, randv, pdf);
+ float3 D = background_light_sample(kg, randu, randv, &ls->pdf);
ls->P = D;
ls->Ng = D;
@@ -207,125 +260,277 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
else {
ls->P = make_float3(data0.y, data0.z, data0.w);
- if(type == LIGHT_POINT) {
- float size = data1.y;
+ if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float radius = data1.y;
- /* sphere light */
- if(size > 0.0f)
- ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
+ if(radius > 0.0f)
+ /* sphere light */
+ ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
+ else
+ ls->use_mis = false;
- ls->Ng = normalize(P - ls->P);
- ls->eval_fac = 0.25f*M_1_PI_F;
- }
- else if(type == LIGHT_SPOT) {
- float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
- float size = data1.y;
-
- /* spot light */
- if(size > 0.0f)
- ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
-
- float3 dir = make_float3(data1.z, data1.w, data2.x);
- float3 I = normalize(P - ls->P);
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->Ng = -ls->D;
- float spot_angle = data2.y;
- float spot_smooth = data2.z;
-
- float eval_fac = dot(dir, I);
-
- if(eval_fac <= spot_angle) {
- eval_fac = 0.0f;
- }
- else {
- float t = eval_fac - spot_angle;
+ float invarea = data1.z;
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
+ ls->pdf = invarea;
- if(t < spot_smooth && spot_smooth != 0.0f)
- eval_fac *= smoothstepf(t/spot_smooth);
+ if(type == LIGHT_SPOT) {
+ /* spot light attentuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
}
-
- ls->Ng = I;
- ls->eval_fac = eval_fac*0.25f*M_1_PI_F;
}
else {
/* area light */
- float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
- float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3);
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
- float3 axisu = make_float3(data1.y, data1.z, data2.w);
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
float3 axisv = make_float3(data2.y, data2.z, data2.w);
float3 D = make_float3(data3.y, data3.z, data3.w);
ls->P += area_light_sample(axisu, axisv, randu, randv);
ls->Ng = D;
- ls->eval_fac = 0.25f;
+ ls->D = normalize_len(ls->P - P, &ls->t);
+
+ float invarea = data2.x;
+
+ if(invarea == 0.0f) {
+ ls->use_mis = false;
+ invarea = 1.0f;
+ }
+
+ ls->eval_fac = 0.25f*invarea;
+ ls->pdf = invarea;
}
- ls->t = 0.0f;
+ ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
ls->shader = __float_as_int(data1.x);
ls->object = ~0;
ls->prim = ~0;
+ ls->lamp = lamp;
}
-__device float regular_light_pdf(KernelGlobals *kg,
- const float3 Ng, const float3 I, float t)
+__device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
{
- float pdf = kernel_data.integrator.pdf_lights;
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
- if(t == FLT_MAX)
- return pdf;
+ LightType type = (LightType)__float_as_int(data0.x);
+ ls->type = type;
+ ls->shader = __float_as_int(data1.x);
+ ls->object = ~0;
+ ls->prim = ~0;
+ ls->lamp = lamp;
+ ls->use_mis = false; /* flag not used for eval */
- float cos_pi = dot(Ng, I);
+ if(type == LIGHT_DISTANT) {
+ /* distant light */
+ float radius = data1.y;
+
+ if(radius == 0.0f)
+ return false;
+ if(t != FLT_MAX)
+ return false;
+
+ /* a distant light is infinitely far away, but equivalent to a disk
+ * shaped light exactly 1 unit away from the current shading point.
+ *
+ * radius t^2/cos(theta)
+ * <----------> t = sqrt(1^2 + tan(theta)^2)
+ * tan(th) area = radius*radius*pi
+ * <----->
+ * \ | (1 + tan(theta)^2)/cos(theta)
+ * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta)
+ * t \th| 1 simplifies to
+ * \-| 1/(cos(theta)^3)
+ * \| magic!
+ * P
+ */
+
+ float3 lightD = make_float3(data0.y, data0.z, data0.w);
+ float costheta = dot(-lightD, D);
+ float cosangle = data1.z;
+
+ if(costheta < cosangle)
+ return false;
+
+ ls->P = -D;
+ ls->Ng = -D;
+ ls->D = D;
+ ls->t = FLT_MAX;
- if(cos_pi <= 0.0f)
- return 0.0f;
+ float invarea = data1.w;
+ ls->pdf = invarea/(costheta*costheta*costheta);
+ ls->eval_fac = ls->pdf;
+ }
+ else if(type == LIGHT_POINT || type == LIGHT_SPOT) {
+ float3 lightP = make_float3(data0.y, data0.z, data0.w);
+ float radius = data1.y;
- return t*t*pdf/cos_pi;
+ /* sphere light */
+ if(radius == 0.0f)
+ return false;
+
+ if(!ray_aligned_disk_intersect(P, D, t,
+ lightP, radius, &ls->P, &ls->t))
+ return false;
+
+ ls->Ng = -D;
+ ls->D = D;
+
+ float invarea = data1.z;
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
+ ls->pdf = invarea;
+
+ if(type == LIGHT_SPOT) {
+ /* spot light attentuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
+
+ if(ls->eval_fac == 0.0f)
+ return false;
+ }
+ }
+ else if(type == LIGHT_AREA) {
+ /* area light */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
+
+ float invarea = data2.x;
+ if(invarea == 0.0f)
+ return false;
+
+ float3 axisu = make_float3(data1.y, data1.z, data1.w);
+ float3 axisv = make_float3(data2.y, data2.z, data2.w);
+ float3 Ng = make_float3(data3.y, data3.z, data3.w);
+
+ /* one sided */
+ if(dot(D, Ng) >= 0.0f)
+ return false;
+
+ ls->P = make_float3(data0.y, data0.z, data0.w);
+
+ if(!ray_quad_intersect(P, D, t,
+ ls->P, axisu, axisv, &ls->P, &ls->t))
+ return false;
+
+ ls->D = D;
+ ls->Ng = Ng;
+ ls->pdf = invarea;
+ ls->eval_fac = 0.25f*ls->pdf;
+ }
+ else
+ return false;
+
+ /* compute pdf */
+ if(ls->t != FLT_MAX)
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
+
+ return true;
}
/* Triangle Light */
-__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
- float randu, float randv, float time, LightSample *ls)
+__device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time)
{
- /* triangle, so get position, normal, shader */
- ls->P = triangle_sample_MT(kg, prim, randu, randv);
- ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
- ls->object = object;
- ls->prim = prim;
- ls->t = 0.0f;
- ls->type = LIGHT_AREA;
- ls->eval_fac = 1.0f;
-
#ifdef __INSTANCING__
/* instance transform */
- if(ls->object >= 0) {
+ if(object >= 0) {
#ifdef __OBJECT_MOTION__
Transform itfm;
Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
- Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM);
- Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
ls->P = transform_point(&tfm, ls->P);
- ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng));
+ ls->Ng = normalize(transform_direction(&tfm, ls->Ng));
}
#endif
}
+__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
+ float randu, float randv, float time, LightSample *ls)
+{
+ /* triangle, so get position, normal, shader */
+ ls->P = triangle_sample_MT(kg, prim, randu, randv);
+ ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
+ ls->object = object;
+ ls->prim = prim;
+ ls->lamp = ~0;
+ ls->use_mis = true;
+ ls->t = 0.0f;
+ ls->type = LIGHT_AREA;
+ ls->eval_fac = 1.0f;
+
+ object_transform_light_sample(kg, ls, object, time);
+}
+
__device float triangle_light_pdf(KernelGlobals *kg,
const float3 Ng, const float3 I, float t)
{
+ float pdf = kernel_data.integrator.pdf_triangles;
float cos_pi = fabsf(dot(Ng, I));
if(cos_pi == 0.0f)
return 0.0f;
- return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi;
+ return t*t*pdf/cos_pi;
}
+/* Curve Light */
+
+#ifdef __HAIR__
+
+__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
+ int segment, float randu, float randv, float time, LightSample *ls)
+{
+ /* this strand code needs completion */
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ float4 P1 = kernel_tex_fetch(__curve_keys, k0);
+ float4 P2 = kernel_tex_fetch(__curve_keys, k1);
+
+ float l = len(P2 - P1);
+
+ float r1 = P1.w;
+ float r2 = P2.w;
+ float3 tg = float4_to_float3(P2 - P1) / l;
+ float3 xc = make_float3(tg.x * tg.z, tg.y * tg.z, -(tg.x * tg.x + tg.y * tg.y));
+ if (dot(xc, xc) == 0.0f)
+ xc = make_float3(tg.x * tg.y, -(tg.x * tg.x + tg.z * tg.z), tg.z * tg.y);
+ xc = normalize(xc);
+ float3 yc = cross(tg, xc);
+ float gd = ((r2 - r1)/l);
+
+ /* normal currently ignores gradient */
+ ls->Ng = sinf(2 * M_PI_F * randv) * xc + cosf(2 * M_PI_F * randv) * yc;
+ ls->P = randu * l * tg + (gd * l + r1) * ls->Ng;
+ ls->object = object;
+ ls->prim = prim;
+ ls->lamp = ~0;
+ ls->use_mis = true;
+ ls->t = 0.0f;
+ ls->type = LIGHT_STRAND;
+ ls->eval_fac = 1.0f;
+ ls->shader = __float_as_int(v00.z);
+
+ object_transform_light_sample(kg, ls, object, time);
+}
+
+#endif
+
/* Light Distribution */
__device int light_distribution_sample(KernelGlobals *kg, float randt)
@@ -357,7 +562,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */
-__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf)
+__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -368,28 +573,25 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
if(prim >= 0) {
int object = __float_as_int(l.w);
- triangle_light_sample(kg, prim, object, randu, randv, time, ls);
+#ifdef __HAIR__
+ int segment = __float_as_int(l.z);
+#endif
+
+#ifdef __HAIR__
+ if (segment != ~0)
+ curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
+ else
+#endif
+ triangle_light_sample(kg, prim, object, randu, randv, time, ls);
+
+ /* compute incoming direction, distance and pdf */
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
}
else {
- int point = -prim-1;
- regular_light_sample(kg, point, randu, randv, P, ls, pdf);
+ int lamp = -prim-1;
+ lamp_light_sample(kg, lamp, randu, randv, P, ls);
}
-
- /* compute incoming direction and distance */
- if(ls->t != FLT_MAX)
- ls->D = normalize_len(ls->P - P, &ls->t);
-}
-
-__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
-{
- float pdf;
-
- if(ls->prim != ~0)
- pdf = triangle_light_pdf(kg, ls->Ng, I, t);
- else
- pdf = regular_light_pdf(kg, ls->Ng, I, t);
-
- return pdf;
}
__device int light_select_num_samples(KernelGlobals *kg, int index)
@@ -398,18 +600,26 @@ __device int light_select_num_samples(KernelGlobals *kg, int index)
return __float_as_int(data3.x);
}
-__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
+__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls)
{
- regular_light_sample(kg, index, randu, randv, P, ls, pdf);
-
- /* compute incoming direction and distance */
- if(ls->t != FLT_MAX)
- ls->D = normalize_len(ls->P - P, &ls->t);
+ lamp_light_sample(kg, index, randu, randv, P, ls);
}
-__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
+__device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
{
- return regular_light_pdf(kg, ls->Ng, I, t);
+ /* sample index */
+ int index = light_distribution_sample(kg, randt);
+
+ /* fetch light data */
+ float4 l = kernel_tex_fetch(__light_distribution, index);
+ int prim = __float_as_int(l.y);
+
+ if(prim < 0) {
+ int lamp = -prim-1;
+ return lamp;
+ }
+ else
+ return ~0;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index 48d1aa6..fb66501 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -105,6 +105,22 @@ __device_inline void sample_uniform_hemisphere(const float3 N,
*pdf = 0.5f * M_1_PI_F;
}
+__device_inline void sample_uniform_cone(const float3 N, float angle,
+ float randu, float randv,
+ float3 *omega_in, float *pdf)
+{
+ float z = cosf(angle*randu);
+ float r = sqrtf(max(0.0f, 1.0f - z*z));
+ float phi = 2.0f * M_PI_F * randv;
+ float x = r * cosf(phi);
+ float y = r * sinf(phi);
+
+ float3 T, B;
+ make_orthonormals (N, &T, &B);
+ *omega_in = x * T + y * B + z * N;
+ *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(angle));
+}
+
__device float3 sample_uniform_sphere(float u1, float u2)
{
float z = 1.0f - 2.0f*u1;
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 2b38544..40aa475 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -20,11 +20,16 @@ CCL_NAMESPACE_BEGIN
enum ObjectTransform {
OBJECT_TRANSFORM = 0,
- OBJECT_INVERSE_TRANSFORM = 3,
- OBJECT_PROPERTIES = 6,
- OBJECT_TRANSFORM_MOTION_PRE = 8,
- OBJECT_TRANSFORM_MOTION_POST = 12,
- OBJECT_DUPLI = 16
+ OBJECT_TRANSFORM_MOTION_PRE = 0,
+ OBJECT_INVERSE_TRANSFORM = 4,
+ OBJECT_TRANSFORM_MOTION_POST = 4,
+ OBJECT_PROPERTIES = 8,
+ OBJECT_DUPLI = 9
+};
+
+enum ObjectVectorTransform {
+ OBJECT_VECTOR_MOTION_PRE = 0,
+ OBJECT_VECTOR_MOTION_POST = 3
};
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
@@ -40,6 +45,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
return tfm;
}
+__device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
+{
+ int offset = object*OBJECT_VECTOR_SIZE + (int)type;
+
+ Transform tfm;
+ tfm.x = kernel_tex_fetch(__objects_vector, offset + 0);
+ tfm.y = kernel_tex_fetch(__objects_vector, offset + 1);
+ tfm.z = kernel_tex_fetch(__objects_vector, offset + 2);
+ tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+
+ return tfm;
+}
+
#ifdef __OBJECT_MOTION__
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 7f8b611..7276393 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -70,11 +70,11 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
}
if(flag & PASS_UV) {
- float3 uv = triangle_uv(kg, sd);
+ float3 uv = primitive_uv(kg, sd);
kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
}
if(flag & PASS_MOTION) {
- float4 speed = triangle_motion_vector(kg, sd);
+ float4 speed = primitive_motion_vector(kg, sd);
kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, sample, speed);
kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, sample, 1.0f);
}
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 3588b09..532c328 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -24,9 +24,10 @@
#include "kernel_montecarlo.h"
#include "kernel_projection.h"
#include "kernel_object.h"
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
#include "kernel_triangle.h"
+#include "kernel_curve.h"
+#include "kernel_primitive.h"
+#include "kernel_projection.h"
#ifdef __QBVH__
#include "kernel_qbvh.h"
#else
@@ -207,7 +208,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, ray);
- shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
+ shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
throughput *= shader_bsdf_transparency(kg, &sd);
@@ -237,6 +238,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
float min_ray_pdf = FLT_MAX;
float ray_pdf = 0.0f;
+#ifdef __LAMP_MIS__
+ float ray_t = 0.0f;
+#endif
PathState state;
int rng_offset = PRNG_BASE_NUM;
@@ -247,8 +251,29 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect);
- if(!scene_intersect(kg, &ray, visibility, &isect)) {
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray.P - ray_t*ray.D;
+ ray_t += isect.t;
+ light_ray.D = ray.D;
+ light_ray.t = ray_t;
+ light_ray.time = ray.time;
+
+ /* intersect with lamp */
+ float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission))
+ path_radiance_accum_emission(&L, throughput, emission, state.bounce);
+ }
+#endif
+
+ if(!hit) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
L_transparent += average(throughput);
@@ -272,7 +297,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
@@ -312,7 +337,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ /* todo: is isect.t wrong here for transparent surfaces? */
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
@@ -373,18 +399,19 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
Ray light_ray;
BsdfEval L_light;
- bool is_lamp;
+ int lamp;
#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -421,6 +448,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ ray_t = 0.0f;
+#endif
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
@@ -456,15 +486,41 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __NON_PROGRESSIVE__
__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer,
- float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
+ float3 throughput, float throughput_normalize,
+ float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L)
{
+#ifdef __LAMP_MIS__
+ float ray_t = 0.0f;
+#endif
+
/* path iteration */
for(;; rng_offset += PRNG_BOUNCE_NUM) {
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect);
- if(!scene_intersect(kg, &ray, visibility, &isect)) {
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray.P - ray_t*ray.D;
+ ray_t += isect.t;
+ light_ray.D = ray.D;
+ light_ray.t = ray_t;
+ light_ray.time = ray.time;
+
+ /* intersect with lamp */
+ float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission))
+ path_radiance_accum_emission(L, throughput, emission, state.bounce);
+ }
+#endif
+
+ if(!hit) {
#ifdef __BACKGROUND__
/* sample background shader */
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
@@ -478,7 +534,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
shader_merge_closures(kg, &sd);
/* blurring of bsdf after bounces, for rays that have a small likelihood
@@ -495,7 +551,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(L, throughput, emission, state.bounce);
}
#endif
@@ -503,7 +559,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_terminate_probability(kg, &state, throughput*throughput_normalize);
float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE);
if(terminate >= probability) {
@@ -556,19 +612,20 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
Ray light_ray;
BsdfEval L_light;
- bool is_lamp;
+ int lamp;
#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
/* sample random light */
- if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -605,6 +662,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
/* set labels */
if(!(label & LABEL_TRANSPARENT)) {
ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ ray_t = 0.0f;
+#endif
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf);
}
@@ -666,7 +726,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
- shader_eval_surface(kg, &sd, rbsdf, state.flag);
+ shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
shader_merge_closures(kg, &sd);
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
@@ -696,7 +756,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
#ifdef __EMISSION__
/* emission */
if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
+ float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf);
path_radiance_accum_emission(&L, throughput, emission, state.bounce);
}
#endif
@@ -759,7 +819,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
if(sd.flag & SD_BSDF_HAS_EVAL) {
Ray light_ray;
BsdfEval L_light;
- bool is_lamp;
+ int lamp;
#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
@@ -777,12 +837,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U);
float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V);
- if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -806,12 +867,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
if(kernel_data.integrator.num_all_lights)
light_t = 0.5f*light_t;
- if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) {
+ if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) {
/* trace shadow ray */
float3 shadow;
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
/* accumulate */
+ bool is_lamp = (lamp != ~0);
path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp);
}
}
@@ -884,8 +946,9 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
bsdf_ray.time = sd.time;
#endif
- kernel_path_indirect(kg, rng, sample*num_samples, bsdf_ray, buffer,
- tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
+ kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer,
+ tp*num_samples_inv, num_samples,
+ min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
}
}
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
new file mode 100644
index 0000000..0851af2
--- /dev/null
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __KERNEL_ATTRIBUTE_CL__
+#define __KERNEL_ATTRIBUTE_CL__
+
+CCL_NAMESPACE_BEGIN
+
+/* attribute lookup */
+
+__device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
+{
+ if(sd->object == ~0)
+ return (int)ATTR_STD_NOT_FOUND;
+
+#ifdef __OSL__
+ if (kg->osl) {
+ return OSLShader::find_attribute(kg, sd, id, elem);
+ }
+ else
+#endif
+ {
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+#ifdef __HAIR__
+ attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+#endif
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
+
+ *elem = (AttributeElement)attr_map.y;
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ }
+}
+
+__device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+#ifdef __HAIR__
+ if(sd->segment == ~0)
+#endif
+ return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+#ifdef __HAIR__
+ else
+ return curve_attribute_float(kg, sd, elem, offset, dx, dy);
+#endif
+}
+
+__device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+#ifdef __HAIR__
+ if(sd->segment == ~0)
+#endif
+ return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+#ifdef __HAIR__
+ else
+ return curve_attribute_float3(kg, sd, elem, offset, dx, dy);
+#endif
+}
+
+__device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
+{
+ AttributeElement elem_uv;
+ int offset_uv = find_attribute(kg, sd, ATTR_STD_UV, &elem_uv);
+
+ if(offset_uv == ATTR_STD_NOT_FOUND)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 uv = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL);
+ uv.z = 1.0f;
+ return uv;
+}
+
+__device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __HAIR__
+ if(sd->segment != ~0)
+ return normalize(sd->dPdu);
+#endif
+
+ /* try to create spherical tangent from generated coordinates */
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED, &attr_elem);
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ float3 data = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
+ data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
+ object_normal_transform(kg, sd, &data);
+ return cross(sd->N, normalize(cross(data, sd->N)));;
+ }
+ else {
+ /* otherwise use surface derivatives */
+ return normalize(sd->dPdu);
+ }
+}
+
+/* motion */
+
+__device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 motion_pre = sd->P, motion_post = sd->P;
+
+ /* deformation motion */
+ AttributeElement elem_pre, elem_post;
+ int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE, &elem_pre);
+ int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST, &elem_post);
+
+ if(offset_pre != ATTR_STD_NOT_FOUND)
+ motion_pre = primitive_attribute_float3(kg, sd, elem_pre, offset_pre, NULL, NULL);
+ if(offset_post != ATTR_STD_NOT_FOUND)
+ motion_post = primitive_attribute_float3(kg, sd, elem_post, offset_post, NULL, NULL);
+
+ /* object motion. note that depending on the mesh having motion vectors, this
+ * transformation was set match the world/object space of motion_pre/post */
+ Transform tfm;
+
+ tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_PRE);
+ motion_pre = transform_point(&tfm, motion_pre);
+
+ tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
+ motion_post = transform_point(&tfm, motion_post);
+
+ float3 P;
+
+ /* camera motion, for perspective/orthographic motion.pre/post will be a
+ * world-to-raster matrix, for panorama it's world-to-camera */
+ if (kernel_data.cam.type != CAMERA_PANORAMA) {
+ tfm = kernel_data.cam.worldtoraster;
+ P = transform_perspective(&tfm, sd->P);
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = transform_perspective(&tfm, motion_pre);
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = transform_perspective(&tfm, motion_post);
+ }
+ else {
+ tfm = kernel_data.cam.worldtocamera;
+ P = normalize(transform_point(&tfm, sd->P));
+ P = float2_to_float3(direction_to_panorama(kg, P));
+ P.x *= kernel_data.cam.width;
+ P.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = normalize(transform_point(&tfm, motion_pre));
+ motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
+ motion_pre.x *= kernel_data.cam.width;
+ motion_pre.y *= kernel_data.cam.height;
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = normalize(transform_point(&tfm, motion_post));
+ motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
+ motion_post.x *= kernel_data.cam.width;
+ motion_post.y *= kernel_data.cam.height;
+ }
+
+ motion_pre = motion_pre - P;
+ motion_post = P - motion_post;
+
+ return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __KERNEL_ATTRIBUTE_CL__ */
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 98a7ec5..0a5a2ab 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -26,11 +26,11 @@
*
*/
+#include "closure/bsdf_util.h"
#include "closure/bsdf.h"
#include "closure/emissive.h"
#include "closure/volume.h"
-#include "svm/svm_bsdf.h"
#include "svm/svm.h"
CCL_NAMESPACE_BEGIN
@@ -56,29 +56,11 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD
__device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::init(kg, sd);
-#endif
-
- /* fetch triangle data */
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 Ns = kernel_tex_fetch(__tri_normal, prim);
- float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
- int shader = __float_as_int(Ns.w);
-
- /* triangle */
#ifdef __INSTANCING__
sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
#endif
- sd->prim = prim;
-#ifdef __UV__
- sd->u = isect->u;
- sd->v = isect->v;
-#endif
- sd->flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
- sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
+ sd->flag = kernel_tex_fetch(__object_flag, sd->object);
/* matrices and time */
#ifdef __OBJECT_MOTION__
@@ -86,23 +68,63 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->time = ray->time;
#endif
- /* vectors */
- sd->P = bvh_triangle_refine(kg, sd, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
- sd->I = -ray->D;
- sd->shader = shader;
+ sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
sd->ray_length = isect->t;
- /* smooth normal */
- if(sd->shader & SHADER_SMOOTH_NORMAL)
- sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+#ifdef __HAIR__
+ if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
+ /* Strand Shader setting*/
+ float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
+
+ sd->shader = __float_as_int(curvedata.z);
+ sd->segment = isect->segment;
+
+ float tcorr = isect->t;
+ if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
+ tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
+ sd->ray_length = tcorr;
+ }
+
+ sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
+ }
+ else {
+#endif
+ /* fetch triangle data */
+ float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
+ float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
+ sd->shader = __float_as_int(Ns.w);
+
+#ifdef __HAIR__
+ sd->segment = ~0;
+#endif
+
+#ifdef __UV__
+ sd->u = isect->u;
+ sd->v = isect->v;
+#endif
+
+ /* vectors */
+ sd->P = bvh_triangle_refine(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
+
+ /* smooth normal */
+ if(sd->shader & SHADER_SMOOTH_NORMAL)
+ sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
#ifdef __DPDU__
- /* dPdu/dPdv */
- triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
+ /* dPdu/dPdv */
+ triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
#endif
+#ifdef __HAIR__
+ }
+#endif
+
+ sd->I = -ray->D;
+
+ sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+
#ifdef __INSTANCING__
if(isect->object != ~0) {
/* instance transform */
@@ -140,24 +162,23 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
- int shader, int object, int prim, float u, float v, float t, float time)
+ int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::init(kg, sd);
-#endif
-
/* vectors */
sd->P = P;
sd->N = Ng;
sd->Ng = Ng;
sd->I = I;
sd->shader = shader;
+#ifdef __HAIR__
+ sd->segment = segment;
+#endif
/* primitive */
#ifdef __INSTANCING__
sd->object = object;
#endif
+ /* currently no access to bvh prim index for strand sd->prim - this will cause errors with needs fixing*/
sd->prim = prim;
#ifdef __UV__
sd->u = u;
@@ -193,8 +214,13 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
/* smooth normal */
+#ifdef __HAIR__
+ if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
+ sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+#else
if(sd->shader & SHADER_SMOOTH_NORMAL) {
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
+#endif
#ifdef __INSTANCING__
if(instanced)
@@ -204,10 +230,17 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#ifdef __DPDU__
/* dPdu/dPdv */
+#ifdef __HAIR__
+ if(sd->prim == ~0 || sd->segment != ~0) {
+ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
+ sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+ }
+#else
if(sd->prim == ~0) {
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
}
+#endif
else {
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
@@ -273,11 +306,6 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
__device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::init(kg, sd);
-#endif
-
/* vectors */
sd->P = ray->D;
sd->N = -sd->P;
@@ -294,6 +322,9 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
sd->object = ~0;
#endif
sd->prim = ~0;
+#ifdef __HAIR__
+ sd->segment = ~0;
+#endif
#ifdef __UV__
sd->u = 0.0f;
sd->v = 0.0f;
@@ -320,36 +351,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
#ifdef __MULTI_CLOSURE__
-#ifdef __OSL__
-__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf,
- int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
-{
- for(int i = 0; i< sd->num_closure; i++) {
- if(i == skip_bsdf)
- continue;
-
- const ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSDF(sc->type)) {
- float bsdf_pdf = 0.0f;
-
- float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
-
- if(bsdf_pdf != 0.0f) {
- bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
- sum_pdf += bsdf_pdf*sc->sample_weight;
- }
-
- sum_sample_weight += sc->sample_weight;
- }
- }
-
- *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
-}
-#endif
-
-__device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf,
- int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
+__device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
+ int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
{
for(int i = 0; i< sd->num_closure; i++) {
if(i == skip_bsdf)
@@ -359,11 +362,10 @@ __device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const flo
if(CLOSURE_IS_BSDF(sc->type)) {
float bsdf_pdf = 0.0f;
-
- float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
+ float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
if(bsdf_pdf != 0.0f) {
- bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
+ bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
sum_pdf += bsdf_pdf*sc->sample_weight;
}
@@ -382,17 +384,12 @@ __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
#ifdef __MULTI_CLOSURE__
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
-#ifdef __OSL__
- if (kg->osl)
- return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
- else
-#endif
- return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+ return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
#else
const ShaderClosure *sc = &sd->closure;
*pdf = 0.0f;
- *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
+ *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
#endif
}
@@ -439,24 +436,14 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
float3 eval;
*pdf = 0.0f;
-#ifdef __OSL__
- if (kg->osl)
- label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
- else
-#endif
- label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
if(*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
if(sd->num_closure > 1) {
float sweight = sc->sample_weight;
-#ifdef __OSL__
- if (kg->osl)
- _shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
- else
-#endif
- _shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
+ _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
}
}
@@ -464,7 +451,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
#else
/* sample the single closure that we picked */
*pdf = 0.0f;
- int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
+ int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
*bsdf_eval *= sd->closure.weight;
return label;
#endif
@@ -478,12 +465,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
float3 eval;
*pdf = 0.0f;
-#ifdef __OSL__
- if (kg->osl)
- label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
- else
-#endif
- label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
if(*pdf != 0.0f)
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
@@ -497,17 +479,11 @@ __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughnes
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type)) {
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::bsdf_blur(sc, roughness);
- else
-#endif
- svm_bsdf_blur(sc, roughness);
- }
+ if(CLOSURE_IS_BSDF(sc->type))
+ bsdf_blur(kg, sc, roughness);
}
#else
- svm_bsdf_blur(&sd->closure, roughness);
+ bsdf_blur(kg, &sd->closure, roughness);
#endif
}
@@ -635,6 +611,16 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto
/* Emission */
+__device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
+{
+#ifdef __OSL__
+ if(kg->osl && sc->prim)
+ return OSLShader::emissive_eval(sd, sc);
+#endif
+
+ return emissive_simple_eval(sd->Ng, sd->I);
+}
+
__device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
{
float3 eval;
@@ -644,18 +630,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_EMISSION(sc->type)) {
-#ifdef __OSL__
- if (kg->osl)
- eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
- else
-#endif
- eval += svm_emissive_eval(sd, sc)*sc->weight;
-
- }
+ if(CLOSURE_IS_EMISSION(sc->type))
+ eval += emissive_eval(kg, sd, sc)*sc->weight;
}
#else
- eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
+ eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
#endif
return eval;
@@ -687,11 +666,11 @@ __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
/* Surface Evaluation */
__device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
- float randb, int path_flag)
+ float randb, int path_flag, ShaderContext ctx)
{
#ifdef __OSL__
if (kg->osl)
- OSLShader::eval_surface(kg, sd, randb, path_flag);
+ OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
else
#endif
{
@@ -706,11 +685,11 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
/* Background Evaluation */
-__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
+__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
{
#ifdef __OSL__
if (kg->osl)
- return OSLShader::eval_background(kg, sd, path_flag);
+ return OSLShader::eval_background(kg, sd, path_flag, ctx);
else
#endif
@@ -753,31 +732,25 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
for(int i = 0; i< sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_VOLUME(sc->type)) {
-#ifdef __OSL__
- if (kg->osl)
- eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
- else
-#endif
- eval += volume_eval_phase(sc, omega_in, omega_out);
- }
+ if(CLOSURE_IS_VOLUME(sc->type))
+ eval += volume_eval_phase(kg, sc, omega_in, omega_out);
}
return eval;
#else
- return volume_eval_phase(&sd->closure, omega_in, omega_out);
+ return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
#endif
}
/* Volume Evaluation */
__device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
- float randb, int path_flag)
+ float randb, int path_flag, ShaderContext ctx)
{
#ifdef __SVM__
#ifdef __OSL__
if (kg->osl)
- OSLShader::eval_volume(kg, sd, randb, path_flag);
+ OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
else
#endif
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
@@ -786,13 +759,13 @@ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
/* Displacement Evaluation */
-__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
+__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
{
/* this will modify sd->P */
#ifdef __SVM__
#ifdef __OSL__
if (kg->osl)
- OSLShader::eval_displacement(kg, sd);
+ OSLShader::eval_displacement(kg, sd, ctx);
else
#endif
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
@@ -805,8 +778,20 @@ __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
__device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
{
int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 Ns = kernel_tex_fetch(__tri_normal, prim);
- int shader = __float_as_int(Ns.w);
+ int shader = 0;
+
+#ifdef __HAIR__
+ if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
+#endif
+ float4 Ns = kernel_tex_fetch(__tri_normal, prim);
+ shader = __float_as_int(Ns.w);
+#ifdef __HAIR__
+ }
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+#endif
int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
@@ -818,7 +803,6 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
#ifdef __NON_PROGRESSIVE__
__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
{
-#ifndef __OSL__
/* merge identical closures, better when we sample a single closure at a time */
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sci = &sd->closure[i];
@@ -826,7 +810,11 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
for(int j = i + 1; j < sd->num_closure; j++) {
ShaderClosure *scj = &sd->closure[j];
+#ifdef __OSL__
+ if(!sci->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
+#else
if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
+#endif
sci->weight += scj->weight;
sci->sample_weight += scj->sample_weight;
@@ -838,7 +826,6 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
}
}
}
-#endif
}
#endif
@@ -846,10 +833,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
__device void shader_release(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __OSL__
- if (kg->osl)
- OSLShader::release(kg, sd);
-#endif
+ /* nothing to do currently */
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 4855a94..e27de95 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -27,6 +27,7 @@
/* bvh */
KERNEL_TEX(float4, texture_float4, __bvh_nodes)
KERNEL_TEX(float4, texture_float4, __tri_woop)
+KERNEL_TEX(uint, texture_uint, __prim_segment)
KERNEL_TEX(uint, texture_uint, __prim_visibility)
KERNEL_TEX(uint, texture_uint, __prim_index)
KERNEL_TEX(uint, texture_uint, __prim_object)
@@ -34,6 +35,7 @@ KERNEL_TEX(uint, texture_uint, __object_node)
/* objects */
KERNEL_TEX(float4, texture_float4, __objects)
+KERNEL_TEX(float4, texture_float4, __objects_vector)
/* triangles */
KERNEL_TEX(float4, texture_float4, __tri_normal)
@@ -41,6 +43,10 @@ KERNEL_TEX(float4, texture_float4, __tri_vnormal)
KERNEL_TEX(float4, texture_float4, __tri_vindex)
KERNEL_TEX(float4, texture_float4, __tri_verts)
+/* curves */
+KERNEL_TEX(float4, texture_float4, __curves)
+KERNEL_TEX(float4, texture_float4, __curve_keys)
+
/* attributes */
KERNEL_TEX(uint4, texture_uint4, __attributes_map)
KERNEL_TEX(float, texture_float, __attributes_float)
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
index 0db4472..d346137 100644
--- a/intern/cycles/kernel/kernel_triangle.h
+++ b/intern/cycles/kernel/kernel_triangle.h
@@ -190,82 +190,5 @@ __device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *s
}
}
-/* motion */
-
-__device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
-{
- float3 motion_pre = sd->P, motion_post = sd->P;
-
- /* deformation motion */
- int offset_pre = find_attribute(kg, sd, ATTR_STD_MOTION_PRE);
- int offset_post = find_attribute(kg, sd, ATTR_STD_MOTION_POST);
-
- if(offset_pre != ATTR_STD_NOT_FOUND)
- motion_pre = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_pre, NULL, NULL);
- if(offset_post != ATTR_STD_NOT_FOUND)
- motion_post = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_post, NULL, NULL);
-
- /* object motion. note that depending on the mesh having motion vectors, this
- * transformation was set match the world/object space of motion_pre/post */
- Transform tfm;
-
- tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE);
- motion_pre = transform_point(&tfm, motion_pre);
-
- tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST);
- motion_post = transform_point(&tfm, motion_post);
-
- float3 P;
-
- /* camera motion, for perspective/orthographic motion.pre/post will be a
- * world-to-raster matrix, for panorama it's world-to-camera */
- if (kernel_data.cam.type != CAMERA_PANORAMA) {
- tfm = kernel_data.cam.worldtoraster;
- P = transform_perspective(&tfm, sd->P);
-
- tfm = kernel_data.cam.motion.pre;
- motion_pre = transform_perspective(&tfm, motion_pre);
-
- tfm = kernel_data.cam.motion.post;
- motion_post = transform_perspective(&tfm, motion_post);
- }
- else {
- tfm = kernel_data.cam.worldtocamera;
- P = normalize(transform_point(&tfm, sd->P));
- P = float2_to_float3(direction_to_panorama(kg, P));
- P.x *= kernel_data.cam.width;
- P.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion.pre;
- motion_pre = normalize(transform_point(&tfm, motion_pre));
- motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre));
- motion_pre.x *= kernel_data.cam.width;
- motion_pre.y *= kernel_data.cam.height;
-
- tfm = kernel_data.cam.motion.post;
- motion_post = normalize(transform_point(&tfm, motion_post));
- motion_post = float2_to_float3(direction_to_panorama(kg, motion_post));
- motion_post.x *= kernel_data.cam.width;
- motion_post.y *= kernel_data.cam.height;
- }
-
- motion_pre = motion_pre - P;
- motion_post = P - motion_post;
-
- return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
-}
-
-__device float3 triangle_uv(KernelGlobals *kg, ShaderData *sd)
-{
- int offset_uv = find_attribute(kg, sd, ATTR_STD_UV);
-
- if(offset_uv == ATTR_STD_NOT_FOUND)
- return make_float3(0.0f, 0.0f, 0.0f);
-
- float3 uv = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, offset_uv, NULL, NULL);
- uv.z = 1.0f;
- return uv;
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index e3a766e..102be44 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -29,7 +29,8 @@
CCL_NAMESPACE_BEGIN
/* constants */
-#define OBJECT_SIZE 18
+#define OBJECT_SIZE 11
+#define OBJECT_VECTOR_SIZE 6
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
@@ -46,6 +47,8 @@ CCL_NAMESPACE_BEGIN
#define __OSL__
#endif
#define __NON_PROGRESSIVE__
+#define __HAIR__
+#define __LAMP_MIS__
#endif
#ifdef __KERNEL_CUDA__
@@ -115,7 +118,6 @@ CCL_NAMESPACE_BEGIN
#define __ANISOTROPIC__
#define __OBJECT_MOTION__
#endif
-
//#define __SOBOL_FULL_SCREEN__
/* Shader Evaluation */
@@ -291,7 +293,8 @@ typedef enum LightType {
LIGHT_BACKGROUND,
LIGHT_AREA,
LIGHT_AO,
- LIGHT_SPOT
+ LIGHT_SPOT,
+ LIGHT_STRAND
} LightType;
/* Camera Type */
@@ -342,21 +345,47 @@ typedef struct Intersection {
float t, u, v;
int prim;
int object;
+ int segment;
} Intersection;
/* Attributes */
+#define ATTR_PRIM_TYPES 2
+#define ATTR_PRIM_CURVE 1
+
typedef enum AttributeElement {
+ ATTR_ELEMENT_NONE,
+ ATTR_ELEMENT_VALUE,
ATTR_ELEMENT_FACE,
ATTR_ELEMENT_VERTEX,
ATTR_ELEMENT_CORNER,
- ATTR_ELEMENT_VALUE,
- ATTR_ELEMENT_NONE
+ ATTR_ELEMENT_CURVE,
+ ATTR_ELEMENT_CURVE_KEY
} AttributeElement;
+typedef enum AttributeStandard {
+ ATTR_STD_NONE = 0,
+ ATTR_STD_VERTEX_NORMAL,
+ ATTR_STD_FACE_NORMAL,
+ ATTR_STD_UV,
+ ATTR_STD_UV_TANGENT,
+ ATTR_STD_UV_TANGENT_SIGN,
+ ATTR_STD_GENERATED,
+ ATTR_STD_POSITION_UNDEFORMED,
+ ATTR_STD_POSITION_UNDISPLACED,
+ ATTR_STD_MOTION_PRE,
+ ATTR_STD_MOTION_POST,
+ ATTR_STD_PARTICLE,
+ ATTR_STD_CURVE_TANGENT,
+ ATTR_STD_CURVE_INTERCEPT,
+ ATTR_STD_NUM,
+
+ ATTR_STD_NOT_FOUND = ~0
+} AttributeStandard;
+
/* Closure data */
-#define MAX_CLOSURE 8
+#define MAX_CLOSURE 16
typedef struct ShaderClosure {
ClosureType type;
@@ -379,6 +408,18 @@ typedef struct ShaderClosure {
#endif
} ShaderClosure;
+/* Shader Context
+ *
+ * For OSL we recycle a fixed number of contexts for speed */
+
+typedef enum ShaderContext {
+ SHADER_CONTEXT_MAIN = 0,
+ SHADER_CONTEXT_INDIRECT = 1,
+ SHADER_CONTEXT_EMISSION = 2,
+ SHADER_CONTEXT_SHADOW = 3,
+ SHADER_CONTEXT_NUM = 4
+} ShaderContext;
+
/* Shader Data
*
* Main shader state at a point on the surface or in a volume. All coordinates
@@ -423,6 +464,11 @@ typedef struct ShaderData {
/* primitive id if there is one, ~0 otherwise */
int prim;
+
+#ifdef __HAIR__
+ /* for curves, segment number in curve, ~0 for triangles */
+ int segment;
+#endif
/* parametric coordinates
* - barycentric weights for triangles */
float u, v;
@@ -466,11 +512,6 @@ typedef struct ShaderData {
/* Closure data, with a single sampled closure for low memory usage */
ShaderClosure closure;
#endif
-
-#ifdef __OSL__
- /* OSL context */
- void *osl_ctx;
-#endif
} ShaderData;
/* Constrant Kernel Data
@@ -596,6 +637,7 @@ typedef struct KernelIntegrator {
int num_all_lights;
float pdf_triangles;
float pdf_lights;
+ float inv_pdf_lights;
int pdf_background_res;
/* bounces */
@@ -631,7 +673,7 @@ typedef struct KernelIntegrator {
int transmission_samples;
int ao_samples;
int mesh_light_samples;
- int pad1, pad2;
+ int pad1;
} KernelIntegrator;
typedef struct KernelBVH {
@@ -642,6 +684,29 @@ typedef struct KernelBVH {
int pad2;
} KernelBVH;
+typedef enum CurveFlag {
+ /* runtime flags */
+ CURVE_KN_BACKFACING = 1, /* backside of cylinder? */
+ CURVE_KN_ENCLOSEFILTER = 2, /* don't consider strands surrounding start point? */
+ CURVE_KN_CURVEDATA = 4, /* curve data available? */
+ CURVE_KN_INTERPOLATE = 8, /* render as a curve? - not supported yet */
+ CURVE_KN_ACCURATE = 16, /* use accurate intersections test? */
+ CURVE_KN_INTERSECTCORRECTION = 32, /* correct for width after determing closest midpoint? */
+ CURVE_KN_POSTINTERSECTCORRECTION = 64, /* correct for width after intersect? */
+ CURVE_KN_NORMALCORRECTION = 128, /* correct tangent normal for slope? */
+ CURVE_KN_TRUETANGENTGNORMAL = 256, /* use tangent normal for geometry? */
+ CURVE_KN_TANGENTGNORMAL = 512, /* use tangent normal for shader? */
+} CurveFlag;
+
+typedef struct KernelCurves {
+ /* strand intersect and normal parameters - many can be changed to flags*/
+ float normalmix;
+ float encasing_ratio;
+ int curveflags;
+ int pad;
+
+} KernelCurves;
+
typedef struct KernelData {
KernelCamera cam;
KernelFilm film;
@@ -649,6 +714,7 @@ typedef struct KernelData {
KernelSunSky sunsky;
KernelIntegrator integrator;
KernelBVH bvh;
+ KernelCurves curve_kernel_data;
} KernelData;
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt
index 1b1bb55..5a27f78 100644
--- a/intern/cycles/kernel/osl/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/CMakeLists.txt
@@ -14,7 +14,9 @@ set(INC_SYS
set(SRC
background.cpp
+ bsdf_diffuse_ramp.cpp
bsdf_phong_ramp.cpp
+ bsdf_toon.cpp
emissive.cpp
osl_closures.cpp
osl_services.cpp
diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript
index d4b42d2..fe7fec4 100644
--- a/intern/cycles/kernel/osl/SConscript
+++ b/intern/cycles/kernel/osl/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
new file mode 100644
index 0000000..a320bea
--- /dev/null
+++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp
@@ -0,0 +1,115 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <OpenImageIO/fmath.h>
+
+#include <OSL/genclosure.h>
+
+#include "osl_closures.h"
+
+#include "kernel_types.h"
+#include "kernel_montecarlo.h"
+#include "closure/bsdf_diffuse_ramp.h"
+
+CCL_NAMESPACE_BEGIN
+
+using namespace OSL;
+
+class DiffuseRampClosure : public CBSDFClosure {
+public:
+ DiffuseRampClosure() : CBSDFClosure(LABEL_DIFFUSE) {}
+ Color3 colors[8];
+ float3 fcolors[8];
+
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "diffuse_ramp"; }
+
+ void setup()
+ {
+ sc.prim = this;
+ m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc);
+
+ for(int i = 0; i < 8; i++)
+ fcolors[i] = TO_FLOAT3(colors[i]);
+ }
+
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
+
+ void blur(float roughness)
+ {
+ bsdf_diffuse_ramp_blur(&sc, roughness);
+ }
+
+ void print_on(std::ostream &out) const
+ {
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
+ }
+
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_ramp_eval_reflect(&sc, fcolors, omega_out, omega_in, &pdf);
+ }
+
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_ramp_eval_transmit(&sc, fcolors, omega_out, omega_in, &pdf);
+ }
+
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_diffuse_ramp_sample(&sc, fcolors, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
+
+ClosureParam *closure_bsdf_diffuse_ramp_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N),
+ CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(DiffuseRampClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure)
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index fb144be..ef656ee 100644
--- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -54,7 +54,7 @@ public:
void setup()
{
- sc.N = TO_FLOAT3(N);
+ sc.prim = this;
m_shaderdata_flag = bsdf_phong_ramp_setup(&sc);
for(int i = 0; i < 8; i++)
@@ -100,7 +100,7 @@ public:
ClosureParam *closure_bsdf_phong_ramp_params()
{
static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(PhongRampClosure, N),
+ CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N),
CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
CLOSURE_STRING_KEYPARAM("label"),
diff --git a/intern/cycles/kernel/osl/bsdf_toon.cpp b/intern/cycles/kernel/osl/bsdf_toon.cpp
new file mode 100644
index 0000000..d409b2c
--- /dev/null
+++ b/intern/cycles/kernel/osl/bsdf_toon.cpp
@@ -0,0 +1,179 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <OpenImageIO/fmath.h>
+
+#include <OSL/genclosure.h>
+
+#include "osl_closures.h"
+
+#include "kernel_types.h"
+#include "kernel_montecarlo.h"
+#include "closure/bsdf_toon.h"
+
+CCL_NAMESPACE_BEGIN
+
+using namespace OSL;
+
+/* DIFFUSE TOON */
+
+class DiffuseToonClosure : public CBSDFClosure {
+public:
+ DiffuseToonClosure() : CBSDFClosure(LABEL_DIFFUSE) {}
+
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "diffuse_toon"; }
+
+ void setup()
+ {
+ sc.prim = this;
+ m_shaderdata_flag = bsdf_diffuse_toon_setup(&sc);
+ }
+
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
+
+ void blur(float roughness)
+ {
+ bsdf_diffuse_toon_blur(&sc, roughness);
+ }
+
+ void print_on(std::ostream &out) const
+ {
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
+ }
+
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_toon_eval_reflect(&sc, omega_out, omega_in, &pdf);
+ }
+
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_diffuse_toon_eval_transmit(&sc, omega_out, omega_in, &pdf);
+ }
+
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_diffuse_toon_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
+
+ClosureParam *closure_bsdf_diffuse_toon_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, sc.N),
+ CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data1),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(DiffuseToonClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_bsdf_diffuse_toon_prepare, DiffuseToonClosure)
+
+/* SPECULAR TOON */
+
+class SpecularToonClosure : public CBSDFClosure {
+public:
+ SpecularToonClosure() : CBSDFClosure(LABEL_GLOSSY) {}
+
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "specular_toon"; }
+
+ void setup()
+ {
+ sc.prim = this;
+ m_shaderdata_flag = bsdf_specular_toon_setup(&sc);
+ }
+
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
+
+ void blur(float roughness)
+ {
+ bsdf_specular_toon_blur(&sc, roughness);
+ }
+
+ void print_on(std::ostream &out) const
+ {
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
+ }
+
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_specular_toon_eval_reflect(&sc, omega_out, omega_in, &pdf);
+ }
+
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
+ {
+ return bsdf_specular_toon_eval_transmit(&sc, omega_out, omega_in, &pdf);
+ }
+
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_specular_toon_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
+
+ClosureParam *closure_bsdf_specular_toon_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(SpecularToonClosure, sc.N),
+ CLOSURE_FLOAT_PARAM(SpecularToonClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(SpecularToonClosure, sc.data1),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(SpecularToonClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_bsdf_specular_toon_prepare, SpecularToonClosure)
+
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 37e3e37..7d9fa81 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -65,7 +65,7 @@ public:
Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const
{
- float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
+ float3 result = emissive_simple_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
return TO_COLOR3(result);
}
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index f95859d..9e65cda 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -43,12 +43,11 @@
#include "kernel_types.h"
#include "kernel_montecarlo.h"
-#include "closure/bsdf.h"
+#include "closure/bsdf_util.h"
#include "closure/bsdf_ashikhmin_velvet.h"
#include "closure/bsdf_diffuse.h"
#include "closure/bsdf_microfacet.h"
#include "closure/bsdf_oren_nayar.h"
-#include "closure/bsdf_phong_ramp.h"
#include "closure/bsdf_reflection.h"
#include "closure/bsdf_refraction.h"
#include "closure/bsdf_transparent.h"
@@ -62,34 +61,34 @@ using namespace OSL;
/* BSDF class definitions */
BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(DiffuseClosure, N),
+ CLOSURE_FLOAT3_PARAM(DiffuseClosure, sc.N),
BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(TranslucentClosure, N),
+ CLOSURE_FLOAT3_PARAM(TranslucentClosure, sc.N),
BSDF_CLOSURE_CLASS_END(Translucent, translucent)
BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(OrenNayarClosure, N),
+ CLOSURE_FLOAT3_PARAM(OrenNayarClosure, sc.N),
CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR)
- CLOSURE_VECTOR_PARAM(ReflectionClosure, N),
+ CLOSURE_FLOAT3_PARAM(ReflectionClosure, sc.N),
BSDF_CLOSURE_CLASS_END(Reflection, reflection)
BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR)
- CLOSURE_VECTOR_PARAM(RefractionClosure, N),
+ CLOSURE_FLOAT3_PARAM(RefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(Refraction, refraction)
BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N),
+ CLOSURE_FLOAT3_PARAM(WestinBackscatterClosure, sc.N),
CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(WestinSheenClosure, N),
+ CLOSURE_FLOAT3_PARAM(WestinSheenClosure, sc.N),
CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen)
@@ -97,35 +96,35 @@ BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR)
BSDF_CLOSURE_CLASS_END(Transparent, transparent)
BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE)
- CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N),
+ CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, sc.N),
CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(WardClosure, N),
- CLOSURE_VECTOR_PARAM(WardClosure, T),
+ CLOSURE_FLOAT3_PARAM(WardClosure, sc.N),
+ CLOSURE_FLOAT3_PARAM(WardClosure, sc.T),
CLOSURE_FLOAT_PARAM(WardClosure, sc.data0),
CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(Ward, ward)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY)
- CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
@@ -194,8 +193,14 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
closure_holdout_params(), closure_holdout_prepare);
register_closure(ss, "ambient_occlusion", id++,
closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare);
+ register_closure(ss, "diffuse_ramp", id++,
+ closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
register_closure(ss, "phong_ramp", id++,
closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
+ register_closure(ss, "diffuse_toon", id++,
+ closure_bsdf_diffuse_toon_params(), closure_bsdf_diffuse_toon_prepare);
+ register_closure(ss, "specular_toon", id++,
+ closure_bsdf_specular_toon_params(), closure_bsdf_specular_toon_prepare);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 2d91b37..daccc03 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -47,13 +47,19 @@ OSL::ClosureParam *closure_emission_params();
OSL::ClosureParam *closure_background_params();
OSL::ClosureParam *closure_holdout_params();
OSL::ClosureParam *closure_ambient_occlusion_params();
+OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
+OSL::ClosureParam *closure_bsdf_diffuse_toon_params();
+OSL::ClosureParam *closure_bsdf_specular_toon_params();
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_diffuse_toon_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_specular_toon_prepare(OSL::RendererServices *, int id, void *data);
enum {
AmbientOcclusion = 100
@@ -68,8 +74,11 @@ void name(RendererServices *, int id, void *data) \
#define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname)
-#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
-#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
+#define CLOSURE_FLOAT3_PARAM(st, fld) \
+ { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
+
+#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
+#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
/* BSDF */
@@ -77,7 +86,6 @@ void name(RendererServices *, int id, void *data) \
class CBSDFClosure : public OSL::ClosurePrimitive {
public:
ShaderClosure sc;
- OSL::Vec3 N, T;
CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
m_scattering_label(scattering), m_shaderdata_flag(0) { }
@@ -85,7 +93,6 @@ public:
int scattering() const { return m_scattering_label; }
int shaderdata_flag() const { return m_shaderdata_flag; }
- ClosureType shaderclosure_type() const { return sc.type; }
virtual void blur(float roughness) = 0;
virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
@@ -112,8 +119,7 @@ public: \
\
void setup() \
{ \
- sc.N = TO_FLOAT3(N); \
- sc.T = TO_FLOAT3(T); \
+ sc.prim = NULL; \
m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
} \
\
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 1a2a210..fb56911 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -75,10 +75,21 @@ struct OSLGlobals {
vector<ustring> object_names;
};
+/* trace() call result */
+struct OSLTraceData {
+ Ray ray;
+ Intersection isect;
+ ShaderData sd;
+ bool setup;
+ bool init;
+};
+
/* thread key for thread specific data lookup */
struct OSLThreadData {
OSL::ShaderGlobals globals;
OSL::PerThreadInfo *thread_info;
+ OSLTraceData tracedata;
+ OSL::ShadingContext *context[SHADER_CONTEXT_NUM];
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index b584a54..92a023b 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -37,9 +37,10 @@
#include "kernel_differential.h"
#include "kernel_object.h"
#include "kernel_bvh.h"
-#include "kernel_attribute.h"
-#include "kernel_projection.h"
#include "kernel_triangle.h"
+#include "kernel_curve.h"
+#include "kernel_primitive.h"
+#include "kernel_projection.h"
#include "kernel_accumulate.h"
#include "kernel_shader.h"
@@ -47,7 +48,7 @@ CCL_NAMESPACE_BEGIN
/* RenderServices implementation */
-#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m))
+#define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2))
/* static ustrings */
ustring OSLRenderServices::u_distance("distance");
@@ -74,6 +75,11 @@ ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
ustring OSLRenderServices::u_geom_name("geom:name");
+#ifdef __HAIR__
+ustring OSLRenderServices::u_is_curve("geom:is_curve");
+ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
+ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
+#endif
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
ustring OSLRenderServices::u_trace("trace");
ustring OSLRenderServices::u_hit("hit");
@@ -121,7 +127,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -151,7 +157,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
itfm = transform_transpose(itfm);
- result = TO_MATRIX44(itfm);
+ COPY_MATRIX44(&result, &itfm);
return true;
}
@@ -166,22 +172,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
if (from == u_ndc) {
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -194,22 +200,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -232,7 +238,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -257,7 +263,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -272,22 +278,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
if (from == u_ndc) {
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -300,22 +306,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to)
if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
- result = TO_MATRIX44(tfm);
+ COPY_MATRIX44(&result, &tfm);
return true;
}
@@ -495,14 +501,14 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OS
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
{
float3 fval[3];
- fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float3(fval, type, derivatives, val);
}
else if (attr.type == TypeDesc::TypeFloat) {
float fval[3];
- fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ fval[0] = primitive_attribute_float(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float(fval, type, derivatives, val);
}
else {
@@ -593,10 +599,17 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
float3 f = particle_angular_velocity(kg, particle_id);
return set_attribute_float3(f, type, derivatives, val);
}
+
+ /* Geometry Attributes */
else if (name == u_geom_numpolyvertices) {
return set_attribute_int(3, type, derivatives, val);
}
- else if (name == u_geom_trianglevertices || name == u_geom_polyvertices) {
+ else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices)
+#ifdef __HAIR__
+ && sd->segment == ~0) {
+#else
+ ) {
+#endif
float3 P[3];
triangle_vertices(kg, sd->prim, P);
@@ -612,6 +625,22 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
ustring object_name = kg->osl->object_names[sd->object];
return set_attribute_string(object_name, type, derivatives, val);
}
+
+#ifdef __HAIR__
+ /* Hair Attributes */
+ else if (name == u_is_curve) {
+ float f = (sd->segment != ~0);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_curve_thickness) {
+ float f = curve_thickness(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == u_curve_tangent_normal) {
+ float3 f = curve_tangent_normal(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+#endif
else
return false;
}
@@ -634,24 +663,34 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
{
KernelGlobals *kg = kernel_globals;
ShaderData *sd = (ShaderData *)renderstate;
- int object = sd->object;
- int tri = sd->prim;
+ int object, prim, segment;
/* lookup of attribute on another object */
- if (object_name != u_empty) {
+ if (object_name != u_empty || sd == NULL) {
OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
if (it == kg->osl->object_name_map.end())
return false;
object = it->second;
- tri = ~0;
+ prim = ~0;
+ segment = ~0;
}
- else if (object == ~0) {
- return get_background_attribute(kg, sd, name, type, derivatives, val);
+ else {
+ object = sd->object;
+ prim = sd->prim;
+#ifdef __HAIR__
+ segment = sd->segment;
+#else
+ segment = ~0;
+#endif
+
+ if (object == ~0)
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
+ object = object*ATTR_PRIM_TYPES + (segment != ~0);
OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object];
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
@@ -660,7 +699,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (attr.elem != ATTR_ELEMENT_VALUE) {
/* triangle and vertex attributes */
- if (tri != ~0)
+ if (prim != ~0)
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
}
else {
@@ -815,13 +854,10 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
ray.dD.dy = TO_FLOAT3(dRdy);
/* allocate trace data */
- TraceData *tracedata = new TraceData();
+ OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
tracedata->ray = ray;
tracedata->setup = false;
-
- if(sg->tracedata)
- delete (TraceData*)sg->tracedata;
- sg->tracedata = tracedata;
+ tracedata->init = true;
/* raytrace */
return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect);
@@ -831,9 +867,9 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
TypeDesc type, void *val, bool derivatives)
{
- TraceData *tracedata = (TraceData*)sg->tracedata;
+ OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
- if(source == u_trace && tracedata) {
+ if(source == u_trace && tracedata->init) {
if(name == u_hit) {
return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index e687700..50c50b9 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -106,13 +106,6 @@ public:
static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
TypeDesc type, bool derivatives, void *val);
- struct TraceData {
- Ray ray;
- Intersection isect;
- ShaderData sd;
- bool setup;
- };
-
static ustring u_distance;
static ustring u_index;
static ustring u_camera;
@@ -137,6 +130,9 @@ public:
static ustring u_geom_trianglevertices;
static ustring u_geom_polyvertices;
static ustring u_geom_name;
+ static ustring u_is_curve;
+ static ustring u_curve_thickness;
+ static ustring u_curve_tangent_normal;
static ustring u_path_ray_length;
static ustring u_trace;
static ustring u_hit;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 32712b2..a32c526 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -26,9 +26,10 @@
#include "osl_services.h"
#include "osl_shader.h"
-#include "util_attribute.h"
#include "util_foreach.h"
+#include "attribute.h"
+
#include <OSL/oslexec.h>
CCL_NAMESPACE_BEGIN
@@ -51,8 +52,13 @@ void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OS
OSLThreadData *tdata = new OSLThreadData();
memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
+ tdata->globals.tracedata = &tdata->tracedata;
+ tdata->globals.flipHandedness = false;
tdata->thread_info = ss->create_thread_info();
+ for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
+ tdata->context[i] = ss->get_context(tdata->thread_info);
+
kg->osl_ss = (OSLShadingSystem*)ss;
kg->osl_tdata = tdata;
}
@@ -65,6 +71,9 @@ void OSLShader::thread_free(KernelGlobals *kg)
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
OSLThreadData *tdata = kg->osl_tdata;
+ for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
+ ss->release_context(tdata->context[i]);
+
ss->destroy_thread_info(tdata->thread_info);
delete tdata;
@@ -77,8 +86,10 @@ void OSLShader::thread_free(KernelGlobals *kg)
/* Globals */
static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
- int path_flag, OSL::ShaderGlobals *globals)
+ int path_flag, OSLThreadData *tdata)
{
+ OSL::ShaderGlobals *globals = &tdata->globals;
+
/* copy from shader data to shader globals */
globals->P = TO_VEC3(sd->P);
globals->dPdx = TO_VEC3(sd->dP.dx);
@@ -100,15 +111,11 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->time = sd->time;
/* booleans */
- globals->raytype = path_flag; /* todo: add our own ray types */
+ globals->raytype = path_flag;
globals->backfacing = (sd->flag & SD_BACKFACING);
- /* don't know yet if we need this */
- globals->flipHandedness = false;
-
/* shader data to be used in services callbacks */
globals->renderstate = sd;
- globals->tracedata = NULL;
/* hacky, we leave it to services to fetch actual object matrix */
globals->shader2common = sd;
@@ -116,6 +123,9 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
/* must be set to NULL before execute */
globals->Ci = NULL;
+
+ /* clear trace data */
+ tdata->tracedata.init = false;
}
/* Surface */
@@ -132,14 +142,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
if (prim) {
ShaderClosure sc;
- sc.prim = prim;
sc.weight = weight;
switch (prim->category()) {
case OSL::ClosurePrimitive::BSDF: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
CBSDFClosure *bsdf = (CBSDFClosure *)prim;
int scattering = bsdf->scattering();
@@ -151,8 +157,13 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
- sc.type = bsdf->shaderclosure_type();
- sc.N = bsdf->sc.N; /* needed for AO */
+
+ sc.type = bsdf->sc.type;
+ sc.N = bsdf->sc.N;
+ sc.T = bsdf->sc.T;
+ sc.data0 = bsdf->sc.data0;
+ sc.data1 = bsdf->sc.data1;
+ sc.prim = bsdf->sc.prim;
/* add */
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
@@ -162,14 +173,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break;
}
case OSL::ClosurePrimitive::Emissive: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
/* sample weight */
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
sc.type = CLOSURE_EMISSION_ID;
+ sc.prim = NULL;
/* flag */
if(sd->num_closure < MAX_CLOSURE) {
@@ -179,14 +188,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break;
}
case AmbientOcclusion: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
/* sample weight */
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ sc.prim = NULL;
if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
@@ -195,11 +202,9 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break;
}
case OSL::ClosurePrimitive::Holdout:
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
sc.sample_weight = 0.0f;
sc.type = CLOSURE_HOLDOUT_ID;
+ sc.prim = NULL;
if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc;
@@ -226,26 +231,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
}
}
-void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
+void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
/* execute shader for this point */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
int shader = sd->shader & SHADER_MASK;
if (kg->osl->surface_state[shader])
- ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals);
-
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals);
/* flatten closure tree */
sd->num_closure = 0;
@@ -287,24 +286,19 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
return make_float3(0.0f, 0.0f, 0.0f);
}
-float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
+float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
/* execute shader for this point */
- if (kg->osl->background_state)
- ss->execute(*ctx, *(kg->osl->background_state), *globals);
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ if (kg->osl->background_state)
+ ss->execute(*octx, *(kg->osl->background_state), *globals);
/* return background color immediately */
if (globals->Ci)
@@ -327,19 +321,16 @@ static void flatten_volume_closure_tree(ShaderData *sd,
if (prim) {
ShaderClosure sc;
- sc.prim = prim;
sc.weight = weight;
switch (prim->category()) {
case OSL::ClosurePrimitive::Volume: {
- if (sd->num_closure == MAX_CLOSURE)
- return;
-
/* sample weight */
float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight;
sc.type = CLOSURE_VOLUME_ID;
+ sc.prim = NULL;
/* add */
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE)
@@ -368,26 +359,20 @@ static void flatten_volume_closure_tree(ShaderData *sd,
}
}
-void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
+void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
/* execute shader */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
int shader = sd->shader & SHADER_MASK;
if (kg->osl->volume_state[shader])
- ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals);
-
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
if (globals->Ci)
flatten_volume_closure_tree(sd, globals->Ci);
@@ -395,46 +380,25 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
/* Displacement */
-void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
+void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
{
- /* gather pointers */
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
- OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
-
/* setup shader globals from shader data */
- shaderdata_to_shaderglobals(kg, sd, 0, globals);
+ OSLThreadData *tdata = kg->osl_tdata;
+ shaderdata_to_shaderglobals(kg, sd, 0, tdata);
/* execute shader */
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
+ OSL::ShaderGlobals *globals = &tdata->globals;
+ OSL::ShadingContext *octx = tdata->context[(int)ctx];
int shader = sd->shader & SHADER_MASK;
if (kg->osl->displacement_state[shader])
- ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals);
-
- /* free trace data */
- if(globals->tracedata)
- delete (OSLRenderServices::TraceData*)globals->tracedata;
+ ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals);
/* get back position */
sd->P = TO_FLOAT3(globals->P);
}
-void OSLShader::init(KernelGlobals *kg, ShaderData *sd)
-{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
- OSLThreadData *tdata = kg->osl_tdata;
-
- sd->osl_ctx = ss->get_context(tdata->thread_info);
-}
-
-void OSLShader::release(KernelGlobals *kg, ShaderData *sd)
-{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
-
- ss->release_context((OSL::ShadingContext *)sd->osl_ctx);
-}
-
/* BSDF Closure */
int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
@@ -490,15 +454,21 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_
/* Attributes */
-int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
+int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
{
/* for OSL, a hash map is used to lookup the attribute by name. */
- OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[sd->object];
- ustring stdname(std::string("std::") + std::string(attribute_standard_name((AttributeStandard)id)));
+ int object = sd->object*ATTR_PRIM_TYPES;
+#ifdef __HAIR__
+ if(sd->segment != ~0) object += ATTR_PRIM_CURVE;
+#endif
+
+ OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
+ ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
if (it != attr_map.end()) {
const OSLGlobals::Attribute &osl_attr = it->second;
+ *elem = osl_attr.elem;
/* return result */
return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
}
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index e614f24..2062c65 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -55,10 +55,10 @@ public:
static void thread_free(KernelGlobals *kg);
/* eval */
- static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
- static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag);
- static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
- static void eval_displacement(KernelGlobals *kg, ShaderData *sd);
+ static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
+ static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx);
+ static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
+ static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx);
/* sample & eval */
static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc,
@@ -73,12 +73,8 @@ public:
static float3 volume_eval_phase(const ShaderClosure *sc,
const float3 omega_in, const float3 omega_out);
- /* release */
- static void init(KernelGlobals *kg, ShaderData *sd);
- static void release(KernelGlobals *kg, ShaderData *sd);
-
/* attributes */
- static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
+ static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index f7fec62..acae46f 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -27,6 +27,7 @@ set(SRC_OSL
node_glass_bsdf.osl
node_glossy_bsdf.osl
node_gradient_texture.osl
+ node_hair_info.osl
node_holdout.osl
node_hsv.osl
node_image_texture.osl
@@ -49,6 +50,7 @@ set(SRC_OSL
node_output_volume.osl
node_particle_info.osl
node_refraction_bsdf.osl
+ node_rgb_curves.osl
node_rgb_ramp.osl
node_separate_rgb.osl
node_set_normal.osl
@@ -58,6 +60,7 @@ set(SRC_OSL
node_translucent_bsdf.osl
node_transparent_bsdf.osl
node_value.osl
+ node_vector_curves.osl
node_vector_math.osl
node_velvet_bsdf.osl
node_voronoi_texture.osl
diff --git a/intern/cycles/kernel/shaders/SConscript b/intern/cycles/kernel/shaders/SConscript
index 36b86d7..daf2b67 100644
--- a/intern/cycles/kernel/shaders/SConscript
+++ b/intern/cycles/kernel/shaders/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
import Blender as B
diff --git a/intern/cycles/kernel/shaders/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl
index ecf6bf5..5c9ffec 100644
--- a/intern/cycles/kernel/shaders/node_add_closure.osl
+++ b/intern/cycles/kernel/shaders/node_add_closure.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_add_closure(
- closure color Closure1 = background(),
- closure color Closure2 = background(),
- output closure color Closure = background())
+ closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
{
Closure = Closure1 + Closure2;
}
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
index b942334..58c4422 100644
--- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -20,8 +20,8 @@
shader node_ambient_occlusion(
normal NormalIn = N,
- color Color = color(0.8, 0.8, 0.8),
- output closure color AO = ambient_occlusion())
+ color Color = 0.8,
+ output closure color AO = 0)
{
AO = Color * ambient_occlusion();
}
diff --git a/intern/cycles/kernel/shaders/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl
index 8e7c846..4740492 100644
--- a/intern/cycles/kernel/shaders/node_attribute.osl
+++ b/intern/cycles/kernel/shaders/node_attribute.osl
@@ -22,7 +22,7 @@ shader node_attribute(
string bump_offset = "center",
string name = "",
output point Vector = point(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Fac = 0.0)
{
getattribute(name, Color);
diff --git a/intern/cycles/kernel/shaders/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl
index b51a168..b0c62c0 100644
--- a/intern/cycles/kernel/shaders/node_background.osl
+++ b/intern/cycles/kernel/shaders/node_background.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_background(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Strength = 1.0,
- output closure color Background = background())
+ output closure color Background = 0)
{
Background = Color * Strength * background();
}
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index b1f2a35..509b4f2 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -65,16 +65,16 @@ shader node_brick_texture(
float Squash = 1.0,
int SquashFrequency = 1,
point Vector = P,
- color Color1 = color(0.2, 0.2, 0.2),
- color Color2 = color(0.8, 0.8, 0.8),
- color Mortar = color(0.0, 0.0, 0.0),
+ color Color1 = 0.2,
+ color Color2 = 0.8,
+ color Mortar = 0.0,
float Scale = 5.0,
float MortarSize = 0.02,
float Bias = 0.0,
float BrickWidth = 0.5,
float RowHeight = 0.25,
output float Fac = 0.0,
- output color Color = color(0.2, 0.2, 0.2))
+ output color Color = 0.2)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl
index b263d81..2de3c94 100644
--- a/intern/cycles/kernel/shaders/node_brightness.osl
+++ b/intern/cycles/kernel/shaders/node_brightness.osl
@@ -19,10 +19,10 @@
#include "stdosl.h"
shader node_brightness(
- color ColorIn = color(0.8, 0.8, 0.8),
+ color ColorIn = 0.8,
float Bright = 0.0,
float Contrast = 0.0,
- output color ColorOut = color(0.8, 0.8, 0.8))
+ output color ColorOut = 0.8)
{
float a = 1.0 + Contrast;
float b = Bright - Contrast*0.5;
diff --git a/intern/cycles/kernel/shaders/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl
index eed56f4..84cfa89 100644
--- a/intern/cycles/kernel/shaders/node_checker_texture.osl
+++ b/intern/cycles/kernel/shaders/node_checker_texture.osl
@@ -44,10 +44,10 @@ shader node_checker_texture(
matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
float Scale = 5.0,
point Vector = P,
- color Color1 = color(0.8, 0.8, 0.8),
- color Color2 = color(0.2, 0.2, 0.2),
+ color Color1 = 0.8,
+ color Color2 = 0.2,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl
index 546369f..1bdb4de 100644
--- a/intern/cycles/kernel/shaders/node_combine_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl
@@ -22,7 +22,7 @@ shader node_combine_rgb(
float R = 0.0,
float G = 0.0,
float B = 0.0,
- output color Image = color(0.8, 0.8, 0.8))
+ output color Image = 0.8)
{
Image = color(R, G, B);
}
diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl
index ea488c9..6a6512e 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_color.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl
@@ -19,7 +19,7 @@
#include "stdosl.h"
shader node_convert_from_color(
- color Color = color(0.0, 0.0, 0.0),
+ color Color = 0.0,
output string String = "",
output float Val = 0.0,
output int ValInt = 0,
diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl
index a20b491..b6d5084 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_float.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl
@@ -22,7 +22,7 @@ shader node_convert_from_float(
float Val = 0.0,
output string String = "",
output int ValInt = 0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl
index 911b492..3d389cf 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_int.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl
@@ -22,7 +22,7 @@ shader node_convert_from_int(
int ValInt = 0,
output string String = "",
output float Val = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
index 1add740..a4cb004 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
@@ -24,7 +24,7 @@ shader node_convert_from_normal(
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output point Point = point(0.0, 0.0, 0.0))
{
Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0);
diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl
index 8a31582..8ea7d38 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_point.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl
@@ -24,7 +24,7 @@ shader node_convert_from_point(
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output normal Normal = normal(0.0, 0.0, 0.0))
{
Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0);
diff --git a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
index d6dc173..eae4772 100644
--- a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
@@ -19,10 +19,10 @@
#include "stdosl.h"
shader node_diffuse_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Roughness = 0.0,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
if (Roughness == 0.0)
BSDF = Color * diffuse(Normal);
diff --git a/intern/cycles/kernel/shaders/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl
index 7ad0f9f..854d94c 100644
--- a/intern/cycles/kernel/shaders/node_emission.osl
+++ b/intern/cycles/kernel/shaders/node_emission.osl
@@ -20,9 +20,9 @@
shader node_emission(
int TotalPower = 0,
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Strength = 1.0,
- output closure color Emission = emission())
+ output closure color Emission = 0)
{
if (TotalPower)
Emission = ((Strength / surfacearea()) * Color) * emission();
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 7da336a..33b30a2 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -48,7 +48,7 @@ shader node_environment_texture(
string filename = "",
string projection = "Equirectangular",
string color_space = "sRGB",
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Alpha = 1.0)
{
vector p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl
index d55e908..5c913c2 100644
--- a/intern/cycles/kernel/shaders/node_gamma.osl
+++ b/intern/cycles/kernel/shaders/node_gamma.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_gamma(
- color ColorIn = color(0.8, 0.8, 0.8),
+ color ColorIn = 0.8,
float Gamma = 1.0,
- output color ColorOut = color(0.0, 0.0, 0.0))
+ output color ColorOut = 0.0)
{
ColorOut = pow(ColorIn, Gamma);
}
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index d1c11b7..3d5d673 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -56,8 +56,7 @@ shader node_geometry(
0.0, 0.0, 0.0, 0.0,
0.5, -0.5, 0.0, 1.0);
- vector T = transform(project, generated);
- T = transform("object", "world", T);
+ vector T = transform("object", "world", transform(project, generated));
Tangent = cross(Normal, normalize(cross(T, Normal)));
}
else {
diff --git a/intern/cycles/kernel/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
index 30b9d30..da1a428 100644
--- a/intern/cycles/kernel/shaders/node_glass_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
@@ -20,12 +20,12 @@
#include "node_fresnel.h"
shader node_glass_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
string distribution = "Sharp",
float Roughness = 0.2,
float IOR = 1.45,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
float f = max(IOR, 1.0 + 1e-5);
float eta = backfacing() ? 1.0 / f: f;
diff --git a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
index 03340c7..79bbe72 100644
--- a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
@@ -20,11 +20,11 @@
#include "node_fresnel.h"
shader node_glossy_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
string distribution = "Beckmann",
float Roughness = 0.2,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
if (distribution == "Sharp")
BSDF = Color * reflection(Normal);
diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl
index 8d862db..9ae281f 100644
--- a/intern/cycles/kernel/shaders/node_gradient_texture.osl
+++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl
@@ -68,7 +68,7 @@ shader node_gradient_texture(
string Type = "Linear",
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl
new file mode 100644
index 0000000..cbb3b98
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_hair_info.osl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * 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.
+ */
+
+#include "stdosl.h"
+
+shader node_hair_info(
+ output float IsStrand = 0.0,
+ output float Intercept = 0.0,
+ output float Thickness = 0.0,
+ output normal TangentNormal = N)
+{
+ getattribute("geom:is_curve", IsStrand);
+ getattribute("geom:curve_intercept", Intercept);
+ getattribute("geom:curve_thickness", Thickness);
+ getattribute("geom:curve_tangent_normal", TangentNormal);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index 0f4bedf..d5fdb1c 100644
--- a/intern/cycles/kernel/shaders/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
@@ -24,8 +24,8 @@ shader node_hsv(
float Saturation = 1.0,
float Value = 1.0,
float Fac = 0.5,
- color ColorIn = color(0.0, 0.0, 0.0),
- output color ColorOut = color(0.0, 0.0, 0.0))
+ color ColorIn = 0.0,
+ output color ColorOut = 0.0)
{
color Color = rgb_to_hsv(ColorIn);
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 9907467..c94a3f7 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -37,7 +37,7 @@ shader node_image_texture(
string color_space = "sRGB",
string projection = "Flat",
float projection_blend = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Alpha = 1.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl
index 2702194..8711e2f 100644
--- a/intern/cycles/kernel/shaders/node_invert.osl
+++ b/intern/cycles/kernel/shaders/node_invert.osl
@@ -20,8 +20,8 @@
shader node_invert(
float Fac = 1.0,
- color ColorIn = color(0.8, 0.8, 0.8),
- output color ColorOut = color(0.8, 0.8, 0.8))
+ color ColorIn = 0.8,
+ output color ColorOut = 0.8)
{
color ColorInv = color(1.0) - ColorIn;
ColorOut = mix(ColorIn, ColorInv, Fac);
diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl
index b81a304..943d9c6 100644
--- a/intern/cycles/kernel/shaders/node_magic_texture.osl
+++ b/intern/cycles/kernel/shaders/node_magic_texture.osl
@@ -99,7 +99,7 @@ shader node_magic_texture(
float Distortion = 5.0,
float Scale = 5.0,
point Vector = P,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl
index 92df043..787f652 100644
--- a/intern/cycles/kernel/shaders/node_mapping.osl
+++ b/intern/cycles/kernel/shaders/node_mapping.osl
@@ -28,9 +28,8 @@ shader node_mapping(
{
point p = transform(Matrix, VectorIn);
- if(use_minmax)
+ if (use_minmax)
p = min(max(mapping_min, p), mapping_max);
VectorOut = p;
}
-
diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl
index b2af362..bcd00bb 100644
--- a/intern/cycles/kernel/shaders/node_mix.osl
+++ b/intern/cycles/kernel/shaders/node_mix.osl
@@ -282,9 +282,9 @@ shader node_mix(
string type = "Mix",
int Clamp = 0,
float Fac = 0.5,
- color Color1 = color(0.0, 0.0, 0.0),
- color Color2 = color(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0))
+ color Color1 = 0.0,
+ color Color2 = 0.0,
+ output color Color = 0.0)
{
float t = clamp(Fac, 0.0, 1.0);
diff --git a/intern/cycles/kernel/shaders/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl
index e28dd1f..a0bef49 100644
--- a/intern/cycles/kernel/shaders/node_mix_closure.osl
+++ b/intern/cycles/kernel/shaders/node_mix_closure.osl
@@ -20,9 +20,9 @@
shader node_mix_closure(
float Fac = 0.5,
- closure color Closure1 = background(),
- closure color Closure2 = background(),
- output closure color Closure = background())
+ closure color Closure1 = 0,
+ closure color Closure2 = 0,
+ output closure color Closure = 0)
{
float t = clamp(Fac, 0.0, 1.0);
Closure = (1.0 - t) * Closure1 + t * Closure2;
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index afdbca2..38232ea 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -37,14 +37,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float
int i;
for (i = 0; i < (int)octaves; i++) {
- value += noise("perlin", p) * pwr;
+ value += safe_noise(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value += rmd * noise("perlin", p) * pwr;
+ value += rmd * safe_noise(p) * pwr;
return value;
}
@@ -65,14 +65,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar
int i;
for (i = 0; i < (int)octaves; i++) {
- value *= (pwr * noise("perlin", p) + 1.0);
+ value *= (pwr * safe_noise(p) + 1.0);
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */
+ value *= (rmd * pwr * safe_noise(p) + 1.0); /* correct? */
return value;
}
@@ -93,11 +93,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
int i;
/* first unscaled octave of function; later octaves are scaled */
- value = offset + noise("perlin", p);
+ value = offset + safe_noise(p);
p *= lacunarity;
for (i = 1; i < (int)octaves; i++) {
- increment = (noise("perlin", p) + offset) * pwr * value;
+ increment = (safe_noise(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
p *= lacunarity;
@@ -105,7 +105,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
rmd = octaves - floor(octaves);
if (rmd != 0.0) {
- increment = (noise("perlin", p) + offset) * pwr * value;
+ increment = (safe_noise(p) + offset) * pwr * value;
value += rmd * increment;
}
@@ -128,7 +128,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- result = noise("perlin", p) + offset;
+ result = safe_noise(p) + offset;
weight = gain * result;
p *= lacunarity;
@@ -136,7 +136,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
if (weight > 1.0)
weight = 1.0;
- signal = (noise("perlin", p) + offset) * pwr;
+ signal = (safe_noise(p) + offset) * pwr;
pwr *= pwHL;
result += weight * signal;
weight *= gain * signal;
@@ -145,7 +145,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- result += rmd * ((noise("perlin", p) + offset) * pwr);
+ result += rmd * ((safe_noise(p) + offset) * pwr);
return result;
}
@@ -166,7 +166,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- signal = offset - fabs(noise("perlin", p));
+ signal = offset - fabs(safe_noise(p));
signal *= signal;
result = signal;
weight = 1.0;
@@ -174,7 +174,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
for (i = 1; i < (int)octaves; i++) {
p *= lacunarity;
weight = clamp(signal * gain, 0.0, 1.0);
- signal = offset - fabs(noise("perlin", p));
+ signal = offset - fabs(safe_noise(p));
signal *= signal;
signal *= weight;
result += signal * pwr;
@@ -198,7 +198,7 @@ shader node_musgrave_texture(
float Scale = 5.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
float dimension = max(Dimension, 1e-5);
float octaves = clamp(Detail, 0.0, 16.0);
diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 0a37949..ec86a10 100644
--- a/intern/cycles/kernel/shaders/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -50,7 +50,7 @@ shader node_noise_texture(
float Detail = 2.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.2, 0.2, 0.2))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl
index 6efaf91..da6eedb 100644
--- a/intern/cycles/kernel/shaders/node_output_surface.osl
+++ b/intern/cycles/kernel/shaders/node_output_surface.osl
@@ -18,7 +18,7 @@
#include "stdosl.h"
-surface node_output_surface(closure color Surface = background())
+surface node_output_surface(closure color Surface = 0)
{
Ci = Surface;
}
diff --git a/intern/cycles/kernel/shaders/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl
index 1809424..ec32ed3 100644
--- a/intern/cycles/kernel/shaders/node_output_volume.osl
+++ b/intern/cycles/kernel/shaders/node_output_volume.osl
@@ -18,7 +18,7 @@
#include "stdosl.h"
-volume node_output_volume(closure color Volume = background())
+volume node_output_volume(closure color Volume = 0)
{
Ci = Volume;
}
diff --git a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
index 0cf9d46..d95a26c 100644
--- a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
@@ -19,12 +19,12 @@
#include "stdosl.h"
shader node_refraction_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
string distribution = "Sharp",
float Roughness = 0.2,
float IOR = 1.45,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
float f = max(IOR, 1.0 + 1e-5);
float eta = backfacing() ? 1.0 / f: f;
diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl
new file mode 100644
index 0000000..362bae8
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#include "stdosl.h"
+#include "oslutil.h"
+
+float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component)
+{
+ float f = clamp(at, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0) i = 0;
+ if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1;
+ float t = f - (float)i;
+
+ float result = ramp[i][component];
+
+ if (t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1][component];
+
+ return result;
+}
+
+shader node_rgb_curves(
+ color ramp[RAMP_TABLE_SIZE] = {0.0},
+
+ color ColorIn = 0.0,
+ float Fac = 0.0,
+ output color ColorOut = 0.0)
+{
+ ColorOut[0] = ramp_lookup(ramp, ColorIn[0], 0);
+ ColorOut[1] = ramp_lookup(ramp, ColorIn[1], 1);
+ ColorOut[2] = ramp_lookup(ramp, ColorIn[2], 2);
+
+ ColorOut = mix(ColorIn, ColorOut, Fac);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
index 0df11bb..bac4b95 100644
--- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
@@ -24,7 +24,7 @@ shader node_rgb_ramp(
float ramp_alpha[RAMP_TABLE_SIZE] = {0.0},
float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
+ output color Color = 0.0,
output float Alpha = 1.0)
{
float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
diff --git a/intern/cycles/kernel/shaders/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl
index b48bd7e..0066a1d 100644
--- a/intern/cycles/kernel/shaders/node_separate_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl
@@ -19,7 +19,7 @@
#include "stdosl.h"
shader node_separate_rgb(
- color Image = color(0.8, 0.8, 0.8),
+ color Image = 0.8,
output float R = 0.0,
output float G = 0.0,
output float B = 0.0)
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 24a63c7..13f958d 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -154,7 +154,7 @@ shader node_sky_texture(
vector Vector = P,
vector sun_direction = vector(0, 0, 1),
float turbidity = 2.2,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
vector p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 1b3ba82..2de0fc0 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -151,12 +151,23 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; }
/* Noise Bases */
+float safe_noise(point p)
+{
+ float f = noise(p);
+
+ /* can happen for big coordinates, things even out to 0.5 then anyway */
+ if(!isfinite(f))
+ return 0.5;
+
+ return f;
+}
+
float noise_basis(point p, string basis)
{
float result = 0.0;
if (basis == "Perlin")
- result = noise(p); /* returns perlin noise in range 0..1 */
+ result = safe_noise(p); /* returns perlin noise in range 0..1 */
if (basis == "Voronoi F1")
result = voronoi_F1S(p);
if (basis == "Voronoi F2")
diff --git a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
index e7efe73..c0a093b 100644
--- a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_translucent_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
BSDF = Color * translucent(Normal);
}
diff --git a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
index 875bce3..976b7d5 100644
--- a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
@@ -19,9 +19,9 @@
#include "stdosl.h"
shader node_transparent_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
BSDF = Color * transparent();
}
diff --git a/intern/cycles/kernel/shaders/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl
index bee6f39..d3672b8 100644
--- a/intern/cycles/kernel/shaders/node_value.osl
+++ b/intern/cycles/kernel/shaders/node_value.osl
@@ -21,10 +21,10 @@
shader node_value(
float value_value = 0.0,
vector vector_value = vector(0.0, 0.0, 0.0),
- color color_value = color(0.0, 0.0, 0.0),
+ color color_value = 0.0,
output float Value = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0),
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
Value = value_value;
Vector = vector_value;
diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl
new file mode 100644
index 0000000..9408228
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_vector_curves.osl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#include "stdosl.h"
+#include "oslutil.h"
+
+float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component)
+{
+ float f = clamp((at + 1.0)*0.5, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
+
+ /* clamp int as well in case of NaN */
+ int i = (int)f;
+ if (i < 0) i = 0;
+ if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1;
+ float t = f - (float)i;
+
+ float result = ramp[i][component];
+
+ if (t > 0.0)
+ result = (1.0 - t) * result + t * ramp[i + 1][component];
+
+ return result*2.0 - 1.0;
+}
+
+shader node_vector_curves(
+ color ramp[RAMP_TABLE_SIZE] = {0.0},
+
+ vector VectorIn = vector(0.0, 0.0, 0.0),
+ float Fac = 0.0,
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
+{
+ VectorOut[0] = ramp_lookup(ramp, VectorIn[0], 0);
+ VectorOut[1] = ramp_lookup(ramp, VectorIn[1], 1);
+ VectorOut[2] = ramp_lookup(ramp, VectorIn[2], 2);
+
+ VectorOut = mix(VectorIn, VectorOut, Fac);
+}
+
diff --git a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
index 3aa662b..5506ab2 100644
--- a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
@@ -20,10 +20,10 @@
#include "node_fresnel.h"
shader node_velvet_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.8,
float Sigma = 0.0,
normal Normal = N,
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
float sigma = clamp(Sigma, 0.0, 1.0);
diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
index 43f8ecc..db87878 100644
--- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
@@ -28,7 +28,7 @@ shader node_voronoi_texture(
float Scale = 5.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
index 82ce15a..bae55bc 100644
--- a/intern/cycles/kernel/shaders/node_ward_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
@@ -19,13 +19,13 @@
#include "stdosl.h"
shader node_ward_bsdf(
- color Color = color(0.8, 0.8, 0.8),
+ color Color = 0.0,
float Roughness = 0.0,
float Anisotropy = 0.0,
float Rotation = 0.0,
normal Normal = N,
normal Tangent = normalize(dPdu),
- output closure color BSDF = diffuse(Normal))
+ output closure color BSDF = 0)
{
/* rotate tangent around normal */
vector T = Tangent;
diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index 6648cd0..11c4689 100644
--- a/intern/cycles/kernel/shaders/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -55,7 +55,7 @@ shader node_wave_texture(
float DetailScale = 1.0,
point Vector = P,
output float Fac = 0.0,
- output color Color = color (0.0, 0.0, 0.0))
+ output color Color = 0.0)
{
point p = Vector;
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 24c3a50..f340eaf 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -161,7 +161,15 @@ vector cross (vector a, vector b) BUILTIN;
float dot (vector a, vector b) BUILTIN;
float length (vector v) BUILTIN;
float distance (point a, point b) BUILTIN;
-float distance (point a, point b, point q) BUILTIN;
+float distance (point a, point b, point q)
+{
+ vector d = b - a;
+ float dd = dot(d, d);
+ if(dd == 0.0)
+ return distance(q, a);
+ float t = dot(q - a, d)/dd;
+ return distance(q, a + clamp(t, 0.0, 1.0)*d);
+}
normal normalize (normal v) BUILTIN;
vector normalize (vector v) BUILTIN;
vector faceforward (vector N, vector I, vector Nref) BUILTIN;
@@ -305,7 +313,7 @@ color transformc (string to, color x)
r = color (dot (vector(0.299, 0.587, 0.114), (vector)x),
dot (vector(0.596, -0.275, -0.321), (vector)x),
dot (vector(0.212, -0.523, 0.311), (vector)x));
- else if (to == "xyz")
+ else if (to == "XYZ")
r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x),
dot (vector(0.212671, 0.715160, 0.072169), (vector)x),
dot (vector(0.019334, 0.119193, 0.950227), (vector)x));
@@ -367,7 +375,7 @@ color transformc (string from, string to, color x)
r = color (dot (vector(1, 0.9557, 0.6199), (vector)x),
dot (vector(1, -0.2716, -0.6469), (vector)x),
dot (vector(1, -1.1082, 1.7051), (vector)x));
- else if (from == "xyz")
+ else if (from == "XYZ")
r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x),
dot (vector(-0.969256, 1.875991, 0.041556), (vector)x),
dot (vector( 0.055648, -0.204043, 1.057311), (vector)x));
@@ -410,6 +418,8 @@ int startswith (string s, string prefix) BUILTIN;
int endswith (string s, string suffix) BUILTIN;
string substr (string s, int start, int len) BUILTIN;
string substr (string s, int start) { return substr (s, start, strlen(s)); }
+float strtof (string str) BUILTIN;
+int strtoi (string str) BUILTIN;
// Define concat in terms of shorter concat
string concat (string a, string b, string c) {
@@ -433,7 +443,10 @@ string concat (string a, string b, string c, string d, string e, string f) {
closure color diffuse(normal N) BUILTIN;
closure color oren_nayar(normal N, float sigma) BUILTIN;
+closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
+closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
+closure color specular_toon(normal N, float size, float smooth) BUILTIN;
closure color translucent(normal N) BUILTIN;
closure color reflection(normal N) BUILTIN;
closure color refraction(normal N, float eta) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 9c79886..1f4857c 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -301,6 +301,12 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_PARTICLE_INFO:
svm_node_particle_info(kg, sd, stack, node.y, node.z);
break;
+#ifdef __HAIR__
+ case NODE_HAIR_INFO:
+ svm_node_hair_info(kg, sd, stack, node.y, node.z);
+ break;
+#endif
+
#endif
case NODE_CONVERT:
svm_node_convert(sd, stack, node.y, node.z, node.w);
@@ -398,6 +404,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_RGB_CURVES:
svm_node_rgb_curves(kg, sd, stack, node, &offset);
break;
+ case NODE_VECTOR_CURVES:
+ svm_node_vector_curves(kg, sd, stack, node, &offset);
+ break;
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index ed70a6d..2beec99 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -28,10 +28,15 @@ __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
/* find attribute by unique id */
uint id = node.y;
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+#ifdef __HAIR__
+ attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+#endif
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id)
- attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
/* return result */
*elem = (AttributeElement)attr_map.y;
@@ -61,21 +66,21 @@ __device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uin
/* fetch and store attribute */
if(type == NODE_ATTR_FLOAT) {
if(mesh_type == NODE_ATTR_FLOAT) {
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL);
stack_store_float(stack, out_offset, f);
}
else {
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
stack_store_float(stack, out_offset, average(f));
}
}
else {
if(mesh_type == NODE_ATTR_FLOAT3) {
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
stack_store_float3(stack, out_offset, f);
}
else {
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL);
stack_store_float3(stack, out_offset, make_float3(f, f, f));
}
}
@@ -94,24 +99,24 @@ __device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *st
if(type == NODE_ATTR_FLOAT) {
if(mesh_type == NODE_ATTR_FLOAT) {
float dx;
- float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL);
stack_store_float(stack, out_offset, f+dx);
}
else {
float3 dx;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL);
stack_store_float(stack, out_offset, average(f+dx));
}
}
else {
if(mesh_type == NODE_ATTR_FLOAT3) {
float3 dx;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL);
stack_store_float3(stack, out_offset, f+dx);
}
else {
float dx;
- float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
+ float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL);
stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
}
}
@@ -130,24 +135,24 @@ __device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *st
if(type == NODE_ATTR_FLOAT) {
if(mesh_type == NODE_ATTR_FLOAT) {
float dy;
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy);
stack_store_float(stack, out_offset, f+dy);
}
else {
float3 dy;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy);
stack_store_float(stack, out_offset, average(f+dy));
}
}
else {
if(mesh_type == NODE_ATTR_FLOAT3) {
float3 dy;
- float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
+ float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy);
stack_store_float3(stack, out_offset, f+dy);
}
else {
float dy;
- float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
+ float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy);
stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
}
}
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
deleted file mode 100644
index 07927fe..0000000
--- a/intern/cycles/kernel/svm/svm_bsdf.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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.
- */
-
-#include "../closure/bsdf_ashikhmin_velvet.h"
-#include "../closure/bsdf_diffuse.h"
-#include "../closure/bsdf_oren_nayar.h"
-#include "../closure/bsdf_phong_ramp.h"
-#include "../closure/bsdf_microfacet.h"
-#include "../closure/bsdf_reflection.h"
-#include "../closure/bsdf_refraction.h"
-#include "../closure/bsdf_transparent.h"
-#ifdef __ANISOTROPIC__
-#include "../closure/bsdf_ward.h"
-#endif
-#include "../closure/bsdf_westin.h"
-
-CCL_NAMESPACE_BEGIN
-
-__device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
-{
- int label;
-
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- /*case CLOSURE_BSDF_PHONG_RAMP_ID:
- label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;*/
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
-#endif
- default:
- label = LABEL_NONE;
- break;
- }
-
- return label;
-}
-
-__device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
-{
- float3 eval;
-
- if(dot(sd->Ng, omega_in) >= 0.0f) {
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- /*case CLOSURE_BSDF_PHONG_RAMP_ID:
- eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
- break;*/
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
-#endif
- default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
- else {
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
-#endif
- default:
- eval = make_float3(0.0f, 0.0f, 0.0f);
- break;
- }
- }
-
- return eval;
-}
-
-__device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
-{
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- bsdf_diffuse_blur(sc, roughness);
- break;
-#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- bsdf_oren_nayar_blur(sc, roughness);
- break;
- /*case CLOSURE_BSDF_PHONG_RAMP_ID:
- bsdf_phong_ramp_blur(sc, roughness);
- break;*/
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- bsdf_translucent_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- bsdf_reflection_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- bsdf_refraction_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- bsdf_transparent_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- bsdf_microfacet_ggx_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- bsdf_microfacet_beckmann_blur(sc, roughness);
- break;
-#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- bsdf_ward_blur(sc, roughness);
- break;
-#endif
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- bsdf_ashikhmin_velvet_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- bsdf_westin_backscatter_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- bsdf_westin_sheen_blur(sc, roughness);
- break;
-#endif
- default:
- break;
- }
-}
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index c4d03c1..a04f4ea 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -28,23 +28,7 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack,
case NODE_GEOM_P: data = sd->P; break;
case NODE_GEOM_N: data = sd->N; break;
#ifdef __DPDU__
- case NODE_GEOM_T: {
- /* try to create spherical tangent from generated coordinates */
- int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND;
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
- data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
- object_normal_transform(kg, sd, &data);
- data = cross(sd->N, normalize(cross(data, sd->N)));;
- }
- else {
- /* otherwise use surface derivatives */
- data = normalize(sd->dPdu);
- }
-
- break;
- }
+ case NODE_GEOM_T: data = primitive_tangent(kg, sd); break;
#endif
case NODE_GEOM_I: data = sd->I; break;
case NODE_GEOM_Ng: data = sd->Ng; break;
@@ -160,5 +144,36 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
}
}
+#ifdef __HAIR__
+
+/* Hair Info */
+
+__device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
+{
+ float data;
+ float3 data3;
+
+ switch(type) {
+ case NODE_INFO_CURVE_IS_STRAND: {
+ data = (sd->segment != ~0);
+ stack_store_float(stack, out_offset, data);
+ break;
+ }
+ case NODE_INFO_CURVE_INTERCEPT:
+ break; /* handled as attribute */
+ case NODE_INFO_CURVE_THICKNESS: {
+ data = curve_thickness(kg, sd);
+ stack_store_float(stack, out_offset, data);
+ break;
+ }
+ case NODE_INFO_CURVE_TANGENT_NORMAL: {
+ data3 = curve_tangent_normal(kg, sd);
+ stack_store_float3(stack, out_offset, data3);
+ break;
+ }
+ }
+}
+#endif
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index db3b8d3..c7cd520 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -18,73 +18,6 @@
CCL_NAMESPACE_BEGIN
-__device float safe_asinf(float a)
-{
- if(a <= -1.0f)
- return -M_PI_2_F;
- else if(a >= 1.0f)
- return M_PI_2_F;
-
- return asinf(a);
-}
-
-__device float safe_acosf(float a)
-{
- if(a <= -1.0f)
- return M_PI_F;
- else if(a >= 1.0f)
- return 0.0f;
-
- return acosf(a);
-}
-
-__device float compatible_powf(float x, float y)
-{
- /* GPU pow doesn't accept negative x, do manual checks here */
- if(x < 0.0f) {
- if(fmod(-y, 2.0f) == 0.0f)
- return powf(-x, y);
- else
- return -powf(-x, y);
- }
- else if(x == 0.0f)
- return 0.0f;
-
- return powf(x, y);
-}
-
-__device float safe_powf(float a, float b)
-{
- if(b == 0.0f)
- return 1.0f;
- if(a == 0.0f)
- return 0.0f;
- if(a < 0.0f && b != (int)b)
- return 0.0f;
-
- return compatible_powf(a, b);
-}
-
-__device float safe_logf(float a, float b)
-{
- if(a < 0.0f || b < 0.0f)
- return 0.0f;
-
- return logf(a)/logf(b);
-}
-
-__device float safe_divide(float a, float b)
-{
- float result;
-
- if(b == 0.0f)
- result = 0.0f;
- else
- result = a/b;
-
- return result;
-}
-
__device float svm_math(NodeMath type, float Fac1, float Fac2)
{
float Fac;
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 224a1d9..5ead648 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -84,9 +84,8 @@ __device uint phash(int kx, int ky, int kz, int3 p)
__device float floorfrac(float x, int* i)
{
- float f = floorf(x);
- *i = (int)f;
- return x - f;
+ *i = quick_floor(x);
+ return x - *i;
}
__device float fade(float t)
@@ -133,7 +132,10 @@ __device_noinline float perlin(float x, float y, float z)
grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )),
nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ),
grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f ))));
- return scale3(result);
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r))? r: 0.0f;
}
__device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod)
@@ -162,7 +164,10 @@ __device_noinline float perlin_periodic(float x, float y, float z, float3 pperio
grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )),
nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ),
grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f ))));
- return scale3(result);
+ float r = scale3(result);
+
+ /* can happen for big coordinates, things even out to 0.0 then anyway */
+ return (isfinite(r))? r: 0.0f;
}
/* perlin noise in range 0..1 */
diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h
index c64413c..054137f 100644
--- a/intern/cycles/kernel/svm/svm_ramp.h
+++ b/intern/cycles/kernel/svm/svm_ramp.h
@@ -63,9 +63,9 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac
float fac = stack_load_float(stack, fac_offset);
float3 color = stack_load_float3(stack, color_offset);
- float r = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.x).w).x;
- float g = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.y).w).y;
- float b = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.z).w).z;
+ float r = rgb_ramp_lookup(kg, *offset, color.x).x;
+ float g = rgb_ramp_lookup(kg, *offset, color.y).y;
+ float b = rgb_ramp_lookup(kg, *offset, color.z).z;
color = (1.0f - fac)*color + fac*make_float3(r, g, b);
stack_store_float3(stack, out_offset, color);
@@ -73,6 +73,25 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac
*offset += RAMP_TABLE_SIZE;
}
+__device void svm_node_vector_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+{
+ uint fac_offset = node.y;
+ uint color_offset = node.z;
+ uint out_offset = node.w;
+
+ float fac = stack_load_float(stack, fac_offset);
+ float3 color = stack_load_float3(stack, color_offset);
+
+ float r = rgb_ramp_lookup(kg, *offset, (color.x + 1.0f)*0.5f).x;
+ float g = rgb_ramp_lookup(kg, *offset, (color.y + 1.0f)*0.5f).y;
+ float b = rgb_ramp_lookup(kg, *offset, (color.z + 1.0f)*0.5f).z;
+
+ color = (1.0f - fac)*color + fac*make_float3(r*2.0f - 1.0f, g*2.0f - 1.0f, b*2.0f - 1.0f);
+ stack_store_float3(stack, out_offset, color);
+
+ *offset += RAMP_TABLE_SIZE;
+}
+
CCL_NAMESPACE_END
#endif /* __SVM_RAMP_H__ */
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 9f2d336..7a1af43 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -248,8 +248,9 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
}
/* first try to get tangent attribute */
- int attr_offset = find_attribute(kg, sd, node.z);
- int attr_sign_offset = find_attribute(kg, sd, node.w);
+ AttributeElement attr_elem, attr_sign_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
+ int attr_sign_offset = find_attribute(kg, sd, node.w, &attr_sign_elem);
if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND) {
stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
@@ -257,8 +258,8 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
}
/* ensure orthogonal and normalized (interpolation breaks it) */
- float3 tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
- float sign = triangle_attribute_float(kg, sd, ATTR_ELEMENT_CORNER, attr_sign_offset, NULL, NULL);
+ float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
+ float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, NULL, NULL);
object_normal_transform(kg, sd, &tangent);
tangent = cross(sd->N, normalize(cross(tangent, sd->N)));;
@@ -295,22 +296,24 @@ __device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack,
if(direction_type == NODE_TANGENT_UVMAP) {
/* UV map */
- int attr_offset = find_attribute(kg, sd, node.z);
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
if(attr_offset == ATTR_STD_NOT_FOUND)
tangent = make_float3(0.0f, 0.0f, 0.0f);
else
- tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
}
else {
/* radial */
- int attr_offset = find_attribute(kg, sd, node.z);
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
float3 generated;
if(attr_offset == ATTR_STD_NOT_FOUND)
generated = sd->P;
else
- generated = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+ generated = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
if(axis == NODE_TANGENT_AXIS_X)
tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index b41e34a..57177ee 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -88,6 +88,7 @@ typedef enum NodeType {
NODE_BRIGHTCONTRAST,
NODE_RGB_RAMP,
NODE_RGB_CURVES,
+ NODE_VECTOR_CURVES,
NODE_MIN_MAX,
NODE_LIGHT_FALLOFF,
NODE_OBJECT_INFO,
@@ -96,7 +97,8 @@ typedef enum NodeType {
NODE_CLOSURE_SET_NORMAL,
NODE_CLOSURE_AMBIENT_OCCLUSION,
NODE_TANGENT,
- NODE_NORMAL_MAP
+ NODE_NORMAL_MAP,
+ NODE_HAIR_INFO
} NodeType;
typedef enum NodeAttributeType {
@@ -131,6 +133,13 @@ typedef enum NodeParticleInfo {
NODE_INFO_PAR_ANGULAR_VELOCITY
} NodeParticleInfo;
+typedef enum NodeHairInfo {
+ NODE_INFO_CURVE_IS_STRAND,
+ NODE_INFO_CURVE_INTERCEPT,
+ NODE_INFO_CURVE_THICKNESS,
+ NODE_INFO_CURVE_TANGENT_NORMAL
+} NodeHairInfo;
+
typedef enum NodeLightPath {
NODE_LP_camera = 0,
NODE_LP_shadow,
@@ -312,6 +321,8 @@ typedef enum ClosureType {
CLOSURE_BSDF_DIFFUSE_ID,
CLOSURE_BSDF_OREN_NAYAR_ID,
+ CLOSURE_BSDF_DIFFUSE_RAMP_ID,
+ CLOSURE_BSDF_DIFFUSE_TOON_ID,
CLOSURE_BSDF_GLOSSY_ID,
CLOSURE_BSDF_REFLECTION_ID,
@@ -321,6 +332,7 @@ typedef enum ClosureType {
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
CLOSURE_BSDF_WESTIN_SHEEN_ID,
CLOSURE_BSDF_PHONG_RAMP_ID,
+ CLOSURE_BSDF_SPECULAR_TOON_ID,
CLOSURE_BSDF_TRANSMISSION_ID,
CLOSURE_BSDF_TRANSLUCENT_ID,
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index 7907061..d67a686 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -31,6 +31,7 @@ set(SRC
object.cpp
osl.cpp
particles.cpp
+ curves.cpp
scene.cpp
session.cpp
shader.cpp
@@ -56,6 +57,7 @@ set(SRC_HEADERS
object.h
osl.h
particles.h
+ curves.h
scene.h
session.h
shader.h
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 95941c1..b6f6ba4 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -26,7 +26,7 @@ CCL_NAMESPACE_BEGIN
/* Attribute */
-void Attribute::set(ustring name_, TypeDesc type_, Element element_)
+void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
{
name = name_;
type = type_;
@@ -39,12 +39,30 @@ void Attribute::set(ustring name_, TypeDesc type_, Element element_)
type == TypeDesc::TypeNormal);
}
-void Attribute::reserve(int numverts, int numtris)
+void Attribute::reserve(int numverts, int numtris, int numcurves, int numkeys)
{
- buffer.resize(buffer_size(numverts, numtris), 0);
+ buffer.resize(buffer_size(numverts, numtris, numcurves, numkeys), 0);
}
-size_t Attribute::data_sizeof()
+void Attribute::add(const float& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+void Attribute::add(const float3& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
+size_t Attribute::data_sizeof() const
{
if(type == TypeDesc::TypeFloat)
return sizeof(float);
@@ -52,19 +70,27 @@ size_t Attribute::data_sizeof()
return sizeof(float3);
}
-size_t Attribute::element_size(int numverts, int numtris)
+size_t Attribute::element_size(int numverts, int numtris, int numcurves, int numkeys) const
{
- if(element == VERTEX)
+ if(element == ATTR_ELEMENT_VALUE)
+ return 1;
+ if(element == ATTR_ELEMENT_VERTEX)
return numverts;
- else if(element == FACE)
+ else if(element == ATTR_ELEMENT_FACE)
return numtris;
- else
+ else if(element == ATTR_ELEMENT_CORNER)
return numtris*3;
+ else if(element == ATTR_ELEMENT_CURVE)
+ return numcurves;
+ else if(element == ATTR_ELEMENT_CURVE_KEY)
+ return numkeys;
+
+ return 0;
}
-size_t Attribute::buffer_size(int numverts, int numtris)
+size_t Attribute::buffer_size(int numverts, int numtris, int numcurves, int numkeys) const
{
- return element_size(numverts, numtris)*data_sizeof();
+ return element_size(numverts, numtris, numcurves, numkeys)*data_sizeof();
}
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
@@ -84,18 +110,51 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
return false;
}
+const char *Attribute::standard_name(AttributeStandard std)
+{
+ if(std == ATTR_STD_VERTEX_NORMAL)
+ return "N";
+ else if(std == ATTR_STD_FACE_NORMAL)
+ return "Ng";
+ else if(std == ATTR_STD_UV)
+ return "uv";
+ else if(std == ATTR_STD_GENERATED)
+ return "generated";
+ else if(std == ATTR_STD_UV_TANGENT)
+ return "tangent";
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ return "tangent_sign";
+ else if(std == ATTR_STD_POSITION_UNDEFORMED)
+ return "undeformed";
+ else if(std == ATTR_STD_POSITION_UNDISPLACED)
+ return "undisplaced";
+ else if(std == ATTR_STD_MOTION_PRE)
+ return "motion_pre";
+ else if(std == ATTR_STD_MOTION_POST)
+ return "motion_post";
+ else if(std == ATTR_STD_PARTICLE)
+ return "particle";
+ else if(std == ATTR_STD_CURVE_TANGENT)
+ return "curve_tangent";
+ else if(std == ATTR_STD_CURVE_INTERCEPT)
+ return "curve_intercept";
+
+ return "";
+}
+
/* Attribute Set */
AttributeSet::AttributeSet()
{
- mesh = NULL;
+ triangle_mesh = NULL;
+ curve_mesh = NULL;
}
AttributeSet::~AttributeSet()
{
}
-Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element element)
+Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement element)
{
Attribute *attr = find(name);
@@ -111,24 +170,22 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element ele
attributes.push_back(Attribute());
attr = &attributes.back();
- if(element == Attribute::VERTEX)
- attr->set(name, type, element);
- else if(element == Attribute::FACE)
- attr->set(name, type, element);
- else if(element == Attribute::CORNER)
- attr->set(name, type, element);
+ attr->set(name, type, element);
- if(mesh)
- attr->reserve(mesh->verts.size(), mesh->triangles.size());
+ /* this is weak .. */
+ if(triangle_mesh)
+ attr->reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ if(curve_mesh)
+ attr->reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
return attr;
}
-Attribute *AttributeSet::find(ustring name)
+Attribute *AttributeSet::find(ustring name) const
{
- foreach(Attribute& attr, attributes)
+ foreach(const Attribute& attr, attributes)
if(attr.name == name)
- return &attr;
+ return (Attribute*)&attr;
return NULL;
}
@@ -154,41 +211,59 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
Attribute *attr = NULL;
if(name == ustring())
- name = attribute_standard_name(std);
-
- if(std == ATTR_STD_VERTEX_NORMAL)
- attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX);
- else if(std == ATTR_STD_FACE_NORMAL)
- attr = add(name, TypeDesc::TypeNormal, Attribute::FACE);
- else if(std == ATTR_STD_UV)
- attr = add(name, TypeDesc::TypePoint, Attribute::CORNER);
- else if(std == ATTR_STD_UV_TANGENT)
- attr = add(name, TypeDesc::TypeVector, Attribute::CORNER);
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- attr = add(name, TypeDesc::TypeFloat, Attribute::CORNER);
- else if(std == ATTR_STD_GENERATED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_MOTION_PRE)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else if(std == ATTR_STD_MOTION_POST)
- attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
- else
- assert(0);
+ name = Attribute::standard_name(std);
+
+ if(triangle_mesh) {
+ if(std == ATTR_STD_VERTEX_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_FACE_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
+ else if(std == ATTR_STD_UV)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_UV_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
+ else if(std == ATTR_STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_POSITION_UNDEFORMED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_POSITION_UNDISPLACED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_MOTION_PRE)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else if(std == ATTR_STD_MOTION_POST)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
+ else
+ assert(0);
+ }
+ else if(curve_mesh) {
+ if(std == ATTR_STD_UV)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
+ else if(std == ATTR_STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
+ else if(std == ATTR_STD_MOTION_PRE)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_MOTION_POST)
+ attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_CURVE_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CURVE_KEY);
+ else if(std == ATTR_STD_CURVE_INTERCEPT)
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
+ else
+ assert(0);
+ }
attr->std = std;
return attr;
}
-Attribute *AttributeSet::find(AttributeStandard std)
+Attribute *AttributeSet::find(AttributeStandard std) const
{
- foreach(Attribute& attr, attributes)
+ foreach(const Attribute& attr, attributes)
if(attr.std == std)
- return &attr;
+ return (Attribute*)&attr;
return NULL;
}
@@ -217,10 +292,14 @@ Attribute *AttributeSet::find(AttributeRequest& req)
return find(req.std);
}
-void AttributeSet::reserve(int numverts, int numtris)
+void AttributeSet::reserve()
{
- foreach(Attribute& attr, attributes)
- attr.reserve(numverts, numtris);
+ foreach(Attribute& attr, attributes) {
+ if(triangle_mesh)
+ attr.reserve(triangle_mesh->verts.size(), triangle_mesh->triangles.size(), 0, 0);
+ if(curve_mesh)
+ attr.reserve(0, 0, curve_mesh->curves.size(), curve_mesh->curve_keys.size());
+ }
}
void AttributeSet::clear()
@@ -235,9 +314,13 @@ AttributeRequest::AttributeRequest(ustring name_)
name = name_;
std = ATTR_STD_NONE;
- type = TypeDesc::TypeFloat;
- element = ATTR_ELEMENT_NONE;
- offset = 0;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_element = ATTR_ELEMENT_NONE;
+ triangle_offset = 0;
+
+ curve_type = TypeDesc::TypeFloat;
+ curve_element = ATTR_ELEMENT_NONE;
+ curve_offset = 0;
}
AttributeRequest::AttributeRequest(AttributeStandard std_)
@@ -245,9 +328,13 @@ AttributeRequest::AttributeRequest(AttributeStandard std_)
name = ustring();
std = std_;
- type = TypeDesc::TypeFloat;
- element = ATTR_ELEMENT_NONE;
- offset = 0;
+ triangle_type = TypeDesc::TypeFloat;
+ triangle_element = ATTR_ELEMENT_NONE;
+ triangle_offset = 0;
+
+ curve_type = TypeDesc::TypeFloat;
+ curve_element = ATTR_ELEMENT_NONE;
+ curve_offset = 0;
}
/* AttributeRequestSet */
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index d05952e..6c0c06d 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -21,7 +21,6 @@
#include "kernel_types.h"
-#include "util_attribute.h"
#include "util_list.h"
#include "util_param.h"
#include "util_types.h"
@@ -42,36 +41,34 @@ class Mesh;
class Attribute {
public:
- enum Element {
- VERTEX,
- FACE,
- CORNER
- };
-
ustring name;
AttributeStandard std;
TypeDesc type;
vector<char> buffer;
- Element element;
+ AttributeElement element;
Attribute() {}
- void set(ustring name, TypeDesc type, Element element);
- void reserve(int numverts, int numfaces);
+ void set(ustring name, TypeDesc type, AttributeElement element);
+ void reserve(int numverts, int numfaces, int numcurves, int numkeys);
- size_t data_sizeof();
- size_t element_size(int numverts, int numfaces);
- size_t buffer_size(int numverts, int numfaces);
+ size_t data_sizeof() const;
+ size_t element_size(int numverts, int numfaces, int numcurves, int numkeys) const;
+ size_t buffer_size(int numverts, int numfaces, int numcurves, int numkeys) const;
char *data() { return (buffer.size())? &buffer[0]: NULL; };
float3 *data_float3() { return (float3*)data(); }
float *data_float() { return (float*)data(); }
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
- const float3 *data_float3() const { return (float3*)data(); }
- const float *data_float() const { return (float*)data(); }
+ const float3 *data_float3() const { return (const float3*)data(); }
+ const float *data_float() const { return (const float*)data(); }
+
+ void add(const float& f);
+ void add(const float3& f);
static bool same_storage(TypeDesc a, TypeDesc b);
+ static const char *standard_name(AttributeStandard std);
};
/* Attribute Set
@@ -80,23 +77,24 @@ public:
class AttributeSet {
public:
- Mesh *mesh;
+ Mesh *triangle_mesh;
+ Mesh *curve_mesh;
list<Attribute> attributes;
AttributeSet();
~AttributeSet();
- Attribute *add(ustring name, TypeDesc type, Attribute::Element element);
- Attribute *find(ustring name);
+ Attribute *add(ustring name, TypeDesc type, AttributeElement element);
+ Attribute *find(ustring name) const;
void remove(ustring name);
Attribute *add(AttributeStandard std, ustring name = ustring());
- Attribute *find(AttributeStandard std);
+ Attribute *find(AttributeStandard std) const;
void remove(AttributeStandard std);
Attribute *find(AttributeRequest& req);
- void reserve(int numverts, int numfaces);
+ void reserve();
void clear();
};
@@ -104,7 +102,7 @@ public:
*
* Request from a shader to use a certain attribute, so we can figure out
* which ones we need to export from the host app end store for the kernel.
- * The attribute is found either by name or by standard. */
+ * The attribute is found either by name or by standard attribute type. */
class AttributeRequest {
public:
@@ -112,9 +110,9 @@ public:
AttributeStandard std;
/* temporary variables used by MeshManager */
- TypeDesc type;
- AttributeElement element;
- int offset;
+ TypeDesc triangle_type, curve_type;
+ AttributeElement triangle_element, curve_element;
+ int triangle_offset, curve_offset;
AttributeRequest(ustring name_);
AttributeRequest(AttributeStandard std);
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp
new file mode 100644
index 0000000..3299503
--- /dev/null
+++ b/intern/cycles/render/curves.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#include "device.h"
+#include "curves.h"
+#include "mesh.h"
+#include "object.h"
+#include "scene.h"
+
+#include "util_foreach.h"
+#include "util_map.h"
+#include "util_progress.h"
+#include "util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Hair System Manager */
+
+CurveSystemManager::CurveSystemManager()
+{
+ primitive = CURVE_LINE_SEGMENTS;
+ line_method = CURVE_CORRECTED;
+ interpolation = CURVE_CARDINAL;
+ triangle_method = CURVE_CAMERA;
+ resolution = 3;
+ segments = 1;
+
+ normalmix = 1.0f;
+ encasing_ratio = 1.01f;
+
+ use_curves = true;
+ use_smooth = true;
+ use_cache = true;
+ use_parents = false;
+ use_encasing = true;
+ use_backfacing = false;
+ use_joined = false;
+ use_tangent_normal = false;
+ use_tangent_normal_geometry = false;
+ use_tangent_normal_correction = false;
+
+ need_update = true;
+ need_mesh_update = false;
+}
+
+CurveSystemManager::~CurveSystemManager()
+{
+}
+
+void CurveSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ if(!need_update)
+ return;
+
+ device_free(device, dscene);
+
+ progress.set_status("Updating Hair settings", "Copying Hair settings to device");
+
+ KernelCurves *kcurve= &dscene->data.curve_kernel_data;
+
+ kcurve->curveflags = 0;
+
+ if(primitive == CURVE_SEGMENTS)
+ kcurve->curveflags |= CURVE_KN_INTERPOLATE;
+
+ if(line_method == CURVE_ACCURATE)
+ kcurve->curveflags |= CURVE_KN_ACCURATE;
+ if(line_method == CURVE_CORRECTED)
+ kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION;
+ if(line_method == CURVE_POSTCORRECTED)
+ kcurve->curveflags |= CURVE_KN_POSTINTERSECTCORRECTION;
+
+ if(use_tangent_normal)
+ kcurve->curveflags |= CURVE_KN_TANGENTGNORMAL;
+ if(use_tangent_normal_correction)
+ kcurve->curveflags |= CURVE_KN_NORMALCORRECTION;
+ if(use_tangent_normal_geometry)
+ kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL;
+ if(use_joined)
+ kcurve->curveflags |= CURVE_KN_CURVEDATA;
+ if(use_backfacing)
+ kcurve->curveflags |= CURVE_KN_BACKFACING;
+ if(use_encasing)
+ kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER;
+
+ kcurve->normalmix = normalmix;
+ kcurve->encasing_ratio = encasing_ratio;
+
+ if(progress.get_cancel()) return;
+
+ need_update = false;
+}
+
+void CurveSystemManager::device_free(Device *device, DeviceScene *dscene)
+{
+
+}
+
+bool CurveSystemManager::modified(const CurveSystemManager& CurveSystemManager)
+{
+ return !(line_method == CurveSystemManager.line_method &&
+ interpolation == CurveSystemManager.interpolation &&
+ primitive == CurveSystemManager.primitive &&
+ use_encasing == CurveSystemManager.use_encasing &&
+ use_tangent_normal == CurveSystemManager.use_tangent_normal &&
+ use_tangent_normal_correction == CurveSystemManager.use_tangent_normal_correction &&
+ use_tangent_normal_geometry == CurveSystemManager.use_tangent_normal_geometry &&
+ encasing_ratio == CurveSystemManager.encasing_ratio &&
+ use_backfacing == CurveSystemManager.use_backfacing &&
+ normalmix == CurveSystemManager.normalmix &&
+ use_cache == CurveSystemManager.use_cache &&
+ use_smooth == CurveSystemManager.use_smooth &&
+ triangle_method == CurveSystemManager.triangle_method &&
+ resolution == CurveSystemManager.resolution &&
+ use_curves == CurveSystemManager.use_curves &&
+ use_joined == CurveSystemManager.use_joined &&
+ segments == CurveSystemManager.segments &&
+ use_parents == CurveSystemManager.use_parents);
+}
+
+bool CurveSystemManager::modified_mesh(const CurveSystemManager& CurveSystemManager)
+{
+ return !(primitive == CurveSystemManager.primitive &&
+ interpolation == CurveSystemManager.interpolation &&
+ use_parents == CurveSystemManager.use_parents &&
+ use_smooth == CurveSystemManager.use_smooth &&
+ triangle_method == CurveSystemManager.triangle_method &&
+ resolution == CurveSystemManager.resolution &&
+ use_curves == CurveSystemManager.use_curves &&
+ use_joined == CurveSystemManager.use_joined &&
+ segments == CurveSystemManager.segments &&
+ use_cache == CurveSystemManager.use_cache);
+}
+
+void CurveSystemManager::tag_update(Scene *scene)
+{
+ need_update = true;
+}
+
+void CurveSystemManager::tag_update_mesh()
+{
+ need_mesh_update = true;
+}
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h
new file mode 100644
index 0000000..bb9ef6d
--- /dev/null
+++ b/intern/cycles/render/curves.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __CURVES_H__
+#define __CURVES_H__
+
+#include "util_types.h"
+#include "util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+class Device;
+class DeviceScene;
+class Progress;
+class Scene;
+
+typedef enum curve_presets {
+ CURVE_CUSTOM,
+ CURVE_TANGENT_SHADING,
+ CURVE_TRUE_NORMAL,
+ CURVE_ACCURATE_PRESET
+} curve_presets;
+
+typedef enum curve_primitives {
+ CURVE_TRIANGLES,
+ CURVE_LINE_SEGMENTS,
+ CURVE_SEGMENTS
+} curve_primitives;
+
+typedef enum curve_triangles {
+ CURVE_CAMERA,
+ CURVE_RIBBONS,
+ CURVE_TESSELATED
+} curve_triangles;
+
+typedef enum curve_lines {
+ CURVE_ACCURATE,
+ CURVE_CORRECTED,
+ CURVE_POSTCORRECTED,
+ CURVE_UNCORRECTED
+} curve_lines;
+
+typedef enum curve_interpolation {
+ CURVE_LINEAR,
+ CURVE_CARDINAL,
+ CURVE_BSPLINE
+} curve_interpolation;
+
+class ParticleCurveData {
+
+public:
+
+ ParticleCurveData();
+ ~ParticleCurveData();
+
+ vector<int> psys_firstcurve;
+ vector<int> psys_curvenum;
+ vector<int> psys_shader;
+
+ vector<float> psys_rootradius;
+ vector<float> psys_tipradius;
+ vector<float> psys_shape;
+ vector<bool> psys_closetip;
+
+ vector<int> curve_firstkey;
+ vector<int> curve_keynum;
+ vector<float> curve_length;
+ vector<float3> curve_uv;
+ vector<float3> curve_vcol;
+
+ vector<float3> curvekey_co;
+ vector<float> curvekey_time;
+};
+
+/* HairSystem Manager */
+
+class CurveSystemManager {
+public:
+
+ int primitive;
+ int line_method;
+ int interpolation;
+ int triangle_method;
+ int resolution;
+ int segments;
+
+ float normalmix;
+ float encasing_ratio;
+
+ bool use_curves;
+ bool use_smooth;
+ bool use_cache;
+ bool use_parents;
+ bool use_encasing;
+ bool use_backfacing;
+ bool use_tangent_normal;
+ bool use_tangent_normal_correction;
+ bool use_tangent_normal_geometry;
+ bool use_joined;
+
+ bool need_update;
+ bool need_mesh_update;
+
+ CurveSystemManager();
+ ~CurveSystemManager();
+
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_free(Device *device, DeviceScene *dscene);
+ bool modified(const CurveSystemManager& CurveSystemManager);
+ bool modified_mesh(const CurveSystemManager& CurveSystemManager);
+
+ void tag_update(Scene *scene);
+ void tag_update_mesh();
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __CURVES_H__ */
+
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 230a12f..e6f8ab4 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -85,11 +85,21 @@ bool ImageManager::set_animation_frame_update(int frame)
return false;
}
-bool ImageManager::is_float_image(const string& filename)
+bool ImageManager::is_float_image(const string& filename, bool is_builtin)
{
- ImageInput *in = ImageInput::create(filename);
bool is_float = false;
+ if(is_builtin) {
+ if(builtin_image_info_cb) {
+ int width, height, channels;
+ builtin_image_info_cb(filename, is_float, width, height, channels);
+ }
+
+ return is_float;
+ }
+
+ ImageInput *in = ImageInput::create(filename);
+
if(in) {
ImageSpec spec;
@@ -113,13 +123,13 @@ bool ImageManager::is_float_image(const string& filename)
return is_float;
}
-int ImageManager::add_image(const string& filename, bool animated, bool& is_float)
+int ImageManager::add_image(const string& filename, bool is_builtin, bool animated, bool& is_float)
{
Image *img;
size_t slot;
/* load image info and find out if we need a float texture */
- is_float = (pack_images)? false: is_float_image(filename);
+ is_float = (pack_images)? false: is_float_image(filename, is_builtin);
if(is_float) {
/* find existing image */
@@ -150,6 +160,7 @@ int ImageManager::add_image(const string& filename, bool animated, bool& is_floa
/* add new image */
img = new Image();
img->filename = filename;
+ img->is_builtin = is_builtin;
img->need_load = true;
img->animated = animated;
img->users = 1;
@@ -184,6 +195,7 @@ int ImageManager::add_image(const string& filename, bool animated, bool& is_floa
/* add new image */
img = new Image();
img->filename = filename;
+ img->is_builtin = is_builtin;
img->need_load = true;
img->animated = animated;
img->users = 1;
@@ -197,12 +209,12 @@ int ImageManager::add_image(const string& filename, bool animated, bool& is_floa
return slot;
}
-void ImageManager::remove_image(const string& filename)
+void ImageManager::remove_image(const string& filename, bool is_builtin)
{
size_t slot;
for(slot = 0; slot < images.size(); slot++) {
- if(images[slot] && images[slot]->filename == filename) {
+ if(images[slot] && images[slot]->filename == filename && images[slot]->is_builtin == is_builtin) {
/* decrement user count */
images[slot]->users--;
assert(images[slot]->users >= 0);
@@ -220,7 +232,7 @@ void ImageManager::remove_image(const string& filename)
if(slot == images.size()) {
/* see if it's in a float texture slot */
for(slot = 0; slot < float_images.size(); slot++) {
- if(float_images[slot] && float_images[slot]->filename == filename) {
+ if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->is_builtin == is_builtin) {
/* decrement user count */
float_images[slot]->users--;
assert(float_images[slot]->users >= 0);
@@ -242,27 +254,43 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
if(img->filename == "")
return false;
- /* load image from file through OIIO */
- ImageInput *in = ImageInput::create(img->filename);
+ ImageInput *in = NULL;
+ int width, height, components;
- if(!in)
- return false;
+ if(!img->is_builtin) {
+ /* load image from file through OIIO */
+ in = ImageInput::create(img->filename);
- ImageSpec spec;
+ if(!in)
+ return false;
- if(!in->open(img->filename, spec)) {
- delete in;
- return false;
+ ImageSpec spec;
+
+ if(!in->open(img->filename, spec)) {
+ delete in;
+ return false;
+ }
+
+ width = spec.width;
+ height = spec.height;
+ components = spec.nchannels;
+ }
+ else {
+ /* load image using builtin images callbacks */
+ if(!builtin_image_info_cb || !builtin_image_pixels_cb)
+ return false;
+
+ bool is_float;
+ builtin_image_info_cb(img->filename, is_float, width, height, components);
}
/* we only handle certain number of components */
- int width = spec.width;
- int height = spec.height;
- int components = spec.nchannels;
-
if(!(components == 1 || components == 3 || components == 4)) {
- in->close();
- delete in;
+ if(in) {
+ in->close();
+ delete in;
+ }
+
return false;
}
@@ -270,14 +298,19 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
uchar *pixels = (uchar*)tex_img.resize(width, height);
int scanlinesize = width*components*sizeof(uchar);
- in->read_image(TypeDesc::UINT8,
- (uchar*)pixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
+ if(in) {
+ in->read_image(TypeDesc::UINT8,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
- in->close();
- delete in;
+ in->close();
+ delete in;
+ }
+ else {
+ builtin_image_pixels_cb(img->filename, pixels);
+ }
if(components == 3) {
for(int i = width*height-1; i >= 0; i--) {
@@ -304,27 +337,42 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
if(img->filename == "")
return false;
- /* load image from file through OIIO */
- ImageInput *in = ImageInput::create(img->filename);
+ ImageInput *in = NULL;
+ int width, height, components;
- if(!in)
- return false;
+ if(!img->is_builtin) {
+ /* load image from file through OIIO */
+ in = ImageInput::create(img->filename);
- ImageSpec spec;
+ if(!in)
+ return false;
- if(!in->open(img->filename, spec)) {
- delete in;
- return false;
+ ImageSpec spec;
+
+ if(!in->open(img->filename, spec)) {
+ delete in;
+ return false;
+ }
+
+ /* we only handle certain number of components */
+ width = spec.width;
+ height = spec.height;
+ components = spec.nchannels;
}
+ else {
+ /* load image using builtin images callbacks */
+ if(!builtin_image_info_cb || !builtin_image_float_pixels_cb)
+ return false;
- /* we only handle certain number of components */
- int width = spec.width;
- int height = spec.height;
- int components = spec.nchannels;
+ bool is_float;
+ builtin_image_info_cb(img->filename, is_float, width, height, components);
+ }
if(!(components == 1 || components == 3 || components == 4)) {
- in->close();
- delete in;
+ if(in) {
+ in->close();
+ delete in;
+ }
return false;
}
@@ -332,14 +380,19 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
float *pixels = (float*)tex_img.resize(width, height);
int scanlinesize = width*components*sizeof(float);
- in->read_image(TypeDesc::FLOAT,
- (uchar*)pixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
+ if(in) {
+ in->read_image(TypeDesc::FLOAT,
+ (uchar*)pixels + (height-1)*scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
- in->close();
- delete in;
+ in->close();
+ delete in;
+ }
+ else {
+ builtin_image_float_pixels_cb(img->filename, pixels);
+ }
if(components == 3) {
for(int i = width*height-1; i >= 0; i--) {
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 4d17717..e39ac14 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -51,9 +51,9 @@ public:
ImageManager();
~ImageManager();
- int add_image(const string& filename, bool animated, bool& is_float);
- void remove_image(const string& filename);
- bool is_float_image(const string& filename);
+ int add_image(const string& filename, bool is_builtin, bool animated, bool& is_float);
+ void remove_image(const string& filename, bool is_builtin);
+ bool is_float_image(const string& filename, bool is_builtin);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
@@ -65,6 +65,9 @@ public:
bool need_update;
+ boost::function<void(const string &filename, bool &is_float, int &width, int &height, int &channels)> builtin_image_info_cb;
+ boost::function<bool(const string &filename, unsigned char *pixels)> builtin_image_pixels_cb;
+ boost::function<bool(const string &filename, float *pixels)> builtin_image_float_pixels_cb;
private:
int tex_num_images;
int tex_num_float_images;
@@ -74,6 +77,7 @@ private:
struct Image {
string filename;
+ bool is_builtin;
bool need_load;
bool animated;
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 4173da4..1b94d60 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -142,6 +142,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* count */
size_t num_lights = scene->lights.size();
size_t num_triangles = 0;
+ size_t num_curve_segments = 0;
foreach(Object *object, scene->objects) {
Mesh *mesh = object->mesh;
@@ -169,10 +170,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(shader->sample_as_light && shader->has_surface_emission)
num_triangles++;
}
+
+ /* disabled for curves */
+#if 0
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ Shader *shader = scene->shaders[curve.shader];
+
+ if(shader->sample_as_light && shader->has_surface_emission)
+ num_curve_segments += curve.num_segments();
+#endif
}
}
- size_t num_distribution = num_triangles;
+ size_t num_distribution = num_triangles + num_curve_segments;
num_distribution += num_lights;
/* emission area */
@@ -216,7 +226,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(shader->sample_as_light && shader->has_surface_emission) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
- distribution[offset].z = 1.0f;
+ distribution[offset].z = __int_as_float(~0);
distribution[offset].w = __int_as_float(object_id);
offset++;
@@ -234,6 +244,40 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
totarea += triangle_area(p1, p2, p3);
}
}
+
+ /*sample as light disabled for strands*/
+#if 0
+ size_t i = 0;
+
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ Shader *shader = scene->shaders[curve.shader];
+ int first_key = curve.first_key;
+
+ if(shader->sample_as_light && shader->has_surface_emission) {
+ for(int j = 0; j < curve.num_segments(); j++) {
+ distribution[offset].x = totarea;
+ distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
+ distribution[offset].z = __int_as_float(j);
+ distribution[offset].w = __int_as_float(object_id);
+ offset++;
+
+ float3 p1 = mesh->curve_keys[first_key + j].loc;
+ float r1 = mesh->curve_keys[first_key + j].radius;
+ float3 p2 = mesh->curve_keys[first_key + j + 1].loc;
+ float r2 = mesh->curve_keys[first_key + j + 1].radius;
+
+ if(!transform_applied) {
+ p1 = transform_point(&tfm, p1);
+ p2 = transform_point(&tfm, p2);
+ }
+
+ totarea += M_PI_F * (r1 + r2) * len(p1 - p2);
+ }
+ }
+
+ i++;
+ }
+#endif
}
if(progress.get_cancel()) return;
@@ -279,6 +323,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* precompute pdfs */
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
+ kintegrator->inv_pdf_lights = 0.0f;
/* sample one, with 0.5 probability of light or triangle */
kintegrator->num_all_lights = num_lights;
@@ -293,6 +338,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_lights = 1.0f/num_lights;
if(trianglearea > 0.0f)
kintegrator->pdf_lights *= 0.5f;
+
+ kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights;
}
/* CDF */
@@ -305,6 +352,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->num_all_lights = 0;
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
+ kintegrator->inv_pdf_lights = 0.0f;
}
}
@@ -431,16 +479,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
if(light->type == LIGHT_POINT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float angle = atanf(radius);
+ float cosangle = cosf(angle);
+ float area = M_PI_F*radius*radius;
+ float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
@@ -455,21 +512,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size);
+ float area = len(axisu)*len(axisv);
+ float invarea = (area > 0.0f)? 1.0f/area: 0.0f;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
- light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
}
else if(light->type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
+ float radius = light->size;
+ float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
float spot_angle = cosf(light->spot_angle*0.5f);
float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
- light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
- light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
+ light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle);
+ light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index bc782a7..d4619dc 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -51,7 +51,11 @@ Mesh::Mesh()
tri_offset = 0;
vert_offset = 0;
- attributes.mesh = this;
+ curve_offset = 0;
+ curvekey_offset = 0;
+
+ attributes.triangle_mesh = this;
+ curve_attributes.curve_mesh = this;
}
Mesh::~Mesh()
@@ -59,14 +63,18 @@ Mesh::~Mesh()
delete bvh;
}
-void Mesh::reserve(int numverts, int numtris)
+void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
{
/* reserve space to add verts and triangles later */
verts.resize(numverts);
triangles.resize(numtris);
shader.resize(numtris);
smooth.resize(numtris);
- attributes.reserve(numverts, numtris);
+ curve_keys.resize(numcurvekeys);
+ curves.resize(numcurves);
+
+ attributes.reserve();
+ curve_attributes.reserve();
}
void Mesh::clear()
@@ -77,7 +85,11 @@ void Mesh::clear()
shader.clear();
smooth.clear();
+ curve_keys.clear();
+ curves.clear();
+
attributes.clear();
+ curve_attributes.clear();
used_shaders.clear();
transform_applied = false;
@@ -86,24 +98,47 @@ void Mesh::clear()
void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
{
- Triangle t;
- t.v[0] = v0;
- t.v[1] = v1;
- t.v[2] = v2;
+ Triangle tri;
+ tri.v[0] = v0;
+ tri.v[1] = v1;
+ tri.v[2] = v2;
- triangles.push_back(t);
+ triangles.push_back(tri);
shader.push_back(shader_);
smooth.push_back(smooth_);
}
+void Mesh::add_curve_key(float3 co, float radius)
+{
+ CurveKey key;
+ key.co = co;
+ key.radius = radius;
+
+ curve_keys.push_back(key);
+}
+
+void Mesh::add_curve(int first_key, int num_keys, int shader)
+{
+ Curve curve;
+ curve.first_key = first_key;
+ curve.num_keys = num_keys;
+ curve.shader = shader;
+
+ curves.push_back(curve);
+}
+
void Mesh::compute_bounds()
{
BoundBox bnds = BoundBox::empty;
size_t verts_size = verts.size();
+ size_t curve_keys_size = curve_keys.size();
for(size_t i = 0; i < verts_size; i++)
bnds.grow(verts[i]);
+ for(size_t i = 0; i < curve_keys_size; i++)
+ bnds.grow(curve_keys[i].co, curve_keys[i].radius);
+
/* happens mostly on empty meshes */
if(!bnds.valid())
bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
@@ -135,7 +170,12 @@ void Mesh::add_face_normals()
float3 v1 = verts_ptr[t.v[1]];
float3 v2 = verts_ptr[t.v[2]];
- fN[i] = normalize(cross(v1 - v0, v2 - v0));
+ float3 norm = cross(v1 - v0, v2 - v0);
+ float normlen = len(norm);
+ if(normlen == 0.0f)
+ fN[i] = make_float3(0.0f, 0.0f, 0.0f);
+ else
+ fN[i] = norm / normlen;
if(flip)
fN[i] = -fN[i];
@@ -243,6 +283,43 @@ void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
}
}
+void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
+{
+ size_t curve_keys_size = curve_keys.size();
+ CurveKey *keys_ptr = NULL;
+
+ /* pack curve keys */
+ if(curve_keys_size) {
+ keys_ptr = &curve_keys[0];
+
+ for(size_t i = 0; i < curve_keys_size; i++) {
+ float3 p = keys_ptr[i].co;
+ float radius = keys_ptr[i].radius;
+
+ curve_key_co[i] = make_float4(p.x, p.y, p.z, radius);
+ }
+ }
+
+ /* pack curve segments */
+ size_t curve_num = curves.size();
+
+ if(curve_num) {
+ Curve *curve_ptr = &curves[0];
+ int shader_id = 0;
+
+ for(size_t i = 0; i < curve_num; i++) {
+ Curve curve = curve_ptr[i];
+ shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
+
+ curve_data[i] = make_float4(
+ __int_as_float(curve.first_key + curvekey_offset),
+ __int_as_float(curve.num_keys),
+ __int_as_float(shader_id),
+ 0.0f);
+ }
+ }
+}
+
void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total)
{
if(progress->get_cancel())
@@ -327,7 +404,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
og->attribute_map.clear();
og->object_names.clear();
- og->attribute_map.resize(scene->objects.size());
+ og->attribute_map.resize(scene->objects.size()*ATTR_PRIM_TYPES);
for(size_t i = 0; i < scene->objects.size(); i++) {
/* set object name to object index map */
@@ -343,7 +420,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
osl_attr.elem = ATTR_ELEMENT_VALUE;
osl_attr.value = attr;
- og->attribute_map[i][attr.name()] = osl_attr;
+ og->attribute_map[i*ATTR_PRIM_TYPES][attr.name()] = osl_attr;
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
}
/* find mesh attributes */
@@ -357,27 +435,46 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
/* set object attributes */
foreach(AttributeRequest& req, attributes.requests) {
- if(req.element == ATTR_ELEMENT_NONE)
- continue;
-
OSLGlobals::Attribute osl_attr;
- osl_attr.elem = req.element;
- osl_attr.offset = req.offset;
-
- if(req.type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(attribute_standard_name(req.std)));
- og->attribute_map[i][stdname] = osl_attr;
+ if(req.triangle_element != ATTR_ELEMENT_NONE) {
+ osl_attr.elem = req.triangle_element;
+ osl_attr.offset = req.triangle_offset;
+
+ if(req.triangle_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if(req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i*ATTR_PRIM_TYPES][stdname] = osl_attr;
+ }
+ else if(req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i*ATTR_PRIM_TYPES][req.name] = osl_attr;
+ }
}
- else if(req.name != ustring()) {
- /* add lookup by mesh attribute name */
- og->attribute_map[i][req.name] = osl_attr;
+
+ if(req.curve_element != ATTR_ELEMENT_NONE) {
+ osl_attr.elem = req.curve_element;
+ osl_attr.offset = req.curve_offset;
+
+ if(req.curve_type == TypeDesc::TypeFloat)
+ osl_attr.type = TypeDesc::TypeFloat;
+ else
+ osl_attr.type = TypeDesc::TypeColor;
+
+ if(req.std != ATTR_STD_NONE) {
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
+ }
+ else if(req.name != ustring()) {
+ /* add lookup by mesh attribute name */
+ og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
+ }
}
}
}
@@ -393,7 +490,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
int attr_map_stride = 0;
for(size_t i = 0; i < scene->meshes.size(); i++)
- attr_map_stride = max(attr_map_stride, mesh_attributes[i].size()+1);
+ attr_map_stride = max(attr_map_stride, (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES);
if(attr_map_stride == 0)
return;
@@ -404,12 +501,13 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
for(size_t i = 0; i < scene->objects.size(); i++) {
Object *object = scene->objects[i];
+ Mesh *mesh = object->mesh;
/* find mesh attributes */
size_t j;
for(j = 0; j < scene->meshes.size(); j++)
- if(scene->meshes[j] == object->mesh)
+ if(scene->meshes[j] == mesh)
break;
AttributeRequestSet& attributes = mesh_attributes[j];
@@ -425,14 +523,29 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
else
id = scene->shader_manager->get_attribute_id(req.std);
- attr_map[index].x = id;
- attr_map[index].y = req.element;
- attr_map[index].z = as_uint(req.offset);
+ if(mesh->triangles.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.triangle_element;
+ attr_map[index].z = as_uint(req.triangle_offset);
- if(req.type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
- else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ if(req.triangle_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
+ }
+
+ index++;
+
+ if(mesh->curves.size()) {
+ attr_map[index].x = id;
+ attr_map[index].y = req.curve_element;
+ attr_map[index].z = as_uint(req.curve_offset);
+
+ if(req.curve_type == TypeDesc::TypeFloat)
+ attr_map[index].w = NODE_ATTR_FLOAT;
+ else
+ attr_map[index].w = NODE_ATTR_FLOAT3;
+ }
index++;
}
@@ -442,6 +555,15 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
attr_map[index].y = 0;
attr_map[index].z = 0;
attr_map[index].w = 0;
+
+ index++;
+
+ attr_map[index].x = ATTR_STD_NONE;
+ attr_map[index].y = 0;
+ attr_map[index].z = 0;
+ attr_map[index].w = 0;
+
+ index++;
}
/* copy to device */
@@ -449,6 +571,60 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
device->tex_alloc("__attributes_map", dscene->attributes_map);
}
+static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_float, vector<float4>& attr_float3,
+ Attribute *mattr, TypeDesc& type, int& offset, AttributeElement& element)
+{
+ if(mattr) {
+ /* store element and type */
+ element = mattr->element;
+ type = mattr->type;
+
+ /* store attribute data in arrays */
+ size_t size = mattr->element_size(
+ mesh->verts.size(),
+ mesh->triangles.size(),
+ mesh->curves.size(),
+ mesh->curve_keys.size());
+
+ if(mattr->type == TypeDesc::TypeFloat) {
+ float *data = mattr->data_float();
+ offset = attr_float.size();
+
+ attr_float.resize(attr_float.size() + size);
+
+ for(size_t k = 0; k < size; k++)
+ attr_float[offset+k] = data[k];
+ }
+ else {
+ float3 *data = mattr->data_float3();
+ offset = attr_float3.size();
+
+ attr_float3.resize(attr_float3.size() + size);
+
+ for(size_t k = 0; k < size; k++)
+ attr_float3[offset+k] = float3_to_float4(data[k]);
+ }
+
+ /* mesh vertex/curve index is global, not per object, so we sneak
+ * a correction for that in here */
+ if(element == ATTR_ELEMENT_VERTEX)
+ offset -= mesh->vert_offset;
+ else if(element == ATTR_ELEMENT_FACE)
+ offset -= mesh->tri_offset;
+ else if(element == ATTR_ELEMENT_CORNER)
+ offset -= 3*mesh->tri_offset;
+ else if(element == ATTR_ELEMENT_CURVE)
+ offset -= mesh->curve_offset;
+ else if(element == ATTR_ELEMENT_CURVE_KEY)
+ offset -= mesh->curvekey_offset;
+ }
+ else {
+ /* attribute not found */
+ element = ATTR_ELEMENT_NONE;
+ offset = 0;
+ }
+}
+
void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
progress.set_status("Updating Mesh", "Computing attributes");
@@ -482,66 +658,24 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
/* todo: we now store std and name attributes from requests even if
* they actually refer to the same mesh attributes, optimize */
foreach(AttributeRequest& req, attributes.requests) {
- Attribute *mattr = mesh->attributes.find(req);
-
- /* todo: get rid of this exception */
- if(!mattr && req.std == ATTR_STD_GENERATED) {
- mattr = mesh->attributes.add(ATTR_STD_GENERATED);
+ Attribute *triangle_mattr = mesh->attributes.find(req);
+ Attribute *curve_mattr = mesh->curve_attributes.find(req);
+
+ /* todo: get rid of this exception, it's only here for giving some
+ * working texture coordinate for subdivision as we can't preserve
+ * any attributes yet */
+ if(!triangle_mattr && req.std == ATTR_STD_GENERATED) {
+ triangle_mattr = mesh->attributes.add(ATTR_STD_GENERATED);
if(mesh->verts.size())
- memcpy(mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
+ memcpy(triangle_mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
}
- /* attribute not found */
- if(!mattr) {
- req.element = ATTR_ELEMENT_NONE;
- req.offset = 0;
- continue;
- }
-
- /* we abuse AttributeRequest to pass on info like element and
- * offset, it doesn't really make sense but is convenient */
-
- /* store element and type */
- if(mattr->element == Attribute::VERTEX)
- req.element = ATTR_ELEMENT_VERTEX;
- else if(mattr->element == Attribute::FACE)
- req.element = ATTR_ELEMENT_FACE;
- else if(mattr->element == Attribute::CORNER)
- req.element = ATTR_ELEMENT_CORNER;
-
- req.type = mattr->type;
-
- /* store attribute data in arrays */
- size_t size = mattr->element_size(mesh->verts.size(), mesh->triangles.size());
-
- if(mattr->type == TypeDesc::TypeFloat) {
- float *data = mattr->data_float();
- req.offset = attr_float.size();
-
- attr_float.resize(attr_float.size() + size);
-
- for(size_t k = 0; k < size; k++)
- attr_float[req.offset+k] = data[k];
- }
- else {
- float3 *data = mattr->data_float3();
- req.offset = attr_float3.size();
-
- attr_float3.resize(attr_float3.size() + size);
-
- for(size_t k = 0; k < size; k++)
- attr_float3[req.offset+k] = float3_to_float4(data[k]);
- }
-
- /* mesh vertex/triangle index is global, not per object, so we sneak
- * a correction for that in here */
- if(req.element == ATTR_ELEMENT_VERTEX)
- req.offset -= mesh->vert_offset;
- else if(mattr->element == Attribute::FACE)
- req.offset -= mesh->tri_offset;
- else if(mattr->element == Attribute::CORNER)
- req.offset -= 3*mesh->tri_offset;
+ update_attribute_element_offset(mesh, attr_float, attr_float3, triangle_mattr,
+ req.triangle_type, req.triangle_offset, req.triangle_element);
+ update_attribute_element_offset(mesh, attr_float, attr_float3, curve_mattr,
+ req.curve_type, req.curve_offset, req.curve_element);
+
if(progress.get_cancel()) return;
}
}
@@ -573,39 +707,62 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
size_t vert_size = 0;
size_t tri_size = 0;
+ size_t curve_key_size = 0;
+ size_t curve_size = 0;
+
foreach(Mesh *mesh, scene->meshes) {
mesh->vert_offset = vert_size;
mesh->tri_offset = tri_size;
+ mesh->curvekey_offset = curve_key_size;
+ mesh->curve_offset = curve_size;
+
vert_size += mesh->verts.size();
tri_size += mesh->triangles.size();
+
+ curve_key_size += mesh->curve_keys.size();
+ curve_size += mesh->curves.size();
}
- if(tri_size == 0)
- return;
+ if(tri_size != 0) {
+ /* normals */
+ progress.set_status("Updating Mesh", "Computing normals");
- /* normals */
- progress.set_status("Updating Mesh", "Computing normals");
+ float4 *normal = dscene->tri_normal.resize(tri_size);
+ float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
+ float4 *tri_verts = dscene->tri_verts.resize(vert_size);
+ float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
- float4 *normal = dscene->tri_normal.resize(tri_size);
- float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
- float4 *tri_verts = dscene->tri_verts.resize(vert_size);
- float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
+ foreach(Mesh *mesh, scene->meshes) {
+ mesh->pack_normals(scene, &normal[mesh->tri_offset], &vnormal[mesh->vert_offset]);
+ mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset);
- foreach(Mesh *mesh, scene->meshes) {
- mesh->pack_normals(scene, &normal[mesh->tri_offset], &vnormal[mesh->vert_offset]);
- mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset);
+ if(progress.get_cancel()) return;
+ }
- if(progress.get_cancel()) return;
+ /* vertex coordinates */
+ progress.set_status("Updating Mesh", "Copying Mesh to device");
+
+ device->tex_alloc("__tri_normal", dscene->tri_normal);
+ device->tex_alloc("__tri_vnormal", dscene->tri_vnormal);
+ device->tex_alloc("__tri_verts", dscene->tri_verts);
+ device->tex_alloc("__tri_vindex", dscene->tri_vindex);
}
- /* vertex coordinates */
- progress.set_status("Updating Mesh", "Copying Mesh to device");
+ if(curve_size != 0) {
+ progress.set_status("Updating Mesh", "Copying Strands to device");
+
+ float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
+ float4 *curves = dscene->curves.resize(curve_size);
- device->tex_alloc("__tri_normal", dscene->tri_normal);
- device->tex_alloc("__tri_vnormal", dscene->tri_vnormal);
- device->tex_alloc("__tri_verts", dscene->tri_verts);
- device->tex_alloc("__tri_vindex", dscene->tri_vindex);
+ foreach(Mesh *mesh, scene->meshes) {
+ mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
+ if(progress.get_cancel()) return;
+ }
+
+ device->tex_alloc("__curve_keys", dscene->curve_keys);
+ device->tex_alloc("__curves", dscene->curves);
+ }
}
void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
@@ -642,6 +799,10 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
device->tex_alloc("__tri_woop", dscene->tri_woop);
}
+ if(pack.prim_segment.size()) {
+ dscene->prim_segment.reference((uint*)&pack.prim_segment[0], pack.prim_segment.size());
+ device->tex_alloc("__prim_segment", dscene->prim_segment);
+ }
if(pack.prim_visibility.size()) {
dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
device->tex_alloc("__prim_visibility", dscene->prim_visibility);
@@ -751,6 +912,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->bvh_nodes);
device->tex_free(dscene->object_node);
device->tex_free(dscene->tri_woop);
+ device->tex_free(dscene->prim_segment);
device->tex_free(dscene->prim_visibility);
device->tex_free(dscene->prim_index);
device->tex_free(dscene->prim_object);
@@ -758,6 +920,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->tri_vnormal);
device->tex_free(dscene->tri_vindex);
device->tex_free(dscene->tri_verts);
+ device->tex_free(dscene->curves);
+ device->tex_free(dscene->curve_keys);
device->tex_free(dscene->attributes_map);
device->tex_free(dscene->attributes_float);
device->tex_free(dscene->attributes_float3);
@@ -765,6 +929,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->bvh_nodes.clear();
dscene->object_node.clear();
dscene->tri_woop.clear();
+ dscene->prim_segment.clear();
dscene->prim_visibility.clear();
dscene->prim_index.clear();
dscene->prim_object.clear();
@@ -772,6 +937,8 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->tri_vnormal.clear();
dscene->tri_vindex.clear();
dscene->tri_verts.clear();
+ dscene->curves.clear();
+ dscene->curve_keys.clear();
dscene->attributes_map.clear();
dscene->attributes_float.clear();
dscene->attributes_float3.clear();
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 637143f..b83752a 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -50,6 +50,21 @@ public:
int v[3];
};
+ /* Mesh Curve */
+ struct Curve {
+ int first_key;
+ int num_keys;
+ uint shader;
+ uint pad;
+
+ int num_segments() { return num_keys - 1; }
+ };
+
+ struct CurveKey {
+ float3 co;
+ float radius;
+ };
+
/* Displacement */
enum DisplacementMethod {
DISPLACE_BUMP,
@@ -65,8 +80,12 @@ public:
vector<uint> shader;
vector<bool> smooth;
+ vector<CurveKey> curve_keys;
+ vector<Curve> curves;
+
vector<uint> used_shaders;
AttributeSet attributes;
+ AttributeSet curve_attributes;
BoundBox bounds;
bool transform_applied;
@@ -82,13 +101,18 @@ public:
size_t tri_offset;
size_t vert_offset;
+ size_t curve_offset;
+ size_t curvekey_offset;
+
/* Functions */
Mesh();
~Mesh();
- void reserve(int numverts, int numfaces);
+ void reserve(int numverts, int numfaces, int numcurves, int numcurvekeys);
void clear();
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
+ void add_curve_key(float3 loc, float radius);
+ void add_curve(int first_key, int num_keys, int shader);
void compute_bounds();
void add_face_normals();
@@ -96,6 +120,7 @@ public:
void pack_normals(Scene *scene, float4 *normal, float4 *vnormal);
void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
+ void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
void compute_bvh(SceneParams *params, Progress *progress, int n, int total);
bool need_attribute(Scene *scene, AttributeStandard std);
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index dea694a..0426769 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -19,6 +19,7 @@
#include "device.h"
#include "mesh.h"
+#include "object.h"
#include "scene.h"
#include "shader.h"
@@ -41,11 +42,24 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
if(!has_displacement)
return false;
+ string msg = string_printf("Computing Displacement %s", mesh->name.c_str());
+ progress.set_status("Updating Mesh", msg);
+
+ /* find object index. todo: is arbitrary */
+ size_t object_index = ~0;
+
+ for(size_t i = 0; i < scene->objects.size(); i++) {
+ if(scene->objects[i]->mesh == mesh) {
+ object_index = i;
+ break;
+ }
+ }
+
/* setup input for device task */
vector<bool> done(mesh->verts.size(), false);
device_vector<uint4> d_input;
uint4 *d_input_data = d_input.resize(mesh->verts.size());
- size_t d_input_offset = 0;
+ size_t d_input_size = 0;
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Mesh::Triangle t = mesh->triangles[i];
@@ -61,8 +75,8 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
done[t.v[j]] = true;
/* set up object, primitive and barycentric coordinates */
- /* when used, non-instanced convention: object = -object-1; */
- int object = ~0; /* todo */
+ /* when used, non-instanced convention: object = ~object */
+ int object = ~object_index;
int prim = mesh->tri_offset + i;
float u, v;
@@ -81,16 +95,16 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
/* back */
uint4 in = make_uint4(object, prim, __float_as_int(u), __float_as_int(v));
- d_input_data[d_input_offset++] = in;
+ d_input_data[d_input_size++] = in;
}
}
- if(d_input_offset == 0)
+ if(d_input_size == 0)
return false;
/* run device task */
device_vector<float4> d_output;
- d_output.resize(d_input.size());
+ d_output.resize(d_input_size);
device->mem_alloc(d_input, MEM_READ_ONLY);
device->mem_copy_to(d_input);
@@ -101,7 +115,7 @@ bool MeshManager::displace(Device *device, Scene *scene, Mesh *mesh, Progress& p
task.shader_output = d_output.device_pointer;
task.shader_eval_type = SHADER_EVAL_DISPLACE;
task.shader_x = 0;
- task.shader_w = d_input.size();
+ task.shader_w = d_output.size();
device->task_add(task);
device->task_wait();
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 3f8055b..d1297c9 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -142,6 +142,7 @@ ImageTextureNode::ImageTextureNode()
slot = -1;
is_float = -1;
filename = "";
+ is_builtin = false;
color_space = ustring("Color");
projection = ustring("Flat");;
projection_blend = 0.0f;
@@ -155,7 +156,7 @@ ImageTextureNode::ImageTextureNode()
ImageTextureNode::~ImageTextureNode()
{
if(image_manager)
- image_manager->remove_image(filename);
+ image_manager->remove_image(filename, is_builtin);
}
ShaderNode *ImageTextureNode::clone() const
@@ -176,7 +177,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(is_float == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, animated, is_float_bool);
+ slot = image_manager->add_image(filename, is_builtin, animated, is_float_bool);
is_float = (int)is_float_bool;
}
@@ -237,7 +238,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
tex_mapping.compile(compiler);
if(is_float == -1)
- is_float = (int)image_manager->is_float_image(filename);
+ is_float = (int)image_manager->is_float_image(filename, false);
compiler.parameter("filename", filename.c_str());
if(is_float || color_space != "Color")
@@ -271,6 +272,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
slot = -1;
is_float = -1;
filename = "";
+ is_builtin = false;
color_space = ustring("Color");
projection = ustring("Equirectangular");
animated = false;
@@ -283,7 +285,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
EnvironmentTextureNode::~EnvironmentTextureNode()
{
if(image_manager)
- image_manager->remove_image(filename);
+ image_manager->remove_image(filename, is_builtin);
}
ShaderNode *EnvironmentTextureNode::clone() const
@@ -304,7 +306,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(slot == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, animated, is_float_bool);
+ slot = image_manager->add_image(filename, is_builtin, animated, is_float_bool);
is_float = (int)is_float_bool;
}
@@ -354,7 +356,7 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
tex_mapping.compile(compiler);
if(is_float == -1)
- is_float = (int)image_manager->is_float_image(filename);
+ is_float = (int)image_manager->is_float_image(filename, false);
compiler.parameter("filename", filename.c_str());
compiler.parameter("projection", projection);
@@ -2240,6 +2242,63 @@ void ParticleInfoNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_particle_info");
}
+/* Hair Info */
+
+HairInfoNode::HairInfoNode()
+: ShaderNode("hair_info")
+{
+ add_output("Is Strand", SHADER_SOCKET_FLOAT);
+ add_output("Intercept", SHADER_SOCKET_FLOAT);
+ add_output("Thickness", SHADER_SOCKET_FLOAT);
+ add_output("Tangent Normal", SHADER_SOCKET_NORMAL);
+}
+
+void HairInfoNode::attributes(AttributeRequestSet *attributes)
+{
+ ShaderOutput *intercept_out = output("Intercept");
+
+ if(!intercept_out->links.empty())
+ attributes->add(ATTR_STD_CURVE_INTERCEPT);
+
+ ShaderNode::attributes(attributes);
+}
+
+void HairInfoNode::compile(SVMCompiler& compiler)
+{
+ ShaderOutput *out;
+
+ out = output("Is Strand");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, out->stack_offset);
+ }
+
+ out = output("Intercept");
+ if(!out->links.empty()) {
+ int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_ATTR, attr, out->stack_offset, NODE_ATTR_FLOAT);
+ }
+
+ out = output("Thickness");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, out->stack_offset);
+ }
+
+ out = output("Tangent Normal");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, out->stack_offset);
+ }
+
+}
+
+void HairInfoNode::compile(OSLCompiler& compiler)
+{
+ compiler.add(this, "node_hair_info");
+}
+
/* Value */
ValueNode::ValueNode()
@@ -3018,9 +3077,56 @@ void RGBCurvesNode::compile(SVMCompiler& compiler)
void RGBCurvesNode::compile(OSLCompiler& compiler)
{
+ float ramp[RAMP_TABLE_SIZE][3];
+
+ for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
+ ramp[i][0] = curves[i].x;
+ ramp[i][1] = curves[i].y;
+ ramp[i][2] = curves[i].z;
+ }
+
+ compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE);
compiler.add(this, "node_rgb_curves");
}
+/* VectorCurvesNode */
+
+VectorCurvesNode::VectorCurvesNode()
+: ShaderNode("rgb_curves")
+{
+ add_input("Fac", SHADER_SOCKET_FLOAT);
+ add_input("Vector", SHADER_SOCKET_VECTOR);
+ add_output("Vector", SHADER_SOCKET_VECTOR);
+}
+
+void VectorCurvesNode::compile(SVMCompiler& compiler)
+{
+ ShaderInput *fac_in = input("Fac");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *vector_out = output("Vector");
+
+ compiler.stack_assign(fac_in);
+ compiler.stack_assign(vector_in);
+ compiler.stack_assign(vector_out);
+
+ compiler.add_node(NODE_VECTOR_CURVES, fac_in->stack_offset, vector_in->stack_offset, vector_out->stack_offset);
+ compiler.add_array(curves, RAMP_TABLE_SIZE);
+}
+
+void VectorCurvesNode::compile(OSLCompiler& compiler)
+{
+ float ramp[RAMP_TABLE_SIZE][3];
+
+ for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
+ ramp[i][0] = curves[i].x;
+ ramp[i][1] = curves[i].y;
+ ramp[i][2] = curves[i].z;
+ }
+
+ compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE);
+ compiler.add(this, "node_vector_curves");
+}
+
/* RGBRampNode */
RGBRampNode::RGBRampNode()
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 97c617f..8b2d6a0 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -70,6 +70,7 @@ public:
int slot;
int is_float;
string filename;
+ bool is_builtin;
ustring color_space;
ustring projection;
float projection_blend;
@@ -89,6 +90,7 @@ public:
int slot;
int is_float;
string filename;
+ bool is_builtin;
ustring color_space;
ustring projection;
bool animated;
@@ -331,6 +333,13 @@ public:
void attributes(AttributeRequestSet *attributes);
};
+class HairInfoNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(HairInfoNode)
+
+ void attributes(AttributeRequestSet *attributes);
+};
+
class ValueNode : public ShaderNode {
public:
SHADER_NODE_CLASS(ValueNode)
@@ -459,6 +468,12 @@ public:
float4 curves[RAMP_TABLE_SIZE];
};
+class VectorCurvesNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(VectorCurvesNode)
+ float4 curves[RAMP_TABLE_SIZE];
+};
+
class RGBRampNode : public ShaderNode {
public:
SHADER_NODE_CLASS(RGBRampNode)
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index bd9f16d..a89f8af 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -19,6 +19,7 @@
#include "device.h"
#include "light.h"
#include "mesh.h"
+#include "curves.h"
#include "object.h"
#include "scene.h"
@@ -45,6 +46,7 @@ Object::Object()
motion.post = transform_identity();
use_motion = false;
use_holdout = false;
+ curverender = false;
}
Object::~Object()
@@ -86,6 +88,10 @@ void Object::apply_transform()
for(size_t i = 0; i < mesh->verts.size(); i++)
mesh->verts[i] = transform_point(&tfm, mesh->verts[i]);
+ for(size_t i = 0; i < mesh->curve_keys.size(); i++)
+ mesh->curve_keys[i].co = transform_point(&tfm, mesh->curve_keys[i].co);
+
+ Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT);
Attribute *attr_fN = mesh->attributes.find(ATTR_STD_FACE_NORMAL);
Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
@@ -110,6 +116,13 @@ void Object::apply_transform()
vN[i] = transform_direction(&ntfm, vN[i]);
}
+ if(attr_tangent) {
+ float3 *tangent = attr_tangent->data_float3();
+
+ for(size_t i = 0; i < mesh->curve_keys.size(); i++)
+ tangent[i] = transform_direction(&tfm, tangent[i]);
+ }
+
if(bounds.valid()) {
mesh->compute_bounds();
compute_bounds(false, 0.0f);
@@ -133,6 +146,7 @@ void Object::tag_update(Scene *scene)
}
}
+ scene->curve_system_manager->need_update = true;
scene->mesh_manager->need_update = true;
scene->object_manager->need_update = true;
}
@@ -150,12 +164,17 @@ ObjectManager::~ObjectManager()
void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress)
{
- float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
+ float4 *objects;
+ float4 *objects_vector = NULL;
int i = 0;
map<Mesh*, float> surface_area_map;
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
bool have_motion = false;
+ objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
+ if(need_motion == Scene::MOTION_PASS)
+ objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
+
foreach(Object *ob, scene->objects) {
Mesh *mesh = ob->mesh;
uint flag = 0;
@@ -184,6 +203,20 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ int first_key = curve.first_key;
+
+ for(int i = 0; i < curve.num_segments(); i++) {
+ float3 p1 = mesh->curve_keys[first_key + i].co;
+ float r1 = mesh->curve_keys[first_key + i].radius;
+ float3 p2 = mesh->curve_keys[first_key + i + 1].co;
+ float r2 = mesh->curve_keys[first_key + i + 1].radius;
+
+ /* currently ignores segment overlaps*/
+ surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+ }
+ }
+
surface_area_map[mesh] = surface_area;
}
else
@@ -199,14 +232,31 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
surface_area += triangle_area(p1, p2, p3);
}
+
+ foreach(Mesh::Curve& curve, mesh->curves) {
+ int first_key = curve.first_key;
+
+ for(int i = 0; i < curve.num_segments(); i++) {
+ float3 p1 = mesh->curve_keys[first_key + i].co;
+ float r1 = mesh->curve_keys[first_key + i].radius;
+ float3 p2 = mesh->curve_keys[first_key + i + 1].co;
+ float r2 = mesh->curve_keys[first_key + i + 1].radius;
+
+ p1 = transform_point(&tfm, p1);
+ p2 = transform_point(&tfm, p2);
+
+ /* currently ignores segment overlaps*/
+ surface_area += M_PI_F *(r1 + r2) * len(p1 - p2);
+ }
+ }
}
/* pack in texture */
int offset = i*OBJECT_SIZE;
memcpy(&objects[offset], &tfm, sizeof(float4)*3);
- memcpy(&objects[offset+3], &itfm, sizeof(float4)*3);
- objects[offset+6] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
+ memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
+ objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
if(need_motion == Scene::MOTION_PASS) {
/* motion transformations, is world/object space depending if mesh
@@ -220,8 +270,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
mtfm_post = mtfm_post * itfm;
- memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
- memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
+ memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
+ memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
}
#ifdef __OBJECT_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
@@ -230,20 +280,16 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
- memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
+ memcpy(&objects[offset], &decomp, sizeof(float4)*8);
flag |= SD_OBJECT_MOTION;
have_motion = true;
}
- else {
- float4 no_motion = make_float4(FLT_MAX);
- memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
- }
}
#endif
/* dupli object coords */
- objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
- objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
+ objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
+ objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
/* object flag */
if(ob->use_holdout)
@@ -256,6 +302,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
}
device->tex_alloc("__objects", dscene->objects);
+ if(need_motion == Scene::MOTION_PASS)
+ device->tex_alloc("__objects_vector", dscene->objects_vector);
dscene->data.bvh.have_motion = have_motion;
}
@@ -297,6 +345,9 @@ void ObjectManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->objects);
dscene->objects.clear();
+ device->tex_free(dscene->objects_vector);
+ dscene->objects_vector.clear();
+
device->tex_free(dscene->object_flag);
dscene->object_flag.clear();
}
@@ -349,6 +400,7 @@ void ObjectManager::apply_static_transforms(Scene *scene, uint *object_flag, Pro
void ObjectManager::tag_update(Scene *scene)
{
need_update = true;
+ scene->curve_system_manager->need_update = true;
scene->mesh_manager->need_update = true;
scene->light_manager->need_update = true;
}
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 9c9b11b..9ba500c 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -48,6 +48,7 @@ public:
MotionTransform motion;
bool use_motion;
bool use_holdout;
+ bool curverender;
float3 dupli_generated;
float2 dupli_uv;
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 894565a..28de56f 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -275,9 +275,43 @@ const char *OSLShaderManager::shader_load_filepath(string filepath)
return shader_load_bytecode(bytecode_hash, bytecode);
}
+/* don't try this at home .. this is a template trick to use either
+ * LoadMemoryShader or LoadMemoryCompiledShader which are the function
+ * names in our custom branch and the official repository. */
+
+template<bool C, typename T = void> struct enable_if { typedef T type; };
+template<typename T> struct enable_if<false, T> { };
+
+template<typename T, typename Sign>
+struct has_LoadMemoryCompiledShader {
+ typedef int yes;
+ typedef char no;
+
+ template<typename U, U> struct type_check;
+ template<typename _1> static yes &chk(type_check<Sign, &_1::LoadMemoryCompiledShader>*);
+ template<typename > static no &chk(...);
+ static bool const value = sizeof(chk<T>(0)) == sizeof(yes);
+};
+
+template<typename T>
+typename enable_if<has_LoadMemoryCompiledShader<T,
+ bool(T::*)(const char*, const char*)>::value, bool>::type
+load_memory_shader(T *ss, const char *name, const char *buffer)
+{
+ return ss->LoadMemoryCompiledShader(name, buffer);
+}
+
+template<typename T>
+typename enable_if<!has_LoadMemoryCompiledShader<T,
+ bool(T::*)(const char*, const char*)>::value, bool>::type
+load_memory_shader(T *ss, const char *name, const char *buffer)
+{
+ return ss->LoadMemoryShader(name, buffer);
+}
+
const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode)
{
- ss->LoadMemoryShader(hash.c_str(), bytecode.c_str());
+ load_memory_shader(ss, hash.c_str(), bytecode.c_str());
/* this is a bit weak, but works */
OSLShaderInfo info;
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 8085cfd..093bfec 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -29,6 +29,7 @@
#include "mesh.h"
#include "object.h"
#include "particles.h"
+#include "curves.h"
#include "scene.h"
#include "svm.h"
#include "osl.h"
@@ -54,6 +55,7 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
integrator = new Integrator();
image_manager = new ImageManager();
particle_system_manager = new ParticleSystemManager();
+ curve_system_manager = new CurveSystemManager();
/* OSL only works on the CPU */
if(device_info_.type == DEVICE_CPU)
@@ -96,6 +98,7 @@ void Scene::free_memory(bool final)
light_manager->device_free(device, &dscene);
particle_system_manager->device_free(device, &dscene);
+ curve_system_manager->device_free(device, &dscene);
if(!params.persistent_images || final)
image_manager->device_free(device, &dscene);
@@ -112,6 +115,7 @@ void Scene::free_memory(bool final)
delete shader_manager;
delete light_manager;
delete particle_system_manager;
+ delete curve_system_manager;
delete image_manager;
}
else {
@@ -165,6 +169,11 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
+ progress.set_status("Updating Hair Systems");
+ curve_system_manager->device_update(device, &dscene, this, progress);
+
+ if(progress.get_cancel()) return;
+
progress.set_status("Updating Meshes");
mesh_manager->device_update(device, &dscene, this, progress);
@@ -242,7 +251,8 @@ bool Scene::need_reset()
|| filter->need_update
|| integrator->need_update
|| shader_manager->need_update
- || particle_system_manager->need_update);
+ || particle_system_manager->need_update
+ || curve_system_manager->need_update);
}
void Scene::reset()
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 92ef692..f6e1dae 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -25,7 +25,6 @@
#include "kernel_types.h"
-#include "util_attribute.h"
#include "util_param.h"
#include "util_string.h"
#include "util_thread.h"
@@ -50,6 +49,7 @@ class Object;
class ObjectManager;
class ParticleSystemManager;
class ParticleSystem;
+class CurveSystemManager;
class Shader;
class ShaderManager;
class Progress;
@@ -62,6 +62,7 @@ public:
device_vector<float4> bvh_nodes;
device_vector<uint> object_node;
device_vector<float4> tri_woop;
+ device_vector<uint> prim_segment;
device_vector<uint> prim_visibility;
device_vector<uint> prim_index;
device_vector<uint> prim_object;
@@ -72,8 +73,12 @@ public:
device_vector<float4> tri_vindex;
device_vector<float4> tri_verts;
+ device_vector<float4> curves;
+ device_vector<float4> curve_keys;
+
/* objects */
device_vector<float4> objects;
+ device_vector<float4> objects_vector;
/* attributes */
device_vector<uint4> attributes_map;
@@ -169,6 +174,7 @@ public:
MeshManager *mesh_manager;
ObjectManager *object_manager;
ParticleSystemManager *particle_system_manager;
+ CurveSystemManager *curve_system_manager;
/* default shaders */
int default_surface;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 1d1a3d5..e49a4a3 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN
Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
- params.background == false || params.progressive_refine, params.background,
+ params.background == false || params.progressive_refine, params.background, params.tile_order,
max(params.device.multi_devices.size(), 1)),
stats()
{
@@ -357,7 +357,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
tile_lock.unlock();
- /* in case of a permant buffer, return it, otherwise we will allocate
+ /* in case of a permanent buffer, return it, otherwise we will allocate
* a new temporary buffer */
if(!params.background) {
tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
@@ -411,6 +411,12 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
rtile.rgba = 0;
rtile.buffers = tilebuffers;
+ /* this will tag tile as IN PROGRESS in blender-side render pipeline,
+ * which is needed to highlight currently rendering tile before first
+ * sample was processed for it
+ */
+ update_tile_sample(rtile);
+
return true;
}
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index cfc1502..27073d2 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -51,6 +51,7 @@ public:
bool experimental;
int samples;
int2 tile_size;
+ int tile_order;
int start_resolution;
int threads;
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index bbcdb47..d62ecd8 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -24,10 +24,11 @@
CCL_NAMESPACE_BEGIN
TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
- bool preserve_tile_device_, bool background_, int num_devices_)
+ bool preserve_tile_device_, bool background_, int tile_order_, int num_devices_)
{
progressive = progressive_;
tile_size = tile_size_;
+ tile_order = tile_order_;
start_resolution = start_resolution_;
num_devices = num_devices_;
preserve_tile_device = preserve_tile_device_;
@@ -165,6 +166,20 @@ void TileManager::set_tiles()
state.buffer.full_height = max(1, params.full_height/resolution);
}
+list<Tile>::iterator TileManager::next_viewport_tile(int device)
+{
+ list<Tile>::iterator iter;
+
+ int logical_device = preserve_tile_device? device: 0;
+
+ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
+ if(iter->device == logical_device && iter->rendering == false)
+ return iter;
+ }
+
+ return state.tiles.end();
+}
+
list<Tile>::iterator TileManager::next_center_tile(int device)
{
list<Tile>::iterator iter, best = state.tiles.end();
@@ -210,28 +225,53 @@ list<Tile>::iterator TileManager::next_center_tile(int device)
return best;
}
-list<Tile>::iterator TileManager::next_simple_tile(int device)
+list<Tile>::iterator TileManager::next_simple_tile(int device, int tile_order)
{
- list<Tile>::iterator iter;
+ list<Tile>::iterator iter, best = state.tiles.end();
+ int resolution = state.resolution_divider;
int logical_device = preserve_tile_device? device: 0;
+ int64_t cordx = max(1, params.width/resolution);
+ int64_t cordy = max(1, params.height/resolution);
+ int64_t mindist = cordx * cordy;
+
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
- if(iter->device == logical_device && iter->rendering == false)
- return iter;
+ if(iter->device == logical_device && iter->rendering == false) {
+ Tile &cur_tile = *iter;
+
+ int64_t distx = cordx;
+
+ if (tile_order == TileManager::RIGHT_TO_LEFT)
+ distx = cordx - cur_tile.x;
+ else if (tile_order == TileManager::LEFT_TO_RIGHT)
+ distx = cordx + cur_tile.x;
+ else if (tile_order == TileManager::TOP_TO_BOTTOM)
+ distx = cordx - cur_tile.y;
+ else /* TileManager::BOTTOM_TO_TOP */
+ distx = cordx + cur_tile.y;
+
+ if(distx < mindist) {
+ best = iter;
+ mindist = distx;
+ }
+ }
}
- return state.tiles.end();
+ return best;
}
bool TileManager::next_tile(Tile& tile, int device)
{
list<Tile>::iterator tile_it;
-
- if(background)
- tile_it = next_center_tile(device);
+ if (background) {
+ if(tile_order == TileManager::CENTER)
+ tile_it = next_center_tile(device);
+ else
+ tile_it = next_simple_tile(device, tile_order);
+ }
else
- tile_it = next_simple_tile(device);
+ tile_it = next_viewport_tile(device);
if(tile_it != state.tiles.end()) {
tile_it->rendering = true;
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 6f7a8f2..99cffb4 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -59,7 +59,7 @@ public:
} state;
TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution,
- bool preserve_tile_device, bool background, int num_devices = 1);
+ bool preserve_tile_device, bool background, int tile_order, int num_devices = 1);
~TileManager();
void reset(BufferParams& params, int num_samples);
@@ -68,12 +68,23 @@ public:
bool next_tile(Tile& tile, int device = 0);
bool done();
+ void set_tile_order(int tile_order_) { tile_order = tile_order_; }
protected:
+ /* Note: this should match enum_tile_order in properties.py */
+ enum {
+ CENTER = 0,
+ RIGHT_TO_LEFT = 1,
+ LEFT_TO_RIGHT = 2,
+ TOP_TO_BOTTOM = 3,
+ BOTTOM_TO_TOP = 4
+ } TileOrder;
+
void set_tiles();
bool progressive;
int num_samples;
int2 tile_size;
+ int tile_order;
int start_resolution;
int num_devices;
@@ -106,9 +117,12 @@ protected:
* mimics behavior of blender internal's tile order
*/
list<Tile>::iterator next_center_tile(int device);
+
+ /* returns simple tile order */
+ list<Tile>::iterator next_simple_tile(int device, int tile_order);
- /* returns first unhandled tile starting from left bottom corner of the image */
- list<Tile>::iterator next_simple_tile(int device);
+ /* returns first unhandled tile (for viewport) */
+ list<Tile>::iterator next_viewport_tile(int device);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 6920df9..48e6808 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -47,7 +47,7 @@ void EdgeDice::reserve(int num_verts, int num_tris)
vert_offset = mesh->verts.size();
tri_offset = mesh->triangles.size();
- mesh->reserve(vert_offset + num_verts, tri_offset + num_tris);
+ mesh->reserve(vert_offset + num_verts, tri_offset + num_tris, 0, 0);
Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index dce4177..bcaaa9a 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -9,7 +9,6 @@ set(INC_SYS
)
set(SRC
- util_attribute.cpp
util_cache.cpp
util_cuda.cpp
util_dynlib.cpp
@@ -33,7 +32,6 @@ endif()
set(SRC_HEADERS
util_algorithm.h
util_args.h
- util_attribute.h
util_boundbox.h
util_cache.h
util_cuda.h
diff --git a/intern/cycles/util/util_attribute.cpp b/intern/cycles/util/util_attribute.cpp
deleted file mode 100644
index 057fb62..0000000
--- a/intern/cycles/util/util_attribute.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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.
- */
-
-#include "util_attribute.h"
-
-CCL_NAMESPACE_BEGIN
-
-const char *attribute_standard_name(AttributeStandard std)
-{
- if(std == ATTR_STD_VERTEX_NORMAL)
- return "N";
- else if(std == ATTR_STD_FACE_NORMAL)
- return "Ng";
- else if(std == ATTR_STD_UV)
- return "uv";
- else if(std == ATTR_STD_GENERATED)
- return "generated";
- else if(std == ATTR_STD_UV_TANGENT)
- return "tangent";
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- return "tangent_sign";
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- return "undeformed";
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- return "undisplaced";
- else if(std == ATTR_STD_MOTION_PRE)
- return "motion_pre";
- else if(std == ATTR_STD_MOTION_POST)
- return "motion_post";
- else if(std == ATTR_STD_PARTICLE)
- return "particle";
-
- return "";
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_attribute.h b/intern/cycles/util/util_attribute.h
deleted file mode 100644
index 334864c..0000000
--- a/intern/cycles/util/util_attribute.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * 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.
- */
-
-#ifndef __UTIL_ATTRIBUTE_H__
-#define __UTIL_ATTRIBUTE_H__
-
-#include "util_types.h"
-
-CCL_NAMESPACE_BEGIN
-
-const char *attribute_standard_name(AttributeStandard std);
-
-CCL_NAMESPACE_END
-
-#endif /* __UTIL_ATTRIBUTE_H__ */
-
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index 6dd1c6c..0c857f9 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -65,6 +65,13 @@ public:
max = ccl::max(max, pt);
}
+ __forceinline void grow(const float3& pt, float border)
+ {
+ float3 shift = {border, border, border, 0.0f};
+ min = ccl::min(min, pt - shift);
+ max = ccl::max(max, pt + shift);
+ }
+
__forceinline void grow(const BoundBox& bbox)
{
grow(bbox.min);
diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp
index 2716f00..12cb0d3 100644
--- a/intern/cycles/util/util_cuda.cpp
+++ b/intern/cycles/util/util_cuda.cpp
@@ -394,10 +394,10 @@ bool cuLibraryInit()
string cuCompilerPath()
{
#ifdef _WIN32
- const char *defaultpath = "C:/CUDA/bin";
+ const char *defaultpaths[] = {"C:/CUDA/bin", NULL};
const char *executable = "nvcc.exe";
#else
- const char *defaultpath = "/usr/local/cuda/bin";
+ const char *defaultpaths[] = {"/Developer/NVIDIA/CUDA-4.2/bin", "/usr/local/cuda-4.2/bin", "/usr/local/cuda/bin", NULL};
const char *executable = "nvcc";
#endif
@@ -405,13 +405,17 @@ string cuCompilerPath()
string nvcc;
- if(binpath)
+ if(binpath) {
nvcc = path_join(binpath, executable);
- else
- nvcc = path_join(defaultpath, executable);
+ if(path_exists(nvcc))
+ return nvcc;
+ }
- if(path_exists(nvcc))
- return nvcc;
+ for(int i = 0; defaultpaths[i]; i++) {
+ nvcc = path_join(defaultpaths[i], executable);
+ if(path_exists(nvcc))
+ return nvcc;
+ }
#ifndef _WIN32
{
diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h
index d9d956b..9682f1c 100644
--- a/intern/cycles/util/util_cuda.h
+++ b/intern/cycles/util/util_cuda.h
@@ -38,7 +38,7 @@ CCL_NAMESPACE_END
#define CUDA_VERSION 3020
-#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
+#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined(__LP64__)
typedef unsigned long long CUdeviceptr;
#else
typedef unsigned int CUdeviceptr;
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 70adee4..c37fa1a 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1092,6 +1092,199 @@ __device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
return r;
}
+/* NaN-safe math ops */
+
+__device float safe_asinf(float a)
+{
+ if(a <= -1.0f)
+ return -M_PI_2_F;
+ else if(a >= 1.0f)
+ return M_PI_2_F;
+
+ return asinf(a);
+}
+
+__device float safe_acosf(float a)
+{
+ if(a <= -1.0f)
+ return M_PI_F;
+ else if(a >= 1.0f)
+ return 0.0f;
+
+ return acosf(a);
+}
+
+__device float compatible_powf(float x, float y)
+{
+ /* GPU pow doesn't accept negative x, do manual checks here */
+ if(x < 0.0f) {
+ if(fmod(-y, 2.0f) == 0.0f)
+ return powf(-x, y);
+ else
+ return -powf(-x, y);
+ }
+ else if(x == 0.0f)
+ return 0.0f;
+
+ return powf(x, y);
+}
+
+__device float safe_powf(float a, float b)
+{
+ if(b == 0.0f)
+ return 1.0f;
+ if(a == 0.0f)
+ return 0.0f;
+ if(a < 0.0f && b != (int)b)
+ return 0.0f;
+
+ return compatible_powf(a, b);
+}
+
+__device float safe_logf(float a, float b)
+{
+ if(a < 0.0f || b < 0.0f)
+ return 0.0f;
+
+ return logf(a)/logf(b);
+}
+
+__device float safe_divide(float a, float b)
+{
+ float result;
+
+ if(b == 0.0f)
+ result = 0.0f;
+ else
+ result = a/b;
+
+ return result;
+}
+
+/* Ray Intersection */
+
+__device bool ray_sphere_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 sphere_P, float sphere_radius,
+ float3 *isect_P, float *isect_t)
+{
+ float3 d = sphere_P - ray_P;
+ float radiussq = sphere_radius*sphere_radius;
+ float tsq = dot(d, d);
+
+ if(tsq > radiussq) { /* ray origin outside sphere */
+ float tp = dot(d, ray_D);
+
+ if(tp < 0.0f) /* dir points away from sphere */
+ return false;
+
+ float dsq = tsq - tp*tp; /* pythagoras */
+
+ if(dsq > radiussq) /* closest point on ray outside sphere */
+ return false;
+
+ float t = tp - sqrtf(radiussq - dsq); /* pythagoras */
+
+ if(t < ray_t) {
+ *isect_t = t;
+ *isect_P = ray_P + ray_D*t;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+__device bool ray_aligned_disk_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 disk_P, float disk_radius,
+ float3 *isect_P, float *isect_t)
+{
+ /* aligned disk normal */
+ float disk_t;
+ float3 disk_N = normalize_len(ray_P - disk_P, &disk_t);
+ float div = dot(ray_D, disk_N);
+
+ if(div == 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ float t = -disk_t/div;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ /* test if within radius */
+ float3 P = ray_P + ray_D*t;
+ if(len_squared(P - disk_P) > disk_radius*disk_radius)
+ return false;
+
+ *isect_P = P;
+ *isect_t = t;
+
+ return true;
+}
+
+__device bool ray_triangle_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 v0, float3 v1, float3 v2,
+ float3 *isect_P, float *isect_t)
+{
+ /* Calculate intersection */
+ float3 e1 = v1 - v0;
+ float3 e2 = v2 - v0;
+ float3 s1 = cross(ray_D, e2);
+
+ const float divisor = dot(s1, e1);
+ if(divisor == 0.0f)
+ return false;
+
+ const float invdivisor = 1.0f/divisor;
+
+ /* compute first barycentric coordinate */
+ const float3 d = ray_P - v0;
+ const float u = dot(d, s1)*invdivisor;
+ if(u < 0.0f)
+ return false;
+
+ /* Compute second barycentric coordinate */
+ const float3 s2 = cross(d, e1);
+ const float v = dot(ray_D, s2)*invdivisor;
+ if(v < 0.0f)
+ return false;
+
+ const float b0 = 1.0f - u - v;
+ if(b0 < 0.0f)
+ return false;
+
+ /* compute t to intersection point */
+ const float t = dot(e2, s2)*invdivisor;
+ if(t < 0.0f || t > ray_t)
+ return false;
+
+ *isect_t = t;
+ *isect_P = ray_P + ray_D*t;
+
+ return true;
+}
+
+__device bool ray_quad_intersect(
+ float3 ray_P, float3 ray_D, float ray_t,
+ float3 quad_P, float3 quad_u, float3 quad_v,
+ float3 *isect_P, float *isect_t)
+{
+ float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f;
+ float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f;
+ float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f;
+ float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f;
+
+ if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t))
+ return true;
+ else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t))
+ return true;
+
+ return false;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index a1c12dd..1f19f85 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -45,7 +45,7 @@ typedef struct Transform {
*
* For the DecompMotionTransform we drop scale from pre/post. */
-typedef struct MotionTransform {
+typedef struct __may_alias MotionTransform {
Transform pre;
Transform mid;
Transform post;
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 3d24610..bb6de11 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -39,12 +39,14 @@
#if defined(_WIN32) && !defined(FREE_WINDOWS)
#define __device_inline static __forceinline
#define __align(...) __declspec(align(__VA_ARGS__))
+#define __may_alias
#else
#define __device_inline static inline __attribute__((always_inline))
#ifndef FREE_WINDOWS64
#define __forceinline inline __attribute__((always_inline))
#endif
#define __align(...) __attribute__((aligned(__VA_ARGS__)))
+#define __may_alias __attribute__((__may_alias__))
#endif
#endif
@@ -446,24 +448,6 @@ __device_inline int4 make_int4(const float3& f)
#endif
-typedef enum AttributeStandard {
- ATTR_STD_NONE = 0,
- ATTR_STD_VERTEX_NORMAL,
- ATTR_STD_FACE_NORMAL,
- ATTR_STD_UV,
- ATTR_STD_UV_TANGENT,
- ATTR_STD_UV_TANGENT_SIGN,
- ATTR_STD_GENERATED,
- ATTR_STD_POSITION_UNDEFORMED,
- ATTR_STD_POSITION_UNDISPLACED,
- ATTR_STD_MOTION_PRE,
- ATTR_STD_MOTION_POST,
- ATTR_STD_PARTICLE,
- ATTR_STD_NUM,
-
- ATTR_STD_NOT_FOUND = ~0
-} AttributeStandard;
-
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_H__ */
diff --git a/intern/dualcon/SConscript b/intern/dualcon/SConscript
index 481e9ae..34df21a 100644
--- a/intern/dualcon/SConscript
+++ b/intern/dualcon/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript
index 9c035c0..133f02e 100644
--- a/intern/elbeem/SConscript
+++ b/intern/elbeem/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
Import('env')
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index 37cde2c..5492a7b 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -33,6 +33,7 @@
#include <libavcodec/avcodec.h>
#include <libavutil/rational.h>
#include <libavutil/opt.h>
+#include <libavutil/mathematics.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
#define FFMPEG_HAVE_PARSE_UTILS 1
@@ -73,12 +74,68 @@
#if ((LIBAVUTIL_VERSION_MAJOR > 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 32))
#define FFMPEG_FFV1_ALPHA_SUPPORTED
+#else
+static inline
+int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
+{
+ const AVOption *rv = NULL;
+ av_set_string3(obj, name, val, 1, &rv);
+ return rv != NULL;
+}
+
+static inline
+int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
+{
+ const AVOption *rv = NULL;
+ rv = av_set_int(obj, name, val);
+ return rv != NULL;
+}
+
+static inline
+int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
+{
+ const AVOption *rv = NULL;
+ rv = av_set_double(obj, name, val);
+ return rv != NULL;
+}
+
+#define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
+#define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
+#define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
+#define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
+#define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
+#define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
#endif
#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2)))
#define avformat_close_input(x) av_close_input_file(*(x))
#endif
+#if ((LIBAVCODEC_VERSION_MAJOR < 53) || (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 42))
+static inline
+int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
+{
+ /* TODO: no options are taking into account */
+ return avcodec_open(avctx, codec);
+}
+#endif
+
+#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 24))
+static inline
+AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
+{
+ /* TODO: no codec is taking into account */
+ return av_new_stream(s, 0);
+}
+
+static inline
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
+{
+ /* TODO: no options are taking into account */
+ return av_find_stream_info(ic);
+}
+#endif
+
#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && (LIBAVFORMAT_VERSION_MICRO >= 100)))
static inline
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index f886dfd..ab5feb2 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -852,6 +852,16 @@ extern int GHOST_toggleConsole(int action);
*/
extern int GHOST_confirmQuit(GHOST_WindowHandle windowhandle);
+/**
+ * Use native pixel size (MacBook pro 'retina'), if supported.
+ */
+extern int GHOST_UseNativePixels(void);
+
+/**
+ * If window was opened using native pixel size, it returns scaling factor.
+ */
+extern float GHOST_GetNativePixelSize(void);
+
#ifdef __cplusplus
}
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index ad5d237..dfe0152 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -294,6 +294,13 @@ public:
* \return The current status.
*/
virtual bool getFullScreen(void) = 0;
+
+ /**
+ * Native pixel size support (MacBook 'retina').
+ * \return The pixel size in float.
+ */
+ virtual bool useNativePixel(void) = 0;
+ virtual float getNativePixelSize(void) = 0;
/***************************************************************************************
* Event management functionality
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index 44882a6..7e142c4 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
@@ -93,7 +119,7 @@ else:
if env['WITH_BF_3DMOUSE']:
defs.append('WITH_INPUT_NDOF')
- if env['OURPLATFORM']=='linux':
+ if env['OURPLATFORM'] in ('linux','darwin'):
incs += ' ' + env['BF_3DMOUSE_INC']
else:
sources.remove('intern' + os.sep + 'GHOST_NDOFManager.cpp')
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 88d02c4..ba0a6eb 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -878,3 +878,16 @@ int GHOST_confirmQuit(GHOST_WindowHandle windowhandle)
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->confirmQuit((GHOST_IWindow *) windowhandle);
}
+
+int GHOST_UseNativePixels(void)
+{
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->useNativePixel();
+}
+
+float GHOST_GetNativePixelSize(void)
+{
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ return system->getNativePixelSize();
+}
+
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
index d29dd4d..0d009e1 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
@@ -27,7 +27,7 @@
#include "GHOST_SystemCocoa.h"
extern "C" {
- #include <3DconnexionClient/ConnexionClientAPI.h>
+ #include <ConnexionClientAPI.h>
#include <stdio.h>
}
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 8c6491b..41beeac 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -45,7 +45,9 @@
GHOST_System::GHOST_System()
- : m_displayManager(0),
+ : m_nativePixel(false),
+ m_nativePixelSize(1),
+ m_displayManager(0),
m_timerManager(0),
m_windowManager(0),
m_eventManager(0)
@@ -373,3 +375,16 @@ int GHOST_System::confirmQuit(GHOST_IWindow *window) const
{
return 1;
}
+
+bool GHOST_System::useNativePixel(void)
+{
+ m_nativePixel = true;
+ return 1;
+}
+
+float GHOST_System::getNativePixelSize(void)
+{
+ if (m_nativePixel)
+ return m_nativePixelSize;
+ return 1.0f;
+}
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index d2e3377..5060f22 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -167,6 +167,16 @@ public:
*/
virtual bool getFullScreen(void);
+
+ /**
+ * Native pixel size support (MacBook 'retina').
+ * \return The pixel size in float.
+ */
+ virtual bool useNativePixel(void);
+ bool m_nativePixel;
+
+ virtual float getNativePixelSize(void);
+ float m_nativePixelSize;
/***************************************************************************************
* Event management functionality
@@ -350,6 +360,7 @@ protected:
/** Settings of the display before the display went fullscreen. */
GHOST_DisplaySetting m_preFullScreenSetting;
+
};
inline GHOST_TimerManager *GHOST_System::getTimerManager() const
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 9162b7c..a1b372d 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -296,8 +296,6 @@ protected:
/** Multitouch trackpad availability */
bool m_hasMultiTouchTrackpad;
- /** Multitouch gesture in progress, useful to distinguish trackpad from mouse scroll events */
- bool m_isGestureInProgress;
};
#endif // __GHOST_SYSTEMCOCOA_H__
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 16edb4a..ac3e223 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -56,7 +56,7 @@
#include "AssertMacros.h"
#pragma mark KeyMap, mouse converters
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
/* Keycodes not defined in Tiger */
/*
* Summary:
@@ -360,7 +360,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA);
}
else {
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
KeyboardLayoutRef keyLayout;
UCKeyboardLayout *uchrData;
@@ -423,7 +423,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
#pragma mark defines for 10.6 api not documented in 10.5
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
enum {
/* The following event types are available on some hardware on 10.5.2 and later */
NSEventTypeGesture = 29,
@@ -551,7 +551,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
char *rstring = NULL;
m_modifierMask =0;
- m_isGestureInProgress = false;
m_cursorDelta_x=0;
m_cursorDelta_y=0;
m_outsideLoopEventProcessed = false;
@@ -575,13 +574,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
rstring = (char*)malloc( len );
sysctl( mib, 2, rstring, &len, NULL, 0 );
- //Hack on MacBook revision, as multitouch avail. function missing
- //MacbookAir or MacBook version >= 5 (retina is MacBookPro10,1)
- if (strstr(rstring,"MacBookAir") ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')) ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-4]>='1') && (rstring[strlen(rstring)-4]<='9')))
- m_hasMultiTouchTrackpad = true;
- else m_hasMultiTouchTrackpad = false;
+ m_hasMultiTouchTrackpad = false;
free( rstring );
rstring = NULL;
@@ -1058,7 +1051,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
//Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager
pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonUp, window, convertButton(0)));
- m_ignoreWindowSizedMessages = true;
+ //m_ignoreWindowSizedMessages = true;
}
break;
default:
@@ -1446,17 +1439,47 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+enum {
+ NSEventPhaseNone = 0,
+ NSEventPhaseBegan = 0x1 << 0,
+ NSEventPhaseStationary = 0x1 << 1,
+ NSEventPhaseChanged = 0x1 << 2,
+ NSEventPhaseEnded = 0x1 << 3,
+ NSEventPhaseCancelled = 0x1 << 4,
+};
+typedef NSUInteger NSEventPhase;
+
+ at interface NSEvent (AvailableOn1070AndLater)
+- (BOOL)hasPreciseScrollingDeltas;
+- (CGFloat)scrollingDeltaX;
+- (CGFloat)scrollingDeltaY;
+- (NSEventPhase)momentumPhase;
+- (BOOL)isDirectionInvertedFromDevice;
+- (NSEventPhase)phase;
+ at end
+#endif
+
GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
{
NSEvent *event = (NSEvent *)eventPtr;
GHOST_WindowCocoa* window;
+ CocoaWindow *cocoawindow;
+ /* [event window] returns other windows if mouse-over, that's OSX input standard
+ however, if mouse exits window(s), the windows become inactive, until you click.
+ We then fall back to the active window from ghost */
window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
if (!window) {
- //printf("\nW failure for event 0x%x",[event type]);
- return GHOST_kFailure;
+ window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
+ if (!window) {
+ //printf("\nW failure for event 0x%x",[event type]);
+ return GHOST_kFailure;
+ }
}
+ cocoawindow = (CocoaWindow *)window->getOSWindow();
+
switch ([event type]) {
case NSLeftMouseDown:
case NSRightMouseDown:
@@ -1509,7 +1532,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
break;
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
{
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x_mouse= mousePos.x;
GHOST_TInt32 y_mouse= mousePos.y;
GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
@@ -1555,9 +1578,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
default:
{
//Normal cursor operation: send mouse position in window
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
-
+
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
@@ -1569,10 +1592,23 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
}
break;
+ /* these events only happen on swiping trackpads */
+ case NSEventTypeBeginGesture:
+ m_hasMultiTouchTrackpad = 1;
+ break;
+ case NSEventTypeEndGesture:
+ m_hasMultiTouchTrackpad = 0;
+ break;
+
case NSScrollWheel:
{
- /* Send trackpad event if inside a trackpad gesture, send wheel event otherwise */
- if (!m_hasMultiTouchTrackpad || !m_isGestureInProgress) {
+ int *momentum = NULL;
+
+ if ([event respondsToSelector:@selector(momentumPhase)])
+ momentum = (int *)[event momentumPhase];
+
+ /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */
+ if (!m_hasMultiTouchTrackpad && momentum == NULL) {
GHOST_TInt32 delta;
double deltaF = [event deltaY];
@@ -1584,11 +1620,20 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta));
}
else {
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
- double dx = [event deltaX];
- double dy = -[event deltaY];
+ double dx;
+ double dy;
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ /* with 10.7 nice scrolling deltas are supported */
+ dx = [event scrollingDeltaX];
+ dy = [event scrollingDeltaY];
+
+#else
+ /* trying to pretend you have nice scrolls... */
+ dx = [event deltaX];
+ dy = -[event deltaY];
const double deltaMax = 50.0;
if ((dx == 0) && (dy == 0)) break;
@@ -1605,9 +1650,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
else dy += 0.5;
if (dy < -deltaMax) dy= -deltaMax;
else if (dy > deltaMax) dy= deltaMax;
-
- window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
+
dy = -dy;
+#endif
+ window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
}
@@ -1616,7 +1662,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case NSEventTypeMagnify:
{
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventMagnify, x, y,
@@ -1626,18 +1672,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case NSEventTypeRotate:
{
- NSPoint mousePos = [event locationInWindow];
+ NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
GHOST_TInt32 x, y;
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
-[event rotation] * 5.0, 0));
}
- case NSEventTypeBeginGesture:
- m_isGestureInProgress = true;
- break;
- case NSEventTypeEndGesture:
- m_isGestureInProgress = false;
- break;
default:
return GHOST_kFailure;
break;
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 46c71f5..75d606a 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -761,6 +761,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_
if (type == GHOST_kEventWindowActivate) {
system->getWindowManager()->setActiveWindow(window);
+ ((GHOST_WindowWin32*)window)->bringTabletContextToFront();
}
return new GHOST_Event(system->getMilliSeconds(), type, window);
@@ -782,8 +783,8 @@ GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax)
{
- minmax->ptMinTrackSize.x = 320;
- minmax->ptMinTrackSize.y = 240;
+ minmax->ptMinTrackSize.x = 640;
+ minmax->ptMinTrackSize.y = 480;
}
#ifdef WITH_INPUT_NDOF
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 2d3cc4f..f5cb0d9 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -132,7 +132,7 @@ GHOST_SystemX11(
GHOST_ASSERT(false, "Could not instantiate timer!");
}
- /* Taking care not to overflow the tv.tv_sec*1000 */
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
@@ -190,7 +190,7 @@ getMilliSeconds() const
GHOST_ASSERT(false, "Could not compute time!");
}
- /* Taking care not to overflow the tv.tv_sec*1000 */
+ /* Taking care not to overflow the tv.tv_sec * 1000 */
return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
}
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 0523b86..e89dd1b 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -28,7 +28,7 @@
#include <Cocoa/Cocoa.h>
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
//Use of the SetSystemUIMode function (64bit compatible)
#include <Carbon/Carbon.h>
#endif
@@ -58,7 +58,7 @@ extern "C" {
extern void wm_draw_update(bContext *C);
};*/
@interface CocoaWindowDelegate : NSObject
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
<NSWindowDelegate>
#endif
{
@@ -67,13 +67,13 @@ extern "C" {
}
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
-- (void)windowWillClose:(NSNotification *)notification;
- (void)windowDidBecomeKey:(NSNotification *)notification;
- (void)windowDidResignKey:(NSNotification *)notification;
- (void)windowDidExpose:(NSNotification *)notification;
- (void)windowDidResize:(NSNotification *)notification;
- (void)windowDidMove:(NSNotification *)notification;
- (void)windowWillMove:(NSNotification *)notification;
+- (BOOL)windowShouldClose:(id)sender;
@end
@implementation CocoaWindowDelegate : NSObject
@@ -83,11 +83,6 @@ extern "C" {
associatedWindow = winCocoa;
}
-- (void)windowWillClose:(NSNotification *)notification
-{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
-}
-
- (void)windowDidBecomeKey:(NSNotification *)notification
{
systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
@@ -115,12 +110,12 @@ extern "C" {
- (void)windowDidResize:(NSNotification *)notification
{
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//if (![[notification object] inLiveResize]) {
//Send event only once, at end of resize operation (when user has released mouse button)
#endif
systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//}
#endif
/* Live resize ugly patch. Needed because live resize runs in a modal loop, not letting main loop run
@@ -132,6 +127,14 @@ extern "C" {
wm_draw_update(ghostC);
}*/
}
+
+- (BOOL)windowShouldClose:(id)sender;
+{
+ //Let Blender close the window rather than closing immediately
+ systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
+ return false;
+}
+
@end
#pragma mark NSWindow subclass
@@ -287,7 +290,7 @@ extern "C" {
}
}
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
//Cmd+key are handled differently before 10.5
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
@@ -425,6 +428,14 @@ extern "C" {
#pragma mark initialization / finalization
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+ at interface NSView (NSOpenGLSurfaceResolution)
+- (BOOL)wantsBestResolutionOpenGLSurface;
+- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
+- (NSRect)convertRectToBacking:(NSRect)bounds;
+ at end
+#endif
+
NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil;
GHOST_WindowCocoa::GHOST_WindowCocoa(
@@ -470,8 +481,8 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
[m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this];
//Forbid to resize the window below the blender defined minimum one
- minSize.width = 320;
- minSize.height = 240;
+ minSize.width = 640;
+ minSize.height = 480;
[m_window setContentMinSize:minSize];
setTitle(title);
@@ -571,13 +582,20 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
[m_window setContentView:m_openGLView];
[m_window setInitialFirstResponder:m_openGLView];
- [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window
-
[m_window makeKeyAndOrderFront:nil];
setDrawingContextType(type);
updateDrawingContext();
activateDrawingContext();
+
+ if (m_systemCocoa->m_nativePixel) {
+ if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
+ [m_openGLView setWantsBestResolutionOpenGLSurface:YES];
+
+ NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]];
+ m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width;
+ }
+ }
m_tablet.Active = GHOST_kTabletModeNone;
@@ -587,6 +605,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
[m_window setAcceptsMouseMovedEvents:YES];
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+ NSView *view = [m_window contentView];
+ [view setAcceptsTouchEvents:YES];
+#endif
+
[m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
NSStringPboardType, NSTIFFPboardType, nil]];
@@ -609,16 +632,11 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
[m_openGLView release];
if (m_window) {
- // previously we called [m_window release], but on 10.8 this does not
- // remove the window from [NSApp orderedWindows] and perhaps other
- // places, leading to crashes. so instead we set setReleasedWhenClosed
- // back to YES right before closing
- [m_window setReleasedWhenClosed:YES];
[m_window close];
- m_window = nil;
}
- //Check for other blender opened windows and make the frontmost key
+ // Check for other blender opened windows and make the frontmost key
+ // Note: for some reason the closed window is still in the list
NSArray *windowsList = [NSApp orderedWindows];
for (int a = 0; a < [windowsList count]; a++) {
if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) {
@@ -626,6 +644,8 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
break;
}
}
+ m_window = nil;
+
[pool drain];
}
@@ -919,7 +939,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
* doesn't know view/window difference. */
m_fullScreen = true;
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//10.6 provides Cocoa functions to autoshow menu bar, and to change a window style
//Hide menu & dock if needed
if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) {
@@ -946,7 +966,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Copy current window parameters
[tmpWindow setTitle:[m_window title]];
[tmpWindow setRepresentedFilename:[m_window representedFilename]];
- [tmpWindow setReleasedWhenClosed:NO];
[tmpWindow setAcceptsMouseMovedEvents:YES];
[tmpWindow setDelegate:[m_window delegate]];
[tmpWindow setSystemAndWindowCocoa:[m_window systemCocoa] windowCocoa:this];
@@ -978,7 +997,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
m_fullScreen = false;
//Exit fullscreen
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
//Show again menu & dock if needed
if ([[m_window screen] isEqual:[NSScreen mainScreen]]) {
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
@@ -1004,14 +1023,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
//Copy current window parameters
[tmpWindow setTitle:[m_window title]];
[tmpWindow setRepresentedFilename:[m_window representedFilename]];
- [tmpWindow setReleasedWhenClosed:NO];
[tmpWindow setAcceptsMouseMovedEvents:YES];
[tmpWindow setDelegate:[m_window delegate]];
[tmpWindow setSystemAndWindowCocoa:[m_window systemCocoa] windowCocoa:this];
[tmpWindow registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
NSStringPboardType, NSTIFFPboardType, nil]];
//Forbid to resize the window below the blender defined minimum one
- [tmpWindow setContentMinSize:NSMakeSize(320, 240)];
+ [tmpWindow setContentMinSize:NSMakeSize(640, 480)];
//Assign the openGL view to the new window
[tmpWindow setContentView:m_openGLView];
@@ -1224,7 +1242,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
[dockIcon lockFocus];
NSRect progressBox = {{4, 4}, {120, 16}};
- [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0];
+ [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
// Track & Outline
[[NSColor blackColor] setFill];
@@ -1263,7 +1281,7 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
[dockIcon lockFocus];
- [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0];
+ [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
[dockIcon unlockFocus];
[NSApp setApplicationIconImage:dockIcon];
[dockIcon release];
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index fead188..bf42952 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1192,6 +1192,16 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
}
}
+void GHOST_WindowWin32::bringTabletContextToFront()
+{
+ if (m_wintab) {
+ GHOST_WIN32_WTOverlap fpWTOverlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab, "WTOverlap");
+ if (fpWTOverlap) {
+ fpWTOverlap(m_tablet, TRUE);
+ }
+ }
+}
+
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 9e4377b..7f50d58 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -58,6 +58,7 @@ typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
+typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
/**
* GHOST window on M$ Windows OSs.
@@ -273,6 +274,7 @@ public:
void processWin32TabletInitEvent();
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
+ void bringTabletContextToFront();
protected:
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 156bc86..3440e3c 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -363,8 +363,8 @@ GHOST_WindowX11(
xsizehints->y = top;
xsizehints->width = width;
xsizehints->height = height;
- xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
- xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
+ xsizehints->min_width = 640; /* size hints, could be made apart of the ghost api */
+ xsizehints->min_height = 480; /* limits are also arbitrary, but should not allow 1x1 window */
xsizehints->max_width = 65535;
xsizehints->max_height = 65535;
XSetWMNormalHints(m_display, m_window, xsizehints);
diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript
index 74d6e07..0712e1c 100644
--- a/intern/guardedalloc/SConscript
+++ b/intern/guardedalloc/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 4a79f5d..11fa477 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -110,6 +110,18 @@ typedef struct MemHead {
#endif
} MemHead;
+/* for openmp threading asserts, saves time troubleshooting
+ * we may need to extend this if blender code starts using MEM_
+ * functions inside OpenMP correctly with omp_set_lock() */
+
+#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
+#if defined(_OPENMP) && defined(DEBUG)
+# include <assert.h>
+# include <omp.h>
+# define DEBUG_OMP_MALLOC
+#endif
+#endif
+
typedef struct MemTail {
int tag3, pad;
} MemTail;
@@ -194,6 +206,10 @@ static void print_error(const char *str, ...)
static void mem_lock_thread(void)
{
+#ifdef DEBUG_OMP_MALLOC
+ assert(omp_in_parallel() == 0);
+#endif
+
if (thread_lock_callback)
thread_lock_callback();
}
@@ -214,8 +230,7 @@ int MEM_check_memory_integrity(void)
err_val = check_memlist(listend);
- if (err_val == NULL) return 0;
- return 1;
+ return (err_val != NULL);
}
@@ -546,6 +561,8 @@ void MEM_printmemlist_stats(void)
qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
printf("\ntotal memory len: %.3f MB\n",
(double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n",
+ (double)peak_mem / (double)(1024 * 1024));
printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
for (a = 0, pb = printblock; a < totpb; a++, pb++) {
printf("%6d (%8.3f %8.3f) %s\n",
diff --git a/intern/iksolver/SConscript b/intern/iksolver/SConscript
index b88d3b1..ba973ad 100644
--- a/intern/iksolver/SConscript
+++ b/intern/iksolver/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript
index c1ad931..208fee5 100644
--- a/intern/itasc/SConscript
+++ b/intern/itasc/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/intern/itasc/kdl/chain.hpp b/intern/itasc/kdl/chain.hpp
index fde9d4e..1776737 100644
--- a/intern/itasc/kdl/chain.hpp
+++ b/intern/itasc/kdl/chain.hpp
@@ -36,7 +36,7 @@ namespace KDL {
class Chain {
private:
#if defined(__APPLE__)
-# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
std::vector<Segment> segments;
# else
// Eigen allocator is needed for alignment of Eigen data types
diff --git a/intern/itasc/kdl/tree.hpp b/intern/itasc/kdl/tree.hpp
index a020c6c..82794f9 100644
--- a/intern/itasc/kdl/tree.hpp
+++ b/intern/itasc/kdl/tree.hpp
@@ -28,7 +28,7 @@
#include <string>
#include <map>
#if defined(__APPLE__)
-# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
//no include
# else
# include <Eigen/Core>
@@ -42,7 +42,7 @@ namespace KDL
//Forward declaration
class TreeElement;
#if defined(__APPLE__)
-# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
typedef std::map<std::string,TreeElement> SegmentMap;
# else
// Eigen allocator is needed for alignment of Eigen data types
diff --git a/intern/locale/SConscript b/intern/locale/SConscript
index df745f0..f60bd90 100644
--- a/intern/locale/SConscript
+++ b/intern/locale/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2012, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Bastien Montagne.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
index 939c66b..80e7529 100644
--- a/intern/locale/boost_locale_wrapper.cpp
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -55,44 +55,49 @@ void bl_locale_set(const char *locale)
// Specify location of dictionaries.
gen.add_messages_path(messages_path);
gen.add_messages_domain(default_domain);
- //gen.set_default_messages_domain(default_domain);
+ //gen.set_default_messages_domain(default_domain);
- if (locale && locale[0]) {
- std::locale::global(gen(locale));
- }
- else {
-#if defined (__APPLE__)
- // workaround to get osx system locale from user defaults
- FILE* fp;
- std::string locale_osx = "";
- char result[16];
- int result_len = 0;
+ try {
+ if (locale && locale[0]) {
+ std::locale::global(gen(locale));
+ }
+ else {
+#ifdef __APPLE__
+ // workaround to get osx system locale from user defaults
+ FILE *fp;
+ std::string locale_osx = "";
+ char result[16];
+ int result_len = 0;
- fp = popen("defaults read .GlobalPreferences AppleLocale", "r");
+ fp = popen("defaults read .GlobalPreferences AppleLocale", "r");
- if(fp) {
- result_len = fread(result, 1, sizeof(result) - 1, fp);
+ if (fp) {
+ result_len = fread(result, 1, sizeof(result) - 1, fp);
- if(result_len > 0) {
- result[result_len-1] = '\0'; // \0 terminate and remove \n
- locale_osx = std::string(result) + std::string(".UTF-8");
- }
+ if (result_len > 0) {
+ result[result_len - 1] = '\0'; // \0 terminate and remove \n
+ locale_osx = std::string(result) + std::string(".UTF-8");
+ }
- pclose(fp);
- }
+ pclose(fp);
+ }
- if(locale_osx == "")
- fprintf(stderr, "Locale set: failed to read AppleLocale read from defaults\n");
+ if (locale_osx == "")
+ fprintf(stderr, "Locale set: failed to read AppleLocale read from defaults\n");
- std::locale::global(gen(locale_osx.c_str()));
+ std::locale::global(gen(locale_osx.c_str()));
#else
- std::locale::global(gen(""));
+ std::locale::global(gen(""));
#endif
+ }
+ // Note: boost always uses "C" LC_NUMERIC by default!
+ }
+ catch(std::exception const &e) {
+ std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
}
- // Note: boost always uses "C" LC_NUMERIC by default!
}
-const char* bl_locale_pgettext(const char *msgctxt, const char *msgid)
+const char *bl_locale_pgettext(const char *msgctxt, const char *msgid)
{
// Note: We cannot use short stuff like boost::locale::gettext, because those return
// std::basic_string objects, which c_ptr()-returned char* is no more valid
@@ -107,7 +112,7 @@ const char* bl_locale_pgettext(const char *msgctxt, const char *msgid)
return msgid;
}
catch(std::exception const &e) {
-// std::cout << "boost_locale_pgettext: " << e.what() << " \n";
+// std::cout << "bl_locale_pgettext(" << msgctxt << ", " << msgid << "): " << e.what() << " \n";
return msgid;
}
}
diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript
index c9a0398..95fa39e 100644
--- a/intern/memutil/SConscript
+++ b/intern/memutil/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/mikktspace/SConscript b/intern/mikktspace/SConscript
index 8f31f21..fcb257a 100644
--- a/intern/mikktspace/SConscript
+++ b/intern/mikktspace/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = ['mikktspace.c']
diff --git a/intern/moto/SConscript b/intern/moto/SConscript
index ba257a3..34a0afe 100644
--- a/intern/moto/SConscript
+++ b/intern/moto/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript
index a4d21f3..6e7c467 100644
--- a/intern/opencolorio/SConscript
+++ b/intern/opencolorio/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2012, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Sergey Sharybin.
+#
+# ***** END GPL LICENSE BLOCK *****
Import('env')
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 44c02d1..d01d8d4 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -331,7 +331,7 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *)
}
OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 18fa4b7..4f839a6 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -238,12 +238,12 @@ void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
}
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
}
-void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
{
impl->OCIO_PackedImageDescRelease(id);
}
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 0ce5f8a..19fd8fe 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -105,9 +105,9 @@ void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_Const
void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes);
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes);
-void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
+void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void);
void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 2d73d2f..b073a03 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -479,7 +479,7 @@ void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
}
OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
try {
void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
diff --git a/intern/opennl/SConscript b/intern/opennl/SConscript
index a0f0273..f47dd56 100644
--- a/intern/opennl/SConscript
+++ b/intern/opennl/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c')
diff --git a/intern/raskter/SConscript b/intern/raskter/SConscript
index 7ad505d..c7bf647 100644
--- a/intern/raskter/SConscript
+++ b/intern/raskter/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2012, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Peter Larabell
+#
+# ***** END GPL LICENSE BLOCK *****
Import ('env')
diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt
index 3b8a4c0..b6338f9 100644
--- a/intern/smoke/CMakeLists.txt
+++ b/intern/smoke/CMakeLists.txt
@@ -29,7 +29,7 @@ set(INC
)
set(INC_SYS
- ../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
${PNG_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
)
diff --git a/intern/smoke/SConscript b/intern/smoke/SConscript
index 0511257..c4a579b 100644
--- a/intern/smoke/SConscript
+++ b/intern/smoke/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/string/SConscript b/intern/string/SConscript
index dac0ead..8e14605 100644
--- a/intern/string/SConscript
+++ b/intern/string/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.cpp')
diff --git a/intern/tools/bpy_introspect_ui.py b/intern/tools/bpy_introspect_ui.py
index 6fc22e8..d0c0506 100644
--- a/intern/tools/bpy_introspect_ui.py
+++ b/intern/tools/bpy_introspect_ui.py
@@ -37,7 +37,7 @@ def module_add(name):
return mod
-class AttributeBuilder(object):
+class AttributeBuilder:
"""__slots__ = (
"_attr", "_attr_list", "_item_set", "_args",
"active", "operator_context", "enabled", "index", "data"
@@ -294,7 +294,8 @@ def fake_runtime():
bpy.utils = module_add("bpy.utils")
bpy.utils.smpte_from_frame = lambda f: ""
- bpy.utils.script_paths = lambda f: []
+ bpy.utils.script_paths = lambda f: ()
+ bpy.utils.user_resource = lambda a, b: ()
bpy.app = module_add("bpy.app")
bpy.app.debug = False
diff --git a/intern/tools/credits_svn_gen.py b/intern/tools/credits_svn_gen.py
index b64cb5d..48cc8fe 100755
--- a/intern/tools/credits_svn_gen.py
+++ b/intern/tools/credits_svn_gen.py
@@ -58,7 +58,7 @@ Example execution commands:
# Generic Class and parsing code, could be useful for all sorts of cases
-class SvnCommit(object):
+class SvnCommit:
"""Just data store really"""
__slots__ = ("revision",
"author",
@@ -125,7 +125,7 @@ contrib_companies = [
"<b>Unity Technologies</b> - FBX Exporter",
"<b>BioSkill GmbH</b> - H3D compatibility for X3D Exporter, "
"OBJ Nurbs Import/Export",
- "<b>AutoCRC</b> - Improvements to fluid particles",
+ "<b>AutoCRC</b> - Improvements to fluid particles, vertex color baking",
]
# ignore commits containing these messages
@@ -166,6 +166,8 @@ author_name_mapping = {
"campbellbarton": "Campbell Barton",
"cessen": "Nathan Vegdahl",
"cmccad": "Casey Corn",
+ "cyborgmuppet": "Ove Murberg Henriksen",
+ "dail": "Justin Dailey",
"damien78": "Damien Plisson",
"damir": "Damir Prebeg",
"desoto": "Chris Burt",
@@ -282,7 +284,7 @@ author_name_mapping = {
# --------------------
# Extension Developers
- "aurel": "Aurel W", # TODO, full name?
+ "aurel": "Aurel Wildfellner",
"axon_d": "Dany Lebel",
"bartekskorupa": "Bartek Skorupa",
"bassamk": "Bassam Kurdali",
@@ -315,6 +317,7 @@ author_name_mapping = {
"michaelw": "Michael Williamson",
"muraj": "Cory Perry",
"paulo_gomes": "Paulo Gomes",
+ "plasmasolutions": "Thomas Beck",
"pontiac": "Martin Buerbaum",
"seminumerical": "Morgan Mörtsell",
"spudmn": "Aaron Keith",
@@ -350,6 +353,8 @@ alert_users = set()
author_overrides_bfb = {
"farny": (43567, 44698),
"damir": (37043, 40311, 44550, 45295),
+ "plasmasolutions": (52074, ),
+ "lichtwerk": (51650, 51850, 51861),
}
author_overrides_ext = {
@@ -514,7 +519,7 @@ def main_credits(min_rev_bfb=0, min_rev_ext=0):
credits = {key: Credit() for key in author_name_mapping}
def commit_to_credit(commits, author_overrides):
- print(len(commits))
+ # print(len(commits))
author_overrides_reverse = {
revision: author
for author, revisions in author_overrides.items()
@@ -574,7 +579,7 @@ def main_credits(min_rev_bfb=0, min_rev_ext=0):
# write out the wiki page
# sort by name
is_main_credits = (min_rev_bfb == 0 and min_rev_ext == 0)
- print(min_rev_bfb, min_rev_ext)
+ # print(min_rev_bfb, min_rev_ext)
if is_main_credits:
filename = "credits.html"
else:
@@ -656,7 +661,7 @@ def main_credits(min_rev_bfb=0, min_rev_ext=0):
def main():
main_credits()
- main_credits(min_rev_bfb=46461, min_rev_ext=3355)
+ main_credits(min_rev_bfb=51024, min_rev_ext=3808)
if __name__ == "__main__":
main()
diff --git a/intern/utfconv/SConscript b/intern/utfconv/SConscript
index 19a698b..875f615 100644
--- a/intern/utfconv/SConscript
+++ b/intern/utfconv/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = ['utfconv.c']
diff --git a/release/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist
index 064ffe5..ecea0e3 100644
--- a/release/darwin/blender.app/Contents/Info.plist
+++ b/release/darwin/blender.app/Contents/Info.plist
@@ -50,5 +50,7 @@
</dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
</dict>
</plist>
diff --git a/release/darwin/blender.app/Contents/MacOS/blender b/release/darwin/blender.app/Contents/MacOS/blender
index 5e05e74..48cdce8 100644
--- a/release/darwin/blender.app/Contents/MacOS/blender
+++ b/release/darwin/blender.app/Contents/MacOS/blender
@@ -1 +1 @@
-placeholder
+placeholder
diff --git a/release/darwin/blenderplayer.app/Contents/Info.plist b/release/darwin/blenderplayer.app/Contents/Info.plist
index c7b9ceb..91eb2d7 100644
--- a/release/darwin/blenderplayer.app/Contents/Info.plist
+++ b/release/darwin/blenderplayer.app/Contents/Info.plist
@@ -45,5 +45,7 @@
</array>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
</dict>
</plist>
diff --git a/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
index 5e05e74..48cdce8 100644
--- a/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
+++ b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
@@ -1 +1 @@
-placeholder
+placeholder
diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png
deleted file mode 100644
index b0d5e82..0000000
Binary files a/release/datafiles/blender_icons.png and /dev/null differ
diff --git a/release/datafiles/blender_icons.sh b/release/datafiles/blender_icons.sh
new file mode 100755
index 0000000..f923f02
--- /dev/null
+++ b/release/datafiles/blender_icons.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# This script updates icons from the SVG file
+
+inkscape blender_icons.svg --export-dpi=90 --without-gui --export-png=blender_icons16.png
+inkscape blender_icons.svg --export-dpi=180 --without-gui --export-png=blender_icons32.png
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
new file mode 100644
index 0000000..fcade5b
--- /dev/null
+++ b/release/datafiles/blender_icons.svg
@@ -0,0 +1,79040 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="602"
+ height="640"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.3.1 r9886"
+ version="1.0"
+ sodipodi:docname="blender_icons.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="/home/wolter/Documenten/Blender/icons/D:\Documents\Blender\icons\BF icons v.2.5.08a.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <title
+ id="title49470">Blender icons v. 2.5.08</title>
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30139">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop30141" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop30143" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30131">
+ <stop
+ style="stop-color:#999999;stop-opacity:1;"
+ offset="0"
+ id="stop30133" />
+ <stop
+ style="stop-color:#999999;stop-opacity:0;"
+ offset="1"
+ id="stop30135" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30122">
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:1;"
+ offset="0"
+ id="stop30124" />
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:0;"
+ offset="1"
+ id="stop30127" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30390">
+ <stop
+ style="stop-color:#363636;stop-opacity:1;"
+ offset="0"
+ id="stop30392" />
+ <stop
+ style="stop-color:#4f4f4f;stop-opacity:1;"
+ offset="1"
+ id="stop30394" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29870">
+ <stop
+ id="stop29872"
+ offset="0"
+ style="stop-color:#989898;stop-opacity:1" />
+ <stop
+ id="stop29874"
+ offset="1"
+ style="stop-color:#3d3d3d;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29757">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29759" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29761" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16772">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16774" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16776" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16764">
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:1;"
+ offset="0"
+ id="stop16766" />
+ <stop
+ style="stop-color:#1e1e1e;stop-opacity:0;"
+ offset="1"
+ id="stop16768" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16723">
+ <stop
+ style="stop-color:#343434;stop-opacity:0.61960787;"
+ offset="0"
+ id="stop16725" />
+ <stop
+ style="stop-color:#3d3d3d;stop-opacity:1;"
+ offset="1"
+ id="stop16727" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient107519">
+ <stop
+ style="stop-color:#f8c5bd;stop-opacity:1"
+ offset="0"
+ id="stop107521" />
+ <stop
+ style="stop-color:#a42f0e;stop-opacity:1"
+ offset="1"
+ id="stop107523" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient107148">
+ <stop
+ id="stop107150"
+ offset="0"
+ style="stop-color:#ee7b68;stop-opacity:1" />
+ <stop
+ id="stop107152"
+ offset="1"
+ style="stop-color:#a42f0e;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient107142">
+ <stop
+ id="stop107144"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop107146"
+ offset="1"
+ style="stop-color:#f18d73;stop-opacity:0.2079646" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient106427">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop106429" />
+ <stop
+ style="stop-color:#030303;stop-opacity:1"
+ offset="1"
+ id="stop106431" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16504">
+ <stop
+ id="stop16506"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop16508"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17602">
+ <stop
+ id="stop17604"
+ offset="0"
+ style="stop-color:#592e00;stop-opacity:1" />
+ <stop
+ id="stop17606"
+ offset="1"
+ style="stop-color:#9e5200;stop-opacity:0.57431373" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17596">
+ <stop
+ style="stop-color:#ee7b00;stop-opacity:1"
+ offset="0"
+ id="stop17598" />
+ <stop
+ style="stop-color:#ffc280;stop-opacity:1"
+ offset="1"
+ id="stop17600" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17438">
+ <stop
+ style="stop-color:#ff9f37;stop-opacity:1"
+ offset="0"
+ id="stop17440" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop17442" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17430">
+ <stop
+ style="stop-color:#ff9f37;stop-opacity:1"
+ offset="0"
+ id="stop17432" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop17434" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30958">
+ <stop
+ id="stop30960"
+ offset="0"
+ style="stop-color:#fff9cf;stop-opacity:1;" />
+ <stop
+ id="stop30962"
+ offset="1"
+ style="stop-color:#c7bc52;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29312">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29314" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29316" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29304">
+ <stop
+ style="stop-color:#11233f;stop-opacity:1;"
+ offset="0"
+ id="stop29306" />
+ <stop
+ style="stop-color:#162d50;stop-opacity:0;"
+ offset="1"
+ id="stop29308" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27896">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27898" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27900" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27854">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27856" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27858" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24343">
+ <stop
+ id="stop24345"
+ offset="0"
+ style="stop-color:#184990;stop-opacity:1;" />
+ <stop
+ id="stop24347"
+ offset="1"
+ style="stop-color:#c1d5f3;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25417">
+ <stop
+ id="stop25419"
+ offset="0"
+ style="stop-color:#60553b;stop-opacity:1;" />
+ <stop
+ id="stop25421"
+ offset="1"
+ style="stop-color:#b0a17f;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25108">
+ <stop
+ id="stop25110"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop25112"
+ offset="1"
+ style="stop-color:#c6c6c6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient43807">
+ <stop
+ style="stop-color:#e31b1b;stop-opacity:1;"
+ offset="0"
+ id="stop43809" />
+ <stop
+ style="stop-color:#930000;stop-opacity:1;"
+ offset="1"
+ id="stop43811" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient38845">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38847" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38849" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38831">
+ <stop
+ style="stop-color:#182b42;stop-opacity:1;"
+ offset="0"
+ id="stop38833" />
+ <stop
+ id="stop38836"
+ offset="0.38971797"
+ style="stop-color:#598ac7;stop-opacity:1;" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1;"
+ offset="1"
+ id="stop38838" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38256">
+ <stop
+ id="stop38258"
+ offset="0"
+ style="stop-color:#e7e0c7;stop-opacity:1;" />
+ <stop
+ id="stop38260"
+ offset="1"
+ style="stop-color:#f1eddf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient71814">
+ <stop
+ style="stop-color:#6e0d00;stop-opacity:1;"
+ offset="0"
+ id="stop71816" />
+ <stop
+ style="stop-color:#6f2913;stop-opacity:0;"
+ offset="1"
+ id="stop71818" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37667">
+ <stop
+ id="stop37669"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop37671"
+ offset="1"
+ style="stop-color:black;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39080">
+ <stop
+ style="stop-color:#1a2a3d;stop-opacity:1;"
+ offset="0"
+ id="stop39082" />
+ <stop
+ id="stop39084"
+ offset="0.5"
+ style="stop-color:#95b0d1;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop39086" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40703">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37925">
+ <stop
+ id="stop37927"
+ offset="0"
+ style="stop-color:#e7cbab;stop-opacity:1;" />
+ <stop
+ id="stop37929"
+ offset="1"
+ style="stop-color:#af7333;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient36273">
+ <stop
+ id="stop36275"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35411">
+ <stop
+ id="stop35414"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31356">
+ <stop
+ id="stop31358"
+ offset="0"
+ style="stop-color:#1a1a1a;stop-opacity:1" />
+ <stop
+ id="stop31360"
+ offset="1"
+ style="stop-color:#1a1a1a;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient28107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7228842,8.5733105e-8,-9.4831885e-8,0.7995973,71.917045,14.582004)"
+ cx="256.49512"
+ cy="81.396774"
+ fx="256.49512"
+ fy="81.396774"
+ r="3.779551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28105"
+ gradientUnits="userSpaceOnUse"
+ x1="875.73486"
+ y1="422.77902"
+ x2="885.04938"
+ y2="427.01648" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28887"
+ id="linearGradient28103"
+ gradientUnits="userSpaceOnUse"
+ x1="873.09998"
+ y1="422.09964"
+ x2="881.01172"
+ y2="429.23453" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28101"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.6572588,1.2500456,-1.6473175,2.2058465,774.83033,-697.31982)"
+ cx="76.180473"
+ cy="500.20651"
+ fx="76.180473"
+ fy="500.20651"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28099"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient28887">
+ <stop
+ style="stop-color:#2158a7;stop-opacity:1;"
+ offset="0"
+ id="stop28889" />
+ <stop
+ style="stop-color:#2f73d5;stop-opacity:0.19607843;"
+ offset="1"
+ id="stop28891" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24168">
+ <stop
+ id="stop24170"
+ offset="0"
+ style="stop-color:#182437;stop-opacity:1;" />
+ <stop
+ id="stop24172"
+ offset="1"
+ style="stop-color:#2b4163;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24144">
+ <stop
+ id="stop24146"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.17958513"
+ id="stop24148" />
+ <stop
+ id="stop24150"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24101">
+ <stop
+ style="stop-color:#643400;stop-opacity:1;"
+ offset="0"
+ id="stop24103" />
+ <stop
+ id="stop24105"
+ offset="0.22606115"
+ style="stop-color:#ed983d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#fff0d5;stop-opacity:1;"
+ offset="1"
+ id="stop24107" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24081">
+ <stop
+ id="stop24083"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.3167825"
+ id="stop24085" />
+ <stop
+ id="stop24087"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23302">
+ <stop
+ id="stop23304"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.39332664"
+ id="stop23306" />
+ <stop
+ id="stop23308"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24735">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop24737" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop24739" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24727">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24729" />
+ <stop
+ id="stop24731"
+ offset="0.77520341"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24733" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24711">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24713" />
+ <stop
+ id="stop24715"
+ offset="0.21609697"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24717" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24695">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24697" />
+ <stop
+ id="stop24699"
+ offset="0.60401857"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24701" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24687">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24689" />
+ <stop
+ id="stop24691"
+ offset="0.59630167"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24693" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681" />
+ <stop
+ id="stop24683"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24671">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24673" />
+ <stop
+ id="stop24675"
+ offset="0.29527253"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24677" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23705">
+ <stop
+ id="stop23707"
+ offset="0"
+ style="stop-color:#d4d2bf;stop-opacity:1;" />
+ <stop
+ id="stop23709"
+ offset="1"
+ style="stop-color:#857f5d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23906">
+ <stop
+ id="stop23908"
+ offset="0"
+ style="stop-color:#ff921d;stop-opacity:1;" />
+ <stop
+ id="stop23910"
+ offset="1"
+ style="stop-color:#ffa751;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42459">
+ <stop
+ style="stop-color:#e7dfab;stop-opacity:1;"
+ offset="0"
+ id="stop42461" />
+ <stop
+ style="stop-color:#af9d33;stop-opacity:1;"
+ offset="1"
+ id="stop42463" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287"
+ y1="-276.1875"
+ x2="-281.4375"
+ y2="-271.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="171.42436"
+ y1="259.71194"
+ x2="170.20523"
+ y2="244.96393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24246"
+ gradientUnits="userSpaceOnUse"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(186,-105)"
+ x1="246.12868"
+ y1="283.63254"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287.56247"
+ y1="-276.71042"
+ x2="-282.59851"
+ y2="-271.35284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient24276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="190.33647"
+ y1="266.7905"
+ x2="170.9689"
+ y2="247.58694" />
+ <linearGradient
+ id="linearGradient24143">
+ <stop
+ id="stop24145"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669" />
+ <stop
+ id="stop24147"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24687"
+ id="linearGradient24238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,304.84783,-86.57833)"
+ x1="120.2969"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ id="linearGradient24642">
+ <stop
+ style="stop-color:#d0dbe8;stop-opacity:1;"
+ offset="0"
+ id="stop24644" />
+ <stop
+ style="stop-color:#6ca3e9;stop-opacity:0;"
+ offset="1"
+ id="stop24646" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24632">
+ <stop
+ style="stop-color:#28394f;stop-opacity:1;"
+ offset="0"
+ id="stop24634" />
+ <stop
+ id="stop24636"
+ offset="0.17637014"
+ style="stop-color:#0d386a;stop-opacity:0.78431374;" />
+ <stop
+ id="stop24638"
+ offset="0.35274029"
+ style="stop-color:#18437d;stop-opacity:0.47058824;" />
+ <stop
+ style="stop-color:#154e94;stop-opacity:0;"
+ offset="1"
+ id="stop24640" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="radialGradient23167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9934369,-0.1143813,0.1033636,0.8977446,-30.451879,30.134649)"
+ cx="-0.10810681"
+ cy="294.60239"
+ fx="-0.10810681"
+ fy="294.60239"
+ r="6.6750002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23201"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-61,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.25"
+ y2="245" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.5"
+ y2="245" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23189">
+ <g
+ transform="translate(-28,49)"
+ id="g23193">
+ <rect
+ y="237"
+ x="22"
+ height="16"
+ width="9"
+ id="rect23195"
+ style="fill:url(#linearGradient23199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ style="fill:url(#linearGradient23201);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23197"
+ width="9"
+ height="16"
+ x="-38"
+ y="237" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24206"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23379"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient23377"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient23375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="52.06274"
+ y1="96.767769"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient23373"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ id="linearGradient23974">
+ <stop
+ id="stop23976"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40983">
+ <stop
+ style="stop-color:#6a9ae0;stop-opacity:1;"
+ offset="0"
+ id="stop40985" />
+ <stop
+ style="stop-color:#5189db;stop-opacity:0;"
+ offset="1"
+ id="stop40987" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23280"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23278"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient23276"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient23274"
+ gradientUnits="userSpaceOnUse"
+ x1="144.8255"
+ y1="132.15414"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ id="linearGradient30777"
+ inkscape:collect="always">
+ <stop
+ id="stop30779"
+ offset="0"
+ style="stop-color:#acacac;stop-opacity:1" />
+ <stop
+ id="stop30781"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29485">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop29487" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop29489" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.55821538"
+ width="2.1164308"
+ y="-1.0219563"
+ height="3.0439126"
+ id="filter20578"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="2.0410255"
+ id="feGaussianBlur20580" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath20586">
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34889"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ transform="matrix(1.870472,0.1894819,-0.6587894,2.4281336,319.59052,-798.11661)" />
+ </clipPath>
+ <radialGradient
+ id="aigrd2"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop15566" />
+ <stop
+ offset="1.0000000"
+ style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
+ id="stop15568" />
+ </radialGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106">
+ <path
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient58334">
+ <stop
+ id="stop58336"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8864">
+ <stop
+ id="stop8866"
+ offset="0"
+ style="stop-color:#b43214;stop-opacity:1;" />
+ <stop
+ id="stop8868"
+ offset="1"
+ style="stop-color:#e86830;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20324">
+ <stop
+ id="stop20326"
+ offset="0"
+ style="stop-color:#35241b;stop-opacity:1;" />
+ <stop
+ style="stop-color:#69390e;stop-opacity:0.8392157;"
+ offset="0.17637014"
+ id="stop20328" />
+ <stop
+ style="stop-color:#6c5b15;stop-opacity:0.67843139;"
+ offset="0.35274029"
+ id="stop20330" />
+ <stop
+ id="stop20332"
+ offset="1"
+ style="stop-color:#947b15;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37623">
+ <stop
+ id="stop37625"
+ offset="0"
+ style="stop-color:#e5e1ca;stop-opacity:1;" />
+ <stop
+ id="stop37627"
+ offset="1"
+ style="stop-color:#d6ca22;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient36116">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop36118" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop36120" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22852"
+ gradientUnits="userSpaceOnUse"
+ x1="133.94305"
+ y1="116.00471"
+ x2="117.29694"
+ y2="133.14267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22850"
+ gradientUnits="userSpaceOnUse"
+ x1="136.55727"
+ y1="125.87247"
+ x2="129.70895"
+ y2="118.00132" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22844"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ id="linearGradient22562">
+ <stop
+ style="stop-color:#001e50;stop-opacity:1;"
+ offset="0"
+ id="stop22564" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop22566" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient22842"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ id="linearGradient22556">
+ <stop
+ id="stop22558"
+ offset="0"
+ style="stop-color:#6a9bef;stop-opacity:1" />
+ <stop
+ style="stop-color:#bccee8;stop-opacity:0.58450705;"
+ offset="0.77941167"
+ id="stop22568" />
+ <stop
+ id="stop22560"
+ offset="1"
+ style="stop-color:#ccdaed;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22556"
+ id="linearGradient22840"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient22838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient22882">
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="0"
+ id="stop22884" />
+ <stop
+ id="stop22886"
+ offset="0.21233012"
+ style="stop-color:#323232;stop-opacity:0.49803922;" />
+ <stop
+ id="stop22888"
+ offset="0.54086536"
+ style="stop-color:#323232;stop-opacity:1;" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0.49803922;"
+ offset="0.83381736"
+ id="stop22890" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop22892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22880"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ id="linearGradient35407">
+ <stop
+ id="stop35409"
+ offset="0"
+ style="stop-color:#a17306;stop-opacity:1;" />
+ <stop
+ style="stop-color:#cca649;stop-opacity:1;"
+ offset="0.43277758"
+ id="stop35411" />
+ <stop
+ id="stop35413"
+ offset="1"
+ style="stop-color:#f9f5e9;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35391">
+ <stop
+ id="stop35393"
+ offset="0"
+ style="stop-color:#322800;stop-opacity:1;" />
+ <stop
+ id="stop35395"
+ offset="1"
+ style="stop-color:#6e4800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient34157">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop34159" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop34161" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient22457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-25.5"
+ y1="36.828632"
+ x2="-25.5"
+ y2="26.027344" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22455"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-354,-314.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22453"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-27.299919"
+ y1="37"
+ x2="-25.5"
+ y2="23.414351" />
+ <linearGradient
+ id="linearGradient21609">
+ <stop
+ id="stop21611"
+ offset="0"
+ style="stop-color:black;stop-opacity:1" />
+ <stop
+ id="stop21613"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21609"
+ id="linearGradient20961"
+ gradientUnits="userSpaceOnUse"
+ x1="162"
+ y1="103.71875"
+ x2="165"
+ y2="103.75" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask20957">
+ <rect
+ y="101"
+ x="162"
+ height="5"
+ width="8"
+ id="rect20959"
+ style="fill:url(#linearGradient20961);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32335"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <filter
+ inkscape:collect="always"
+ id="filter23214"
+ x="-0.48015866"
+ width="1.9603173"
+ y="-0.47984189"
+ height="1.9596838"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.53351805"
+ id="feGaussianBlur23216" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient19900">
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:1;"
+ offset="0"
+ id="stop19902" />
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:0;"
+ offset="1"
+ id="stop19904" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18105">
+ <stop
+ id="stop18107"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18056">
+ <stop
+ id="stop18058"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18060"
+ offset="1"
+ style="stop-color:#295498;stop-opacity:0.34057972;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19625">
+ <stop
+ id="stop19627"
+ offset="0"
+ style="stop-color:#2258a6;stop-opacity:1;" />
+ <stop
+ id="stop19629"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient20217"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient18821">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient29149">
+ <stop
+ id="stop29151"
+ offset="0"
+ style="stop-color:#76adff;stop-opacity:1;" />
+ <stop
+ id="stop29153"
+ offset="1"
+ style="stop-color:#a5c9ff;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient21820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient21818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21816"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21814"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient21741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient21773"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9281768,0,0,0.9971589,401.42265,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22166"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22164"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22162"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22160"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22158"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient22156"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22154"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15809">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15811" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop15813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15437">
+ <stop
+ id="stop15439"
+ offset="0"
+ style="stop-color:#20529e;stop-opacity:1;" />
+ <stop
+ id="stop15441"
+ offset="1"
+ style="stop-color:#1d3f71;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15425">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14262">
+ <stop
+ id="stop14264"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath17188">
+ <path
+ style="fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 240.5,-19.90625 c -1.87005,0 -3.40625,1.536202 -3.40625,3.40625 l 0,2 c 0,1.87005 1.53621,3.40625 3.40625,3.40625 l 0,-2.8125 c -0.33932,0 -0.59375,-0.254431 -0.59375,-0.59375 l 0,-2 c 0,-0.339319 0.25443,-0.59375 0.59375,-0.59375 l 0,-2.8125 z"
+ id="path17190" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient18344">
+ <stop
+ style="stop-color:#6c6c6c;stop-opacity:1;"
+ offset="0"
+ id="stop18346" />
+ <stop
+ style="stop-color:#f0f0f0;stop-opacity:1;"
+ offset="1"
+ id="stop18348" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060">
+ <stop
+ id="stop5062"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient27957">
+ <stop
+ id="stop27959"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0.59290552"
+ id="stop27963" />
+ <stop
+ id="stop27961"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23647">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop23649" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop23651" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23390">
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000"
+ offset="0.0000000"
+ id="stop23392" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000"
+ offset="1.0000000"
+ id="stop23400" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16359">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16361" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16363" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.26,-38.98429)"
+ x1="386.09836"
+ y1="230.09529"
+ x2="388.35962"
+ y2="248.10277" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15744"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="390.61163"
+ y1="229.34804"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.203777,0,0,0.903901,837.9645,-18.01568)"
+ x1="383.67041"
+ y1="225.94354"
+ x2="385.60632"
+ y2="248.55901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15681"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,839.2424,-18.01568)"
+ x1="391.80222"
+ y1="230.5647"
+ x2="387.94211"
+ y2="247.83209" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13545"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="137.11284"
+ y2="126.19643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15878"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient20756">
+ <stop
+ style="stop-color:#932200;stop-opacity:1;"
+ offset="0"
+ id="stop20758" />
+ <stop
+ style="stop-color:#f8420a;stop-opacity:1;"
+ offset="1"
+ id="stop20760" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient13543"
+ gradientUnits="userSpaceOnUse"
+ x1="126.45676"
+ y1="110.59049"
+ x2="134.94949"
+ y2="122.08995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15693"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="215.07817"
+ y1="109.00085"
+ x2="235.90916"
+ y2="121.88217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="217.22589"
+ y1="107.25085"
+ x2="235.90916"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15854"
+ gradientUnits="userSpaceOnUse"
+ x1="381.56296"
+ y1="234.59885"
+ x2="393"
+ y2="247.99632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient13639"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.987"
+ y1="259.26602"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52023"
+ gradientUnits="userSpaceOnUse"
+ x1="390.75"
+ y1="244.5312"
+ x2="395.9375"
+ y2="250.9062" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient14661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="400.88739"
+ y1="257.4874"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52025"
+ gradientUnits="userSpaceOnUse"
+ x1="391.01859"
+ y1="241.86644"
+ x2="396.79285"
+ y2="247.83134" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient15995"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.08661"
+ y1="257.41327"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15993"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15997"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ id="linearGradient47130">
+ <stop
+ style="stop-color:#ed7b00;stop-opacity:1;"
+ offset="0"
+ id="stop47132" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop47134" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52027"
+ gradientUnits="userSpaceOnUse"
+ x1="329.28757"
+ y1="244.97151"
+ x2="339.84518"
+ y2="254.18553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15436"
+ gradientUnits="userSpaceOnUse"
+ x1="319.75095"
+ y1="234.63918"
+ x2="333.94208"
+ y2="248.68198" />
+ <linearGradient
+ id="linearGradient32842">
+ <stop
+ style="stop-color:#183e75;stop-opacity:1;"
+ offset="0"
+ id="stop32844" />
+ <stop
+ style="stop-color:#1d3f71;stop-opacity:0;"
+ offset="1"
+ id="stop32846" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient13900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2541045,-1.3755453,0.900369,1.4754358,-3699.4512,2858.7)"
+ cx="2357.1072"
+ cy="826.77924"
+ fx="2357.1072"
+ fy="826.77924"
+ r="6.1896501" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40983"
+ id="linearGradient38692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2226.9963,823)"
+ x1="130.70599"
+ y1="18.44199"
+ x2="130.70599"
+ y2="21.94199" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15717"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15715"
+ gradientUnits="userSpaceOnUse"
+ x1="320.2735"
+ y1="25.109356"
+ x2="332.41409"
+ y2="37.468754" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15713"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15709"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="323.37836"
+ y1="30.3883"
+ x2="343.5636"
+ y2="53.758793" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15646"
+ gradientUnits="userSpaceOnUse"
+ x1="279.00009"
+ y1="-16.62501"
+ x2="291.93054"
+ y2="-6.3206272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15644"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-253)"
+ x1="25.437477"
+ y1="238.54002"
+ x2="51.01355"
+ y2="263.79816" />
+ <linearGradient
+ id="linearGradient20973">
+ <stop
+ id="stop20975"
+ offset="0"
+ style="stop-color:#15ff00;stop-opacity:1;" />
+ <stop
+ id="stop20977"
+ offset="1"
+ style="stop-color:#15ff00;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20962">
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:1;"
+ offset="0"
+ id="stop20965" />
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:0;"
+ offset="1"
+ id="stop20967" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20036">
+ <stop
+ style="stop-color:#ffb55e;stop-opacity:1;"
+ offset="0"
+ id="stop20038" />
+ <stop
+ style="stop-color:#ff8400;stop-opacity:0;"
+ offset="1"
+ id="stop20040" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15574"
+ gradientUnits="userSpaceOnUse"
+ x1="197.63152"
+ y1="169.14206"
+ x2="190.41687"
+ y2="160.02296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15358"
+ gradientUnits="userSpaceOnUse"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15362"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15360"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,39.669142,20)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14517"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3959732"
+ y1="216.62332"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16069"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="17.011419"
+ y2="82.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient16067"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,-440.36032,-147)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16063"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="6.9917974"
+ y1="219.61856"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16154"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16150"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.8504581"
+ y1="217.4549"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16174"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="2.911078"
+ y1="217.3624"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ id="linearGradient13998">
+ <stop
+ id="stop14000"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15705"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15703"
+ gradientUnits="userSpaceOnUse"
+ x1="146.80022"
+ y1="158.34668"
+ x2="150.08357"
+ y2="162.03282" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15701"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15699"
+ gradientUnits="userSpaceOnUse"
+ x1="122.84515"
+ y1="126.83902"
+ x2="149.88129"
+ y2="164.94562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15742"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="227.57907"
+ y1="118.47696"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="222.4996"
+ y1="110.37873"
+ x2="233.08319"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="230.95012"
+ y1="100.89436"
+ x2="230.74091"
+ y2="124.09359" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15778"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="135.54141"
+ y2="122.0597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15780"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10.767079)"
+ x1="132.35471"
+ y1="246.32236"
+ x2="129.81586"
+ y2="243.70523" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15774"
+ gradientUnits="userSpaceOnUse"
+ x1="103.53399"
+ y1="88.301094"
+ x2="136.3542"
+ y2="123.17216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15450"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15452"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15448"
+ gradientUnits="userSpaceOnUse"
+ x1="132.12782"
+ y1="246.32236"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15446"
+ gradientUnits="userSpaceOnUse"
+ x1="87.969383"
+ y1="69.87941"
+ x2="135.40274"
+ y2="121.19196" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15124"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient15122"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16025"
+ gradientUnits="userSpaceOnUse"
+ x1="192.11751"
+ y1="122.12527"
+ x2="184.43379"
+ y2="112.34031" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.395521,0,0,-0.3955,275.223,171.0515)"
+ x1="213.51967"
+ y1="121.417"
+ x2="204.05295"
+ y2="111.7235" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.607961,0,0,0.607967,64.49194,51.63899)"
+ x1="213.53587"
+ y1="122.66508"
+ x2="203.33264"
+ y2="112.67535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15748"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="349.04059"
+ y1="143.70836"
+ x2="336.72485"
+ y2="117.00745" />
+ <linearGradient
+ id="linearGradient10585">
+ <stop
+ id="stop10587"
+ offset="0.0000000"
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10595"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4138">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31320">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12678">
+ <stop
+ id="stop12680"
+ offset="0"
+ style="stop-color:#d40000;stop-opacity:1" />
+ <stop
+ id="stop12682"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13520"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.401389,-3.2412)"
+ x1="130.59862"
+ y1="121.2412"
+ x2="142.29109"
+ y2="133.53448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23215"
+ x1="147.07098"
+ y1="134.18185"
+ x2="129.67148"
+ y2="115.54105"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient23178">
+ <stop
+ style="stop-color:#ff992b;stop-opacity:1;"
+ offset="0"
+ id="stop23180" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop23182" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13973">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13938">
+ <stop
+ id="stop13940"
+ offset="0"
+ style="stop-color:#6e0c00;stop-opacity:1;" />
+ <stop
+ id="stop13942"
+ offset="1"
+ style="stop-color:#ee3800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14232">
+ <stop
+ style="stop-color:#fff32a;stop-opacity:1;"
+ offset="0"
+ id="stop14234" />
+ <stop
+ style="stop-color:#fff551;stop-opacity:0;"
+ offset="1"
+ id="stop14236" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter13996"
+ x="-0.23644176"
+ width="1.4728835"
+ y="-0.24368355"
+ height="1.4873672"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.29550651"
+ id="feGaussianBlur13998" />
+ </filter>
+ <linearGradient
+ id="linearGradient14418">
+ <stop
+ id="stop14420"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-26,2.9206276e-6)"
+ x1="474"
+ y1="73.999992"
+ x2="477.25"
+ y2="77.499992" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,1.4603138e-6)"
+ x1="474.84375"
+ y1="75"
+ x2="477.5"
+ y2="77.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18852"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18850"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18901"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(279.04534,461.00001)"
+ x1="151"
+ y1="-234"
+ x2="149.95467"
+ y2="-239.14549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.04419,461)"
+ x1="151"
+ y1="-234"
+ x2="150.25"
+ y2="-236.85815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.99885,461)"
+ x1="150.11926"
+ y1="-235.21587"
+ x2="145.20955"
+ y2="-241.85452" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,459)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17535"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17533"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17527"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18207">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18209" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop18211" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient18213"
+ x1="481.46063"
+ y1="219"
+ x2="519.44189"
+ y2="218.48816"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17506"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17504"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17502"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17500"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17498"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2078427,0,0,1.0516432,-357.40769,69.427229)"
+ x1="362.28571"
+ y1="-45.098213"
+ x2="352.46426"
+ y2="-54.124699" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18666">
+ <rect
+ y="6"
+ x="62.921577"
+ height="14.000001"
+ width="15.098035"
+ id="rect18668"
+ style="fill:url(#linearGradient18670);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15592"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15590"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="135.54628"
+ y2="120.58403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15596"
+ gradientUnits="userSpaceOnUse"
+ x1="124.52369"
+ y1="112.22441"
+ x2="131.10667"
+ y2="118.10129" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15594"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="134.62978"
+ y2="120.14633" />
+ <filter
+ inkscape:collect="always"
+ x="-0.71999419"
+ width="2.4399884"
+ y="-0.72000581"
+ height="2.4400115"
+ id="filter31351"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.83077614"
+ id="feGaussianBlur31353" />
+ </filter>
+ <linearGradient
+ id="linearGradient14219">
+ <stop
+ id="stop14221"
+ offset="0"
+ style="stop-color:#ff8605;stop-opacity:1;" />
+ <stop
+ id="stop14223"
+ offset="1"
+ style="stop-color:#9c6700;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31456">
+ <stop
+ style="stop-color:#2b1600;stop-opacity:1;"
+ offset="0"
+ id="stop31458" />
+ <stop
+ style="stop-color:#6e3900;stop-opacity:0;"
+ offset="1"
+ id="stop31460" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19425">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop19427" />
+ <stop
+ id="stop19431"
+ offset="0.63109845"
+ style="stop-color:#fffffe;stop-opacity:0.65789473;" />
+ <stop
+ style="stop-color:#fffffe;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop19429" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30208">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop30210" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop30212" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15782"
+ gradientUnits="userSpaceOnUse"
+ x1="125.19086"
+ y1="125.66204"
+ x2="132.98256"
+ y2="118" />
+ <linearGradient
+ id="linearGradient9030">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542">
+ <stop
+ id="stop37544"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30124">
+ <stop
+ style="stop-color:#1d4a8c;stop-opacity:1;"
+ offset="0"
+ id="stop30126" />
+ <stop
+ style="stop-color:#c1d4f2;stop-opacity:1;"
+ offset="1"
+ id="stop30128" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15893">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop15895" />
+ <stop
+ id="stop15897"
+ offset="0.37679368"
+ style="stop-color:#b5ccf0;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b5ccf0;stop-opacity:1;"
+ offset="0.59786767"
+ id="stop15899" />
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="1"
+ id="stop15901" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24000">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop24002" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop24004" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient32998">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop33000" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop33002" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="radialGradient21517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.891843,0,0,0.909224,-173.99085,171.21624)"
+ cx="350.5"
+ cy="14.5"
+ fx="350.5"
+ fy="14.5"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21641"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="133.62564"
+ y2="120.24665" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21643"
+ gradientUnits="userSpaceOnUse"
+ x1="126.15096"
+ y1="113.21745"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20796"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(159.9998,-41.00751)"
+ x1="261.44702"
+ y1="234.6606"
+ x2="274.30609"
+ y2="247.73561" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20798"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(199.9999,105.99249)"
+ x1="235.46884"
+ y1="103"
+ x2="228.71886"
+ y2="94.53125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.2344713"
+ y1="215.76874"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21864"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="19.011419"
+ y2="86" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3268692"
+ y1="215.35608"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21904"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-237)"
+ x1="24.374985"
+ y1="238.33629"
+ x2="55.384842"
+ y2="269.1373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,16)"
+ x1="278.55817"
+ y1="-16.978563"
+ x2="291.577"
+ y2="-5.8786855" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient31650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.816279,0,-3.646264e-6,0.779872,56.32029,28.34496)"
+ cx="306.55292"
+ cy="11.818644"
+ fx="306.55292"
+ fy="11.818644"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="radialGradient31652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.580596,1.138426,-0.692447,0.961382,-175.3891,-329.6844)"
+ cx="312.80765"
+ cy="10.620173"
+ fx="312.80765"
+ fy="10.620173"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20962"
+ id="radialGradient31654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.48445,-0.00657397,0.00734631,1.660903,-154.1629,19.305572)"
+ cx="313.74268"
+ cy="15.619254"
+ fx="313.74268"
+ fy="15.619254"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20973"
+ id="radialGradient31656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.756245,0,-3.378096e-6,0.722516,72.63115,31.07857)"
+ cx="309.0571"
+ cy="15.518281"
+ fx="309.0571"
+ fy="15.518281"
+ r="4.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31664"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8579582,0,0,0.9285714,7.397998,-211.96428)"
+ x1="-6.3249049"
+ y1="205.0083"
+ x2="32.351238"
+ y2="248.75177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9569715,-1,0,259,351.18743)"
+ x1="347.6467"
+ y1="216.75188"
+ x2="345.98633"
+ y2="243.92201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166667,0,0,0.9166667,24.364541,-55.041665)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9297203,-1.2117965,0,305.73028,342.22894)"
+ x1="346.15555"
+ y1="218.2382"
+ x2="346.58698"
+ y2="238.44429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31694"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient31696"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="64.998215"
+ y1="90.951675"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,105.5221,92.482413)"
+ x1="257.0376"
+ y1="10.838325"
+ x2="277.61203"
+ y2="31.019331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31934"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7827973,0,0,0.9989462,77.082208,42.08484)"
+ x1="332.03717"
+ y1="68.624634"
+ x2="346.08932"
+ y2="83.002625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31936"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(262,-125)"
+ x1="79.329903"
+ y1="236"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient33666"
+ gradientUnits="userSpaceOnUse"
+ x1="124.14184"
+ y1="126.23546"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33668"
+ gradientUnits="userSpaceOnUse"
+ x1="125.45158"
+ y1="125.94608"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33670"
+ gradientUnits="userSpaceOnUse"
+ x1="142.97318"
+ y1="107.64013"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33681"
+ gradientUnits="userSpaceOnUse"
+ x1="139.93341"
+ y1="110.56118"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient33700"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55772"
+ y1="98.630066"
+ x2="123.9021"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10540"
+ gradientUnits="userSpaceOnUse"
+ x1="130.95198"
+ y1="117.09563"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient11333"
+ gradientUnits="userSpaceOnUse"
+ x1="119.1647"
+ y1="106.08605"
+ x2="133.01006"
+ y2="119.79803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-425,393.99999)"
+ x1="225.6198"
+ y1="5.7625732"
+ x2="236.47855"
+ y2="14.103563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient28077"
+ x1="306.26187"
+ y1="272"
+ x2="307"
+ y2="263.55374"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="431.05026"
+ y1="121.42467"
+ x2="446.26407"
+ y2="110.49417" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28528"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="442.69827"
+ y1="107.56771"
+ x2="450.27414"
+ y2="122.95798" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-474,158.25)"
+ x1="437.57828"
+ y1="104.34499"
+ x2="447.96875"
+ y2="117.90625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28532"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10982"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10984"
+ x1="212.04637"
+ y1="182.09375"
+ x2="222.35799"
+ y2="182.77524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11762"
+ x1="371.98389"
+ y1="203"
+ x2="376.48389"
+ y2="203"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11764"
+ x1="366.98389"
+ y1="203"
+ x2="370.98389"
+ y2="202.75"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11766"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient12427"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14219"
+ id="radialGradient12429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5007214,0.3131662,-0.3623683,0.5793905,300.02235,-93.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16359"
+ id="linearGradient12602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,456.04574,-116.51416)"
+ x1="88.079262"
+ y1="66.110847"
+ x2="95.954262"
+ y2="58.272621" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient12114"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1438.0001,-418)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1830.2675,-33.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1397.7474,-388.72044)"
+ x1="1984.5453"
+ y1="828.21777"
+ x2="1978.11"
+ y2="829.35315" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12215"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12217"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient12305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="257.24991"
+ y1="147.38998"
+ x2="262.24991"
+ y2="152.46707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient12307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="258.08322"
+ y1="147.87068"
+ x2="264.16571"
+ y2="153.8233" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13046"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-161.99999)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13041">
+ <rect
+ style="fill:url(#linearGradient13046);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect13043"
+ width="7"
+ height="8"
+ x="276"
+ y="-12" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-145.93749)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13052">
+ <rect
+ y="4.0625"
+ x="276"
+ height="8"
+ width="7"
+ id="rect13054"
+ style="fill:url(#linearGradient13056);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14173"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient13112"
+ gradientUnits="userSpaceOnUse"
+ x1="133.42287"
+ y1="120.62622"
+ x2="126.67323"
+ y2="113.20281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13114"
+ gradientUnits="userSpaceOnUse"
+ x1="120.77391"
+ y1="106.19939"
+ x2="144.64095"
+ y2="129.62753" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8289081,0,0,2.1560411,236.27148,-864.45588)"
+ x1="212"
+ y1="435.59741"
+ x2="211.99998"
+ y2="435.32159" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1035181,0,0,1,158.18497,-359.77344)"
+ x1="229.6875"
+ y1="440.51562"
+ x2="238.53125"
+ y2="440.57812" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23390"
+ id="radialGradient16034"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8126517,-0.04317018,0.04642643,1.9485655,-18.817545,-774.28453)"
+ cx="224.32494"
+ cy="441.84744"
+ fx="224.32494"
+ fy="441.84744"
+ r="6.7191267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient16036"
+ gradientUnits="userSpaceOnUse"
+ x1="211.99998"
+ y1="435.7319"
+ x2="211.99998"
+ y2="436.07974"
+ gradientTransform="matrix(0.9803611,0,0,2.1560411,204.16345,-864.45588)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16039"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(182,-359.75)"
+ x1="221.96414"
+ y1="439.75"
+ x2="238.87605"
+ y2="448.88205" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0008786,0,0,1.081555,-21.021535,-187.45087)"
+ x1="-12.839478"
+ y1="201"
+ x2="44.522621"
+ y2="256.70349" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.099576,0,0,1.0999923,190.46996,204.85062)"
+ x1="9.6310225"
+ y1="76"
+ x2="15"
+ y2="81" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,370.43125,-83.863716)"
+ x1="-5.6700387"
+ y1="250.87607"
+ x2="-46.452946"
+ y2="251.42462" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17714"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,280.08766,104.72255)"
+ x1="102.61966"
+ y1="50.742527"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient12655"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12658"
+ gradientUnits="userSpaceOnUse"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13527"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13529"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(68.016116,127.00002)"
+ x1="97.983887"
+ y1="127.99998"
+ x2="88.983887"
+ y2="115.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14570"
+ gradientUnits="userSpaceOnUse"
+ x1="94.485573"
+ y1="122.13319"
+ x2="89.207298"
+ y2="125.83332" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14572"
+ gradientUnits="userSpaceOnUse"
+ x1="88.560204"
+ y1="127.88263"
+ x2="94.011101"
+ y2="123.83599" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient47130"
+ id="linearGradient13699"
+ x1="-162.89217"
+ y1="245"
+ x2="-174.18907"
+ y2="224.99274"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26282"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26284"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26286"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14198"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15195"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient15209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15211"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15363"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9999519,0,0,0.9998051,-33.993941,254.01926)"
+ x1="101.21339"
+ y1="68.783279"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15365"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,40.331334,244.81698)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10585"
+ id="linearGradient15367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.032977,0,0,1,128.82015,107.77516)"
+ x1="12.330792"
+ y1="246.97107"
+ x2="41.654194"
+ y2="247.3784" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient15383"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14377"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient16640"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="85.874489"
+ y1="501.74075"
+ x2="26.561054"
+ y2="498.48148" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16642"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16644"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,300.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient16648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient32447"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30231"
+ gradientUnits="userSpaceOnUse"
+ x1="441.48248"
+ y1="105.03784"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient30233"
+ gradientUnits="userSpaceOnUse"
+ x1="445.37457"
+ y1="112.86145"
+ x2="425.92511"
+ y2="84.928581" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30235"
+ gradientUnits="userSpaceOnUse"
+ x1="440.68439"
+ y1="106.0996"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30237"
+ gradientUnits="userSpaceOnUse"
+ x1="440.34833"
+ y1="105.74502"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30239"
+ gradientUnits="userSpaceOnUse"
+ x1="440.7211"
+ y1="104.97093"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23302"
+ id="linearGradient30241"
+ gradientUnits="userSpaceOnUse"
+ x1="414.99771"
+ y1="-35"
+ x2="414.99771"
+ y2="-36.625011" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24081"
+ id="linearGradient30243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.00461"
+ y1="-34"
+ x2="415.94211"
+ y2="-37.718761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient30247"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.41162"
+ y1="-34.342831"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30249"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30326"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30328"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30330"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30332"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30334"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30336"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30338"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30340"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30344"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30346"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30348"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30394"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30396"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30398"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30400"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30402"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30404"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30406"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30408"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30414"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30416"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-394.58897,440.54169)"
+ x1="326.51352"
+ y1="32.007874"
+ x2="347.91187"
+ y2="57.261913" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17431"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-400.00857,439.95001)"
+ x1="317.30908"
+ y1="22.7787"
+ x2="330.87869"
+ y2="38.161732" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask17570">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m -44,358 0,14 14,-14 -14,0 z"
+ id="path17572" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18682"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.9230835,365.8517,-147.63686)"
+ x1="27.405855"
+ y1="189.20862"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18690"
+ gradientUnits="userSpaceOnUse"
+ x1="29.972469"
+ y1="164"
+ x2="29.972469"
+ y2="168"
+ gradientTransform="translate(359.05264,-81.98142)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="30.435225"
+ y1="202.99998"
+ x2="30.435225"
+ y2="251.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18756"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18779"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6923077,0,0,-0.6923079,29.049874,351.11545)"
+ x1="7.9951181"
+ y1="264.90152"
+ x2="32.267426"
+ y2="237.9342" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-122.98388,276)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5384613,0,0,0.538461,-189.69233,224.07704)"
+ x1="29.142912"
+ y1="161.42842"
+ x2="29.142912"
+ y2="252.42851" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.538461,-193.81309,224.07705)"
+ x1="29.871567"
+ y1="153.99983"
+ x2="29.871567"
+ y2="252.4285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.461541,-193.81309,236.42243)"
+ x1="29.871567"
+ y1="174.58366"
+ x2="29.871567"
+ y2="259.08319" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18854"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2500001,0,0,2.2000001,-102.35484,177)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.8000001,-122.98388,285.5)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.0000001,0,0,1.6000003,163.54205,53.499972)"
+ x1="-60.266121"
+ y1="74.0625"
+ x2="-54.766121"
+ y2="84.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32725"
+ gradientUnits="userSpaceOnUse"
+ x1="-88.0625"
+ y1="364"
+ x2="-44.983891"
+ y2="411.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-117.02574,313.78567)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient32729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6666675,0,0,0.6666633,-101.32265,336.66698)"
+ x1="61.983898"
+ y1="88.999977"
+ x2="89.770271"
+ y2="121.709" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-122.97299,306.4115)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient32749"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-123.05997,-52.467545)"
+ x1="326.72092"
+ y1="33.927608"
+ x2="352.03485"
+ y2="60.463093" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32751"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="-46.417774"
+ y1="1.9796312"
+ x2="-21.988398"
+ y2="27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-128.47957,-53.059225)"
+ x1="324.13901"
+ y1="28.882492"
+ x2="333.96365"
+ y2="39.250004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(18,0)"
+ x1="-51.6875"
+ y1="442.6875"
+ x2="-42.377892"
+ y2="452.20007" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17177"
+ gradientUnits="userSpaceOnUse"
+ x1="28.322077"
+ y1="160.10768"
+ x2="32.679554"
+ y2="164.34546" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient17179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-6.8461644e-7,-1.8,1.1087755,0.00352366,-193.46828,187.54551)"
+ cx="4.351675"
+ cy="81.592964"
+ fx="4.351675"
+ fy="81.592964"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18344"
+ id="radialGradient17181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5123107,0.9569981,-0.5028837,0.7946898,-131.57281,-236.33663)"
+ cx="244.14325"
+ cy="-14.13948"
+ fx="244.14325"
+ fy="-14.13948"
+ r="3.4000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17214"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17216"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17218"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2859748,0,0,1,-272.87621,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4289612,0,0,1,-326.93899,144.5)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17222"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17224"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17226"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2868892,0,0,1,-644.69395,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="36.247395"
+ y2="249.62102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="103.65562"
+ y1="49.547874"
+ x2="120.79755"
+ y2="57.84819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient18721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,244.3928,19.4113)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320"
+ id="linearGradient18728"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="linearGradient18765"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,309.42934,-349.44584)"
+ x1="-26.207859"
+ y1="252.77303"
+ x2="-5.4963508"
+ y2="253.15045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient35488"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35490"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient35492"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient35494"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35967"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.656002,0,0,0.656002,88.923481,27.003843)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath18524">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.1435655,0,0,1.1436475,512.11415,45.72091)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path18526"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69954133;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18634">
+ <path
+ sodipodi:nodetypes="ccccscc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 207,134 0,14 11,0 0,-7.5625 c -1.97252,-0.24738 -3.5,-1.89814 -3.5,-3.9375 0,-0.94675 0.35614,-1.81444 0.90625,-2.5 L 207,134 z"
+ id="path18636" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient18478"
+ gradientUnits="userSpaceOnUse"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18480"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97.983877,565.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35583"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="4.952816"
+ y2="-27.882322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35585"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="3.1666665"
+ y2="-29.550003" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35587"
+ gradientUnits="userSpaceOnUse"
+ x1="-3.5"
+ y1="-35.5"
+ x2="2.6932251"
+ y2="-29.488832" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35589"
+ gradientUnits="userSpaceOnUse"
+ x1="4.9341426"
+ y1="-29.678047"
+ x2="4.8398785e-16"
+ y2="-32.351803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35591"
+ gradientUnits="userSpaceOnUse"
+ x1="0.5079475"
+ y1="-32.317398"
+ x2="4.2000003"
+ y2="-28.597046" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient35593"
+ gradientUnits="userSpaceOnUse"
+ x1="2.8144052"
+ y1="-28.1"
+ x2="-4.375"
+ y2="-36.441402" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35595"
+ gradientUnits="userSpaceOnUse"
+ x1="-2.7708333"
+ y1="-35.5"
+ x2="1.1666667"
+ y2="-32" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient35740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,-206.46148,-296.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="10.490564"
+ y2="176.41806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient35742"
+ gradientUnits="userSpaceOnUse"
+ x1="58.060974"
+ y1="-23.721956"
+ x2="40"
+ y2="-35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35744"
+ gradientUnits="userSpaceOnUse"
+ x1="46.1875"
+ y1="-28.59375"
+ x2="41.099998"
+ y2="-33.59375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36116"
+ id="linearGradient35746"
+ gradientUnits="userSpaceOnUse"
+ x1="46"
+ y1="-32"
+ x2="43.883884"
+ y2="-33.939339" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35748"
+ gradientUnits="userSpaceOnUse"
+ x1="41"
+ y1="-29"
+ x2="43"
+ y2="-27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35750"
+ gradientUnits="userSpaceOnUse"
+ x1="48.662914"
+ y1="-27.071922"
+ x2="43.47097"
+ y2="-32.337086" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6.3,-4.7)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.200001"
+ y2="-28.640625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.315625,-3.75)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35756"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(3.3,0.3)"
+ x1="38.700001"
+ y1="-31.299999"
+ x2="40.012501"
+ y2="-29.799999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35772"
+ gradientUnits="userSpaceOnUse"
+ x1="51.912914"
+ y1="-24.696922"
+ x2="40.75"
+ y2="-35.75"
+ gradientTransform="translate(-0.75,4.75)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51774"
+ gradientUnits="userSpaceOnUse"
+ x1="135.32962"
+ y1="120.04005"
+ x2="130.7244"
+ y2="116.31882" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51776"
+ gradientUnits="userSpaceOnUse"
+ x1="130.9015"
+ y1="115.23484"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient51804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.43697,300.37199)"
+ x1="107.78085"
+ y1="50.778313"
+ x2="111.53449"
+ y2="46.679707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.55698,300.497)"
+ x1="115.37703"
+ y1="51.021076"
+ x2="112.87534"
+ y2="51.021076" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.35699,300.55457)"
+ x1="110.57378"
+ y1="50.963791"
+ x2="108.07208"
+ y2="50.963791" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.36783,218.31526)"
+ x1="-13.691219"
+ y1="241.78653"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.13133,218.33837)"
+ x1="-9.0782614"
+ y1="249.96617"
+ x2="-2.9318311"
+ y2="240.68927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.5254431"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.091064"
+ y2="242.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68941"
+ gradientUnits="userSpaceOnUse"
+ x1="-41.065678"
+ y1="240.10526"
+ x2="-15.758821"
+ y2="244.11874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(440.2082,-188.0039)"
+ x1="-10.991813"
+ y1="237.9574"
+ x2="-7.0786314"
+ y2="246.7774" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.9582,-188.0039)"
+ x1="-5.1338587"
+ y1="244.08765"
+ x2="-14.193665"
+ y2="251.35759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient68947"
+ gradientUnits="userSpaceOnUse"
+ x1="-15.6"
+ y1="247.38559"
+ x2="-3.321322"
+ y2="245.68124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68949"
+ gradientUnits="userSpaceOnUse"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.7065439"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68951"
+ gradientUnits="userSpaceOnUse"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.125"
+ y2="242.81946" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.25,0.2058042)"
+ x1="-12.538609"
+ y1="240.79787"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68955"
+ gradientUnits="userSpaceOnUse"
+ x1="-7.20822"
+ y1="247.4906"
+ x2="-1.7751017"
+ y2="239.86711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient69009"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5466301,0,0,1.6489946,-293.01107,-16.485383)"
+ x1="582"
+ y1="49.294117"
+ x2="582"
+ y2="47.176472" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask69005">
+ <rect
+ style="fill:url(#linearGradient69009);fill-opacity:1;display:inline"
+ id="rect69007"
+ width="24.746082"
+ height="26.383913"
+ x="596.30127"
+ y="39.580433" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20269"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20275"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20283"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20303"
+ gradientUnits="userSpaceOnUse"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20309"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21567"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21596"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21647"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21649"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21979"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath22590">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22592"
+ width="12"
+ height="14"
+ x="-30"
+ y="490.00012" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ id="filter22979"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur22981" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter22999"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur23001" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter23007"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur23009" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter23015"
+ x="-0.95999229"
+ width="2.9199846"
+ y="-0.96000773"
+ height="2.9200156"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.1077015"
+ id="feGaussianBlur23017" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.1666667,-737,357.33333)"
+ x1="771.0965"
+ y1="354.28479"
+ x2="772"
+ y2="358.85715" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23591">
+ <rect
+ mask="none"
+ style="fill:url(#linearGradient23595);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23593"
+ width="11"
+ height="14"
+ x="30"
+ y="768" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath23877">
+ <rect
+ transform="scale(1,-1)"
+ y="-540"
+ x="952"
+ height="6"
+ width="15"
+ id="rect23879"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23978"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23980"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320"
+ id="linearGradient23982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.733333,808.99997,-697.8)"
+ x1="150.5"
+ y1="239.9987"
+ x2="150.5"
+ y2="237" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29485"
+ id="linearGradient23986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,715,364)"
+ x1="147.0625"
+ y1="243.76387"
+ x2="142.9375"
+ y2="243.69914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30777"
+ id="linearGradient23988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2857143,364,645.14283)"
+ x1="148"
+ y1="244.11113"
+ x2="144"
+ y2="244.11113" />
+ <linearGradient
+ id="linearGradient3564"
+ inkscape:collect="always">
+ <stop
+ id="stop3566"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop3568"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39155">
+ <stop
+ id="stop39157"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39159"
+ offset="1"
+ style="stop-color:#dadada;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39171"
+ inkscape:collect="always">
+ <stop
+ id="stop39173"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39175"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient21442"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39155"
+ id="linearGradient21444"
+ gradientUnits="userSpaceOnUse"
+ x1="31.1875"
+ y1="18.875"
+ x2="29.875"
+ y2="34.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3564"
+ id="linearGradient21446"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06818845,0,0,0.06818845,22.51112,27.02885)"
+ x1="185.9903"
+ y1="193.33229"
+ x2="190.46461"
+ y2="-458.05771" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39171"
+ id="radialGradient21448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.647222,0,0,1.26792,-15.47413,-5.79794)"
+ cx="26.109201"
+ cy="19.668886"
+ fx="26.109201"
+ fy="19.668886"
+ r="20.278975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39281"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="71"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39283"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1944456,0,0,1.2000039,-34.222431,-14.950295)"
+ x1="175.17659"
+ y1="74.972061"
+ x2="176.40117"
+ y2="76.182281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39285"
+ gradientUnits="userSpaceOnUse"
+ x1="165.19363"
+ y1="64.53186"
+ x2="176.15442"
+ y2="76.210785" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39287"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="172.30418"
+ y1="69.838829"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39289"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39291"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39293"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39008"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39010"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39012"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39014"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39016"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39022"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39026"
+ x1="1127.7983"
+ y1="448.375"
+ x2="1153.0486"
+ y2="430.25"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient57417"
+ gradientUnits="userSpaceOnUse"
+ x1="146.82516"
+ y1="134.65511"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient57419"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57421"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57423"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient57454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(258.00306,-231.00101)"
+ x1="75.25"
+ y1="393.25"
+ x2="73.5"
+ y2="391.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask57450">
+ <rect
+ y="154.99899"
+ x="326.00305"
+ height="15"
+ width="15"
+ id="rect57452"
+ style="fill:url(#linearGradient57454);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22891"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="174.99828"
+ y1="12.918247"
+ x2="167.59578"
+ y2="12.551482" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22893"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="169.47711"
+ y1="10.424105"
+ x2="169.47711"
+ y2="8.1183796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22895"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.728189,0,0,1.727271,237.88848,243.63713)"
+ x1="169.41847"
+ y1="10.306772"
+ x2="169.4877"
+ y2="7.9604731" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="145.00008"
+ y1="11.99999"
+ x2="160.31258"
+ y2="19.34374" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="149.00008"
+ y1="10.924165"
+ x2="171.37508"
+ y2="19.12499" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient22901"
+ gradientUnits="userSpaceOnUse"
+ x1="-68.25"
+ y1="263"
+ x2="-56"
+ y2="265.53439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22903"
+ gradientUnits="userSpaceOnUse"
+ x1="-66"
+ y1="264"
+ x2="-57"
+ y2="264.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32998"
+ id="linearGradient22905"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="176.42079"
+ y1="12.946938"
+ x2="169.47711"
+ y2="12.36799" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient22933"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22935"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient22937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22939"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22970"
+ x1="-197.84375"
+ y1="399.90625"
+ x2="-191"
+ y2="409"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19625"
+ id="linearGradient23241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="476.76578"
+ y2="162.94037" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12678"
+ id="radialGradient23245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0982561,0,0,1.2662999,-45.858153,-42.45126)"
+ cx="470.15939"
+ cy="164.46814"
+ fx="470.15939"
+ fy="164.46814"
+ r="3.500145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23247"
+ gradientUnits="userSpaceOnUse"
+ x1="128.7561"
+ y1="115.77483"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23250"
+ gradientUnits="userSpaceOnUse"
+ x1="127.30917"
+ y1="111.48133"
+ x2="138.30522"
+ y2="124.69373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23445"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="475.50031"
+ y2="162.92206" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23447"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.37032"
+ y1="12.147777"
+ x2="175.38158"
+ y2="15.699567" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23533"
+ gradientUnits="userSpaceOnUse"
+ x1="155.82454"
+ y1="16.845156"
+ x2="158.41653"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.727201,9.075096e-6,0,1.728246,-147.7149,-10.37485)"
+ x1="171.03941"
+ y1="11.121979"
+ x2="175.33569"
+ y2="16.202652" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.18394"
+ y1="11.912162"
+ x2="176.46956"
+ y2="16.427906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40847"
+ gradientUnits="userSpaceOnUse"
+ x1="156.00008"
+ y1="16.99999"
+ x2="159.00008"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40965"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,14)"
+ x1="62.107086"
+ y1="223.54628"
+ x2="96.812675"
+ y2="258.38593" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient40967"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-21,0)"
+ x1="79.04213"
+ y1="253.5"
+ x2="60.155113"
+ y2="234.7775" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24098"
+ x1="208.25"
+ y1="-133.89581"
+ x2="204.01923"
+ y2="-111.15749"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23510"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3008215,-8.6726798)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23512"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="110.16959"
+ y1="57.061836"
+ x2="117.55341"
+ y2="64.995972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23514"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3010161,-8.6726854)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="54.252415"
+ y2="100.44998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23550"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,0.01738631)"
+ x1="468.07968"
+ y1="275.27036"
+ x2="510"
+ y2="266.99997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient23555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,3.959006e-5)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23581"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,404.07104,216.722)"
+ x1="116.75796"
+ y1="52.264809"
+ x2="103.18628"
+ y2="55.747272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient23585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-1.0000037)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="radialGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="radialGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0009003,-1.5278593,1.1592123,0.7594114,-59.938837,957.7287)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23562"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,461.68129,182.37748)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="56.524509"
+ y2="101.25028" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,323.39462,186.24644)"
+ x1="115.45872"
+ y1="58.869785"
+ x2="106.20376"
+ y2="58.354706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,347.39462,166.24644)"
+ x1="110.54202"
+ y1="56.645538"
+ x2="115.53827"
+ y2="63.567348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2445337,0,0,1.5876961,523.20711,115.4619)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,503.28129,157.47747)"
+ x1="29.506693"
+ y1="100.66651"
+ x2="34.276955"
+ y2="105.98901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24054"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24066"
+ x1="202.5"
+ y1="143.84116"
+ x2="202.5"
+ y2="132.60213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-259,202)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient23738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23750"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,59.49999,53.45766)"
+ x1="445.5"
+ y1="148.90862"
+ x2="433.5"
+ y2="148.69533" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6499984,0,0,0.5439483,434.02514,137.87435)"
+ x1="113.71248"
+ y1="158.24995"
+ x2="91.499992"
+ y2="158.24994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0052083,0,0,0.5057472,778.49218,365.83334)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23914"
+ gradientUnits="userSpaceOnUse"
+ x1="29.200638"
+ y1="160.18758"
+ x2="32.928555"
+ y2="164.13913" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23916"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.02887268,-1.2550276,0.795821,0.01830762,8.763469,168.20647)"
+ cx="11.708446"
+ cy="81.275032"
+ fx="11.708446"
+ fy="81.275032"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.01269957,-0.9297674,1.1086869,0.01514236,-16.51473,165.70609)"
+ cx="4.7455525"
+ cy="82.433929"
+ fx="4.7455525"
+ fy="82.433929"
+ r="5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24460"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(383,-37.999994)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24456">
+ <rect
+ y="108"
+ x="299"
+ height="17"
+ width="7"
+ id="rect24458"
+ style="fill:url(#linearGradient24460);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-142.95536)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24466">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient24470);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24468"
+ width="7"
+ height="9"
+ x="276"
+ y="4.0625" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23971"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23973"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23975"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24099"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24539"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="107.39532"
+ y1="58.065113"
+ x2="127.70434"
+ y2="58.065113" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24541"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1000194,0,0,1.0998287,110.29549,-8.6726854)"
+ x1="30.389694"
+ y1="95.008034"
+ x2="65.52562"
+ y2="93.69249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="483.00034"
+ y1="163"
+ x2="476.68781"
+ y2="162.85956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24545"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24547"
+ gradientUnits="userSpaceOnUse"
+ x1="475.00034"
+ y1="155"
+ x2="469.75034"
+ y2="155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,-6e-5)"
+ x1="442.81525"
+ y1="290.49384"
+ x2="436.5"
+ y2="290.5249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient24551"
+ gradientUnits="userSpaceOnUse"
+ x1="445.99902"
+ y1="288.5"
+ x2="407.3793"
+ y2="288.5" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath24168">
+ <path
+ style="fill:#808080;fill-rule:evenodd;stroke:none"
+ d="m 134.27489,222.11125 c -3.9249,-6.46418 -7.61892,6.46419 -11.54381,0 l 0,0 -1.61614,0 0,8.77283 14.77608,0 0,-8.77283 -1.61613,0 z"
+ id="path24170"
+ sodipodi:nodetypes="cccccccc" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient24112"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24114"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="302.84085"
+ y1="243.23151"
+ x2="308.82889"
+ y2="244.70323" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6879084,0,0,0.6879446,216.19282,166.82605)"
+ x1="121.7408"
+ y1="115.90587"
+ x2="130.01318"
+ y2="116.60553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24121"
+ gradientUnits="userSpaceOnUse"
+ x1="135.698"
+ y1="122.92034"
+ x2="129.70906"
+ y2="117.15551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24123"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="162.61801"
+ y1="4.5569806"
+ x2="180.11391"
+ y2="23.410421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24192"
+ gradientUnits="userSpaceOnUse"
+ x1="167.43744"
+ y1="23.749996"
+ x2="175.06059"
+ y2="32.144764"
+ gradientTransform="translate(-94.937441,240)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="166.86487"
+ y1="12.306217"
+ x2="173.93744"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24268"
+ gradientUnits="userSpaceOnUse"
+ x1="186.74992"
+ y1="10.795519"
+ x2="189.24992"
+ y2="9.0189686"
+ gradientTransform="matrix(1,0,0,-0.985055,75.000075,275.63418)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24277"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient24395"
+ x1="-27.5"
+ y1="268.76776"
+ x2="-39.875"
+ y2="277.4375"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15893"
+ id="linearGradient41127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,594,-42.40625)"
+ x1="409.45645"
+ y1="52.77837"
+ x2="402.30673"
+ y2="55.86327" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27957"
+ id="linearGradient41129"
+ gradientUnits="userSpaceOnUse"
+ x1="180.20316"
+ y1="8.0551176"
+ x2="192.75177"
+ y2="12.942369" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41172"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="268.21783"
+ y1="200.66605"
+ x2="284.9375"
+ y2="224.1875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient41174"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42069"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="276.39999"
+ y1="215.3125"
+ x2="265.70886"
+ y2="196.576" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42115"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(60,-342)"
+ x1="206"
+ y1="535"
+ x2="212"
+ y2="549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="263"
+ y1="193.93752"
+ x2="296.25"
+ y2="239.89455" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="265.98389"
+ y1="195"
+ x2="290.98389"
+ y2="232" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40722"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9819031,0,0,0.9481466,-88.271503,-83.584533)"
+ x1="1.6577729"
+ y1="253.01927"
+ x2="-57.772419"
+ y2="253.62515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.977157,0,0,0.9835482,0.06815071,100.43848)"
+ x1="107.84375"
+ y1="57.374996"
+ x2="116.99999"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="241.17908"
+ y1="214.40446"
+ x2="279.89563"
+ y2="254.94975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6025789,0,0,0.668336,263.48819,85.675422)"
+ x1="49.543404"
+ y1="230.81766"
+ x2="73.932747"
+ y2="247.27646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9120445,0,0,1,25.749745,8.9261515)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="308.97327"
+ y2="242" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.584271,0,0,0.661005,267.80323,78.438648)"
+ x1="51.682816"
+ y1="229.19724"
+ x2="73.932762"
+ y2="247.35141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40742"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9103441,0,0,0.989031,29.299938,2.5312404)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="307.25021"
+ y2="241.62509" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40758"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.997359,-17.993456)"
+ x1="199.4335"
+ y1="294.81082"
+ x2="196.00264"
+ y2="259.99347" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40760"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,51.339144,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40762"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,59.339161,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40788"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="146.51619"
+ y1="217.52046"
+ x2="174.56255"
+ y2="252.52081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient40790"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18056"
+ id="linearGradient40792"
+ gradientUnits="userSpaceOnUse"
+ x1="170.42908"
+ y1="237.25"
+ x2="170.71698"
+ y2="249.15927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40794"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.5625"
+ y1="249.55817"
+ x2="168.5"
+ y2="240.10249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40545"
+ gradientUnits="userSpaceOnUse"
+ x1="279.38629"
+ y1="-16.946415"
+ x2="293.80472"
+ y2="-2.5475447" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40547"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9230687,0,0,0.9230801,261.38476,-234.15464)"
+ x1="43.921535"
+ y1="261.52924"
+ x2="29.429007"
+ y2="243.98439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23775"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9230769,0,0,-0.9258123,59.615385,471.81593)"
+ x1="-0.71355486"
+ y1="209.97131"
+ x2="37.5"
+ y2="252.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23777"
+ gradientUnits="userSpaceOnUse"
+ x1="72.698921"
+ y1="599.20789"
+ x2="77.111115"
+ y2="604.11108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23351"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23353"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23355"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23357"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23599"
+ x1="191"
+ y1="158.72728"
+ x2="196.59441"
+ y2="167.67831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.89375,0,0,0.89375,20.29375,17.10625)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22704"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23132"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23134"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23147"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23177"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23183"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23185"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23231"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23235"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23239"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23257"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23563"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23566"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23587"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23626"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23635"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23799"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23801"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23807"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23811"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23821"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23827"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23829"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23833"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23835"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23837"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23853"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23860"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42685"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient22892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22917"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22922"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="262.67139"
+ cy="74.072273"
+ fx="262.67139"
+ fy="74.072273"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient22954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37925"
+ id="linearGradient23890"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient23892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23906"
+ id="radialGradient23894"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0553103,1.0606182,-1.2516598,1.280294,67.321819,-297.60493)"
+ cx="262.07156"
+ cy="74.306007"
+ fx="262.07156"
+ fy="74.306007"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="radialGradient23898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient24090"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient24092"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24094"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="263.21707"
+ cy="74.441246"
+ fx="263.21707"
+ fy="74.441246"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient24102"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24104"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="66.954422"
+ y1="240.03282"
+ x2="68.458534"
+ y2="246.96069" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="244.37868"
+ y1="285.00754"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24695"
+ id="linearGradient24374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.97597"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-150.99992,596.00357)"
+ x1="199.87271"
+ y1="272.29477"
+ x2="212.22493"
+ y2="287.50357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24811"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.539974"
+ y1="421.80756"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24841"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24144"
+ id="linearGradient24843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="64.019142"
+ y1="419.06366"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24867"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24869"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24871"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.659767"
+ y1="422.46088"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24873"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25073"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25075"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient42055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.94298"
+ y1="281.27435"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient42057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient24132"
+ gradientUnits="userSpaceOnUse"
+ x1="445.77841"
+ y1="113.24564"
+ x2="426.11459"
+ y2="84.777061" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24599"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1489145,-0.69297,0.4772363,0.7912359,-113.08929,303.20064)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7236207,-0.7167103,1.004637,1.0143218,-131.254,253.93955)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient24797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.3967"
+ y1="310.77368"
+ x2="309.02371"
+ y2="308.51169" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24820"
+ x1="311.37668"
+ y1="311.88205"
+ x2="307.5"
+ y2="308.21875"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4011721,0.3766097,-0.7099042,0.7562044,179.21454,-58.566632)"
+ cx="207.04807"
+ cy="78.473343"
+ fx="207.04807"
+ fy="78.473343"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4543499,0.4687811,-0.6244606,0.6052369,161.562,-65.729731)"
+ cx="206.39249"
+ cy="78.443413"
+ fx="206.39249"
+ fy="78.443413"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="248.69196"
+ y1="279.72827"
+ x2="269.3085"
+ y2="303.10999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient62558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,-33.03632,32.03632)"
+ x1="289.61554"
+ y1="320.55179"
+ x2="250.22783"
+ y2="282.28745" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62560"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,59,638)"
+ x1="354.50601"
+ y1="283.61511"
+ x2="327.92044"
+ y2="300.96124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25381"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25387"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25369">
+ <g
+ id="g25371"
+ transform="translate(-21,-21)">
+ <path
+ style="fill:url(#linearGradient25381);fill-rule:evenodd;stroke:none"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ id="path25373"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="4" />
+ <path
+ inkscape:transform-center-y="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25375"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ style="fill:url(#linearGradient25383);fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:transform-center-x="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25377"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ style="fill:url(#linearGradient25385);fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:transform-center-y="4"
+ sodipodi:nodetypes="cccc"
+ id="path25379"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ style="fill:url(#linearGradient25387);fill-rule:evenodd;stroke:none" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.01321"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25579"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25561">
+ <g
+ transform="translate(-21,-21)"
+ id="g25563">
+ <path
+ inkscape:transform-center-x="4"
+ sodipodi:nodetypes="cccc"
+ id="path25565"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ style="fill:url(#linearGradient25573);fill-rule:evenodd;stroke:none" />
+ <path
+ style="fill:url(#linearGradient25575);fill-rule:evenodd;stroke:none"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ id="path25567"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="-4" />
+ <path
+ style="fill:url(#linearGradient25577);fill-rule:evenodd;stroke:none"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ id="path25569"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="-4" />
+ <path
+ style="fill:url(#linearGradient25579);fill-rule:evenodd;stroke:none"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ id="path25571"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="4" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25872"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,328.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,111)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="243.92192"
+ y1="-2.6686089"
+ x2="275.10107"
+ y2="26.600887" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25888"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25890"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25892"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25894"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-72.000001)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25929"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25931"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25957"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25961"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-112)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25984"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-88.000005)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient26011"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient26013"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26015"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,-76.000004)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient26077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26083"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26126"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26128"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26130"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="68.383354"
+ y1="239.95235"
+ x2="69.285805"
+ y2="247.29691" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27973"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27975"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28099"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient28107"
+ gradientUnits="userSpaceOnUse"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845"
+ gradientTransform="translate(-19,294.91429)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient27448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-19,294.91429)"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27450"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27540"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27544"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient27598"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient27600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27604"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient27606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient27610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient30389"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30391"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient30393"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient30395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient30397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29129"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27767"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27769"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient27771"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="112.18942"
+ y1="114.71685"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27773"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient31865"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.986122,0,0,0.986122,2.8033684,0.804927)"
+ cx="202"
+ cy="58"
+ fx="202"
+ fy="58"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask31861">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient31865);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path31863"
+ sodipodi:cx="202"
+ sodipodi:cy="58"
+ sodipodi:rx="11"
+ sodipodi:ry="11"
+ d="m 213,58 a 11,11 0 1 1 -22,0 11,11 0 1 1 22,0 z" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath31849">
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 232.13187,93.950853 4.84276,0 4.23742,4.237465 0,4.842822 -9.08018,0 0,-9.080287 0,0 z"
+ id="path31851"
+ sodipodi:nodetypes="cccccc" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ id="filter30544"
+ x="-0.11968782"
+ width="1.2393756"
+ y="-0.12031381"
+ height="1.2406276"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.59634694"
+ id="feGaussianBlur30546" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30552"
+ x="-0.12"
+ width="1.24"
+ y="-0.12"
+ height="1.24"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.4"
+ id="feGaussianBlur30554" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30556"
+ x="-0.12"
+ width="1.24"
+ y="-0.12"
+ height="1.24"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.4"
+ id="feGaussianBlur30558" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30564"
+ x="-0.12000064"
+ width="1.2400013"
+ y="-0.11999936"
+ height="1.2399987"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.36320908"
+ id="feGaussianBlur30566" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter30580"
+ x="-0.11981065"
+ width="1.2396213"
+ y="-0.12018995"
+ height="1.2403799"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.479335"
+ id="feGaussianBlur30582" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32298"
+ gradientUnits="userSpaceOnUse"
+ x1="-117.5"
+ y1="431.5"
+ x2="-119.5"
+ y2="429.5"
+ gradientTransform="translate(258,-96.99999)" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask32294">
+ <rect
+ y="323"
+ x="134"
+ height="16"
+ width="9"
+ id="rect32296"
+ style="fill:url(#linearGradient32298);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53119"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53123"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53125"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient53127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient53129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="362.79037"
+ y1="-159.88834"
+ x2="373.83752"
+ y2="-150.41035" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9900316,0,0,1,2.450297,0.00704954)"
+ x1="343.51892"
+ y1="175.19124"
+ x2="350.97491"
+ y2="183.3365" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53139"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53141"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53143"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53145"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53147"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient53149"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient53151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,115.625,254.97076)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient53157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53159"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient53161"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,237.00668)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53163"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53165"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53171"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient50870"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2e-6,0)"
+ x1="-22.902081"
+ y1="448"
+ x2="-14.000002"
+ y2="448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33427"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="136.04924"
+ y2="121.25749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33429"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient33585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7071068,-0.7071068,0.7071067,0.7071067,-140.04288,401.30258)"
+ x1="458.99997"
+ y1="89.363937"
+ x2="452.63602"
+ y2="90.071045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31356"
+ id="linearGradient33831"
+ gradientUnits="userSpaceOnUse"
+ x1="134.00002"
+ y1="116"
+ x2="142.00002"
+ y2="108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33833"
+ gradientUnits="userSpaceOnUse"
+ x1="124.75568"
+ y1="112.24533"
+ x2="132.97911"
+ y2="120.16792" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33835"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="254.19829"
+ y1="2.1803131"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37475"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37477"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="275.62497"
+ y2="26.679274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37479"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37481"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37483"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37485"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37487"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37489"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37491"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.5793179,0,-1.0159927e-7,-1.6412688,666.67947,207.37331)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37493"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37495"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37497"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37499"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37501"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37503"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37505"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37507"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37509"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3336259,0,-8.5793649e-8,-1.3859393,603.17514,187.32668)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3648614,0,-8.7803051e-8,-1.4184,611.24862,189.87526)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37517"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37519"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient37525"
+ gradientUnits="userSpaceOnUse"
+ x1="337.34329"
+ y1="43.328976"
+ x2="330.27045"
+ y2="35.276588" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37527"
+ gradientUnits="userSpaceOnUse"
+ x1="329.9158"
+ y1="35.5"
+ x2="335.27429"
+ y2="41.570362" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="166.89752"
+ y1="9.0567484"
+ x2="193.26451"
+ y2="38.642647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37531"
+ gradientUnits="userSpaceOnUse"
+ x1="127.93343"
+ y1="122.8346"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37533"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37535"
+ gradientUnits="userSpaceOnUse"
+ x1="122.86111"
+ y1="127.14286"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37537"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37539"
+ gradientUnits="userSpaceOnUse"
+ x1="266"
+ y1="659"
+ x2="285"
+ y2="659" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient37541"
+ gradientUnits="userSpaceOnUse"
+ x1="244.21062"
+ y1="600.74884"
+ x2="244.21062"
+ y2="602.96759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35407"
+ id="linearGradient37543"
+ gradientUnits="userSpaceOnUse"
+ x1="235.29379"
+ y1="588.43396"
+ x2="245.93307"
+ y2="604.52502" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37545"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37547"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37553"
+ gradientUnits="userSpaceOnUse"
+ x1="86.248604"
+ y1="32"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="81"
+ y1="27"
+ x2="64.5"
+ y2="9.0000019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient37557"
+ gradientUnits="userSpaceOnUse"
+ x1="70.78582"
+ y1="15.659542"
+ x2="79.465332"
+ y2="24.480759" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient37559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5997527,0.4726093,-0.6665451,0.8458611,35.480681,-28.765852)"
+ cx="63.013588"
+ cy="14.60904"
+ fx="63.013588"
+ fy="14.60904"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37571"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient37573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="83.261826"
+ y1="502.54196"
+ x2="41.311054"
+ y2="501.10059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient37575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37578"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37580"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2665671,0.04035316,-0.03648524,1.99062,-82.893589,-502.25433)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37588"
+ gradientUnits="userSpaceOnUse"
+ x1="264.10001"
+ y1="330.10001"
+ x2="264.89999"
+ y2="330.89999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient37590"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="51.37524"
+ y1="96.955269"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient37594"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37596"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient37612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37614"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37636"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="387.30396"
+ y1="126.23978"
+ x2="332.88193"
+ y2="123.61623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37640"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42322"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42326"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42328"
+ gradientUnits="userSpaceOnUse"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42330"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42332"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42336"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42338"
+ gradientUnits="userSpaceOnUse"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42340"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42342"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42344"
+ gradientUnits="userSpaceOnUse"
+ x1="-69.457596"
+ y1="31.914484"
+ x2="-76.564636"
+ y2="28.695114" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42346"
+ gradientUnits="userSpaceOnUse"
+ x1="-57.780041"
+ y1="48.005856"
+ x2="-78.812721"
+ y2="31" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42348"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42350"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.2998291,32.548709,64.760571)"
+ x1="51.497997"
+ y1="97.491707"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,79.011866)"
+ x1="51.497997"
+ y1="94.987144"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,83.013491)"
+ x1="51.497997"
+ y1="94.987129"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197983,83.013493)"
+ x1="48.998543"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197981,79.010163)"
+ x1="48.99855"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,42.19798,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196563,83.013493)"
+ x1="48.998539"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196561,79.010163)"
+ x1="48.998547"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,46.19656,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42368"
+ gradientUnits="userSpaceOnUse"
+ x1="-109.125"
+ y1="52.625"
+ x2="-121.73741"
+ y2="38.387074" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42370"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42372"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42374"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42376"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-41,98)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42378"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42380"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42382"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-57.134785,102.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42384"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-92.714287,177.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42386"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42388"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42390"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42392"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient42394"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1226244,0.04761823,-0.1611956,3.8002759,59.188894,-553.59611)"
+ cx="-215.0979"
+ cy="201.01204"
+ fx="-215.0979"
+ fy="201.01204"
+ r="5.8999949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42396"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,4)"
+ x1="-224"
+ y1="201"
+ x2="-214.39445"
+ y2="195.27762" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="209.05762"
+ y1="290.00357"
+ x2="215.34009"
+ y2="277.00357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42400"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42402"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42404"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42408"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42410"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42414"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="133.62697"
+ y2="120.49951" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42418"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42420"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-120,79)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42422"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-136.13478,83.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-171.71429,158.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient42430"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1664.4413"
+ y1="720.01788"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient42432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1977.4047"
+ y2="829.72656" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42436"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42438"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42440"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42442"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42444"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42446"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1658027,0,0,1.1657997,-354.28972,51.94393)"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42462"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42464"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42466"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8370074,0,0,0.8129865,84.784966,-149.92038)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,11.285548,8.325368)"
+ x1="111.03847"
+ y1="57.034107"
+ x2="117.16058"
+ y2="60.591385" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42472"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42474"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42477"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42479"
+ gradientUnits="userSpaceOnUse"
+ x1="-92.587807"
+ y1="-18.005362"
+ x2="-100.62162"
+ y2="-17.998919" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42481"
+ gradientUnits="userSpaceOnUse"
+ x1="-101"
+ y1="-16"
+ x2="-93"
+ y2="-17" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42483"
+ gradientUnits="userSpaceOnUse"
+ x1="-87.491188"
+ y1="-22.830606"
+ x2="-102.96513"
+ y2="-22.166544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42485"
+ gradientUnits="userSpaceOnUse"
+ x1="-98.997849"
+ y1="-23.173643"
+ x2="-98.997849"
+ y2="-25.872688" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42487"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42489"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42491"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42493"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5290924,0,0,0.5294132,-17.313533,46.110999)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42495"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5350034,0,0,0.5349052,24.446207,45.843517)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42497"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42499"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42501"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42503"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42505"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42507"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42509"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42511"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4749148,1.0023386,-1.2226848,-0.4749148,213.62384,41.735193)"
+ x1="118.95689"
+ y1="106.42961"
+ x2="135.14919"
+ y2="119.05286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5333554,1.1220467,-1.1447545,-0.5333554,196.63818,32.816067)"
+ x1="130.39502"
+ y1="116.31751"
+ x2="147.95374"
+ y2="134.687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient42517"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42519"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42521"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42523"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42525"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,26.488451,35.562258)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35408"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35414"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35418"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35420"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35422"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35424"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35468"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35470"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35476"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35478"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35480"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35482"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35484"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35486"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35488"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient34618"
+ gradientUnits="userSpaceOnUse"
+ x1="125.59209"
+ y1="112.6446"
+ x2="133.11621"
+ y2="119.21729" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient34620"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="141.83322"
+ y2="132.30261" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35446"
+ gradientUnits="userSpaceOnUse"
+ x1="31"
+ y1="60.000004"
+ x2="34"
+ y2="54.000004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35448"
+ gradientUnits="userSpaceOnUse"
+ x1="135.46967"
+ y1="118"
+ x2="121.4286"
+ y2="101.14284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35450"
+ gradientUnits="userSpaceOnUse"
+ x1="133.60002"
+ y1="118"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35452"
+ gradientUnits="userSpaceOnUse"
+ x1="132.30316"
+ y1="123.05057"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35454"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35718"
+ x1="28.130203"
+ y1="65.791054"
+ x2="32.5"
+ y2="55.066181"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient36452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,137.60085,-8.4035259)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,131.60084,3.5964741)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36458"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,143.60084,3.5964739)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37095"
+ gradientUnits="userSpaceOnUse"
+ x1="125.75312"
+ y1="111.40558"
+ x2="143.16118"
+ y2="129.27902" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="185.89514"
+ y1="30.343155"
+ x2="197.03207"
+ y2="42.717522" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="188"
+ y1="40.25"
+ x2="180.8125"
+ y2="32.46875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="187.8125"
+ y1="33.9375"
+ x2="184.25"
+ y2="30.15625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3.0999952,2.9000005)"
+ x1="177.85001"
+ y1="33.537502"
+ x2="186.00626"
+ y2="43.381248" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,6.188671,1.0072576)"
+ x1="182.20605"
+ y1="39.645184"
+ x2="172.36885"
+ y2="31.368597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36656"
+ gradientUnits="userSpaceOnUse"
+ x1="181.14906"
+ y1="32.701904"
+ x2="186.00002"
+ y2="37.415516" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,9.438677,-2.4927424)"
+ x1="181.9404"
+ y1="40.924297"
+ x2="175.82253"
+ y2="34.272892" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient36470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36713"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36715"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36721"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36727"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37396"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37398"
+ gradientUnits="userSpaceOnUse"
+ x1="389.51059"
+ y1="241.72565"
+ x2="388.20074"
+ y2="242.55887"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,0)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,-582)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38561">
+ <g
+ id="g38563">
+ <rect
+ y="278"
+ x="-23"
+ height="13"
+ width="16"
+ id="rect38565"
+ style="fill:url(#linearGradient38570);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient38572);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38567"
+ width="16"
+ height="13"
+ x="-23"
+ y="-304" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-1" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-7-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-4-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-4-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-8-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7-6"
+ id="linearGradient39048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="96"
+ y1="42"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-4-2"
+ id="linearGradient39050"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="65"
+ y1="20"
+ x2="66"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-4"
+ id="linearGradient39052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="67.25"
+ y1="18"
+ x2="68"
+ y2="16" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-4-27"
+ id="linearGradient39835-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8422958,0,0,0.8364537,82.535678,2.9394266)"
+ x1="89.975014"
+ y1="-32.339718"
+ x2="88.492455"
+ y2="-33.303608" />
+ <linearGradient
+ id="linearGradient35411-4-27">
+ <stop
+ id="stop35414-0-9"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-9-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39837-4"
+ gradientUnits="userSpaceOnUse"
+ x1="131.02808"
+ y1="123.49161"
+ x2="128.7139"
+ y2="115.97001" />
+ <linearGradient
+ id="linearGradient35411-8-1-3">
+ <stop
+ id="stop35414-2-7-1"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-4-1-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39839-3"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-5-4"
+ id="linearGradient39841-3"
+ gradientUnits="userSpaceOnUse"
+ x1="115.15884"
+ y1="88.476723"
+ x2="109.18613"
+ y2="82.308861" />
+ <linearGradient
+ id="linearGradient23974-5-4">
+ <stop
+ id="stop23976-27-1"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-6-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-8"
+ id="linearGradient39843-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="101"
+ y1="84.25"
+ x2="97.75"
+ y2="81.5" />
+ <linearGradient
+ id="linearGradient1610-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-77"
+ id="linearGradient39845-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="87.44548"
+ y1="81.439644"
+ x2="96.592278"
+ y2="89.708977" />
+ <linearGradient
+ id="linearGradient319-77">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-31" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41540"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient23974-4">
+ <stop
+ id="stop23976-20"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-9"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-37"
+ id="linearGradient32529-7"
+ gradientUnits="userSpaceOnUse"
+ x1="139.2112"
+ y1="111.35809"
+ x2="125.18381"
+ y2="128" />
+ <linearGradient
+ id="linearGradient319-37">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-60" />
+ </linearGradient>
+ <linearGradient
+ y2="125.77761"
+ x2="139.07738"
+ y1="115.76797"
+ x1="129.62384"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient41582"
+ xlink:href="#linearGradient23974-4"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient41666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient41670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41674"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42432"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42435"
+ gradientUnits="userSpaceOnUse"
+ x1="135.45557"
+ y1="122.90726"
+ x2="130.54761"
+ y2="116.54932" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42437"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath42711">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42713"
+ width="8.7252884"
+ height="17.464855"
+ x="127.4093"
+ y="214.76154" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient38796-7-9">
+ <stop
+ style="stop-color:#fc9694;stop-opacity:1;"
+ offset="0"
+ id="stop38798-6-8" />
+ <stop
+ style="stop-color:#e71609;stop-opacity:1;"
+ offset="1"
+ id="stop38800-1-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-87">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-78" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679-1">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681-0" />
+ <stop
+ id="stop24683-7"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38719"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38722"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient38724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.46314"
+ y1="113.45913"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38726"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38007"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-1">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-7"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43410-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43412-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38796-7-9"
+ id="linearGradient40270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="59.622501"
+ y1="54.1525"
+ x2="60.981617"
+ y2="55.566177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="57.789688"
+ y2="54.130001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="56"
+ y2="52.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.54625,-1)"
+ x1="63.666252"
+ y1="37.960625"
+ x2="60.676094"
+ y2="34.685287" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679-1"
+ id="linearGradient40278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="52.17437"
+ y1="65.644958"
+ x2="50.371208"
+ y2="62.960247" />
+ <linearGradient
+ id="linearGradient24143-0">
+ <stop
+ id="stop24145-0"
+ offset="0"
+ style="stop-color:#2c2c2c;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669-1" />
+ <stop
+ id="stop24147-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-3-7"
+ id="linearGradient39686-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-70.605209"
+ y1="-121.58411"
+ x2="-28.177105"
+ y2="-89.026711" />
+ <linearGradient
+ id="linearGradient1610-3-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-9-4"
+ id="linearGradient39688-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-74"
+ y1="-124"
+ x2="-55.5975"
+ y2="-103.2075" />
+ <linearGradient
+ id="linearGradient319-5-9-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-24-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-6">
+ <stop
+ id="stop37544-18"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-92"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-3" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-41" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-1">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-9" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient59371">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop59373" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop59375" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9-1"
+ id="linearGradient42965-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(301.02752,449.99999)"
+ x1="25.963812"
+ y1="155.66899"
+ x2="29.972469"
+ y2="168" />
+ <linearGradient
+ id="linearGradient319-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-92-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-55-5" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter24186-3-2"
+ x="-0.12810811"
+ width="1.2562162"
+ y="-0.11285714"
+ height="1.2257143"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.395"
+ id="feGaussianBlur24188-3-7" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-06-1"
+ id="linearGradient42967-6"
+ gradientUnits="userSpaceOnUse"
+ x1="335.96875"
+ y1="607.09375"
+ x2="337.04251"
+ y2="628.20752" />
+ <linearGradient
+ id="linearGradient1610-06-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41266"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41268"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41270"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient41272"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient40920"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40922"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40924"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40926"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,404.60763,237.35923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient40928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9435203,-2.1990242,1.1704696,1.0049395,-665.14472,173.40654)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40930"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient40932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-6"
+ id="linearGradient36549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1511102,0,0,-1.1511102,152.68442,762.00423)"
+ x1="-16.608393"
+ y1="199.5118"
+ x2="30.713354"
+ y2="245.13458" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="radialGradient36551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6959954,0.116912,-0.04402498,0.2620878,107.60035,414.99606)"
+ cx="32.193073"
+ cy="243.37001"
+ fx="32.193073"
+ fy="243.37001"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143-0"
+ id="linearGradient36553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,147.99998,720.60935)"
+ x1="32.204613"
+ y1="233.6039"
+ x2="35.615856"
+ y2="251.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36555"
+ gradientUnits="userSpaceOnUse"
+ x1="148.76726"
+ y1="134.53409"
+ x2="114.11786"
+ y2="101.28939" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809"
+ id="linearGradient36557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="481.60803"
+ y1="163.09677"
+ x2="477.10818"
+ y2="163.00024" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient59371"
+ id="linearGradient36559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500181,0,0,0.8546123,-235.38338,339.18935)"
+ x1="473.79471"
+ y1="164.64572"
+ x2="463.90472"
+ y2="160.80888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-1"
+ id="linearGradient36561"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36563"
+ gradientUnits="userSpaceOnUse"
+ x1="138.46678"
+ y1="124.90586"
+ x2="126.18426"
+ y2="116.14438" />
+ <linearGradient
+ id="linearGradient9030-7-8-6">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-4-9-2" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-0-2-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809-2-2">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811-1-6" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813-4-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-7-5-5">
+ <stop
+ id="stop20057-1-7-7"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-1-6-8"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-4-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-8-5-8" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-8-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37829">
+ <stop
+ id="stop37831"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop37833" />
+ <stop
+ id="stop37835"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8"
+ id="radialGradient39256"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient39258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ id="linearGradient40455-7">
+ <stop
+ id="stop40457-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36657"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8"
+ id="radialGradient36659"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient36661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient36663"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37829"
+ id="linearGradient37089"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,165.4,716.20935)"
+ x1="261.17639"
+ y1="247.85646"
+ x2="253.86414"
+ y2="288.70752" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39080"
+ id="linearGradient37091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.888884,0,0,-0.8730569,136.66557,688.20759)"
+ x1="261.60016"
+ y1="247.008"
+ x2="263.60016"
+ y2="262.27994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-124.99991,219.9903)"
+ x1="19.923029"
+ y1="232.59058"
+ x2="50.485012"
+ y2="265.9697" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809-2-2"
+ id="linearGradient37096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="199.26254"
+ y1="144.5041"
+ x2="193.7029"
+ y2="144.5041" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-7-5-5"
+ id="linearGradient37098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="579.625"
+ y1="54.299286"
+ x2="576.4375"
+ y2="49.84375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="582.79974"
+ y1="56.363762"
+ x2="575.70361"
+ y2="49.87711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37102"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37104"
+ gradientUnits="userSpaceOnUse"
+ x1="140.78264"
+ y1="123.96156"
+ x2="132.25548"
+ y2="116.40535" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7"
+ id="radialGradient37553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.135666"
+ cy="95.970413"
+ fx="-73.135666"
+ fy="95.970413"
+ r="4.9999957" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37667"
+ id="radialGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4604901,-0.4901463,0.6187826,0.5813434,279.52277,457.42224)"
+ cx="756.98285"
+ cy="206.8443"
+ fx="756.98285"
+ fy="206.8443"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient37558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-94.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758.62622"
+ y2="305.53677" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1"
+ id="radialGradient37553-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.227486"
+ cy="95.949913"
+ fx="-73.227486"
+ fy="95.949913"
+ r="4.9999957" />
+ <linearGradient
+ id="linearGradient40455-7-1">
+ <stop
+ id="stop40457-6-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-7"
+ id="radialGradient37555-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4769848,-0.5257394,0.6056598,0.5494938,269.68012,490.96577)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-9"
+ id="linearGradient37558-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-9">
+ <stop
+ id="stop58336-27"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(1,-94.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37610-3"
+ xlink:href="#linearGradient16500-4"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71834"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient71836"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient37188"
+ gradientUnits="userSpaceOnUse"
+ x1="-22"
+ y1="36.47311"
+ x2="-18.85"
+ y2="22.485678"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.00015,169.99998)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37201"
+ gradientUnits="userSpaceOnUse"
+ x1="-26"
+ y1="38"
+ x2="-27"
+ y2="30.200407"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ id="linearGradient1610-7409">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-488" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-5" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-17" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-1">
+ <stop
+ id="stop58336-5"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-27"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-14">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-23" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-22" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7409"
+ id="linearGradient37317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="272.92456"
+ y2="26.239208" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-5"
+ id="radialGradient37319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-1"
+ id="linearGradient37321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-14"
+ id="linearGradient37323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.1275"
+ y1="301.01553"
+ x2="758.77625"
+ y2="305.51749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37338"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(461.00015,453)"
+ x1="37"
+ y1="53"
+ x2="36.74033"
+ y2="44.322407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37132"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37134"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ id="linearGradient40455-7-1-7">
+ <stop
+ id="stop40457-6-6-4"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-0"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient38362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,2.85168,-84)"
+ x1="-9.3937483"
+ y1="203.3882"
+ x2="28.275171"
+ y2="249.73875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1-7"
+ id="radialGradient38364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1033468,0.01995877,-0.02366572,0.9281732,7.8124646,13.285893)"
+ cx="-73.972397"
+ cy="94.935921"
+ fx="-73.972397"
+ fy="94.935921"
+ r="4.9999957" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38367"
+ gradientUnits="userSpaceOnUse"
+ x1="19.210167"
+ y1="143.17894"
+ x2="38.580528"
+ y2="167.11429"
+ gradientTransform="matrix(1,0,0,0.8461542,0,25.615323)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-7">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-1"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-6">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-49" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38051"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37534"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ id="linearGradient1610-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-18" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-92" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient38254"
+ gradientUnits="userSpaceOnUse"
+ x1="124.19057"
+ y1="111.30384"
+ x2="134.62978"
+ y2="120.14633" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37509"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient37613"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37615"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38073-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-14.752135"
+ y1="101.82622"
+ x2="-45.074585"
+ y2="68.279541" />
+ <linearGradient
+ id="linearGradient15425-4-9-8">
+ <stop
+ style="stop-color:#960000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-8-24" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-8-2-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-1"
+ id="linearGradient38075-5"
+ gradientUnits="userSpaceOnUse"
+ x1="137.33838"
+ y1="124.67571"
+ x2="131.35606"
+ y2="118.00494" />
+ <linearGradient
+ id="linearGradient5060-1">
+ <stop
+ id="stop5062-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-1"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient38077-1"
+ gradientUnits="userSpaceOnUse"
+ x1="127.15736"
+ y1="111.48302"
+ x2="146.01884"
+ y2="136.15825" />
+ <linearGradient
+ id="linearGradient319-52">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-7614" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38079-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-15"
+ y1="101"
+ x2="-22"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418-6"
+ id="linearGradient14433-1"
+ gradientUnits="userSpaceOnUse"
+ x1="139.29807"
+ y1="127.35454"
+ x2="130.33557"
+ y2="115.81818" />
+ <linearGradient
+ id="linearGradient14418-6">
+ <stop
+ id="stop14420-8"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422-5"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14435-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.36379"
+ y1="110.81054"
+ x2="135.22182"
+ y2="120.76331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14437-6"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="141.43347"
+ y2="127.52184" />
+ <filter
+ inkscape:collect="always"
+ id="filter15421-1"
+ x="-0.23999846"
+ width="1.4799969"
+ y="-0.24000154"
+ height="1.4800031"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.29233622"
+ id="feGaussianBlur15423-8" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-2"
+ id="linearGradient14439-9"
+ gradientUnits="userSpaceOnUse"
+ x1="125.20553"
+ y1="111.38132"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ id="linearGradient10069-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-79" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14441-4"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient48327-1"
+ id="radialGradient38306-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4461753,0.01083717,0.0036163,6.752143,-191.34795,-740.3814)"
+ cx="131.99811"
+ cy="126.63337"
+ fx="131.99811"
+ fy="126.63337"
+ r="9.1978254" />
+ <linearGradient
+ id="linearGradient48327-1">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop48329-23" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop48331-3" />
+ </linearGradient>
+ <linearGradient
+ y2="118.69846"
+ x2="132.35237"
+ y1="111.38132"
+ x1="125.20553"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37646-4"
+ xlink:href="#linearGradient10069-74-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient10069-74-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-0-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-9-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-7409-3-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-48-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-82-6-27" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient38313-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient37677"
+ gradientUnits="userSpaceOnUse"
+ x1="130.60338"
+ y1="115.87343"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ id="linearGradient319-19">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-8-3-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-95-2-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-43-7-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-6">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-8-4">
+ <stop
+ id="stop20057-8-0"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-2-0"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39088">
+ <stop
+ id="stop39090"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop39092"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-83">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-24" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-11" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-95">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-10" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-64" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-87" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-42" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40173"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40175"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40282"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38693"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38703"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38706"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-157,821.03125)"
+ x1="-90.5"
+ y1="413.51562"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38720"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3846148,0,0,1,-211.38442,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,821.03125)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-2.4825165)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,824.54874)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39201"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39203"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39205"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39207"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39246"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39248"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39255"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39259"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient38961"
+ gradientUnits="userSpaceOnUse"
+ x1="488.5"
+ y1="568"
+ x2="495"
+ y2="568" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38956">
+ <rect
+ style="fill:url(#linearGradient38961);stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38958"
+ width="16"
+ height="12"
+ x="488"
+ y="560"
+ rx="0"
+ ry="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient39115"
+ gradientUnits="userSpaceOnUse"
+ x1="487.2518"
+ y1="531.95105"
+ x2="490.65796"
+ y2="580.63715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39117"
+ gradientUnits="userSpaceOnUse"
+ x1="496.49335"
+ y1="537.78113"
+ x2="498.40021"
+ y2="540.13623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39119"
+ gradientUnits="userSpaceOnUse"
+ x1="495.85294"
+ y1="541.69116"
+ x2="495.25"
+ y2="539.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-3"
+ id="linearGradient39122"
+ gradientUnits="userSpaceOnUse"
+ x1="494.38467"
+ y1="532.42651"
+ x2="496.21078"
+ y2="541.02698" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703"
+ id="linearGradient39261"
+ gradientUnits="userSpaceOnUse"
+ x1="122.25188"
+ y1="106.08706"
+ x2="147.08464"
+ y2="134.12131" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39263"
+ gradientUnits="userSpaceOnUse"
+ x1="116.75861"
+ y1="97.375854"
+ x2="145.729"
+ y2="137.52937" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39265"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient319-46">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-03" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-62" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-46"
+ id="linearGradient39508"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,0)"
+ x1="39.102718"
+ y1="641.73358"
+ x2="58.680996"
+ y2="661.93829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43807"
+ id="linearGradient39518"
+ gradientUnits="userSpaceOnUse"
+ x1="648.09674"
+ y1="355.85541"
+ x2="634.09503"
+ y2="341.23715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39088"
+ id="linearGradient39520"
+ gradientUnits="userSpaceOnUse"
+ x1="696.63055"
+ y1="403.93069"
+ x2="643.71313"
+ y2="349.93216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-95"
+ id="linearGradient39523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.8461523,99.385524,54.308237)"
+ x1="633.10468"
+ y1="338.95337"
+ x2="649.69073"
+ y2="354.92981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39716"
+ gradientUnits="userSpaceOnUse"
+ x1="121.80637"
+ y1="106.4641"
+ x2="142.1468"
+ y2="132.44617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39718"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40297"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask40306">
+ <path
+ id="path40308"
+ d="m 195,11.00001 0,14 0.5,0 13.5,-13.5 0,-0.5 -14,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703-5-5"
+ id="linearGradient39261-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="128.09367"
+ y1="112.43961"
+ x2="145.20987"
+ y2="133.4879" />
+ <linearGradient
+ id="linearGradient40703-5-5">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705-8-2" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707-8-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38252-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38254-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38256-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient40511-7-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ id="linearGradient1610-74-9-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-0-8-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-9-3-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient40507-4-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-8-6-5">
+ <stop
+ id="stop58336-8-9-2"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-24-8-7"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient40649-2-6-6"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-5-6-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-17-2-4" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-11-3-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient40502-7-8-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40635-7-2-2"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ id="linearGradient319-5-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-2-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-7-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40637-9-5-8"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <filter
+ inkscape:collect="always"
+ id="filter13996-9-7-7"
+ x="-0.23644176"
+ width="1.4728835"
+ y="-0.24368355"
+ height="1.4873672"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.29550651"
+ id="feGaussianBlur13998-5-8-6" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973-3-7-8"
+ id="linearGradient40639-1-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.2239"
+ y1="112.62726"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ id="linearGradient13973-3-7-8">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975-1-8-9" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977-2-0-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40641-9-2-7"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient41638-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient41640-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient41642-5-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient41644-5-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40875-3-9-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ id="linearGradient37542-3-0-7-6">
+ <stop
+ id="stop37544-1-6-6-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-2-1-7-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40877-5-5-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ id="linearGradient319-34-8-7-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-11-9-8-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-38-3-1-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40879-9-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="171.50414"
+ y2="248.54021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40881-8-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-7-6-7-4"
+ id="radialGradient40883-4-0-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.06118084,-0.8594818,2.4629674,-0.1753088,-259.40057,190.15309)"
+ cx="77.721619"
+ cy="104.09358"
+ fx="77.721619"
+ fy="104.09358"
+ r="3.9999998" />
+ <linearGradient
+ id="linearGradient10069-7-6-7-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-81-3-2-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-6-7-5-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39136-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39138-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39140-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="174.35753"
+ y2="250.6842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39143-0-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <linearGradient
+ id="linearGradient319-17-1-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40679"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25417"
+ id="linearGradient40731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.997161,-259.00079,67.35344)"
+ x1="280.0918"
+ y1="129.28557"
+ x2="267.20212"
+ y2="116.41341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40733"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-7"
+ id="linearGradient40733-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-8"
+ id="linearGradient40733-03"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40897">
+ <rect
+ y="198"
+ x="-41"
+ height="16"
+ width="15"
+ id="rect40899"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40902">
+ <rect
+ y="197"
+ x="-22"
+ height="17"
+ width="15"
+ id="rect40904"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38478"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(254.01612,-211.00101)"
+ x1="96.824379"
+ y1="393.90298"
+ x2="94.246101"
+ y2="391.21976" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38474">
+ <rect
+ style="fill:url(#linearGradient38478);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38476"
+ width="15"
+ height="15"
+ x="343.01611"
+ y="174.99901" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44320"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42992"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7"
+ id="linearGradient42994"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(4.9999967,20)"
+ x1="-114.75"
+ y1="546.5"
+ x2="-110.5"
+ y2="542.5" />
+ <linearGradient
+ id="linearGradient44627">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop44629" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop44631" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9-7-4-74">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44402"
+ gradientUnits="userSpaceOnUse"
+ x1="351.15625"
+ y1="108.35222"
+ x2="345.40625"
+ y2="108.00847" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44404"
+ gradientUnits="userSpaceOnUse"
+ x1="351.71875"
+ y1="106.93575"
+ x2="347.1875"
+ y2="106.7795" />
+ <filter
+ inkscape:collect="always"
+ id="filter44473"
+ x="-0.12578467"
+ width="1.2515693"
+ y="-0.11472401"
+ height="1.229448"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.81235925"
+ id="feGaussianBlur44475" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter44477"
+ x="-0.12176471"
+ width="1.2435294"
+ y="-0.11828571"
+ height="1.2365714"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.8625"
+ id="feGaussianBlur44479" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44485"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="284.5"
+ y2="106.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44942"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="351.71875"
+ y1="106.93575"
+ x2="339.125"
+ y2="105.092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44944"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,698,183)"
+ x1="351.15625"
+ y1="108.35222"
+ x2="336.40625"
+ y2="106.19597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44950"
+ gradientUnits="userSpaceOnUse"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102"
+ gradientTransform="matrix(-1,0,0,1,593.02125,-1.8e-6)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44954"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath45147">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccc"
+ id="path45149"
+ d="m 5,261 13,0 0,1 -1,0 0,1 1,0 0,1 -1,0 0,1 -1,0 0,2 2,0 0,-1 1,0 0,-1 1,0 0,1 1,0 0,-1 1,0 0,13 -17,0 0,-17 z"
+ style="opacity:0.2;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient45220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,221,10)"
+ x1="115.84575"
+ y1="10.8125"
+ x2="106.125"
+ y2="19.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45283"
+ gradientUnits="userSpaceOnUse"
+ x1="125.86876"
+ y1="111.85698"
+ x2="130.88379"
+ y2="121.70699" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45285"
+ gradientUnits="userSpaceOnUse"
+ x1="134.78751"
+ y1="122.29202"
+ x2="132.60205"
+ y2="117.96092" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74"
+ id="radialGradient45309"
+ cx="336.42892"
+ cy="611.10455"
+ fx="336.42892"
+ fy="611.10455"
+ r="5.9852905"
+ gradientTransform="matrix(1.0070601,0.03386866,-0.03770425,1.1211085,20.665977,-85.772965)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627"
+ id="linearGradient43826"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,1444.9824,-215)"
+ x1="689.47357"
+ y1="427"
+ x2="685.47357"
+ y2="427" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43822">
+ <rect
+ y="208"
+ x="754"
+ height="9"
+ width="12"
+ id="rect43824"
+ style="opacity:0.93999993;fill:url(#linearGradient43826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient43856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient43858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46780"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46782"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46784"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46786"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46822"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46824"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46992"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46994"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient47000"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25106"
+ gradientUnits="userSpaceOnUse"
+ x1="408.91928"
+ y1="373.01221"
+ x2="410.55432"
+ y2="375.5058" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25117"
+ gradientUnits="userSpaceOnUse"
+ x1="411.05389"
+ y1="375.39175"
+ x2="407.62576"
+ y2="370.21317" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient25449"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25451"
+ gradientUnits="userSpaceOnUse"
+ x1="436.54755"
+ y1="524.30481"
+ x2="434.49387"
+ y2="519.46057" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25453"
+ gradientUnits="userSpaceOnUse"
+ x1="432.0849"
+ y1="524.97125"
+ x2="433"
+ y2="526" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="410.73904"
+ cy="370.11554"
+ fx="410.73904"
+ fy="370.11554"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="292.25"
+ y1="106.5"
+ x2="289.5"
+ y2="109.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24341"
+ x1="413.9498"
+ y1="386.45807"
+ x2="406.7699"
+ y2="374.42419"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24349"
+ gradientUnits="userSpaceOnUse"
+ x1="403.9577"
+ y1="367.62839"
+ x2="413.98795"
+ y2="374.07153" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6"
+ id="radialGradient24354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6402148,-1.1088846,0.8413297,0.4857498,104.42892,800.46622)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient24511"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24513"
+ gradientUnits="userSpaceOnUse"
+ x1="256.90005"
+ y1="80.100891"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient24515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24519"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6691529,0,4.3047361e-8,0.6954014,84.50351,24.951375)"
+ cx="259.02887"
+ cy="77.962585"
+ fx="259.02887"
+ fy="77.962585"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3879142,0,8.9286134e-8,1.4423572,-101.87942,-32.970267)"
+ cx="259.55096"
+ cy="77.188034"
+ fx="259.55096"
+ fy="77.188034"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="240.70209"
+ y1="-9.4293213"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient25056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient25058"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25060"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient29407"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29409"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29411"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient29413"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient44939-8-7-1-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient37396-1"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ id="linearGradient37542-7">
+ <stop
+ id="stop37544-40"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-94"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient15742-5"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998"
+ gradientTransform="matrix(0,1,-1,0,634.98585,-146.00607)" />
+ <linearGradient
+ id="linearGradient37542-5">
+ <stop
+ id="stop37544-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-71"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27860"
+ x1="392.02036"
+ y1="241.13428"
+ x2="386.30408"
+ y2="241.31801"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient27872"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27874"
+ gradientUnits="userSpaceOnUse"
+ x1="390.87131"
+ y1="241.13428"
+ x2="386.74603"
+ y2="242.46706"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient27886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,146.99795,-188.00607)"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27896"
+ id="linearGradient27902"
+ x1="388.70071"
+ y1="244.85669"
+ x2="391.17557"
+ y2="249.54126"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient10069-9-71">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-2">
+ <stop
+ id="stop23976-2"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath28964">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient28968);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 117.50984,228.63415 0,-15.01646 11.71735,5.49383 0,15.38271 -11.71735,-5.86008 z"
+ id="path28966" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-2"
+ id="linearGradient28968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ id="linearGradient319-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-26.511335"
+ y1="257.99881"
+ x2="-30.075666"
+ y2="259.87677" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29419">
+ <path
+ id="path29422"
+ d="m 117.50984,229.00041 0,-15.38272 11.71735,5.49383 0,15.74897 -11.71735,-5.86008 z"
+ style="opacity:0.5;fill:url(#linearGradient29424);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient29988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-35.153767"
+ y1="271.58572"
+ x2="-23.636715"
+ y2="252.03563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5"
+ id="linearGradient29990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-113.93222,176.71918)"
+ x1="446.93222"
+ y1="105.28082"
+ x2="441.93222"
+ y2="120.28082" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-71"
+ id="linearGradient29994"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="131.72171"
+ y2="118.18078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6-8"
+ id="linearGradient29773-5"
+ gradientUnits="userSpaceOnUse"
+ x1="124.78239"
+ y1="111.13178"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ id="linearGradient21327-6-8">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3-4" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28526">
+ <stop
+ id="stop28528"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop28530"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-52-2">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-32-8" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-46-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient29334"
+ gradientUnits="userSpaceOnUse"
+ x1="121.74819"
+ y1="104.14172"
+ x2="140.18503"
+ y2="126.89457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient29336"
+ gradientUnits="userSpaceOnUse"
+ x1="155.10138"
+ y1="91.071259"
+ x2="122.40444"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient29338"
+ gradientUnits="userSpaceOnUse"
+ x1="124.66362"
+ y1="126.19594"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29340"
+ gradientUnits="userSpaceOnUse"
+ x1="124.28249"
+ y1="126.88889"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29342"
+ gradientUnits="userSpaceOnUse"
+ x1="147.25899"
+ y1="101.45953"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1138.1963"
+ y1="287.70486"
+ x2="1146.6705"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1286)"
+ x1="757.2467"
+ y1="367.52411"
+ x2="740.30865"
+ y2="405.3895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="745.48267"
+ y1="396.45972"
+ x2="737.62225"
+ y2="401.90442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient28583"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-239.00001,1286)"
+ x1="743"
+ y1="402"
+ x2="752"
+ y2="400" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38845"
+ id="linearGradient28589"
+ gradientUnits="userSpaceOnUse"
+ x1="162.41054"
+ y1="413.87982"
+ x2="161.83331"
+ y2="406.47784"
+ gradientTransform="matrix(0,1,-1,0,574.99991,384.00001)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="743.87036"
+ y1="396.04428"
+ x2="744.1059"
+ y2="423.54419" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,719.99999,383.00001)"
+ x1="148.56801"
+ y1="544.21143"
+ x2="163.11441"
+ y2="569.18829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28603"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1141.2856"
+ y1="288.19919"
+ x2="1146.2682"
+ y2="291.35333" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-52-2"
+ id="radialGradient29805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.94105289,0.01178942,-0.01073736,0.8570756,238.4669,249.70522)"
+ cx="-30.028414"
+ cy="19.425121"
+ fx="-30.028414"
+ fy="19.425121"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29801">
+ <rect
+ style="opacity:0.35;color:#000000;fill:url(#radialGradient29805);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.71217775;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect29803"
+ width="15"
+ height="16"
+ x="204"
+ y="257" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29884"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29886"
+ gradientUnits="userSpaceOnUse"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath50172-0">
+ <path
+ id="path50174-8"
+ d="m -177.34375,498 a 1.001098,1.001098 0 1 0 0.0937,2 l 3.65625,0 -4.25,5.9375 a 1.0001,1.0001 0 0 0 -0.1875,0.59375 l 0,0.5 a 1.0001,1.0001 0 0 0 1,1 L -171.75,508 a 1.0001,1.0001 0 1 0 0,-2 l -3.6875,0.0312 4.25,-5.9375 A 1.0001,1.0001 0 0 0 -171,499.5 l 0,-0.5 a 1.0001,1.0001 0 0 0 -1,-1 l -5.25,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
+ </clipPath>
+ <filter
+ color-interpolation-filters="sRGB"
+ inkscape:collect="always"
+ id="filter50168-9"
+ x="-0.26459751"
+ width="1.529195"
+ y="-0.21958679"
+ height="1.4391736">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.0769376"
+ id="feGaussianBlur50170-2" />
+ </filter>
+ <radialGradient
+ id="radialGradient16142-7"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16144-4" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16146-0" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient37542-78">
+ <stop
+ id="stop37544-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-78"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-0" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-89" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-04-82">
+ <stop
+ id="stop37544-9-0"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-4-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-38-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-6-7" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-9-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30766-8"
+ inkscape:collect="always">
+ <stop
+ id="stop30768-7"
+ offset="0"
+ style="stop-color:#be0000;stop-opacity:1" />
+ <stop
+ id="stop30770-8"
+ offset="1"
+ style="stop-color:#ff5108;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30752-0">
+ <stop
+ style="stop-color:#0c1b63;stop-opacity:1;"
+ offset="0"
+ id="stop30754-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop30756-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-64,-10)"
+ x1="18.773417"
+ y1="6.2494373"
+ x2="6.9718256"
+ y2="17.82831" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.701513,0.712657,0.712657,0.701513,50.5916,-449.6745)"
+ x1="385.62408"
+ y1="244.3396"
+ x2="401.63013"
+ y2="244.38875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-65.00001,-10.749995)"
+ x1="61.032951"
+ y1="5.9830923"
+ x2="46.491322"
+ y2="20.147326" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32146"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.199998,0,0,1.199999,-74.19988,-12.499988)"
+ x1="59.02124"
+ y1="6.0129876"
+ x2="44.509518"
+ y2="20.110929" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32148"
+ gradientUnits="userSpaceOnUse"
+ x1="47.348152"
+ y1="-25.553123"
+ x2="53.567928"
+ y2="-31.095215" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142-7"
+ id="linearGradient31946"
+ gradientUnits="userSpaceOnUse"
+ x1="-176.1799"
+ y1="508.33572"
+ x2="-193.07495"
+ y2="482.27924" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142"
+ id="linearGradient31948"
+ gradientUnits="userSpaceOnUse"
+ x1="-178.00789"
+ y1="505.36523"
+ x2="-194.90294"
+ y2="479.30875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-78"
+ id="linearGradient31950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="155.37498"
+ y1="230.51552"
+ x2="181.25543"
+ y2="269.24564" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-04-82"
+ id="linearGradient31954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-354.13606,119.42158)"
+ x1="148.47061"
+ y1="217.28368"
+ x2="171.77303"
+ y2="250.87756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-38-2"
+ id="linearGradient31956"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="-259.99872"
+ y1="340.81195"
+ x2="-253.90541"
+ y2="345.10736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30766-8"
+ id="linearGradient31958"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0017964,0,0,0.99629977,-0.31613165,0.94171311)"
+ x1="167.51979"
+ y1="252.44223"
+ x2="170.78137"
+ y2="261.69635" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31960"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.473038"
+ y1="238.21507"
+ x2="89.889603"
+ y2="243.80345" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30752-0"
+ id="linearGradient31962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.53265"
+ y1="244.52007"
+ x2="168.53265"
+ y2="239.5473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-237.5,45.5045)"
+ x1="263.35254"
+ y1="19.495501"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31966"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-238,44.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-243.5,51.5045)"
+ x1="260.25369"
+ y1="11.017987"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31970"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-244,50.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31972"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-57.00003,-165.99191)"
+ x1="85.853188"
+ y1="239.5473"
+ x2="90.563423"
+ y2="242.99191" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31974"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-51,-172)"
+ x1="88"
+ y1="240.90625"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28526"
+ id="linearGradient32236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-175.72238"
+ y1="66.323799"
+ x2="-183.03308"
+ y2="66.235535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-8-4"
+ id="linearGradient32238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-174.51762"
+ y1="66.654762"
+ x2="-183.58472"
+ y2="65.917358" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62"
+ id="linearGradient32240"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,406.86085,228.58514)"
+ x1="-180.7581"
+ y1="63.445515"
+ x2="-169.07387"
+ y2="62.182106" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.861107"
+ y2="-15.138513" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.705353"
+ y2="-15.562586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29312"
+ id="linearGradient32246"
+ gradientUnits="userSpaceOnUse"
+ x1="242.99834"
+ y1="291.5047"
+ x2="244.75"
+ y2="291.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29304"
+ id="linearGradient32248"
+ gradientUnits="userSpaceOnUse"
+ x1="245.20622"
+ y1="294.49902"
+ x2="243.5"
+ y2="294.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32299"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32301"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.000005,-120)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32303"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-9.025729,344.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient32305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-14.983875,337)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32353"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32355"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32357"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,39.488451,313.56226)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32359"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32426"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32428"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32430"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.77915445,-6.9426235e-4,0.00527501,0.79821029,158.94945,341.39422)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7"
+ id="linearGradient32434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="84.95932"
+ y2="122.23821" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.14826,118.6716)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.74301467,-0.74301467,0.74301467,0.74301467,250.58064,118.02214)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-19-1"
+ id="linearGradient32854-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1666676,0,0,-1.1666676,119.15081,827.66691)"
+ x1="262.04343"
+ y1="233.0448"
+ x2="273.85818"
+ y2="247.32738" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-19-1">
+ <stop
+ id="stop37544-48-6-1-8-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-6-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-7-8-3-0-3"
+ id="linearGradient32856-3-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,-249.10439,522.04547)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient44939-8-4-7-8-3-0-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-40-2-4-2-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-9-4-9-8-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-4-6-5-0-3"
+ id="linearGradient32858-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,144.9138,-563.9364)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-4-6-5-0-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-58-5-9-1-2-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-0-8-0-4-9" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52637-8-8">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52641-2-8);fill-opacity:1;stroke:none;stroke-width:2.79999995000000010;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52639-8-9"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52641-2-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-361.27885,-161.73915)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-0-9-9">
+ <stop
+ id="stop37544-48-6-1-4-1-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-9-3-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient52998-5-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-307"
+ y1="475"
+ x2="-303.00003"
+ y2="463.92236" />
+ <linearGradient
+ id="linearGradient319-31-8-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-23-2-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-34-4-4-2" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52879-0-5">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52883-6-8);fill-opacity:1;stroke:none;stroke-width:2.79999995000000010;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52881-7-3"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354.95001"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52883-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-362.22886,-161.73912)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient53000-3-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-308.7684"
+ y1="476.0105"
+ x2="-304.76843"
+ y2="464.93286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34488-1-8"
+ id="linearGradient53002-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-839.95,-273.25)"
+ x1="469.49295"
+ y1="-101.22778"
+ x2="470.7515"
+ y2="-102.52942" />
+ <linearGradient
+ id="linearGradient34488-1-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop34490-0-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop34492-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32877-9-6-8"
+ id="linearGradient32896-0-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-217.1391"
+ y1="626.39844"
+ x2="-213.69197"
+ y2="623.21643" />
+ <linearGradient
+ id="linearGradient32877-9-6-8">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0"
+ id="stop32879-8-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop32881-4-3-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-4-9-5"
+ id="linearGradient32899-8-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-180.37465"
+ y1="650.94128"
+ x2="-177.70576"
+ y2="653.27765" />
+ <linearGradient
+ id="linearGradient33058-4-9-5">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-3-3-9" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-9-4-7" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32901-4-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1748275,-1.7208853,0.51495275,0.35155123,-289.20197,69.961171)"
+ cx="-197.66467"
+ cy="630.61389"
+ fx="-197.66467"
+ fy="630.61389"
+ r="7.03125" />
+ <linearGradient
+ id="linearGradient44939-8-4-8-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-0-0-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-8-6-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-2-7-1-7"
+ id="linearGradient32903-6-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-218.31921"
+ y1="624.84143"
+ x2="-215.31401"
+ y2="628.46533" />
+ <linearGradient
+ id="linearGradient33058-2-7-1-7">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-1-8-8-5" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-4-3-4-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32905-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.62164476,0.39733376,-0.55111069,0.86222272,269.0477,166.72227)"
+ cx="-202.18748"
+ cy="627"
+ fx="-202.18748"
+ fy="627"
+ r="7.03125" />
+ <linearGradient
+ y2="-102.52942"
+ x2="470.73633"
+ y1="-101.3037"
+ x1="469.52335"
+ gradientTransform="translate(-829.95,-273.25)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient58927"
+ xlink:href="#linearGradient34488-1-8"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-71-6-9-7"
+ id="linearGradient21875-7-1-0-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="278.34866"
+ y2="32.902874" />
+ <linearGradient
+ id="linearGradient1610-71-6-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-26-8-5-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-04-8-8-0" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106-9-2-9-9">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850-4-7-0-4"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011-6-7-0-8"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013-0-1-0-8" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-6-6-2-4"
+ id="linearGradient21877-3-2-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ id="linearGradient5060-6-6-2-4">
+ <stop
+ id="stop5062-2-0-5-5"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-4-4-5-5"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4671-6-4-1-7"
+ id="linearGradient34959-9-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1666.1765"
+ y1="639.65356"
+ x2="1659.0875"
+ y2="629.23273" />
+ <linearGradient
+ id="linearGradient4671-6-4-1-7">
+ <stop
+ id="stop4673-7-6-4-1"
+ offset="0"
+ style="stop-color:#ffd43b;stop-opacity:1;" />
+ <stop
+ id="stop4675-8-0-8-1"
+ offset="1"
+ style="stop-color:#ffe873;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4689-1-6-4-2"
+ id="linearGradient34961-3-6-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1641.4773"
+ y1="607.50525"
+ x2="1663.2872"
+ y2="626.40344" />
+ <linearGradient
+ id="linearGradient4689-1-6-4-2">
+ <stop
+ id="stop4691-6-2-6-7"
+ offset="0"
+ style="stop-color:#5a9fd4;stop-opacity:1;" />
+ <stop
+ id="stop4693-0-4-8-6"
+ offset="1"
+ style="stop-color:#306998;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34963-5-9-1"
+ gradientUnits="userSpaceOnUse"
+ x1="922.89703"
+ y1="339.66599"
+ x2="924.10608"
+ y2="344.10001" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-88-8-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-2-5-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34965-1-5-2"
+ gradientUnits="userSpaceOnUse"
+ x1="919.09998"
+ y1="345.42163"
+ x2="922.104"
+ y2="355.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-8-9-5-5"
+ id="linearGradient34967-4-1-8"
+ gradientUnits="userSpaceOnUse"
+ x1="922.64624"
+ y1="342.71866"
+ x2="921.82654"
+ y2="341.98108" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-8-9-5-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-9-8-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-0-2-8-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34969-4-4-1"
+ gradientUnits="userSpaceOnUse"
+ x1="917.75"
+ y1="355.5"
+ x2="917.25"
+ y2="353" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34971-5-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="923"
+ y1="343.75"
+ x2="923"
+ y2="344.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="radialGradient34973-2-5-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4166677,-7.678944e-6,1.853542e-6,0.58333478,-1309.0016,145.80659)"
+ cx="924"
+ cy="349.20001"
+ fx="924"
+ fy="349.20001"
+ r="6" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34975-9-4-9"
+ gradientUnits="userSpaceOnUse"
+ x1="921.34045"
+ y1="341.34042"
+ x2="922.16492"
+ y2="342.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-4-6-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-2-4-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-3-5-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-2-6-4-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-1-1-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-6-5-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-45-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-5-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-1-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-1-1-9-4-7-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-74-7-2-2-2-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-09-4-7-5-1-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-4-0-5-2-4-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-8-9-4-6-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-8-4-3-8-9-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-24-8-2-6-0-2">
+ <stop
+ id="stop58336-55-8-3-6-3-3"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-17-2-3-3-0-2"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-11-1-4-3-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-5-1-5-5-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-27-3-6-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-1-7-5-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-7-4-3-6-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-1-2-5-7-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-5-7-6-8-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-2-9-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-7-3-4-6-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-8-9-6-4-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-2-8-2-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-4-6-6-1-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-4"
+ id="linearGradient15131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9999519,0,0,0.9998051,-33.244333,253.26813)"
+ x1="101.21339"
+ y1="68.783279"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ id="linearGradient37542-4">
+ <stop
+ id="stop37544-180"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-62"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-2"
+ id="linearGradient15133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0910287,0,0,1.0900105,41.555722,244.97315)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ id="linearGradient319-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-72" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10585-5"
+ id="linearGradient15135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.032977,0,0,1,128.82015,107.77516)"
+ x1="12.330792"
+ y1="246.97107"
+ x2="41.654194"
+ y2="247.3784" />
+ <linearGradient
+ id="linearGradient10585-5">
+ <stop
+ id="stop10587-5"
+ offset="0.0000000"
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10595-5"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-0"
+ id="linearGradient15123"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ id="linearGradient1610-0">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-6" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-42" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-0"
+ id="radialGradient15125"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-0">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-61" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-46"
+ id="linearGradient15127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-46">
+ <stop
+ id="stop58336-9"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-5"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-46"
+ id="linearGradient15129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-46">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-4" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0-4"
+ id="linearGradient14559-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="56.069553" />
+ <linearGradient
+ id="linearGradient319-19-0-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865-0-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0-4"
+ id="linearGradient14561-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14482-2"
+ id="linearGradient14563-3"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55806"
+ y1="94.884857"
+ x2="149.53032"
+ y2="101.436" />
+ <linearGradient
+ id="linearGradient14482-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14484-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14486-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7-1-2"
+ id="linearGradient14565-5"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ id="linearGradient319-95-2-7-1-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.75675678;"
+ offset="0"
+ id="stop320-43-7-3-3-3" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4-1-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3-0-3"
+ id="linearGradient14567-8"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ id="linearGradient10069-8-3-3-0-3">
+ <stop
+ style="stop-color:#764511;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7-1-8" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1-0-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-19-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14482">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14484" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14486" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-95-2-7-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.75675678;"
+ offset="0"
+ id="stop320-43-7-3-3" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-8-3-3-0">
+ <stop
+ style="stop-color:#764511;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7-1" />
+ <stop
+ style="stop-color:#915515;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15098">
+ <stop
+ style="stop-color:#646464;stop-opacity:1;"
+ offset="0"
+ id="stop15100" />
+ <stop
+ style="stop-color:#fcfcfc;stop-opacity:1;"
+ offset="1"
+ id="stop15102" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7-0"
+ id="linearGradient26282-0-8"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ id="linearGradient13998-7-0">
+ <stop
+ id="stop14000-1-1"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002-0-0"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7-0"
+ id="linearGradient26284-9-6"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7-2"
+ id="linearGradient26286-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ id="linearGradient319-7-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-5-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-5-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7-2"
+ id="linearGradient26288-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7"
+ id="linearGradient26282-0"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ id="linearGradient13998-7">
+ <stop
+ id="stop14000-1"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002-0"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-7"
+ id="linearGradient26284-9"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7"
+ id="linearGradient26286-4"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ id="linearGradient319-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7"
+ id="linearGradient26288-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74-8"
+ id="radialGradient45309-0"
+ cx="336.42892"
+ cy="611.10455"
+ fx="336.42892"
+ fy="611.10455"
+ r="5.9852905"
+ gradientTransform="matrix(1.0070601,0.03386866,-0.03770425,1.1211085,20.665977,-85.772965)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient10069-9-7-4-74-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9-1-2"
+ id="linearGradient42965-7-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(301.02752,449.99999)"
+ x1="25.963812"
+ y1="155.66899"
+ x2="29.972469"
+ y2="168" />
+ <linearGradient
+ id="linearGradient319-9-1-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-92-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-55-5-8" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter24186-3-2-5"
+ x="-0.12810811"
+ width="1.2562162"
+ y="-0.11285714"
+ height="1.2257143"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.395"
+ id="feGaussianBlur24188-3-7-6" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-06-1-5"
+ id="linearGradient42967-6-4"
+ gradientUnits="userSpaceOnUse"
+ x1="335.96875"
+ y1="607.09375"
+ x2="337.04251"
+ y2="628.20752" />
+ <linearGradient
+ id="linearGradient1610-06-1-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-4-2" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1-2-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-12-5"
+ id="linearGradient42487-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ id="linearGradient319-12-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-34-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-81-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-8-7"
+ id="linearGradient42489-5-9"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ id="linearGradient15425-8-7">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-9" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-7-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-12-5"
+ id="linearGradient42491-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-8-7"
+ id="linearGradient17232-8"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="141.64546"
+ y2="130.81215" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-31-8"
+ id="radialGradient37501-4-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ id="linearGradient319-35-31-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-38-14-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-94-6-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-31-8"
+ id="linearGradient37503-1-1-1"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-08-1"
+ id="radialGradient37501-4-9-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ id="linearGradient319-35-08-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-38-1-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-94-1-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-08-1"
+ id="linearGradient37503-1-9-9"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-0"
+ id="radialGradient37501-4-64"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ id="linearGradient319-35-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-38-15" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-94-19" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-35-0"
+ id="linearGradient37503-1-7"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ id="linearGradient18105-2-9">
+ <stop
+ id="stop18107-8-4"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109-1-4"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15531-9-5">
+ <stop
+ style="stop-color:#20539d;stop-opacity:1"
+ offset="0"
+ id="stop15534-1-3" />
+ <stop
+ style="stop-color:#bdc9df;stop-opacity:1"
+ offset="1"
+ id="stop15537-7-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-27-5">
+ <stop
+ id="stop23976-25-8"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-48-3"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient27277-1-8">
+ <stop
+ id="stop27279-5-2"
+ offset="0"
+ style="stop-color:#444444;stop-opacity:1;" />
+ <stop
+ id="stop27281-4-1"
+ offset="1"
+ style="stop-color:#adadad;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-63-5">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-9-2" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-6-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27301-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27303-3-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27305-7-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15530-7"
+ id="linearGradient15537-5"
+ x1="223.00443"
+ y1="252.2876"
+ x2="222.72559"
+ y2="247.07268"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.1092502,-0.02900917)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15530-7">
+ <stop
+ style="stop-color:#16396d;stop-opacity:1"
+ offset="0"
+ id="stop15533-4" />
+ <stop
+ style="stop-color:#739ad4;stop-opacity:1"
+ offset="1"
+ id="stop15535-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-40-9">
+ <stop
+ id="stop37544-6-0"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1" />
+ <stop
+ id="stop37546-3-3"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-84-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-78-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-30-96" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-84-3-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-78-3-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-30-9-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38342-8"
+ id="linearGradient15502-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1386698,0,0,1.1421744,-30.9218,-35.447285)"
+ x1="214.40482"
+ y1="253.6573"
+ x2="225.75406"
+ y2="244.98485" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient38342-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38344-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38346-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15482-65"
+ id="linearGradient15474-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.625,0,0,1,355.875,184)"
+ x1="-174.15565"
+ y1="68.784225"
+ x2="-185.42635"
+ y2="63.762562" />
+ <linearGradient
+ id="linearGradient15482-65">
+ <stop
+ id="stop15484-4"
+ offset="0"
+ style="stop-color:#2869ab;stop-opacity:1" />
+ <stop
+ id="stop15486-2"
+ offset="1"
+ style="stop-color:#a7c8f0;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-6-11"
+ id="linearGradient15467-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.56865388,0,0,0.77023595,345.79076,197.07321)"
+ x1="-182.5201"
+ y1="63.631611"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ id="linearGradient319-6-11">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-73-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-51-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15595-7"
+ id="linearGradient15601-9"
+ x1="248.04936"
+ y1="256.02081"
+ x2="238.4982"
+ y2="243.66418"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient15595-7">
+ <stop
+ style="stop-color:#1b4685;stop-opacity:1;"
+ offset="0"
+ id="stop15597-5" />
+ <stop
+ style="stop-color:#183e75;stop-opacity:0;"
+ offset="1"
+ id="stop15599-3" />
+ </linearGradient>
+ <linearGradient
+ y2="65.529938"
+ x2="-162.92078"
+ y1="62.360832"
+ x1="-191.30537"
+ gradientTransform="matrix(0.56865388,0,0,0.9414558,346.44835,191.39968)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient15576-5"
+ xlink:href="#linearGradient319-6-1-5"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-6-1-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-73-4-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-51-8-0" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(-0.04936017,-0.02079917)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient15614-7"
+ id="linearGradient15620-8"
+ x1="194.98087"
+ y1="238.83058"
+ x2="195.88264"
+ y2="253.1198"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15614-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15616-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15618-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-64-7"
+ id="linearGradient42432-3-3"
+ gradientUnits="userSpaceOnUse"
+ x1="248.20378"
+ y1="275.71143"
+ x2="238.40068"
+ y2="262.12378" />
+ <linearGradient
+ id="linearGradient1610-64-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-29-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15275-9"
+ id="linearGradient15281-5"
+ gradientUnits="userSpaceOnUse"
+ x1="238.25577"
+ y1="263.93561"
+ x2="244.04422"
+ y2="281.74426" />
+ <linearGradient
+ id="linearGradient15275-9">
+ <stop
+ id="stop15277-2"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop15279-1"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath42711-8-1">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42713-4-3"
+ width="8.7252884"
+ height="17.464855"
+ x="127.4093"
+ y="214.76154" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15361-7"
+ id="linearGradient15368-7"
+ x1="132.26923"
+ y1="125.62637"
+ x2="132.11778"
+ y2="119.48639"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient15361-7">
+ <stop
+ style="stop-color:#2766a6;stop-opacity:1;"
+ offset="0"
+ id="stop15363-7" />
+ <stop
+ style="stop-color:#6ba2e5;stop-opacity:1;"
+ offset="1"
+ id="stop15365-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15320-0"
+ id="linearGradient15326-8"
+ x1="134.91025"
+ y1="122.37094"
+ x2="129.09338"
+ y2="113.63851"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient15320-0">
+ <stop
+ style="stop-color:#0868f5;stop-opacity:1;"
+ offset="0"
+ id="stop15322-3" />
+ <stop
+ style="stop-color:#fbfdfe;stop-opacity:1;"
+ offset="1"
+ id="stop15324-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-0-2">
+ <stop
+ id="stop23976-22-8"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-4-5"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31320-4-3">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-9-2" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-3-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14262-95-2">
+ <stop
+ id="stop14264-2-2"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-7-2"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-40-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-95-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-16-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-28-0-5">
+ <stop
+ id="stop23976-64-2-3"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-5-3-7"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-23-4"
+ id="radialGradient53141-5-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ id="linearGradient319-23-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-65-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-3-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-48-9"
+ id="linearGradient53143-6-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ id="linearGradient23974-48-9">
+ <stop
+ id="stop23976-13-7"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-28-3"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2-0"
+ id="linearGradient53145-1-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-27.086565"
+ y1="177.33885"
+ x2="-28.929489"
+ y2="175.48488" />
+ <linearGradient
+ id="linearGradient20756-2-0">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop20758-7-2" />
+ <stop
+ style="stop-color:#b5ccf0;stop-opacity:1;"
+ offset="1"
+ id="stop20760-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-23-4"
+ id="linearGradient53147-9-4"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28399-4"
+ id="linearGradient28405-0"
+ x1="329.46249"
+ y1="-104.63468"
+ x2="331.51218"
+ y2="-102.69718"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient28399-4">
+ <stop
+ style="stop-color:#0b1728;stop-opacity:1;"
+ offset="0"
+ id="stop28401-2" />
+ <stop
+ style="stop-color:#0b1728;stop-opacity:0;"
+ offset="1"
+ id="stop28403-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-1-2"
+ id="linearGradient18721-1-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,244.3928,19.4113)"
+ x1="-87.329895"
+ y1="-122.61974"
+ x2="-80.592239"
+ y2="-126.83872" />
+ <linearGradient
+ id="linearGradient23974-1-2">
+ <stop
+ id="stop23976-3-3"
+ offset="0"
+ style="stop-color:#3e7dd7;stop-opacity:0" />
+ <stop
+ style="stop-color:#8faedb;stop-opacity:1"
+ offset="0.48394433"
+ id="stop28407-8" />
+ <stop
+ id="stop23978-26-7"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-0-3"
+ id="linearGradient18728-6-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ id="linearGradient31320-0-3">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-4-5" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-9-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-97-5"
+ id="linearGradient18765-0-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,309.42934,-349.44584)"
+ x1="-20.377066"
+ y1="250.63214"
+ x2="-23.077509"
+ y2="252.61113" />
+ <linearGradient
+ id="linearGradient14262-97-5">
+ <stop
+ id="stop14264-0-6"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-6-3"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-406-5"
+ id="linearGradient18712-0-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="111.30827"
+ y1="56.21777"
+ x2="106.06621"
+ y2="52.58638" />
+ <linearGradient
+ id="linearGradient319-406-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="0"
+ id="stop320-76-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop321-36-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15539-2"
+ id="linearGradient15545-5"
+ x1="220.10603"
+ y1="248.22742"
+ x2="219.99527"
+ y2="254.01555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.1092502,-0.02900917)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15539-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15541-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15543-1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(-0.04936017,-0.02079917)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient15547-6"
+ id="linearGradient15553-4"
+ x1="216.16943"
+ y1="248.86955"
+ x2="216.65909"
+ y2="252.40509"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15547-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15549-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15551-1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38363-7"
+ id="radialGradient15517-8"
+ cx="217.74739"
+ cy="253.99704"
+ fx="217.74739"
+ fy="253.99704"
+ r="9.0099697"
+ gradientTransform="matrix(2.3861605,-0.28739765,0.07141566,0.59293888,-320.08363,164.28237)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient38363-7">
+ <stop
+ id="stop38365-1"
+ offset="0"
+ style="stop-color:#1d4d91;stop-opacity:1" />
+ <stop
+ style="stop-color:#658fd4;stop-opacity:1;"
+ offset="0.44217443"
+ id="stop15519-3" />
+ <stop
+ id="stop38367-1"
+ offset="1"
+ style="stop-color:#c3d7ff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38342-8"
+ id="linearGradient38716-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1386698,0,0,1.1421744,-30.97116,-35.468084)"
+ x1="209.90396"
+ y1="249.06081"
+ x2="234.13614"
+ y2="251.62866" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-56-4"
+ id="linearGradient17222-4-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ id="linearGradient37542-56-4">
+ <stop
+ id="stop37544-88-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-9-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-528-2"
+ id="linearGradient17224-0-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ id="linearGradient319-528-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-68-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-86-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-24-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-3-2" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-4-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-67-6"
+ id="linearGradient42519-8-7"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ id="linearGradient1610-67-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-75-5" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-31-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-41-5"
+ id="linearGradient42523-5-8"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient9030-41-5">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-2-0" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-10-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-76-2"
+ id="linearGradient42521-3-0"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ id="linearGradient319-76-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-3-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-18-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679-9-1"
+ id="linearGradient25927-1-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ id="linearGradient24679-9-1">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681-7-0" />
+ <stop
+ id="stop24683-6-7"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685-4-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671-1-3"
+ id="linearGradient25929-7-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ id="linearGradient24671-1-3">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24673-7-4" />
+ <stop
+ id="stop24675-7-4"
+ offset="0.29527253"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24677-5-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-16-6"
+ id="linearGradient15963-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="425.5929"
+ y1="179.08949"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ id="linearGradient319-16-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-683-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-08-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-86-8"
+ id="linearGradient15744-9-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="390.61163"
+ y1="229.34804"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ id="linearGradient37542-86-8">
+ <stop
+ id="stop37544-39-4"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0-3"
+ id="linearGradient10982-8-5"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient319-0-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-31" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-3" />
+ </linearGradient>
+ <linearGradient
+ y2="121"
+ x2="235.90916"
+ y1="107.25085"
+ x1="217.22589"
+ gradientTransform="matrix(1.0222226,0,0,0.73333282,-29.133504,-14.766607)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16268-9"
+ xlink:href="#linearGradient37542-86-0-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient37542-86-0-1">
+ <stop
+ id="stop37544-39-8-4"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-1-1"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="118.5"
+ x2="235"
+ y1="118.5"
+ x1="228.5468"
+ gradientTransform="matrix(0,1.253963,1,0,-46.30656,-81.941791)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16302-5"
+ xlink:href="#linearGradient319-0-2-5"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-0-2-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-0-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-86-2-7"
+ id="linearGradient15744-9-0-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="388.85464"
+ y1="230.24152"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ id="linearGradient37542-86-2-7">
+ <stop
+ id="stop37544-39-5-3"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-2-9"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0-4-4"
+ id="linearGradient10982-8-9-5"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient319-0-4-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-2-9" />
+ </linearGradient>
+ <linearGradient
+ y2="121"
+ x2="235.90916"
+ y1="107.25085"
+ x1="217.22589"
+ gradientTransform="matrix(1.0222226,0,0,0.73333282,-29.2335,-145.66661)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16268-5-0"
+ xlink:href="#linearGradient37542-86-0-6-8"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient37542-86-0-6-8">
+ <stop
+ id="stop37544-39-8-7-4"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-7-1-5-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="118.5"
+ x2="235"
+ y1="118.5"
+ x1="228.5468"
+ gradientTransform="matrix(0,1.253963,-1,0,177.20656,-82.04179)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16302-3-4"
+ xlink:href="#linearGradient319-0-2-3-8"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-0-2-3-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-15-0-0-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-26-9-5-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15859-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15861-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15863-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17523-0-7-7"
+ id="linearGradient27998-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(214.99838,108.99542)"
+ x1="87.765633"
+ y1="16.828125"
+ x2="85.033081"
+ y2="18.891191" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17523-0-7-7">
+ <stop
+ style="stop-color:#323232;stop-opacity:1;"
+ offset="0"
+ id="stop17525-0-3-1" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop17527-5-9-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17515-1-4-4"
+ id="linearGradient28000-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(206.99837,-42.004575)"
+ x1="95.812523"
+ y1="167.78125"
+ x2="93.152969"
+ y2="169.77431" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17515-1-4-4">
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:1;"
+ offset="0"
+ id="stop17517-7-4-5" />
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:0;"
+ offset="1"
+ id="stop17519-6-7-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17532-0-9-1"
+ id="linearGradient28002-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(206.99837,-42.004575)"
+ x1="95.322037"
+ y1="167.49391"
+ x2="92.640839"
+ y2="169.55806" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17532-0-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop17534-2-2-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop17536-3-0-8" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-5-1-4-8"
+ id="radialGradient28004-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ id="linearGradient10069-5-1-4-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-18-9-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-252-1-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-2-3"
+ id="linearGradient28006-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,344.60085,-50.387906)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-4-2-3">
+ <stop
+ id="stop36275-9-0-3-3"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-3-5-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-22-0"
+ id="linearGradient28008-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,350.57878,-38.420763)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-4-22-0">
+ <stop
+ id="stop36275-9-0-6-7"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-3-6-9"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17523-8"
+ id="linearGradient27963-5"
+ gradientUnits="userSpaceOnUse"
+ x1="87.765633"
+ y1="16.828125"
+ x2="85.033081"
+ y2="18.891191" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17523-8">
+ <stop
+ style="stop-color:#323232;stop-opacity:1;"
+ offset="0"
+ id="stop17525-7" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop17527-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17515-0"
+ id="linearGradient27965-1"
+ gradientUnits="userSpaceOnUse"
+ x1="95.812523"
+ y1="167.78125"
+ x2="93.152969"
+ y2="169.77431" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17515-0">
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:1;"
+ offset="0"
+ id="stop17517-3" />
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:0;"
+ offset="1"
+ id="stop17519-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17532-4"
+ id="linearGradient27967-9"
+ gradientUnits="userSpaceOnUse"
+ x1="95.322037"
+ y1="167.49391"
+ x2="92.640839"
+ y2="169.55806" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17532-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop17534-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop17536-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-5-1-8"
+ id="radialGradient27969-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ id="linearGradient10069-5-1-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-18-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-252-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-8"
+ id="linearGradient27971-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,137.60085,-8.4035259)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-4-8">
+ <stop
+ id="stop36275-9-0-0"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-3-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-4-8"
+ id="linearGradient27973-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,143.60084,3.5964739)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17523-0-5"
+ id="linearGradient17973-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(176.0221,109.0221)"
+ x1="87.765633"
+ y1="16.828125"
+ x2="85.033081"
+ y2="18.891191" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17523-0-5">
+ <stop
+ style="stop-color:#323232;stop-opacity:1;"
+ offset="0"
+ id="stop17525-0-6" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop17527-5-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17515-1-9"
+ id="linearGradient17975-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.02209,-41.977903)"
+ x1="95.812523"
+ y1="167.78125"
+ x2="93.152969"
+ y2="169.77431" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17515-1-9">
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:1;"
+ offset="0"
+ id="stop17517-7-9" />
+ <stop
+ style="stop-color:#8c8c8c;stop-opacity:0;"
+ offset="1"
+ id="stop17519-6-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17532-0-8"
+ id="linearGradient17977-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.02209,-41.977903)"
+ x1="95.322037"
+ y1="167.49391"
+ x2="92.640839"
+ y2="169.55806" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient17532-0-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop17534-2-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop17536-3-8" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-5-12"
+ id="radialGradient17979-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ id="linearGradient10069-5-12">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-9"
+ id="linearGradient17981-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,305.60083,-50.403526)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ id="linearGradient36273-9-9">
+ <stop
+ id="stop36275-9-8"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277-1-35"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273-9-9"
+ id="linearGradient17983-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,311.60082,-38.403526)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-4-6-0"
+ id="linearGradient32430-7-9-7"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient9030-4-6-0">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-3-3-8" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-1-6-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7-2-5-2"
+ id="linearGradient32434-5-8-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ id="linearGradient44939-8-7-1-7-2-5-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4-7-8-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0-1-0-2" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1-6-0"
+ id="radialGradient15137-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.227486"
+ cy="95.949913"
+ fx="-73.227486"
+ fy="95.949913"
+ r="4.9999957" />
+ <linearGradient
+ id="linearGradient40455-7-1-6-0">
+ <stop
+ id="stop40457-6-6-8-7"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-7-9"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-7-5-3"
+ id="radialGradient15139-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4769848,-0.5257394,0.6056598,0.5494938,269.68012,490.96577)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-7-5-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6-1-7" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1-8-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-9-6-7"
+ id="linearGradient15141-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-9-6-7">
+ <stop
+ id="stop58336-27-3-0"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9-5-0"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-1-4"
+ id="linearGradient15143-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-94.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4-1-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31-1-1" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23-1-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-0-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-7-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8-0-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-1-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-3-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25108-1-0">
+ <stop
+ id="stop25110-8-5"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop25112-1-0"
+ offset="1"
+ style="stop-color:#c6c6c6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8-7-1-7-2-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4-7-86" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0-1-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7-2-4"
+ id="linearGradient55624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15098"
+ id="linearGradient55656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,221,10)"
+ x1="115.01612"
+ y1="12"
+ x2="106.125"
+ y2="19.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108-1-0"
+ id="linearGradient55785"
+ gradientUnits="userSpaceOnUse"
+ x1="436.54755"
+ y1="524.30481"
+ x2="434.49387"
+ y2="519.46057" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108-1-0"
+ id="linearGradient55787"
+ gradientUnits="userSpaceOnUse"
+ x1="432.0849"
+ y1="524.97125"
+ x2="433"
+ y2="526" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0"
+ id="linearGradient55950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="56.069553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19-0"
+ id="linearGradient55952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14482"
+ id="linearGradient55954"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55806"
+ y1="94.884857"
+ x2="149.53032"
+ y2="101.436" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7-1"
+ id="linearGradient55956"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3-0"
+ id="linearGradient55958"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-0-9"
+ id="linearGradient55988"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="284.5"
+ y2="106.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-6-2"
+ id="linearGradient55990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,593.02125,-1.8e-6)"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient56084"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(210.99996,-273.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-08"
+ id="linearGradient56084-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(210.99996,-273.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ id="linearGradient319-08">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-36" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-21" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-08"
+ id="linearGradient29129-4"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-71"
+ id="linearGradient56084-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(210.99996,-273.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ id="linearGradient319-71">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-33" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-71"
+ id="linearGradient29129-1"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-24-4"
+ id="linearGradient56401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2868892,0,0,1,-249.7433,-143.02079)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-76-2"
+ id="linearGradient56428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,27.439091,-300.45853)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15859-1"
+ id="linearGradient14951"
+ gradientUnits="userSpaceOnUse"
+ x1="4.1933641"
+ y1="199.12067"
+ x2="17.16466"
+ y2="211.01585" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15859-1-3"
+ id="linearGradient14951-4"
+ gradientUnits="userSpaceOnUse"
+ x1="12.602254"
+ y1="206.13333"
+ x2="26.167894"
+ y2="220.66356" />
+ <linearGradient
+ id="linearGradient15859-1-3">
+ <stop
+ style="stop-color:#ff992b;stop-opacity:1"
+ offset="0"
+ id="stop15861-1-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop15863-7-73" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-28-0-5"
+ id="linearGradient15989"
+ gradientUnits="userSpaceOnUse"
+ x1="94.485573"
+ y1="122.13319"
+ x2="89.207298"
+ y2="125.83332" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-4-3"
+ id="linearGradient15994"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-40-7"
+ id="linearGradient16002"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,69.29396,203.19342)"
+ x1="103.65562"
+ y1="49.547874"
+ x2="120.79755"
+ y2="57.84819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-95-2"
+ id="linearGradient16005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,139.37998,3.53336)"
+ x1="-26.207859"
+ y1="252.77303"
+ x2="-5.4963508"
+ y2="253.15045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-0-2"
+ id="linearGradient16010"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,74.34344,372.3905)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27301-6-2"
+ id="linearGradient16558"
+ gradientUnits="userSpaceOnUse"
+ x1="497"
+ y1="264"
+ x2="507.125"
+ y2="276.75"
+ gradientTransform="translate(-0.04936017,-0.04091017)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-63-5"
+ id="linearGradient16561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,0.97920913)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27277-1-8"
+ id="linearGradient16564"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,1.9965991)"
+ x1="501.19104"
+ y1="270.69452"
+ x2="488.93024"
+ y2="272.60611" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-27-5"
+ id="linearGradient16567"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,383.02168,218.70121)"
+ x1="116.41398"
+ y1="53.197613"
+ x2="104.06187"
+ y2="53.601826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15531-9-5"
+ id="linearGradient16570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,383.02168,218.70121)"
+ x1="116.41398"
+ y1="53.197613"
+ x2="109.72195"
+ y2="43.434277" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105-2-9"
+ id="linearGradient16573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,1.9792524)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ id="linearGradient1610-3-7-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-4-3" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6-0-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-5-9-4-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-8-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-24-8-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-3-7-4"
+ id="linearGradient16887"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-70.605209"
+ y1="-121.58411"
+ x2="-28.177105"
+ y2="-89.026711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-9-4-2"
+ id="linearGradient16889"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-74"
+ y1="-124"
+ x2="-55.5975"
+ y2="-103.2075" />
+ <linearGradient
+ id="linearGradient319-95">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-242" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-44" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-43"
+ id="linearGradient22933-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ id="linearGradient37542-43">
+ <stop
+ id="stop37544-7"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-12"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48"
+ id="linearGradient22935-6"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ id="linearGradient319-48">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-59"
+ id="linearGradient22937-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ id="linearGradient10069-59">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-30" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48"
+ id="linearGradient22939-8"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ y2="460.6622"
+ x2="264"
+ y1="452"
+ x1="264"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17039"
+ xlink:href="#linearGradient319-48"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-43-6"
+ id="linearGradient22933-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ id="linearGradient37542-43-6">
+ <stop
+ id="stop37544-7-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-12-6"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-6"
+ id="linearGradient22935-6-2"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ id="linearGradient319-48-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-59-3"
+ id="linearGradient22937-4-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ id="linearGradient10069-59-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-30-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-3-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-6"
+ id="linearGradient22939-8-6"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ y2="460.6622"
+ x2="264"
+ y1="452"
+ x1="264"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17172"
+ xlink:href="#linearGradient319-48-6"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-48-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-43-3"
+ id="linearGradient22933-6-87"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ id="linearGradient37542-43-3">
+ <stop
+ id="stop37544-7-8"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-12-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-5"
+ id="linearGradient22935-6-22"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ id="linearGradient319-48-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-64-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-6-50" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-59-8"
+ id="linearGradient22937-4-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ id="linearGradient10069-59-8">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-30-2" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-3-06" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-5"
+ id="linearGradient22939-8-3"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ y2="460.6622"
+ x2="264"
+ y1="452"
+ x1="264"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17172-9"
+ xlink:href="#linearGradient319-48-5"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17438"
+ id="linearGradient17582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="267.125"
+ y1="462.1875"
+ x2="267.25"
+ y2="450" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17596"
+ id="linearGradient17584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-26.918331,340)"
+ x1="245.91833"
+ y1="101"
+ x2="246.02513"
+ y2="94.443054" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-4"
+ id="linearGradient17586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17602"
+ id="linearGradient17588"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-29.000001,340)"
+ x1="247"
+ y1="102"
+ x2="247"
+ y2="95.409012" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17430"
+ id="linearGradient17590"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="270.5"
+ y1="464.0625"
+ x2="270.125"
+ y2="447.0625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-4"
+ id="linearGradient17592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,-19)"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-48-4"
+ id="linearGradient17594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6,-47,163.8)"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622" />
+ <linearGradient
+ id="linearGradient37542-1">
+ <stop
+ id="stop37544-62"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-75">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-39" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-1"
+ id="linearGradient17715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88913256,0,0,0.96231883,-17.039429,-158.76811)"
+ x1="30.435225"
+ y1="202.99998"
+ x2="30.435225"
+ y2="251.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-75"
+ id="linearGradient17717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.92839719,0,0,1.1347062,0.81276468,-9.2113636)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.903511"
+ y2="81.589714" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95"
+ id="linearGradient17932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,627.46943,130.00389)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ id="linearGradient37542-49">
+ <stop
+ id="stop37544-8"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-99"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-995">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-08" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-273" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49"
+ id="linearGradient20080"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,-379,416.1659)"
+ x1="42.033173"
+ y1="164.51399"
+ x2="75.32457"
+ y2="164.51399" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-995"
+ id="linearGradient20084"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,685.50001,836.08335)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49-3"
+ id="linearGradient20080-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,-379,416.1659)"
+ x1="42.033173"
+ y1="164.51399"
+ x2="75.32457"
+ y2="164.51399" />
+ <linearGradient
+ id="linearGradient37542-49-3">
+ <stop
+ id="stop37544-8-7"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-99-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49-3"
+ id="linearGradient20082-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(216,445.00002)"
+ x1="118.1319"
+ y1="157.11609"
+ x2="85.577972"
+ y2="157.54283" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-995-3"
+ id="linearGradient20084-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,685.50001,836.08335)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ id="linearGradient319-995-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-08-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-273-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-49"
+ id="linearGradient20199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(209.99848,445.06252)"
+ x1="118.1319"
+ y1="157.11609"
+ x2="85.577972"
+ y2="157.54283" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-66-0-4-7"
+ id="linearGradient16783-1-6-0-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,290.55464,214.86015)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="17.012707"
+ y2="172.79289" />
+ <linearGradient
+ id="linearGradient37542-66-0-4-7">
+ <stop
+ id="stop37544-85-0-9-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-15-9-5-7"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4343-1-1-9-1"
+ id="linearGradient16778-3-5-3-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5990464,-0.03583042,0.03242597,0.6546824,306.65287,109.38342)"
+ x1="-12.264804"
+ y1="333.22653"
+ x2="-10.869003"
+ y2="334.86029" />
+ <linearGradient
+ id="linearGradient4343-1-1-9-1">
+ <stop
+ id="stop4345-2-9-5-6"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop4347-1-5-5-1"
+ offset="1"
+ style="stop-color:#fff9f9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-73-3-4-6"
+ id="linearGradient16775-4-9-5-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(497.01612,511)"
+ x1="-190.37566"
+ y1="-180.13821"
+ x2="-189.34792"
+ y2="-182" />
+ <linearGradient
+ id="linearGradient319-73-3-4-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-87-5-2-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-66-3-7-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-65-4-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-14-9-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-49-3-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8"
+ id="linearGradient17904-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97,-102)"
+ x1="386.88852"
+ y1="409.84152"
+ x2="389.14081"
+ y2="412.45016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8"
+ id="linearGradient17893-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-106,-102)"
+ x1="387"
+ y1="409.86362"
+ x2="388.86676"
+ y2="411.88974" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-65-4-8"
+ id="linearGradient18148"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-102,-94)"
+ x1="387"
+ y1="410"
+ x2="388.78125"
+ y2="411.78125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-3"
+ id="linearGradient37097-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="184.00143"
+ y1="28.989071"
+ x2="193.51584"
+ y2="39.879452" />
+ <linearGradient
+ id="linearGradient23974-3">
+ <stop
+ id="stop23976-6"
+ offset="0"
+ style="stop-color:#a3a3a3;stop-opacity:1" />
+ <stop
+ id="stop23978-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16504"
+ id="linearGradient15782-9"
+ gradientUnits="userSpaceOnUse"
+ x1="125.19086"
+ y1="125.66204"
+ x2="132.98256"
+ y2="118" />
+ <linearGradient
+ id="linearGradient319-47">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-85" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-48" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-47"
+ id="linearGradient33681-3"
+ gradientUnits="userSpaceOnUse"
+ x1="139.93341"
+ y1="110.56118"
+ x2="129.60957"
+ y2="120.41502" />
+ <linearGradient
+ id="linearGradient23974-3-78">
+ <stop
+ id="stop23976-6-5"
+ offset="0"
+ style="stop-color:#a3a3a3;stop-opacity:1" />
+ <stop
+ id="stop23978-2-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16504-0">
+ <stop
+ id="stop16506-3"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop16508-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-47-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-85-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-48-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-3-78"
+ id="linearGradient16713"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="186.25801"
+ y1="31.40288"
+ x2="193.51584"
+ y2="39.879452" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16504-0"
+ id="linearGradient16716"
+ gradientUnits="userSpaceOnUse"
+ x1="125.19086"
+ y1="125.66204"
+ x2="132.98256"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-47-9"
+ id="linearGradient16718"
+ gradientUnits="userSpaceOnUse"
+ x1="139.93341"
+ y1="110.56118"
+ x2="127.39279"
+ y2="123.48748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-5"
+ id="linearGradient17833-9"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078"
+ gradientTransform="translate(144,188)" />
+ <linearGradient
+ id="linearGradient1610-36-6-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-6" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7"
+ id="linearGradient17833-8"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078"
+ gradientTransform="translate(144,188)" />
+ <linearGradient
+ id="linearGradient1610-36-6-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-96"
+ id="linearGradient20796-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(159.9998,-41.00751)"
+ x1="261.44702"
+ y1="234.6606"
+ x2="274.30609"
+ y2="247.73561" />
+ <linearGradient
+ id="linearGradient37542-96">
+ <stop
+ id="stop37544-7-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-37"
+ id="linearGradient20798-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(199.9999,105.99249)"
+ x1="235.46884"
+ y1="103"
+ x2="228.71886"
+ y2="94.53125" />
+ <linearGradient
+ id="linearGradient10069-37">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-9"
+ id="linearGradient39254-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ id="linearGradient1610-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-4-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-09" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-9"
+ id="radialGradient39256-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-0" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-2"
+ id="linearGradient39258-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-2">
+ <stop
+ id="stop58336-97"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-90"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(0,-95.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16151"
+ xlink:href="#linearGradient16500-49"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-49">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-16" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-19-1-1"
+ id="linearGradient79029"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1666676,0,0,-1.1666676,795.08409,370.66085)"
+ x1="262.04343"
+ y1="233.0448"
+ x2="273.85818"
+ y2="247.32738" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-19-1-1">
+ <stop
+ id="stop37544-48-6-1-8-9-3"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-6-8-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-7-8-3-0-3-6"
+ id="linearGradient79025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,426.82889,65.03941)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient44939-8-4-7-8-3-0-3-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-40-2-4-2-4-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-9-4-9-8-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-4-6-5-0-3-6"
+ id="linearGradient79020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.53706486,0,0,-0.53706486,531.01948,106.93034)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-4-6-5-0-3-6">
+ <stop
+ style="stop-color:#252525;stop-opacity:1"
+ offset="0"
+ id="stop10071-5-4-58-5-9-1-2-1-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-0-8-0-4-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient81143-4"
+ id="linearGradient80406-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.58017143,0,0,0.92830994,410.31278,270.33169)"
+ x1="-187.57428"
+ y1="63.340904"
+ x2="-157.37125"
+ y2="79.243309" />
+ <linearGradient
+ id="linearGradient81143-4">
+ <stop
+ style="stop-color:#2561b7;stop-opacity:1"
+ offset="0"
+ id="stop81145-0" />
+ <stop
+ style="stop-color:#f9fbff;stop-opacity:1"
+ offset="1"
+ id="stop81147-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15487-1-8-4-3"
+ id="linearGradient80403-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.92827429,0,0,0.92830994,60.469415,101.37929)"
+ x1="254.19243"
+ y1="237.48314"
+ x2="273.92343"
+ y2="254.49823" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15487-1-8-4-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop15489-3-2-3-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop15491-4-4-1-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-40-9"
+ id="linearGradient81258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99995186,0,0,0.99980511,154.9567,150.99846)"
+ x1="123.80291"
+ y1="90.165237"
+ x2="142.64377"
+ y2="105.8204" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-84-1"
+ id="linearGradient81260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,229.31341,141.82572)"
+ x1="45.107925"
+ y1="91.099701"
+ x2="51.546276"
+ y2="96.026611" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-84-3-2"
+ id="linearGradient81262"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,235.27474,141.76351)"
+ x1="46.007988"
+ y1="90.678802"
+ x2="50.907307"
+ y2="95.401253" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14829"
+ id="linearGradient14814"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-722.19531,285.57729)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ id="linearGradient14829">
+ <stop
+ id="stop14831"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop14833"
+ offset="1"
+ style="stop-color:#757575;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14632"
+ id="linearGradient14816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-214.43013,42.779961)"
+ x1="148.54834"
+ y1="301.96149"
+ x2="166.33298"
+ y2="317.25269" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient14632">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop14634" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop14636" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106-0">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850-6"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011-8"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013-0" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-9"
+ id="linearGradient14818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-233.12445,-35.715412)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ id="linearGradient5060-9">
+ <stop
+ id="stop5062-0"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-7"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821-9"
+ id="radialGradient14820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient18821-9">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823-1" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39155-5"
+ id="linearGradient14822"
+ gradientUnits="userSpaceOnUse"
+ x1="31.1875"
+ y1="18.875"
+ x2="29.875"
+ y2="34.375" />
+ <linearGradient
+ id="linearGradient39155-5">
+ <stop
+ id="stop39157-4"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39159-1"
+ offset="1"
+ style="stop-color:#dadada;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3564-9"
+ id="linearGradient14825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06818845,0,0,0.06818845,22.51112,27.02885)"
+ x1="185.9903"
+ y1="193.33229"
+ x2="190.46461"
+ y2="-458.05771" />
+ <linearGradient
+ id="linearGradient3564-9"
+ inkscape:collect="always">
+ <stop
+ id="stop3566-9"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop3568-2"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39171-8"
+ id="radialGradient14827"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.647222,0,0,1.26792,-15.47413,-5.79794)"
+ cx="26.109201"
+ cy="19.668886"
+ fx="26.109201"
+ fy="19.668886"
+ r="20.278975" />
+ <linearGradient
+ id="linearGradient39171-8"
+ inkscape:collect="always">
+ <stop
+ id="stop39173-9"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39175-5"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14829"
+ id="linearGradient14800"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-169.92789,274.92229)"
+ x1="243.92192"
+ y1="-2.6686089"
+ x2="275.10107"
+ y2="26.600887" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14605"
+ id="linearGradient14802"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-13.427886,57.417785)"
+ x1="87"
+ y1="241.125"
+ x2="90.764404"
+ y2="243.87347" />
+ <linearGradient
+ id="linearGradient14605">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.56485355;"
+ offset="0"
+ id="stop14607" />
+ <stop
+ style="stop-color:#fffffe;stop-opacity:0;"
+ offset="1"
+ id="stop14609" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath22590-7">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22592-5-0"
+ width="12"
+ height="14"
+ x="-30"
+ y="490.00012" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-5"
+ id="linearGradient14804"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ id="linearGradient13998-5">
+ <stop
+ id="stop14000-00"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002-54"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998-5"
+ id="linearGradient14806"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-53"
+ id="linearGradient14808"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ id="linearGradient319-53">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-61" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-53"
+ id="linearGradient14810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-41" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-4" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="299.83005"
+ x1="753.39417"
+ gradientTransform="translate(-683.42789,-5.5822151)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient20368"
+ xlink:href="#linearGradient16500-1"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-41-8-0-7-1"
+ id="linearGradient16663-3-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="184.95361"
+ y1="115.79691"
+ x2="235.24524"
+ y2="119.04691" />
+ <linearGradient
+ id="linearGradient37542-41-8-0-7-1">
+ <stop
+ id="stop37544-5-2-6-6-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-8-6-8-7-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-41-8-0-7-4"
+ id="linearGradient16663-3-0-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="179.3838"
+ y1="116.92558"
+ x2="235.24524"
+ y2="119.04691" />
+ <linearGradient
+ id="linearGradient37542-41-8-0-7-4">
+ <stop
+ id="stop37544-5-2-6-6-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-8-6-8-7-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7-8-6-0"
+ id="radialGradient106344-5"
+ cx="386.68588"
+ cy="247.46175"
+ fx="386.68588"
+ fy="247.46175"
+ r="2.3794625"
+ gradientTransform="matrix(4.5687397,-0.29531319,0.13355055,5.747731,-1415.8878,-1055.5606)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient37542-7-8-6-0">
+ <stop
+ id="stop37544-40-1-3-9"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop37546-94-7-0-7"
+ offset="1"
+ style="stop-color:#030303;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ y2="245.04375"
+ x2="400.77301"
+ y1="243.97655"
+ x1="385.67264"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient106307-2"
+ xlink:href="#linearGradient319-488-8-2"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-488-8-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-13-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-67-2-2" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient106427"
+ id="radialGradient106433"
+ cx="383.96912"
+ cy="249.87636"
+ fx="383.96912"
+ fy="249.87636"
+ r="2.3794624"
+ gradientTransform="matrix(4.5686863,-0.29541184,0.13359632,5.7477127,-1403.7889,-1070.199)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7-8-6-0-8"
+ id="radialGradient106344-5-2"
+ cx="386.68588"
+ cy="247.46175"
+ fx="386.68588"
+ fy="247.46175"
+ r="2.3794625"
+ gradientTransform="matrix(4.5687397,-0.29531319,0.13355055,5.747731,-1415.8878,-1055.5606)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient37542-7-8-6-0-8">
+ <stop
+ id="stop37544-40-1-3-9-3"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop37546-94-7-0-7-1"
+ offset="1"
+ style="stop-color:#030303;stop-opacity:1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient106427-3"
+ id="radialGradient106433-4"
+ cx="383.96912"
+ cy="249.87636"
+ fx="383.96912"
+ fy="249.87636"
+ r="2.3794625"
+ gradientTransform="matrix(4.5686863,-0.29541184,0.13359632,5.7477127,-1403.7889,-1070.199)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient106427-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop106429-1" />
+ <stop
+ style="stop-color:#030303;stop-opacity:1"
+ offset="1"
+ id="stop106431-0" />
+ </linearGradient>
+ <linearGradient
+ y2="245.04375"
+ x2="400.77301"
+ y1="243.97655"
+ x1="385.67264"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient106307-2-4"
+ xlink:href="#linearGradient319-488-8-2-0"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient319-488-8-2-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-13-8-8-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-67-2-2-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-36-6-7-9">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4-5" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-36-6-7-9-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-9-4-5-0" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-5-9-87-3-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7-9"
+ id="linearGradient106628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(64,338)"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-36-6-7-9-4"
+ id="linearGradient106641"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(39.8125,337.625)"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-1-1-9-4-7-1"
+ id="linearGradient106804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.40161"
+ y2="29.679312" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-4-0-5-2-4-7"
+ id="radialGradient106806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-24-8-2-6-0-2"
+ id="linearGradient106808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-11-1-4-3-1"
+ id="linearGradient106810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-1-7-5-7-7"
+ id="linearGradient106812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-5-7-6-8-9"
+ id="linearGradient106814"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient106816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient106818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="219"
+ y1="604.31494"
+ x2="221"
+ y2="609.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-4-6-7-7"
+ id="linearGradient106820"
+ gradientUnits="userSpaceOnUse"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-2-6-4-4"
+ id="linearGradient106822"
+ gradientUnits="userSpaceOnUse"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ id="linearGradient106824"
+ gradientUnits="userSpaceOnUse"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ id="linearGradient106826"
+ gradientUnits="userSpaceOnUse"
+ x1="219"
+ y1="604.31494"
+ x2="221"
+ y2="609.36218" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107148"
+ id="radialGradient107138"
+ gradientUnits="userSpaceOnUse"
+ cx="12.465761"
+ cy="353.51611"
+ fx="12.465761"
+ fy="353.51611"
+ r="2.91875"
+ gradientTransform="matrix(0.84360011,0.04170664,-0.04937856,0.99878013,19.37109,-0.08239219)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107142"
+ id="linearGradient107140"
+ gradientUnits="userSpaceOnUse"
+ x1="11.695067"
+ y1="352.60217"
+ x2="16.773348"
+ y2="358.90598" />
+ <radialGradient
+ r="2.91875"
+ fy="353.59497"
+ fx="12.128428"
+ cy="353.59497"
+ cx="12.128428"
+ gradientTransform="matrix(0.2864009,1.1071441,-1.0639391,0.27522442,384.79448,242.64422)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient107490"
+ xlink:href="#linearGradient107519"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15097-0-8"
+ id="radialGradient15836-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.14826933,2.1671891,-2.0135104,-0.13775545,-42.975294,-475.30953)"
+ cx="327.72662"
+ cy="-102.09388"
+ fx="327.72662"
+ fy="-102.09388"
+ r="3.3160801" />
+ <linearGradient
+ id="linearGradient15097-0-8">
+ <stop
+ style="stop-color:#c4c4c4;stop-opacity:1"
+ offset="0"
+ id="stop15099-1-83" />
+ <stop
+ style="stop-color:#868686;stop-opacity:1"
+ offset="1"
+ id="stop15101-9-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-5-2-6-6"
+ id="linearGradient15851-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.2185076,0,0,1.1902393,14.075854,397.20828)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ id="linearGradient23974-5-2-6-6">
+ <stop
+ id="stop23976-9-2-7-6"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-3-1-6-0"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-5-2-6-7"
+ id="linearGradient15818-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ id="linearGradient31320-5-2-6-7">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-5-4-5-8" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-0-8-5-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-9-5-9-4"
+ id="linearGradient15846-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.2185076,0,0,1.1902393,92.990431,-50.358654)"
+ x1="-20.864969"
+ y1="250.35432"
+ x2="-34.640823"
+ y2="264.67712" />
+ <linearGradient
+ id="linearGradient14262-9-5-9-4">
+ <stop
+ id="stop14264-5-2-9-0"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-0-4-4-2"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-92-8-5-0"
+ id="linearGradient15843-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99098745,0,0,1.0233007,7.9488742,191.90653)"
+ x1="113.17896"
+ y1="49.395184"
+ x2="111.81031"
+ y2="62.520573" />
+ <linearGradient
+ id="linearGradient319-92-8-5-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-40-7-9-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-93-7-0-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-92-8-5-0"
+ id="linearGradient16562-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99098745,0,0,1.0233007,7.9488742,191.90653)"
+ x1="114.36164"
+ y1="22.752264"
+ x2="104.74062"
+ y2="65.241188" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15959-9-5"
+ id="linearGradient15773-7"
+ gradientUnits="userSpaceOnUse"
+ x1="113.07384"
+ y1="252.04327"
+ x2="119.9112"
+ y2="249.41632"
+ gradientTransform="matrix(1.2133883,0,0,1.2133883,-25.22919,-53.154498)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15959-9-5">
+ <stop
+ style="stop-color:#4d4d4d;stop-opacity:1;"
+ offset="0"
+ id="stop15961-9-6" />
+ <stop
+ style="stop-color:#4d4d4d;stop-opacity:0;"
+ offset="1"
+ id="stop15963-8-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16723"
+ id="linearGradient16730"
+ x1="112.5"
+ y1="252.5"
+ x2="116.5"
+ y2="250"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient16800"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.64335,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient16802"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29757"
+ id="linearGradient29763"
+ x1="-224.85715"
+ y1="205.71428"
+ x2="-214.42857"
+ y2="206"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29870"
+ id="radialGradient29940"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.311465,0.10059658,-0.15692472,2.0458095,520.8023,-36.428937)"
+ cx="-214.41437"
+ cy="203.04764"
+ fx="-214.41437"
+ fy="203.04764"
+ r="5.8999949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30390"
+ id="linearGradient28911"
+ gradientUnits="userSpaceOnUse"
+ x1="531.875"
+ y1="56.062489"
+ x2="542.99994"
+ y2="61.562489" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705-0"
+ id="linearGradient22892-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ id="linearGradient23705-0">
+ <stop
+ id="stop23707-9"
+ offset="0"
+ style="stop-color:#d4d2bf;stop-opacity:1;" />
+ <stop
+ id="stop23709-4"
+ offset="1"
+ style="stop-color:#857f5d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168-8"
+ id="linearGradient22954-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <linearGradient
+ id="linearGradient24168-8">
+ <stop
+ id="stop24170-2"
+ offset="0"
+ style="stop-color:#182437;stop-opacity:1;" />
+ <stop
+ id="stop24172-4"
+ offset="1"
+ style="stop-color:#2b4163;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="radialGradient22952-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="262.67139"
+ cy="74.072273"
+ fx="262.67139"
+ fy="74.072273"
+ r="3.5" />
+ <linearGradient
+ id="linearGradient319-51">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="linearGradient22928-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <linearGradient
+ id="linearGradient29791">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29793" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29795" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821-2"
+ id="radialGradient22950-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient18821-2">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823-7" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825-6" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="radialGradient22922-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ id="linearGradient29802">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29804" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29806" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-2"
+ id="linearGradient22917-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <linearGradient
+ id="linearGradient5060-2">
+ <stop
+ id="stop5062-3"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-2"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-51"
+ id="radialGradient23727-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ id="linearGradient29813">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29815" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29817" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107519"
+ id="radialGradient30077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2864009,1.1071441,-1.0639391,0.27522442,384.79448,242.64422)"
+ cx="12.128428"
+ cy="353.59497"
+ fx="12.128428"
+ fy="353.59497"
+ r="2.91875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient30079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.64335,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient30081"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient107519"
+ id="radialGradient30090"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2864009,1.1071441,-1.0639391,0.27522442,384.79448,242.64422)"
+ cx="12.128428"
+ cy="353.59497"
+ fx="12.128428"
+ fy="353.59497"
+ r="2.91875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient30092"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.64335,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient30094"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16772"
+ id="linearGradient30097"
+ gradientUnits="userSpaceOnUse"
+ x1="63.847855"
+ y1="353.1496"
+ x2="61.116474"
+ y2="360.82117"
+ gradientTransform="matrix(-1,0,0,1,112.28991,0.1875)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16764"
+ id="linearGradient30100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,112.28991,0.1875)"
+ x1="63.643349"
+ y1="354.8125"
+ x2="60.996902"
+ y2="359.97281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30122"
+ id="linearGradient30129"
+ x1="48.5"
+ y1="354.75"
+ x2="51"
+ y2="360.25"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30131"
+ id="linearGradient30137"
+ x1="60.289909"
+ y1="361.0625"
+ x2="63.789909"
+ y2="354.0625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30139"
+ id="linearGradient30145"
+ x1="63.789909"
+ y1="355.0625"
+ x2="61.039909"
+ y2="360.0625"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10000"
+ objecttolerance="10000"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2"
+ inkscape:cx="199.42005"
+ inkscape:cy="320.97898"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer3"
+ showgrid="false"
+ inkscape:window-width="2560"
+ inkscape:window-height="1571"
+ inkscape:window-x="0"
+ inkscape:window-y="1"
+ inkscape:snap-nodes="false"
+ inkscape:snap-bbox="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:object-nodes="false"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:window-maximized="1"
+ inkscape:bbox-paths="false"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-grids="true"
+ inkscape:snap-to-guides="false"
+ inkscape:snap-page="false"
+ units="pt"
+ inkscape:snap-center="false"
+ inkscape:snap-object-midpoints="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid17394"
+ visible="true"
+ enabled="true"
+ spacingx="0.25px"
+ spacingy="0.25px"
+ empspacing="4"
+ color="#808080"
+ opacity="0.09803922"
+ dotted="false"
+ empcolor="#7f7f7f"
+ empopacity="0.25098039"
+ snapvisiblegridlinesonly="true"
+ originx="0px"
+ originy="-2.7755576e-17px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Blender icons v. 2.5.08</dc:title>
+ <dc:date>21.05.2012</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:coverage />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/" />
+ <dc:description>This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed.</dc:description>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:prohibits
+ rdf:resource="http://creativecommons.org/ns#CommercialUse" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="bckgrnd"
+ style="display:none">
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20607"
+ width="1083.874"
+ height="650"
+ x="-4"
+ y="-4" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23417"
+ sodipodi:nodetypes="cc"
+ d="" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23347"
+ sodipodi:nodetypes="cc"
+ d="" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer5"
+ inkscape:label="grid"
+ style="opacity:0.3;display:inline"
+ sodipodi:insensitive="true">
+ <g
+ id="g40174"
+ transform="translate(0,2)">
+ <g
+ id="g22995">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22955"
+ width="1"
+ height="7"
+ x="422"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="401"
+ height="7"
+ width="1"
+ id="rect22957"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22959"
+ width="1"
+ height="7"
+ x="380"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="359"
+ height="7"
+ width="1"
+ id="rect22961"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22963"
+ width="1"
+ height="7"
+ x="338"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="317"
+ height="7"
+ width="1"
+ id="rect22965"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22967"
+ width="1"
+ height="7"
+ x="296"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="275"
+ height="7"
+ width="1"
+ id="rect22969"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22971"
+ width="1"
+ height="7"
+ x="254"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="233"
+ height="7"
+ width="1"
+ id="rect22973"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22975"
+ width="1"
+ height="7"
+ x="212"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="191"
+ height="7"
+ width="1"
+ id="rect22977"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22979"
+ width="1"
+ height="7"
+ x="170"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="149"
+ height="7"
+ width="1"
+ id="rect22981"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22983"
+ width="1"
+ height="7"
+ x="128"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="107"
+ height="7"
+ width="1"
+ id="rect22985"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22987"
+ width="1"
+ height="7"
+ x="86"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="65"
+ height="7"
+ width="1"
+ id="rect22989"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22991"
+ width="1"
+ height="7"
+ x="44"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="23"
+ height="7"
+ width="1"
+ id="rect22993"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="506"
+ height="7"
+ width="1"
+ id="rect23024"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23026"
+ width="1"
+ height="7"
+ x="485"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="464"
+ height="7"
+ width="1"
+ id="rect23028"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23030"
+ width="1"
+ height="7"
+ x="443"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect10985"
+ width="1"
+ height="7"
+ x="527"
+ y="0"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g24954">
+ <g
+ id="g23711"
+ transform="translate(0,462)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23713"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23715">
+ <path
+ id="path23717"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23719" />
+ <path
+ id="path23721"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23723" />
+ <path
+ id="path23725"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23727" />
+ <path
+ id="path23729"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23731" />
+ <path
+ id="path23733"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23735" />
+ <path
+ id="path23737"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23739" />
+ <path
+ id="path23741"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23743" />
+ <path
+ id="path23745"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23747" />
+ <path
+ id="path23749"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23751" />
+ <path
+ id="path23753"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23755" />
+ <path
+ id="path23757"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23759" />
+ <path
+ id="path23761"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23763" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10987" />
+ </g>
+ </g>
+ <g
+ id="g23765"
+ transform="translate(0,441)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect23767"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23769">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23771" />
+ <path
+ id="path23773"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23775" />
+ <path
+ id="path23777"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23779" />
+ <path
+ id="path23781"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23783" />
+ <path
+ id="path23785"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23787" />
+ <path
+ id="path23789"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23791" />
+ <path
+ id="path23793"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23795" />
+ <path
+ id="path23797"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23799" />
+ <path
+ id="path23801"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23803" />
+ <path
+ id="path23805"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23807" />
+ <path
+ id="path23809"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23811" />
+ <path
+ id="path23813"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23815" />
+ <path
+ id="path23817"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10990"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g23819"
+ transform="translate(0,420)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23821"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23823">
+ <path
+ id="path23825"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23827" />
+ <path
+ id="path23829"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23831" />
+ <path
+ id="path23833"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23835" />
+ <path
+ id="path23837"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23839" />
+ <path
+ id="path23841"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23843" />
+ <path
+ id="path23845"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23847" />
+ <path
+ id="path23849"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23851" />
+ <path
+ id="path23853"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23855" />
+ <path
+ id="path23857"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23859" />
+ <path
+ id="path23861"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23863" />
+ <path
+ id="path23865"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23867" />
+ <path
+ id="path23869"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23871" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10992" />
+ </g>
+ </g>
+ <g
+ id="g23873"
+ transform="translate(0,399)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect23875"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23877">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23879" />
+ <path
+ id="path23881"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23883" />
+ <path
+ id="path23885"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23887" />
+ <path
+ id="path23889"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23891" />
+ <path
+ id="path23893"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23895" />
+ <path
+ id="path23897"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23899" />
+ <path
+ id="path23901"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23903" />
+ <path
+ id="path23905"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23907" />
+ <path
+ id="path23909"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23911" />
+ <path
+ id="path23913"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23915" />
+ <path
+ id="path23917"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23919" />
+ <path
+ id="path23921"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23923" />
+ <path
+ id="path23925"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10994"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g23927"
+ transform="translate(0,378)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23929"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23931">
+ <path
+ id="path23933"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23935" />
+ <path
+ id="path23937"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23939" />
+ <path
+ id="path23941"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23943" />
+ <path
+ id="path23945"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23947" />
+ <path
+ id="path23949"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23951" />
+ <path
+ id="path23953"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23955" />
+ <path
+ id="path23957"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23959" />
+ <path
+ id="path23961"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23963" />
+ <path
+ id="path23965"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23967" />
+ <path
+ id="path23969"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23971" />
+ <path
+ id="path23973"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23975" />
+ <path
+ id="path23977"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23979" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10996" />
+ </g>
+ </g>
+ <g
+ id="g23981"
+ transform="translate(0,357)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23983"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g23985">
+ <path
+ id="path23987"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23989" />
+ <path
+ id="path23991"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23993" />
+ <path
+ id="path23995"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path23997" />
+ <path
+ id="path23999"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24001" />
+ <path
+ id="path24003"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24005" />
+ <path
+ id="path24007"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24009" />
+ <path
+ id="path24011"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24013" />
+ <path
+ id="path24015"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24017" />
+ <path
+ id="path24019"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24021" />
+ <path
+ id="path24023"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24025" />
+ <path
+ id="path24027"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24029" />
+ <path
+ id="path24031"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24033" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path10998" />
+ </g>
+ </g>
+ <g
+ id="g24035"
+ transform="translate(0,336)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24037"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24039">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24041" />
+ <path
+ id="path24043"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24045" />
+ <path
+ id="path24047"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24049" />
+ <path
+ id="path24051"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24053" />
+ <path
+ id="path24055"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24057" />
+ <path
+ id="path24059"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24061" />
+ <path
+ id="path24063"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24065" />
+ <path
+ id="path24067"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24069" />
+ <path
+ id="path24071"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24073" />
+ <path
+ id="path24075"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24077" />
+ <path
+ id="path24079"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24081" />
+ <path
+ id="path24083"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24085" />
+ <path
+ id="path24087"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11000"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24089"
+ transform="translate(0,315)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24091"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24093">
+ <path
+ id="path24095"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24097" />
+ <path
+ id="path24099"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24101" />
+ <path
+ id="path24103"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24105" />
+ <path
+ id="path24107"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24109" />
+ <path
+ id="path24111"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24113" />
+ <path
+ id="path24115"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24117" />
+ <path
+ id="path24119"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24121" />
+ <path
+ id="path24123"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24125" />
+ <path
+ id="path24127"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24129" />
+ <path
+ id="path24131"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24133" />
+ <path
+ id="path24135"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24137" />
+ <path
+ id="path24139"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24141" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11002" />
+ </g>
+ </g>
+ <g
+ id="g24143"
+ transform="translate(0,294)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24145"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24147">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24149" />
+ <path
+ id="path24151"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24153" />
+ <path
+ id="path24155"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24157" />
+ <path
+ id="path24159"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24161" />
+ <path
+ id="path24163"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24165" />
+ <path
+ id="path24167"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24169" />
+ <path
+ id="path24171"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24173" />
+ <path
+ id="path24175"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24177" />
+ <path
+ id="path24179"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24181" />
+ <path
+ id="path24183"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24185" />
+ <path
+ id="path24187"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24189" />
+ <path
+ id="path24191"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24193" />
+ <path
+ id="path24195"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11004"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24197"
+ transform="translate(0,273)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24199"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24201">
+ <path
+ id="path24203"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24205" />
+ <path
+ id="path24207"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24209" />
+ <path
+ id="path24211"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24213" />
+ <path
+ id="path24215"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24217" />
+ <path
+ id="path24219"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24221" />
+ <path
+ id="path24223"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24225" />
+ <path
+ id="path24227"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24229" />
+ <path
+ id="path24231"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24233" />
+ <path
+ id="path24235"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24237" />
+ <path
+ id="path24239"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24241" />
+ <path
+ id="path24243"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24245" />
+ <path
+ id="path24247"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24249" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11006" />
+ </g>
+ </g>
+ <g
+ id="g24251"
+ transform="translate(0,252)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24253"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24255">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24257" />
+ <path
+ id="path24259"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24261" />
+ <path
+ id="path24263"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24265" />
+ <path
+ id="path24267"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24269" />
+ <path
+ id="path24271"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24273" />
+ <path
+ id="path24275"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24277" />
+ <path
+ id="path24279"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24281" />
+ <path
+ id="path24283"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24285" />
+ <path
+ id="path24287"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24289" />
+ <path
+ id="path24291"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24293" />
+ <path
+ id="path24295"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24297" />
+ <path
+ id="path24299"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24301" />
+ <path
+ id="path24303"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11008"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24305"
+ transform="translate(0,231)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24307"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24309">
+ <path
+ id="path24311"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24313" />
+ <path
+ id="path24315"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24317" />
+ <path
+ id="path24319"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24321" />
+ <path
+ id="path24323"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24325" />
+ <path
+ id="path24327"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24329" />
+ <path
+ id="path24331"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24333" />
+ <path
+ id="path24335"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24337" />
+ <path
+ id="path24339"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24341" />
+ <path
+ id="path24343"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24345" />
+ <path
+ id="path24347"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24349" />
+ <path
+ id="path24351"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24353" />
+ <path
+ id="path24355"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24357" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11010" />
+ </g>
+ </g>
+ <g
+ id="g24359"
+ transform="translate(0,210)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24361"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24363">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24365" />
+ <path
+ id="path24367"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24369" />
+ <path
+ id="path24371"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24373" />
+ <path
+ id="path24375"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24377" />
+ <path
+ id="path24379"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24381" />
+ <path
+ id="path24383"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24385" />
+ <path
+ id="path24387"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24389" />
+ <path
+ id="path24391"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24393" />
+ <path
+ id="path24395"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24397" />
+ <path
+ id="path24399"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24401" />
+ <path
+ id="path24403"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24405" />
+ <path
+ id="path24407"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24409" />
+ <path
+ id="path24411"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11012"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24413"
+ transform="translate(0,189)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24415"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24417">
+ <path
+ id="path24419"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24421" />
+ <path
+ id="path24423"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24425" />
+ <path
+ id="path24427"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24429" />
+ <path
+ id="path24431"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24433" />
+ <path
+ id="path24435"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24437" />
+ <path
+ id="path24439"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24441" />
+ <path
+ id="path24443"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24445" />
+ <path
+ id="path24447"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24449" />
+ <path
+ id="path24451"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24453" />
+ <path
+ id="path24455"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24457" />
+ <path
+ id="path24459"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24461" />
+ <path
+ id="path24463"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24465" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11014" />
+ </g>
+ </g>
+ <g
+ id="g24467"
+ transform="translate(0,168)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24469"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24471">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24473" />
+ <path
+ id="path24475"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24477" />
+ <path
+ id="path24479"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24481" />
+ <path
+ id="path24483"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24485" />
+ <path
+ id="path24487"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24489" />
+ <path
+ id="path24491"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24493" />
+ <path
+ id="path24495"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24497" />
+ <path
+ id="path24499"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24501" />
+ <path
+ id="path24503"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24505" />
+ <path
+ id="path24507"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24509" />
+ <path
+ id="path24511"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24513" />
+ <path
+ id="path24515"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24517" />
+ <path
+ id="path24519"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11016"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24521"
+ transform="translate(0,147)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24523"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24525">
+ <path
+ id="path24527"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24529" />
+ <path
+ id="path24531"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24533" />
+ <path
+ id="path24535"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24537" />
+ <path
+ id="path24539"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24541" />
+ <path
+ id="path24543"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24545" />
+ <path
+ id="path24547"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24549" />
+ <path
+ id="path24551"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24553" />
+ <path
+ id="path24555"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24557" />
+ <path
+ id="path24559"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24561" />
+ <path
+ id="path24563"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24565" />
+ <path
+ id="path24567"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24569" />
+ <path
+ id="path24571"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24573" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11018" />
+ </g>
+ </g>
+ <g
+ id="g24575"
+ transform="translate(0,126)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24577"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24579">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24581" />
+ <path
+ id="path24583"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24585" />
+ <path
+ id="path24587"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24589" />
+ <path
+ id="path24591"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24593" />
+ <path
+ id="path24595"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24597" />
+ <path
+ id="path24599"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24601" />
+ <path
+ id="path24603"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24605" />
+ <path
+ id="path24607"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24609" />
+ <path
+ id="path24611"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24613" />
+ <path
+ id="path24615"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24617" />
+ <path
+ id="path24619"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24621" />
+ <path
+ id="path24623"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24625" />
+ <path
+ id="path24627"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11020"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24630"
+ transform="translate(0,105)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24632"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24634">
+ <path
+ id="path24636"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24638" />
+ <path
+ id="path24640"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24642" />
+ <path
+ id="path24644"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24646" />
+ <path
+ id="path24648"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24650" />
+ <path
+ id="path24652"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24654" />
+ <path
+ id="path24656"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24658" />
+ <path
+ id="path24660"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24662" />
+ <path
+ id="path24664"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24666" />
+ <path
+ id="path24668"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24670" />
+ <path
+ id="path24672"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24674" />
+ <path
+ id="path24676"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24678" />
+ <path
+ id="path24680"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24682" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11022" />
+ </g>
+ </g>
+ <g
+ id="g24684"
+ transform="translate(0,84)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24686"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24688">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24690" />
+ <path
+ id="path24692"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24694" />
+ <path
+ id="path24696"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24698" />
+ <path
+ id="path24700"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24702" />
+ <path
+ id="path24704"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24706" />
+ <path
+ id="path24708"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24710" />
+ <path
+ id="path24712"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24714" />
+ <path
+ id="path24716"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24718" />
+ <path
+ id="path24720"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24722" />
+ <path
+ id="path24724"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24726" />
+ <path
+ id="path24728"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24730" />
+ <path
+ id="path24732"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24734" />
+ <path
+ id="path24736"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11024"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24738"
+ transform="translate(0,63)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24740"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24742">
+ <path
+ id="path24744"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24746" />
+ <path
+ id="path24748"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24750" />
+ <path
+ id="path24752"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24754" />
+ <path
+ id="path24756"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24758" />
+ <path
+ id="path24760"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24762" />
+ <path
+ id="path24764"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24766" />
+ <path
+ id="path24768"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24770" />
+ <path
+ id="path24772"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24774" />
+ <path
+ id="path24776"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24778" />
+ <path
+ id="path24780"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24782" />
+ <path
+ id="path24784"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24786" />
+ <path
+ id="path24788"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24790" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11026" />
+ </g>
+ </g>
+ <g
+ id="g24792"
+ transform="translate(0,42)">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24794"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24796">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24798" />
+ <path
+ id="path24800"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24802" />
+ <path
+ id="path24804"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24806" />
+ <path
+ id="path24808"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24810" />
+ <path
+ id="path24812"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24814" />
+ <path
+ id="path24816"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24818" />
+ <path
+ id="path24820"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24822" />
+ <path
+ id="path24824"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24826" />
+ <path
+ id="path24828"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24830" />
+ <path
+ id="path24832"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24834" />
+ <path
+ id="path24836"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24838" />
+ <path
+ id="path24840"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24842" />
+ <path
+ id="path24844"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11028"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24846"
+ transform="translate(0,21)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24848"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g24850">
+ <path
+ id="path24852"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24854" />
+ <path
+ id="path24856"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24858" />
+ <path
+ id="path24860"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24862" />
+ <path
+ id="path24864"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24866" />
+ <path
+ id="path24868"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24870" />
+ <path
+ id="path24872"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24874" />
+ <path
+ id="path24876"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24878" />
+ <path
+ id="path24880"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24882" />
+ <path
+ id="path24884"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24886" />
+ <path
+ id="path24888"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24890" />
+ <path
+ id="path24892"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24894" />
+ <path
+ id="path24896"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24898" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path11030" />
+ </g>
+ </g>
+ <g
+ id="g24900">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect24902"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24904">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24906" />
+ <path
+ id="path24908"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24910" />
+ <path
+ id="path24912"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24914" />
+ <path
+ id="path24916"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24918" />
+ <path
+ id="path24920"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24922" />
+ <path
+ id="path24924"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24926" />
+ <path
+ id="path24928"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24930" />
+ <path
+ id="path24932"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24934" />
+ <path
+ id="path24936"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24938" />
+ <path
+ id="path24940"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24942" />
+ <path
+ id="path24944"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24946" />
+ <path
+ id="path24948"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path24950" />
+ <path
+ id="path24952"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11032"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,483)"
+ id="g39833">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect39835"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39837">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39840" />
+ <path
+ id="path39842"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39844" />
+ <path
+ id="path39846"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39848" />
+ <path
+ id="path39850"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39852" />
+ <path
+ id="path39854"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39856" />
+ <path
+ id="path39858"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39860" />
+ <path
+ id="path39862"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39864" />
+ <path
+ id="path39866"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39868" />
+ <path
+ id="path39870"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39872" />
+ <path
+ id="path39874"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39876" />
+ <path
+ id="path39878"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39880" />
+ <path
+ id="path39882"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39884" />
+ <path
+ id="path39888"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path39890"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g39892"
+ transform="translate(0,504)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39894"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g39896">
+ <path
+ id="path39898"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39900" />
+ <path
+ id="path39902"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39904" />
+ <path
+ id="path39907"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39909" />
+ <path
+ id="path39911"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39913" />
+ <path
+ id="path39915"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39917" />
+ <path
+ id="path39919"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39921" />
+ <path
+ id="path39923"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39925" />
+ <path
+ id="path39927"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39929" />
+ <path
+ id="path39931"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39933" />
+ <path
+ id="path39935"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39937" />
+ <path
+ id="path39939"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39941" />
+ <path
+ id="path39943"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39945" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39947" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,525)"
+ id="g39949">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect39951"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39953">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39955" />
+ <path
+ id="path39957"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39959" />
+ <path
+ id="path39961"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39963" />
+ <path
+ id="path39965"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39967" />
+ <path
+ id="path39969"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39971" />
+ <path
+ id="path39973"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39975" />
+ <path
+ id="path39977"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39979" />
+ <path
+ id="path39981"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39983" />
+ <path
+ id="path39985"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39987" />
+ <path
+ id="path39989"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39991" />
+ <path
+ id="path39993"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39995" />
+ <path
+ id="path39997"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path39999" />
+ <path
+ id="path40001"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path40003"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g40005"
+ transform="translate(0,546)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40007"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g40009">
+ <path
+ id="path40011"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40013" />
+ <path
+ id="path40015"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40017" />
+ <path
+ id="path40019"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40021" />
+ <path
+ id="path40023"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40025" />
+ <path
+ id="path40027"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40029" />
+ <path
+ id="path40031"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40033" />
+ <path
+ id="path40035"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40038" />
+ <path
+ id="path40040"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40042" />
+ <path
+ id="path40044"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40046" />
+ <path
+ id="path40048"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40050" />
+ <path
+ id="path40052"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40054" />
+ <path
+ id="path40056"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40058" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40060" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,567)"
+ id="g40062">
+ <rect
+ ry="0"
+ rx="0"
+ y="26"
+ x="0"
+ height="1"
+ width="6"
+ id="rect40064"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g40066">
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40068" />
+ <path
+ id="path40070"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40072" />
+ <path
+ id="path40074"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40076" />
+ <path
+ id="path40078"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40080" />
+ <path
+ id="path40082"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40084" />
+ <path
+ id="path40086"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40088" />
+ <path
+ id="path40090"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40092" />
+ <path
+ id="path40094"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40096" />
+ <path
+ id="path40098"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40100" />
+ <path
+ id="path40102"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40104" />
+ <path
+ id="path40106"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40108" />
+ <path
+ id="path40110"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40112" />
+ <path
+ id="path40114"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path40116"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g40118"
+ transform="translate(0,588)">
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40120"
+ width="6"
+ height="1"
+ x="0"
+ y="26"
+ rx="0"
+ ry="0" />
+ <g
+ id="g40122">
+ <path
+ id="path40124"
+ d="m 506,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 485,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40126" />
+ <path
+ id="path40128"
+ d="m 464,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 443,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40130" />
+ <path
+ id="path40132"
+ d="m 422,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 401,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40134" />
+ <path
+ id="path40136"
+ d="m 380,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 359,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40138" />
+ <path
+ id="path40140"
+ d="m 338,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 317,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40142" />
+ <path
+ id="path40144"
+ d="m 296,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 275,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40146" />
+ <path
+ id="path40148"
+ d="m 254,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 233,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40150" />
+ <path
+ id="path40152"
+ d="m 212,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40154" />
+ <path
+ id="path40156"
+ d="m 170,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 149,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40158" />
+ <path
+ id="path40160"
+ d="m 128,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40162" />
+ <path
+ id="path40164"
+ d="m 86,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 65,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40166" />
+ <path
+ id="path40168"
+ d="m 44,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 23,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40170" />
+ <path
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 527,20 0,6 -6,0 0,1 6,0 0,6 1,0 0,-6 6,0 0,-1 -6,0 0,-6 -1,0 z"
+ id="path40172" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(0,633)"
+ id="g25954">
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="422"
+ height="7"
+ width="1"
+ id="rect25956"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25958"
+ width="1"
+ height="7"
+ x="401"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="380"
+ height="7"
+ width="1"
+ id="rect25960"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25962"
+ width="1"
+ height="7"
+ x="359"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="338"
+ height="7"
+ width="1"
+ id="rect25964"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25966"
+ width="1"
+ height="7"
+ x="317"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="296"
+ height="7"
+ width="1"
+ id="rect25968"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25970"
+ width="1"
+ height="7"
+ x="275"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="254"
+ height="7"
+ width="1"
+ id="rect25972"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25974"
+ width="1"
+ height="7"
+ x="233"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="212"
+ height="7"
+ width="1"
+ id="rect25976"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25978"
+ width="1"
+ height="7"
+ x="191"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="170"
+ height="7"
+ width="1"
+ id="rect25980"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25982"
+ width="1"
+ height="7"
+ x="149"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="128"
+ height="7"
+ width="1"
+ id="rect25984"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25986"
+ width="1"
+ height="7"
+ x="107"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="86"
+ height="7"
+ width="1"
+ id="rect25988"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25990"
+ width="1"
+ height="7"
+ x="65"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="44"
+ height="7"
+ width="1"
+ id="rect25992"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25994"
+ width="1"
+ height="7"
+ x="23"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25996"
+ width="1"
+ height="7"
+ x="506"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="485"
+ height="7"
+ width="1"
+ id="rect25998"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26000"
+ width="1"
+ height="7"
+ x="464"
+ y="0"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="443"
+ height="7"
+ width="1"
+ id="rect26002"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="0"
+ x="527"
+ height="7"
+ width="1"
+ id="rect11034"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g30515"
+ transform="translate(-121.95685,2)">
+ <rect
+ ry="0"
+ rx="0"
+ y="488"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect26734"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26788"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="467"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="446"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect26842"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26896"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="425"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="404"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect26950"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="383"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27004"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27058"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="362"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="341"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27112"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27166"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="320"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="299"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27220"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27274"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="278"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="257"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27328"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27382"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="236"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="215"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27436"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27490"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="194"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="173"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27544"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27598"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="152"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="131"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27652"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27706"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="110"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="89"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27760"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27814"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="68"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="47"
+ x="665.95685"
+ height="1"
+ width="6"
+ id="rect27868"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27922"
+ width="6"
+ height="1"
+ x="665.95685"
+ y="26"
+ rx="0"
+ ry="0" />
+ </g>
+ <rect
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28448"
+ width="0"
+ height="0"
+ x="217.25"
+ y="263.5" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer4"
+ inkscape:label="sheet layout"
+ style="display:inline"
+ sodipodi:insensitive="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path19551-18-8"
+ d="m 585,613.25 1,0 0,0.5 1,0 0,-0.5 1,0 0,0.75 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,0.75 -1,0 0,-0.5 -1,0 0,0.5 -1,0 0,1.5 z m 1,-0.25 0,-1 1,0 0,1 -1,0 z m 2,0 0,-1 1,0 0,1 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19551-18-1"
+ d="m 907.75,209 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ id="g28552-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 536,14 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28554-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 539,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28556-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544,14 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -2,-1 0,-3 -1,0 0,3 1,0 z"
+ id="path28558-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 553,14 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ id="path28560-9"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28562-4"
+ width="1"
+ height="1"
+ x="548"
+ y="18" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28564-8"
+ width="1"
+ height="5"
+ x="557"
+ y="14" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 559,14 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path28566-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 565.75,14 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28568-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 570,14 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path28570-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 573,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28572-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21.98523,3)"
+ id="g28574-5">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 534,74 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28576-1"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28578-7"
+ width="1"
+ height="5"
+ x="538"
+ y="74" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 540,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path28580-1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28582-1"
+ d="m 544,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28584-5"
+ d="m 551,74 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28586-2"
+ d="m 554,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 558,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path28588-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 562,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28590-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 567,74 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path28592-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 570,74 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28594-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ id="g28596-2">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 535,119 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path28598-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 539,119 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28600-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 545,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ id="path28602-2"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28604-1"
+ width="1"
+ height="5"
+ x="549"
+ y="119" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 551,119 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28606-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 555,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ id="path28608-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(16,1)"
+ id="g28610-5">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 540,160 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28612-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544,160 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28614-6"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28616-1"
+ width="1"
+ height="5"
+ x="548"
+ y="160" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 550,160 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28618-8"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="160"
+ x="554"
+ height="5"
+ width="1"
+ id="rect28620-9"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 556,160 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28622-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 562,160 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -0.99999,0 0,1.25 -1.00001,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path28624-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ id="g28626-9">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 535.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28628-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 539,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28630-4"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28632-3"
+ width="1"
+ height="5"
+ x="544"
+ y="224" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 546,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path28634-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 552.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28636-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 556,224 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28638-3"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="224"
+ x="560"
+ height="5"
+ width="1"
+ id="rect28640-3"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 563,224 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28642-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 567,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28644-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,-1)"
+ id="g28646-1">
+ <path
+ id="path28648-3"
+ d="m 535,267 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28650-8"
+ d="m 542,267 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 546,267 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28652-7"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28654-4"
+ width="1"
+ height="5"
+ x="550"
+ y="267" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 552,267 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28656-2"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28658-7"
+ width="1"
+ height="5"
+ x="556"
+ y="267" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 558,267 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28660-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 562,267 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28662-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 567,267 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28664-3"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(25,-1)"
+ id="g28666-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 532,36 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28668-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 539.75,36 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28670-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 543,36 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28672-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 547,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28674-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28676-0"
+ d="m 555,36 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 558,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28678-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 562,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28680-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28682-6"
+ d="m 566,36 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28684-0"
+ d="m 570,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 535,36 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path28686-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(19,125)"
+ id="g28688-4">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 538,299 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28690-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 542,299 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path28692-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 547,299 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28694-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 551,299 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path28696-0"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28698-9"
+ width="1"
+ height="5"
+ x="555"
+ y="299" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 557,299 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28700-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 562,299 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28702-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 566,299 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28704-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(21,128)"
+ id="g28706-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 539.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28708-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 535,359 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28710-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 543,359 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28712-9"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28714-3"
+ d="m 547.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22,125)"
+ id="g28716-4">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 545,393 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28718-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 549,393 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28720-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 534,393 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path28722-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 541,393 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28724-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 554,393 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28726-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22.01477,127)"
+ id="g28728-1">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 538,412 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path28730-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 534,412 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path28732-4"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28734-9"
+ width="1"
+ height="5"
+ x="542"
+ y="412" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 549,412 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28736-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 553,412 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path28738-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 558,412 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28740-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28742-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(22.01477,127)"
+ id="g28744-8">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 534,434 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path28746-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 556,434 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path28748-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 552,434 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path28750-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 562,434 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path28752-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 543,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path28754-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 538,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path28756-9"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28758-8"
+ d="m 547,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.3;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(19,127)"
+ id="g28760-4">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28762-0"
+ width="1"
+ height="5"
+ x="542"
+ y="486" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 537,486 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path28764-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10763-6"
+ transform="translate(21,0)">
+ <path
+ id="path10757-3"
+ d="m 536,14 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10759-6"
+ d="m 539,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10761-1"
+ d="m 544,14 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -2,-1 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10763-5"
+ d="m 553,14 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="18"
+ x="548"
+ height="1"
+ width="1"
+ id="rect10765-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="14"
+ x="557"
+ height="5"
+ width="1"
+ id="rect10767-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10769-0"
+ d="m 559,14 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10771-9"
+ d="m 565.75,14 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10773-7"
+ d="m 570,14 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10775-3"
+ d="m 573,14 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10815-7"
+ transform="translate(21.98523,3)">
+ <path
+ id="path10799-2"
+ d="m 534,74 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="74"
+ x="538"
+ height="5"
+ width="1"
+ id="rect10801-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10803-0"
+ d="m 540,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path10805-1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 551,74 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path10807-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 554,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path10809-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10811-7"
+ d="m 558,74 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10813-5"
+ d="m 562,74 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10815-4"
+ d="m 567,74 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10817-1"
+ d="m 570,74 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10827-2"
+ transform="translate(21,0)">
+ <path
+ id="path10672-0"
+ d="m 535,119 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10678-0"
+ d="m 539,119 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10680-1"
+ d="m 545,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="119"
+ x="549"
+ height="5"
+ width="1"
+ id="rect10682-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10684-6"
+ d="m 551,119 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10686-0"
+ d="m 555,119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10835-7"
+ transform="translate(16,1)">
+ <path
+ id="path10688-1"
+ d="m 540,160 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10690-7"
+ d="m 544,160 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="160"
+ x="548"
+ height="5"
+ width="1"
+ id="rect10692-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10694-7"
+ d="m 550,160 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect10696-7"
+ width="1"
+ height="5"
+ x="554"
+ y="160" />
+ <path
+ id="path10698-3"
+ d="m 556,160 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10700-3"
+ d="m 562,160 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -0.99999,0 0,1.25 -1.00001,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10846-5"
+ transform="translate(21,0)">
+ <path
+ id="path10703-9"
+ d="m 535.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10705-9"
+ d="m 539,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="224"
+ x="544"
+ height="5"
+ width="1"
+ id="rect10708-8"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10711-1"
+ d="m 546,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10714-8"
+ d="m 552.75,224 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10716-2"
+ d="m 556,224 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect10718-6"
+ width="1"
+ height="5"
+ x="560"
+ y="224" />
+ <path
+ id="path10734-6"
+ d="m 563,224 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10736-0"
+ d="m 567,224 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10857-3"
+ transform="translate(21,-1)">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 535,267 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path10744-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 542,267 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path10746-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10748-1"
+ d="m 546,267 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="267"
+ x="550"
+ height="5"
+ width="1"
+ id="rect10750-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10752-5"
+ d="m 552,267 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="267"
+ x="556"
+ height="5"
+ width="1"
+ id="rect10754-0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10756-9"
+ d="m 558,267 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10758-4"
+ d="m 562,267 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10760-7"
+ d="m 567,267 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10803-8"
+ transform="translate(25,-1)">
+ <path
+ id="path10777-3"
+ d="m 532,36 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10781-5"
+ d="m 539.75,36 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10783-1"
+ d="m 543,36 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10785-2"
+ d="m 547,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 555,36 0,1.75 -1,0 0,1.25 -1,0 0,2 1,0 0,-1.75 1,0 0,-1.25 1,0 0,-2 -1,0 z"
+ id="path10787-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10789-1"
+ d="m 558,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10791-6"
+ d="m 562,36 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 566,36 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ id="path10795-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 570,36 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path10797-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10800-6"
+ d="m 535,36 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10885-1"
+ transform="translate(19,125)">
+ <path
+ id="path10869-8"
+ d="m 538,299 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10871-9"
+ d="m 542,299 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10873-8"
+ d="m 547,299 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10875-4"
+ d="m 551,299 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="299"
+ x="555"
+ height="5"
+ width="1"
+ id="rect10877-1"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10879-4"
+ d="m 557,299 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10881-3"
+ d="m 562,299 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10883-9"
+ d="m 566,299 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10921-8"
+ transform="translate(21,128)">
+ <path
+ id="path10895-8"
+ d="m 539.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10897-0"
+ d="m 535,359 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10899-8"
+ d="m 543,359 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 547.75,359 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path10901-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10914-7"
+ transform="translate(22,125)">
+ <path
+ id="path10903-8"
+ d="m 545,393 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10906-3"
+ d="m 549,393 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10908-8"
+ d="m 534,393 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10910-3"
+ d="m 541,393 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10912-7"
+ d="m 554,393 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10942-1"
+ transform="translate(22.01477,127)">
+ <path
+ id="path10928-0"
+ d="m 538,412 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10930-7"
+ d="m 534,412 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="412"
+ x="542"
+ height="5"
+ width="1"
+ id="rect10932-3"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10934-4"
+ d="m 549,412 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10936-9"
+ d="m 553,412 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10938-6"
+ d="m 558,412 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10940-5"
+ d="m 544,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10966-1"
+ transform="translate(22.01477,127)">
+ <path
+ id="path10951-0"
+ d="m 534,434 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10953-9"
+ d="m 556,434 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10956-9"
+ d="m 552,434 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10958-6"
+ d="m 562,434 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10960-8"
+ d="m 543,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10962-3"
+ d="m 538,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 547,434 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ id="path10964-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10980-8"
+ transform="translate(19,127)">
+ <rect
+ y="486"
+ x="542"
+ height="5"
+ width="1"
+ id="rect10975-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path10978-9"
+ d="m 537,486 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544,133 0,1 9,0 0,62 -9,0 0,1 9,0 1,0 0,-33 1,0 0,-1 -1,0 0,-30 -1,0 -9,0 z"
+ id="rect11044-9"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <a
+ style="display:inline;enable-background:new"
+ id="a28530-2">
+ <g
+ style="fill:#b3b3b3"
+ transform="translate(-3e-6,1)"
+ id="g11054-5">
+ <path
+ id="path19464-5"
+ d="m 1.75,13 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19466-3"
+ d="m 1,34 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 L 3,34 2,34 1,34 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19468-3"
+ d="m 2,55.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19470-3"
+ d="m 1,76 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 L 3,76 1,76 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19472-7"
+ d="m 1,98 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19474-4"
+ d="m 1,118 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19476-3"
+ d="m 2,139 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19478-8"
+ d="m 1,160 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="182"
+ x="2"
+ height="5"
+ width="1"
+ id="rect19480-0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path19482-8"
+ d="m 3,202 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19484-8"
+ d="m 1,223 0,5 1,0 0,-1.75 1,0 0,-1.5 -1,0 0,-1.75 -1,0 z m 2,1.75 1,0 0,-1.75 -1,0 0,1.75 z m 0,1.5 0,1.75 1,0 0,-1.75 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19486-0"
+ d="m 1,244 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19488-6"
+ d="m 3e-6,265 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 0,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 0,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19490-8"
+ d="m 1,286 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19492-1"
+ d="m 2,307 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m -1,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19494-9"
+ d="m 1,328 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19496-8"
+ d="m 2,349 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -1,-1 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19498-9"
+ d="m 1,370 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19500-7"
+ d="m 2,391 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19502-2"
+ d="m 1,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19504-2"
+ d="m 1,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19506-8"
+ d="m 1,455 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19508-2"
+ d="m 3e-6,475 0,3.25 1,0 0,1.75 1,0 0,-1.75 0.999997,0 0,1.75 1.000003,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 L 3,478 l 0,-2 -0.999997,0 0,2 -1,0 0,-3 -1,0 0,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1,497 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ id="rect19510-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.750003,556 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38399-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.000003,577 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 0,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path38401-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 2.000003,598.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 0,0 z"
+ id="path38403-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.000003,619 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 0,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path38405-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38411-1"
+ d="m 1.750003,563 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38413-5"
+ d="m 1.750003,584 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1.750003,605 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38415-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38417-6"
+ d="m 1.750003,626 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 0,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38419-1"
+ d="m 548.75,556 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38421-2"
+ d="m 548,577 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38423-4"
+ d="m 549,598.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38425-2"
+ d="m 548,619 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548.75,563 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38427-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548.75,584 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38429-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38431-6"
+ d="m 548.75,605 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548.75,626 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path38433-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </a>
+ <path
+ inkscape:connector-curvature="0"
+ id="path19537-6"
+ d="m 12,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19539-5"
+ d="m 33,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 L 35,2 33,2 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19541-3"
+ d="m 54,2 0,1 2,0 0,1 1,0 0,-1.25 -1,0 L 56,2 54,2 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 L 57,5 56,5 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19543-9"
+ d="m 75,2 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19545-2"
+ d="m 96,2 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19547-4"
+ d="m 118,2 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19549-6"
+ d="m 138,2 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19551-18"
+ d="m 159.75,2 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19553-2"
+ d="m 180.75,2 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccc"
+ id="path19555-1"
+ d="m 202.75,2 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 514,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path19559-1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 476,2 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path19561-9" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 497,2 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ id="path19563-7" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518,2 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path19565-6" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19577-2"
+ d="m 200,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19579-9"
+ d="m 244,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19581-5"
+ d="m 265,2 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19583-2"
+ d="m 286,2 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19585-0"
+ d="m 307,2 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19587-0"
+ d="m 329,2 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19589-3"
+ d="m 349,2 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19591-9"
+ d="m 370.75,2 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19593-1"
+ d="m 391.75,2 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19595-8"
+ d="m 413.75,2 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19597-1"
+ d="m 221,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ id="path19599-9" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19601-5"
+ d="m 242,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19603-3"
+ d="m 263,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19605-2"
+ d="m 284,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19607-5"
+ d="m 305,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19609-2"
+ d="m 326,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19611-5"
+ d="m 347,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19613-8"
+ d="m 368,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19615-6"
+ d="m 389,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19617-7"
+ d="m 409,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19619-7"
+ d="m 435,2 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19621-2"
+ d="m 430,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19623-2"
+ d="m 451,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 455,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path19625-9" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19627-4"
+ d="m 472,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19629-1"
+ d="m 493,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path11036-9"
+ d="m 536,2 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 541,2 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ id="path11038-6" />
+ <g
+ id="g11125-9"
+ transform="translate(547,1)"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <path
+ id="path11128-8"
+ d="m 1.75,13 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11130-2"
+ d="m 1,34 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 L 3,34 2,34 1,34 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11132-5"
+ d="m 2,55.25 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11134-5"
+ d="m 1,76 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 L 3,76 1,76 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11136-4"
+ d="m 1,98 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11138-9"
+ d="m 1,118 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11140-1"
+ d="m 2,139 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11142-2"
+ d="m 1,160 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="182"
+ x="2"
+ height="5"
+ width="1"
+ id="rect11144-5"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path11146-0"
+ d="m 3,202 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11148-8"
+ d="m 1,223 0,5 1,0 0,-1.75 1,0 0,-1.5 -1,0 0,-1.75 -1,0 z m 2,1.75 1,0 0,-1.75 -1,0 0,1.75 z m 0,1.5 0,1.75 1,0 0,-1.75 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11150-3"
+ d="m 1,244 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11152-9"
+ d="m 1,265 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11154-3"
+ d="m 1,286 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11156-9"
+ d="m 2,307 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m -1,0 0,-3 -1,0 0,3 1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11158-6"
+ d="m 1,328 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11160-7"
+ d="m 2,349 0,1 1,0 0,-1 -1,0 z m 1,1 0,3 1,0 0,-3 -1,0 z m 0,3 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m -1,-1 0,-3 -1,0 0,3 1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11162-9"
+ d="m 1,370 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11164-9"
+ d="m 2,391 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11166-7"
+ d="m 1,412 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11168-6"
+ d="m 1,434 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11170-9"
+ d="m 1,455 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-3 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11172-3"
+ d="m 3e-6,474.75 0,3.25 1,0 0,1.75 1,0 0,-1.75 L 3,478 l 0,1.75 1.000003,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1.000003,0 0,-2 -0.999997,0 0,2 -1,0 0,-3 -1,0 0,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1,497 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ id="path11174-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path38393-7"
+ d="m 1,518 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38395-6"
+ d="m 1,539 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548,518 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path38435-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 548,539 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path38437-5"
+ inkscape:connector-curvature="0" />
+ <g
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g41041-8"
+ transform="translate(0,634)">
+ <path
+ id="path41043-2"
+ d="m 12,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41045-5"
+ d="m 33,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 L 35,1 33,1 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41047-4"
+ d="m 54,1 0,1 2,0 0,1 1,0 0,-1.25 -1,0 L 56,1 54,1 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 L 57,4 56,4 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41049-4"
+ d="m 75,1 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41051-1"
+ d="m 96,1 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41053-6"
+ d="m 118,1 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41055-1"
+ d="m 138,1 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41057-6"
+ d="m 159.75,1 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41059-3"
+ d="m 180.75,1 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccc"
+ id="path41061-3"
+ d="m 202.75,1 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 514,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path41063-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 476,1 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ id="path41065-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 497,1 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ id="path41067-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518,1 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path41069-2"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41071-8"
+ d="m 200,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41073-2"
+ d="m 244,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41075-5"
+ d="m 265,1 0,1 2,0 0,1 1,0 0,-1.25 -1,0 0,-0.75 -2,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.25 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41077-3"
+ d="m 286,1 0,3 1,0 1,0 0,2 1,0 0,-4 -1,0 0,1 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41079-6"
+ d="m 307,1 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41081-1"
+ d="m 329,1 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41083-8"
+ d="m 349,1 0,1 2,0 0,1 -1,0 0,3 1,0 0,-2.75 1,0 0,-1.25 0,-1 -3,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41085-6"
+ d="m 370.75,1 0,1 -0.5,0 0,1 0.5,0 0,1 -0.75,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 0.5,0 0,-1 -0.5,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41087-2"
+ d="m 391.75,1 0,1 -0.75,0 0,1 0.75,0 0,1 1.25,0 0,1 -1.5,0 0,1 1.5,0 0,-0.75 1,0 0,-3.25 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41089-1"
+ d="m 413.75,1 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41091-4"
+ d="m 221,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ id="path41093-6"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41095-2"
+ d="m 242,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41097-9"
+ d="m 263,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41099-1"
+ d="m 284,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41101-5"
+ d="m 305,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41103-0"
+ d="m 326,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41105-3"
+ d="m 347,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41107-6"
+ d="m 368,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41109-4"
+ d="m 389,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41111-9"
+ d="m 409,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41113-2"
+ d="m 435,1 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41116-9"
+ d="m 430,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41118-3"
+ d="m 451,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 455,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path41120-4"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41122-4"
+ d="m 472,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41124-0"
+ d="m 493,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41126-5"
+ d="m 536,1 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 541,1 0,0.75 -1,0 0,3.25 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -1.25,0 0,-1 1.5,0 0,-1 -1.5,0 z m 0,3 1,0 0,1 -1,0 0,-1 z"
+ id="path41128-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path30643-6"
+ d="m 585,617.25 1,0 0,0.75 3,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -3,0 0,0.75 -1,0 0,1.5 z m 1,-0.25 0,-1 3,0 0,1 -3,0 z m 1,-0.25 1,0 0,-0.5 -1,0 0,0.5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path30647-3"
+ d="m 585,630 1,0 0,-2 1,0 0,1 1,0 0,-1 -0.75,0 0,-1 -1.5,0 0,1 -0.75,0 0,2 z m 3,-1 0,1 1,0 1,0 0,-3 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path30649-4"
+ d="m 585,624 3,0 0,-1 0,-1 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 -1.5,0 0,1 -0.75,0 0,1 -1,0 0,-2 -1,0 0,2 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="589"
+ x="-626"
+ height="1"
+ width="1"
+ id="rect30651-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30653-8"
+ width="1"
+ height="1"
+ x="-620"
+ y="589"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ y="589"
+ x="-634"
+ height="1"
+ width="1"
+ id="rect30725-87"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path30723-5"
+ d="m 587,638 2.25,0 0,-1 0.75,0 0,-1 -0.75,0 0,-1 -2.25,0 0,1 2,0 0,1 -2,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ id="path30643-7-0"
+ d="m 903.75,209 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path30647-6-1"
+ d="m 891,209 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path30649-7-4"
+ d="m 897,209 0,3 1,0 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="213"
+ x="895"
+ height="1"
+ width="1"
+ id="rect30651-8-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30653-7-0"
+ width="1"
+ height="1"
+ x="901"
+ y="213" />
+ <rect
+ y="213"
+ x="887"
+ height="1"
+ width="1"
+ id="rect30725-8-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path30723-1-1"
+ d="m 883,211 0,2.25 1,0 0,0.75 1,0 0,-0.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(810,316)"
+ id="g72798"
+ style="opacity:0.5;display:inline;enable-background:new">
+ <g
+ id="g72716">
+ <path
+ id="path72434"
+ d="m 186,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-127"
+ x="219"
+ height="5"
+ width="1"
+ id="rect72436"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path72438"
+ d="m 144,-127 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72440"
+ d="m 189,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72442"
+ d="m 165,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72446"
+ d="m 130,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72448"
+ d="m 154,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72450"
+ d="m 133,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72452"
+ d="m 138,-127 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72454"
+ d="m 151,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72456"
+ d="m 146,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 209,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path72458"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 160,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path72460" />
+ <path
+ id="path72462"
+ d="m 171,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72464"
+ d="m 175,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 179,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path72466" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 194,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path72468" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 202,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72470" />
+ <path
+ id="path72472"
+ d="m 205,-127 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path72474"
+ d="m 215,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 222,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72476" />
+ <path
+ id="path72478"
+ d="m 225,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 229,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path72480" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 235,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72482" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 238,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path72484" />
+ <path
+ id="path72486"
+ d="m 242.75,-123 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32008-7"
+ d="m 72,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32010-4"
+ d="m 76,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-127"
+ x="80"
+ height="5"
+ width="1"
+ id="rect32012-0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32015-9"
+ d="m 83,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32017-4"
+ d="m 89,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32019-8"
+ d="m 97,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32021-8"
+ d="m 93,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32023-2"
+ d="m 102,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32026-4"
+ d="m 106,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 110,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path32029-5" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 115,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path32031-5" />
+ <rect
+ y="-127"
+ x="121"
+ height="5"
+ width="1"
+ id="rect32033-1"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 124,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path32035-7" />
+ </g>
+ <g
+ id="g72757">
+ <path
+ id="path72562"
+ d="m 78,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="82"
+ height="5"
+ width="1"
+ id="rect72564"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path72576"
+ d="m 72,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72578"
+ d="m 130,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72580"
+ d="m 94.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72582"
+ d="m 85,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 88,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path72588" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 99,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72590" />
+ <path
+ id="path72592"
+ d="m 103,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 107,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path72594" />
+ <path
+ id="path72596"
+ d="m 111,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 117,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path72598" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 121.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path72600" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 125,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path72602" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect72604"
+ width="1"
+ height="5"
+ x="136"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 138,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path72606" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 144.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path72608" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path72610"
+ d="m 148,-119 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 153,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path72612" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 157,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path72614" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 163,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path72616" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect72618"
+ width="1"
+ height="5"
+ x="174"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 168,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ id="path72620" />
+ <path
+ id="path72622"
+ d="m 180,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path72624"
+ d="m 176,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32207-9-7"
+ d="m 187,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32209-6-7"
+ d="m 191,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32211-3-7"
+ d="m 195,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32213-7-3"
+ d="m 199,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32216-8-3"
+ d="m 203,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32218-8-5"
+ width="1"
+ height="5"
+ x="207"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32220-2-9"
+ d="m 210,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32222-9-9"
+ d="m 213,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32224-1-8"
+ d="m 217,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path72678"
+ d="m 225,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 235,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path72680"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="223"
+ height="5"
+ width="1"
+ id="rect72682"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-115"
+ x="239"
+ height="1"
+ width="1"
+ id="rect72684"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path72686"
+ d="m 230,-119 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(810,316)"
+ style="display:inline;enable-background:new"
+ id="g72880">
+ <g
+ transform="translate(231,-90)"
+ id="g32242-4">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -12.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32244-2" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -9,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path32246-0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -3,-17 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path32248-9" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32250-7" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 6,-17 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path32252-3" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10,-17 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path32254-7" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -43.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32256-2" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32258-6"
+ d="m -40,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32260-0"
+ d="m -35,-17 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -31,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path32262-1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -27,-17 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path32264-6" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32266-5"
+ d="m -23,-17 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32268-7"
+ d="m -17,-17 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-19"
+ x="11"
+ height="1"
+ width="1"
+ id="rect32270-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g21967-4"
+ transform="translate(111.96875,-88)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 48,-20 0,0.75 -1,0 0,0.25 -0.25,0 0,1 -0.75,0 0,3 0.75,0 0,1 0.25,0 0,0.25 1,0 0,0.75 3,0 0,-0.75 1,0 0,-0.25 0.25,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -0.25,0 0,-0.25 -1,0 0,-0.75 -3,0 z m 0,1 3,0 0,1 1,0 0,3 -1,0 0,1 -3,0 0,-1 -1,0 0,-3 1,0 0,-1 z"
+ id="path32272-1"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path32274-2"
+ d="m 49,-18 0,0.75 -1,0 0,1.5 1,0 0,0.75 1.25,0 0,-1 -1.25,0 0,-1 1.25,0 0,-1 -1.25,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 171.71875,-107 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ id="path72688" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 175.96875,-107 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ id="path72690" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 177.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path72692" />
+ <path
+ id="path72694"
+ d="m 166.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 182.96875,-106 0,1 1,0 0,-1 -1,0 z m -0.21875,3 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ id="path72696" />
+ </g>
+ <g
+ style="opacity:0.4;display:inline;enable-background:new"
+ id="g73280"
+ transform="matrix(0,-1,1,0,722,710)">
+ <g
+ id="g73282">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 186,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73284" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73286"
+ width="1"
+ height="5"
+ x="219"
+ y="-127" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 144,-127 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ id="path73288" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 189,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73290" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 165,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path73292" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 130,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path73294" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 154,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73296" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 133,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ id="path73298" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 138,-127 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ id="path73300" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73302" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 146,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73304" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path73306"
+ d="m 209,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path73308"
+ d="m 160,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 171,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73310" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 175,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73312" />
+ <path
+ id="path73314"
+ d="m 179,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73316"
+ d="m 194,-127 0,4.25 1,0 0,0.75 2,0 0,-0.75 1,0 0,-4.25 -1,0 0,4 -2,0 0,-4 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73318"
+ d="m 202,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 205,-127 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73320" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215,-127 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path73322"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73324"
+ d="m 222,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 225,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73326" />
+ <path
+ id="path73328"
+ d="m 229,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73330"
+ d="m 235,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73332"
+ d="m 238,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 242.75,-123 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ id="path73334" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 72,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73336"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 76,-127 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73338"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73340"
+ width="1"
+ height="5"
+ x="80"
+ y="-127" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 83,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ id="path73342"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89,-127 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73344"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 97,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73346"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 93,-127 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path73348"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 102,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73350"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 106,-127 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73352"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73354"
+ d="m 110,-127 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73356"
+ d="m 115,-127 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73358"
+ width="1"
+ height="5"
+ x="121"
+ y="-127" />
+ <path
+ id="path73360"
+ d="m 124,-127 0,0.75 -1,0 0,1.5 1,0 0,0.75 1,0 0,1 -2,0 0,1 2,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -1,0 0,-1 1.5,0 0,-1 -1.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g73362"
+ transform="translate(175,-8)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 78,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73364" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73366"
+ width="1"
+ height="5"
+ x="82"
+ y="-119" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 72,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ id="path73368" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 130,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73370" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 94.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73372" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73374" />
+ <path
+ id="path73376"
+ d="m 88,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73378"
+ d="m 99,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 103,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73380" />
+ <path
+ id="path73382"
+ d="m 107,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 111,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ id="path73384" />
+ <path
+ id="path73386"
+ d="m 117,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73388"
+ d="m 121.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73390"
+ d="m 125,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="136"
+ height="5"
+ width="1"
+ id="rect73392"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path73394"
+ d="m 138,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73396"
+ d="m 144.75,-119 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148,-119 0,5 1,0 2,0 0,-1 -2,0 0,-4 -1,0 z"
+ id="path73398"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73400"
+ d="m 153,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73402"
+ d="m 157,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73404"
+ d="m 163,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="174"
+ height="5"
+ width="1"
+ id="rect73406"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path73408"
+ d="m 168,-119 0,3.25 1,0 0,1.75 1,0 0,-1.75 1,0 0,1.75 1,0 0,-1.75 1,0 0,-3.25 -1,0 0,3 -1,0 0,-2 -1,0 0,2 -1,0 0,-3 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 180,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73410" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 176,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73412" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 187,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73414"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 191,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ id="path73416"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 195,-119 0,5 1,0 0,-2 1.25,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73418"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 199,-119 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73420"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 203,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ id="path73422"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-119"
+ x="207"
+ height="5"
+ width="1"
+ id="rect73424"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 210,-119 0,0.75 -1,0 0,3.5 1,0 0,0.75 2,0 0,-1 0,-1.25 -1,0 0,1.25 -1,0 0,-3 2,0 0,-1 -2,0 z"
+ id="path73426"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 213,-119 0,5 1,0 0,-2 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path73428"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 217,-119 0,1 1,0 0,4 1,0 0,-4 1,0 0,-1 -3,0 0,0 z"
+ id="path73430"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 225,-119 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73432" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path73434"
+ d="m 235,-119 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73436"
+ width="1"
+ height="5"
+ x="223"
+ y="-119" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73438"
+ width="1"
+ height="1"
+ x="239"
+ y="-115" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 230,-119 0,5 1,0 0,-2 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73440" />
+ </g>
+ </g>
+ <g
+ id="g73442"
+ style="display:inline;enable-background:new"
+ transform="matrix(0,-1,1,0,692,540.96875)">
+ <g
+ id="g73444"
+ transform="translate(231,-90)">
+ <path
+ id="path73446"
+ d="m -12.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73448"
+ d="m -9,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,3 1,0 0,-5 -1,0 0,1 -1,0 0,1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73450"
+ d="m -3,-17 0,5 1,0 1,0 0,-0.5 1,0 0,-1.5 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z m 0,2 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73452"
+ d="m 1,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73454"
+ d="m 6,-17 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 1,0 0,-3 -1,0 z m 0,3 -2,0 0,1 2,0 0,-1 z m -2,0 0,-3 -1,0 0,3 1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73456"
+ d="m 10,-17 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73458"
+ d="m -43.25,-17 0,1 -0.75,0 0,4 1,0 0,-2 1,0 0,2 1,0 0,-4 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -40,-17 0,5 1,0 0,-3 1,0 0,-1 -1,0 0,-1 -1,0 z m 2,2 0,1 1,0 0,2 1,0 0,-5 -1,0 0,2 -1,0 z"
+ id="path73460"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -35,-17 0,1 0,3 0,1 2,0 0,-0.75 1,0 0,-3.5 -1,0 0,-0.75 -2,0 z m 1,1 1,0 0,3 -1,0 0,-3 z"
+ id="path73462"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73464"
+ d="m -31,-17 0,5 1,0 0,-2 1,0 0,2 1,0 0,-2 -0.75,0 0,-1 0.75,0 0,-1.25 -1,0 0,-0.75 -1,0 -1,0 z m 1,1 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73466"
+ d="m -27,-17 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -23,-17 0,5 1,0 2,0 0,-1 -2,0 0,-1 1,0 0,-1 -1,0 0,-1 2,0 0,-1 -2,0 -1,0 z"
+ id="path73468"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -17,-17 0,4 -1,0 0,-1 -1,0 0,1 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-4 -1,0 z"
+ id="path73470"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect73472"
+ width="1"
+ height="1"
+ x="11"
+ y="-19" />
+ </g>
+ <g
+ transform="translate(111.96875,-88)"
+ id="g73474">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccc"
+ id="path73476"
+ d="m 48,-20 0,0.75 -1,0 0,0.25 -0.25,0 0,1 -0.75,0 0,3 0.75,0 0,1 0.25,0 0,0.25 1,0 0,0.75 3,0 0,-0.75 1,0 0,-0.25 0.25,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -0.25,0 0,-0.25 -1,0 0,-0.75 -3,0 z m 0,1 3,0 0,1 1,0 0,3 -1,0 0,1 -3,0 0,-1 -1,0 0,-3 1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 49,-18 0,0.75 -1,0 0,1.5 1,0 0,0.75 1.25,0 0,-1 -1.25,0 0,-1 1.25,0 0,-1 -1.25,0 z"
+ id="path73478"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path73480"
+ d="m 171.71875,-107 0,1 -0.75,0 0,3 0.75,0 0,1 1.5,0 0,-1 0.75,0 0,-3 -0.75,0 0,-1 -1.5,0 z m 0.25,1 1,0 0,3 -1,0 0,-3 z m 0.25,1 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73482"
+ d="m 175.96875,-107 0,1 -1,0 0,1 1,0 0,3 1,0 0,-5 -1,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path73484"
+ d="m 177.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 166.96875,-107 0,1 2,0 0,1 -1,0 0,1 1,0 0,-0.75 1,0 0,-1.5 -1,0 0,-0.75 -2,0 z m 1,3 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path73486" />
+ <path
+ id="path73488"
+ d="m 182.96875,-106 0,1 1,0 0,-1 -1,0 z m -0.21875,3 0,1 -0.75,0 0,1 1,0 0,-1 1,0 0,-1 -1.25,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ inkscape:label="ICONS"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline">
+ <g
+ transform="matrix(0,1,1,0,-174,194)"
+ style="display:inline;enable-background:new"
+ id="g106468-0">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.9535916,0,0,1.1712921,1176.1968,319.2322)"
+ id="g29877-5-3-1-8"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path29879-5-0-9-1"
+ d="m 392.96689,241.84215 -0.56915,0 -3.5287,2.84782 0,1.13912 3.5287,2.84781 0.56915,0 0,-6.83475 0,0 0,0 z"
+ style="color:#000000;fill:url(#radialGradient106344-5-2);fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient106433-4);stroke-width:0.66107476px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path29881-5-6-0-4"
+ d="m 392.96688,248.67221 -0.57173,0 -3.51515,-2.83619 -0.008,-1.21916"
+ style="fill:none;stroke:url(#linearGradient106307-2-4);stroke-width:0.66107482px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="598"
+ x="404"
+ height="16"
+ width="16"
+ id="rect24491-0"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 5a.png"
+ transform="translate(440.42789,-242.41778)"
+ id="g14713">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ id="g14715"
+ transform="translate(-320.42789,5.4177849)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14717"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g14719">
+ <g
+ transform="translate(480,287.5)"
+ id="g14721"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(-118.5,-200.5)"
+ id="g14723" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g14725" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14727"
+ width="16"
+ height="16"
+ x="68.572113"
+ y="294.41779"
+ rx="0"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient14800);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 72.738774,294.91779 10.33334,0 0,14.99999 -13,0 -1e-5,-11.99999 2.66667,-3 z"
+ id="path14729"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path14731"
+ style="fill:none;stroke:url(#linearGradient14802);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 71.072114,299.41778 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path14733"
+ d="m 69.572114,298.41778 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:0.75490196;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path14735"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 70.072114,297.41779 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ clip-path="url(#clipPath22590-7)"
+ mask="none"
+ transform="translate(100.57211,-194.58234)"
+ id="g14737"
+ style="display:inline"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14739"
+ width="16"
+ height="16"
+ x="-29"
+ y="491.00012" />
+ <g
+ id="g14741">
+ <g
+ id="g14743">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14745" />
+ <path
+ transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path14747"
+ style="fill:none;stroke:#000000;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path14749"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -8.5,5.00012 3.5,-3.5"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <path
+ transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path14751"
+ style="fill:none;stroke:url(#linearGradient14804);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -26.5,501.50012 -21.5,496.5 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient14806);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14753" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path14755"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
+ <path
+ transform="matrix(2,0,0,2,-46,385)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path14757"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient14808);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14759"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -6.734366,7.94478 3.280183,-3.10926 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient14810);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path14761" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient20368);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 74.072114,296.91778 0,2 -2,0"
+ id="path14763"
+ inkscape:connector-curvature="0"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 4 (alpha).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14765"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_big_redone 5a.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(1090.1244,-109.28264)">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="336.28265"
+ x="-78.124435"
+ height="48"
+ width="48"
+ id="rect14767"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path14769"
+ d="m -60.624426,339.78264 22.999995,0 0,41 -32.999995,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient14814);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path14771"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient14816);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.56470588"
+ d="m -38.874431,340.78264 c -4.875,0 -21.749995,0 -21.749995,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-8)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path14773"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106-0)"
+ inkscape:connector-curvature="0"
+ transform="translate(-186.12444,-93.717362)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path14775"
+ style="fill:none;stroke:url(#linearGradient14818);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -68.624426,350.03264 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m -70.624426,349.03264 0,31.75 32.999995,0 0,-41 -23.749995,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path14777"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-8)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path14779"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106-0)"
+ inkscape:connector-curvature="0"
+ transform="translate(-186.12444,-93.717362)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path14781"
+ d="m -70.124426,349.28264 0.0108,0.72434 9.9892,-2.72434 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:0.75294118;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m -38.624431,341.28264 0,38.5 -30.499995,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path14783"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.5406242,0,0,0.5829534,-67.987756,347.93806)"
+ inkscape:label="Layer 1"
+ id="g14785">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.54857142;fill:url(#radialGradient14820);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14788"
+ sodipodi:cx="28.019106"
+ sodipodi:cy="38.98439"
+ sodipodi:rx="15.467961"
+ sodipodi:ry="5.3033009"
+ d="m 43.487067,38.98439 a 15.467961,5.3033009 0 1 1 -30.935922,0 15.467961,5.3033009 0 1 1 30.935922,0 z"
+ transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)" />
+ <path
+ style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
+ id="path14790"
+ d="m 16.048489,28.093447 c 0.0098,0.576682 0.196474,1.697902 0.471116,2.577425 0.581566,1.854137 1.56684,3.572658 2.939126,5.086496 1.407488,1.553118 3.138519,2.803227 5.139315,3.68976 2.105357,0.931573 4.384795,1.407488 6.750134,1.403741 2.365339,-0.005 4.644601,-0.488686 6.74896,-1.427017 2.00002,-0.895288 3.731043,-2.148391 5.13754,-3.705517 1.369207,-1.519844 2.352576,-3.241114 2.934089,-5.096258 0.294262,-0.938353 0.476921,-1.889392 0.553238,-2.845308 0.07331,-0.939306 0.04204,-1.883511 -0.09183,-2.823792 -0.259981,-1.835599 -0.896294,-3.556847 -1.872652,-5.12758 -0.895541,-1.441699 -2.047808,-2.70454 -3.417268,-3.766975 0,0 0.002,-0.002 0.002,-0.002 0,0 -13.828458,-10.6197195 -13.828458,-10.6197195 -0.01176,-0.00978 -0.02252,-0.019551 -0.03529,-0.028344 -0.909003,-0.6959264 -3.879837,-0.7738945 -4.87679,-0.075035 -1.01067,0.7057021 -1.091821,1.8092613 -0.195527,2.5482146 1.899775,1.4997633 2.656207,2.2801589 4.566507,3.7797379 0,0 -14.852491,0.167033 -14.852491,0.167033 -1.994685,0 -3.1682609,0.947915 -3.4153947,2.333683 -0.2180771,1.222836 0.7479213,2.738129 2.4800217,2.738129 2.956573,0.0039 5.942111,-0.0069 8.909215,-0.01272 0,0 -16.01999,12.453223 -16.01999,12.453223 -0.020527,0.01564 -0.041053,0.02933 -0.06158,0.04497 -1.4974197,1.148389 -1.9831951,3.059322 -1.0399808,4.268393 0.9598323,1.22959 2.9977653,1.230588 4.5147288,0.006 0,0 8.677593,-7.102098 8.677593,-7.102098 0,0 -0.12511,0.959824 -0.116333,1.535532 l 1e-6,2.6e-5 0,0 0,0 z"
+ sodipodi:nodetypes="csssssssssscccsscccscccssccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient14822);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14792"
+ sodipodi:cx="31.1875"
+ sodipodi:cy="25.75"
+ sodipodi:rx="11.5625"
+ sodipodi:ry="10.125"
+ d="m 42.75,25.75 a 11.5625,10.125 0 1 1 -23.125,0 11.5625,10.125 0 1 1 23.125,0 z"
+ transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)" />
+ <path
+ sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc"
+ id="path14794"
+ d="m 25.8125,6.40625 c -0.334829,4.572e-4 -0.72202,0.089606 -0.90625,0.21875 4.5e-4,0.010412 4.5e-4,0.020838 0,0.03125 -0.212626,0.1484635 -0.188235,0.1956271 -0.1875,0.1875 0.0092,0.010621 -0.0072,-4.246e-4 0.03125,0.03125 0.01962,0.00828 0.03527,0.012546 0.0625,0.03125 0.01676,0.01151 0.01357,0.014555 0.03125,0.03125 0.193748,0.1576058 4.954976,4.005164 4.954976,4.005164 0.489837,0.39864 0.677395,1.066352 0.46875,1.65625 -0.115662,0.32703 -0.422813,0.541217 -0.6875,0.59375 -0.264687,0.05253 -0.498447,0.03054 -0.71875,0.03125 -5.639658,0.05119 -16.87989,0.03851 -16.87989,0.03851 -0.4102,2.75e-4 -0.935835,0.115997 -1.34375,0.34375 -0.407915,0.227753 -0.6637862,0.523861 -0.6875002,0.90625 -0.024417,0.393728 0.098829,0.605767 0.3437502,0.78125 0.244921,0.175483 0.614978,0.25 0.875,0.25 0,0 8.8125,0 8.8125,0 0.600305,-7.28e-4 1.223895,0.311058 1.4375,0.9375 0.04676,0.137121 0.06335,0.269976 0.0625,0.40625 -8.49e-4,0.136274 -0.02214,0.268794 -0.09375,0.375 -0.143211,0.212412 -0.319507,0.298568 -0.5,0.4375 0,0 -15.7871819,12.746851 -15.856336,12.800078 C 5.0310984,30.500117 5,30.53125 5,30.53125 5.0100745,30.519077 5.000335,30.499512 5,30.5 L 4.8125,30.3125 c 0.012336,0.02165 0.014481,0.03307 0.03125,0.0625 0.063558,0.0774 0.125,0.15625 0.125,0.15625 -0.00585,0.0056 -0.031233,0.03124 -0.03125,0.03125 0,0 -0.043442,-0.09921 -0.09375,-0.1875 0.037843,0.09884 0.06253,0.218739 0.0625,0.21875 -0.4662091,0.37119 -0.7783348,0.889746 -0.875,1.28125 -0.1043319,0.422581 -0.046,0.62455 0.125,0.84375 0.2999827,0.384295 1.3975356,0.595547 2.40625,-0.21875 0,0 8.65625,-7.09375 8.65625,-7.09375 0.473718,-0.387074 1.1446,-0.458625 1.6875,-0.15625 0.544608,0.303331 0.798054,0.927572 0.71875,1.53125 0,0 -0.0626,0.908319 -0.0625,1.25 2e-6,0.0085 -1.19e-4,0.02348 0,0.03125 0.192796,2.523718 1.400736,4.762818 3.03125,6.71875 2.801818,3.089095 6.627659,4.401619 10.75,4.5625 4.113324,-0.043 7.964529,-1.606111 10.75,-4.625 2.546631,-3.125326 3.513872,-6.363859 3.15625,-9.375 C 44.891575,22.325847 43.222923,19.516566 40.4375,17.25 35.951885,13.599946 31.206991,10.168434 26.59375,6.625 26.57515,6.610386 26.56455,6.59802 26.5625,6.59375 26.43835,6.498703 26.144223,6.4057899 25.8125,6.40625 z"
+ style="opacity:0.4857143;fill:none;stroke:url(#linearGradient14825);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#3465a4;fill-rule:evenodd;stroke:none"
+ id="path14796"
+ d="m 25.708956,26.064593 c 0.07649,-1.397943 0.759369,-2.631914 1.78592,-3.505519 1.010226,-0.858782 2.366788,-1.383145 3.848625,-1.383145 1.480894,0 2.837456,0.524363 3.847446,1.383145 1.027685,0.873605 1.709741,2.106651 1.787122,3.504594 0.07927,1.438713 -0.49591,2.77459 -1.504012,3.764001 -1.027686,1.007933 -2.493008,1.640678 -4.130556,1.640678 -1.63849,0 -3.103814,-0.632745 -4.131451,-1.640678 -1.00914,-0.989411 -1.58234,-2.325288 -1.503094,-3.763076 l 0,0 0,0 0,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.51999996;fill:url(#radialGradient14827);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.8125,6.03125 c -0.404852,5.53e-4 -2.204797,-0.059029 -2.48145,0.1349032 -0.280209,0.195652 -0.335403,0.376484 -0.34375,0.46875 -0.0083,0.092266 -0.01539,0.17648 0.1875,0.34375 0.01899,0.015735 0.04457,0.014317 0.0625,0.03125 0.124258,0.101028 4.748869,4.1248618 4.748869,4.1248618 0.373658,0.304091 0.504393,0.795817 0.34375,1.25 -0.160635,0.454191 -0.580748,0.373449 -1.0625,0.375 -5.634142,0.05114 -15.087371,-0.129601 -15.087371,-0.129601 -0.952967,6.38e-4 -2.339958,0.524782 -2.4062504,1.59375 -0.063562,1.024947 0.9247974,1.4375 1.5937504,1.4375 0,-1e-6 8.8125,0 8.8125,0 0.488364,-5.92e-4 0.936141,0.225277 1.09375,0.6875 0.157609,0.462231 -0.01926,0.514621 -0.40625,0.8125 0,0 -16.086298,13.088586 -16.086298,13.088586 -0.00142,0.0014 -0.029829,-0.0014 -0.03125,0 -0.064037,0.04879 -0.054226,0.04875 -0.03125,0.03125 -0.5536758,0.424619 -0.9087886,1.004019 -1.03125,1.5 -0.1224536,0.495981 -0.04661,0.856152 0.1875,1.15625 0.4788333,0.613413 1.777612,0.754857 2.90625,-0.15625 1e-7,10e-7 8.65625,-7.09375 8.65625,-7.09375 0.361955,-0.295753 0.872897,-0.352437 1.28125,-0.125 0.408345,0.227436 0.623381,0.692814 0.5625,1.15625 0,-1e-6 -0.0997,0.953636 -0.09375,1.34375 0.09498,1.301756 0.451616,2.521825 0.989039,3.664234 C 20.799917,36.321089 27.770982,19.392853 44.1875,21.03125 43.339652,19.54368 42.151282,18.185293 40.65625,16.96875 36.159865,13.309932 31.42016,9.882897 26.8125,6.34375 26.805335,6.338858 26.788292,6.317553 26.78125,6.3125 26.570707,6.151312 26.216591,6.030689 25.8125,6.03125 z"
+ id="path14798"
+ sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g20347"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18813"
+ width="16"
+ height="16"
+ x="257"
+ y="176" />
+ <g
+ transform="translate(254.01612,148.99638)"
+ id="g10120"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="czc"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 4.4999991,39.491912 c 4.0000009,0 3.4999969,-7 5.9999989,-7 2.500002,0 2.000002,7 5.999999,7"
+ id="path10122"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path10124"
+ d="m 4.4999991,39.491912 c 4.0000009,0 3.4999969,-7 5.9999989,-7 2.500002,0 2.000002,7 5.999999,7"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="czc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g20291"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18821"
+ width="16"
+ height="16"
+ x="341"
+ y="176" />
+ <g
+ transform="translate(258.01612,148.99638)"
+ id="g10158"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 85.500006,38.5 90.478251,33.099997 95.456495,38.5"
+ id="path10160"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path10162"
+ d="M 85.500006,38.5 90.478251,33.099997 95.456495,38.5"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g20301"
+ transform="translate(0,2)">
+ <rect
+ y="176"
+ x="320"
+ height="16"
+ width="16"
+ id="rect18819"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(257.01612,148.99638)"
+ id="g10164"
+ style="display:inline">
+ <path
+ id="path10166"
+ d="M 65.500015,38.5 C 68.5,37 70,35 70.560871,31.5 71,35 72.5,37 75.621727,38.5"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 65.500015,38.5 C 68.5,37 70,35 70.560871,31.5 71,35 72.5,37 75.621727,38.5"
+ id="path10168"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g20337"
+ transform="translate(0,2)">
+ <rect
+ y="176"
+ x="278"
+ height="16"
+ width="16"
+ id="rect18815"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(255.01612,148.99638)"
+ id="g10170"
+ style="display:inline">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path10172"
+ sodipodi:cx="30.5"
+ sodipodi:cy="40"
+ sodipodi:rx="6"
+ sodipodi:ry="6"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
+ sodipodi:start="0"
+ sodipodi:end="3.1415927"
+ sodipodi:open="true"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1,0,0,-1,0,78.5)" />
+ <path
+ transform="matrix(1,0,0,-1,0,78.5)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:open="true"
+ sodipodi:end="3.1415927"
+ sodipodi:start="0"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
+ sodipodi:ry="6"
+ sodipodi:rx="6"
+ sodipodi:cy="40"
+ sodipodi:cx="30.5"
+ id="path10174"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g20311"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18817"
+ width="16"
+ height="16"
+ x="299"
+ y="176" />
+ <g
+ transform="translate(256.01612,148.99638)"
+ id="g10176"
+ style="display:inline">
+ <path
+ sodipodi:open="true"
+ sodipodi:end="3.1415927"
+ sodipodi:start="0"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
+ sodipodi:ry="6"
+ sodipodi:rx="6"
+ sodipodi:cy="40"
+ sodipodi:cx="30.5"
+ id="path10178"
+ style="fill:none;stroke:#000000;stroke-width:2.65631413;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.833333,0,0,-1.333333,25.08333,92.82524)" />
+ <path
+ transform="matrix(0.833333,0,0,-1.333333,25.08333,92.82524)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.32815707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path10181"
+ sodipodi:cx="30.5"
+ sodipodi:cy="40"
+ sodipodi:rx="6"
+ sodipodi:ry="6"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
+ sodipodi:start="0"
+ sodipodi:end="3.1415927"
+ sodipodi:open="true" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g18862"
+ transform="translate(259,151)">
+ <rect
+ y="28"
+ x="103"
+ height="16"
+ width="16"
+ id="rect18823"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01612368,-0.00361762)"
+ id="g10183"
+ style="display:inline">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path10185"
+ d="m 104.5,37.503635 0,-4.000017 12,0 0,4"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#d7d7d7;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 104.5,37.503635 0,-4.000017 12,0 0,4"
+ id="path10187"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g18856"
+ transform="translate(260,151)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18825"
+ width="16"
+ height="16"
+ x="123"
+ y="28" />
+ <g
+ transform="translate(0.01612368,-0.00361762)"
+ id="g10189"
+ style="display:inline">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cssssc"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 124.5,39.491912 c 0.99099,0 0.85013,-1.626312 1.08378,-2.386485 0.35579,-1.15753 1.07105,-1.19962 1.4919,-0.197292 1.2357,2.943014 1.5163,-5.054472 2.42432,-6.416223 1.00014,-1.499896 0.90687,8.170836 3,4 1.95704,-3.899658 1.50039,4.999088 4,5"
+ id="path10191"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10193"
+ d="m 124.5,39.491912 c 0.99099,0 0.85013,-1.626312 1.08378,-2.386485 0.35579,-1.15753 1.07105,-1.19962 1.4919,-0.197292 1.2357,2.943014 1.5163,-5.054472 2.42432,-6.416223 1.00014,-1.499896 0.90687,8.170836 3,4 1.95704,-3.899658 1.50039,4.999088 4,5"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cssssc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g33683"
+ transform="translate(0,2)">
+ <rect
+ y="176"
+ x="446"
+ height="16"
+ width="16"
+ id="rect18831"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(263.91329,149.04559)"
+ id="g11360"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient37097);fill-opacity:1;fill-rule:nonzero;stroke:#11243e;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 190.07108,29.454411 c -3.02619,0 -5.48439,2.463313 -5.48438,5.5 0,3.036688 2.45819,5.500001 5.48438,5.5 3.02619,0 5.48437,-2.46331 5.48437,-5.5 0,-3.036689 -2.45818,-5.500001 -5.48437,-5.5 z m 0,2.98305 c 1.36546,0 2.53849,1.100464 2.53848,2.454803 0,1.354341 -1.17303,2.501413 -2.53848,2.501412 -1.36546,0 -2.47581,-1.14707 -2.47581,-2.501412 0,-1.354341 1.11035,-2.454805 2.47581,-2.454803 z"
+ id="path11362"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="csssccsssc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11364"
+ style="fill:none;stroke:url(#linearGradient15782);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.566689,0,0,-0.562497,115.2063,101.3747)" />
+ <path
+ transform="matrix(0.4330916,0,0,-0.424074,132.95389,85.01929)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33681);stroke-width:2.33340454;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11366"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g33690"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18829"
+ width="16"
+ height="16"
+ x="425"
+ y="176" />
+ <g
+ transform="translate(263,148.99995)"
+ id="g11368"
+ style="display:inline">
+ <g
+ id="g11370"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.786268,0,0,0.7877987,82.392071,-41.848894)">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37095);fill-opacity:1;fill-rule:nonzero;stroke:#11243e;stroke-width:1.16319752;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path11372"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.874026,0,0,0.873701,-3.948211,-5.552958)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11374"
+ style="fill:none;stroke:url(#linearGradient33700);stroke-width:3.20095801;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.398744,0,0,-0.395524,58.82401,144.1804)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11376"
+ style="fill:none;stroke:url(#linearGradient33666);stroke-width:5.31599474;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.186538,0,0,-0.189699,145.3693,57.36304)" />
+ <path
+ transform="matrix(0.566689,0,0,-0.562497,95.23056,101.3747)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33668);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11378"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.424906,0,0,-0.424074,114.01316,85.183325)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33670);stroke-width:2.35577321;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11380"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g12431"
+ transform="translate(0,128)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17412"
+ width="16.000002"
+ height="16"
+ x="5"
+ y="302" />
+ <g
+ transform="translate(-316.99999,374)"
+ id="g19609"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path17384"
+ style="fill:none;stroke:#2c1700;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 330.02726,-62.5 4.63639,3 m -4.63639,-3 -4.63634,3 m 4.60909,-3 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#2c1700;stroke-width:1.80000007;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 329,-70 0,2 1.99999,0 0,-2 L 329,-70 z m -5,10 10e-6,2 2,0 -10e-6,-2 -2,0 z m 9.99999,0 0,2 2,0 0,-2 -2,0 z"
+ id="path17386"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.0911926,0,0,1.176776,253.08415,-79.548088)"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path17388"
+ style="fill:url(#radialGradient12427);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ d="m 330.02726,-62.5 4.63639,3"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffddb9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17390"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 330.02724,-62.5 4.63639,3 m -4.63639,-3 -4.63634,3 m 4.60909,-3 0,-6"
+ style="opacity:0.8;fill:none;stroke:url(#radialGradient12429);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17392"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ id="path17394"
+ d="m 333.99999,-60 0,2 2,0 0,-2 -2,0 z"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path17396"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#be6200;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 330.02726,-62.5 -4.63634,3"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path17398"
+ style="fill:none;stroke:#ff921d;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 330.00001,-62.5 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 329,-70 0,2 1.99999,0 0,-2 L 329,-70 z"
+ id="path17400"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e07400;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 324.00001,-60 0,2 1.99999,0 0,-2 -1.99999,0 z"
+ id="path17402"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-63.75"
+ x="328.25"
+ height="3.5"
+ width="3.5000002"
+ id="rect17404"
+ style="opacity:0.05;fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path17406"
+ d="m 324.49999,-58.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1.00000083px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#ffe680;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000107px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 329.49999,-68.5 0,-0.967392 0.99998,0"
+ id="path17408"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path17410"
+ d="m 334.5,-58.499999 0,-1 1,0"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000107px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 334,-60.5 -3,-1.870665"
+ id="path17415"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#784e21;stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333.5,-59.499999 0,-1 1,0"
+ id="path17417"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path17419"
+ d="m 329.49999,-67.5 1,0"
+ style="opacity:0.4;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#8c5b27;stroke-width:1.00000107px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path17421"
+ d="m 326.49995,-59.500011 0,-1 -1,0"
+ style="opacity:0.4;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#8c5b27;stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.27999998;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 326,-60.5 3,-1.870665"
+ id="path17423"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17425"
+ d="m 329.5,-67.5 0,4"
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-63"
+ x="329.06403"
+ height="2"
+ width="2"
+ id="rect17427"
+ style="fill:#fff1d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g24997"
+ transform="translate(0,128)">
+ <rect
+ ry="0"
+ rx="0"
+ y="302"
+ x="47"
+ height="16"
+ width="16"
+ id="rect17065"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24983">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="313.5"
+ x="49.5"
+ height="3"
+ width="2.9998772"
+ id="rect17067"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17069"
+ width="2.9998772"
+ height="3"
+ x="52.500122"
+ y="303.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path17071"
+ d="m 51,315 c 4.5365,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#2b1600;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffad55;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 51,315 c 4.49647,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path17073"
+ sodipodi:nodetypes="csc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path17075"
+ d="m 51,315 c 4.49647,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:url(#linearGradient24436);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path17077"
+ d="m 51.999878,314 c -0.67541,0 -1.35081,10e-6 -2.02623,10e-6 0,0.66939 0,1.33877 0,2.00817 0.67542,0 1.35082,-10e-6 2.02623,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffad55;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 55,304 c -0.65334,0 -1.30668,10e-6 -1.96003,10e-6 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-10e-6 1.96003,-10e-6 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path17081"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 53.5,305.5 0,-1 1,0"
+ id="path17083"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17085"
+ d="m 50.473648,315.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path17087"
+ d="m 53,315.66293 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.55431 0,-1.1086 0,-1.66292 0.32001,0 0.64002,10e-6 0.96003,10e-6 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.25;fill:#783e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path17089"
+ d="m 56,306.51208 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.63982 0,-1.27964 0,-1.91948 0.32001,0 0.64002,1e-5 0.96003,1e-5 0,0.63983 0,1.27966 0,1.91948 z"
+ style="opacity:0.15;fill:#783e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#783e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 53,316 c -0.32001,0 -0.64002,0 -0.96003,0 0,-0.21055 0,-0.42107 0,-0.63162 0.32001,0 0.64002,0 0.96003,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path17091"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g10687"
+ transform="translate(0,128)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17348"
+ width="16"
+ height="16"
+ x="47"
+ y="281"
+ rx="0"
+ ry="0" />
+ <g
+ id="g10677">
+ <g
+ id="g18285"
+ style="opacity:0.7;display:inline"
+ transform="translate(-290.00001,409.99343)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path18233"
+ d="m 341.00001,-115.99343 c 4.5365,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 341.00001,-115.99343 c 4.49647,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path18235"
+ sodipodi:nodetypes="csc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g17345"
+ transform="translate(-189.02763,408)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-115.5"
+ x="238.52776"
+ height="3"
+ width="2.9998772"
+ id="rect17355"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path17358"
+ d="m 241.02763,-115 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17360"
+ width="2.9998772"
+ height="3"
+ x="241.52776"
+ y="-125.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 244.02763,-125 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-1e-5 1.96003,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path17362"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g21376"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21362"
+ width="16"
+ height="16"
+ x="131"
+ y="71" />
+ <g
+ transform="translate(-71,-61)"
+ id="g9875"
+ style="display:inline">
+ <g
+ id="g9889"
+ transform="translate(0,1.00001)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path9891"
+ d="m 210,135.5 6.5,0 0,11 -9,0 0,-8.5 2.5,-2.5 z"
+ style="fill:url(#linearGradient21370);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient21372);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ sodipodi:nodetypes="ccc"
+ id="path9893"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path9895"
+ d="m 207,138.99999 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 207.5,138 0,8.5 9,0 0,-11 -6.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path9897"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path9899"
+ style="fill:none;stroke:url(#linearGradient21374);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 208.5,139.49999 0,6.00001 m 3,-9.00001 4,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g9877"
+ transform="translate(-4,-3)"
+ style="opacity:0.4">
+ <path
+ style="fill:url(#linearGradient21364);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient21366);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ d="m 210,135.5 6.5,0 0,11 -9,0 0,-8.5 2.5,-2.5 z"
+ id="path9879"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path9881"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 207,138.99999 4,0 0,-4 -4,4 z"
+ id="path9883"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path9885"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 207.5,138 0,8.5 9,0 0,-11 -6.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 208.5,139.49999 0,6.00001 m 3,-9.00001 4,0"
+ style="fill:none;stroke:url(#linearGradient21368);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path9887"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g10203"
+ transform="translate(-211.20006,170)" />
+ <g
+ id="g21567"
+ transform="translate(-0.9687515,1.9789998)">
+ <g
+ transform="matrix(1.0019536,0,0,1,-173.76637,169.95095)"
+ id="g10199"
+ style="stroke:none">
+ <rect
+ y="6.0700502"
+ x="325.10001"
+ height="15.979"
+ width="16.000004"
+ id="rect10201"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="g21550">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10205"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667691;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.5769158,0,0,0.5769218,86.73182,118.78861)" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.769221,0,0,0.769229,59.2704,9.1909)"
+ id="g10207"
+ style="display:inline">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10209"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10211"
+ style="opacity:0.4;fill:url(#linearGradient21641);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="g10213"
+ transform="translate(-215.99994,222.97281)"
+ style="display:inline">
+ <rect
+ style="opacity:0.1;fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10215"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.495766"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="40.991806"
+ x="372.99994"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect10217"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10219"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.49577"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ <g
+ style="display:inline"
+ id="g10221"
+ transform="matrix(0.769221,0,0,0.769229,64.0398,14.9217)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10224"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.91227174;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7125226,0,0,0.7125021,34.447023,139.42475)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient21643);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10226"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="display:inline"
+ transform="translate(-211.00001,228.97281)"
+ id="g10228">
+ <rect
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="-43.495766"
+ x="372.49994"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect10230"
+ style="opacity:0.1;fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect10232"
+ width="2.0000861"
+ height="2.0000756"
+ x="372.99994"
+ y="40.991806"
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)" />
+ <rect
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="-43.49577"
+ x="372.49994"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect10234"
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g21647"
+ transform="translate(-1,1.9790001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21645"
+ width="16"
+ height="16"
+ x="173"
+ y="176" />
+ <g
+ transform="translate(-209.00002,169.98079)"
+ id="g10236"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.769221,0,0,0.769229,289.2704,-160.7881)"
+ id="g10238"
+ style="display:inline">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10240"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10242"
+ style="opacity:0.4;fill:url(#linearGradient15590);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ style="display:inline"
+ id="g10244"
+ transform="matrix(0.769221,0,0,0.769229,294.0398,-155.0573)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10246"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient15592);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10248"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="g10250"
+ transform="translate(16.000061,55.993807)"
+ style="display:inline">
+ <rect
+ style="opacity:0.25;fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10252"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.495766"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="40.991806"
+ x="372.99994"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect10254"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10256"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.49577"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g21623"
+ transform="translate(-0.9999786,1.9982099)">
+ <g
+ transform="matrix(0.9999986,0,0,1,-170.19957,169.98079)"
+ id="g10260">
+ <g
+ transform="translate(39.10005,-0.04905017)"
+ id="g10262">
+ <rect
+ y="6.0700502"
+ x="325.10001"
+ height="15.979"
+ width="16.000025"
+ id="rect10264"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="g10266" />
+ </g>
+ <g
+ id="g21602">
+ <path
+ transform="matrix(0.5769158,0,0,0.5769218,128.71244,118.78864)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667691;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path10268"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ style="opacity:0.45;display:inline"
+ id="g10270"
+ transform="matrix(0.769221,0,0,0.769229,101.2704,9.19269)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10272"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.38667703;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient15594);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10275"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.769221,0,0,0.769229,106.0398,14.92349)"
+ id="g10277"
+ style="display:inline">
+ <path
+ transform="matrix(0.7119136,0,0,0.7119136,34.527408,139.4942)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.91303903;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path10279"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.28576)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10281"
+ style="opacity:0.4;fill:url(#linearGradient15596);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="179.47975"
+ x="198.49991"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect10283"
+ style="opacity:0.05;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#6a6a6a;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline" />
+ <rect
+ style="opacity:0.1;fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10285"
+ width="3.0000761"
+ height="2.9999874"
+ x="203.49991"
+ y="185.47972"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="-187.9819"
+ x="203.99991"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect10287"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#0055d4;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect10289"
+ width="3.0000761"
+ height="2.9999874"
+ x="203.49991"
+ y="185.47972"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ </g>
+ <g
+ id="g21519"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect10293"
+ width="16"
+ height="16"
+ x="131"
+ y="176" />
+ <g
+ transform="translate(0.8812553,-0.8570429)"
+ id="g21511">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 142.1,184.4 2.5,0 m -9.5,0 -2.5,0 m 6,-3.5 0,-2.5 m 0,9.5 0,2.5"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path10295"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 141.08637,118 a 9.0863705,9.0860729 0 1 1 -18.17274,0 9.0863705,9.0860729 0 1 1 18.17274,0 z"
+ sodipodi:ry="9.0860729"
+ sodipodi:rx="9.0863705"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10297"
+ style="fill:none;stroke:#000000;stroke-width:8.3510685;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.383132,0,0,0.383237,88.0266,139.17807)" />
+ <path
+ id="path10299"
+ style="fill:none;stroke:url(#radialGradient21517);stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 142.1,184.4 2.5,0 m -9.5,0 -2.5,0 m 6,-3.5 0,-2.5 m 0,9.5 0,2.5"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.383132,0,0,0.383237,88.0266,139.17807)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#ffffff;stroke-width:4.69747591;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10301"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="9.0863705"
+ sodipodi:ry="9.0860729"
+ d="m 141.08637,118 a 9.0863705,9.0860729 0 1 1 -18.17274,0 9.0863705,9.0860729 0 1 1 18.17274,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g21663"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21661"
+ width="16"
+ height="16"
+ x="215"
+ y="176" />
+ <g
+ transform="translate(-87.98837,-19.85)"
+ id="g21392"
+ style="display:inline">
+ <g
+ id="g11189"
+ style="opacity:0.05"
+ transform="translate(-62.011627,236.84995)">
+ <rect
+ style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11191"
+ width="2.9998775"
+ height="3"
+ x="366.5"
+ y="-39.5"
+ ry="1.375"
+ rx="1.375" />
+ <rect
+ ry="1.375"
+ y="-39.5"
+ x="371.5"
+ height="3"
+ width="2.9998775"
+ id="rect11193"
+ style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.375" />
+ <rect
+ style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11195"
+ width="2.9998775"
+ height="3"
+ x="376.5"
+ y="-39.5"
+ ry="1.375"
+ rx="1.375" />
+ </g>
+ <rect
+ style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11197"
+ width="2.9998775"
+ height="3"
+ x="304.48837"
+ y="197.34995"
+ ry="1.375"
+ rx="1.375" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path11199"
+ d="m 304.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1.375"
+ y="197.34995"
+ x="309.48837"
+ height="3"
+ width="2.9998775"
+ id="rect11201"
+ style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.375" />
+ <path
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 309.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path11203"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11205"
+ width="2.9998775"
+ height="3"
+ x="314.48837"
+ y="197.34995"
+ ry="1.375"
+ rx="1.375" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path11207"
+ d="m 314.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11724"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22465"
+ width="16"
+ height="16"
+ x="425"
+ y="113" />
+ <g
+ id="g14791"
+ transform="translate(-38,43.987183)"
+ style="display:inline">
+ <rect
+ style="fill:#f09432;fill-opacity:1;fill-rule:nonzero;stroke:#462400;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14793"
+ width="4.0018005"
+ height="3.9871812"
+ x="468.5"
+ y="74.512817"
+ rx="1.4768832"
+ ry="1.4768832" />
+ <rect
+ y="75.5"
+ x="469.5018"
+ height="2.012816"
+ width="1.9981995"
+ id="rect14795"
+ style="fill:none;stroke:url(#linearGradient14841);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.49075836"
+ rx="0.49075836" />
+ </g>
+ </g>
+ <g
+ id="g11718"
+ transform="translate(0,2)">
+ <rect
+ y="113"
+ x="404"
+ height="16"
+ width="16"
+ id="rect22463"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g14927"
+ transform="translate(-39,43.987183)"
+ style="opacity:0.9;display:inline">
+ <rect
+ ry="1.5045315"
+ rx="1.5045315"
+ y="74.512817"
+ x="448.5"
+ height="3.9871812"
+ width="4.0018005"
+ id="rect14929"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient14935);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:6.18177886;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14931"
+ width="1.9981995"
+ height="2.012816"
+ x="449.5018"
+ y="75.5"
+ rx="0.5299269"
+ ry="0.5299269" />
+ </g>
+ </g>
+ <g
+ id="g11764"
+ transform="translate(0,2)">
+ <rect
+ y="113"
+ x="341"
+ height="16"
+ width="16"
+ id="rect22331"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-81,-103)"
+ id="g22313"
+ style="display:inline">
+ <g
+ id="g22243">
+ <g
+ transform="translate(-0.9546587,1e-5)"
+ id="g18888"
+ style="opacity:0.85">
+ <path
+ sodipodi:nodetypes="cssc"
+ d="m 430.45466,223.24999 c -2.76033,0 -5,1.88345 -5,3.25 0,1.5 2.5,3 5.5,3 0.15891,0 4,0.25 6,-2.5"
+ style="fill:none;stroke:url(#linearGradient18896);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18757"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18762"
+ style="fill:none;stroke:url(#linearGradient18898);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 434.20466,226.49999 3.25115,2e-5 -10e-4,2.99998"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 433.25,226.5 3.25,0 0,2.99999"
+ style="fill:none;stroke:url(#linearGradient18904);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18764"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18766"
+ style="fill:none;stroke:url(#linearGradient18901);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 429.5,223.25 c -2.76033,0 -5,1.88345 -5,3.25 0,1.5 2.5,3 5.5,3 0,0 4,0.25 6,-2.5"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(278.02661,459.99999)"
+ id="g18768">
+ <path
+ id="path18770"
+ d="m 151,-240.5 c -2.48519,0 -4.49999,0.89481 -4.5,2 l 0,1 c 0,1.10519 2.0148,2 4.5,2 2.48519,0 4.5,-0.8948 4.5,-2 l 0,-1 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ style="fill:url(#linearGradient18843);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.68242937;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient18845);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151.00029,-243.51106 c -1.9309,0 -3.5,0.66961 -3.5,1.5 L 147.5,-240 c 0,0.83039 1.5691,1.5 3.5,1.5 1.9309,0 3.5,-0.66961 3.5,-1.5 l 2.9e-4,-2.01106 c 0,-0.83039 -1.5691,-1.5 -3.5,-1.5 z"
+ id="path18779"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18848);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148.5,-241.75 0,2.70352 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875 l 0,-2.70352"
+ id="path18787"
+ sodipodi:nodetypes="ccssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient18850);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18789"
+ sodipodi:cx="108"
+ sodipodi:cy="-222"
+ sodipodi:rx="3.3084693"
+ sodipodi:ry="1.2798798"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
+ transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" />
+ <path
+ sodipodi:nodetypes="cssss"
+ id="path18791"
+ d="m 154.5,-239 c 0,0.18405 -0.0775,0.36038 -0.21919,0.52335 -0.49587,0.57019 -1.77826,0.97665 -3.28081,0.97665 -1.48659,0 -2.75767,-0.39787 -3.26474,-0.95854 C 147.58334,-238.62651 147.5,-238.80911 147.5,-239"
+ style="fill:none;stroke:url(#linearGradient18852);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18798"
+ d="m 151,-243.5 c -1.9309,1e-5 -3.52661,0.41962 -3.52661,1.25001 L 147.5,-239.75 c -0.61542,0.34205 -1,0.77768 -1,1.25 l -0.0266,1.25001 c 0,1.10519 2.04141,1.74999 4.52661,1.74999 2.48519,0 4.47339,-0.64479 4.47339,-1.74999 L 155.5,-238.5 c 0,-0.47232 -0.38458,-0.90795 -1,-1.25 l -0.0266,-2.49999 c 0,-0.83038 -1.54249,-1.25001 -3.47339,-1.25001 l -1e-5,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path18800"
+ d="m 148.5,-239.04648 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875"
+ style="fill:none;stroke:#0066ff;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g11730"
+ transform="translate(0,2)">
+ <rect
+ y="113"
+ x="383"
+ height="16"
+ width="16"
+ id="rect22455"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-79,-103)"
+ id="g22283"
+ style="display:inline">
+ <g
+ transform="translate(318.02661,459.99999)"
+ id="g17510">
+ <path
+ id="path17512"
+ d="m 151,-240.5 c -2.48519,0 -4.49999,0.89481 -4.5,2 l 0,1 c 0,1.10519 2.0148,2 4.5,2 2.48519,0 4.5,-0.8948 4.5,-2 l 0,-1 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ style="fill:url(#linearGradient17527);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.68242937;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient17529);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151.00029,-243.51106 c -1.9309,0 -3.5,0.66961 -3.5,1.5 L 147.5,-240 c 0,0.83039 1.5691,1.5 3.5,1.5 1.9309,0 3.5,-0.66961 3.5,-1.5 l 2.9e-4,-2.01106 c 0,-0.83039 -1.5691,-1.5 -3.5,-1.5 z"
+ id="path17514"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17531);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148.5,-241.75 0,2.70352 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875 l 0,-2.70352"
+ id="path17516"
+ sodipodi:nodetypes="ccssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient17533);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17518"
+ sodipodi:cx="108"
+ sodipodi:cy="-222"
+ sodipodi:rx="3.3084693"
+ sodipodi:ry="1.2798798"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
+ transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" />
+ <path
+ sodipodi:nodetypes="cssss"
+ id="path17520"
+ d="m 154.5,-239 c 0,0.18405 -0.0775,0.36038 -0.21919,0.52335 -0.49587,0.57019 -1.77826,0.97665 -3.28081,0.97665 -1.48659,0 -2.75767,-0.39787 -3.26474,-0.95854 C 147.58334,-238.62651 147.5,-238.80911 147.5,-239"
+ style="fill:none;stroke:url(#linearGradient17535);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17522"
+ d="m 151,-243.5 c -1.9309,1e-5 -3.52661,0.41962 -3.52661,1.25001 L 147.5,-239.75 c -0.61542,0.34205 -1,0.77768 -1,1.25 l -0.0266,1.25001 c 0,1.10519 2.04141,1.74999 4.52661,1.74999 2.48519,0 4.47339,-0.64479 4.47339,-1.74999 L 155.5,-238.5 c 0,-0.47232 -0.38458,-0.90795 -1,-1.25 l -0.0266,-2.49999 c 0,-0.83038 -1.54249,-1.25001 -3.47339,-1.25001 l -1e-5,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path17524"
+ d="m 148.5,-239.04648 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875"
+ style="fill:none;stroke:#0066ff;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g22254">
+ <g
+ transform="translate(20.029029,0)"
+ style="opacity:0.85"
+ id="g17822">
+ <path
+ d="m 446.75,226.25 -2.25,2.25 2.25,2.25 m 7.5,-4.5 2.25,2.25 -2.25,2.25"
+ style="fill:none;stroke:url(#linearGradient17817);stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17811"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17809"
+ d="m 444.54256,228.5 11.66489,0 0,0"
+ style="fill:none;stroke:url(#linearGradient17819);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(20.029029,0)"
+ id="g17801">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 444.54256,228.5 11.95744,0"
+ id="path17024"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path17796"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 446.75,226.25 -2.25,2.25 2.25,2.25 m 7.5,-4.5 2.25,2.25 -2.25,2.25"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g11749"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22453"
+ width="16"
+ height="16"
+ x="362"
+ y="113" />
+ <g
+ transform="translate(-81,-103)"
+ id="g22300"
+ style="display:inline">
+ <g
+ id="g17482"
+ transform="translate(298.02661,466.04648)">
+ <path
+ style="fill:url(#linearGradient17498);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.68242937;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151,-240.5 c -2.48519,0 -4.49999,0.89481 -4.5,2 l 0,1 c 0,1.10519 2.0148,2 4.5,2 2.48519,0 4.5,-0.8948 4.5,-2 l 0,-1 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ id="path17484"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path17486"
+ d="m 151.00029,-243.51106 c -1.9309,0 -3.5,0.66961 -3.5,1.5 L 147.5,-240 c 0,0.83039 1.5691,1.5 3.5,1.5 1.9309,0 3.5,-0.66961 3.5,-1.5 l 2.9e-4,-2.01106 c 0,-0.83039 -1.5691,-1.5 -3.5,-1.5 z"
+ style="fill:url(#linearGradient17500);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccssscc"
+ id="path17488"
+ d="m 148.5,-241.75 0,2.70352 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875 l 0,-2.70352"
+ style="fill:none;stroke:url(#linearGradient17502);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
+ sodipodi:ry="1.2798798"
+ sodipodi:rx="3.3084693"
+ sodipodi:cy="-222"
+ sodipodi:cx="108"
+ id="path17490"
+ style="fill:url(#linearGradient17504);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17506);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 154.5,-239 c 0,0.18405 -0.0775,0.36038 -0.21919,0.52335 -0.49587,0.57019 -1.77826,0.97665 -3.28081,0.97665 -1.48659,0 -2.75767,-0.39787 -3.26474,-0.95854 C 147.58334,-238.62651 147.5,-238.80911 147.5,-239"
+ id="path17492"
+ sodipodi:nodetypes="cssss"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccsccccc"
+ style="fill:none;stroke:#000000;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151,-243.5 c -1.9309,1e-5 -3.52661,0.41962 -3.52661,1.25001 L 147.5,-239.75 c -0.61542,0.34205 -1,0.77768 -1,1.25 l -0.0266,1.25001 c 0,1.10519 2.04141,1.74999 4.52661,1.74999 2.48519,0 4.47339,-0.64479 4.47339,-1.74999 L 155.5,-238.5 c 0,-0.47232 -0.38458,-0.90795 -1,-1.25 l -0.0266,-2.49999 c 0,-0.83038 -1.54249,-1.25001 -3.47339,-1.25001 l -1e-5,0 z"
+ id="path17494"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0066ff;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 148.5,-239.04648 c 0.0622,0.056 0.19266,0.12733 0.40625,0.21875 0.46667,0.19974 1.2423,0.32773 2.09375,0.32773 0.85145,0 1.62708,-0.12799 2.09375,-0.32773 0.21359,-0.0914 0.34401,-0.16271 0.40625,-0.21875"
+ id="path17496"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g22250">
+ <path
+ style="opacity:0.85;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 456.5,218.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ id="path17828"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17826"
+ d="m 456.5,218.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ style="fill:url(#linearGradient18213);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g23801"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22457"
+ width="16"
+ height="16"
+ x="320"
+ y="113" />
+ <g
+ mask="url(#mask18666)"
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g18026"
+ transform="matrix(0.927273,0,0,1,260.65455,106)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 70.499967,14.5 4.284298,2.5 m -4.284298,-2.5 -4.34315,2.5 m 4.313724,-2.5 0,-4.5"
+ style="fill:none;stroke:#000000;stroke-width:3.42696857;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path18028"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18030"
+ d="m 69.39211,8 0,2 2.156862,0 0,-2 -2.156862,0 z m -4.313742,8 1.8e-5,2 2.156862,0 -1.8e-5,-2 -2.156862,0 z m 8.627466,0 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.55771327;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient23738);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path18032"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.176776,0,0,1.176776,-12.47787,-2.548088)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ id="path18035"
+ style="fill:none;stroke:#91ae42;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.470541,14.5 74.784265,17"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#91ae42;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 73.705834,16 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path18037"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18039"
+ d="m 69.39211,8 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#4989e9;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18041"
+ d="m 65.078405,16 0,2 2.156844,0 0,-2 -2.156844,0 z"
+ style="fill:#ef6529;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 70.470541,14.5 66.156817,17"
+ style="fill:none;stroke:#ef6529;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path18043"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 70.470541,14.5 0,-4.5"
+ style="fill:none;stroke:#4989e9;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path18045"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.699335,0,0,0.602252,21.19685,5.767346)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path18047"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1.03847623px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 65.617602,17.5 0,-1 1.078431,0"
+ id="path18049"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path18051"
+ d="m 69.93132,9.5 0,-0.9673924 1.078413,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1.03847599px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 74.24505,17.500004 0,-1 1.078431,0"
+ id="path18053"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-162,-102)"
+ id="g18124">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.70588235;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 495.5,226 c 0,0 0,-1.75 0,-1.75 0,-0.96333 -0.75,-1.75 -2,-1.75 -1.25,0 -2,0.78667 -2,1.75 l 0,1.75"
+ id="path18055"
+ sodipodi:nodetypes="csccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="225.48849"
+ x="489.5"
+ height="5.0114956"
+ width="7.9999995"
+ id="rect18057"
+ style="fill:url(#linearGradient23750);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.70588235;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csccc"
+ id="path18059"
+ d="m 495.5,226 c 0,0 0,-1.75 0,-1.75 0,-0.96333 -0.75,-1.75 -2,-1.75 -1.25,0 -2,0.78667 -2,1.75 l 0,1.75"
+ style="fill:none;stroke:url(#linearGradient23752);stroke-width:1.39999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient23754);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect18061"
+ width="6.0312495"
+ height="3.0344827"
+ x="490.5"
+ y="226.5"
+ rx="0"
+ ry="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15876"
+ width="16"
+ height="16"
+ x="110"
+ y="409"
+ ry="0" />
+ <g
+ id="g20862"
+ transform="translate(168,65.000007)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20632"
+ width="16"
+ height="16"
+ x="68"
+ y="428" />
+ <g
+ style="display:inline"
+ transform="translate(-15.161301,338)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g10762">
+ <path
+ d="m 86.5,100.53983 4.342131,0.008 c 5.188235,0.0101 5.335295,-2.04831 3.335293,-4.04831 -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path10764"
+ sodipodi:nodetypes="czszcccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czszcccc"
+ id="path10766"
+ style="fill:none;stroke:url(#linearGradient13991);stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="m 86.5,100.53983 4.342131,0.008 C 96.03037,100.55844 96.17743,98.5 94.177424,96.5 c -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g10534"
+ transform="translate(0,128.00001)">
+ <rect
+ y="428"
+ x="193.9839"
+ height="16"
+ width="16"
+ id="rect20642"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-29.016109,339.00751)"
+ id="g20606">
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10953">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.25,-1.53125 -1,-1 -1.53125,1.25 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ id="path10955"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ id="path10957"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.5,-1.78125 -1,-1 -1.78125,1.5 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ style="fill:url(#linearGradient20796);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 434.9998,198.49249 -1.5,1.25 m -2,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.01806,0.29269 -1.5172,0.50569 m -1.49,1.50752 c -0.20864,0.49552 -0.41426,1.14284 -0.4928,1.48679 l -1.5,0 0,1 m 1.5,-5 -0.5,0.5 m 1.25,6.5 -1.25,1.5 m 6.5,-5.5 0,3.5 -3.5,0 m -3,-6 0.5,-0.5 1.5,1.25"
+ style="fill:none;stroke:#f9f9f9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ id="path10959"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10961">
+ <rect
+ ry="0"
+ rx="0"
+ y="202.46629"
+ x="430.49979"
+ height="8.1236582"
+ width="7.0000763"
+ id="rect10963"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ d="m 432.53795,204.5065 2.96201,0 m -2.96201,1.993 2.96201,0 m -2.96201,1.993 2.96201,0"
+ style="fill:none;stroke:#000000;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path10965"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="202.48912"
+ x="430.49661"
+ height="8.0067444"
+ width="7.0067482"
+ id="rect10967"
+ style="fill:none;stroke:url(#linearGradient20798);stroke-width:0.99325603;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g10512"
+ transform="translate(0,128.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20640"
+ width="16"
+ height="16"
+ x="173"
+ y="428" />
+ <g
+ transform="translate(-29.98389,338.00045)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g11077"
+ style="display:inline">
+ <g
+ id="g11079"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.965527,0,0,0.993394,8.273839,0.460629)">
+ <g
+ id="g11081"
+ transform="matrix(1.086383,0,0,1.082072,-19.43307,-7.852041)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.833341,0,0,0.829252,85.1747,-87.30584)"
+ id="g11083" />
+ <g
+ style="stroke:#000000;stroke-width:1.13287878;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="g11085"
+ transform="matrix(0.833341,0,0,0.829252,85.1747,-87.30584)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23208"
+ style="fill:#dad727;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.92361271;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.929498,0,0,0.910458,28.4835,116.0319)" />
+ <path
+ transform="matrix(0.8580178,0,0,0.8424365,37.918882,124.05843)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient23215);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.92361271;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23213"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 210.20333,98.981214 0,-1.914298 1.90698,0 0,1.914298 -1.90698,0 z"
+ id="path11089"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g11091">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ inkscape:transform-center-y="-3.3687892"
+ id="path11093"
+ d="m 208.05857,93.345302 2.18641,2.891627 c 0.50125,-0.147037 1.16637,-0.122617 1.82389,-0.02056 l 2.18648,-2.87107 c -1.9067,-1.162873 -4.29008,-1.162873 -6.19678,0 l 0,3e-6 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ inkscape:transform-center-y="2.4548853"
+ id="path11095"
+ d="m 208.53524,102.88086 1.43003,-3.336509 c -0.67737,-0.380664 -0.53518,-1.067385 -0.59136,-1.547136 l -3.93706,-4.21e-4 c 0,2.093176 1.43003,4.186346 3.09839,4.884066 l 0,0 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="3.3187399"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:transform-center-x="-3.318739"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 213.77867,102.88086 -1.43002,-3.336509 c 0.67738,-0.380664 0.53486,-1.067385 0.59105,-1.547136 l 3.93736,-4.21e-4 c 0,2.325746 -1.43003,4.186346 -3.09839,4.884066 z"
+ id="path11097"
+ inkscape:transform-center-y="2.4548853"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <path
+ d="m 139.7074,118 a 7.7074003,7.7241406 0 1 1 -15.4148,0 7.7074003,7.7241406 0 1 1 15.4148,0 z"
+ sodipodi:ry="7.7241406"
+ sodipodi:rx="7.7074003"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11099"
+ style="fill:none;stroke:url(#linearGradient13520);stroke-width:1.40287328;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.713599,0,0,0.712048,116.8049,13.97832)" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(-160.2001,83.979)"
+ id="g11101">
+ <g
+ transform="translate(39.10005,-0.04905017)"
+ id="g11103" />
+ <g
+ id="g11105" />
+ </g>
+ <g
+ id="g11107"
+ style="opacity:0.3;display:inline"
+ transform="matrix(1.0489321,0,0,1.0749238,-10.489315,-7.3395414)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ inkscape:transform-center-y="-3.3687892"
+ id="path11109"
+ d="m 208.05857,93.345302 2.18641,2.891627 c 0.50125,-0.147037 1.16637,-0.122617 1.82389,-0.02056 l 2.18648,-2.87107 c -1.9067,-1.162873 -4.29008,-1.162873 -6.19678,0 l 0,3e-6 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ inkscape:transform-center-y="2.4548853"
+ id="path11111"
+ d="m 208.53524,102.88086 1.43003,-3.336509 c -0.67737,-0.380664 -0.53518,-1.067385 -0.59136,-1.547136 l -3.93706,-4.21e-4 c 0,2.093176 1.43003,4.186346 3.09839,4.884066 l 0,0 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:transform-center-x="3.3187399"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21197"
+ transform="translate(20,319.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21195"
+ width="16"
+ height="16"
+ x="363"
+ y="174" />
+ <g
+ transform="matrix(0.68898,0.688545,-0.68898,0.688545,503.65632,-65.53941)"
+ id="g11065"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccczcczccccscsccscscc"
+ id="path11067"
+ d="m 85.658035,278.19867 c 1.5,0 2.00279,1.00232 2.00279,2.00232 l 1.14e-4,0.36297 c 0,0.75 -0.916764,1.9289 -1.666764,1.9289 -0.75,0 -0.858674,0.24559 -2.129469,-1.0252 -0.5,0 -0.22594,-2.3e-4 -0.72594,-2.3e-4 -1.269993,1.26999 -1.394591,1.02543 -2.144591,1.02543 -0.75,0 -1.681542,-1.18154 -1.681542,-1.93154 l -1.15e-4,-0.36297 c 0,-1 0.489879,-2.00105 1.989879,-2.00105 l -0.01948,-5.74221 c -1.5,0 -1.97318,-1.05691 -1.973496,-2.05693 l -1.14e-4,-0.36297 c 0,-0.75 0.855204,-1.89751 1.666764,-1.9289 0.71584,-0.0277 0.873337,-0.24811 2.144133,1.02268 l 0.725939,2.3e-4 c 1.088566,-1.08856 1.396658,-1.02291 2.129928,-1.02291 0.75,0 1.681542,1.18154 1.681542,1.93154 l 1.15e-4,0.36297 c 1.58e-4,0.5 -0.519172,2.05566 -2.019172,2.05566 l 0.01948,5.74221 -10e-7,0 0,0 0,0 z"
+ style="fill:url(#linearGradient15748);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.821307;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 82.032098,271.66942 0.0023,7.25939"
+ id="path11069"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1.02663434px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 85.299056,272.39639 -1,0"
+ id="path11071"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path11073"
+ d="m 85.310309,278.21333 -1,0"
+ style="fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 82.397361,278.92893 c -2.4948,-0.75001 -2.539872,2.90296 -0.906565,2.72199"
+ id="path11075"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path24253"
+ d="m 82.395068,271.66953 c -2.548534,0.53612 -2.178736,-2.90444 -0.908284,-2.72256"
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:transform-center-x="-0.32852741"
+ inkscape:transform-center-y="-1.3911103"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 82.5437,278.0941 -1,0"
+ id="path24290"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24294"
+ d="m 82.532207,272.51355 -1,0"
+ style="opacity:0.6;fill:#646464;fill-opacity:0.75;fill-rule:evenodd;stroke:#646464;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path33682"
+ d="m 84.394211,280.56292 0.726168,0.72617"
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.02663434px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.390887,270.0368 0.72571,-0.72571"
+ id="path33684"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24682"
+ transform="translate(-166,402)">
+ <rect
+ y="217"
+ x="402"
+ height="16"
+ width="16"
+ id="rect24679"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g9450"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.6171649,0,0,0.6170324,328.7006,73.30195)"
+ style="opacity:0.8;display:inline">
+ <g
+ style="display:inline"
+ id="g9452"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path9454"
+ style="fill:url(#linearGradient15446);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.00075221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.872933,0,0,0.883992,56.29135,118.6984)" />
+ </g>
+ <path
+ d="m 134.19651,245.03757 -6.46038,0 m 3.23019,3.23013 0,-6.46025"
+ style="fill:none;stroke:url(#linearGradient15448);stroke-width:4.86145973;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ id="path9456"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 130.96632,248.2677 0,-6.46025"
+ style="fill:none;stroke:#000000;stroke-width:2.10663271;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path9458"
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g9460"
+ style="fill:none;stroke:url(#linearGradient15452);stroke-width:1.91174495;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.8478042,0,0,0.8531716,59.60482,122.34129)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15450);stroke-width:2.43795967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path9462"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ id="path9465"
+ style="fill:none;stroke:#000000;stroke-width:2.10663271;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 134.19651,245.03757 -6.46038,0"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24609"
+ transform="translate(307.00001,487.05412)">
+ <rect
+ y="111"
+ x="202"
+ height="16"
+ width="16"
+ id="rect24481"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(1.7e-4,10.00012)"
+ id="g9996"
+ style="display:inline">
+ <path
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.91431391;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 209.99983,115.99988 c 3.86419,0 6.99999,-3.13578 6.99999,-6.99996 0,-3.86418 -3.1358,-6.99997 -6.99999,-6.99997 -3.86419,0 -6.99998,3.13579 -6.99998,6.99997 0,3.86418 3.13579,6.99996 6.99998,6.99996 z m 0,-4.66664 c -1.45833,0 -2.33333,-0.875 -2.33333,-2.33332 0,-1.45833 0.875,-2.33332 2.33333,-2.33332 1.45833,0 2.33333,0.87499 2.33333,2.33332 0,1.45832 -0.875,2.33332 -2.33333,2.33332 z"
+ id="path9998"
+ sodipodi:nodetypes="csssccsssc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g10000"
+ transform="matrix(-2.005135,0,0,-2.005129,595.3141,357.6101)">
+ <path
+ style="fill:none;stroke:url(#linearGradient15578);stroke-width:0.59846401;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 192.16369,120.79528 c -1.76189,0 -3.19179,1.42994 -3.1918,3.19182 0,1.76188 1.42991,3.19183 3.1918,3.19183 1.76188,0 3.19179,-1.42995 3.1918,-3.19183 0,-1.76188 -1.42992,-3.19182 -3.1918,-3.19182 l 0,0 0,0 0,0 z"
+ id="path10002"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path10004"
+ d="m 192.16376,122.51797 c -0.81098,0 -1.46916,0.65815 -1.46916,1.46907 0,0.81094 0.65818,1.46907 1.46916,1.46907 0.81097,0 1.46913,-0.65813 1.46913,-1.46907 0,-0.81092 -0.65816,-1.46907 -1.46913,-1.46907 z"
+ style="fill:none;stroke:url(#linearGradient15580);stroke-width:0.59846407;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g106468">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.9535916,0,0,1.1712921,1176.1968,319.2322)"
+ id="g29877-5-3-1"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path29879-5-0-9"
+ d="m 392.96689,241.84215 -0.56915,0 -3.5287,2.84782 0,1.13912 3.5287,2.84781 0.56915,0 0,-6.83475 0,0 0,0 z"
+ style="color:#000000;fill:url(#radialGradient106344-5);fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient106433);stroke-width:0.66107476px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path29881-5-6-0"
+ d="m 392.96688,248.67221 -0.57173,0 -3.51515,-2.83619 -0.008,-1.21916"
+ style="fill:none;stroke:url(#linearGradient106307-2);stroke-width:0.66107482px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="598"
+ x="404"
+ height="16"
+ width="16"
+ id="rect24491"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g29910">
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29875"
+ width="16"
+ height="16"
+ x="619"
+ y="-441" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0,-2.196282,-1.316799,0,755.9575,1484.5661)"
+ id="g29877"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path29879"
+ d="m 392.96689,241.84215 -0.56915,0 -3.5287,2.84782 0,1.13912 3.5287,2.84781 0.56915,0 0,-6.83475 0,0 0,0 z"
+ style="color:#000000;fill:url(#linearGradient29884);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.58802557px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path29881"
+ d="m 392.51157,247.53778 0,-4.93622 -3.18721,2.46812"
+ style="fill:none;stroke:url(#linearGradient29886);stroke-width:0.58802563px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24559"
+ transform="translate(259,508.00001)">
+ <rect
+ y="111"
+ x="103"
+ height="16"
+ width="16"
+ id="rect24489"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(-0.248353,0.02816779,0.02830718,0.248422,140.45214,86.01031)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10768"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ style="display:inline"
+ id="g24623"
+ transform="translate(-112,487.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24479"
+ width="16"
+ height="16"
+ x="243"
+ y="111" />
+ <g
+ transform="translate(0.01612278,6)"
+ id="g10870"
+ style="display:inline">
+ <rect
+ style="fill:url(#linearGradient15719);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect10872"
+ width="11.000006"
+ height="2.9999976"
+ x="245.48387"
+ y="111.49999"
+ rx="0"
+ ry="1.4769578"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15721);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 254.47577,112.49191 -7.99189,0.008 0.0242,1"
+ id="path10874"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24617"
+ transform="translate(-113,487.00001)">
+ <rect
+ y="111"
+ x="223"
+ height="16"
+ width="16"
+ id="rect24477"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01612278,6)"
+ id="g10876"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient15723);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 225.48388,111.49999 4.01612,-0.008 -0.0161,-3.99192 3,0 0.0161,3.99192 3.98388,0.008 0,3 -3.98388,-0.008 -0.0161,4.008 -3,0 0.0161,-4.008 -4.01612,0.008 0,-3 z"
+ id="path10878"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10880"
+ d="m 232.48388,112.49999 3,0 m -5,2 0,3 m 1,-9 -1,0 0.0161,3.99192 -4.01612,0.008 0.0242,1"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24629"
+ transform="translate(-128,487.00001)">
+ <rect
+ y="132"
+ x="322"
+ height="16"
+ width="16"
+ id="rect24475"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g11344"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.9261989,0,0,0.928757,209.23303,-98.08036)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g11346"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11348"
+ style="fill:url(#linearGradient15774);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.06496322;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.872933,0,0,0.883992,56.29135,130.45005)" />
+ </g>
+ <path
+ d="m 134.19651,255.80467 -6.46038,0 m 3.23019,3.23013 0,-6.46025"
+ style="fill:none;stroke:url(#linearGradient15776);stroke-width:3.2301569;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ id="path11350"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 130.96632,259.0348 0,-6.46025"
+ style="fill:none;stroke:#000000;stroke-width:1.07819378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path11352"
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g11354"
+ style="fill:none;stroke:url(#linearGradient15780);stroke-width:1.27024341;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.858314,0,0,0.863791,58.21752,134.9089)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15778);stroke-width:1.60000753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path11356"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ id="path11358"
+ style="fill:none;stroke:#000000;stroke-width:1.07819378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 134.19651,255.80467 -6.46038,0"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24604"
+ transform="translate(305,487.00001)">
+ <rect
+ y="111"
+ x="183"
+ height="16"
+ width="16"
+ id="rect24483"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(-1,0,0,-1,382.01612,238.00006)"
+ id="g54036"
+ style="display:inline">
+ <path
+ sodipodi:type="arc"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient16025);stroke-width:1.94115818;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path54038"
+ sodipodi:cx="190.5"
+ sodipodi:cy="119.5"
+ sodipodi:rx="5.5"
+ sodipodi:ry="5.5"
+ d="m 196,119.5 a 5.5,5.5 0 1 1 -11,0 5.5,5.5 0 1 1 11,0 z"
+ transform="matrix(0.61819,0,0,0.618186,73.23488,45.12681)" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24582"
+ transform="translate(114.02028,508.00993)">
+ <rect
+ y="111"
+ x="143"
+ height="16"
+ width="16"
+ id="rect24487"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24576">
+ <path
+ transform="matrix(1.4256767,0,0,1.4314068,-320.1963,68.175135)"
+ d="m 333.29445,35.5 a 2.7944512,2.7944512 0 1 1 -5.5889,0 2.7944512,2.7944512 0 1 1 5.5889,0 z"
+ sodipodi:ry="2.7944512"
+ sodipodi:rx="2.7944512"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path15084"
+ style="fill:#e6e6e6;fill-opacity:0.25490196;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.2885487,0,0,1.2885617,-274.87525,73.246084)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path15086"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient15122);stroke-width:0.77606368;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient15124);stroke-width:0.77608043;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path15099"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.288521,0,0,-1.2885339,576.8463,164.73299)" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.6;display:inline"
+ id="g24923"
+ transform="translate(4,529.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24905"
+ width="16"
+ height="16"
+ x="43"
+ y="69" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10995"
+ style="display:inline">
+ <g
+ style="fill:none;display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-0.608695,0,0,0.604849,289.36339,-70.36932)"
+ id="g10997">
+ <path
+ id="path10999"
+ d="m 394.08819,237.85988 -6.57143,6.61322 6.57143,6.61322 1.23215,0 -10e-6,-13.22644 -1.23214,0 z"
+ style="fill:none;stroke:#000000;stroke-width:1.64807379;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path11001"
+ d="m 49.233877,73.74999 3.75,3.75 -3.75,3.75 -0.25,0 0,-7.5 0.25,0 z"
+ style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 57.25,606.75 -3.75,3.75 -0.5,0"
+ id="path35403"
+ sodipodi:nodetypes="cc"
+ transform="translate(-4.0161228,-529.00001)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24911"
+ transform="translate(28,550.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24909"
+ width="16"
+ height="16"
+ x="82"
+ y="69" />
+ <g
+ style="display:inline"
+ transform="matrix(0,-1,1,0,-153.98989,467.9919)"
+ id="g11003"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ id="path11005"
+ d="m 392.49192,239.48989 -5.00001,4.75 0,0.5 5.00001,4.75 1,0 0,-10 -1,0 z"
+ style="color:#000000;fill:url(#linearGradient15742-5);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11007"
+ d="m 392.49191,248.23989 0,-7.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g24917"
+ transform="translate(27,550.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24907"
+ width="16"
+ height="16"
+ x="62"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g11009"
+ transform="matrix(-1,0,0,1,461.01011,-167)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ style="fill:url(#linearGradient15742);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 392.5,239.5 -4.98989,4.74999 0,0.5 4.98989,4.75001 1.01011,-1e-5 0.0368,-9.96874 L 392.5,239.5 z"
+ id="path11011"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient27860);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.51011,248.24999 0,-7.5 -4,3.75"
+ id="path11013"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25461"
+ transform="translate(444,424.00001)">
+ <rect
+ y="174"
+ x="23"
+ height="16"
+ width="16"
+ id="rect25118"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25451">
+ <g
+ id="use25367"
+ transform="translate(24.016123,6)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25447"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25449"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ id="use25369"
+ transform="translate(28.016123,6)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25441"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25443"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <rect
+ y="184.50003"
+ x="26.516125"
+ height="3.0000005"
+ width="1.0000005"
+ id="rect25373"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25375"
+ width="1"
+ height="3"
+ x="25.516123"
+ y="183.5" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25412"
+ transform="translate(443,424.00001)">
+ <rect
+ y="174"
+ x="3"
+ height="16"
+ width="16"
+ id="rect25116"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25401">
+ <g
+ id="use9783"
+ transform="translate(4.0161228,0)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25397"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25399"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ id="use9785"
+ transform="translate(8.0161228,0)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect25391"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect25393"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ id="g9787"
+ transform="translate(0.01612278,0)">
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect9789"
+ width="1.0000005"
+ height="3.0000005"
+ x="6.5000019"
+ y="178.50003" />
+ <rect
+ y="177.5"
+ x="5.5"
+ height="3"
+ width="1"
+ id="rect9791"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.3;marker:none;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25528"
+ transform="translate(93,445.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25526"
+ width="16"
+ height="16"
+ x="143"
+ y="153" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10844"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient15699);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 144.5,163.5 13,0 0,-1 c 0,-2.25 -0.5,-3 -4,-3 -0.5,-1.25 -1.5,-3 -4,-3 l -1,0 c -3.75,0 -4,2.25 -4,5 l 0,2 z"
+ id="path10846"
+ sodipodi:nodetypes="ccscsccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient15701);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.46666667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path10848"
+ sodipodi:cx="147"
+ sodipodi:cy="165"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 148,165 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(1.5,0,0,1.5,-73.5,-83.5)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csccc"
+ id="path10850"
+ d="m 150,157.5 -1.5,0 c -3,0 -3,1.5 -3,5 m 10.99996,-0.71441 c 0,-1.60712 5e-5,-1.28559 -2.99996,-1.28559"
+ style="fill:none;stroke:url(#linearGradient15703);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.5,0,0,1.5,-66.5,-83.5)"
+ d="m 148,165 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="165"
+ sodipodi:cx="147"
+ id="path10852"
+ style="fill:url(#linearGradient15705);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.46666667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g35472"
+ transform="translate(0,128.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25724"
+ width="16"
+ height="16"
+ x="89"
+ y="470" />
+ <g
+ id="g35249">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path12027"
+ d="m 94.5,480.5 1.25,-1.25"
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-6.245879"
+ inkscape:transform-center-x="-6.2091889"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.62898993;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path12029"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.4308622,0,0,1.4308687,469.36987,363.18486)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.863188,484.13807 94.25,480.75"
+ id="path12031"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 94.5,480.5 1.25,-1.25"
+ id="path12033"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.4308622,0,0,1.4308687,469.36987,363.18486)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path35965"
+ style="opacity:0.5;fill:url(#radialGradient35967);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.55910218;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.2091889"
+ inkscape:transform-center-y="-6.245879" />
+ <g
+ id="g12035"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0005769,0,0,0.9999104,-69.113516,270.01809)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35488);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient35490);stroke-width:0.87477797;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path12037"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" />
+ <g
+ id="g35307">
+ <path
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path35287"
+ style="opacity:0.25;fill:url(#radialGradient35492);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient35494);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35289"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
+ </g>
+ <path
+ inkscape:transform-center-y="-6.490455"
+ inkscape:transform-center-x="-3.3976162"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path12041"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.993526,0,0,1.026234,103.4315,65.484747)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path12043"
+ d="m 90.75,484.25 3.5,-3.5"
+ style="fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.25,484 94,480.25"
+ id="path12045"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21566"
+ transform="translate(-206,-205)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21528"
+ width="16"
+ height="16"
+ x="463"
+ y="236" />
+ <g
+ transform="translate(459.98858,167)"
+ style="display:inline"
+ id="g14449">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path14451"
+ d="m 17.51142,84.5 -13.988585,0 -0.011415,-14 14,0 0,14 z"
+ style="fill:url(#linearGradient16063);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path14523"
+ style="fill:none;stroke:url(#linearGradient16067);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 6.0097,77.5 6.00172,0 m 1,0 4,0 m -6,-2 6,0 m -3,-2 3,0 m -11.00172,0 7.00172,0 m -7.00172,2 4.00172,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient16069);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51142,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 0,0 0,0 0,0 z"
+ id="path14459"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21557"
+ transform="translate(-205,-205)">
+ <rect
+ y="236"
+ x="483"
+ height="16"
+ width="16"
+ id="rect21548"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21749">
+ <g
+ transform="translate(479.98859,167)"
+ style="display:inline"
+ id="g14498">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path14500"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ style="fill:url(#linearGradient14511);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient14517);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51141,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 z"
+ id="path14508"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 486,246.5 7.03916,0 m -2.03916,2 -5,0 m 0.0392,-6 5,0 m -5,-2 6,0 m -6,4 3,0"
+ style="fill:none;stroke:url(#linearGradient21531);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path15300"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21497"
+ transform="translate(97,5)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21493"
+ width="16"
+ height="16"
+ x="223"
+ y="26" />
+ <g
+ id="g21465">
+ <g
+ style="display:inline"
+ id="g10969"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(0.1889228,-16)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g10971"
+ transform="matrix(1.083333,0,0,1.083326,-149.75,-207.0817)">
+ <g
+ id="g10973">
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path10975"
+ d="m 356.53857,243.30784 -11.07692,0 0,-11.07699 11.07692,0 0,11.07699 z"
+ style="fill:url(#linearGradient15734);fill-opacity:1;fill-rule:evenodd;stroke:#333333;stroke-width:0.92307967px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.92307913px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 346.38485,242.26935 -1.3e-4,-9.11543 9.14632,0"
+ id="path10977"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ id="path10979"
+ d="m 227,49 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 231,47 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z"
+ id="path10981"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g16140"
+ style="display:inline"
+ transform="translate(219.98859,-43)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient16150);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ id="path16142"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path16148"
+ d="m 16.51141,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 z"
+ style="fill:none;stroke:url(#linearGradient16154);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path16156"
+ d="m 227,33 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 231,31 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z"
+ id="path16158"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21514"
+ transform="translate(96.030183,5)">
+ <rect
+ y="26"
+ x="202.96982"
+ height="16"
+ width="16"
+ id="rect21491"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21479">
+ <g
+ transform="translate(-19.811077,-16)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g10983"
+ style="display:inline">
+ <g
+ transform="matrix(1.083333,0,0,1.083326,-149.75,-207.0817)"
+ id="g10985"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g10987">
+ <path
+ style="fill:url(#linearGradient15736);fill-opacity:1;fill-rule:evenodd;stroke:#333333;stroke-width:0.92307967px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 356.53857,243.30784 -11.07692,0 0,-11.07699 11.07692,0 0,11.07699 z"
+ id="path10989"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path10991"
+ d="m 346.38485,242.26935 -1.3e-4,-9.11543 9.14632,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.92307913px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 231,47 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z m -7,-2 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ id="path10993"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(199.98859,-43)"
+ style="display:inline"
+ id="g16160">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path16162"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ style="fill:url(#linearGradient16170);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient16174);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51141,71.5 -12,0 -1e-6,12 12.000001,0 0,-12 z"
+ id="path16168"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 211,31 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-3 -1,0 z m 3,4 0,2 1,0 0,-2 -1,0 z m -7,-2 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 -2,0 0,1 2,0 0,1 -2,0 0,1 2,0 1,0 0,-4 -1,0 z m -2,3 0,-1 -1,0 0,1 1,0 z"
+ id="path16178"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11969"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21607"
+ width="16"
+ height="16"
+ x="362"
+ y="29" />
+ <g
+ id="g11961">
+ <g
+ transform="translate(358.98859,-40)"
+ style="display:inline"
+ id="g14938">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path14940"
+ d="m 17.51141,84.5 -14,0 -1e-7,-14 13.9814141,0 0.01859,14 -4e-6,0 z"
+ style="fill:url(#linearGradient21902);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient21904);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 16.51141,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 z"
+ id="path14942"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccc"
+ id="path14947"
+ d="m 366,33.03125 0,1 -1,0 0,1 1,0 0,2 1,0 0,-4 -1,0 z M 365,39 l 0,1 2.3295,0 0,-1 L 365,39 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0.0594,1 -1.05938,0 0,1 -1,0 0,1 3,0 0,-1 -1.44062,0 0.5,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 369,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ id="path14953"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 370,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -4,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ id="path14955"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11979"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21605"
+ width="16"
+ height="16"
+ x="341"
+ y="29" />
+ <g
+ id="g11953">
+ <g
+ id="g14924"
+ style="display:inline"
+ transform="translate(337.98858,-40)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient21862);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.500005,84.5 -13.988585,0 -1e-7,-14 14.0000001,0 -0.01141,14 -5e-6,0 0,0 0,0 z"
+ id="path14929"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path14933"
+ d="m 16.51142,71.5 -12,0 0,12 12.000001,0 -10e-7,-12 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient21864);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g11949">
+ <path
+ id="path14967"
+ d="m 344,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path14971"
+ d="m 345,34 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,3 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -8,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g15785"
+ transform="translate(-168.02763,373.00001)" />
+ <g
+ id="g15789"
+ transform="translate(-168.02763,380.00001)" />
+ <g
+ transform="translate(-163.02763,375.00001)"
+ id="g15795" />
+ <g
+ id="g15801"
+ transform="translate(-163.02763,371.00001)" />
+ <g
+ transform="translate(-163.02763,382.00001)"
+ id="g15807" />
+ <g
+ style="display:inline"
+ transform="translate(150,389)"
+ id="g22272">
+ <g
+ id="g22274"
+ transform="translate(-30,0)">
+ <rect
+ ry="0"
+ rx="0"
+ y="-127"
+ x="200"
+ height="16"
+ width="16"
+ id="rect22276"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 204,-114 c 4.5365,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path22282"
+ sodipodi:nodetypes="csc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22278"
+ width="2.9998772"
+ height="3"
+ x="202.50012"
+ y="-115.5"
+ ry="1.4999387"
+ rx="1.4843137" />
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-125.5"
+ x="205.50012"
+ height="3"
+ width="2.9998772"
+ id="rect22280"
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path22284"
+ d="m 204,-114 c 4.49647,0 8.5,-3 8.5,-6 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:url(#linearGradient24098);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#afc6e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 205,-115 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path22288"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path22291"
+ d="m 208,-125 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-1e-5 1.96003,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#87aade;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 176.5,-123.5 0,-1 1,0"
+ id="path22293"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22295"
+ d="m 173.5,-113.5 0,-1 1,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path22297"
+ d="m 176,-113.25657 c -0.33333,0 -0.66667,-1e-5 -1,-1e-5 0,-0.55431 0,-1.1086 0,-1.66292 0.33333,0 0.66667,1e-5 1,1e-5 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.35;fill:#002255;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path22299"
+ d="m 179,-122.48792 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.63982 0,-1.27964 0,-1.91948 0.32001,0 0.64002,1e-5 0.96003,1e-5 0,0.63983 0,1.27966 0,1.91948 z"
+ style="opacity:0.2;fill:#002255;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#00112b;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 176,-113 c -0.33333,0 -0.66667,0 -1,0 0,-0.21055 0,-0.42107 0,-0.63162 0.33333,0 0.66667,0 1,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path22302"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g31233"
+ transform="translate(-58,-17)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31205"
+ width="16"
+ height="16"
+ x="63"
+ y="48" />
+ <g
+ id="g9148"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline"
+ transform="matrix(1.0003553,0,0,0.9995949,18.983834,-41.953346)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:url(#linearGradient15356);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect9150"
+ width="12.995382"
+ height="13.003749"
+ x="45.5"
+ y="91.491928" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient15358);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 46.49945,103.49527 0,-11.002747 10.996287,0 0,11.002747 -10.996287,0 z"
+ id="path9152"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31226"
+ transform="translate(-57,-17)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31207"
+ width="16"
+ height="16"
+ x="83"
+ y="48" />
+ <g
+ style="display:inline"
+ id="g9154"
+ transform="matrix(1.1658027,0,0,1.1657997,-59.289717,-204.05607)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path9156"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23686159;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient15360);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path9158"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)" />
+ <path
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15362);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path9160"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g31393"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31391"
+ width="16"
+ height="16"
+ x="110"
+ y="29" />
+ <g
+ transform="translate(-73,-123.96875)"
+ id="g9974"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:none"
+ d="M 186.2503,165.73428 C 185.16882,164.6489 184.5,163.15208 184.5,161.5 c 0,-3.312 2.688,-6 6,-6 1.65758,0 3.15886,0.67328 4.24511,1.76111 l -8.49481,8.47317 z"
+ id="path9976"
+ sodipodi:nodetypes="csscc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23601"
+ d="m 188,154 0,2 6,0 0,-2 -6,0 z m 6,2 0,2 1.96875,0 0,6 -1.96875,0 0,1.96875 -6,0 0,-1.96875 -2,0 0,2 2,0 0,1.96875 6,0 0,-1.96875 2,0 0,-2 1.96875,0 0,-6 -1.96875,0 0,-2 -2,0 z m -8,8 0,-6 -2,0 0,6 2,0 z m 0,-6 2,0 0,-2 -2,0 0,2 z"
+ style="opacity:0.1;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 188,154 0,2 6,0 0,-2 -6,0 z m 6,2 0,2 1.96875,0 0,6 -1.96875,0 0,1.96875 -6,0 0,-1.96875 -2,0 0,2 2,0 0,1.96875 6,0 0,-1.96875 2,0 0,-2 1.96875,0 0,-6 -1.96875,0 0,-2 -2,0 z m -8,8 0,-6 -2,0 0,6 2,0 z m 0,-6 2,0 0,-2 -2,0 0,2 z"
+ id="path9978"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:url(#linearGradient15574);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 186,158 2,0 0,-2 6,0 0,2 2,0 0,6 -2,0 0,2 -6,0 0,-2 -2,0 0,-6 z"
+ id="path9980"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path23596"
+ d="m 186.5,158.46875 2,0 0,-2 5,0 0,2 2,0 0,5 -2,0 0,2 -5,0 0,-2 -2,0 0,-5 z"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient23599);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31442"
+ transform="translate(-235,4)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31425"
+ width="16"
+ height="16"
+ x="282"
+ y="6" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(0.01612278,22)"
+ id="g10456"
+ style="display:inline">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path10458"
+ d="m 296.49991,-1.4999999 -13.00008,0 0,-12.9999991 13.00008,0 0,12.9999991 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient15644);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15646);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 284.50009,-2.5000021 0,-11.0000069 11.00001,0"
+ id="path10460"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path10462"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 286.42863,-12.4 -0.84311,0 m 2.83879,3 -0.83163,0 m 2.83056,3 -0.82626,0 m 2.78967,1 -0.80293,0 m 3.77084,1 -1.74082,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31515"
+ transform="translate(18,130)">
+ <rect
+ y="27"
+ x="323"
+ height="16"
+ width="16"
+ id="rect31510"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01612278,-12)"
+ id="g10854"
+ style="display:inline">
+ <rect
+ style="fill:url(#linearGradient15707);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="rect10856"
+ width="12"
+ height="12"
+ x="324.50003"
+ y="41.500015" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient15709);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path10858"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(1.000048,0,0,0.999998,-0.01591645,12.000064)" />
+ <path
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient15711);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
+ d="m 335.50002,42.500013 -10,0 0,10 L 335.5,52.5 l 0,-10"
+ id="path10860"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15713);stroke-width:1.16669464;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path10862"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.857099,0,0,0.857147,47.22893,17.071296)" />
+ </g>
+ </g>
+ <g
+ transform="translate(39,130)"
+ id="g27524"
+ style="opacity:0.2;display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27526"
+ width="16"
+ height="16"
+ x="323"
+ y="27" />
+ <g
+ style="display:inline"
+ id="g27528"
+ transform="translate(0.01612278,-12)">
+ <rect
+ y="41.500015"
+ x="324.50003"
+ height="12"
+ width="12"
+ id="rect27530"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ <path
+ transform="matrix(1.000048,0,0,0.999998,-0.01591645,12.000064)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path27532"
+ style="fill:url(#linearGradient27540);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path27534"
+ d="m 335.50002,42.500013 -10,0 0,10 L 335.5,52.5 l 0,-10"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient27542);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.857099,0,0,0.857147,47.22893,17.071296)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path27536"
+ style="fill:none;stroke:url(#linearGradient27544);stroke-width:1.16669464;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g31523"
+ transform="translate(19,130)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31513"
+ width="16"
+ height="16"
+ x="343"
+ y="27" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10864"
+ style="display:inline">
+ <path
+ transform="matrix(1.142871,0,0,1.142855,-27.218817,-5.0713453)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path10866"
+ style="fill:url(#linearGradient15715);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87499601;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient15717);stroke-width:1.16669464;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path10868"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.857099,0,0,0.857147,67.228993,5.071249)" />
+ </g>
+ </g>
+ <g
+ id="g31658"
+ transform="translate(63,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31549"
+ width="16"
+ height="16"
+ x="26"
+ y="8" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient31664);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 40.499999,22.499999 -12.999999,0 0,-12.999999 12.982741,0 0.01726,12.999999 -2e-6,0 z"
+ id="path31555"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccc"
+ id="path31559"
+ d="M 36.5,11.548223 36.5,19 l 0,-7.451777 z M 37.5,16 l 0,3 0,-3 z m -3,-2 0,5 0,-5 z m 1,0 0,5 0,-5 z m -3,1 0,4 0,-4 z m 6,0 0,4 0,-4 z m -5,1 0,3 0,-3 z m -3,1 0,2 0,-2 z m 9,1.578539 0,0.421461 0,-0.421461 z M 31.5,18 l 0,1 0,-1 z m -3,-0.52573 0,1.52573 0,-1.52573 z m 1,1.087098 0,0.438632 0,-0.438632 z"
+ style="fill:none;stroke:url(#linearGradient31666);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient31672);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 28.5,19.5 11,0"
+ id="path31670"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path31557"
+ d="m 39.5,10.500004 -11,0 0,11 11.000001,0 -10e-7,-11 z"
+ style="fill:none;stroke:url(#linearGradient31668);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g31429"
+ transform="translate(-234,4)">
+ <rect
+ y="6"
+ x="302"
+ height="16"
+ width="16"
+ id="rect31427"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01612278,-16)"
+ id="g13262"
+ style="display:inline">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(20.00009,22)"
+ id="g13264">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path13266"
+ d="m 296.49991,14.5 -13.00008,0 0,-12.999999 13.00008,0 0,12.999999 z"
+ style="fill:url(#linearGradient31646);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient31648);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 284.50009,13.499998 0,-11.000007 11.00001,0"
+ id="path13268"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path13270"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 310,34 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g13272"
+ transform="translate(0,-10)"
+ style="stroke-width:1.10000002;stroke-miterlimit:4;stroke-dasharray:none">
+ <path
+ id="path13274"
+ style="fill:none;stroke:url(#radialGradient31650);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 310,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ d="m 310,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ style="fill:none;stroke:url(#radialGradient31652);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path13276"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13278"
+ style="fill:none;stroke:url(#radialGradient31654);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 310,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ d="m 309.98388,44 -3.5,-1.5 0,-5 3.5,-1.5 3.5,1.5 0,5 -3.5,1.5 z"
+ style="fill:none;stroke:url(#radialGradient31656);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path13280"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-21,-418)"
+ id="g31674">
+ <rect
+ y="428"
+ x="47"
+ height="16"
+ width="16"
+ id="rect31676"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g31678">
+ <rect
+ ry="0"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31680"
+ width="13.016124"
+ height="12.953857"
+ x="48.499996"
+ y="429.54614" />
+ <rect
+ y="430"
+ x="50.016117"
+ height="11.046139"
+ width="11.000001"
+ id="rect31682"
+ style="fill:url(#linearGradient31694);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <path
+ style="fill:url(#linearGradient31696);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 49,430 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m 3,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ id="path31684"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient31698);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ id="path31686"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g11938"
+ transform="translate(0,2)">
+ <rect
+ y="8"
+ x="278"
+ height="16"
+ width="16"
+ id="rect31906"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-64.983874,-102.97791)"
+ id="g14768"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient31932);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 348.18876,112.47791 8.33334,0 0,13 -11,0 -1e-5,-10 2.66667,-3 0,0 0,0 0,0 z"
+ id="path14575"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 349,114 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 0,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m 0,-2 2,0 0,-2 -2,0 0,2 z m 0,-2 0,-2 -2,0 0,2 2,0 z"
+ id="rect14548"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path14579"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,409.54887,-222.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient31934);stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 354.58387,114.50843 -7.05183,-0.0551 0.007,9.11382"
+ id="path14581"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 345,116 4,0 0,-4 -4,4 z"
+ id="path14583"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 346.5,117.00001 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient31936);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path14585"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path14587"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 345.5221,114.97791 0,10.5 11,0 0,-13 -8.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g10845"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31964"
+ width="16"
+ height="16"
+ x="26"
+ y="260" />
+ <g
+ transform="translate(-2322.9523,-570.94199)"
+ id="g12799"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cczcccc"
+ id="path12801"
+ d="m 2349.9523,841.94199 c 2.0093,-2.0093 3.5347,-3.43269 5.544,-5.44199 3.25,-3.25 9,-2 9,2 -4.5,-2.5 -7.044,3.94199 -0.544,3.94199 l 0,1.5 -14,0 0,-2 z"
+ style="opacity:0.8;fill:url(#linearGradient38692);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 2349.5,842.49627 c 1.9988,-1.99875 3.9535,-4.05552 5.9523,-6.05428 3.25,-3.25 9.044,-1.94199 9.044,2.05801 -4.5,-2.5 -6.544,4.94199 0,4"
+ id="path12805"
+ sodipodi:nodetypes="cczc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccs"
+ id="path12807"
+ d="m 2351,842.51381 c 1.67,-1.67002 3.34,-3.34005 5.0101,-5.01008 2.1922,-2.31174 5.9422,-2.81174 7.4422,-0.0617"
+ style="fill:none;stroke:url(#radialGradient13900);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g13136"
+ transform="translate(0,2)">
+ <rect
+ y="260"
+ x="131"
+ height="16"
+ width="16"
+ id="rect32039"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g13125">
+ <g
+ id="g12811"
+ transform="translate(-70.98388,253.6)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="opacity:0.4">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.090908,0,0,1.083334,-60.5905,-148.5)"
+ id="g12813">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path12815"
+ d="m 253.9851,154.06144 0.0148,-7.98461 -5.97312,2.67692 c 0,2.37037 -0.0149,8.01803 -0.0149,8.53832 l 5.97323,-3.23063 -1e-5,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 242.06842,154.06144 0,-8.21538 5.95834,2.90769 0,8.30769 -5.95834,-3 z"
+ id="path12817"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path12819"
+ d="m 242.06842,146.21529 5.95834,-2.67692 5.95834,2.67692 -5.95834,2.53846 -5.95834,-2.53846 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path12821"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 209.98388,21.9 -6.5,-3.5 0,-8.5 m 6.5,12 6.5,-3.5 0,-8.5 m 0,0 -6.5,-2.75 -6.5,2.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g12823"
+ transform="matrix(0.668332,0,0,0.668394,53.64412,108.1139)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path12825"
+ style="fill:url(#linearGradient13112);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.60044813;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8412876,0,0,0.8414582,16.661932,139.91818)" />
+ <path
+ transform="matrix(0.654253,0,0,0.6543912,41.350498,161.99208)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient13114);stroke-width:2.28663301;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path27909"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g10823"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31968"
+ width="16"
+ height="16"
+ x="68"
+ y="260" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12863"
+ d="m 70.562559,271.5 0.24994,0.25 9,-9 -0.24994,-0.25 -9,0 0,9 z"
+ style="fill:url(#linearGradient24189);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 70.562559,271.5 -6e-5,-9 9,5e-5 m -4.99994,4.89995 0,-4.8 m 0.89997,3.9 -4.8,0"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="path12865"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12867"
+ d="m 71.562559,265.51369 0,-2.01369 1.99998,0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24198"
+ style="opacity:0.4">
+ <path
+ id="path12861"
+ d="m 72.562559,273.5 -0.25006,-0.25 9,-9 0.25006,0.25 0,9 -9,0 z"
+ style="fill:url(#linearGradient24209);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient24192);stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ d="m 80.499999,265.5 0,7 -7,0"
+ id="path27953"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path12869"
+ d="m 81.562559,264.5 0,9 -9,-5e-5"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 75.562559,265.51369 0,-2.01369 1.99998,0"
+ id="path12871"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12873"
+ d="m 71.562579,269.51369 0,-2.01369 1.99998,0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 71,277 83,265"
+ id="path42252"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g14009"
+ transform="translate(1,-0.01245054)" />
+ <g
+ id="g17702"
+ transform="translate(-1e-5,127)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12049"
+ width="16"
+ height="16"
+ x="47.000004"
+ y="387" />
+ <g
+ transform="translate(-336.01611,233)"
+ id="g22979">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 391.01611,155 -6.00001,2.125 0,7.65625 6.00001,3.21875 6,-3.21875 0,-7.65625 -6,-2.125 z"
+ id="path12053"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path12063"
+ d="m 397.01609,164.76992 0,-7.6298 -6,-2.14012 c 0,2.58362 8.3e-4,12.47266 8.3e-4,13.03976 l 5.99917,-3.26984 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17712);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path12065"
+ d="m 385.01609,164.75 0,-7.5 6,-2.25 c 0,2.37037 0,12.47971 0,13 l -6,-3.25 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99989706;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path12067"
+ d="m 385.01658,157.14012 6.00034,-2.17997 5.99917,2.17997 -5.99975,2.72493 -5.99976,-2.72493 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
+ id="path12835"
+ d="m 385.01612,158 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-0.5 -2,-0.5 0,1 z m 0,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,1 2,1 0,-2 -2,0 z m -2,-2 0,-2 -2,0 0,2 2,0 z"
+ style="fill:#c81700;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17714);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 385.51625,164.52217 0,-7.03525 5.49627,-2.01007 5.49628,2.01007 0,7.03525 -5.49628,3.01511 -5.49627,-3.01511 z"
+ id="path12069"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23022"
+ transform="translate(19,-17)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23020"
+ width="16"
+ height="16"
+ x="343"
+ y="237" />
+ <g
+ id="g9430"
+ transform="translate(19.991123,0.02506982)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path9432"
+ d="m 330.5,240.5 5,5 -5,5 -5,-5 5,-5 z"
+ style="fill:url(#linearGradient15436);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.85000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m 327,245.5 3.5,-3.5"
+ id="path9434"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23028"
+ transform="translate(18.067322,-17)">
+ <rect
+ y="237"
+ x="322.93268"
+ height="16"
+ width="16"
+ id="rect23018"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ transform="translate(0.04112278,0.02506982)"
+ id="g12077">
+ <path
+ style="fill:url(#linearGradient52027);fill-opacity:1;fill-rule:nonzero;stroke:#341b00;stroke-width:0.85000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m 330.5,240.5 5,5 -5,5 -5,-5 5,-5 z"
+ id="path12079"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path12081"
+ d="m 327,245.5 3.5,-3.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23056"
+ transform="translate(118,4)">
+ <rect
+ y="216"
+ x="181"
+ height="16"
+ width="16"
+ id="rect23010"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0,1,1,0,-56.06114,-164)"
+ id="g13176"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <path
+ id="path13178"
+ d="m 392.53018,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ style="opacity:0.2;fill:none;stroke:#ff982a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.7;fill:none;stroke:#ff982a;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 392.5,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ id="path13180"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13182"
+ d="m 392.5,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ style="fill:url(#linearGradient52023);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient13639);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path13184"
+ d="m 389,244.5 2.5,-2.5"
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23048"
+ transform="translate(35,4.96982)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23012"
+ width="16"
+ height="16"
+ x="201"
+ y="215.03018" />
+ <g
+ transform="matrix(0,1,1,0,-35.015077,-166)"
+ id="g13216"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <path
+ id="path13218"
+ d="m 395.53018,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ style="opacity:0.2;fill:none;stroke:#ff982a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.75;fill:none;stroke:#ff982a;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 395.5,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ id="path13220"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13222"
+ d="m 391.5,239.5312 -9,4 9,4 4,-4 -4,-4 z"
+ style="fill:url(#linearGradient52025);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient14661);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path13224"
+ d="m 385,243.5312 6.25,-2.75"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23040"
+ transform="translate(36,4.96982)">
+ <rect
+ y="215.03018"
+ x="221"
+ height="16"
+ width="16"
+ id="rect23014"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g13226"
+ transform="matrix(0,1,1,0,-15.015077,-166)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.2;fill:none;stroke:#ff982a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 395.53018,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ id="path13228"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path13230"
+ d="m 395.53018,243.5312 -4,-4 -9,4 9,4 4,-4 z"
+ style="opacity:0.75;fill:none;stroke:#ff982a;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient15993);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient15995);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 391.5,239.5312 -9,4 9,4 4,-4 -4,-4 z"
+ id="path13232"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 385,243.5312 6.25,-2.75"
+ id="path13234"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23034"
+ transform="translate(37,5)">
+ <rect
+ y="215"
+ x="241"
+ height="16"
+ width="16"
+ id="rect23016"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0,1,1,0,4.9849228,-166)"
+ id="g13236"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <path
+ id="path13238"
+ d="m 391.5,239.5312 -9,4 9,4 4,-4 -4,-4 z"
+ style="fill:url(#linearGradient15997);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path13240"
+ d="m 385,243.5312 6.25,-2.75"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23114"
+ transform="translate(-81,46)">
+ <rect
+ y="174"
+ x="401"
+ height="16"
+ width="16"
+ id="rect23112"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g11747"
+ transform="matrix(0,1,1,0,163.98492,-206)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:url(#linearGradient15854);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.5,240.5312 -1,0 -4,3.9688 4,4.0312 1,0 0,-8 z"
+ id="path11749"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 389,244.5 2.5,-2.5"
+ id="path11751"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23160"
+ transform="translate(-316,25)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23130"
+ width="16"
+ height="16"
+ x="364"
+ y="195" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10790"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient15681);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 364.48388,198.5 0,9 1,0 5,-3.75 0,3.75 1,0 5.01612,-3.71875 0,3.71875 2,0 0,-9 -2,0 0,3.71875 -5.01612,-3.71875 -1,0 0,3.75 -5,-3.75 -1,0 z"
+ id="path10792"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10794"
+ d="m 365.48388,206.5 0,-6.75 4.25,3.25"
+ style="fill:none;stroke:url(#linearGradient11764);stroke-width:0.99999952px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient11762);stroke-width:0.99999952px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 371.48388,206.5 0,-6.75 4.5,3.25"
+ id="path10796"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 377.23388,206.75 0.0161,-7.5"
+ id="path10798"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path11760"
+ d="m 377.98388,200 -1.25,0 0,-1 1.25,0 0,1 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23168"
+ transform="translate(-315.95126,25)">
+ <rect
+ y="195"
+ x="382.95126"
+ height="16"
+ width="16"
+ id="rect23132"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01597308,0.03124949)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g10800"
+ style="display:inline">
+ <g
+ id="g10802"
+ transform="matrix(-1,0,0,1,762.9688,2.086163e-7)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ style="fill:url(#linearGradient15683);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 365.53351,198.46875 -1,0 0,9 1,0 5,-3.75 0,3.75755 1,0 5.00539,-3.71875 0,3.71875 1.99461,0 0,-9 -1.99461,0 0,3.71875 -5.00539,-3.71875 -1,0 0,3.74245 -5,-3.75 z"
+ id="path10804"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path10806"
+ d="m 369.28351,202.71875 -3.5,-2.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 375.28351,202.71875 -3.5,-2.75"
+ id="path10808"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path10986"
+ d="m 377.03351,199.9763 1.25,0 0,-1 -1.25,0 0,1 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path10810"
+ d="m 385.18529,206.7263 0,-7.5"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23154"
+ transform="translate(-317,25)">
+ <rect
+ y="195"
+ x="343"
+ height="16"
+ width="16"
+ id="rect23128"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g10812"
+ transform="matrix(-2.196282,0,0,1.316799,1208.5661,-118.9575)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ style="color:#000000;fill:url(#linearGradient37396-1);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.58802557px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 392.96689,239.5639 -0.56915,0 -4.43932,4.36665 0,1.13912 4.43932,4.36665 0.56915,0 0,-9.87242 0,0 0,0 z"
+ id="path10814"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient11766);stroke-width:0.58802563px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.51157,248.2972 0,-7.97389 -4.09783,3.98695"
+ id="path10816"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23136"
+ transform="translate(-194,25)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23134"
+ width="16"
+ height="16"
+ x="283"
+ y="195" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g10818"
+ style="display:inline">
+ <g
+ id="g10820"
+ transform="translate(0,8)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ ry="1.9320945"
+ rx="0"
+ y="286.5"
+ x="189.49994"
+ height="3"
+ width="11.000029"
+ id="rect10822"
+ style="fill:url(#linearGradient15687);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path10824"
+ d="m 287.5,199.27782 0,-8.77775 1,-7e-5"
+ style="fill:none;stroke:url(#linearGradient15689);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(6,8)"
+ id="g10826">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:url(#linearGradient15691);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect10828"
+ width="11.000029"
+ height="3"
+ x="189.49994"
+ y="286.5"
+ rx="0"
+ ry="1.9320945"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:url(#linearGradient15693);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 287.5,199.27782 0,-8.77775 1,-7e-5"
+ id="path10830"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23146"
+ transform="translate(-318,25)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23126"
+ width="16"
+ height="16"
+ x="323"
+ y="195" />
+ <g
+ style="display:inline"
+ id="g11898"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.714947,0,0,0.714947,237.35342,27.84315)">
+ <g
+ style="display:inline"
+ id="g11900"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11903"
+ style="fill:url(#linearGradient13543);fill-opacity:1;fill-rule:nonzero;stroke:#552200;stroke-width:1.77777624;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.847956,0,0,0.858716,59.65221,121.6111)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g11905"
+ style="fill:none;stroke:url(#linearGradient15878);stroke-width:1.65010214;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.780492,0,0,0.786646,68.5413,130.1431)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient13545);stroke-width:2.28401804;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path11907"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g24423">
+ <rect
+ y="220"
+ x="131"
+ height="16"
+ width="16"
+ id="rect23008"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ transform="translate(-71.046377,45.90625)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g11015">
+ <path
+ style="fill:url(#linearGradient15744);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 205.54638,177.59375 -1,0 0,9 1,0 5,-3.75 0,3.75 1,0 5,-3.75 0,-1.5 -5,-3.75 -1,0 0,3.75 -5,-3.75 z"
+ id="path11017"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path11019"
+ d="m 205.54638,185.34375 0,-6.5 4.25,3.25"
+ style="fill:none;stroke:url(#linearGradient10982);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient10984);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 211.54638,185.34375 0,-6.5 4,3"
+ id="path11021"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g23235"
+ transform="translate(-74,46)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23226"
+ width="16"
+ height="16"
+ x="184"
+ y="174" />
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1,0,0,1,402.07862,-0.09375)"
+ id="g11023">
+ <path
+ id="path11025"
+ d="m 205.57862,177.59375 -1,0 0,9 1,0 5,-3.75 0,3.75 1,0 5,-3.75 0,-1.5 -5,-3.75 -1,0 0,3.75 -5,-3.75 z"
+ style="fill:url(#linearGradient15746);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 209.57862,181.84375 -4,-3"
+ id="path11027"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path11029"
+ d="m 215.57862,181.84375 -4,-3"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23738"
+ transform="matrix(0.9375966,0,0,0.937515,141.13219,-26.987026)"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ <g
+ transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)"
+ id="g23740"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ <g
+ transform="translate(-1.863085e-7,0.53333)"
+ id="g23742"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ <g
+ transform="translate(0.533324,-1.066663)"
+ id="g23744"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect10527"
+ width="16"
+ height="16"
+ x="131"
+ y="31" />
+ <g
+ style="display:inline"
+ id="g10530"
+ transform="matrix(1.1658027,0,0,1.1657997,-11.289717,-221.05607)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ transform="matrix(0.629932,0,0,0.6236653,45.764188,149.53247)"
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:none;stroke:#ffffff;stroke-width:5.47410154;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path23603"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10532"
+ style="fill:none;stroke:#000000;stroke-width:2.25806689;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.629932,0,0,0.6236653,45.764188,149.53247)" />
+ <g
+ id="g11317">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient11333);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.6060524;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path11331"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.5326189,-0.05995148,0.06070777,-0.5287352,192.0574,293.4132)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10536"
+ style="fill:none;stroke:url(#linearGradient10540);stroke-width:1.78041101;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4812861,0,0,0.4822895,65.395173,166.1609)" />
+ </g>
+ </g>
+ <g
+ id="g16279"
+ transform="translate(318,7.00009)" />
+ <g
+ id="g28089"
+ transform="translate(0,2)">
+ <rect
+ y="260"
+ x="-315"
+ height="16"
+ width="16"
+ id="rect16267"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ <g
+ id="g28079">
+ <g
+ id="g51539"
+ style="opacity:0.4">
+ <path
+ id="path51537"
+ d="m 300.5,270.5 5,4 0,1 2,0 0,-1 6,-4 1,0 0,-2 -2,0 0,1 -11,0 0,-1 -2,0 0,2 1,0 z"
+ style="fill:#ffffff;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccc"
+ d="m 299.5,268.5 0,2 2,10e-6 0,-2 -2,-10e-6 z m 13,0 0,2 2,10e-6 0,-2 -2,-10e-6 z m -7,4.99999 0,2 2,10e-6 0,-2 -2,-10e-6 z m 7,-3.99999 -11,0 m -0.75,1 4.75,3.878 m 2.08359,0.122 5.66641,-4"
+ style="fill:none;stroke:url(#linearGradient28077);stroke-width:0.99999952;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path16283"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g28004"
+ transform="translate(501,-139)">
+ <path
+ id="path16269"
+ d="m -200,401 12,0 -6.4,7.99999 L -200,401 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#162d50;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path16271"
+ d="m -199.75,401 11.75,0 -6.5,7.99999 L -199.75,401 z"
+ style="fill:url(#linearGradient28057);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path16273"
+ d="m -189.5,401.5 -9.25,0 4.25,6.5"
+ style="opacity:0.87999998;fill:none;stroke:url(#linearGradient22970);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="rect16275"
+ width="2.0172491"
+ height="2.0328345"
+ x="-201.51724"
+ y="399.46716" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="rect16285"
+ width="2.0172396"
+ height="2.0000157"
+ x="-195.5"
+ y="408.49997" />
+ <rect
+ y="399.49997"
+ x="-188.51724"
+ height="2.0000157"
+ width="2.0172396"
+ id="rect16287"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g16397"
+ transform="matrix(1.045454,0,0,1.0610941,-16.32706,109.05266)"
+ style="opacity:0.45"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g16403"
+ transform="matrix(1.000037,0,0,1.0187902,152.96764,39.785579)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.9375,0,0,0.9375,192.125,77.25821)"
+ id="g16405"
+ style="display:inline">
+ <g
+ id="g16407"
+ style="fill:#000000;fill-opacity:1"
+ transform="matrix(1,0,0,1.037041,0,-6.074721)" />
+ <g
+ transform="translate(-84.26666,-72.24656)"
+ id="g16409">
+ <g
+ transform="translate(1.070738,1.59725)"
+ id="g16411">
+ <g
+ id="g16413"
+ transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)">
+ <g
+ id="g16415"
+ transform="translate(-1.863085e-7,0.53333)">
+ <g
+ id="g16417"
+ transform="translate(0.533324,-1.066663)" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g16419"
+ transform="matrix(0.903797,0,0,0.872724,-4.64464,27.13735)" />
+ <g
+ id="g16421" />
+ </g>
+ </g>
+ <g
+ id="g16425"
+ transform="matrix(1.000872,0,0,1.0462972,140.88404,50.499099)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g28330"
+ transform="translate(315.99999,18.99998)" />
+ <g
+ id="g28446"
+ transform="translate(0,-18.999939)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28314"
+ width="16"
+ height="16"
+ x="-293.99997"
+ y="280.99994"
+ transform="scale(-1,1)" />
+ <g
+ id="g28424">
+ <g
+ id="g28320"
+ transform="translate(318.99999,17.49994)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient24395);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -33,272.25 0,-7 6,2.75 0,7.25 -6,-3 z"
+ id="path28322"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28324"
+ d="m -33,272.25 0,-7 6,2.75 0,7.25 -6,-3 z"
+ style="fill:url(#linearGradient28532);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path28326"
+ d="m -27.25,274.75 0,-6.5 -5.5,-2.5 0,6.25"
+ style="fill:none;stroke:url(#linearGradient28530);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g28414"
+ style="opacity:0.8"
+ transform="translate(0.25,0.25)">
+ <path
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 280,285.25 5.5,-2.5"
+ id="path28410"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path28376"
+ d="m 280,285.25 5.5,-2.5"
+ style="fill:none;stroke:#ffc655;stroke-width:1px;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.6"
+ id="g28418"
+ transform="translate(0,-7.5)">
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 286.5,296 5.5,-3"
+ id="path28420"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path28422"
+ d="m 286.5,296 5.5,-3"
+ style="fill:#ff8080;fill-rule:evenodd;stroke:#ffc655;stroke-width:1px;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:#0b1728;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 279.99999,292.9999 0,-7 6,2.75004 0,7.25 -6,-3.00004 z"
+ id="path28328"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g28402"
+ style="opacity:0.8">
+ <path
+ id="path28398"
+ d="m 286.5,296 5.5,-3"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ff8080;fill-rule:evenodd;stroke:#ffc655;stroke-width:1px;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;display:inline"
+ d="m 286.5,296 5.5,-3"
+ id="path28374"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-161.00001,168.99994)"
+ id="g28338">
+ <g
+ id="g28340">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path28342"
+ d="m 441,123.99996 0,-7 6,2.75004 0,7.25 -6,-3.00004 z"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#162d50;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path28344"
+ d="m 441.00001,124.00006 0,-7 6,2.74994 c 0,2.37037 0,6.72971 0,7.25 l -6,-2.99994 z"
+ style="fill:url(#linearGradient28474);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.09488797;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#22467e;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 441,117 0,2.25 2,0 0,-1.25 -2,-1 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,1.25 2,1 0,-2.25 -2,0 z m -2,-2 0,-2 -2,0 0,2 2,0 z"
+ id="path28346"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path28348"
+ d="m 446.75,126.5 0,-6.5 -5.5,-2.5 0,6.25 5.5,2.75 z"
+ style="fill:none;stroke:url(#linearGradient28528);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g12156"
+ transform="translate(-130.97687,-108)" />
+ <g
+ transform="translate(-517,612.99998)"
+ id="g12564"
+ style="display:inline">
+ <rect
+ y="-183"
+ x="543"
+ height="16"
+ width="16"
+ id="rect12566"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g12568">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12570"
+ width="2.9998772"
+ height="3"
+ x="554.50031"
+ y="-181.49998"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12572"
+ d="m 546.00017,-179.49999 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:#2b1600;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-181.49998"
+ x="544.50043"
+ height="3"
+ width="2.9998772"
+ id="rect12574"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12576"
+ width="2.9998772"
+ height="3"
+ x="549.5"
+ y="-171.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ style="fill:none;stroke:#ffad55;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 546.00017,-179.53678 5,9.5 5,-9.5 -10,0 z"
+ id="path12578"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12580"
+ d="m 557.00046,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 552.00029,-170.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12582"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 547.00059,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12584"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12586"
+ d="m 546.00017,-179.53678 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:url(#linearGradient12602);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 555.5,-179.5 0,-1 1,0"
+ id="path12588"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path12590"
+ d="m 545.5,-179.5 0,-1 1,0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 550.5,-169.5 0,-1 1,0"
+ id="path12592"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 555,-180.34409 -0.96003,1e-5 0,2.34418 2.21003,-1e-4 0.36569,-1 -1.61569,0 0,-1.34409 z"
+ id="path12594"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 552,-172 c -0.65334,0 -1.30669,1e-5 -1.96003,1e-5 0,0.33321 0,0.66641 0,0.99963 0.65334,0 1.30669,0 1.96003,0 0,-0.33322 0,-0.66643 0,-0.99964 z"
+ id="path12596"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12598"
+ d="m 547.03997,-180.34409 0.96003,1e-5 0,2.34418 -0.96003,-1.0001 0,-1.34409 z"
+ style="opacity:0.2;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 545.65591,-179 1e-5,0.96003 2.34418,0 L 547,-179 l -1.34409,0 z"
+ id="path12600"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-537,592)"
+ id="g12618"
+ style="display:inline">
+ <rect
+ y="-183"
+ x="563"
+ height="16"
+ width="16"
+ id="rect12620"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g12622">
+ <g
+ transform="translate(476.04566,-283.51773)"
+ id="g12624"
+ style="opacity:0.7">
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.95451,104.01774 5,9.5 5,-9.5 -10,0 z"
+ id="path12626"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12628"
+ d="m 89.95451,103.98095 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12630"
+ width="2.9998772"
+ height="3"
+ x="574.50031"
+ y="-181.49998"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-181.49998"
+ x="564.50043"
+ height="3"
+ width="2.9998772"
+ id="rect12632"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12634"
+ width="2.9998772"
+ height="3"
+ x="569.5"
+ y="-171.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12636"
+ d="m 577.00046,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 572.00029,-170.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12638"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 567.00059,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12640"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ transform="scale(1,-1)"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12777"
+ width="16"
+ height="16"
+ x="26"
+ y="-446" />
+ <g
+ id="g12053"
+ transform="translate(-21,128)">
+ <rect
+ y="302"
+ x="-231"
+ height="16"
+ width="16"
+ id="rect12012"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ <g
+ id="g12045">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.9;fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#2b1600;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-2.75 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ id="path12014"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12016"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-3.25 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ style="opacity:0.95;fill:#ff9f37;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.75;fill:url(#radialGradient12116);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-3.25 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ id="path12020"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12018"
+ d="m 218,313.25 c -0.99997,-6.5 5.99997,-3.25 4.99994,-9.25 l 5.00003,2 c 1,7 -6,2 -5,10 L 218,313.25 z"
+ style="opacity:0.7;fill:url(#linearGradient12114);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient12118);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 223.24994,304.5 4.25003,1.75 c 1,5.75 -5.50003,2 -5.08025,8.84783 l -4.04773,-2.23212"
+ id="path12022"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12024"
+ d="m 223.24994,304.5 4.25003,1.75"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g12219"
+ transform="translate(-20.999998,128)">
+ <rect
+ transform="scale(-1,1)"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12147"
+ width="16.000032"
+ height="16"
+ x="-231.00003"
+ y="281" />
+ <g
+ transform="translate(235.00016,-1)"
+ id="g12149">
+ <g
+ id="g12151"
+ transform="translate(-376,510)"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12153"
+ d="m 358.99997,-216.75 c -0.99997,-6.5 6.00003,-2.75 5,-9.25 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path12155"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.7;fill:url(#linearGradient12213);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path12157"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12159"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="opacity:0.75;fill:url(#radialGradient12215);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path12161"
+ d="m 364.24984,-225.5 4.25016,1.75 c 1,5.75 -5.50003,2 -5.08381,8.85761 l -4.04561,-2.26888"
+ style="fill:none;stroke:url(#linearGradient12217);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 364.24997,-225.5 4.25003,1.75"
+ id="path12163"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-399.2499,383.75)"
+ id="g12165">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12167"
+ width="2.9998772"
+ height="3"
+ x="391.75"
+ y="-99.25"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 394.24987,-98.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12169"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g12171"
+ transform="translate(-406.2499,380.75)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-98.25"
+ x="392.74988"
+ height="3"
+ width="2.9998772"
+ id="rect12173"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12175"
+ d="m 395.24974,-97.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.666663 0,1.333317 0,1.99999 0.66668,0 1.33333,-1e-5 2,-1e-5 0,-0.666663 0,-1.333327 0,-1.99999 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -11.00003,286 c -0.66668,0 -1.33332,0 -2,0 0,-0.33334 0,-0.66666 0,-1 0.66668,0 1.33332,0 2,0 0,0.33334 0,0.66667 0,1 z"
+ id="path12177"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12179"
+ d="m -7.00003,285.53933 c -0.33334,0 -0.66666,10e-6 -1,10e-6 0,0.82281 0,1.64561 0,2.46844 0.33334,0 0.66666,-1e-5 1,-1e-5 0,-0.82282 0,-1.64562 0,-2.46844 l 0,0 0,0 0,0 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12187"
+ d="m -9.972188,286 c -0.342621,0 -0.685221,0 -1.027842,0 0,-0.66873 0,-1.33742 0,-2.00616 0.342621,0 0.685221,0 1.027842,0 0,0.66874 0,1.33745 0,2.00616 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -6.000162,287 c -0.33334,0 -0.66666,0 -1,0 0,0.33428 0,0.66856 0,1.00284 0.33334,0 0.66666,0 1,0 0,-0.33428 0,-0.66856 0,-1.00284 z"
+ id="path12239"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g12249"
+ style="opacity:0.65;display:inline"
+ transform="translate(-98,462.06404)" />
+ <g
+ style="display:inline"
+ transform="translate(-53.00012,422.06403)"
+ id="g12255" />
+ <g
+ transform="translate(-98,483.06404)"
+ style="opacity:0.65;display:inline"
+ id="g12325" />
+ <g
+ id="g12327"
+ transform="translate(-53.00012,443.06403)"
+ style="display:inline" />
+ <g
+ id="g24293"
+ transform="translate(0,2)">
+ <rect
+ y="260"
+ x="257"
+ height="16"
+ width="16"
+ id="rect28219"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999875;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24279">
+ <rect
+ transform="matrix(1,5.257811e-6,0,1,0,0)"
+ y="261.49863"
+ x="258.5"
+ height="7.007431"
+ width="6.9999733"
+ id="rect28121"
+ style="fill:url(#linearGradient24272);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g12274"
+ transform="translate(6.2265309e-7,0.00746971)">
+ <g
+ style="opacity:0.4"
+ id="g11480"
+ transform="matrix(1,0,0,-0.985055,81.000076,281.63418)">
+ <rect
+ transform="matrix(1,-5.3375811e-6,0,-1,0,0)"
+ y="-14.357183"
+ x="183.49992"
+ height="7.1213336"
+ width="7.000011"
+ id="rect11482"
+ style="fill:url(#linearGradient12305);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00755596;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.00755763px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 184.49992,8.2651727 0,5.0306663 5,0.04519"
+ id="path11484"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-0.985055,78.000075,278.62671)"
+ id="g11472">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:url(#linearGradient12307);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.90680158;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect11474"
+ width="6.9999948"
+ height="7.1137514"
+ x="183.49992"
+ y="-14.349599"
+ transform="matrix(1,-5.3375811e-6,0,-1,0,0)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path11476"
+ d="m 184.49993,8.3103653 -1e-5,5.0230827 5,0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.00755763px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:url(#linearGradient24277);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect24275"
+ width="6.8437233"
+ height="6.8198147"
+ x="258.65625"
+ y="261.68613"
+ transform="matrix(1,5.257811e-6,0,1,0,0)" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24268);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 259.5,267.5 0,-5 5,0 0,5 -5,0 z"
+ id="path28123"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path12295"
+ d="m 266.5,265.5 0,3.94801 -4,0"
+ style="opacity:0.2;fill:none;stroke:#162d50;stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ ry="0"
+ rx="0.80014729"
+ y="73"
+ x="257"
+ height="16"
+ width="16"
+ id="rect11420"
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g16042"
+ transform="translate(-147,2)">
+ <path
+ style="fill:url(#linearGradient16039);fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 412,73.5 c -4.5,0 -7.25,0.75 -5.75,2.5 l 4.25,4.5 0,6.25 3,-2 0,-4.25 c 1.48333,-1.72541 2.75638,-2.81017 4.25,-4.5 1.5,-1.75 -1.25,-2.5 -5.75,-2.5 z"
+ id="path11422"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#radialGradient16034);fill-opacity:1;stroke:url(#linearGradient16036);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 418.24999,74.499997 c -0.005,1.49998 -1.49999,2.000009 -6.25,2.000009 -4.74999,0 -6.25738,-0.500029 -6.24999,-2.000009 0.005,-1.000014 1.5,-1.999986 6.24999,-1.999986 4.75001,0 6.24506,0.999972 6.25,1.999986 z"
+ id="path11424"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path11426"
+ d="m 410.89062,80.47656 0,5.75 2.20704,-1.585938 0,-4.164062 -0.40829,0 -1.79875,0 z"
+ style="fill:url(#linearGradient16031);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11428"
+ d="m 412.5,85.25 0,-4.25"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:0.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 406.5,75 c 0,-1.75 2.5,-1.5 5.5,-1.49999 3,1e-5 5.5,-0.25001 5.5,1.25001"
+ id="path12224"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path12211"
+ d="m 417.49999,74.50002 c 10e-6,1.74998 -1.4838,1.99999 -5.50001,1.99999 -4.01617,0 -5.49583,-0.50001 -5.49999,-1.99999 -0.004,-1.50002 1.48382,-2.00001 5.49999,-2.00001 4.01621,0 5.49583,0.49999 5.50001,2.00001 z"
+ style="fill:none;stroke:url(#linearGradient16027);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 411.27412,80.5 2.13816,0"
+ id="path12238"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g11534"
+ transform="translate(21,-1)" />
+ <g
+ id="g17375"
+ transform="translate(10.000031,192.5)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\Browser icons ver 1\font_file SMALL.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect17377"
+ width="16"
+ height="16"
+ x="162.99997"
+ y="237.5" />
+ <g
+ transform="translate(73,-319.5)"
+ id="g17379"
+ style="fill:#ffcc00;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline">
+ <path
+ style="fill:none;stroke:#2b1600;stroke-width:1.20000005;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ transform="translate(262.99997,326)"
+ id="rect17381"
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#ffcc00;display:inline"
+ id="g17395"
+ transform="translate(73,-319.5)">
+ <path
+ style="fill:url(#linearGradient13699)"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ id="rect17397"
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ transform="translate(262.99997,326)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.85;fill:#ffffff;display:inline"
+ d="m 198,304 0,1 0.5,0 0,-1 -0.5,0 z m 1,1 0,10 0.65625,0 0,-10 L 199,305 z m 7,0 0,1 0.5,0 0,-1 -0.5,0 z m -2,4 0,1 0.5,0 0,-1 -0.5,0 z m 0,2 0,1 0.5,0 0,-1 -0.5,0 z m -6,4 0,1 0.5,0 0,-1 -0.5,0 z"
+ id="path17411"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ transform="translate(-31.000031,-64.5)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g31245"
+ transform="matrix(0.425032,0.424791,0.425032,-0.424791,-342.55466,249.47119)"
+ style="display:inline" />
+ <g
+ transform="translate(-157,15.000007)"
+ style="opacity:0.5"
+ id="g13244" />
+ <g
+ id="g13375"
+ style="opacity:0.3"
+ transform="translate(-177.01509,15.000007)" />
+ <g
+ id="g13383"
+ style="opacity:0.5"
+ transform="translate(-143,15.000007)" />
+ <g
+ id="g14144"
+ transform="translate(289,331.00001)">
+ <rect
+ y="183"
+ x="-158"
+ height="16"
+ width="16"
+ id="rect14146"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(36,0)"
+ id="g14148">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path14151"
+ d="m -187,192 4,-4"
+ style="fill:none;stroke:#162d50;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m -191,198 0.76562,0.21876 4.73438,-4.71876 0,-3 -3,0 -4,4 -0.75,0.75 0.25,0.75 2,2 z"
+ style="fill:url(#linearGradient14167);fill-opacity:1;fill-rule:evenodd;stroke:#162d50;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path14153"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path14155"
+ d="m -190.5,197.5 -2,-2"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ id="path14157"
+ d="m -179.48388,187.51562 c 2.75,-1.75 -1.25,-5.75 -3,-3 L -183,186.5 l -1.48388,0.0156 -0.26612,0.73438 -0.73388,0.26562 0.98388,-0.0156 0,1 1,1 1,0 0.0161,1.01562 0.23388,-0.76562 0.76612,-0.23438 L -181.5,188 l 2.01612,-0.48438 z"
+ style="fill:url(#linearGradient14169);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient14171);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -186.5,191.5 2,-2"
+ id="path14159"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient14173);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -180,187.5 c 2.49911,-1.20238 -0.79146,-5.05796 -2.25,-2.75 l -0.75,1.75 -1.25,0.25 -0.75,0.75 2.75,2.75 0.75,-1 0,-1.25 1.5,-0.5 z"
+ id="path14161"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path14163"
+ d="M -180.23388,184.53124 C -181.75937,183.83967 -182,185 -182.5,186.75 l -1.98388,0.53124"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -192.5,195.5 4.26612,-4.23438 1.75,0 2,-2"
+ id="path14165"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="matrix(-1.0226846,0,0,1.0218469,-86.775576,130.3547)"
+ id="g17210">
+ <g
+ id="g17212"
+ transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)">
+ <g
+ id="g17214"
+ transform="translate(-1.863085e-7,0.53333)">
+ <g
+ id="g17216"
+ transform="translate(0.533324,-1.066663)" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g13705"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17322"
+ width="16"
+ height="16"
+ x="47"
+ y="29" />
+ <g
+ transform="translate(116,-325)"
+ id="g17324">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path17326"
+ d="m -55,358.25 -6,-2.25 -6,2.25 0,7.5 6,3.25 6,-3.25 0,-7.5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path17328"
+ d="m -55,365.75 0,-7.5 -6,2.75 c 0,2.58363 8.34e-4,7.47325 8.34e-4,8.04035 L -55,365.75 z"
+ style="fill:url(#linearGradient17337);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -67,365.75 0,-7.5 6,2.75 8.34e-4,8.04035 L -67,365.75 z"
+ id="path17330"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path17332"
+ d="m -67,358.25 6,-2.25 6,2.25 -6,2.75 -6,-2.75 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17339);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -66.499841,365.52276 -66.5,358.5 l 5.5,-2 5.5,2 0,7 -5.5,3 -5.499841,-2.97724 z"
+ id="path17334"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g17610"
+ transform="translate(-20.999893,190.97867)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="281.02133"
+ x="193.99989"
+ height="16"
+ width="16"
+ id="rect17612"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17614">
+ <rect
+ y="285.52133"
+ x="198.49976"
+ height="2"
+ width="8"
+ id="rect17616"
+ style="fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(191.9999,212.02134)"
+ id="g17618"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient17656);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 16.499049,83.47866 -12.999056,0 -10e-8,-12.97866 13.0114221,0 -0.01237,12.97866 4e-6,0 z"
+ id="path17620"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17622"
+ width="8"
+ height="2"
+ x="198.49976"
+ y="289.52136" />
+ <rect
+ y="283"
+ x="195.99989"
+ height="12"
+ width="12.000107"
+ id="rect17624"
+ style="opacity:0.1;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17626"
+ transform="translate(-31.00024,484.0498)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 237.5,-198.52846 0,1 -8.99987,0"
+ id="path17628"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path17630"
+ d="m 228.55567,-198.51423 8.88878,0"
+ style="fill:none;stroke:#4d4d4d;stroke-width:0.99999994px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g17632"
+ transform="translate(-16.999997,0.9739989)">
+ <rect
+ transform="scale(-1,1)"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:evenodd;stroke:#5f8dd3;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17634"
+ width="2"
+ height="3.0120413"
+ x="-253.5"
+ y="-200.474" />
+ <path
+ id="path17636"
+ d="m 251.49999,-197.47154 2,0 0,-3"
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 251.99999,-196.47154 2.5,0 0,-3.5"
+ id="path17638"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g17640"
+ transform="translate(-31.00024,484.0498)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17642"
+ d="m 237.5,-192.60425 0,1 -8.99987,0.026"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 228.50013,-192.60425 8.99987,0.026"
+ id="path17644"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g17646"
+ transform="translate(-19.014593,0.97154)">
+ <rect
+ y="-194.51543"
+ x="-251.5"
+ height="2.9940825"
+ width="2.0000002"
+ id="rect17648"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:evenodd;stroke:#5f8dd3;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ <path
+ id="path17650"
+ d="m 249.49999,-191.52134 2,0 0,-3"
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17652"
+ d="m 250.01459,-190.52134 2.5,0 0,-3.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path17654"
+ d="m 196.4999,294.5 0.0303,-11 11.01349,0 -0.0303,11 -11.01349,0 z"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient17658);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g13494"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(0,128.00001)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#e6e6e6;fill-opacity:0.23529412;fill-rule:nonzero;stroke:none"
+ id="rect16876"
+ width="8.0127983"
+ height="8.012805"
+ x="260.99997"
+ y="473.98718"
+ ry="0.4193894"
+ rx="0.4193894" />
+ <rect
+ ry="0.82841855"
+ y="473.48724"
+ x="260.50003"
+ height="9.0127392"
+ width="9.0127354"
+ id="rect16878"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient12658);stroke-width:1.00002468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ rx="0.82841796" />
+ <rect
+ rx="0.80560946"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient12655);stroke-width:1.00002468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect16880"
+ width="9.0127354"
+ height="9.0127392"
+ x="-269.51276"
+ y="-482.5"
+ ry="0.83038348"
+ transform="scale(-1,-1)" />
+ </g>
+ <g
+ id="g28870"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g13494.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(0,128.00001)">
+ <g
+ transform="translate(20.999991,0)"
+ id="g13503">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#e6e6e6;fill-opacity:0.23529412;fill-rule:nonzero;stroke:none"
+ id="rect13505"
+ width="8.0127983"
+ height="8.012805"
+ x="260.99997"
+ y="473.98718"
+ ry="0.4193894"
+ rx="0.4193894" />
+ <rect
+ ry="0.82841855"
+ y="473.48724"
+ x="260.50003"
+ height="9.0127392"
+ width="9.0127354"
+ id="rect13507"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient13511);stroke-width:1.00002468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ rx="0.82841796" />
+ <rect
+ rx="0.80560946"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient13513);stroke-width:1.00002468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect13509"
+ width="9.0127354"
+ height="9.0127392"
+ x="-269.51276"
+ y="-482.5"
+ ry="0.83038348"
+ transform="scale(-1,-1)" />
+ </g>
+ <path
+ d="m 283.5,478.5 1.99999,2 m 3.75,-4.75 c -1.28654,1.14367 -2.78042,2.75628 -3.75,4.75"
+ style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ id="path16507"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(135,508.00993)"
+ id="g13515"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect13517"
+ width="16"
+ height="16"
+ x="143"
+ y="111" />
+ <g
+ id="g13519">
+ <path
+ sodipodi:type="arc"
+ style="fill:#e6e6e6;fill-opacity:0.25490196;fill-rule:nonzero;stroke:none;display:inline"
+ id="path13521"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="2.7944512"
+ sodipodi:ry="2.7944512"
+ d="m 333.29445,35.5 a 2.7944512,2.7944512 0 1 1 -5.5889,0 2.7944512,2.7944512 0 1 1 5.5889,0 z"
+ transform="matrix(1.4256767,0,0,1.4314068,-320.1963,68.175135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient13527);stroke-width:0.77606368;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path13523"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(1.2885487,0,0,1.2885617,-274.87525,73.246084)" />
+ <path
+ transform="matrix(-1.288521,0,0,-1.2885339,576.8463,164.73299)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path13525"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient13529);stroke-width:0.77608043;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path15120"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.8543143,0,0,0.8543231,3.66123,596.67148)" />
+ <g
+ id="g18811"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18695"
+ width="16"
+ height="16"
+ x="236"
+ y="260" />
+ <g
+ id="g18697"
+ transform="translate(-86,370.75)">
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 330,-107.75 -5,2 0.0372,6.324398 5,2.71875 4.99999,-2.71875 L 335,-105.75 l -5,-2 z"
+ id="path18699"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18719"
+ d="m 330.03717,-107.6131 -5,1.875 0,6.312498 5,2.71875 4.99999,-2.71875 0,-6.312498 -4.99999,-1.875 z"
+ style="fill:url(#linearGradient18721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18703"
+ transform="translate(179,-179)">
+ <path
+ id="path18707"
+ d="m 146.0019,73.295281 5,-1.894157 5,1.894157 -5,2.073959 -5,-2.073959 z"
+ style="fill:url(#linearGradient18728);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path18763"
+ d="m 335,-105.5 -5,2 0,6.75 5,-2.75 0,-6 z"
+ style="fill:url(#linearGradient18765);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path18709"
+ d="m 334.5,-105.25 0.002,5.587357 -4.5,2.480073 -4.5,-2.480073 -0.002,-5.587357 4.5,-1.75 4.5,1.75 z"
+ style="fill:none;stroke:url(#linearGradient18712);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18758"
+ style="opacity:0.8;fill:none;stroke:#d7e3f4;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 330.25,-103.25 3.25,-1.5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18737"
+ style="opacity:0.7" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="M 330.25,-103.25 335,-105.5"
+ style="fill:#0b1728;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18760"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g14548"
+ transform="translate(0,23)">
+ <rect
+ y="239"
+ x="152"
+ height="16"
+ width="16"
+ id="rect14326"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g14538">
+ <path
+ sodipodi:nodetypes="css"
+ id="path14330"
+ d="m 155.51612,249.67445 c 0,3.70073 8,3.70073 8,0 0,-2.71386 -4,-1.727 -4,-5.67444"
+ style="fill:none;stroke:#0b1728;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.8675713,0,0,-1.199958,80.598976,391.9948)"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
+ sodipodi:ry="1.25"
+ sodipodi:rx="1.75"
+ sodipodi:cy="125"
+ sodipodi:cx="91.5"
+ id="path14332"
+ style="fill:#e6e6e6;fill-opacity:1;stroke:#0b1728;stroke-width:2.74424219;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient14568);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 155.51612,249.75002 c 0,3.75 8,3.75 8,0 0,-2.75 -4,-1.75 -4,-5.75"
+ id="path14334"
+ sodipodi:nodetypes="css"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;stroke:url(#linearGradient14570);stroke-width:1.28417933;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path14336"
+ sodipodi:cx="91.5"
+ sodipodi:cy="125"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.25"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
+ transform="matrix(0.8540253,0,0,-1.199954,81.814709,391.9942)" />
+ <path
+ transform="matrix(0.8540253,0,0,-1.199954,81.814709,391.9942)"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
+ sodipodi:ry="1.25"
+ sodipodi:rx="1.75"
+ sodipodi:cy="125"
+ sodipodi:cx="91.5"
+ id="path14338"
+ style="fill:none;stroke:url(#linearGradient14572);stroke-width:1.28417933;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ sodipodi:type="arc" />
+ <rect
+ y="241"
+ x="158.99884"
+ height="2"
+ width="2.0011597"
+ id="rect14340"
+ style="opacity:0.75;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cs"
+ id="path14342"
+ d="m 155.95084,249.59135 c 0,3.34488 7.13055,3.34488 7.13055,0"
+ style="opacity:0.45;fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(349,127.99988)"
+ id="g26256">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26258"
+ width="16"
+ height="16"
+ x="-29"
+ y="491.00012" />
+ <g
+ id="g26260">
+ <g
+ id="g26262">
+ <path
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26264"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26266"
+ style="fill:none;stroke:#28170b;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path26268"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -9.5,6 6,-6"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26270"
+ style="fill:none;stroke:url(#linearGradient26282);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -27.5,502.5 l 6,-6 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient26284);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26272"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path26274"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
+ <path
+ transform="matrix(2,0,0,2,-46,385)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26276"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient26286);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26278"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -7.704183,9.08552 4.25,-4.25 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient26288);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path26280"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g15201"
+ transform="translate(0,128.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15183"
+ width="16"
+ height="16"
+ x="215"
+ y="365" />
+ <g
+ id="g15185"
+ transform="translate(167.99999,-62.999991)">
+ <rect
+ y="429.54614"
+ x="48.499996"
+ height="12.953857"
+ width="13.016124"
+ id="rect15187"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <rect
+ ry="0"
+ style="fill:url(#linearGradient15195);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15189"
+ width="11.000001"
+ height="11.046139"
+ x="50.016117"
+ y="430" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ id="path15191"
+ d="m 49,430 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m 3,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ style="fill:url(#linearGradient15209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15193"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ style="fill:none;stroke:url(#linearGradient15211);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-174.00091,22.99815)"
+ id="g15532" />
+ <g
+ id="g15356"
+ transform="translate(-21,128.00001)">
+ <rect
+ y="344"
+ x="89"
+ height="16"
+ width="16"
+ id="rect15319"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g15351">
+ <rect
+ y="345.50153"
+ x="90.5"
+ height="12.998481"
+ width="13"
+ id="rect15323"
+ style="fill:url(#linearGradient15363);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15326"
+ d="m 91.499805,357.49999 0,-10.99829 11.000195,0 0,10.99829 -11.000195,0 z"
+ style="fill:none;stroke:url(#linearGradient15365);stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cszzcc"
+ id="path15332"
+ d="m 103.5,353.27516 c -0.37083,-1.1875 -1.21031,-1.72293 -1.9,-1.72929 -1.39235,-0.0134 -1.47709,3.98814 -2.999997,4 -1.491657,0.0119 -2.001315,-7 -3.5,-7 -1.52993,-10e-4 -1.18608,5.00645 -3.5,4.97929 l -1,0"
+ style="fill:none;stroke:url(#linearGradient15367);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\Browser icons ver 1\font_file SMALL.png"
+ transform="translate(-73.999969,234.50001)"
+ id="g15369">
+ <rect
+ y="237.5"
+ x="162.99997"
+ height="16"
+ width="16"
+ id="rect15371"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <g
+ style="fill:#ffcc00;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline"
+ id="g15373"
+ transform="translate(73,-319.5)">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ id="path15375"
+ transform="translate(262.99997,326)"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(73,-319.5)"
+ id="g15377"
+ style="fill:#ffcc00;display:inline">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccc"
+ id="path15379"
+ transform="translate(262.99997,326)"
+ d="m -169,233 0,1 1,0 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-4 3,0 0,1 1,0 0,-3 -1,0 0,1 -3,0 0,-5 5,0 0,1 1,0 0,-2 -8,0 -1,0 z"
+ style="fill:url(#linearGradient15383)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="translate(-31.000031,-64.5)"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ id="path15381"
+ d="m 198,304 0,1 0.5,0 0,-1 -0.5,0 z m 1,1 0,10 0.65625,0 0,-10 L 199,305 z m 7,0 0,1 0.5,0 0,-1 -0.5,0 z m -2,4 0,1 0.5,0 0,-1 -0.5,0 z m 0,2 0,1 0.5,0 0,-1 -0.5,0 z m -6,4 0,1 0.5,0 0,-1 -0.5,0 z"
+ style="opacity:0.85;fill:#ffffff;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g14355"
+ transform="translate(0,128.00001)">
+ <rect
+ y="428"
+ x="68"
+ height="16"
+ width="16"
+ id="rect14357"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g14359"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(-15.161301,338)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="czszcccc"
+ id="path14368"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 86.5,100.53983 4.342131,0.008 c 5.188235,0.0101 5.335295,-2.04831 3.335293,-4.04831 -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 86.5,100.53983 4.342131,0.008 C 96.03037,100.55844 96.17743,98.5 94.177424,96.5 c -0.964875,-0.964875 -4.5,-4 1.500002,-5 M 88.840543,97.588774 86.5,100.53983 M 88.828993,103.5 86.5,100.53983"
+ style="fill:none;stroke:url(#linearGradient14377);stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path14375"
+ sodipodi:nodetypes="czszcccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-111.96756,-108)"
+ id="g15923">
+ <g
+ id="g15925" />
+ </g>
+ <g
+ transform="translate(189.19394,55.494451)"
+ id="g15616" />
+ <g
+ style="display:inline"
+ id="g16518"
+ transform="translate(0,64.000007)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16520"
+ width="16"
+ height="16"
+ x="110"
+ y="492"
+ rx="0"
+ ry="0" />
+ <g
+ id="g16522">
+ <rect
+ ry="1.7356256"
+ y="494.5"
+ x="110.5"
+ height="12"
+ width="15"
+ id="rect16524"
+ style="fill:url(#linearGradient16638);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.7356256" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path16527"
+ d="M 111,498.48148 111,504 c 0,0.56404 0.36784,1.00001 0.84375,1 l 12.3125,0 C 124.63216,505 125,504.56405 125,504 l 0,-5.51852 c -0.31371,0.37179 -0.76923,0.59259 -1.25,0.59259 l -11.5,0 c -0.48077,0 -0.93629,-0.2208 -1.25,-0.59259 z"
+ style="fill:url(#linearGradient16640);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.5817194"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16530"
+ width="15"
+ height="2"
+ x="110.5"
+ y="494.5"
+ ry="1" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16532"
+ width="15"
+ height="12"
+ x="110.5"
+ y="494.5"
+ ry="1.503511"
+ rx="1.503511" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.75859177;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path16535"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.3955004,0,0,1.2452423,11.18333,-121.72474)" />
+ <rect
+ rx="0.5078125"
+ ry="0.4910686"
+ y="495.5"
+ x="111.5"
+ height="10"
+ width="13.000001"
+ id="rect16537"
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(1.5770887,0,0,1.5999841,-3.50675,-301.69208)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path16540"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.62952667;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient16642);stroke-width:0.97061968;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path16542"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1794014,0,0,0.8999954,27.50686,48.952303)" />
+ <path
+ transform="matrix(1.1827463,0,0,1.2,27.245789,-99.900024)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path16544"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:0.83938956;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient16644);stroke-width:1.26754272;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path16546"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.790122,0,0,0.787736,57.870479,107.05649)" />
+ <g
+ id="g16548"
+ transform="matrix(0.7547901,0,0,1,59.021765,-1)">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#999999;stroke-width:2.89550138;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path16550"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.7901234,0,0,0.2000006,9.8760061,395.5997)" />
+ <path
+ sodipodi:nodetypes="csccc"
+ id="path16554"
+ d="m 69.505631,495.5 0,-0.50001 c 0,-0.276 0.896,-0.5 2,-0.5 1.104,0 2,0.224 2,0.5 l 0,0.50001"
+ style="fill:none;stroke:#000000;stroke-width:1.15103066;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16556"
+ width="2.6497433"
+ height="1"
+ x="70.189362"
+ y="495" />
+ </g>
+ <rect
+ y="496.5"
+ x="122"
+ height="1.5"
+ width="2"
+ id="rect16558"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#radialGradient16646);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16562"
+ width="2"
+ height="1.5"
+ x="122"
+ y="496.5" />
+ <rect
+ y="497"
+ x="115"
+ height="1"
+ width="1"
+ id="rect16564"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient16648);stroke-width:0.67151165;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path16566"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1827463,0,0,1.2,27.245789,-99.900024)" />
+ <path
+ transform="matrix(0.8888868,0,0,0.8862026,50.166822,57.626266)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path16568"
+ style="fill:url(#radialGradient16650);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path16570"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.1975308,0,0,0.1999991,103.0926,401.10045)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient32447);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32441"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-0.8867575,0.06148883,-0.06130315,-0.8840797,219.44126,941.51187)" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g21847"
+ transform="translate(24,422.99999)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21291"
+ width="16"
+ height="16"
+ x="464"
+ y="7"
+ rx="0"
+ ry="0" />
+ <g
+ id="g21822">
+ <rect
+ ry="1.5909902"
+ y="10.5"
+ x="465.5"
+ height="10"
+ width="12"
+ id="rect21295"
+ style="fill:url(#linearGradient21776);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5909902" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path21297"
+ d="m 465.46685,13.40909 0,4.59375 c 0,0.56244 0.34142,0.99717 0.78315,0.99716 l 10.5,0.01065 c 0.44173,0 0.78315,-0.43471 0.78315,-0.99716 l 0,-4.59375 c -0.29118,0.37073 -0.71398,0.59091 -1.16022,0.59091 L 466.62707,14 c -0.44624,0 -0.86904,-0.22018 -1.16022,-0.59091 l 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient21773);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.362712"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21299"
+ width="12"
+ height="2.0056314"
+ x="465.5"
+ y="10.494369"
+ ry="1.0028157" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21301"
+ width="12"
+ height="10"
+ x="465.5"
+ y="10.5"
+ ry="1.3782184"
+ rx="1.3782184" />
+ <rect
+ rx="0.39062494"
+ ry="0.44196323"
+ y="11.5"
+ x="466.5"
+ height="7.999999"
+ width="9.9998779"
+ id="rect21303"
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21305"
+ transform="matrix(0.7547901,0,0,1,414.01868,-484.99999)">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#999999;stroke-width:2.90780973;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21307"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)" />
+ <path
+ sodipodi:nodetypes="csccc"
+ id="path21309"
+ d="m 69.531013,495.51105 0,-0.50001 c 0,-0.276 0.890314,-0.5 1.987308,-0.5 1.096993,0 1.987307,0.224 1.987307,0.5 l 0,0.50001"
+ style="fill:none;stroke:#000000;stroke-width:1.15103066;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21311"
+ width="2.6497409"
+ height="1"
+ x="70.193451"
+ y="495.01105" />
+ </g>
+ <g
+ transform="matrix(1,0,0,0.6666667,331,-319.00002)"
+ id="g21313">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21315"
+ width="2"
+ height="1.5"
+ x="143"
+ y="496.5" />
+ <rect
+ y="496.5"
+ x="143"
+ height="1.5"
+ width="2"
+ id="rect21317"
+ style="fill:url(#radialGradient21741);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ y="13"
+ x="468"
+ height="1"
+ width="1"
+ id="rect21319"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21804"
+ transform="translate(1.1408497e-7,0.5000446)">
+ <path
+ transform="matrix(1.187982,0,0,1.0569758,379.83032,-513.21497)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21323"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89240623;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:0.71801031;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21325"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.3827154,0,0,1.4028327,364.1482,-688.72206)" />
+ <path
+ transform="matrix(0.987526,0,0,0.8124641,394.9733,-392.80617)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21327"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient21814);stroke-width:1.11641002;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:1.00804472;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21329"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9848328,0,0,0.9992585,395.19018,-485.12778)" />
+ <path
+ transform="matrix(0.591154,0,0,0.5887513,425.87219,-279.05319)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21331"
+ style="fill:none;stroke:url(#linearGradient21816);stroke-width:1.69505489;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.9913883,0,0,1.0058976,394.67318,-488.46061)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21333"
+ style="fill:none;stroke:url(#radialGradient21818);stroke-width:0.80110824;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient21820);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21335"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.6941559,0,0,0.6920597,417.67198,-331.15708)" />
+ <path
+ transform="matrix(0.1975308,0,0,0.1999991,456.0926,-84.399595)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path21337"
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(-0.6760501,-0.1575078,0.1570322,-0.6740085,446.07727,367.34791)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22185"
+ style="opacity:0.7;fill:url(#radialGradient22187);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ style="opacity:0.05;fill:none;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 476.49997,11.941967 0,7.174103"
+ id="rect21642"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(45,422.99999)"
+ id="g22102"
+ style="opacity:0.25;display:inline">
+ <rect
+ ry="0"
+ rx="0"
+ y="7"
+ x="464"
+ height="16"
+ width="16"
+ id="rect22104"
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22106">
+ <rect
+ style="fill:url(#linearGradient22154);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22108"
+ width="12"
+ height="10"
+ x="465.5"
+ y="10.5"
+ ry="1.5909902"
+ rx="1.5909902" />
+ <path
+ style="fill:url(#linearGradient22156);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 465,13.40909 0,4.59375 c 0,0.56244 0.36784,0.99717 0.84375,0.99716 l 11.3125,0.01065 c 0.47591,0 0.84375,-0.43471 0.84375,-0.99716 l 0,-4.59375 c -0.31371,0.37073 -0.76923,0.59091 -1.25,0.59091 L 466.25,14 c -0.48077,0 -0.93629,-0.22018 -1.25,-0.59091 l 0,0 0,0 0,0 z"
+ id="path22110"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1"
+ y="10.494369"
+ x="465"
+ height="2"
+ width="13"
+ id="rect22112"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.4762714" />
+ <rect
+ ry="1.3782184"
+ y="10.5"
+ x="465.5"
+ height="10"
+ width="12"
+ id="rect22114"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.3782184" />
+ <rect
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22116"
+ width="9.9998779"
+ height="7.999999"
+ x="466.5"
+ y="11.5"
+ ry="0.44196323"
+ rx="0.39062494" />
+ <g
+ transform="matrix(0.7547901,0,0,1,414.01868,-484.99999)"
+ id="g22118">
+ <path
+ transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22120"
+ style="fill:none;stroke:#999999;stroke-width:2.90780973;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.15103066;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69.531013,495.51105 0,-0.50001 c 0,-0.276 0.890314,-0.5 1.987308,-0.5 1.096993,0 1.987307,0.224 1.987307,0.5 l 0,0.50001"
+ id="path22122"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="495.01105"
+ x="70.193451"
+ height="1"
+ width="2.6497409"
+ id="rect22124"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g22126"
+ transform="matrix(1,0,0,0.6666667,331,-319.00002)">
+ <rect
+ y="496.5"
+ x="143"
+ height="1.5"
+ width="2"
+ id="rect22128"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#radialGradient22158);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22130"
+ width="2"
+ height="1.5"
+ x="143"
+ y="496.5" />
+ </g>
+ <rect
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22132"
+ width="1"
+ height="1"
+ x="468"
+ y="13" />
+ <g
+ transform="translate(1.1408497e-7,0.5000446)"
+ id="g22134">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89240623;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22136"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.187982,0,0,1.0569758,379.83032,-513.21497)" />
+ <path
+ transform="matrix(1.3827154,0,0,1.4028327,364.1482,-688.72206)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22138"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.71801031;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient22160);stroke-width:1.11641002;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22140"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.987526,0,0,0.8124641,394.9733,-392.80617)" />
+ <path
+ transform="matrix(0.9848328,0,0,0.9992585,395.19018,-485.12778)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22142"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:1.00804472;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient22162);stroke-width:1.69505489;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22144"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.591154,0,0,0.5887513,425.87219,-279.05319)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient22164);stroke-width:0.80110824;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22146"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9913883,0,0,1.0058976,394.67318,-488.46061)" />
+ <path
+ transform="matrix(0.6941559,0,0,0.6920597,417.84876,-330.91401)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22148"
+ style="fill:url(#radialGradient22166);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22150"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.1975308,0,0,0.1999991,456.07844,-84.89955)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22152"
+ d="m 476.49997,11.941967 0,7.174103"
+ style="opacity:0.05;fill:none;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-272,478.06251)"
+ id="g30185"
+ style="opacity:0.98000004;display:inline"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="-48"
+ x="403"
+ height="16"
+ width="16"
+ id="rect30187"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(1.3340954,0,0,1.3333333,-178.16901,-188.16667)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#2b1600;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30189"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30191"
+ style="fill:none;stroke:#2b1600;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.3340954,0,0,1.3333333,-184.1736,-187.16666)" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30193"
+ style="fill:url(#linearGradient24132);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccc"
+ id="path30195"
+ d="m 409.5,-39.50001 -2,2.000003 -2,0 0,2 2,0 0,1 1,1 5,7e-6 0,-1 2.99542,0 1.5,1 0.25,0 0,-5 -0.25,0 -1.5,1 -2.99542,0 0,-2 -4,-1e-5 0,0 0,0 0,0 z"
+ style="fill:#f89a35;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="8.1340281"
+ sodipodi:start="3.0449434"
+ transform="matrix(1.0812107,0,0,1.082338,-66.018179,-160.93645)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30231);stroke-width:0.92440742;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30197"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 440.514,108.7895 a 3,3 0 1 1 2.1568,2.59363" />
+ <path
+ transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30233);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30199"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="5.930273"
+ sodipodi:start="0.96146912"
+ d="m 445.21695,110.9601 a 3,3 0 1 1 1.09816,-3.497"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30201"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30235);stroke-width:0.9380942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.0655819,0,0,1.0664004,-65.085308,-158.20716)" />
+ <rect
+ y="-41"
+ x="409"
+ height="2.0000005"
+ width="4.0000658"
+ id="rect30203"
+ style="fill:#c8955e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(0.3352674,0,0,0.3357219,258.80309,-78.928541)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30237);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30205"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <rect
+ y="-43"
+ x="407"
+ height="1.0000002"
+ width="1"
+ id="rect30207"
+ style="fill:#2b2200;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30209"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30239);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.3352674,0,0,0.3357219,264.80311,-79.91866)" />
+ <rect
+ style="fill:#2b2200;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30211"
+ width="1"
+ height="1.0000002"
+ x="413.00003"
+ y="-43.99012" />
+ <rect
+ y="-37"
+ x="413"
+ height="2"
+ width="3.99542"
+ id="rect30213"
+ style="fill:url(#linearGradient30241);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30215"
+ d="m 416.49542,-37 1.5,-1 0,4 -1.5,-1 0,-2 z"
+ style="fill:url(#linearGradient30243);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30217"
+ d="m 415.99542,-37 1,-0.5 0,3 -1,-0.5 0,-2 z"
+ style="fill:url(#linearGradient30245);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient30247);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 413,-37 1,0 0,2 -1,0 0,-2 z"
+ id="path30219"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path30221"
+ d="m 409.75,-38.5 2.75,0 0,4 -4,0 0,-2.75 1.25,-1.25 z"
+ style="fill:#ec8f2c;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient30249);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1.2544428"
+ y="-37.821297"
+ x="407"
+ height="2.6761446"
+ width="2.8293107"
+ id="rect30223"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient20217);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.2544428" />
+ <rect
+ style="fill:#ffdbb5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30225"
+ width="3"
+ height="1"
+ x="406"
+ y="-37.000008" />
+ <rect
+ style="fill:#634321;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30227"
+ width="4"
+ height="1"
+ x="409"
+ y="-40" />
+ </g>
+ <g
+ style="opacity:0.98000004;display:inline"
+ id="g30282"
+ transform="translate(-271.99542,457.0625)">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30284"
+ width="16"
+ height="16"
+ x="403"
+ y="-48" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30286"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.3340954,0,0,1.3333333,-178.16901,-188.16667)" />
+ <path
+ transform="matrix(1.3340954,0,0,1.3333333,-184.1736,-187.16666)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30288"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <path
+ transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30326);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30290"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <path
+ style="fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 407.5,-39.5 0,1.999993 -2,0 0,2 2,0 0,1 1,1 5,7e-6 0,-1 2.99542,0 1.5,1 0.25,0 0,-5 -0.25,0 -1.5,1 -2.99542,0 0,-2 -6,0 z"
+ id="path30292"
+ sodipodi:nodetypes="cccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 440.514,108.7895 a 3,3 0 1 1 2.1568,2.59363"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30294"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30328);stroke-width:0.92440742;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.0812107,0,0,1.082338,-66.018179,-160.93645)"
+ sodipodi:start="3.0449434"
+ sodipodi:end="8.1340281"
+ sodipodi:open="true" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30296"
+ style="fill:url(#linearGradient30330);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)" />
+ <path
+ transform="matrix(1.0655819,0,0,1.0664004,-65.085308,-158.20716)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30332);stroke-width:0.9380942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30298"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 445.21695,110.9601 a 3,3 0 1 1 1.09816,-3.497"
+ sodipodi:start="0.96146912"
+ sodipodi:end="5.930273"
+ sodipodi:open="true" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30300"
+ width="4.0000658"
+ height="2.0000005"
+ x="409"
+ y="-41" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30302"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30334);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.3352674,0,0,0.3357219,258.80309,-78.928541)" />
+ <rect
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30304"
+ width="1"
+ height="1.0000002"
+ x="407"
+ y="-43" />
+ <path
+ transform="matrix(0.3352674,0,0,0.3357219,264.80311,-79.91866)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30336);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30306"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <rect
+ y="-43.99012"
+ x="413.00003"
+ height="1.0000002"
+ width="1"
+ id="rect30308"
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#linearGradient30338);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30310"
+ width="3.99542"
+ height="2"
+ x="413"
+ y="-37" />
+ <path
+ style="fill:url(#linearGradient30340);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 416.49542,-37 1.5,-1 0,4 -1.5,-1 0,-2 z"
+ id="path30312"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient30342);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.99542,-37 1,-0.5 0,3 -1,-0.5 0,-2 z"
+ id="path30314"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30316"
+ d="m 413,-37 1,0 0,2 -1,0 0,-2 z"
+ style="fill:url(#linearGradient30344);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient30346);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 409.75,-38.5 2.75,0 0,4 -4,0 0,-2.75 1.25,-1.25 z"
+ id="path30318"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient30348);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30320"
+ width="2.8293107"
+ height="2.6761446"
+ x="407"
+ y="-37.821297"
+ ry="1.2544428"
+ rx="1.2544428" />
+ <rect
+ y="-37.000008"
+ x="406"
+ height="1"
+ width="3"
+ id="rect30322"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-40"
+ x="409"
+ height="1"
+ width="4"
+ id="rect30324"
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="opacity:0.98000004;display:inline"
+ id="g30350"
+ transform="translate(-145.99542,541.00002)">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30352"
+ width="16"
+ height="16"
+ x="403"
+ y="-48" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30354"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.3340954,0,0,1.3333333,-178.16901,-188.16667)" />
+ <path
+ transform="matrix(1.3340954,0,0,1.3333333,-184.1736,-187.16666)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.74978584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30356"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <path
+ transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30394);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30358"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <path
+ style="fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 407.5,-39.5 0,1.999993 -2,0 0,2 2,0 0,1 1,1 5,7e-6 0,-1 2.99542,0 1.5,1 0.25,0 0,-5 -0.25,0 -1.5,1 -2.99542,0 0,-2 -6,0 z"
+ id="path30360"
+ sodipodi:nodetypes="cccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 440.514,108.7895 a 3,3 0 1 1 2.1568,2.59363"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30362"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30396);stroke-width:0.92440742;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.0812107,0,0,1.082338,-66.018179,-160.93645)"
+ sodipodi:start="3.0449434"
+ sodipodi:end="8.1340281"
+ sodipodi:open="true" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30364"
+ style="fill:url(#linearGradient30398);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.85464907;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)" />
+ <path
+ transform="matrix(1.0655819,0,0,1.0664004,-65.085308,-158.20716)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30400);stroke-width:0.9380942;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30366"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 445.21695,110.9601 a 3,3 0 1 1 1.09816,-3.497"
+ sodipodi:start="0.96146912"
+ sodipodi:end="5.930273"
+ sodipodi:open="true" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30368"
+ width="4.0000658"
+ height="2.0000005"
+ x="409"
+ y="-41" />
+ <path
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
+ sodipodi:ry="3"
+ sodipodi:rx="3"
+ sodipodi:cy="108.5"
+ sodipodi:cx="443.5"
+ id="path30370"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30402);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.3352674,0,0,0.3357219,258.80309,-78.928541)" />
+ <rect
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30372"
+ width="1"
+ height="1.0000002"
+ x="407"
+ y="-43" />
+ <path
+ transform="matrix(0.3352674,0,0,0.3357219,264.80311,-79.91866)"
+ sodipodi:type="arc"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient30404);stroke-width:2.98067403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30374"
+ sodipodi:cx="443.5"
+ sodipodi:cy="108.5"
+ sodipodi:rx="3"
+ sodipodi:ry="3"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
+ <rect
+ y="-43.99012"
+ x="413.00003"
+ height="1.0000002"
+ width="1"
+ id="rect30376"
+ style="fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#linearGradient30406);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30378"
+ width="3.99542"
+ height="2"
+ x="413"
+ y="-37" />
+ <path
+ style="fill:url(#linearGradient30408);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 416.49542,-37 1.5,-1 0,4 -1.5,-1 0,-2 z"
+ id="path30380"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient30410);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.99542,-37 1,-0.5 0,3 -1,-0.5 0,-2 z"
+ id="path30382"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path30384"
+ d="m 413,-37 1,0 0,2 -1,0 0,-2 z"
+ style="fill:url(#linearGradient30412);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient30414);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 409.75,-38.5 2.75,0 0,4 -4,0 0,-2.75 1.25,-1.25 z"
+ id="path30386"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient30416);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30388"
+ width="2.8293107"
+ height="2.6761446"
+ x="407"
+ y="-37.821297"
+ ry="1.2544428"
+ rx="1.2544428" />
+ <rect
+ y="-37.000008"
+ x="406"
+ height="1"
+ width="3"
+ id="rect30390"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-40"
+ x="409"
+ height="1"
+ width="4"
+ id="rect30392"
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17352"
+ width="16"
+ height="16"
+ x="194"
+ y="10" />
+ <g
+ id="g40205">
+ <rect
+ y="11.546152"
+ x="195.49998"
+ height="12.953857"
+ width="13.016124"
+ id="rect17356"
+ style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <rect
+ ry="0"
+ style="fill:url(#linearGradient40202);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17358"
+ width="11.000001"
+ height="11.046139"
+ x="197.01611"
+ y="12.00001" />
+ <g
+ transform="translate(146.99999,-417.99999)"
+ id="g40036">
+ <g
+ id="g39822"
+ transform="translate(-146.99999,417.99999)">
+ <rect
+ y="12"
+ x="196"
+ height="3"
+ width="3"
+ id="rect39628"
+ style="fill:#106386;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="15"
+ x="199"
+ height="3"
+ width="3"
+ id="rect39636"
+ style="fill:#ba0036;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#9f0022;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39670"
+ width="3"
+ height="3"
+ x="202"
+ y="12" />
+ <rect
+ style="fill:#688c7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39676"
+ width="3"
+ height="3"
+ x="205"
+ y="15" />
+ <rect
+ style="fill:#b77100;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39678"
+ width="3"
+ height="3"
+ x="196"
+ y="18" />
+ <rect
+ style="fill:#a67c58;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39684"
+ width="3"
+ height="3"
+ x="199"
+ y="21" />
+ <rect
+ y="18"
+ x="202"
+ height="3"
+ width="3"
+ id="rect39686"
+ style="fill:#7a2537;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="21"
+ x="205"
+ height="3"
+ width="3"
+ id="rect39692"
+ style="fill:#869c2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17363"
+ d="m 207.51769,12.50001 -11.0177,0 0,11 11.0177,0 0,-11"
+ style="fill:none;stroke:url(#linearGradient40189);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="10"
+ x="174"
+ height="16"
+ width="16"
+ id="rect39978"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17366"
+ transform="translate(286,-429)">
+ <g
+ id="g17368"
+ transform="translate(16,-32)">
+ <rect
+ y="471"
+ x="-45"
+ height="16"
+ width="16"
+ id="rect17370"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="472.5"
+ x="-43.483856"
+ height="13"
+ width="12.983856"
+ id="rect17372"
+ style="fill:url(#linearGradient17429);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path17374"
+ d="m -31.5,473.50001 -10.983862,0 0,11"
+ style="fill:none;stroke:url(#linearGradient17431);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="443"
+ x="-25"
+ height="5"
+ width="5"
+ id="rect17376"
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17379"
+ width="5"
+ height="5"
+ x="-22"
+ y="446" />
+ </g>
+ <g
+ id="g32743"
+ transform="translate(9.471,32.00923)">
+ <rect
+ y="-22.009235"
+ x="226.52901"
+ height="16"
+ width="16"
+ id="rect17382"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-20.509235"
+ x="228.04515"
+ height="13"
+ width="12.983856"
+ id="rect17384"
+ style="fill:url(#linearGradient32749);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ <rect
+ transform="translate(271.529,-379.00923)"
+ style="fill:url(#linearGradient32751);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17387"
+ width="12"
+ height="12"
+ x="-43"
+ y="359"
+ mask="url(#mask17570)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17389"
+ d="m 240.029,-19.509225 -10.98386,0 0,11.0000002 10.98384,-10e-6 0,-11.0000002"
+ style="fill:none;stroke:url(#linearGradient32753);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17336"
+ transform="translate(275,-385.99999)"
+ style="opacity:0.25">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17338"
+ width="16"
+ height="16"
+ x="-60"
+ y="396" />
+ <g
+ id="g17340">
+ <rect
+ y="397.54614"
+ x="-58.500015"
+ height="12.953857"
+ width="13.016124"
+ id="rect17342"
+ style="fill:url(#linearGradient32725);fill-opacity:1;fill-rule:nonzero;stroke:#333333;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <rect
+ ry="0"
+ style="fill:url(#linearGradient32727);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17344"
+ width="11.000001"
+ height="11.046139"
+ x="-56.983894"
+ y="398" />
+ <path
+ style="fill:url(#linearGradient32729);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -58,398 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m 0,-2 2,0 0,-2 -2,0 0,2 z m 0,-2 0,-2 -2,0 0,2 2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z"
+ id="path17346"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path17348"
+ d="m -46.482307,398.50001 -11.017704,0 0,11 11.017704,0 0,-11"
+ style="opacity:0.45;fill:none;stroke:url(#linearGradient32731);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.65;fill:none;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 217.5,24.000005 11.5,-11.5"
+ id="path17578"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g17152"
+ transform="translate(339,-210)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18439"
+ width="16"
+ height="16"
+ x="-124"
+ y="325"
+ rx="0"
+ ry="0" />
+ <g
+ transform="translate(-11,154.99966)"
+ id="g18441"
+ style="opacity:0.7">
+ <g
+ transform="translate(-99,-97.999673)"
+ id="g18443"
+ style="display:inline">
+ <g
+ transform="translate(41.011415,162)"
+ style="display:inline"
+ id="g18445">
+ <g
+ transform="translate(-80,-48)"
+ id="g18447">
+ <path
+ style="fill:#d7d7d7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 36.488585,166.3823 -0.25,1.1177 -9.499995,0 -1.25,-1.25 -5e-6,-10.75 11,0 0,10.8823 z"
+ id="path18449"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path18451"
+ d="m 34.988585,166.00001 -8,0 0,-1.00001 8,0 0,1.00001 z"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path18453"
+ d="m 35.47469,156.50008 -8.986105,-8e-5 5e-6,10 8.999995,0 -0.01389,-9.99992 -5e-6,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient17177);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="165.00002"
+ x="27.988585"
+ height="1.0000023"
+ width="1"
+ id="rect18455"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1,0,0,-1,0,320)"
+ id="g18457"
+ style="fill:#ee0000;fill-opacity:1" />
+ </g>
+ </g>
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18459"
+ d="m -101,181 -10,0 0,-8 10,0 0,8 z"
+ style="opacity:0.5;fill:url(#radialGradient17179);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-11,154.99966)"
+ id="g18461">
+ <g
+ id="g18463"
+ transform="translate(-347,193.00032)">
+ <path
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#e1e1e1;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 246.5,-15.5 c -1.65264,0 -3,1.347359 -3,3 l 0,2 c 0,1.6526411 1.34737,3 3,3 l 0,0 c 1.65264,0 3,-1.3473589 3,-3 l -0.0312,-1.96875 c 0,-1.652641 -1.31612,-3.03125 -2.96875,-3.03125 l 0,0 -5e-5,0 z m 0,2 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-2 c 0,-0.554 0.446,-1 1,-1 z"
+ id="path18465"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18467"
+ d="m 246.5,-19.5 c -1.65264,0 -3,1.347359 -3,3 l 0,2 c 0,1.652641 1.34737,3 3,3 l 0,0 c 1.65264,0 3,-1.347359 3,-3 l 0,-2 c 0,-1.652641 -1.34737,-3 -3,-3 l 0,0 z m 0,2 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-2 c 0,-0.554 0.446,-1 1,-1 z"
+ style="fill:url(#radialGradient17181);fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(6,0)"
+ clip-path="url(#clipPath17188)"
+ id="path18473"
+ d="m 240.5,-15.5 c -1.65264,0 -3,1.347359 -3,3 l 0,2 c 0,1.6526411 1.34737,3 3,3 l 0,0 c 1.65264,0 3,-1.3473589 3,-3 l -0.0312,-1.96875 c 0,-1.652641 -1.31612,-3.03125 -2.96875,-3.03125 l 0,0 -5e-5,0 z m 0,2 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-2 c 0,-0.554 0.446,-1 1,-1 z"
+ style="fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-14.06875"
+ x="244"
+ height="2.5"
+ width="1"
+ id="rect18475"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18477"
+ width="1"
+ height="1"
+ x="245"
+ y="-15.06875" />
+ </g>
+ <g
+ id="g18479" />
+ </g>
+ </g>
+ <g
+ id="g18489"
+ transform="translate(287,-54.93125)">
+ <g
+ id="g18491"
+ transform="translate(0,-3.2e-4)"
+ style="opacity:0.7">
+ <g
+ style="display:inline"
+ id="g18493"
+ transform="translate(-79,-97.999673)">
+ <g
+ id="g18495"
+ style="display:inline"
+ transform="translate(41.011415,162)">
+ <g
+ id="g18497"
+ transform="translate(-80,-48)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path18499"
+ d="m 36.488585,166.3823 -0.25,1.1177 -9.499995,0 -1.25,-1.25 -5e-6,-10.75 11,0 0,10.8823 z"
+ style="fill:#d7d7d7;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 34.988585,165.99999 -8,0 0,-1 8,0 0,1 z"
+ id="path18501"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient23914);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 35.47469,156.50008 -8.986105,-8e-5 5e-6,10 8.999995,0 -0.01389,-9.99992 -5e-6,0 0,0 0,0 z"
+ id="path18503"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18505"
+ width="1"
+ height="1.000007"
+ x="27.988585"
+ y="165"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ style="fill:#ee0000;fill-opacity:1"
+ id="g18507"
+ transform="matrix(1,0,0,-1,0,320)" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-157,18.000328)"
+ style="opacity:0.5"
+ id="g18509">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18511"
+ d="m 76,164 -10,0 0,-9 10,0 0,9 z"
+ style="opacity:0.8;fill:url(#radialGradient23916);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#radialGradient23918);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 76,164 -10,0 0,-9 10,0 0,9 z"
+ id="path18513"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g18515"
+ transform="translate(0,-3.2e-4)">
+ <g
+ id="g18517">
+ <g
+ transform="translate(-360,181.00032)"
+ id="g18519"
+ mask="url(#mask13041)">
+ <path
+ id="path18521"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.316109 -2.96875,2.96875 l 0,1.0625 c 0,1.6526411 1.31612,2.96875 2.96875,2.96875 l 0.0625,0 c 1.65264,0 2.96875,-1.3161089 2.96875,-2.96875 l 0,-1.0625 c 0,-1.652641 -1.31612,-2.96875 -2.96875,-2.96875 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.446 1,1 l 0,1 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-1 c 0,-0.554 0.446,-1 1,-1 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18523"
+ width="1"
+ height="2.5"
+ x="277"
+ y="-10" />
+ <rect
+ y="-11"
+ x="278"
+ height="1"
+ width="1"
+ id="rect18525"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g18527"
+ transform="translate(-360,191.06282)"
+ mask="url(#mask13052)">
+ <path
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.316109 -2.96875,2.96875 l 0,1.0625 c 0,1.6526411 1.31612,2.96875 2.96875,2.96875 l 0.0625,0 c 1.65264,0 2.96875,-1.3161089 2.96875,-2.96875 l 0,-1.0625 c 0,-1.652641 -1.31612,-2.96875 -2.96875,-2.96875 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.446 1,1 l 0,1 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-1 c 0,-0.554 0.446,-1 1,-1 z"
+ id="path18529"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-10"
+ x="277"
+ height="2.5"
+ width="1"
+ id="rect18531"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18533"
+ width="1"
+ height="1"
+ x="278"
+ y="-11" />
+ </g>
+ </g>
+ <g
+ id="g18535" />
+ </g>
+ </g>
+ <g
+ id="g18658"
+ transform="translate(-147.04123,1.9815)">
+ <rect
+ y="71.018501"
+ x="383.04123"
+ height="16"
+ width="16"
+ id="rect18661"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g18663">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient18682);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 397.54124,84.25 -1.25,1.25 -10.5,0 -1.24999,-1.25 0,-11.75 12.99999,0 0,11.75 z"
+ id="path18665"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path18667"
+ d="m 396.04123,84.0185 -10,0 0,-1.0185 10,0 0,1.0185 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="83.018501"
+ x="387.04123"
+ height="0.99999702"
+ width="0.99998772"
+ id="rect18671"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-39.85994,-165.9815)"
+ id="g18674">
+ <path
+ sodipodi:nodetypes="csssccc"
+ d="m 430.24956,241.60271 -0.86957,2.62878 c -1.04667,3.16416 -1.3885,3.86937 -2.40118,2.64949 -0.37662,-0.45369 -1.31958,0.42592 -0.85102,0.66654 2.9195,1.49927 3.83448,-0.99495 4.73215,-3.56602 l 0.75,-2.37879 -1.36038,0 0,0 0,0 0,0 z"
+ id="path18676"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.33455,240.97335 c -0.77131,0.0353 -1.46745,0.21844 -2.3658,0.6829 -0.74329,0.3843 -1.31497,1.26096 -1.28125,1.75 0.0247,0.35816 0.29068,0.65625 0.65625,0.65625 0.36558,0 0.6936,-0.30765 0.6781,-0.65797 C 428,242.91083 427.68952,243 427.84375,242.625 c 0.11839,-0.28788 0.47629,-0.71901 0.90625,-0.83455 0.61327,-0.1648 1.873,0.18401 2.5,0.20955 1.75215,0.0714 3.67097,-0.15759 4.5,-1 -0.24423,0.0241 -2.49503,0.0675 -2.75,0.0625 -1.06533,-0.0208 -1.89414,-0.12444 -2.66545,-0.0891 l 0,-5e-5 z"
+ id="path18678"
+ sodipodi:nodetypes="cssssssscss"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ d="m 430.47881,243.98149 c 1.25,0 2.77121,0.0774 3.52119,0.0185 -0.28977,0.34542 -1.08416,0.80085 -1.5,0.89651 -0.84895,0.19531 -2.02119,-0.033 -2.89006,0.0468 l 0.86887,-0.96184 0,3e-5 z"
+ id="path18680"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:url(#linearGradient18690);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 396.54123,73.51858 -10.98611,-8e-5 -0.0139,11.00008 11,0 0,-11 10e-6,0 z"
+ id="path18688"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(2,529.00001)"
+ id="g18738"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18740"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g18742"
+ transform="translate(0.01612278,0)">
+ <rect
+ style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38458"
+ width="11.999999"
+ height="9.0000172"
+ x="4.9838772"
+ y="70.999992" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18744"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient18752);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18746"
+ d="M 15.983877,81.999998 7.7338772,82 l 0,-0.999998 8.2499998,-2e-6 0,0.999998 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18756);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ id="path18748"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18750"
+ width="1"
+ height="1"
+ x="5.9838772"
+ y="80.999992"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ transform="translate(256.9902,446.00001)"
+ id="g18759"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18761"
+ width="16"
+ height="16"
+ x="42.0098"
+ y="173" />
+ <g
+ style="display:inline"
+ id="g18763"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(-0.00161682,-3.9821186e-5)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path41276"
+ d="m 56.511417,178.50003 -10,0 0,9 8.75,0 1.25,-1.25 0,-7.75 z"
+ style="opacity:0.15;fill:#000000;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18765"
+ d="m 55.011418,177.00004 -10.000001,-1e-5 0,9 10.000001,1e-5 0,-9 z"
+ style="opacity:0.85;fill:url(#linearGradient18779);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 55.501617,177.75004 -1.25,-1.25 -8.4902,-1e-5 -1.25,1.25 0,7.5 1.25,1.25 8.4902,1e-5 1.25,-1.25 0,-7.5 z"
+ id="path18767"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 54.011419,178.00004 -8.000002,-1e-5 0,0.99996 8.000002,1e-5 0,-0.99996 z"
+ id="path18773"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18860"
+ d="m 54.5098,177.5 0,8 -9,-1e-5 0,-8 9,1e-5 z"
+ style="fill:none;stroke:url(#linearGradient18862);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g18864"
+ transform="translate(210,253.00005)">
+ <rect
+ y="345"
+ x="-184"
+ height="16"
+ width="16"
+ id="rect18694"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18698"
+ d="m -176.47247,352.5 -0.59149,0 -5.43604,0 0.0161,-6.00003 6.01141,0 0,6.00003 2e-5,0 0,0 0,0 z"
+ style="fill:url(#linearGradient18846);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient18841);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -176.5,358.5 -1,1 -3.73388,0 -1.25,-1.25 0,-5.74999 6.01141,0 L -176.5,358.5 z"
+ id="path18702"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18710"
+ d="m -169.5133,358.25 -1.2367,1.25 -4.75,0 -1,-1 0,-12 7.00001,0 -0.0133,11.75 -10e-6,0 z"
+ style="fill:url(#linearGradient18831);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18712"
+ d="m -171,358 -4,0 0,-1.00004 4,0 0,1.00004 z"
+ style="color:#000000;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18718"
+ d="m -177.5,353.5 0,5 -4,0 0,-5 4,0 z"
+ style="fill:none;stroke:url(#linearGradient18823);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -178,358.00004 -3,0 0,-1.00004 3,0 0,1.00004 z"
+ id="path18850"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18854);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -170.5,347.5 0,11.00001 -5,0 0,-11.00001 5,0 z"
+ id="path18852"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient18858);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -177.5,347.50001 0,4 -4,0 0,-4 4,0 z"
+ id="path18856"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path17395"
+ d="m -178,358.00004 -3,0 0,-1.00004 3,0 0,1.00004 z"
+ style="color:#000000;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17204"
+ transform="translate(290,-291)">
+ <g
+ transform="translate(-204,295)"
+ id="g18875"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18877"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g18879"
+ transform="translate(0.01612278,0)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18881"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17222);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18883"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17224);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ id="path18885"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18887"
+ width="1"
+ height="1"
+ x="6.9838772"
+ y="81"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m -197.50001,368.5 9,0 m -9,2 9,0 m -9,2 9,0"
+ style="fill:none;stroke:url(#linearGradient17226);stroke-width:0.9999994px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ id="path19108"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17183"
+ transform="translate(294,-291)">
+ <g
+ style="display:inline"
+ id="g19069"
+ transform="translate(-187,295)">
+ <rect
+ y="69"
+ x="3"
+ height="16"
+ width="16"
+ id="rect19071"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01612278,0)"
+ id="g19073"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient17214);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ id="path19075"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ id="path19077"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path19079"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ style="fill:none;stroke:url(#linearGradient17216);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ y="81"
+ x="6.9838772"
+ height="1"
+ width="1"
+ id="rect19081"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ id="path19112"
+ style="fill:none;stroke:url(#linearGradient17218);stroke-width:0.99999946px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ d="m -173.49999,372.5 2,0 m -2,-2 2,0 m -2,-2 2,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m -180.5,372.5 3,0 m -3,-2 3,0 m -3,-2 3,0"
+ style="fill:none;stroke:url(#linearGradient17220);stroke-width:0.99999952px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ id="path19116"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#999999;fill-opacity:0.75;fill-rule:evenodd;stroke:#808080;stroke-width:0.99999928px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m -175.39386,374.49044 0,-7.03646"
+ id="path19120"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path19122"
+ d="m -174.39384,374.5 0,-8.00012 2.89384,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.9999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g41473">
+ <g
+ id="g20803"
+ transform="translate(-116.99998,424.00001)">
+ <g
+ transform="translate(-340.00002,-121.00001)"
+ id="g20805">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9e9af;stroke-width:0.49999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32699"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.9999998,0,0,2.0000014,-462.99991,-192.00026)" />
+ <path
+ transform="matrix(1.4285718,0,0,1.4285718,-197.57158,-82.000059)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path32701"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e1e08a;stroke-width:0.69999987;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#adac2f;stroke-width:1.16666663;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32703"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(0.8571429,0,0,0.8571429,67.857123,27.999992)" />
+ </g>
+ <rect
+ y="71"
+ x="125"
+ height="2"
+ width="2"
+ id="rect20813"
+ style="fill:#f4f4d7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g41392">
+ <g
+ transform="translate(-456.00027,338.00001)"
+ id="g20782">
+ <path
+ style="fill:url(#linearGradient23241);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.66961 -3,1.5 l 0,7 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 0,-7 c 0,-0.83039 -1.0691,-1.5 -3,-1.5 z"
+ id="path20784"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23243);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 470.50029,158.5 0,6.45352 c 0,0.54648 1.28413,0.46583 2,0.54648 1,0 2,0 2,-0.55753 l 0,-6.45352"
+ id="path20786"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient23245);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.5 -3,1.5 l 0,7 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 0,-7 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ id="path20788"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#eff6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path20790"
+ sodipodi:cx="108"
+ sodipodi:cy="-222"
+ sodipodi:rx="3.3084693"
+ sodipodi:ry="1.2798798"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
+ transform="matrix(0.9067635,0,0,1.3047091,374.56954,447.97555)" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path20793"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.5 -3,1.5 l 0,7 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 0,-7 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ style="fill:none;stroke:#162d50;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-116.99998,424.00001)"
+ id="g32690">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path32692"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.05875278;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4371593,0,0,0.4371565,71.294972,28.418283)" />
+ <path
+ transform="matrix(-0.3851128,-0.04237784,0.04389507,-0.3737467,174.55414,129.70537)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path32694"
+ style="opacity:0.6;fill:url(#linearGradient23247);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path20801"
+ style="fill:none;stroke:url(#linearGradient23250);stroke-width:3.99999762;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.3000001,0,0,0.3000002,89.398992,44.603723)" />
+ </g>
+ <rect
+ y="493"
+ x="5"
+ height="16"
+ width="16"
+ id="rect20815"
+ style="fill:none;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g17123"
+ transform="translate(207.01492,72.000007)">
+ <rect
+ y="442"
+ x="-34"
+ height="16"
+ width="16"
+ id="rect17125"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="czsccccccccccccccccccccccccccccs"
+ id="path17128"
+ d="m -21.25,443.25 c -1.25,-1.25 -3.5,0.25 -7.5,4 -4,3.75 -5.25,6.25 -4,7.5 1.013195,1.01319 3.75,2.5 3.75,2.5 l 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 -2.75,-3.5 1,-1 3.5,2.75 0.25,0 0,-0.25 c 0,0 -2,-3.25 -2.5,-3.75 z"
+ style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient17135);fill-rule:evenodd;stroke:none"
+ d="m -21.25,443.25 c -0.5,-0.5 -3.5,0.25 -7.5,4 -4,3.75 -4.5,7 -4,7.5 0.5,0.5 3.5,2.75 3.5,2.75 l 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 -2.75,-3.25 0.75,-0.75 3.25,2.75 0.75,-0.75 c 0,0 -2.249997,-3 -2.75,-3.5 z"
+ id="path17131"
+ sodipodi:nodetypes="czsccccccccccccccccccccccs"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -21.75,443.75 c -1,-1 -3.5,1 -6.5,4 -3,3 -5,5.5 -4,6.5"
+ id="path17133"
+ sodipodi:nodetypes="czs"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g17299"
+ transform="translate(-21,128.00001)">
+ <g
+ transform="translate(464,422)"
+ id="g17228"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17230"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g17232"
+ transform="translate(0.01612278,0)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path17234"
+ d="m 17.453876,82.25 -1.219999,1.25 -10.4999998,0 -1.25,-1.25 -1e-7,-11.75 12.9814139,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17242);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path17236"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17244);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 5.4838772,82.5 0,-11 10.9999998,0 0,11 -10.9999998,0 z"
+ id="path17238"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17240"
+ width="1"
+ height="1"
+ x="6.9838772"
+ y="81"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ transform="translate(20.96875,0)"
+ id="g17279">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 450.70226,498 6.81386,0 m -4.98487,-2.5 -1.82899,2.5 m 1.82899,2.5 -1.82899,-2.5"
+ style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17281"
+ sodipodi:nodetypes="czcccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path17283"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 453.28125,496 -0.75,1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 452.78125,499 4.76119,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.50000006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path17286"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g17117" />
+ <g
+ id="g17121"
+ transform="translate(9,0)" />
+ <g
+ transform="translate(6,4)"
+ id="g17128" />
+ <g
+ id="g17136"
+ transform="translate(1,6)" />
+ <g
+ id="g17149"
+ transform="translate(8,7)" />
+ <g
+ style="display:inline"
+ id="g22103"
+ transform="translate(-10,466.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33081"
+ width="16"
+ height="16"
+ x="162"
+ y="90" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33085"
+ width="2.5"
+ height="1.75"
+ x="165.74995"
+ y="96.749977" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path33087"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,2.75 -5.99999,3.24999 -6.00001,-3.24999 0,-2.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="91.999977"
+ x="170.98643"
+ height="7"
+ width="2"
+ id="rect32743"
+ style="opacity:0.96000001;fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path33091"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
+ style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 164.99997,101.74998 -1e-5,-2.25 6,3 0.01,2.49885 -6.00995,-3.24885 -4e-5,0 0,0 0,0 z"
+ id="path33093"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path33095"
+ d="m 176.99996,101.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#aa0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33097"
+ width="2"
+ height="1"
+ x="165.99995"
+ y="97.999977" />
+ <rect
+ y="96.999977"
+ x="165.99995"
+ height="1"
+ width="2"
+ id="rect32749"
+ style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#ffaaaa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32751"
+ width="1"
+ height="2"
+ x="165.99995"
+ y="96.999977" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path32753"
+ d="m 165.49996,99.49998 0,0 0,2 5.5,3 5.5,-3 0,-2"
+ style="fill:none;stroke:url(#linearGradient22081);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-114.00004,-232.99999)"
+ id="g32755">
+ <rect
+ style="opacity:0.3;fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33103"
+ width="2"
+ height="3.9642856"
+ x="285"
+ y="328.03571" />
+ <path
+ transform="matrix(1.6666708,0,0,1.6666633,-190.66784,-215.66559)"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="325"
+ sodipodi:cx="286"
+ id="path33105"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#550000;stroke-width:0.59999985;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32759"
+ width="2"
+ height="3.5000324"
+ x="285"
+ y="328.49997" />
+ <rect
+ y="328.49997"
+ x="285"
+ height="3.5000324"
+ width="1"
+ id="rect32761"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient32335);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.59999985;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32763"
+ sodipodi:cx="286"
+ sodipodi:cy="325"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.333351,0,0,1.333345,-95.338377,-107.33714)" />
+ <rect
+ y="331"
+ x="284"
+ height="1"
+ width="1"
+ id="rect32765"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32767"
+ width="2"
+ height="1"
+ x="285"
+ y="332" />
+ <rect
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32769"
+ width="1"
+ height="1"
+ x="287"
+ y="331" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path48963"
+ d="m 165.49996,98.99998 5.5,2.75"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask20957)"
+ id="g21598">
+ <path
+ mask="none"
+ sodipodi:nodetypes="cccc"
+ id="path21596"
+ d="m 168.25,102.75 -0.75,0.75 c -1,1 -0.75,1 -2,1 l -2.25,0"
+ style="opacity:0.7;fill:none;stroke:#1a1a1a;stroke-width:2.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ececec;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 168.25,102.75 -0.75,0.75 c -1.25,1.17188 -0.75,1 -2,1 l -3,0"
+ id="path21594"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g34058"
+ transform="translate(0,12)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path32379"
+ d="m 35.5,65.5 6,0 0,11 -9,0 0,-8 3,-3 z"
+ style="fill:url(#linearGradient31964);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient31966);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(0,-10)"
+ id="g34026">
+ <path
+ style="fill:url(#linearGradient31968);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient31970);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ d="m 29.5,71.5 6,0 0,11 -9,0 0,-8 3,-3 z"
+ id="path32383"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="73"
+ x="27.984795"
+ height="8"
+ width="6.0303202"
+ id="rect32389"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ transform="matrix(-1,0,0,1,217.99997,-167)"
+ id="g32391">
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ id="g32393">
+ <path
+ style="fill:#b41500;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 187.03125,239 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m 0,-2 0,-2 -2,0 0,2 2,0 z"
+ transform="matrix(-1,0,0,1,375.01609,1)"
+ id="path32395"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ id="g32397"
+ transform="translate(2,-2)" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ transform="translate(0,-4)"
+ id="g32399" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ id="g32401"
+ transform="translate(2,-6)" />
+ <g
+ style="fill:#fa0000;fill-opacity:1"
+ transform="translate(0,-8)"
+ id="g32403" />
+ </g>
+ <path
+ mask="none"
+ clip-path="none"
+ transform="matrix(1.499975,0,0,1.4959551,100.24881,-314.20841)"
+ sodipodi:nodetypes="ccc"
+ id="path32405"
+ style="fill:none;stroke:#000000;stroke-width:0.66757292px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter23214)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path32407"
+ style="opacity:0.98999999;fill:none;stroke:url(#linearGradient31972);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 27.5,76 -3e-5,5.5081 M 31,72.5 l 3.49997,0.0081"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path32409"
+ d="m 25.99997,75.00809 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 26.5,64 0,8.5 6,0 -0.01513,4 9.01513,0 0,-11 -5.98487,0 -0.01513,-4 -6.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path32414"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-158,-135)"
+ id="g33249">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccc"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 35,78 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z m -1,2 0,1 6,0 0,-1 -6,0 z m 5,2 0,1 1,0 0,-1 -1,0 z"
+ transform="translate(158,125)"
+ id="rect33241"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ d="m 33.5,73.25 0,2.25001 M 36.25,66.5 l 4.25,0"
+ style="fill:none;stroke:url(#linearGradient31974);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path33301"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g22429"
+ transform="translate(542.99004,484.00118)">
+ <rect
+ y="9"
+ x="-34"
+ height="16"
+ width="16"
+ id="rect22431"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22433">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#2a2512;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -32,17 7,-3 6,2.5 0,3.74998 -6.99999,3.74999 L -32,20.74998 -32,17 z"
+ id="path22435"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -32,17 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 L -32,17 z"
+ id="path22437"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#2c281a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -24.99004,20.99883 -25,14.00002 -32,17 l 3.5,1.75 3.50996,2.24883 0,0 0,0 0,0 z"
+ id="path22439"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22441"
+ d="M -24.99004,20.99883 -25,14 l 6,2.5 -3.5,1.75 -2.49004,2.74883 0,0 0,0 0,0 z"
+ style="fill:#716844;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22453);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M -19.5,16.5 -25,14.25 -31.5,17"
+ id="path22443"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path22445"
+ d="M -31.99999,20.74998 -32,17.5 l 6,3 0.01,3.49883 -6.00995,-3.24885 -4e-5,0 0,0 0,0 z"
+ style="fill:#c6b77c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#595235;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -19,20.25 0,-3.24998 -7,3.49998 c 0,2.58362 0,2.93288 0,3.49998 L -19,20.25 z"
+ id="path22447"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient22455);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.5,17.5 0,2.99998 5.5,3 6.5,-3.49998 0,-2.99998"
+ id="path22449"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path22451"
+ d="m -31.5,17.5 5.5,3 6.5,-3.5"
+ style="fill:none;stroke:url(#linearGradient22457);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17123"
+ width="1"
+ height="0"
+ x="90"
+ y="523" />
+ <g
+ style="display:inline"
+ id="g18470"
+ transform="matrix(-1,0,0,1,269,-561)">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18472"
+ width="16"
+ height="16"
+ x="164"
+ y="592" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ d="m 169.51126,596.5 c 3.98874,3.75 3.98874,7.5 3.98874,9 m 1.01472,-11 c 3.48528,5 2.98528,9.5 2.98874,11 M 166.5,600.5 c 2,1 3,3 3.00692,5"
+ style="fill:none;stroke:url(#linearGradient18478);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path18474"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18476"
+ style="fill:none;stroke:url(#linearGradient18480);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 169.51126,596.5 c 3.98874,3.75 3.98874,7 3.98874,9 m 1.01472,-11 c 3.48528,5 2.98528,9.5 2.98874,11 M 166.5,600.5 c 2,1 3,3 3.00692,5"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g22771"
+ transform="translate(-186,487.00001)">
+ <g
+ id="g21832"
+ style="opacity:0.85">
+ <rect
+ transform="scale(-1,1)"
+ y="82"
+ x="-433.5"
+ height="3"
+ width="7.8166504"
+ id="rect22717"
+ style="opacity:0.5;fill:url(#linearGradient22880);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ y="83"
+ x="-434"
+ height="1"
+ width="8.9931746"
+ id="rect21783"
+ style="fill:url(#linearGradient22848);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ y="83"
+ x="-430.5"
+ height="1"
+ width="2"
+ id="rect22877"
+ style="fill:#333333;fill-opacity:0.81960784;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="opacity:0.8"
+ id="g22652">
+ <rect
+ y="69"
+ x="422"
+ height="16"
+ width="16"
+ id="rect22589"
+ style="opacity:0.05;fill:url(#radialGradient22838);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22619">
+ <path
+ sodipodi:nodetypes="csscccc"
+ id="path21775"
+ d="m 422.51387,74.4375 c 2.14278,1.6383 5.29475,5.652 6.25,7.5625 0.5,1 1.05394,1.01957 1.5,0 0.875,-2 3.25,-4.75 4.75,-6 l -3.5,-4 c -1.25,1.83839 -2,3.25 -2.75,4.63304 -1.71617,-1.72583 -4.35859,-3.39262 -6.25,-4.13304"
+ style="fill:url(#linearGradient22840);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient22842);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22626">
+ <g
+ id="g22622">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path21777"
+ d="m 422.51387,73.5 c 1.93909,0.815624 4.07262,1.664731 6,4 l 0.75,0 c 0.82427,-1.547027 1.51287,-2.596571 2.16161,-3.5"
+ style="fill:none;stroke:url(#linearGradient22844);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22846);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 422.51387,73.5 c 1.93909,0.815624 5.41183,5.25 7,8 1.5,-3 2.75,-4 4.75,-6.25"
+ id="path21779"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22896);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 428.5,78.5 c 0.95165,-1.519624 1.88025,-3.040081 2.92548,-4.5"
+ id="path22894"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g22592"
+ transform="translate(434.01387,-281)">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient22850);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.82784271;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21781"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.4380641,0,0,0.4372851,-57.820839,302.39978)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient22852);stroke-width:4.11671448;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path21785"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.2913522,0,0,0.2916372,38.453823,319.58486)" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g35565"
+ transform="translate(147,527.00001)">
+ <rect
+ y="71"
+ x="215"
+ height="16"
+ width="16"
+ id="rect34912"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35549">
+ <g
+ transform="translate(167,137)"
+ id="g34916">
+ <path
+ transform="translate(58.032932,-27.838387)"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34918"
+ style="fill:none;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.56022131;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34920"
+ sodipodi:cx="0"
+ sodipodi:cy="-32"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(1.4285714,0,0,1.4274429,55.5,-11.825777)" />
+ </g>
+ <g
+ id="g34922"
+ transform="matrix(1.1068703,0,0,1.0981766,160.5341,122.19554)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34924"
+ sodipodi:cx="0"
+ sodipodi:cy="-32"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(1.1751782,0,0,1.1751782,56.000001,-1.2882925)" />
+ <path
+ transform="matrix(0.9994022,0,0,0.9994021,56.002092,-6.9152216)"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34926"
+ style="fill:none;stroke:url(#linearGradient35583);stroke-width:1.17982781;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35585);stroke-width:1.16643703;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34928"
+ sodipodi:cx="0"
+ sodipodi:cy="-32"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.774689,0,0,0.7805148,56.890573,-14.812697)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35587);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99581552;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34930"
+ sodipodi:cx="0"
+ sodipodi:cy="-32"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(1.0042021,0,0,1.0042021,55.985293,-6.7448206)" />
+ <path
+ transform="matrix(0.9108044,0,0,0.9108044,55.985293,-9.7335486)"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34932"
+ style="fill:url(#linearGradient35589);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99581552;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="translate(167,137)"
+ id="g34934">
+ <path
+ transform="matrix(0.8571429,0,0,0.8571429,58.032932,-32.409816)"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34936"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35591);stroke-width:1.40000081;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34938"
+ sodipodi:cx="0"
+ sodipodi:cy="-32"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.7142853,0,0,0.7142853,58.032932,-36.981258)" />
+ <path
+ transform="translate(58.032932,-27.838387)"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="-32"
+ sodipodi:cx="0"
+ id="path34940"
+ style="fill:none;stroke:url(#linearGradient35593);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35595);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34942"
+ sodipodi:cx="0"
+ sodipodi:cy="-32"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.8571429,0,0,0.8571429,58.032932,-32.409816)" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g35712"
+ transform="translate(307,636)">
+ <rect
+ y="-38"
+ x="34"
+ height="16"
+ width="16"
+ id="rect35714"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(231.01612,149)"
+ id="g34102"
+ style="opacity:0.96000001;display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35717"
+ d="m -187.24592,-178.75235 -5.0202,5.00235 -3,2 -1,-1 2,-3 5.0202,-5.00235 2,2 z"
+ style="fill:url(#linearGradient35740);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -187.24592,-178.75235 -5.2702,5.25235 -3,2 -1,-1 2,-3 5.2702,-5.25235 2,2 z"
+ id="path34105"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path34107"
+ d="m -195.4858,-172.48532 1.46968,-2.51468 4.26612,-4.25"
+ style="fill:none;stroke:#ffffff;stroke-width:0.85000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path35721"
+ d="m 44.5,-37.5 -2,2 1,1 -2,2 -4,0 -1,1 7,7 1,-1 0,-4 2,-2 1,1 1.5098,-1.5098 0.4902,-0.4902 -5,-5 z"
+ style="fill:url(#linearGradient35742);fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35723"
+ d="m 44.5,-29.5 -3,-3"
+ style="fill:none;stroke:url(#linearGradient35744);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35725"
+ d="m 46.5,-31.5 -3,-3"
+ style="fill:none;stroke:url(#linearGradient35746);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35729"
+ d="m 43.5,-33.5 -1.75,1.75 -4,0 -0.25,0.25"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35731"
+ d="m 43.5,-35.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35733"
+ d="m 42,-32 0,0 2,-2 2.5,2.5 -2,2 L 42,-32"
+ style="fill:url(#linearGradient35750);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient35752);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 44.55,-36.45 3.95,3.95"
+ id="path34886"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path34890"
+ d="m 43.5,-35.5 3.715625,3.66875"
+ style="fill:none;stroke:url(#linearGradient35754);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient35756);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 41.55,-31.45 2.2,2.2"
+ id="path34894"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 45.5,-31.5 -1.25,1.25"
+ id="path34906"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path34908"
+ d="M 48.65,-32.65 47.4,-31.4"
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient35772);fill-rule:evenodd;stroke:none"
+ d="m 41.5,-32.25 -4.25,0 6.5,6.25 0,-4"
+ id="path35770"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path35727"
+ d="m 38.25,-31.25 5.5,5.5"
+ style="fill:none;stroke:url(#linearGradient35748);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(47,-247.0151)"
+ id="g51988" />
+ <rect
+ y="73"
+ x="277.99997"
+ height="16"
+ width="16"
+ id="rect51964"
+ style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.65;display:inline"
+ id="g11875"
+ transform="translate(-334,109.04419)">
+ <path
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68937);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 433.14375,58.950006 -2.75,2.75"
+ id="path11878"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11880"
+ d="m 425.39375,56.700006 2.75,-2.75"
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68939);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g11883"
+ transform="translate(0,-0.044194)">
+ <path
+ transform="translate(459.95822,-187.9558)"
+ sodipodi:nodetypes="czzc"
+ id="path11885"
+ d="m -32.20822,242.24999 2,-2 c 3.74999,-3.75 8.74999,1.25 5,5 l -2,2"
+ style="fill:none;stroke:url(#linearGradient68941);stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="48"
+ x="423"
+ height="16"
+ width="16"
+ id="rect51637"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
+ <g
+ transform="translate(440,-188)"
+ id="g11891">
+ <path
+ transform="translate(-440,188.0442)"
+ id="path11895"
+ d="m 432.125,49.03125 c -1.30818,0.127946 -2.64484,0.727176 -3.75,1.8125 l -4.78125,4.6875 2.8125,2.875 4.78125,-4.71875 c 1.25772,-1.235151 1.98833,-0.85542 2.53125,-0.3125 0.54292,0.542919 0.91397,1.2336 -0.34375,2.46875 l -4.78125,4.6875 2.8125,2.875 4.78125,-4.71875 c 2.52607,-2.480751 2.30083,-6.16792 0.34375,-8.125 -0.97854,-0.978541 -2.36579,-1.53434 -3.84375,-1.53125 -0.18474,3.86e-4 -0.37562,-0.01828 -0.5625,0 z m 0.5625,0.875 c 1.23689,8.8e-4 2.39931,0.461809 3.21875,1.28125 1.63889,1.63889 1.89928,4.676909 -0.34375,6.875 l -4.28125,4.1875 -1.5625,-1.5625 4.3125,-4.21875 c 1.54471,-1.51377 1.17361,-2.857641 0.3125,-3.71875 -0.86111,-0.86111 -2.23654,-1.201271 -3.78125,0.3125 l -4.28125,4.1875 -1.5625,-1.5625 4.3125,-4.21875 c 1.12152,-1.09905 2.41936,-1.563381 3.65625,-1.5625 z"
+ style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path11897"
+ d="m -3.4321903,240.29419 c 0.82637,1.47069 0.7752067,3.63228 -0.8178097,5.23203 l -2.2237373,2.23314"
+ style="opacity:0.3;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.6"
+ id="g11899">
+ <path
+ sodipodi:nodetypes="czs"
+ id="path11901"
+ d="m 425.25,55.75 4.25,-4.25 c 1.59639,-1.596386 4.02931,-1.32637 5.5,-0.5"
+ style="fill:none;stroke:url(#linearGradient68943);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient68945);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 435,56 -4.75,4.75"
+ id="path11905"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-313,109)"
+ id="g51645"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect11909"
+ width="16"
+ height="16"
+ x="423"
+ y="48" />
+ <g
+ id="g11911"
+ transform="translate(440,-187.9558)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.79999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -15,245 4.79178,-4.70581 c 3.7837908,-3.7159 8.7837908,1.2841 5,5 L -10,250"
+ id="path51649"
+ sodipodi:nodetypes="czzc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czzc"
+ id="path51651"
+ d="m -14.5,244.5 4.29178,-4.20581 c 3.7877432,-3.71186 8.7877432,1.28814 5,5 L -9.5,249.5"
+ style="fill:none;stroke:url(#linearGradient68947);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68949);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -6.75,246.75 -9.5,249.5"
+ id="path51653"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path51655"
+ d="m -14.5,244.5 2.75,-2.75"
+ style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68951);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#481608;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -10.95822,242.99999 -2,-2"
+ id="path11922"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient68953);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -14.70822,243.74999 4.25,-4.25 c 1.5,-1.49999 3.5,-1.5 5,-0.75"
+ id="path11924"
+ sodipodi:nodetypes="czs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11926"
+ d="m -5.95822,247.99999 -2,-2"
+ style="fill:none;stroke:#481608;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11928"
+ d="m -4.95822,243.99999 -4.5,4.5"
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient68955);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cs"
+ id="path11930"
+ d="m -4.0503493,245.73202 c 1.5801026,-1.61251 1.6441797,-3.76134 0.8178097,-5.23203"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g28545"
+ transform="translate(21,-19)">
+ <g
+ style="opacity:0.8;display:inline"
+ mask="url(#mask69005)"
+ transform="matrix(0.646567,0,0,0.644332,-233.54872,129.49706)"
+ id="g36675">
+ <g
+ style="display:inline"
+ id="g36677"
+ transform="matrix(1.8217829,0,0,1.8217829,375.38164,-343.68741)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36680"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.14285731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7428442,0,0,0.7454212,30.426387,135.62554)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient51774);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path36682"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.6852904,-0.07823249,0.07810925,-0.6899628,209.72326,315.34566)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36684"
+ style="fill:none;stroke:url(#linearGradient51776);stroke-width:1.33333385;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6367237,0,0,0.6389323,44.434295,148.19125)" />
+ </g>
+ </g>
+ <g
+ transform="translate(-61.375,-188.625)"
+ id="g51790"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill-opacity:1;display:inline"
+ id="rect22754"
+ width="16"
+ height="16"
+ x="213.375"
+ y="343.625" />
+ <g
+ id="g51778">
+ <path
+ sodipodi:nodetypes="czscc"
+ id="path22715"
+ d="m 219.36593,351.65 0,-3.5 c 0,-2.025 1.25907,-2.525 2.50907,-2.525 1.25,0 2.5,0.5 2.49092,2.525 l 0,3.5"
+ style="fill:none;stroke:#000000;stroke-width:3.79999995;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient51804);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.36593,351.65 0.009,-3.275 c 0.006,-2.25 1.24773,-2.74375 2.5,-2.75 1.25227,-0.006 2.5,0.5 2.50907,2.725 l -0.0182,3.3"
+ id="path22717"
+ sodipodi:nodetypes="czscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22719"
+ d="m 224.35595,351.24375 0,0.53125"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient51806);stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient51808);stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.40595,351.72527 0,-0.50027"
+ id="path22721"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22723"
+ d="m 220.7625,350.275 -2,0"
+ style="fill:none;stroke:#803300;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#803300;stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 225.61593,350.15 -2.25,0"
+ id="path22725"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path22727"
+ d="m 218.61592,352.15 0,-4 c 0,-2.025 1.21963,-2.89049 2.75,-3.25"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient51810);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient51812);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 223.61593,352.15 0,-3.75115 c 0,-1.35618 -0.49093,-2.02385 -1.24093,-2.02385"
+ id="path22730"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.05;fill:none;stroke:#000000;stroke-width:0.73376155;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 225.24243,350.48448 c -0.001,-0.14034 0.0155,-2.61281 0,-2.75 -0.10562,-0.93297 -0.53761,-1.74673 -1.11525,-2.29782"
+ id="path22732"
+ sodipodi:nodetypes="css"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path22738"
+ d="m 220.11593,347.65 0,3.125"
+ style="opacity:0.02000002;fill:none;stroke:#000000;stroke-width:0.84999996;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g20285"
+ transform="translate(0,107.00001)">
+ <rect
+ y="449"
+ x="257"
+ height="16"
+ width="16"
+ id="rect19373"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.6;stroke:#162d50"
+ id="g19375"
+ transform="translate(14.081669,359)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path19377"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path19379"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path19381"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19385"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ style="fill:url(#linearGradient20275);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path19455"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ style="fill:none;stroke:url(#linearGradient20309);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient20269);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 260.5,454.5 0,4.9091"
+ id="path19387"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,455.5 1,0"
+ id="path19389"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path19391"
+ d="m 262.59506,453.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path19393"
+ d="m 258.5,454.63598 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,454.5 1,-1"
+ id="path19395"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path19397"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path20281"
+ d="m 263.5,452.5 0,9"
+ style="fill:none;stroke:url(#linearGradient20283);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient20303);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 258.5,454.3 0,5.4"
+ id="path20301"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g38213"
+ transform="translate(0,-1.00005)">
+ <rect
+ y="513.99988"
+ x="26"
+ height="16"
+ width="16"
+ id="rect38641"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36101">
+ <g
+ id="g22740"
+ style="opacity:0.7"
+ transform="translate(-116,424.99975)">
+ <g
+ transform="translate(-179,199.50012)"
+ id="g38620">
+ <path
+ id="path38622"
+ d="m 329.5,-108.25 -5.5,1.75 0,7.74988 6,2.09544 5,-2.84532 0,-6.75 -5.5,-2 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.00012 0,-7.49988 6,-1.75 0,11.5 -0.5,0.25 -5.5,-2.50012 z"
+ id="path38624"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g38626">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#787878;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path38628"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path38630"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient38718);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.25012 0,-7.24988"
+ id="path38632"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient38721);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 145.5,93.25012 c 0,0 5,2.25 5,2.25 l 5,-2.25"
+ id="path38634"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.19199997;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38636"
+ width="1"
+ height="7.75"
+ x="150"
+ y="95.000122" />
+ <rect
+ y="95.25"
+ x="151"
+ height="7.75"
+ width="1"
+ id="rect22687"
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ rx="0"
+ ry="0"
+ y="526.49988"
+ x="33.5"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect38643"
+ style="fill:none;stroke:#783e00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="0"
+ ry="0"
+ y="516.49988"
+ x="27.5"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect38645"
+ style="fill:none;stroke:#783e00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:none;stroke:#783e00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38647"
+ width="2.9999485"
+ height="3.0001416"
+ x="27.5"
+ y="524.49969"
+ ry="0"
+ rx="0" />
+ <rect
+ style="fill:none;stroke:#783e00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38649"
+ width="2.9999485"
+ height="3.0001416"
+ x="33.5"
+ y="518.49969"
+ ry="0"
+ rx="0" />
+ <rect
+ style="opacity:0.06000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38754"
+ width="3.9785564"
+ height="4"
+ x="34.021442"
+ y="519.00006" />
+ <rect
+ rx="0"
+ ry="0"
+ y="518.99976"
+ x="34"
+ height="2.0000772"
+ width="1.9999485"
+ id="rect39152"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="rect28386"
+ d="m 28,519.50001 -0.5,0 0,-3.00014 2.99995,0"
+ style="fill:none;stroke:#462500;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#462500;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 28,524.50001 -0.5,0 0,3.00014 2.99995,0"
+ id="path28390"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path28392"
+ d="m 33.5,527.75001 -9e-5,1.75004 3.00014,0 -5e-5,-1.75004"
+ style="fill:none;stroke:#462500;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="517.00006"
+ x="28.021444"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0-2"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28536"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000046"
+ y="517"
+ ry="0"
+ rx="0" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28538"
+ width="1.9999485"
+ height="2.0000772"
+ x="34.000046"
+ y="527"
+ ry="0"
+ rx="0" />
+ <rect
+ y="525.00006"
+ x="28.021444"
+ height="1.9999889"
+ width="3.9785564"
+ id="rect38756"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect28540"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000046"
+ y="525"
+ ry="0"
+ rx="0" />
+ </g>
+ </g>
+ <g
+ id="g39255"
+ transform="translate(-21,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39088"
+ width="16"
+ height="16"
+ x="173"
+ y="70.976562" />
+ <g
+ id="g39227">
+ <g
+ transform="translate(1.0000047,-0.02344036)"
+ id="g39109">
+ <g
+ transform="translate(8,8)"
+ id="g39113">
+ <rect
+ ry="0"
+ y="72.5"
+ x="173.5"
+ height="6"
+ width="5"
+ id="rect39115"
+ style="fill:url(#linearGradient39281);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="fill:#333333"
+ transform="matrix(-1,0,0,-1,352,144)"
+ id="g39117" />
+ <rect
+ ry="0"
+ style="fill:none;stroke:url(#linearGradient39283);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39119"
+ width="2.9999952"
+ height="4.0000029"
+ x="174.52599"
+ y="73.523438" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path39123"
+ d="m 183.25,82.5 c 0.25,0 1.5,0 1.5,0 l -1.5,0 z m 0,2 1.5,0 -1.5,0 z"
+ style="fill:none;stroke:#333333;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-6.9999953,-9.0234404)"
+ id="g39125">
+ <g
+ id="g39127"
+ transform="translate(8,8)">
+ <rect
+ style="fill:url(#linearGradient39285);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39129"
+ width="5"
+ height="6"
+ x="173.5"
+ y="72.5"
+ ry="0" />
+ <g
+ id="g39131"
+ transform="matrix(-1,0,0,-1,352,144)"
+ style="fill:#333333" />
+ <path
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 177,73.02344 0,1 -1,0 0,-1 1,0 z m -1,1 0,1 -1,0 0,-1 1,0 z m -1,0 -1,0 0,-1 1,0 0,1 z m 0,1 0,1 -1,0 0,-1 1,0 z m 0,1 1,0 0,1 -1,0 0,-1 z m 0,1 0,1 -1,-1 1,0 z m 1,0 1,0 0,1 -1,0 0,-1 z m 1,0 0,-1 1,0 0,1 -1,0 z m 0,-1 -1,0 0,-1 1,0 0,1 z m 0,-1 0,-1 1,0 0,1 -1,0 z"
+ id="rect39177"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39287);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 174.52599,77.52344 0,-4.000002 2.99999,0"
+ id="rect39133"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39149"
+ transform="translate(1,-9)">
+ <g
+ transform="translate(8,8)"
+ id="g39151">
+ <rect
+ ry="0"
+ y="72.5"
+ x="173.5"
+ height="6"
+ width="5"
+ id="rect39153"
+ style="fill:url(#linearGradient39289);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="fill:#333333"
+ transform="matrix(-1,0,0,-1,352,144)"
+ id="g39155" />
+ <rect
+ ry="0"
+ style="fill:none;stroke:url(#linearGradient39291);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39157"
+ width="2.9999952"
+ height="4.0000029"
+ x="174.52599"
+ y="73.523438" />
+ </g>
+ </g>
+ <g
+ transform="translate(-7,0)"
+ id="g39163">
+ <g
+ id="g39165"
+ transform="translate(8,8)">
+ <rect
+ style="fill:url(#linearGradient39293);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39167"
+ width="5"
+ height="6"
+ x="173.5"
+ y="72.5"
+ ry="0" />
+ <g
+ id="g39169"
+ transform="matrix(-1,0,0,-1,352,144)"
+ style="fill:#333333" />
+ <rect
+ y="73.523438"
+ x="174.52599"
+ height="4.0000029"
+ width="2.9999952"
+ id="rect39171"
+ style="fill:none;stroke:url(#linearGradient39295);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(168,-37)"
+ id="g39106">
+ <g
+ style="opacity:0.5;display:inline"
+ id="g39108"
+ transform="translate(69,-142)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39110"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g39112">
+ <g
+ transform="translate(-386,446.5)"
+ id="g39114">
+ <path
+ id="path39116"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path39118"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g39120">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path39122"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path39124"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient39008);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ id="path39126"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient39010);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39128"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39012);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ id="path39130"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="197"
+ x="7.0214434"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0-11"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="204"
+ x="7.0214434"
+ height="3"
+ width="3.9785564"
+ id="rect37868-0-7"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g39132"
+ transform="matrix(0.8303712,0,0,0.8404094,-87.641227,155.05106)">
+ <g
+ id="g39134">
+ <path
+ id="path39136"
+ d="m 115.18474,49.326679 0.0443,0 c 0.98532,0 1.77856,0.793241 1.77856,1.778566 l 0,1.46e-4 c 0,0.985326 -0.79324,1.778566 -1.77856,1.778566 l -0.0443,0 c -0.98533,0 -1.77857,-0.79324 -1.77857,-1.778566 l 0,-1.46e-4 c 0,-0.985325 0.79324,-1.778566 1.77857,-1.778566 z"
+ style="fill:none;stroke:#000000;stroke-width:1.78961492;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path39138"
+ d="m 116.40772,49.919572 c -0.80364,0 -1.60728,1.2e-5 -2.41092,1.2e-5 0,0.793735 0,1.587459 0,2.381206 0.80364,0 1.60728,-1.2e-5 2.41092,-1.2e-5 0,-0.793735 0,-1.587471 0,-2.381206 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.78961492;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 115.18474,57.651268 0.0443,0 c 0.98532,0 1.77856,0.793241 1.77856,1.778566 l 0,1.46e-4 c 0,0.985326 -0.79324,1.778566 -1.77856,1.778566 l -0.0443,0 c -0.98533,0 -1.77857,-0.79324 -1.77857,-1.778566 l 0,-1.46e-4 c 0,-0.985325 0.79324,-1.778566 1.77857,-1.778566 z"
+ id="path37768"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 116.40772,58.244161 c -0.80364,0 -1.60728,1.2e-5 -2.41092,1.2e-5 0,0.793735 0,1.587459 0,2.381206 0.80364,0 1.60728,-1.2e-5 2.41092,-1.2e-5 0,-0.793735 0,-1.587471 0,-2.381206 z"
+ id="path37770"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(168,-37)"
+ id="g39140">
+ <g
+ transform="translate(90,-142)"
+ id="g39142"
+ style="opacity:0.5;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect39144"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39146"
+ transform="translate(1,0)">
+ <g
+ id="g39148"
+ transform="translate(-386,446.5)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ id="path39150"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path39152"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39154"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39156"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39158"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39160"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient39014);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect39162"
+ style="fill:url(#linearGradient39016);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path39164"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient39018);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="198"
+ x="29"
+ height="8"
+ width="2.0000007"
+ id="rect37868-0-14"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="201"
+ x="32.021442"
+ height="7"
+ width="3.9785564"
+ id="rect37868-0-3"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-1081.9421,-238.02038)"
+ style="fill:#ffeeaa;display:inline"
+ id="g39166">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect39168"
+ width="1.9820247"
+ height="8.0116062"
+ x="1109.4872"
+ y="435.4964"
+ transform="matrix(1,2.1226448e-5,0,1,0,0)" />
+ <rect
+ transform="matrix(1,3.6759233e-5,0,1,0,0)"
+ y="435.97955"
+ x="1109.958"
+ height="7.0000257"
+ width="0.99999994"
+ id="rect39170"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ transform="matrix(1,2.1226448e-5,0,1,0,0)"
+ y="438.49628"
+ x="1114.4713"
+ height="8.0116062"
+ width="1.9820247"
+ id="rect37773"
+ style="fill:#d5e5ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect37775"
+ width="0.99999994"
+ height="7.0000257"
+ x="1114.9421"
+ y="438.97937"
+ transform="matrix(1,3.6759233e-5,0,1,0,0)" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(168,-37)"
+ id="g39172">
+ <g
+ style="opacity:0.5;display:inline"
+ id="g39174"
+ transform="translate(111,-142)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39176"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g39178">
+ <g
+ transform="translate(-386,446.5)"
+ id="g39180">
+ <path
+ id="path39182"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path39184"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g39186">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path39188"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path39190"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient39020);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ id="path39192"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient39022);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39194"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39024);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ id="path39196"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="201"
+ x="54"
+ height="7"
+ width="2.9785564"
+ id="rect37868-0-57"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-1080.9861,-240)"
+ style="fill:#ffeeaa;display:inline"
+ id="g39198">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path39200"
+ d="m 1130.4859,445.25 0,-7.5 6,2.75 0,8 -6,-3.25 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient39026);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g28811"
+ transform="translate(0,128.00001)">
+ <rect
+ y="365"
+ x="194"
+ height="16"
+ width="16"
+ id="rect28809"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g23255"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0004639,0,0,0.9963165,-69.122722,304.28985)">
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23257"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.86138636;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.81218,0,0,0.815735,163.7897,-27.2907)" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.98701,62.965769 0.0109,7.256732 c -1.99907,0 -3.99814,-0.250925 -6.00812,-1.234549 0,-3.324245 2.68676,-6.022183 5.99722,-6.022183 l 0,0 0,0 0,0 z m 0.0109,7.256732 c 1.99908,0 3.99815,-0.250925 5.98632,-1.234549 0,3.324245 -2.68675,6.022182 -5.99722,6.022182 l 0.0109,-4.787633 0,0 0,0 0,0 z"
+ id="path23259"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient23274);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path23261"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)" />
+ <path
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23263"
+ style="opacity:0.1;fill:url(#linearGradient23276);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.624782,0,0,0.627489,188.53052,-5.0185058)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23265"
+ style="opacity:0.8;fill:url(#linearGradient23278);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.40226042;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.70545,67.406839 c 0.34141,-0.888253 0.96594,-1.399916 1.66978,-1.680902"
+ id="path23267"
+ sodipodi:nodetypes="cs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23269"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.6;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;filter:url(#filter13996)"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23271"
+ style="fill:none;stroke:url(#linearGradient23280);stroke-width:1.45689511;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6875,0,0,0.6875,180.25,-12.125)" />
+ </g>
+ </g>
+ <g
+ id="g40234">
+ <rect
+ y="514.00012"
+ x="5"
+ height="15.99988"
+ width="16"
+ id="rect40163"
+ style="opacity:0;fill:#f6d0a6;fill-opacity:1;fill-rule:evenodd;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g40089"
+ transform="translate(70,178)">
+ <g
+ id="g40091"
+ transform="translate(-386,446.5)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#422200;fill-opacity:1;fill-rule:evenodd;stroke:#281500;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ id="path40093"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path40095"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#efa351;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g40097"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40099"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#915515;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40101"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#f5ca9b;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40103"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient40171);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect40106"
+ style="fill:url(#linearGradient40173);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path40109"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient40175);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g57337"
+ transform="translate(10,254)" />
+ <g
+ style="display:inline"
+ id="g57399"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0004639,0,0,0.9963165,-237.12363,495.28986)">
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path57401"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.86138636;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.81218,0,0,0.815735,163.7897,-27.2907)" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.98701,62.965769 0.0109,7.256732 c -1.99907,0 -3.99814,-0.250925 -6.00812,-1.234549 0,-3.324245 2.68676,-6.022183 5.99722,-6.022183 l 0,0 0,0 0,0 z m 0.0109,7.256732 c 1.99908,0 3.99815,-0.250925 5.98632,-1.234549 0,3.324245 -2.68675,6.022182 -5.99722,6.022182 l 0.0109,-4.787633 0,0 0,0 0,0 z"
+ id="path57403"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient57417);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path57405"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)" />
+ <path
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path57407"
+ style="opacity:0.1;fill:url(#linearGradient57419);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.624782,0,0,0.627489,188.53052,-5.0185058)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path57409"
+ style="opacity:0.8;fill:url(#linearGradient57421);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.40226042;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.70545,67.406839 c 0.34141,-0.888253 0.96594,-1.399916 1.66978,-1.680902"
+ id="path57411"
+ sodipodi:nodetypes="cs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path57413"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.6;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;filter:url(#filter13996)"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path57415"
+ style="fill:none;stroke:url(#linearGradient57423);stroke-width:1.45689511;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6875,0,0,0.6875,180.25,-12.125)" />
+ </g>
+ <g
+ style="display:inline"
+ id="g22832"
+ transform="translate(73,-15)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22222"
+ width="16"
+ height="16"
+ x="-68"
+ y="256" />
+ <g
+ id="g22818">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m -66.5,257.5 5,0 c 0,1 3,1 3,0 l 5,0 0,5 -2,0 -2.9e-4,8 -8.99971,-5e-5 0,-7.99995 -2,0 0,-5 z"
+ id="path22864"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="rect22236"
+ d="m -66.5,257.5 4.75,0 c -0.5,3.25 4,3.25 3.5,0 l 4.75,0 0,5 -2,0 -2.9e-4,8 -8.99971,-5e-5 0,-7.99995 -2,0 0,-5 z"
+ style="fill:url(#linearGradient22905);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient22891);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -66,258 4,0 c 0,2.5 4,2.5 4,0 l 4,0 0,4 -2,0 0,8 -8,0 0,-8 -2,0 0,-4 z"
+ id="path23050"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path23055"
+ d="m -66,258 4,0 c 0,0.61505 0.242101,1.07878 0.607179,1.3912 L -61.5,259.5 -64,262 l -2,0 0,-4 z"
+ style="fill:url(#linearGradient22893);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient22895);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -54,258 -4,0 c 0,0.61505 -0.242101,1.07878 -0.607179,1.3912 L -58.5,259.5 l 2.5,2.5 2,0 0,-4 z"
+ id="path23059"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient22897);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -56.5,262.75 0,6.75 -7,0 0,-7.5"
+ id="path22238"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22276"
+ d="m -56.5,269.5 -7,0 m -2,-8 0,-3 m 11,0 0,3 m -8,-3 c 0.5,2.75 4.5,2.75 5,0"
+ style="fill:none;stroke:url(#linearGradient22899);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23065"
+ d="m -63.5,264.5 c 0.75,3.5 4.25,5.5 7,3"
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient22901);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.85;fill:none;stroke:url(#linearGradient22903);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-opacity:1;stroke-dasharray:none"
+ d="m -63.5,263.5 c 1,3.5 4.25,5.5 7,3"
+ id="path23063"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g23071"
+ transform="translate(0,1)"
+ style="opacity:0.9">
+ <path
+ style="opacity:0.4;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -60.5,262.5 1,0 0,2.75"
+ id="path23069"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path23067"
+ d="m -60.5,262.5 1,0 0,2.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-105,-229)"
+ id="g22900"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22902"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904"
+ style="opacity:0.6;stroke:#162d50">
+ <path
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#162d50;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.9;fill:none;stroke:#d5e5ff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22910"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:url(#linearGradient22933);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22924"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path22926"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#d5e5ff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22939);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient22941);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23411"
+ transform="translate(-399,-19)">
+ <rect
+ transform="scale(-1,1)"
+ y="260"
+ x="-441"
+ height="16"
+ width="16"
+ id="rect22167"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23378">
+ <g
+ transform="translate(-36.00033,108.00006)"
+ id="g22183">
+ <path
+ style="fill:url(#linearGradient23445);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.66961 -3,1.5 l 0,8 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 0,-8 c 0,-0.83039 -1.0691,-1.5 -3,-1.5 z"
+ id="path22187"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23447);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 470.50029,158.5 0,7.51105 c 0,0.54648 1,0.54648 2,0.54648 1,0 2,0 2,-0.55753 l 0,-7.51105"
+ id="path22189"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#eff6ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22199"
+ sodipodi:cx="108"
+ sodipodi:cy="-222"
+ sodipodi:rx="3.3084693"
+ sodipodi:ry="1.2798798"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
+ transform="matrix(0.9067635,0,0,1.3047091,374.56954,447.97555)" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path22203"
+ d="m 472.50029,156.5 c -1.9309,0 -3,0.5 -3,1.5 l 0,8 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 0,-8 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cssc"
+ id="path23068"
+ d="m 436.5,265.5 0,-0.75 c 0,-4.25 -7,-4.25 -7,0 l 0,2.75"
+ style="opacity:0.55;fill:none;stroke:#0b1728;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.1;fill:none;stroke:#e1e08e;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22214"
+ width="2.9999998"
+ height="3"
+ x="428"
+ y="266"
+ rx="1.2002208"
+ ry="1.2002208" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#0b1728;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 436.5,265.5 0,-0.75"
+ id="path23343"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#d7e3f4;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 436.5,265.5 0,-0.75 c 0,-4.25 -7,-4.25 -7,0 l 0,2.75"
+ id="path22210"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.2002209"
+ y="266"
+ x="428"
+ height="3"
+ width="3"
+ id="rect22216"
+ style="opacity:0.4;fill:#a09f2c;fill-opacity:1;fill-rule:nonzero;stroke:#d6d562;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="1.2002209" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23005"
+ d="m 427,266 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 427,270 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23007"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23009"
+ d="m 430.99994,270 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#8c8b0a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.99994,266.00006 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23012"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#545306;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 428.25,266.25 0.75,-0.75 1,0 0.75,0.75 0.75,0.75 0,1 -0.75,0.75 -0.75,0.75 -1,0 -0.75,-0.75 -0.75,-0.75 0,-1 0.75,-0.75 z"
+ id="rect23002"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path22218"
+ d="m 428,267 c 1,0 1.99998,10e-6 2.99998,10e-6 0,0.33335 0,0.6667 0,1.00005 -1,0 -1.99998,-1e-5 -2.99998,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 428.99996,269 c 0,-0.99999 1e-5,-1.99995 1e-5,-2.99994 0.33335,0 0.6667,0 1.00005,0 0,0.99999 -1e-5,1.99995 -1e-5,2.99994 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path22220"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 427,266 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23312"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23314"
+ d="m 427,270 c 0,-0.33336 10e-6,-0.6667 10e-6,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.99994,270 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ id="path23316"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23318"
+ d="m 430.99994,266.00006 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.6667,0 1.00005,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.6667,0 -1.00005,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.65"
+ id="g23333"
+ transform="translate(464,-83)">
+ <g
+ id="g23320">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23014"
+ d="m -38,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ style="fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#504f14;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#504f14;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -32.000059,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 l 0,0 0,0 0,0 z"
+ id="path23016"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23018"
+ d="m -35,354 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ style="fill:#8c8b25;fill-opacity:1;fill-rule:nonzero;stroke:#504f14;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23325"
+ style="fill:#ffffff;stroke:none">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -38,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ id="path23327"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23329"
+ d="m -32.000059,351 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -10e-6,0.6667 -10e-6,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -35,354 c 0,-0.33336 1e-5,-0.6667 1e-5,-1.00006 0.33335,0 0.666699,0 1.000049,0 0,0.33336 -1e-5,0.6667 -1e-5,1.00006 -0.33335,0 -0.666699,0 -1.000049,0 z"
+ id="path23331"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g22853"
+ transform="translate(4.2e-4,2.056923)">
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g22355"
+ transform="translate(296.99995,249.99998)">
+ <rect
+ transform="matrix(1,5.248259e-6,0,1,0,0)"
+ y="15.999177"
+ x="155.00008"
+ height="3.9999785"
+ width="4.0000005"
+ id="rect22359"
+ style="fill:url(#linearGradient23531);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect22365"
+ width="4.9999776"
+ height="4.9999595"
+ x="154.50008"
+ y="15.499179"
+ transform="matrix(1,5.248259e-6,0,1,0,0)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22367"
+ d="m 155.50007,19.49999 -5.5e-4,-3.000005 2.99988,5e-6 6.8e-4,3 -3.00001,0 0,0 0,0 0,0 z"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient23533);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(187.99958,-21.0368)"
+ id="g23427">
+ <g
+ transform="translate(170.04549,179.51905)"
+ id="g23429"
+ style="opacity:0.7">
+ <path
+ style="fill:none;stroke:#214478;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.45451,103.98095 0,11 11,0 0,-11 -11,0 z"
+ id="path23431"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23433"
+ d="m 90.45451,103.98095 0,11 11,0 0,-11 -11,0 z"
+ style="fill:none;stroke:#afc6e9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23435">
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="293.5"
+ x="270.49985"
+ height="3"
+ width="2.9998772"
+ id="rect23438"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23440"
+ width="2.9998772"
+ height="3"
+ x="258.50024"
+ y="281.5368"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="293.49997"
+ x="258.49969"
+ height="3"
+ width="2.9998772"
+ id="rect23442"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 273,294 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path23444"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23446"
+ d="m 261,294 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23448"
+ d="m 261.00042,282.0368 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23450"
+ width="2.9998772"
+ height="3"
+ x="270.49985"
+ y="281.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23452"
+ d="m 273,282 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g40939"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31966"
+ width="16"
+ height="16"
+ x="47"
+ y="260" />
+ <g
+ transform="translate(0,21)"
+ id="g40631">
+ <rect
+ style="fill:#87aade;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40597"
+ width="5"
+ height="3"
+ x="56.500004"
+ y="240.5" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40599"
+ d="m 48.5,244.5 5,0 0,3 8,0 0,6 -13,0 0,-9 z"
+ style="fill:url(#linearGradient40965);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ d="m 49,250.5 12,0 m -4.5,-2.5 0,2.5 m -5,-2.5 0,2.5 m 2,2.5 0,-2.5 m 5,2.5 0,-2.5 m -5.5,-3 -4,0"
+ style="fill:none;stroke:url(#linearGradient40967);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ id="path40601"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 48.5,244.5 5,0 0,3 8,0 0,6 -13,0 0,-9 z"
+ id="path40603"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40605"
+ d="m 49.5,246.5 0,-1 3,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 49.5,249.5 0,-1 1,0"
+ id="path40615"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 57.5,242.5 0,-1 3,0"
+ id="use40619"
+ inkscape:connector-curvature="0" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40963"
+ transform="translate(3,3)"
+ width="600"
+ height="512" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40969"
+ transform="translate(8,3)"
+ width="600"
+ height="512"
+ style="opacity:0.9" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40971"
+ transform="translate(0,6)"
+ width="600"
+ height="512" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40605"
+ id="use40973"
+ transform="translate(5,6)"
+ width="600"
+ height="512" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path40615"
+ id="use40975"
+ transform="translate(10,3)"
+ width="600"
+ height="512"
+ style="opacity:0.9" />
+ </g>
+ </g>
+ <g
+ id="g40825"
+ transform="translate(0,1)">
+ <rect
+ y="260"
+ x="215"
+ height="16"
+ width="16"
+ id="rect40827"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g40829"
+ transform="translate(67.999923,253.00001)">
+ <path
+ style="fill:url(#linearGradient40843);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 148.50005,9.5 7.00001,3.68e-5 1e-5,2.9999632 -4,0 0,4 -3.00002,0.0039 0,-7.00391 0,10e-6 z"
+ id="path40831"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(1,5.248259e-6,0,1,0,0)"
+ y="14.499187"
+ x="153.49606"
+ height="6.9999576"
+ width="7.004014"
+ id="rect40833"
+ style="fill:url(#linearGradient40845);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40835"
+ d="m 148.50005,9.5 7.00001,3.68e-5 1e-5,2.9999632 -4,0 0,4 -3.00002,0.0039 0,-7.00391 0,10e-6 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 149.50015,15.500012 7e-5,-5.000011 4.99993,0"
+ id="path40837"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect40839"
+ width="7.004014"
+ height="6.9999576"
+ x="153.49606"
+ y="14.499187"
+ transform="matrix(1,5.248259e-6,0,1,0,0)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path40841"
+ d="m 154.50063,20.499995 6e-5,-4.999998 4.99933,0 6e-5,4.999993 -4.99945,5e-6 z"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient40847);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23613" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(404,214.02012)"
+ id="g13021">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12989"
+ width="16"
+ height="16"
+ x="63"
+ y="48" />
+ <g
+ id="g12991"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline"
+ transform="matrix(1.0003553,0,0,0.9995949,19.983834,-40.953347)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.35;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect13004"
+ width="10.996093"
+ height="11.004457"
+ x="45.5"
+ y="91.49041" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.2;fill:none;stroke:url(#linearGradient23510);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 46.499645,101.49618 0,-9.003652 8.996803,-0.0017 0,9.003642 -8.996803,0.002 0,-2.9e-4 0,0 0,0 z"
+ id="path13009"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient23512);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 53.247247,91.490409 3.248846,0.0015 0,11.002931 -10.996093,1e-5 0,-3.251316 7.747247,-7.753141 0,1.6e-5 z"
+ id="rect12993"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient23514);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 46.499451,101.49446 1.94e-4,-1.750708 7.247425,-7.252938 1.749378,0 10e-7,9.001936 -8.996998,0.002 0,-2.9e-4 0,0 0,0 z"
+ id="path12995"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-0.9999998,2.020123)"
+ id="g23516">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23518"
+ width="16"
+ height="16"
+ x="489"
+ y="260" />
+ <path
+ sodipodi:nodetypes="cssc"
+ d="m 499.5,261.50004 -4.5,2 c -1.94148,0.86288 -2.18285,2.53884 -3,4.5 l -1.25,3"
+ style="fill:none;stroke:#0b1728;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23520"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path23522"
+ d="m 503,268.00008 0,2.99996 -3,1.5 c -3,1.5 -6.25,1.5 -10,1.49996 l 0,-2.49996 c 0.5,-0.99996 1.75,-2.75004 5,-4.00004 l 4,-1.5 1,0 3,1.25 0,0.75008 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23524"
+ d="m 495,267.5 4,-1.5 1,0 3,1.25 0,0.75004 0,2.75 -3,1.5 -10,1.5 0,-1.75 c 0.5,-1 1.77456,-3.24182 5,-4.50004 z"
+ style="fill:#c2d4ef;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23542"
+ style="fill:none;stroke:url(#linearGradient23555);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 496.75,263.00004 c -3,1.5 -2.75,8.5 2.25,7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient23581);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 519.82031,262 c 0.5,-0.16016 0.35115,-1.44373 -0.66015,-1 l -3.91016,1.75 c -2.5,0.75 -2.85099,2.90496 -3.82813,5.08203 L 510,271 l 0,3 c 3.76795,10e-6 7,0 10,-1.5 0.59071,-0.29535 2.31945,-1.15973 3,-1.5 l 0,-3 c -0.71506,0.35798 -2.3836,1.1918 -3,1.5 -0.45529,0.22765 -0.90706,0.42996 -1.375,0.59375 -4.60397,1.02313 -4.54405,-5.38421 -1.625,-6.84375 l 2.82031,-1.25 z"
+ transform="translate(-20,0)"
+ id="path23526"
+ sodipodi:nodetypes="cccsccsccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:none;stroke:url(#linearGradient23550);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 490.5,273.51739 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
+ id="path23528"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23530"
+ width="2"
+ height="1"
+ x="497"
+ y="267" />
+ <g
+ id="g23575"
+ style="fill:#000000">
+ <rect
+ style="opacity:0.8;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23532"
+ width="2"
+ height="1"
+ x="497"
+ y="268" />
+ <rect
+ y="267"
+ x="496"
+ height="1.5"
+ width="1"
+ id="rect23534"
+ style="opacity:0.6;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.6;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23536"
+ width="1"
+ height="1.5"
+ x="499"
+ y="267" />
+ <rect
+ y="266.5"
+ x="497"
+ height="0.5"
+ width="2"
+ id="rect23538"
+ style="opacity:0.5;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ sodipodi:nodetypes="csc"
+ id="path23540"
+ d="m 490.5,272.5 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
+ style="fill:none;stroke:url(#linearGradient23585);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23546"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 499.5,261.50004 -3.07779,1.36791 L 495,263.50004 c -1.94148,0.86288 -2.18285,2.53884 -3,4.5 l -1.25,3"
+ sodipodi:nodetypes="ccssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23587"
+ transform="translate(-42.01991,-103.9242)">
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23589"
+ width="16"
+ height="16"
+ x="-382.01102"
+ y="403.99695" />
+ <g
+ id="g23591">
+ <rect
+ style="fill:none;stroke:#04090f;stroke-width:2.89999986;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23594"
+ width="8.4671335"
+ height="5.6703448"
+ x="-33.946648"
+ y="-559.34406"
+ ry="2.143424"
+ rx="2.1489482"
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)" />
+ <rect
+ rx="2.1489475"
+ ry="2.1434233"
+ y="-557.84644"
+ x="-28.308893"
+ height="5.5734196"
+ width="8.5043812"
+ id="rect23596"
+ style="fill:none;stroke:#04090f;stroke-width:2.89999986;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24349);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 411.51991,375.4242 -0.5,-0.5 c -0.69131,-0.69131 -0.87523,-2.06255 1.2e-4,-2.92851 l 3.01169,-2.97968 c 0.87526,-0.86596 2.29698,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ id="path23598"
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:0.10736198;fill-rule:nonzero;stroke:#04090f;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.50000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 408.98474,371.9281 c 0.84182,-0.84182 2.19551,-0.84356 3.03517,-0.004"
+ id="path23561"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ id="path24352"
+ d="m 411.51991,375.4242 -0.5,-0.5 c -0.69131,-0.69131 -0.87523,-2.06255 1.2e-4,-2.92851 l 3.01169,-2.97968 c 0.87526,-0.86596 2.29698,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ style="opacity:0.68999999;fill:none;stroke:url(#radialGradient24354);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23600"
+ style="fill:none;stroke:url(#linearGradient24341);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 407.52985,379.36839 c 0.5623,0.50813 1.81497,0.33519 2.49825,-0.3481 l 2.95063,-3.084 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.95063,3.08399 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 1e-5,-9e-5 0,0 0,0 z"
+ sodipodi:nodetypes="ccccccczz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccczz"
+ d="m 407.52985,379.36839 c 0.5623,0.50813 1.81497,0.33519 2.49825,-0.3481 l 2.95063,-3.084 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.95063,3.08399 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 1e-5,-9e-5 0,0 0,0 z"
+ style="fill:none;stroke:url(#radialGradient23610);stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path23602"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:0.10736198;fill-rule:nonzero;stroke:#04090f;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.50000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.01991,375.9242 c -0.84182,0.84182 -2.16034,0.83966 -3,0"
+ id="path23563"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssssc"
+ id="path23604"
+ d="m 417.52541,369.52542 0.49841,0.4984 c 0.68807,0.68805 0.86671,2.11766 -0.004,2.98828 l -2.99178,2.99178 c -0.68328,0.68328 -1.74799,0.71589 -2.49825,0.34809 -0.18628,-0.0913 -0.37463,-0.2925 -0.51148,-0.42936 l -0.7484,-0.74841"
+ style="fill:none;stroke:url(#radialGradient23612);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22800"
+ transform="translate(-21,2)">
+ <rect
+ y="260"
+ x="530"
+ height="16"
+ width="16"
+ id="rect23587"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.35;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect23591"
+ width="4.0000005"
+ height="15"
+ x="533.5"
+ y="260.5" />
+ <path
+ style="fill:url(#linearGradient22847);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 533.5,275.5 4,0 0,-1 c 0,-2.5 2,-5 5,-5 l 1,0 0,-4 -1,0 c -5.17135,0 -9,3.25 -9,9 l 0,1 z"
+ id="path23595"
+ sodipodi:nodetypes="ccssccssc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.2;fill:none;stroke:url(#linearGradient22849);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 534.50003,274.5 0,-12.99752 1.99998,-0.002 0,12.99752 -1.99998,0.002 z"
+ id="path23593"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23709"
+ d="m 542.5,266.5 c -4.89085,0.22833 -7.75,2.75 -8,8"
+ style="fill:none;stroke:url(#linearGradient22851);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23347"
+ transform="translate(251.98387,128)"
+ style="display:inline">
+ <rect
+ y="428"
+ x="26.016129"
+ height="16.000002"
+ width="16.000006"
+ id="rect23350"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23352"
+ width="16"
+ height="16"
+ x="26"
+ y="428" />
+ <g
+ style="display:inline"
+ id="g23354"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0004639,0,0,0.9963165,-237.11238,367.28985)">
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23356"
+ style="fill:#724c4c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10749674;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.81218,0,0,0.815735,163.7897,-27.2907)" />
+ <path
+ transform="matrix(0.7480284,0,0,0.7480284,172.26025,-19.267349)"
+ sodipodi:type="arc"
+ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.16363633;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23358"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.7478104,0,0,0.7510504,172.29077,-19.598754)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23360"
+ style="opacity:0.6;fill:url(#linearGradient23373);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ id="path40668"
+ d="m 269.98748,62.965763 c -1.39411,0.455357 -2.67784,0.634788 -4.24803,3.011091 l 2.24896,0 1.99907,-3.011091 0,0 0,0 0,0 z m 0.99954,0 0,3.011091 2.99861,0 -1.99908,-3.011091 -0.99953,0 z m 2.99861,3.011091 0.99953,3.011091 1.99907,0 c 0.006,-0.929403 -0.1914,-1.917894 -0.74965,-3.011091 l -2.24895,0 0,0 0,0 0,0 z m 0.99953,3.011091 -3.99814,0 0,3.011092 2.49884,0 1.4993,-3.011092 z m -3.99814,3.011092 -2.99861,0 1.99907,3.011091 0.99954,0 0,-3.011091 0,0 0,0 0,0 z m -2.99861,0 -0.99954,-3.011092 -1.99907,0 c -0.006,0.929404 0.1914,1.917895 0.74965,3.011092 l 2.24896,0 0,0 0,0 0,0 z m -0.99954,-3.011092 3.99815,0 0,-3.011091 -2.49884,0 -1.49931,3.011091 0,0 0,0 0,0 z m 7.24312,3.011092 -1.85125,3.011091 c 1.3675,-0.485137 2.19971,-0.728674 3.85384,-3.011091 l -2.00259,0 z"
+ style="fill:url(#linearGradient23375);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#990d18;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 274.00069,72.011668 0.005,0.97479 -0.99045,0.01431 -0.0223,1.019377 -0.481,0.837285 c 0.77072,-0.321774 2.72643,-1.067855 3.69499,-2.816464 l -2.20604,-0.0293 -2e-4,2e-6 0,0 0,0 z"
+ id="path23365"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#linearGradient23377);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path40671"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23369"
+ style="fill:none;stroke:url(#linearGradient23379);stroke-width:1.14049816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.7010701,0,0,0.7040938,178.4346,-14.083074)" />
+ <path
+ id="path23371"
+ d="m 268.98793,64.973163 0,0.407752 -0.93706,0 0,0.595945 -0.56224,0 0,1.003697 -0.49977,0 0,1.505546 0.99953,0 0,-1.505546 0.4373,0 0,-0.595945 0.56224,0 0,-0.407752 1.53054,0 0,-1.003697 -1.53054,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#aaccff;stroke-width:0;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22826"
+ transform="translate(21,-18.979877)">
+ <rect
+ y="281"
+ x="509"
+ height="16"
+ width="16"
+ id="rect22743"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22808">
+ <g
+ id="g23567">
+ <path
+ style="fill:url(#linearGradient23565);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 511.5,282.5 1.25,0 1.5,1 5.5,0 1.5,-1 1.25,0 0,8.25 c 0,6.25 -11,6.25 -11,0 l 0,-8.25 z"
+ id="path22751"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient23562);stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 512.5,291 0,-7.25 c 0.8354,1.24437 8.04784,1.12713 9,0 l 0,7.25 c 0,4.5 -9,4.5 -9,0 z"
+ id="path22753"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23624"
+ style="opacity:0.5">
+ <g
+ id="g23620">
+ <rect
+ y="286"
+ x="514"
+ height="3"
+ width="3"
+ id="rect23592"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.0220957"
+ ry="1.1453303" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518.8317,286 1.3366,0 c 0.46076,0 0.8317,0.49209 0.8317,1.10334 l 0,0.79332 C 521,288.50791 520.62906,289 520.1683,289 l -1.3366,0 C 518.37094,289 518,288.50791 518,287.89666 l 0,-0.79332 C 518,286.49209 518.37094,286 518.8317,286 z"
+ id="rect23595"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23614">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23599"
+ width="2"
+ height="2"
+ x="514"
+ y="290" />
+ <rect
+ y="291"
+ x="515"
+ height="2"
+ width="4.5"
+ id="rect23601"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23607"
+ width="1.25"
+ height="2"
+ x="519.5"
+ y="290" />
+ </g>
+ </g>
+ <path
+ style="fill:#0b1728;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 514,287.25 1.25,-1.25 0.75,0 0,2 -2,0 0,-0.75 z"
+ id="rect23575"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="290"
+ x="514"
+ height="1"
+ width="1"
+ id="rect23577"
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23579"
+ width="4"
+ height="1"
+ x="515"
+ y="291" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23583"
+ width="1"
+ height="1"
+ x="519"
+ y="290" />
+ <path
+ style="fill:#0b1728;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 520,286 -0.75,0 -1.25,1.25 0,0.75 2,0 0,-2 z"
+ id="rect23597"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24003"
+ transform="translate(210,-37)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g24005"
+ transform="translate(90,-142)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24007"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g24009">
+ <g
+ transform="translate(-386,446.5)"
+ id="g24011">
+ <path
+ id="path24028"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path24030"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g24032">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path24034"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path24036"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient24052);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ id="path24039"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient24054);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24041"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24056);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ id="path24044"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24062"
+ d="m 202.5,135.71875 -6,2.18085 0,7.36038 6,3.27127 6,-3.27127 0,-7.36038 -6,-2.18085 z"
+ style="opacity:0.65;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(-259,202)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:none;stroke:url(#linearGradient24066);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -56.5,337.71875 -6,2.18085 0,7.36038 6,3.27127 6,-3.27127 0,-7.36038 -6,-2.18085 z"
+ id="path24058"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24046"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-1081.9421,-238.02038)" />
+ </g>
+ <g
+ id="g24311"
+ transform="translate(-16.99965,-228.99997)">
+ <g
+ style="opacity:0.55"
+ transform="translate(21.0003,-3e-5)"
+ id="g24226">
+ <g
+ transform="translate(43.04504,242.48228)"
+ id="g24228">
+ <path
+ style="opacity:0.8;fill:none;stroke:#333333;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.45451,103.98095 0,7 7.00045,0.0368 0,-7 -7.00045,-0.0368 z"
+ id="path24230"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path24232"
+ d="m 90.45451,103.98095 4.5e-4,7.03677 7,0 -4.5e-4,-7.03677 -7,0 z"
+ style="fill:#989898;fill-opacity:1;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24234"
+ width="2.9998772"
+ height="3"
+ x="139.50012"
+ y="352.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="344.50003"
+ x="131.4998"
+ height="3"
+ width="2.9998772"
+ id="rect24236"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24238"
+ width="2.9998772"
+ height="3"
+ x="131.50012"
+ y="352.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path24240"
+ d="m 142.00027,353 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 134.00042,353.00003 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path24242"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 133.99997,345.00003 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path24244"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="344.5"
+ x="139.49985"
+ height="3"
+ width="2.9998772"
+ id="rect24246"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 142,345 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path24248"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g24250"
+ transform="translate(16.999682,3.99994)">
+ <g
+ id="g24252"
+ transform="translate(43.04504,242.48228)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path24254"
+ d="m 90.45451,103.98095 0,7 7.00045,0.0368 0,-7 -7.00045,-0.0368 z"
+ style="opacity:0.8;fill:none;stroke:#333333;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#c3c3c3;fill-opacity:1;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.45451,103.98095 4.5e-4,7.03677 7,0 -4.5e-4,-7.03677 -7,0 z"
+ id="path24256"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="352.5"
+ x="139.50012"
+ height="3"
+ width="2.9998772"
+ id="rect24258"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24260"
+ width="2.9998772"
+ height="3"
+ x="131.4998"
+ y="344.50003"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="352.5"
+ x="131.50012"
+ height="3"
+ width="2.9998772"
+ id="rect24262"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 142.00027,353 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path24264"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path24266"
+ d="m 134.00042,353.00003 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path24268"
+ d="m 133.99997,345.00003 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24270"
+ width="2.9998772"
+ height="3"
+ x="139.49985"
+ y="344.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path24272"
+ d="m 142,345 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23719"
+ width="0"
+ height="0"
+ x="547"
+ y="255" />
+ <g
+ id="g24088"
+ transform="translate(341,-57.00032)" />
+ <g
+ transform="translate(361,-56.00032)"
+ id="g24276" />
+ <g
+ id="g23953"
+ transform="translate(-60,60)">
+ <rect
+ y="-29"
+ x="128"
+ height="16"
+ width="16"
+ id="rect23087"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23937">
+ <path
+ sodipodi:nodetypes="cscc"
+ d="m 140,-21 c 1.125,1 3.5,0.25 3.5,-1 0,-1.5 0.47443,-1.637992 -2,-1.5 -0.1033,1.43128 -0.66697,1.819388 -1.5,2.5 z"
+ style="fill:#999999;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23906"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23099"
+ style="fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 132,-21 c -1.125,1 -3.5,0.25 -3.5,-1 0,-1.5 -0.47443,-1.637992 2,-1.5 0.1033,1.43128 0.66697,1.819388 1.5,2.5 z"
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23090"
+ style="fill:url(#linearGradient23971);fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 135.75,-25.5 -1.25,-2 -0.75,0 -3.25,2.75 0,1.25 c 0.15379,2.182132 1.3678,1.901463 3,4 l 0,4.5 c 0,1.5 1.5,1.5 2.5,1.5 1,0 2.5,0 2.5,-1.5 l 0,-4.5 c 1.62605,-2.090636 2.83897,-1.844587 3,-4 l 0,-1.25 -3.25,-2.75 -0.75,0 -1.25,2"
+ sodipodi:nodetypes="cccccccsccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23876"
+ width="2"
+ height="1"
+ x="135"
+ y="-16" />
+ <rect
+ y="-21"
+ x="135"
+ height="2"
+ width="2.75"
+ id="rect23881"
+ style="fill:url(#linearGradient24099);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="1"
+ rx="1" />
+ <rect
+ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23883"
+ width="2"
+ height="1"
+ x="135"
+ y="-21" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23902"
+ sodipodi:cx="133"
+ sodipodi:cy="-23"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="translate(0.5,-0.46875)" />
+ <path
+ transform="matrix(1.2143583,0,0,1.1512108,-28.054112,2.9290602)"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path23125"
+ style="fill:none;stroke:url(#linearGradient23973);stroke-width:0.93034029;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.8392157,0,0,0.8382979,21.884318,-4.2140957)"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path23900"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <rect
+ y="-15"
+ x="135"
+ height="1"
+ width="2"
+ id="rect23914"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccs"
+ d="m 131.88556,-21.103144 c 0.4583,0.371362 1.00745,1.072735 1.61444,1.853144 l 0,3.75 c 0,1.5 1.5,2 2.5,2 1,0 2.5,-0.5 2.5,-2 l 0,-3.75 c 0.64842,-0.833678 1.23114,-1.545786 1.70766,-1.936772 M 130.5,-23.5 l 0,-1.25 3,-2.75 1,0 1.25,1.75 0.5,0 1.25,-1.75 1,0 3,2.75 0,1.25"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path23924"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient23975);stroke-width:0.94079971;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23960"
+ sodipodi:cx="133"
+ sodipodi:cy="-23"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(1.2116904,0,0,1.1282344,-22.693138,2.3776257)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23970"
+ sodipodi:cx="133"
+ sodipodi:cy="-23"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(0.8392157,0,0,0.8382979,26.893134,-4.2140957)" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 136.75,-24.75 138,-26.5"
+ id="path23929"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23978"
+ d="m 129.25,-22.25 0.5,-0.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 142.75,-22.5 -0.25,-0.25"
+ id="path23980"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24504"
+ transform="translate(-21,-19)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23149"
+ width="16"
+ height="16"
+ x="-441"
+ y="281"
+ transform="scale(-1,1)" />
+ <g
+ id="g24488">
+ <g
+ id="g24377"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline"
+ transform="matrix(-1.0003553,0,0,0.9995949,486.01617,193.04665)">
+ <path
+ style="fill:url(#linearGradient24539);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.70001745;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40018745;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 55.496449,92.490815 4.998228,0.0015 -1e-6,6.000906 -4.998227,-4e-6 m -5.997869,0 -3.99858,10e-7 10e-7,-6.002432 3.998579,0"
+ id="path24388"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient24541);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 55.496399,97.494124 3.998631,4.3e-4 10e-7,-4.003331 -3.998582,-3e-6 m -5.997771,-8.55e-4 -2.999032,8.54e-4 -1.96e-4,4.001622 2.99913,0"
+ id="path24390"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.5"
+ id="g23153"
+ transform="translate(-39.00033,129)">
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path23156"
+ d="m 472.50033,152.49994 c -1.9309,0 -3,0.66961 -3,1.5 L 469.50029,166 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3,-0.66961 3,-1.5 l 4e-5,-12.00006 c 0,-0.83039 -1.0691,-1.5 -3,-1.5 z"
+ style="fill:url(#linearGradient24543);fill-opacity:1;fill-rule:nonzero;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23158"
+ d="m 470.50033,153.99994 -4e-5,12.01111 c 0,0.54648 1,0.54648 2,0.54648 1,0 2,0 2,-0.55753 l 4e-5,-12.01111"
+ style="fill:none;stroke:url(#linearGradient24545);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.9067635,0,0,1.2421435,374.56954,430.00586)"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
+ sodipodi:ry="1.2798798"
+ sodipodi:rx="3.3084693"
+ sodipodi:cy="-222"
+ sodipodi:cx="108"
+ id="path23160"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.73959124;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:0.69999999;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 472.50033,152.49994 c -0.62477,0 -1.15931,0.0523 -1.5966,0.15704 -0.91421,0.21887 -1.4034,0.66652 -1.4034,1.34296 L 469.50029,166 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 4e-5,-12.00006 c 0,-1 -1.0691,-1.5 -3,-1.5 z"
+ id="path23163"
+ sodipodi:nodetypes="csccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24547);stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 469.50033,154 c 0,1.5 1.0691,1.5 3,1.5 1.9309,0 3,-0.25 3,-1.5"
+ id="path24484"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path24404"
+ style="fill:url(#linearGradient24549);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 436.5,292 c -2.9e-4,-0.74999 -2.9e-4,-6.75005 0,-6.00006 2.9e-4,0.74999 -1.0691,1.5 -3,1.5 -1.9309,0 -3,-0.66961 -3,-1.5 0,-0.83039 0,5.16967 0,6.00006 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 z"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.75001,287.5 c 0,0.54447 0.98001,0.98352 2.75,0.98352 1.77,0 2.75027,-0.49177 2.75,-0.98352"
+ id="path24464"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24472"
+ style="fill:none;stroke:url(#linearGradient24551);stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.5,285.75 0,5.5 m 6,-5.5 0,5.5"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path24424"
+ d="m 430.5,285.5 0,0.5 c 0,0.83039 1.0691,1.5 3,1.5 1.9309,0 3.00029,-0.75001 3,-1.5 l 0,-0.5"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.5,291.5 0,0.75 c 0,0.75 1.0691,1.25 3,1.25 1.9309,0 3,-0.5 3,-1.25 l 0,-0.75"
+ id="path24470"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24095"
+ transform="translate(126,23)">
+ <g
+ style="opacity:0.45;display:inline"
+ id="g23290"
+ transform="translate(216,191)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23292"
+ width="16"
+ height="16"
+ x="83"
+ y="48" />
+ <g
+ style="display:inline"
+ id="g23294"
+ transform="matrix(1.1658027,0,0,1.1657997,-59.289717,-204.05607)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23297"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient24112);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path23299"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)" />
+ <path
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient24114);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path23301"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,-1)"
+ id="g23266"
+ style="display:inline;enable-background:new">
+ <g
+ id="g24238">
+ <path
+ style="opacity:0.7;fill:url(#linearGradient24116);fill-opacity:1;fill-rule:nonzero;stroke:#132747;stroke-width:0.69999999;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 313.25,246.5 c -2.13129,3.51035 -4.20028,0.92659 -6.75,0 -2.5,-0.90852 -5.25,-1.69675 -5.75,-0.25 -1,3.5 1.75,8.25 6.25,8.25 4.5,0 7.25,-4.5 6.25,-8 z"
+ id="path24164"
+ sodipodi:nodetypes="csczc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path24220"
+ d="M 301.49346,248.00351 C 300.75,245 304.5,246.75 307.5,247.5"
+ style="fill:none;stroke:url(#linearGradient24118);stroke-width:1.00000083;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.0828313,0,0,1.0828897,167.85295,5.9780113)"
+ id="g24116"
+ style="display:inline;enable-background:new"
+ clip-path="url(#clipPath24168)">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24121);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.98504531;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24134"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6352868,0,0,0.6352859,44.642106,148.53594)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient24123);stroke-width:1.45364487;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path24144"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ sodipodi:nodetypes="cs"
+ id="path24166"
+ d="m 306.9667,246.52825 c -1.63301,1.38546 -3.26623,2.75322 -4.93069,1.49745"
+ style="fill:none;stroke:#132747;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 313.25,246.25 c -1,-3.5 -4.2097,-1.48101 -6.2833,0.27825"
+ id="path24198"
+ sodipodi:nodetypes="cs"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41107"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41109"
+ width="16"
+ height="16"
+ x="110"
+ y="260" />
+ <g
+ style="display:inline"
+ id="g41111"
+ transform="translate(-92.033883,254)">
+ <g
+ id="g41113"
+ transform="translate(20.05,-0.09375)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41115"
+ d="m 195.7,12.34375 -8.21612,8.25"
+ style="fill:none;stroke:#0b1728;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.941788,0.336207,-0.336207,0.941788,16.5539,-62.39971)"
+ id="g41117">
+ <path
+ sodipodi:nodetypes="csccsc"
+ id="path41119"
+ d="m 191.82819,15.661146 c -2.50169,-2.892812 -3.51599,-3.257525 -5.63502,-2.501059 -1.55469,0.555005 -3.0441,1.883066 -4.82641,-0.135198 l 3.04462,-5.5995832 c 1.58362,1.6624741 2.57888,1.2029919 3.73322,0.7909034 1.64813,-0.5883624 2.98174,-0.5189446 6.10591,2.3329558"
+ style="fill:url(#linearGradient41127);fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient41129);stroke-width:0.85000008;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 184.59619,8.6865928 -2.20359,4.2375362 c 0.98797,0.735441 2.20267,0.01003 3.54842,-0.470383 2.11902,-0.756466 3.52208,-0.551271 5.62148,1.765004 l 1.625,-3.46875 c -2.19923,-2.2239943 -3.61351,-2.2477085 -5.02619,-1.7433979 -1.08094,0.3858805 -2.30419,0.5856276 -3.56512,-0.3200093 z"
+ id="path41121"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#6593d4;fill-opacity:1;fill-rule:evenodd;stroke:#87aade;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 195.7,12.34375 -8.21612,8.25"
+ id="path41123"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41125"
+ d="m 191.6399,15.190092 3.2987,-3.242382"
+ style="opacity:0.5;fill:#6593d4;fill-opacity:1;fill-rule:evenodd;stroke:#2c5aa0;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41132"
+ transform="translate(237.98389,298.06154)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="195"
+ x="124.01612"
+ height="16"
+ width="16"
+ id="rect41134"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41136">
+ <path
+ id="path41138"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 131.51612,200.41538 0,3.2 3,1.88462 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9.08462 3,0.0846 2,-3 m -10.75,0.25 2.25,2.66538 3.5,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect41140"
+ width="2"
+ height="1.9692308"
+ x="130.01611"
+ y="196.96924"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ y="196.96924"
+ x="130.01611"
+ height="1.9692308"
+ width="2"
+ id="rect41142"
+ style="opacity:0.95;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41144"
+ style="fill:none;stroke:url(#linearGradient41170);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 125.76612,197.75 2.25,2.75 3.5,0 m 0,0 0,3 3,2 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9 3,0 2,-3"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41146"
+ transform="translate(78,299.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41148"
+ width="16"
+ height="16"
+ x="263"
+ y="194" />
+ <g
+ id="g41150"
+ transform="translate(0,-1)">
+ <path
+ id="path41152"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect41154"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccccc"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23087"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ style="fill:none;stroke:url(#linearGradient41172);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path41157"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="196"
+ x="269.76608"
+ height="2.75"
+ width="2.4999998"
+ id="rect41159"
+ style="opacity:0.5;fill:none;stroke:url(#radialGradient41174);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect41161"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ transform="translate(28.983879,319.02657)"
+ id="g41999"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42001"
+ width="16"
+ height="16"
+ x="124.01612"
+ y="195"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(6.71875e-6,0.03077095)"
+ style="display:inline;enable-background:new"
+ id="g42059">
+ <path
+ id="path42061"
+ style="fill:none;stroke:#000000;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 131.51612,200.41538 0,3.2 3,1.88462 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 -0.002,3.68505 m 3.00187,-8.76967 3,0.0846 2,-3 m -10.75,0.25 2.25,2.66538 3.5,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42063"
+ width="2"
+ height="1.9692308"
+ x="130.01611"
+ y="196.97343"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ y="196.97343"
+ x="130.01611"
+ height="1.9692308"
+ width="2"
+ id="rect42065"
+ style="opacity:0.95;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42067"
+ style="fill:none;stroke:url(#linearGradient42069);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 125.76612,197.75 2.25,2.75 3.5,0 m 0,0 0,3 3,2 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 -0.002,3.68505 m 3.00187,-8.68505 3,0 2,-3"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-19.00001,-0.03076)"
+ style="display:inline;enable-background:new"
+ id="g42015">
+ <g
+ id="g42017"
+ transform="translate(-1.999999,-8.9958)">
+ <path
+ id="path42019"
+ d="m 145.99053,204.49753 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ style="fill:none;stroke:#964e00;stroke-width:1.49505997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42021"
+ d="m 147.00606,204.9958 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g42023"
+ transform="translate(0,-1)">
+ <path
+ style="fill:none;stroke:#964e00;stroke-width:1.49505997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156.00059,196.50173 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ id="path42025"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 157.01612,197 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ id="path42027"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(120,68)"
+ id="g42071"
+ style="display:inline;enable-background:new">
+ <rect
+ y="194"
+ x="263"
+ height="16"
+ width="16"
+ id="rect42073"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0,-1)"
+ id="g42075">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ style="fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path42077"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect42079"
+ style="fill:none;stroke:#0b1728;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ id="path42081"
+ style="fill:none;stroke:#0b1728;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42083"
+ style="fill:none;stroke:url(#linearGradient42093);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.5;fill:none;stroke:url(#radialGradient42091);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42085"
+ width="2.4999998"
+ height="2.75"
+ x="269.76608"
+ y="196" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#c8d8f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42087"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196" />
+ </g>
+ </g>
+ <g
+ transform="translate(-111,236)"
+ id="g42095"
+ style="display:inline;enable-background:new">
+ <rect
+ y="194"
+ x="263"
+ height="16"
+ width="16"
+ id="rect42097"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0,-1)"
+ id="g42099">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ style="fill:none;stroke:#241300;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42101"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect42103"
+ style="fill:none;stroke:#2b1600;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ id="path42105"
+ style="fill:none;stroke:#241300;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42107"
+ style="fill:none;stroke:#ffad55;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.5;fill:none;stroke:url(#radialGradient42115);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42109"
+ width="2.4999998"
+ height="2.75"
+ x="269.76608"
+ y="196" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42111"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ style="fill:none;stroke:url(#linearGradient42121);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path42117"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(113.22629,214.3098)"
+ id="g42123"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42125"
+ width="16"
+ height="16"
+ x="124.01612"
+ y="195"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g42127"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 131.51612,200.41538 0,3.2 3,1.88462 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9.08462 3,0.0846 2,-3 m -10.75,0.25 2.25,2.66538 3.5,0"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42129"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="196.96924"
+ x="130.01611"
+ height="1.9692308"
+ width="2"
+ id="rect42131"
+ style="fill:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.95;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect42133"
+ width="2"
+ height="1.9692308"
+ x="130.01611"
+ y="196.96924" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ d="m 125.76612,197.75 2.25,2.75 3.5,0 m 0,0 0,3 3,2 2.75,-1.75 m -5.75,-0.62692 -3,2.37692 0,4 m 3,-9 3,0 2,-3"
+ style="fill:none;stroke:url(#linearGradient42155);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42135"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g42161"
+ transform="translate(-128.99942,340.96539)"
+ style="display:inline;enable-background:new">
+ <g
+ id="g42163"
+ transform="translate(-1.999997,-8)">
+ <path
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 256,-137.52519 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ id="path42165"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 257.01553,-137.02692 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ id="path42167"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g42169">
+ <path
+ id="path42171"
+ d="m 265.98447,-145.52519 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42173"
+ d="m 267,-145.02692 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g42258"
+ transform="translate(0,86)">
+ <g
+ transform="translate(-111,129)"
+ id="g42260"
+ style="opacity:0.9;display:inline;enable-background:new">
+ <rect
+ y="194"
+ x="263"
+ height="16"
+ width="16"
+ id="rect42262"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0,-1)"
+ id="g42264"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccccc"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path42266"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="196"
+ x="270.01611"
+ height="2"
+ width="2"
+ id="rect42268"
+ style="fill:none;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ id="path42270"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42272"
+ style="fill:none;stroke:url(#linearGradient42290);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 270.51612,199.5 -0.0161,2 1.75,4 1.25,3 m -3,-7 -1.75,4 -1.25,3 m 3.01612,-9 3,0 2.75,0 m -11.5,0 2.75,0 3,0"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.5;fill:none;stroke:url(#radialGradient42292);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect42274"
+ width="2.4999998"
+ height="2.75"
+ x="269.76608"
+ y="196" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect42276"
+ width="2"
+ height="2"
+ x="270.01611"
+ y="196" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42278"
+ transform="translate(-83.0076,464.0087)">
+ <path
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 236.98447,-138.49827 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ id="path42280"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 238,-138 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ id="path42282"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42284"
+ transform="translate(-81,470)">
+ <path
+ id="path42286"
+ d="m 246.98447,-144.49827 0.0368,0 c 0.81818,0 1.47687,0.66665 1.47687,1.49473 l 0,1.2e-4 c 0,0.82808 -0.65869,1.49472 -1.47687,1.49472 l -0.0368,0 c -0.81819,0 -1.47687,-0.66664 -1.47687,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.65868,-1.49473 1.47687,-1.49473 z"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42288"
+ d="m 248,-144 c -0.66732,0 -1.33464,1e-5 -2.00196,1e-5 0,0.66707 0,1.33412 0,2.00119 0.66732,0 1.33464,-1e-5 2.00196,-1e-5 0,-0.66706 0,-1.33412 0,-2.00119 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22051"
+ transform="translate(67,200.06499)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline" />
+ <g
+ id="g40816"
+ transform="translate(-23,0)">
+ <g
+ id="g40830" />
+ </g>
+ <g
+ id="g23451"
+ transform="translate(-393.99971,438.98222)" />
+ <g
+ id="g23461"
+ transform="matrix(0.8342485,0,0,0.8354168,-433.47749,469.22699)" />
+ <g
+ id="g23710"
+ transform="translate(399,24.000007)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\x.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="1.767767"
+ y="596.5"
+ x="69.5"
+ height="13"
+ width="13"
+ id="rect23677"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.767767" />
+ <g
+ style="display:inline"
+ id="g23438"
+ transform="translate(45,357.99031)">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:url(#linearGradient23775);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 25,239.50969 0.5,-0.5 11,0 0.5,0.5 0,11 -0.5,0.5 -11,0 -0.5,-0.5 0,-11 z"
+ id="path23673"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23655"
+ width="16"
+ height="16"
+ x="23"
+ y="237.00969" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 25.499991,250.49338 0,-11.00155 10.999993,0"
+ id="path23447"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(0.9,0,0,0.9,7.6,60.3)"
+ d="m 80.166667,603 a 4.1666665,4.1666665 0 1 1 -8.333334,0 4.1666665,4.1666665 0 1 1 8.333334,0 z"
+ sodipodi:ry="4.1666665"
+ sodipodi:rx="4.1666665"
+ sodipodi:cy="603"
+ sodipodi:cx="76"
+ id="path23605"
+ style="fill:#dad9d9;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient23777);stroke-width:0.8888889;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <rect
+ y="602"
+ x="74"
+ height="2"
+ width="1"
+ id="rect23613"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23615"
+ width="1"
+ height="2"
+ x="77"
+ y="602" />
+ </g>
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
+ y="262"
+ x="194"
+ height="16"
+ width="16"
+ id="rect23619"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23350"
+ transform="translate(0,128.00001)">
+ <rect
+ y="427.99997"
+ x="215"
+ height="16"
+ width="16"
+ id="rect51640"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
+ y="427.99997"
+ x="215"
+ height="16"
+ width="16"
+ id="rect18676"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23292">
+ <g
+ id="g23271">
+ <g
+ id="g23265">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use22458"
+ d="m 229.97728,432.50003 0,0 -2.86364,-0.81818 -1.22727,0.20455 0,1.22727 1.22727,0.20455 2.86364,-0.81819 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23257);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use22460"
+ d="m 226.5,435.97731 0,0 0.81819,-2.86364 -0.20455,-1.22727 -1.22727,0 -0.20455,1.22727 0.81818,2.86364 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23254);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use22462"
+ d="m 223.02273,432.50003 0,0 2.86364,0.81819 1.22727,-0.20455 0,-1.22727 -1.22727,-0.20455 -2.86364,0.81818 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23251);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path22465"
+ d="m 226.5,429.02276 0,0 -0.81818,2.86364 0.20455,1.22727 1.22727,0 0.20455,-1.22727 -0.81819,-2.86364 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23248);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23259">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22585"
+ d="m 226.09091,428.00003 -0.4091,3.68182 0.20455,1.43182 1.22727,0 0.20455,-1.43182 -0.40909,-3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23244);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="use22587"
+ d="m 231,432.09094 -3.68182,-0.40909 -1.43182,0.20454 0,1.22728 1.43182,0.20454 3.68182,-0.40909 0,-0.81818 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23239);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="use22589"
+ d="m 226.09091,437.00003 -0.4091,-3.68182 0.20455,-1.43182 1.22727,0 0.20455,1.43182 -0.40909,3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23235);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="use22591"
+ d="m 221.99999,432.90912 3.68182,0.40909 1.43182,-0.20454 0,-1.22728 -1.43182,-0.20454 -3.68182,0.40909 0,0.81818 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23231);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(141,-197.00002)"
+ id="g19146">
+ <rect
+ y="628.25"
+ x="85"
+ height="2.5"
+ width="1"
+ id="rect19148"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect19150"
+ width="1"
+ height="2.5"
+ x="629"
+ y="-86.75" />
+ </g>
+ </g>
+ <g
+ id="g23162"
+ transform="translate(0,-4)">
+ <g
+ id="g23156">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24185"
+ d="m 224.75,442.5 0,0 -3.5,-0.75 -1.5,0 0,1.5 1.5,0 3.5,-0.75 z"
+ style="fill:none;stroke:url(#linearGradient23177);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24187"
+ d="m 220.5,446.75 0,0 0.75,-3.5 0,-1.5 -1.5,0 0.25,1.5 0.5,3.5 z"
+ style="fill:none;stroke:url(#linearGradient23179);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24189"
+ d="m 216.25,442.5 0,0 3.5,0.75 1.5,0 0,-1.5 -1.5,0 -3.5,0.75 z"
+ style="fill:none;stroke:url(#linearGradient23181);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path24197"
+ d="m 220.5,438 0,-0.15625 -0.75,3.90625 0,1.5 1.5,0 0,-1.5 -0.75,-3.75 z"
+ style="fill:none;stroke:url(#linearGradient23183);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23150">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path24201"
+ d="m 220,437 -0.5,4.5 0.25,1.75 1.5,0 0.25,-1.75 -0.5,-4.5 -1,0 z"
+ style="fill:url(#linearGradient23185);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="use24203"
+ d="m 226,442 -4.5,-0.5 -1.75,0.25 0,1.5 1.75,0.25 4.5,-0.5 0,-1 z"
+ style="fill:url(#linearGradient23187);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="use24205"
+ d="m 220,448 -0.5,-4.5 0.25,-1.75 1.5,0 0.25,1.75 -0.5,4.5 -1,0 z"
+ style="fill:url(#linearGradient23189);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="use24207"
+ d="m 215,443 4.5,0.5 1.75,-0.25 0,-1.5 -1.75,-0.25 -4.5,0.5 0,1 z"
+ style="fill:url(#linearGradient23191);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(135,-187.00002)"
+ id="g24209">
+ <rect
+ y="628"
+ x="85"
+ height="2.9999599"
+ width="1"
+ id="rect24211"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24213"
+ width="1"
+ height="3"
+ x="629"
+ y="-87" />
+ </g>
+ </g>
+ <g
+ id="g23052"
+ transform="translate(0,4)">
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path24226"
+ d="m 218.75004,424.50004 -0.5,0 -0.50004,1.74996 0.25004,1.75004 1,0 0.24996,-1.75004 -0.49996,-1.74996 z"
+ style="fill:none;stroke:url(#linearGradient22715);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22711);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 221.50004,427.75004 0,-0.5 -1.74996,-0.50004 -1.75004,0.25004 0,1 1.75004,0.24996 1.74996,-0.49996 z"
+ id="use24228"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22707);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215.50004,427.25004 0,0.5 1.74996,0.50004 1.75004,-0.25004 0,-1 -1.75004,-0.24996 -1.74996,0.49996 z"
+ id="use24230"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22704);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.25004,430.50004 0.5,0 0.50004,-1.74996 -0.25004,-1.75004 -1,0 -0.24996,1.75004 0.49996,1.74996 z"
+ id="use24232"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path24236"
+ d="m 218.00004,424.00004 -0.12109,2.86328 0.1211,1.13676 0.99999,-4e-5 0.125,-1.125 -0.125,-2.875 -1,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient22701);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient22698);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 222.00004,427.00004 -2.86328,-0.12109 -1.13676,0.12109 4e-5,1 1.125,0.125 2.875,-0.125 0,-1 z"
+ id="use24238"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient22695);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.00004,431.00004 0.12109,-2.86328 -0.1211,-1.13676 -0.99999,4e-5 -0.125,1.125 0.125,2.875 1,0 0,0 0,0 0,0 z"
+ id="use24240"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient22692);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215.00004,428.00004 2.86328,0.12109 1.13676,-0.12109 -4e-5,-1 -1.125,-0.125 -2.875,0.125 0,1 z"
+ id="use24242"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(133.00004,-201.99996)"
+ id="g24244">
+ <rect
+ y="628.5"
+ x="85"
+ height="2"
+ width="1"
+ id="rect24249"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24251"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ <g
+ id="g23116"
+ transform="translate(0,-4)">
+ <g
+ transform="translate(0,-6.4549394)"
+ id="g23090">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24445"
+ d="m 230.20453,450.95187 0,0 -2.22727,-0.63574 -0.95454,0.15894 0,0.9536 0.95454,0.15893 2.22727,-0.63573 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23132);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24447"
+ d="m 227.49999,453.65374 0,0 0.63637,-2.22507 -0.15909,-0.9536 -0.95455,0 -0.15909,0.9536 0.63636,2.22507 z"
+ style="fill:none;stroke:url(#linearGradient23134);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="use24449"
+ d="m 224.79546,450.95187 0,0 2.22727,0.63574 0.95454,-0.15894 0,-0.9536 -0.95454,-0.15893 -2.22727,0.63573 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23136);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23138);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.5,448.25 0,0 -0.63637,2.22507 0.15909,0.9536 0.95455,0 0.15909,-0.9536 L 227.5,448.25 z"
+ id="path24452"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23110">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22819"
+ d="m 227.18182,441.00653 -0.31818,2.86081 0.15909,1.11253 0.95454,0 0.15909,-1.11253 -0.31818,-2.86081 -0.63636,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23140);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22821"
+ d="m 231,444.1852 -2.86364,-0.31786 -1.11363,0.15893 0,0.9536 1.11363,0.15894 2.86364,-0.31787 0,-0.63574 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23142);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22823"
+ d="m 227.18182,447.99961 -0.31818,-2.8608 0.15909,-1.11254 0.95454,0 0.15909,1.11254 -0.31818,2.8608 -0.63636,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23144);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path22825"
+ d="m 224.00001,444.82094 2.86363,0.31787 1.11363,-0.15894 0,-0.9536 -1.11363,-0.15893 -2.86363,0.31786 0,0.63574 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23147);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23105">
+ <g
+ transform="translate(141.99999,-184.99353)"
+ id="g24264">
+ <rect
+ y="628.5"
+ x="85"
+ height="2"
+ width="1"
+ id="rect24266"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24268"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g23415"
+ transform="translate(62.999992,65.000007)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23417"
+ width="16"
+ height="16"
+ x="215"
+ y="427.99997" />
+ <rect
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23419"
+ width="16"
+ height="16"
+ x="215"
+ y="427.99997"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g23422">
+ <g
+ id="g23424">
+ <g
+ id="g23426">
+ <path
+ style="fill:none;stroke:url(#linearGradient23563);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 229.97728,432.50003 0,0 -2.86364,-0.81818 -1.22727,0.20455 0,1.22727 1.22727,0.20455 2.86364,-0.81819 0,0 0,0 0,0 z"
+ id="path23430"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23566);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.5,435.97731 0,0 0.81819,-2.86364 -0.20455,-1.22727 -1.22727,0 -0.20455,1.22727 0.81818,2.86364 0,0 0,0 0,0 z"
+ id="path23432"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23568);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 223.02273,432.50003 0,0 2.86364,0.81819 1.22727,-0.20455 0,-1.22727 -1.22727,-0.20455 -2.86364,0.81818 0,0 0,0 0,0 z"
+ id="path23434"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23570);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.5,429.02276 0,0 -0.81818,2.86364 0.20455,1.22727 1.22727,0 0.20455,-1.22727 -0.81819,-2.86364 0,0 0,0 0,0 z"
+ id="path23437"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23439">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23572);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.09091,428.00003 -0.4091,3.68182 0.20455,1.43182 1.22727,0 0.20455,-1.43182 -0.40909,-3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ id="path23441"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23574);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 231,432.09094 -3.68182,-0.40909 -1.43182,0.20454 0,1.22728 1.43182,0.20454 3.68182,-0.40909 0,-0.81818 0,0 0,0 0,0 z"
+ id="path23443"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23576);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.09091,437.00003 -0.4091,-3.68182 0.20455,-1.43182 1.22727,0 0.20455,1.43182 -0.40909,3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ id="path23449"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23578);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 221.99999,432.90912 3.68182,0.40909 1.43182,-0.20454 0,-1.22728 -1.43182,-0.20454 -3.68182,0.40909 0,0.81818 0,0 0,0 0,0 z"
+ id="path23453"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23455"
+ transform="translate(141,-197.00002)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23457"
+ width="1"
+ height="2.5"
+ x="85"
+ y="628.25" />
+ <rect
+ y="-86.75"
+ x="629"
+ height="2.5"
+ width="1"
+ id="rect23463"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,-4)"
+ id="g23465">
+ <g
+ id="g23467">
+ <path
+ style="fill:none;stroke:url(#linearGradient23580);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.75,442.5 0,0 -3.49999,-0.75 -1.50001,0 0,1.5 1.50001,0 3.49999,-0.75 z"
+ id="path23469"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23582);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220.5,446.75 0,0 0.75001,-3.5 -1e-5,-1.5 -1.5,0 1e-5,1.5 0.74999,3.5 z"
+ id="path23472"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23587);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 216.25,442.5 0,0 3.50001,0.75 1.49999,0 0,-1.5 -1.49999,0 -3.50001,0.75 z"
+ id="path23474"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23589);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220.5,438.25 0,0 -0.74999,3.5 -1e-5,1.5 1.5,0 1e-5,-1.5 -0.75001,-3.5 z"
+ id="path23476"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23479">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23591);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220,437 -0.5,4.5 0.25,1.75 1.5,0 0.25,-1.75 -0.5,-4.5 -1,0 z"
+ id="path23481"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23593);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226,442 -4.5,-0.5 -1.75,0.25 0,1.5 1.75,0.25 4.5,-0.5 0,-1 z"
+ id="path23484"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23597);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220,448 -0.5,-4.5 0.25,-1.75 1.5,0 0.25,1.75 -0.5,4.5 -1,0 z"
+ id="path23486"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23600);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215,443 4.5,0.5 1.75,-0.25 0,-1.5 -1.75,-0.25 -4.5,0.5 0,1 z"
+ id="path23488"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23491"
+ transform="translate(135,-187.00002)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23493"
+ width="1"
+ height="2.9999599"
+ x="85"
+ y="628" />
+ <rect
+ y="-87"
+ x="629"
+ height="3"
+ width="1"
+ id="rect23496"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,4)"
+ id="g23498">
+ <path
+ style="fill:none;stroke:url(#linearGradient23602);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.75004,424.50004 -0.5,0 -0.50004,1.74996 0.25004,1.75004 1,0 0.24996,-1.75004 -0.49996,-1.74996 z"
+ id="path23500"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23502"
+ d="m 221.50004,427.75004 0,-0.5 -1.74996,-0.50004 -1.75004,0.25004 0,1 1.75004,0.24996 1.74996,-0.49996 z"
+ style="fill:none;stroke:url(#linearGradient23606);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23504"
+ d="m 215.50004,427.25004 0,0.5 1.74996,0.50004 1.75004,-0.25004 0,-1 -1.75004,-0.24996 -1.74996,0.49996 z"
+ style="fill:none;stroke:url(#linearGradient23608);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23506"
+ d="m 218.25004,430.50004 0.5,0 0.50004,-1.74996 -0.25004,-1.75004 -1,0 -0.24996,1.75004 0.49996,1.74996 z"
+ style="fill:none;stroke:url(#linearGradient23610);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23612);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.00004,424.00004 -0.12109,2.86328 0.1211,1.13676 0.99999,-4e-5 0.125,-1.125 -0.125,-2.875 -1,0 0,0 0,0 0,0 z"
+ id="path23508"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path23510"
+ d="m 222.00004,427.00004 -2.86328,-0.12109 -1.13676,0.12109 4e-5,1 1.125,0.125 2.875,-0.125 0,-1 z"
+ style="fill:url(#linearGradient23616);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path23512"
+ d="m 219.00004,431.00004 0.12109,-2.86328 -0.1211,-1.13676 -0.99999,4e-5 -0.125,1.125 0.125,2.875 1,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23618);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path23514"
+ d="m 215.00004,428.00004 2.86328,0.12109 1.13676,-0.12109 -4e-5,-1 -1.125,-0.125 -2.875,0.125 0,1 z"
+ style="fill:url(#linearGradient23620);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g23517"
+ transform="translate(133.00004,-201.99996)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23520"
+ width="1"
+ height="2"
+ x="85"
+ y="628.5" />
+ <rect
+ y="-86.5"
+ x="629"
+ height="2"
+ width="1"
+ id="rect23522"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,-4)"
+ id="g23524">
+ <g
+ id="g23526"
+ transform="translate(0,-6.4549394)">
+ <path
+ style="fill:none;stroke:url(#linearGradient23622);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 230.20453,450.95187 0,0 -2.22727,-0.63574 -0.95454,0.15894 0,0.9536 0.95454,0.15893 2.22727,-0.63573 0,0 0,0 0,0 z"
+ id="path23529"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23624);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.49999,453.65374 0,0 0.63637,-2.22507 -0.15909,-0.9536 -0.95455,0 -0.15909,0.9536 0.63636,2.22507 z"
+ id="path23531"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23626);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.79546,450.95187 0,0 2.22727,0.63574 0.95454,-0.15894 0,-0.9536 -0.95454,-0.15893 -2.22727,0.63573 0,0 0,0 0,0 z"
+ id="path23533"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23535"
+ d="m 227.5,448.25 0,0 -0.63637,2.22507 0.15909,0.9536 0.95455,0 0.15909,-0.9536 L 227.5,448.25 z"
+ style="fill:none;stroke:url(#linearGradient23628);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23538">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23630);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.18182,441.00653 -0.31818,2.86081 0.15909,1.11253 0.95454,0 0.15909,-1.11253 -0.31818,-2.86081 -0.63636,0 0,0 0,0 0,0 z"
+ id="path23541"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23632);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 231,444.1852 -2.86364,-0.31786 -1.11363,0.15893 0,0.9536 1.11363,0.15894 2.86364,-0.31787 0,-0.63574 0,0 0,0 0,0 z"
+ id="path23544"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23635);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.18182,447.99961 -0.31818,-2.8608 0.15909,-1.11254 0.95454,0 0.15909,1.11254 -0.31818,2.8608 -0.63636,0 0,0 0,0 0,0 z"
+ id="path23549"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23637);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.00001,444.82094 2.86363,0.31787 1.11363,-0.15894 0,-0.9536 -1.11363,-0.15893 -2.86363,0.31786 0,0.63574 0,0 0,0 0,0 z"
+ id="path23551"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23555">
+ <g
+ id="g23557"
+ transform="translate(141.99999,-184.99353)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23559"
+ width="1"
+ height="2"
+ x="85"
+ y="628.5" />
+ <rect
+ y="-86.5"
+ x="629"
+ height="2"
+ width="1"
+ id="rect23561"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-21.000008,-166)"
+ id="g23639">
+ <rect
+ y="427.99997"
+ x="215"
+ height="16"
+ width="16"
+ id="rect23641"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
+ y="427.99997"
+ x="215"
+ height="16"
+ width="16"
+ id="rect23643"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23645">
+ <g
+ id="g23647">
+ <g
+ id="g23649">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23651"
+ d="m 229.97728,432.50003 0,0 -2.86364,-0.81818 -1.22727,0.20455 0,1.22727 1.22727,0.20455 2.86364,-0.81819 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23797);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23653"
+ d="m 226.5,435.97731 0,0 0.81819,-2.86364 -0.20455,-1.22727 -1.22727,0 -0.20455,1.22727 0.81818,2.86364 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23799);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23655"
+ d="m 223.02273,432.50003 0,0 2.86364,0.81819 1.22727,-0.20455 0,-1.22727 -1.22727,-0.20455 -2.86364,0.81818 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23801);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23668"
+ d="m 226.5,429.02276 0,0 -0.81818,2.86364 0.20455,1.22727 1.22727,0 0.20455,-1.22727 -0.81819,-2.86364 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23803);stroke-width:2.04500008;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23670">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23672"
+ d="m 226.09091,428.00003 -0.4091,3.68182 0.20455,1.43182 1.22727,0 0.20455,-1.43182 -0.40909,-3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23805);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23674"
+ d="m 231,432.09094 -3.68182,-0.40909 -1.43182,0.20454 0,1.22728 1.43182,0.20454 3.68182,-0.40909 0,-0.81818 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23807);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23676"
+ d="m 226.09091,437.00003 -0.4091,-3.68182 0.20455,-1.43182 1.22727,0 0.20455,1.43182 -0.40909,3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23809);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23678"
+ d="m 221.99999,432.90912 3.68182,0.40909 1.43182,-0.20454 0,-1.22728 -1.43182,-0.20454 -3.68182,0.40909 0,0.81818 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23811);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(141,-197.00002)"
+ id="g23680">
+ <rect
+ y="628.25"
+ x="85"
+ height="2.5"
+ width="1"
+ id="rect23682"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23684"
+ width="1"
+ height="2.5"
+ x="629"
+ y="-86.75" />
+ </g>
+ </g>
+ <g
+ id="g23686"
+ transform="translate(0,-4)">
+ <g
+ id="g23688">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23690"
+ d="m 224.75,442.5 0,0 -3.5,-1 -1.5,0.25 0,1.5 1.5,0.25 3.5,-1 z"
+ style="fill:none;stroke:url(#linearGradient23813);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23692"
+ d="m 220.5,446.75 0,0 0.75001,-3.5 -1e-5,-1.5 -1.5,0 1e-5,1.5 0.74999,3.5 z"
+ style="fill:none;stroke:url(#linearGradient23815);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23695"
+ d="m 216.25,442.5 0,0 3.50001,0.75 1.49999,0 0,-1.5 -1.49999,0 -3.50001,0.75 z"
+ style="fill:none;stroke:url(#linearGradient23817);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23697"
+ d="m 220.5,438.25 0,0 -0.74999,3.75 -1e-5,1.25 1.5,0 1e-5,-1.25 -0.75001,-3.75 z"
+ style="fill:none;stroke:url(#linearGradient23819);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23700">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23702"
+ d="m 220,437 -0.5,4.5 0.25,1.75 1.5,0 0.25,-1.75 -0.5,-4.5 -1,0 z"
+ style="fill:url(#linearGradient23821);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23704"
+ d="m 226,442 -4.5,-0.5 -1.75,0.25 0,1.5 1.75,0.25 4.5,-0.5 0,-1 z"
+ style="fill:url(#linearGradient23823);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23706"
+ d="m 220,448 -0.5,-4.5 0.25,-1.75 1.5,0 0.25,1.75 -0.5,4.5 -1,0 z"
+ style="fill:url(#linearGradient23825);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23708"
+ d="m 215,443 4.5,0.5 1.75,-0.25 0,-1.5 -1.75,-0.25 -4.5,0.5 0,1 z"
+ style="fill:url(#linearGradient23827);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(135,-187.00002)"
+ id="g23713">
+ <rect
+ y="628"
+ x="85"
+ height="2.9999599"
+ width="1"
+ id="rect23715"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23717"
+ width="1"
+ height="3"
+ x="629"
+ y="-87" />
+ </g>
+ </g>
+ <g
+ id="g23719"
+ transform="translate(0,4)">
+ <path
+ inkscape:transform-center-y="-1.25"
+ sodipodi:nodetypes="ccccccc"
+ id="path23728"
+ d="m 218.75004,424.50004 -0.5,0 -0.50004,1.74996 0.25004,1.75004 1,0 0.24996,-1.75004 -0.49996,-1.74996 z"
+ style="fill:none;stroke:url(#linearGradient23829);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23831);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 221.50004,427.75004 0,-0.5 -1.74996,-0.50004 -1.75004,0.25004 0,1 1.75004,0.24996 1.74996,-0.49996 z"
+ id="path23736"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23833);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215.50004,427.25004 0,0.5 1.74996,0.50004 1.75004,-0.25004 0,-1 -1.75004,-0.24996 -1.74996,0.49996 z"
+ id="path23738"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23835);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.25004,430.50004 0.5,0 0.50004,-1.74996 -0.25004,-1.75004 -1,0 -0.24996,1.75004 0.49996,1.74996 z"
+ id="path23740"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.25"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.49998"
+ id="path23742"
+ d="m 218.00004,424.00004 -0.12109,2.86328 0.1211,1.13676 0.99999,-4e-5 0.125,-1.125 -0.125,-2.875 -1,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23837);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23839);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 222.00004,427.00004 -2.86328,-0.12109 -1.13676,0.12109 4e-5,1 1.125,0.125 2.875,-0.125 0,-1 z"
+ id="path23744"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23841);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.00004,431.00004 0.12109,-2.86328 -0.1211,-1.13676 -0.99999,4e-5 -0.125,1.125 0.125,2.875 1,0 0,0 0,0 0,0 z"
+ id="path23746"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23843);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215.00004,428.00004 2.86328,0.12109 1.13676,-0.12109 -4e-5,-1 -1.125,-0.125 -2.875,0.125 0,1 z"
+ id="path23748"
+ inkscape:transform-center-y="-1.49998"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(133.00004,-201.99996)"
+ id="g23751">
+ <rect
+ y="628.5"
+ x="85"
+ height="2"
+ width="1"
+ id="rect23753"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23755"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ <g
+ id="g23757"
+ transform="translate(0,-4)">
+ <g
+ transform="translate(0,-6.4549394)"
+ id="g23759">
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23767"
+ d="m 230.20453,450.95187 0,0 -2.22727,-0.63574 -0.95454,0.15894 0,0.9536 0.95454,0.15893 2.22727,-0.63573 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23845);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23770"
+ d="m 227.49999,453.65374 0,0 0.63637,-2.22507 -0.15909,-0.9536 -0.95455,0 -0.15909,0.9536 0.63636,2.22507 z"
+ style="fill:none;stroke:url(#linearGradient23847);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23774"
+ d="m 224.79546,450.95187 0,0 2.22727,0.63574 0.95454,-0.15894 0,-0.9536 -0.95454,-0.15893 -2.22727,0.63573 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient23849);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23851);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.5,448.25 0,0 -0.63637,2.22507 0.15909,0.9536 0.95455,0 0.15909,-0.9536 L 227.5,448.25 z"
+ id="path23776"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23778">
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23780"
+ d="m 227.18182,441.00653 -0.31818,2.86081 0.15909,1.11253 0.95454,0 0.15909,-1.11253 -0.31818,-2.86081 -0.63636,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23853);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23782"
+ d="m 231,444.1852 -2.86364,-0.31786 -1.11363,0.15893 0,0.9536 1.11363,0.15894 2.86364,-0.31787 0,-0.63574 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23856);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23784"
+ d="m 227.18182,447.99961 -0.31818,-2.8608 0.15909,-1.11254 0.95454,0 0.15909,1.11254 -0.31818,2.8608 -0.63636,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23858);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.75"
+ id="path23786"
+ d="m 224.00001,444.82094 2.86363,0.31787 1.11363,-0.15894 0,-0.9536 -1.11363,-0.15893 -2.86363,0.31786 0,0.63574 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23860);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23788">
+ <g
+ transform="translate(141.99999,-184.99353)"
+ id="g23791">
+ <rect
+ y="628.5"
+ x="85"
+ height="2"
+ width="1"
+ id="rect23793"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23795"
+ width="1"
+ height="2"
+ x="629"
+ y="-86.5" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g24300"
+ transform="translate(-49,6.0000069)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="529"
+ x="117"
+ height="16"
+ width="16"
+ id="rect24298"
+ style="opacity:0;fill:#cccccc;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(28.71596,210.64282)"
+ id="g41346"
+ style="display:inline">
+ <rect
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect41308"
+ width="14"
+ height="6.0000124"
+ x="88.784042"
+ y="326.84842"
+ ry="2.0305908"
+ rx="2.0305908"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ rx="1.029202"
+ ry="1.029202"
+ y="327.84842"
+ x="89.784042"
+ height="4.00875"
+ width="12"
+ id="rect41626"
+ style="fill:none;stroke:url(#linearGradient24317);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="2.0154257"
+ ry="2.0154257"
+ y="319.85718"
+ x="88.784042"
+ height="4.9999971"
+ width="14"
+ id="rect41313"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new" />
+ <rect
+ rx="0.97821051"
+ ry="0.97821051"
+ y="320.85718"
+ x="89.784042"
+ height="2.9999971"
+ width="12.000008"
+ id="rect41629"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24319);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41631"
+ width="8"
+ height="3.9999919"
+ x="89.284042"
+ y="320.35718"
+ rx="0"
+ ry="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient24321);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect41633"
+ width="12.000008"
+ height="2.9999971"
+ x="89.784042"
+ y="320.85718"
+ ry="0.97821051"
+ rx="0.97821051" />
+ <rect
+ style="opacity:0.6;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41635"
+ width="0.99999988"
+ height="3.0000272"
+ x="96.284042"
+ y="320.85718"
+ rx="0"
+ ry="0" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ transform="matrix(-1,0,0,1,193.28404,-130.61032)"
+ id="g41637">
+ <g
+ id="g41639">
+ <rect
+ transform="matrix(-1,0,0,1,194,-1.1e-6)"
+ ry="0"
+ rx="0"
+ y="459.9675"
+ x="91"
+ height="1"
+ width="1"
+ id="rect41641"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(-1,0,0,1,194,-1.1e-6)"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24094"
+ width="1"
+ height="3"
+ x="92"
+ y="458.9675"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24096"
+ width="1"
+ height="1"
+ x="92"
+ y="459.9675"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="458.9675"
+ x="93"
+ height="3"
+ width="1"
+ id="rect24098"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g24339"
+ transform="translate(0,128.00001)">
+ <rect
+ y="407"
+ x="194"
+ height="16"
+ width="16"
+ id="rect24195"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-230,238.99245)"
+ id="g41674"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient24238);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 424.5,170.5 0,10.5 1.5,1.5 9.5,0 0,-11 -7,0 0,-1 -4,0 z"
+ id="path24199"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline"
+ id="g41677"
+ transform="translate(-26,49.00749)">
+ <rect
+ ry="0"
+ rx="0"
+ y="120.50006"
+ x="456.5"
+ height="7.9999371"
+ width="7.0000038"
+ id="rect41679"
+ style="fill:url(#linearGradient24276);fill-opacity:1;fill-rule:nonzero;stroke:#4d4d4d;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <g
+ id="g41681">
+ <path
+ style="fill:#c80000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 192,239 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z"
+ transform="translate(267,-117.99994)"
+ id="path41683"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ ry="0"
+ rx="0"
+ y="121.5"
+ x="457.5"
+ height="5.9999981"
+ width="5.0000038"
+ id="rect41685"
+ style="fill:none;stroke:url(#linearGradient24278);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ </g>
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient24244);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 427.5,175.5 12,0.008 0,5.5 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.00755 0,-9e-4 z"
+ id="path41687"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 426.5,181.5 -1.01563,-0.98437 0,-9.02344 2,0 0,1 2.17355,0.0154"
+ id="path41689"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 428,181.50755 9.5,0"
+ id="path41691"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41693"
+ d="m 438.5,176.50755 -10,-0.008 0,4.00755 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24246);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 428,171.00755 0,2 -3,0 0,-2 3,0 z"
+ id="path24228"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24230"
+ transform="translate(270,-408)"
+ style="fill:#d45500;fill-opacity:1;display:inline" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path24234"
+ d="m 424.5,170.5 0,10.5 1.5,1.5 12,0.008 1.5,-1.49245 0,-5.5 -2,-0.008 0,-6 -7,0 0,2 -2,-0.008 0,-1 -4,0 0,4.5e-4 z"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#d40000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 189.5,244.14308 0,-5.64308 7,0 0,5.64842"
+ id="path41698"
+ sodipodi:nodetypes="cccc"
+ transform="translate(241,-68.99245)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(-65,-169.00755)"
+ id="g24176" />
+ <g
+ id="g24393"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(0,128.00001)">
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24152"
+ width="16"
+ height="16"
+ x="89"
+ y="407" />
+ <g
+ id="g24378">
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path41754"
+ d="m 89.5,409.49245 0,10.5 1.5,1.5 9.5,0 0,-11 -7,0 0,-1 -4,0 z"
+ style="fill:url(#linearGradient24374);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline"
+ id="g41756"
+ transform="translate(-361,287.99994)">
+ <rect
+ ry="0"
+ rx="0"
+ y="120.50006"
+ x="456.5"
+ height="7.9999371"
+ width="7.0000038"
+ id="rect24160"
+ style="fill:url(#linearGradient41721);fill-opacity:1;fill-rule:nonzero;stroke:#333333;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="121.5"
+ x="457.5"
+ height="5.9999981"
+ width="5.0000038"
+ id="rect24162"
+ style="fill:none;stroke:url(#linearGradient41723);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path41760"
+ style="opacity:0.65;fill:none;stroke:#333333;stroke-width:0.9999997px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 458.49992,122.50172 3.00006,0 m -3.00006,1.99301 3.00006,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path41762"
+ d="m 92.5,414.49245 12,0.008 0,5.5 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.00755 0,-9e-4 z"
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient24367);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41764"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-9.02344 2,0 0,1 2.17355,0.0154"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41766"
+ d="m 93,420.5 9.5,0"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient24362);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 103.5,415.5 -10,-0.008 0,4.00755 -1.5,1.5 -1.5,-1.5"
+ id="path41768"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path24174"
+ d="m 93,410 0,2 -3,0 0,-2 3,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,409.49245 0,10.5 1.5,1.5 12,0.008 1.5,-1.49245 0,-5.5 -2,-0.008 0,-6 -7,0 0,2 -2,-0.008 0,-1 -4,0 0,4.5e-4 z"
+ id="path24178"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path24190"
+ d="m 95.5,410.5 0,-2 7,0 0,5.92967"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g22846"
+ transform="translate(84,86)">
+ <rect
+ ry="0"
+ y="323"
+ x="26"
+ height="16"
+ width="16"
+ id="rect22783"
+ style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22817">
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ id="path22788"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path22790"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ style="opacity:0.9;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 33,338 2,0 0,1 -2,-10e-6 L 33,338 z"
+ id="path22792"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#24221c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22794"
+ width="6"
+ height="4.75"
+ x="31"
+ y="333.25"
+ rx="0.765625"
+ ry="0.765625" />
+ <rect
+ y="334"
+ x="32"
+ height="3"
+ width="4"
+ id="rect22796"
+ style="fill:#736c54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ style="fill:url(#linearGradient22892);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 0.48959,-2e-6 2.86976,-0.0067 3.35937,-0.0067 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 L 249.25,80 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 3.35937,-0.0067 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 C 252.11976,81.993327 249.7396,82 249.25,82 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z"
+ id="path22798"
+ sodipodi:nodetypes="cssssccccsccsssc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22800"
+ d="m 32.25,336.24999 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 32.25,334.24999 1.25,0"
+ id="path22802"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="336"
+ x="37"
+ height="1"
+ width="0.25"
+ id="rect22804"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22807"
+ width="0.25"
+ height="1"
+ x="37"
+ y="334" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22809"
+ width="0.25"
+ height="1"
+ x="30.75"
+ y="336" />
+ <rect
+ y="334"
+ x="30.75"
+ height="1"
+ width="0.25"
+ id="rect22812"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(1.1428575,0,0,1.1249998,-252.2858,245.25001)"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ id="path22814"
+ style="fill:url(#linearGradient22954);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ inkscape:radius="0.5"
+ sodipodi:type="inkscape:offset" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.5"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ style="opacity:0.6;fill:url(#radialGradient22952);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22816"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ transform="matrix(1.1428578,0,0,1.1562502,-252.28587,242.81248)" />
+ <path
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ style="fill:none;stroke:url(#linearGradient22928);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path22818"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path22820"
+ style="opacity:0.25;fill:url(#radialGradient22950);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path22822"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)" />
+ <path
+ id="path22824"
+ style="fill:none;stroke:url(#radialGradient22922);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="333"
+ x="31.5"
+ height="0.75"
+ width="5"
+ id="rect22826"
+ style="opacity:0.85;fill:#3d3829;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22828"
+ d="m 32.5,337.01145 3,-0.0115 0,1 -3,0.0114 0,-0.99999 0,9e-5 0,0 0,0 z"
+ style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22830"
+ d="m 33,330 0,2.75 2,0 0,-2.75 -2,0 z"
+ style="opacity:0.2;fill:url(#linearGradient22917);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="328"
+ x="32"
+ height="1"
+ width="1"
+ id="rect22832"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 32.875,333.12498 c 0,-1.39113 -0.517691,-2.25114 -1.113536,-2.77529 C 31.064459,329.73656 30.5,328.93567 30.5,327.93988 c 0,-1.84706 1.637,-3.43989 3.5,-3.43989 1.863,0 3.5,1.59283 3.5,3.43989 0,0.99579 -0.564459,1.79668 -1.261464,2.40981 -0.595845,0.52415 -1.113536,1.38416 -1.113536,2.77529"
+ style="fill:none;stroke:url(#radialGradient23727);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path22836"
+ sodipodi:nodetypes="csscssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22838"
+ d="m 33,338.00001 0.5,0 0,1 L 33,339 l 0,-0.99999 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="329"
+ x="33"
+ height="1"
+ width="2"
+ id="rect23759"
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23761"
+ width="1"
+ height="1"
+ x="35"
+ y="328" />
+ </g>
+ </g>
+ <g
+ id="g23767"
+ transform="translate(84,107.00001)">
+ <rect
+ style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23769"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g23771">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path23788"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ style="opacity:0.3;fill:#ff8400;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b1600;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ id="path23802"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23808"
+ d="m 33,338 2,0 0,1 -2,-10e-6 L 33,338 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect23810"
+ style="fill:#2b1600;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#846544;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23812"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path23816"
+ d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 0.48959,-2e-6 2.86976,-0.0067 3.35937,-0.0067 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 L 249.25,80 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 3.35937,-0.0067 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 C 252.11976,81.993327 249.7396,82 249.25,82 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z"
+ style="fill:url(#linearGradient23890);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 32.25,336.24999 1.25,0"
+ id="path23819"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23821"
+ d="m 32.25,334.24999 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23824"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="36.96875"
+ height="1.099999"
+ width="0.28125"
+ id="rect23826"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="336"
+ x="30.75"
+ height="1"
+ width="0.25"
+ id="rect23828"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23830"
+ width="0.28125"
+ height="1.099999"
+ x="30.90625"
+ y="333.95001" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.5"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ style="fill:url(#linearGradient23892);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23838"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ transform="matrix(1.1428575,0,0,1.1249998,-252.2858,245.25001)" />
+ <path
+ transform="matrix(1.1428578,0,0,1.1562502,-252.28587,242.81248)"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ id="path23840"
+ style="opacity:0.95;fill:url(#radialGradient23894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ inkscape:radius="0.5"
+ sodipodi:type="inkscape:offset" />
+ <path
+ id="path23842"
+ style="fill:none;stroke:url(#linearGradient23896);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient23898);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23844"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
+ <path
+ transform="matrix(0.99567,0,-0.00787885,1,-30.654936,191)"
+ sodipodi:type="arc"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path23846"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ style="fill:none;stroke:url(#radialGradient23900);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path23848"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.85;fill:#503416;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23850"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 32.5,337.01145 3,-0.0115 0,1 -3,0.0114 0,-0.99999 0,9e-5 0,0 0,0 z"
+ id="path23852"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:url(#linearGradient23902);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 33,330 0,2.75 2,0 0,-2.75 -2,0 z"
+ id="path23860"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23862"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path23866"
+ style="fill:none;stroke:url(#radialGradient23904);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 32.875,333.12498 c 0,-1.39113 -0.517691,-2.25114 -1.113536,-2.77529 C 31.064459,329.73656 30.5,328.93567 30.5,327.93988 c 0,-1.84706 1.637,-3.43989 3.5,-3.43989 1.863,0 3.5,1.59283 3.5,3.43989 0,0.99579 -0.564459,1.79668 -1.261464,2.40981 -0.595845,0.52415 -1.113536,1.38416 -1.113536,2.77529"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 33,338.00001 0.5,0 0,1 L 33,339 l 0,-0.99999 z"
+ id="path23873"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23877"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect23888"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g23912"
+ transform="translate(-21,233.00001)">
+ <rect
+ style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23915"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g23917">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path23920"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ id="path23927"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path23931"
+ d="m 33,338 2,0 0,1 -2,-10e-6 L 33,338 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect23933"
+ style="fill:#24221c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#a89858;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23935"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path23948"
+ d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 0.48959,-2e-6 2.86976,-0.0067 3.35937,-0.0067 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 L 249.25,80 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 3.35937,-0.0067 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 C 252.11976,81.993327 249.7396,82 249.25,82 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z"
+ style="fill:url(#linearGradient24090);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 32.35,336.4 1.25,0"
+ id="path23950"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23956"
+ d="m 32.35,334.4 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23959"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="36.96875"
+ height="1.099999"
+ width="0.28125"
+ id="rect23961"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="336"
+ x="30.75"
+ height="1"
+ width="0.25"
+ id="rect23965"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23967"
+ width="0.28125"
+ height="1.099999"
+ x="30.90625"
+ y="333.95001" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.5"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ style="fill:url(#linearGradient24092);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23982"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ transform="matrix(1.1428575,0,0,1.1249998,-252.2858,245.25001)" />
+ <path
+ transform="matrix(1.1428578,0,0,1.1562502,-252.28587,242.81248)"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ id="path23984"
+ style="opacity:0.6;fill:url(#radialGradient24094);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ inkscape:radius="0.5"
+ sodipodi:type="inkscape:offset" />
+ <path
+ id="path24054"
+ style="fill:none;stroke:url(#linearGradient24096);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient24098);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24056"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
+ <path
+ transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)"
+ sodipodi:type="arc"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path24060"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ style="fill:none;stroke:url(#radialGradient24100);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path24064"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.85;fill:#504416;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24066"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 32.5,337.01145 3,-0.0115 0,1 -3,0.0114 0,-0.99999 0,9e-5 0,0 0,0 z"
+ id="path24068"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:url(#linearGradient24102);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 33,330 0,2.75 2,0 0,-2.75 -2,0 z"
+ id="path24070"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24072"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path24078"
+ style="fill:none;stroke:url(#radialGradient24104);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 32.875,333.12498 c 0,-1.39113 -0.517691,-2.25114 -1.113536,-2.77529 C 31.064459,329.73656 30.5,328.93567 30.5,327.93988 c 0,-1.84706 1.637,-3.43989 3.5,-3.43989 1.863,0 3.5,1.59283 3.5,3.43989 0,0.99579 -0.564459,1.79668 -1.261464,2.40981 -0.595845,0.52415 -1.113536,1.38416 -1.113536,2.77529"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 33,338.00001 0.5,0 0,1 L 33,339 l 0,-0.99999 z"
+ id="path24082"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24086"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect24088"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g25056"
+ transform="translate(-168,2)">
+ <g
+ style="opacity:0.75"
+ id="g24996">
+ <rect
+ y="71"
+ x="446"
+ height="16"
+ width="16"
+ id="rect24939"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24941"
+ transform="translate(359,-336)">
+ <path
+ style="fill:url(#linearGradient25073);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,410.5 0,9.49245 1.5,1.5 8.5,0 0,-9.99245 -7,0 0,-1 -3,0 z"
+ id="path24943"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g24945"
+ style="display:inline" />
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25075);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 92.5,414.4849 10,0.0151 0,5.50755 -1.5,1.49245 -10,0 0,-2 1.5,0 0,-5.0151 z"
+ id="path24947"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-8.02344 1.01563,0.0154 0,1 7,0"
+ id="path24949"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 93,420.5 7.5,0"
+ id="path24951"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24953"
+ d="m 101.5,415.50755 -8,-0.008 0,4 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient25077);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path24957"
+ d="m 89.5,410.5 0,9.49245 1.5,1.5 10,0.0151 1.5,-1.49245 0,-5.50755 -3,-0.008 0,-2.9849 -7,-0.0151 0,-1 -3,0 0,4.5e-4 0,0 0,0 z"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25007"
+ transform="matrix(0.9986805,0,0,1,129.4308,-202)">
+ <rect
+ rx="1.2018067"
+ y="275"
+ x="318.99011"
+ height="3"
+ width="3.0039635"
+ id="rect25009"
+ style="opacity:0.4;fill:none;stroke:#fac900;stroke-width:4.00264168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="1.2018067" />
+ <rect
+ style="opacity:0.8;fill:none;stroke:#e6b800;stroke-width:2.00132084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25011"
+ width="3.0039637"
+ height="3"
+ x="318.99011"
+ y="275"
+ rx="1.2018068"
+ ry="1.2018068" />
+ <path
+ style="fill:#aa8800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 318.99011,278 c 0,-1.00003 3e-5,-2.00003 3e-5,-3.00006 1.00131,0 2.00262,0 3.00393,0 0,1.00003 -3e-5,2.00003 -3e-5,3.00006 -1.00131,0 -2.00262,0 -3.00393,0 z"
+ id="path32046"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 318.48945,276 c 1.33509,0 2.67017,10e-6 4.00526,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.33509,0 -2.67017,-1e-5 -4.00526,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ id="path25013"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25015"
+ d="m 319.99139,278.50006 c 0,-1.33337 10e-6,-2.66669 10e-6,-4.00006 0.33379,0 0.66758,0 1.00137,0 0,1.33337 -1e-5,2.66669 -1e-5,4.00006 -0.33379,0 -0.66758,0 -1.00137,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g42026"
+ transform="translate(-126,2)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g41200"
+ style="opacity:0.65;display:inline;enable-background:new">
+ <rect
+ y="71"
+ x="341"
+ height="16"
+ width="16"
+ id="rect41164"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41166"
+ transform="translate(252,-337)">
+ <path
+ style="fill:url(#linearGradient42055);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,409.49245 0,10.5 1.5,1.5 10.5,0.008 0,-11 -8,-0.008 0,-1 -4,0 z"
+ id="path41168"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g41170"
+ style="display:inline" />
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient42057);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 92.5,414.49245 11,0.0151 0,5.5 -1.5,1.49245 -11,0 0,-2 1.5,0 0,-5.00755 0,0 0,0 0,0 z"
+ id="path41172"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-9.02344 2,0 0,1 L 100.5,411.5"
+ id="path41174"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 93,420.5 9.5,0"
+ id="path41176"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41178"
+ d="m 102.5,415.5 -9,-0.008 0,4.00755 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient42059);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 93,410 0,2 -3,0 0,-2 3,0 z"
+ id="path41180"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path41182"
+ d="m 89.5,409.50755 0,10.4849 1.5,1.5 11,0.008 1.5,-1.49245 0,-5.5 -2,-0.008 0,-3.9849 -8,-0.008 0,-1 -4,0 0,4.5e-4 z"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-81,-80.992447)"
+ id="g24185"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccc"
+ id="path41134"
+ d="m 428.75,158.5 3,-0.008 0,6.50755 0,2.50755 0.75,0 0,-1 1,0 0,-1 2,0 0,1 1,0 0,1 0.67818,0 0,-9.50755 -0.67818,0 0,-0.5 -0.25,0 0,-0.75 -1.75,-0.008 -4.75,0.008 0,1 -1,0 0,0.75 0,4.5e-4 z"
+ style="fill:none;stroke:#401406;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41137"
+ transform="translate(-16,37.992447)">
+ <g
+ transform="translate(0,-1)"
+ id="g41139">
+ <rect
+ style="fill:#822b0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24197"
+ width="3"
+ height="0.99999988"
+ x="445"
+ y="121.00755" />
+ <g
+ id="g24199">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41143"
+ d="m 446,120 0,1 6,0 0,-1 -6,0 z"
+ style="fill:#ed7e5c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:#e7541a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 448,121 0,9.00755 1,0.008 0,-1 1,0 0,-1 1,-0.008 0,1.00755 1,0 0,1 1,-0.008 0,-9.00755 -5,0 0,4.5e-4 0,0 0,0 z"
+ id="path41145"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 448,121 0,9.00755 1,0 0,-9.00755 -1,0 0,0 0,0 0,0 z"
+ id="path41147"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41149"
+ d="m 452,121 0,9.00755 1,0 0,-9.00755 -1,0 0,0 0,0 0,0 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 446,120.00755 0,1 2,-0.008 0,-1 -2,0.008 z"
+ id="path41151"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41153"
+ d="m 445,121.00755 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.45;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24216"
+ style="opacity:0.3">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41156"
+ d="m 451,128.00755 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 450,127.00755 0,1 1,0 0,-1 -1,0 0,0 0,0 0,0 z"
+ id="path41158"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41160"
+ d="m 449,128.00755 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g62487"
+ transform="translate(0,128)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23556"
+ width="16"
+ height="16"
+ x="281"
+ y="68" />
+ <g
+ transform="matrix(0,-1,1,0,-254.00001,365.00041)"
+ id="g24740">
+ <g
+ style="opacity:0.7"
+ id="g24922">
+ <path
+ d="m 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:#1a1a1a;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24671"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24673"
+ style="fill:none;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="323.5"
+ x="80.500122"
+ height="3"
+ width="2.9998772"
+ id="rect24678"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path24681"
+ d="m 83.00041,324.00001 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24684"
+ width="2.9998772"
+ height="3"
+ x="80.49971"
+ y="334.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 83,335 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path24686"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g62412"
+ transform="translate(1,127)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="67"
+ x="303"
+ height="16"
+ width="16"
+ id="rect23554"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0,1,1,0,-255,214)"
+ id="g24695">
+ <g
+ transform="translate(-356.00003,55.00003)"
+ id="g24697">
+ <g
+ transform="translate(296.99995,249.99998)"
+ id="g24699"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline" />
+ <g
+ id="g24701"
+ transform="translate(187.99958,-21.0368)">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="opacity:0.9;fill:none;stroke:#2b1600;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24703"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path24705"
+ style="fill:none;stroke:#ed993f;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24709" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ d="m 258.50045,291.53677 0,3.28125 0,6.71875 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:url(#linearGradient62436);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24711"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g24713">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24715"
+ width="1"
+ height="1"
+ x="90"
+ y="325"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="325"
+ x="96"
+ height="1"
+ width="1"
+ id="rect24717"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24719"
+ width="1"
+ height="1"
+ x="102"
+ y="325"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ transform="translate(0,5)"
+ id="g24721">
+ <rect
+ ry="0"
+ rx="0"
+ y="325"
+ x="90"
+ height="1"
+ width="1"
+ id="rect24723"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24725"
+ width="1"
+ height="1"
+ x="96"
+ y="325"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="325"
+ x="102"
+ height="1"
+ width="1"
+ id="rect24727"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g24729"
+ transform="translate(0,9.96875)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24731"
+ width="1"
+ height="1"
+ x="90"
+ y="325.03125"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="325.03125"
+ x="96"
+ height="1"
+ width="1"
+ id="rect24733"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24736"
+ width="1"
+ height="1"
+ x="102"
+ y="325.03125"
+ rx="0"
+ ry="0" />
+ <path
+ id="rect24766"
+ d="m 70,304 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.27999998;fill:#2b1600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(21,11.03125)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g62543"
+ transform="translate(1,2)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="340"
+ x="261"
+ height="16"
+ width="16"
+ id="rect23562"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24926"
+ transform="matrix(0,1,1,0,18,172)">
+ <g
+ id="g24928"
+ transform="translate(-356.00003,55.00003)">
+ <g
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g24930"
+ transform="translate(296.99995,249.99998)" />
+ <g
+ transform="translate(187.99958,-21.0368)"
+ id="g24932">
+ <path
+ id="path24935"
+ style="opacity:0.9;fill:none;stroke:#0b1728;stroke-width:2.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 258.50045,291.53677 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:url(#linearGradient62558);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24937"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g24939" />
+ </g>
+ </g>
+ <g
+ id="g24943">
+ <path
+ id="rect24945"
+ transform="translate(-252,42)"
+ d="m 342,283 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m -12,5 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m -12,5 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.7;fill:url(#linearGradient62560);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g24951"
+ transform="translate(0,5)" />
+ <g
+ transform="translate(0,9.96875)"
+ id="g24959">
+ <path
+ style="opacity:0.27999998;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 70,304 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 6,-1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 5,0 0,1 1,0 0,-1 -1,0 z m -11,4 0,1 1,0 0,-1 -1,0 z m 6,0 0,1 1,0 0,-1 -1,0 z"
+ id="path24967"
+ transform="translate(21,11.03125)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24707"
+ transform="translate(-210,128)">
+ <rect
+ y="302"
+ x="299"
+ height="16"
+ width="16"
+ id="rect24543"
+ style="opacity:0;fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#f0a453;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 304.5,308.5 c 1.52069,0 3,-1.25 3,-2.5 0,-2 1.5,-3.5 3.5,-3.5 2,0 3.5,1.568 3.5,3.5 0,1.84581 -1.5,3.5 -3.5,3.5 -1.25,0 -2.5,1.5 -2.5,3 0,2.25 -1.75,4 -4,4 -2.25,0 -4,-1.75 -4,-4 0,-2.25 1.75,-4 4,-4 z"
+ id="path24546"
+ sodipodi:nodetypes="cssssszzs"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 311,303 c -1.75507,0 -3,1.24493 -3,3 0,0.81824 -0.48216,1.55558 -1.125,2.09375 C 306.23216,308.63192 305.39457,309 304.5,309 c -1.996,0 -3.5,1.504 -3.5,3.5 0,1.996 1.504,3.5 3.5,3.5 1.996,0 3.5,-1.504 3.5,-3.5 0,-0.88607 0.36895,-1.73024 0.90625,-2.375 0.5373,-0.64476 1.27281,-1.125 2.09375,-1.125 1.72989,0 3,-1.41958 3,-3 0,-1.67845 -1.25603,-3 -3,-3 z"
+ id="path24792"
+ style="opacity:0.8;fill:url(#linearGradient24797);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86598092;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.48985747"
+ sodipodi:type="inkscape:offset" />
+ <path
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path24550"
+ style="fill:none;stroke:url(#radialGradient24599);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset" />
+ <path
+ transform="translate(96.999991,232.95)"
+ sodipodi:type="arc"
+ style="opacity:0.75;fill:url(#radialGradient43962);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path43958"
+ sodipodi:cx="207.5"
+ sodipodi:cy="79.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 211,79.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" />
+ <path
+ d="m 211,79.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="79.5"
+ sodipodi:cx="207.5"
+ id="path43960"
+ style="opacity:0.75;fill:url(#radialGradient43964);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.14754021;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.8714292,0,0,0.8714292,130.17844,236.77138)" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.96440691"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="fill:none;stroke:url(#radialGradient24632);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24630"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ transform="matrix(0,-1,-1,0,617,617)" />
+ <path
+ transform="matrix(0,-1,-1,0,617,617)"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path24809"
+ style="fill:none;stroke:url(#linearGradient24820);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g23140"
+ transform="translate(32,248.99993)"
+ mask="url(#mask23189)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="286"
+ x="-6"
+ height="16"
+ width="16"
+ id="rect39828"
+ style="opacity:0;fill:#ffffff;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23145">
+ <g
+ id="g23149">
+ <path
+ id="path39832"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -4.5,289.5 1.5,0 c 3.5,0 1.9989834,11 6.5,11 2.6782554,0 2.25,-3 5.25,-3 l 0.25,0"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ d="m 9,297.5 -0.25,0 c -3,0 -2.5,3 -5.25,3 -4.5010166,0 -3,-11 -6.5,-11 l -2,0"
+ style="fill:none;stroke:#bde7a2;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39834"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path39836"
+ style="opacity:0.35;fill:none;stroke:url(#radialGradient23167);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 3.5,300.5 c -4.5,0 -3,-11 -6.5,-11"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23161">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path39839"
+ d="m -4.5,294.5 6,0 c 4,0 2,-7 6,-7 l 1,0"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -5,294.5 6.5,0 c 4,0 2,-7 6,-7 l 1.5,0"
+ id="path23165"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(54,277.99993)"
+ id="g24129"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24131"
+ width="16"
+ height="16"
+ x="203"
+ y="257" />
+ <g
+ style="display:inline;enable-background:new"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g24133"
+ transform="translate(-39.983882,19.00809)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 244.51612,238.49191 -0.0161,3 7.98388,0 0.0161,-3 -7.98388,0 z"
+ id="path39845"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path39847"
+ d="m 247.51612,241.49191 -0.0161,3 11,0 0.0161,-3 -11,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path39849"
+ d="m 243.5,247.49191 -0.0161,3 12,0 0.0161,-3 -12,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 250.48388,250.49191 -0.0161,3 7.01612,0 0.0161,-3 -7.01612,0 z"
+ id="path39851"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient24202);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 205.51612,259.5 c 0,-0.25 0,-1 0,-1 l 6,0"
+ id="path39853"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path24145"
+ d="m 208.51612,262.5 c 0,-0.25 0,-1 0,-1 l 9,0"
+ style="fill:none;stroke:url(#linearGradient24204);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24206);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 204.5,268.5 c 0,-0.25 0,-1 0,-1 l 10,0"
+ id="path24147"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient24208);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 211.5,271.5 c 0,-0.25 0,-1 0,-1 l 5,0"
+ id="path39857"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(2,298)"
+ id="g40315"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g40317"
+ transform="matrix(-1.023377,0,0,1.016727,-99.930251,85.381494)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40319"
+ d="m -114.25921,159.20547 0,-6.88483 5.85921,2.61269 -0.01,7.96045 -5.84921,-3.68831 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.96069634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.96069634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -102.53333,159.20547 0,-6.88483 -5.86667,2.61269 -0.0101,7.96045 5.87676,-3.68831 10e-6,0 0,0 0,0 z"
+ id="path40321"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40323"
+ d="m -102.53333,152.32064 -5.8704,-1.47533 -5.85548,1.47533 5.85921,2.85858 5.86667,-2.85858 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.96069634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40325"
+ d="m -114.25921,159.20548 0,-6.88484 5.86294,-1.47532 c 0,2.52838 -0.004,11.53297 -0.004,12.08795 l -5.85864,-3.72779 -3e-4,0 z"
+ style="fill:url(#linearGradient40722);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -102.53333,159.20548 0,-6.88484 -5.8704,-1.47533 0.003,12.08796 5.86724,-3.72779 1.6e-4,0 0,0 0,0 z"
+ id="path40327"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40329"
+ d="m -102.53333,152.32064 -5.8704,-1.47533 -5.85548,1.47533 5.85548,1.72121 5.8704,-1.72121 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path40331"
+ d="m -103.02191,152.32064 1e-5,6.63895 0,0 -5.37437,3.44241 -5.37437,-3.44241 1e-5,-6.63895"
+ style="fill:none;stroke:url(#linearGradient40724);stroke-width:0.98034734px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="237"
+ x="3"
+ height="16"
+ width="16"
+ id="rect40333"
+ style="fill:none;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(12.401337,137.46985)"
+ id="g40381"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40383"
+ width="16"
+ height="16"
+ x="265.59866"
+ y="397.53015" />
+ <g
+ style="display:inline"
+ id="g40385"
+ transform="translate(2.6147745,148.53014)">
+ <path
+ id="path40387"
+ d="m 270,251 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.29736,-1.49999 -1.5,1.5 1.51611,1.28124 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.51611,1.28126 1.5,1.5 1.29736,-1.50001 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.26514,1.50001 1.5,-1.5 -1.25,-1.25 c 0.29338,-0.44313 0.26916,-0.96592 0.39111,-1.50001 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.0977,-1.05686 -0.39111,-1.49999 l 1.25,-1.25 -1.5,-1.5 -1.25,1.25 C 273.04076,252.70663 272.53409,252.74695 272,252.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient40734);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 270,251 0,1.625 c -0.53409,0.12195 -1.07298,0.0816 -1.51611,0.37501 l -1.25,-1.25 -1.5,1.5 1.25,1.25 c -0.29338,0.44313 -0.23694,0.9659 -0.35889,1.49999 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.0655,1.05688 0.35889,1.50001 l -1.25,1.25 1.5,1.5 1.25,-1.25 c 0.44313,0.29338 0.98202,0.25304 1.51611,0.37499 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.04076,-0.0816 1.48389,-0.37499 l 1.25,1.25 1.5,-1.5 -1.25,-1.25 c 0.29338,-0.44313 0.26916,-0.96592 0.39111,-1.50001 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.0977,-1.05686 -0.39111,-1.49999 l 1.25,-1.25 -1.5,-1.5 -1.25,1.25 C 273.04076,252.70663 272.53409,252.74695 272,252.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ id="path40389"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccscccccccc"
+ id="path40391"
+ d="M 274.73389,252.25001 273.5,253.75 m -2,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.01806,0.29269 -1.5172,0.50569 m -1.49,1.50752 c -0.20864,0.49552 -0.41426,1.14284 -0.4928,1.48679 l -1.5,0 0,1 m 1.5,-5 -0.5,0.5 m 1.25,6.5 -1.51611,1.25001"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 273.23389,255.50001 0,3.75 L 269.5,259.25"
+ id="path40393"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 266.43389,253.45001 1,-1"
+ id="path40395"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="535"
+ x="320"
+ height="16"
+ width="16"
+ id="rect40397"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(18.016113,298.07385)"
+ id="g40399"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path40401"
+ d="m 309.21778,249.41313 5.01611,0.013 c 1.29844,0 2.25,-0.80274 2.25,-2.25 l 0.0161,-4.48698 c 0,-1.29844 -0.95156,-2.25 -2.25,-2.25 l -1.75,0"
+ style="opacity:0.6;fill:none;stroke:#191919;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.01000001;fill:none;stroke:#e8a930;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40403"
+ width="1.9930685"
+ height="1.9947703"
+ x="309.50693"
+ y="239.5"
+ ry="0.99734437"
+ rx="0.98426884" />
+ <path
+ style="fill:none;stroke:#bcd0f5;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 310.98389,249.42615 3,0 c 1.29844,0 2.5,-1.20156 2.5,-2.5 l 0.0161,-3.93424 c 0,-1.29844 -1.20156,-2.55274 -2.5,-2.55274 l -1.5,0"
+ id="path40406"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40408"
+ width="7.0161614"
+ height="5.9999523"
+ x="302.46777"
+ y="246.42619"
+ ry="1.5185405"
+ rx="1.7691951"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="0.0128693"
+ ry="0.010695697"
+ y="246.92615"
+ x="302.96777"
+ height="4.9999976"
+ width="6.0161119"
+ id="rect40410"
+ style="fill:url(#linearGradient40736);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="1.5194846"
+ ry="1.4892343"
+ y="237.42615"
+ x="305.49991"
+ height="5.9341388"
+ width="6.9999981"
+ id="rect40412"
+ style="fill:none;stroke:#000000;stroke-width:0.99999958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect40414"
+ width="4.0322218"
+ height="0.99999762"
+ x="303.96777"
+ y="247.92615"
+ ry="0.0053478414"
+ rx="0.0086254831"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="0"
+ ry="0"
+ y="247.42625"
+ x="303.46777"
+ height="3.9999583"
+ width="5.0161114"
+ id="rect40416"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient40738);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ style="fill:url(#linearGradient40740);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect40418"
+ width="5.9999843"
+ height="5.0000072"
+ x="306"
+ y="237.92615"
+ ry="0"
+ rx="0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="0.0071879062"
+ ry="0.0053478414"
+ y="238.92615"
+ x="306.98389"
+ height="0.99999762"
+ width="4.0322237"
+ id="rect40420"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient40742);stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40422"
+ width="5.0067563"
+ height="3.9560828"
+ x="306.5"
+ y="238.41525"
+ ry="0"
+ rx="0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ ry="0"
+ y="248.43787"
+ x="309.48389"
+ height="1.9882908"
+ width="2"
+ id="rect40424"
+ style="fill:#ffb72a;fill-opacity:1;fill-rule:nonzero;stroke:#553800;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="0" />
+ <rect
+ rx="0"
+ style="fill:#ffb72a;fill-opacity:1;fill-rule:nonzero;stroke:#553800;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40426"
+ width="2"
+ height="1.9882908"
+ x="312.48389"
+ y="239.43787"
+ ry="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40520"
+ transform="translate(-1,128)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="407"
+ x="216"
+ height="16"
+ width="16"
+ id="rect40522"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g40524"
+ transform="translate(12,170.00654)">
+ <path
+ sodipodi:nodetypes="cccssssssccccsssssscccccc"
+ id="path40526"
+ d="m 207.5,239.5 0,3 0,5.03125 c -0.31763,0.0283 -0.63892,0.0942 -0.96875,0.21875 -0.61538,0.23235 -1.12455,0.59487 -1.5,1.03125 -0.37546,0.43635 -0.63146,0.99926 -0.46875,1.625 0.1627,0.62575 0.6413,0.93109 1.15625,1.03125 0.51496,0.10016 1.1346,0.0761 1.75,-0.15625 0.61542,-0.23236 1.12456,-0.62615 1.5,-1.0625 0.33776,-0.39252 0.53125,-0.86133 0.53125,-1.46875 l 0,-6.25 6,0 0,5.03125 c -0.31763,0.0283 -0.63892,0.0942 -0.96875,0.21875 -0.61538,0.23235 -1.12455,0.59487 -1.5,1.03125 -0.37546,0.43635 -0.63146,0.99926 -0.46875,1.625 0.1627,0.62575 0.6413,0.93109 1.15625,1.03125 0.51496,0.10016 1.1346,0.0761 1.75,-0.15625 0.61542,-0.23236 1.12456,-0.62615 1.5,-1.0625 C 217.30651,249.82623 217.5,249.3373 217.5,248.75 l 0,-9.25 -1,0 -1,0 -6,0 -2,0 z"
+ style="fill:url(#linearGradient40758);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.58322862;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g40528">
+ <path
+ id="path40530"
+ d="m 207.44628,248.42245 c -0.25577,0.0323 -0.54038,0.11684 -0.81334,0.24698 -0.36394,0.17354 -0.65949,0.40136 -0.86757,0.65378 -0.20806,0.2524 -0.34395,0.56878 -0.21514,0.8647 0.12879,0.29592 0.44506,0.40032 0.76358,0.40164 0.3185,0.001 0.6909,-0.0762 1.05486,-0.24968 0.36397,-0.17355 0.65786,-0.41845 0.86594,-0.67084 0.20807,-0.25239 0.34394,-0.56879 0.21514,-0.86472 -0.12879,-0.29592 -0.44345,-0.38323 -0.76195,-0.38454 -0.0796,-3.4e-4 -0.15625,-0.008 -0.24152,0.003 l 0,-3.2e-4 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient40760);stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 209.5,241.5 6,0"
+ id="path40532"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40762);stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 215.4463,248.42245 c -0.25577,0.0323 -0.54038,0.11684 -0.81334,0.24698 -0.36394,0.17354 -0.65949,0.40136 -0.86757,0.65378 -0.20806,0.2524 -0.34395,0.56878 -0.21514,0.8647 0.12879,0.29592 0.44506,0.40032 0.76358,0.40164 0.3185,0.001 0.6909,-0.0762 1.05486,-0.24968 0.36397,-0.17355 0.65786,-0.41845 0.86594,-0.67084 0.20807,-0.25239 0.34394,-0.56879 0.21514,-0.86472 -0.12879,-0.29592 -0.44345,-0.38323 -0.76195,-0.38454 -0.0796,-3.4e-4 -0.15625,-0.008 -0.24152,0.003 l 0,-3.2e-4 0,0 0,0 z"
+ id="path40534"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g40602"
+ transform="translate(0,128)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40604"
+ width="16"
+ height="16"
+ x="299"
+ y="407" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.927848,0,0,0.916217,147.82022,210.72362)"
+ id="g40606"
+ style="display:inline">
+ <path
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient42519);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.22752953;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path40608"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ style="fill:none;stroke:url(#linearGradient42523);stroke-width:1.17973554;stroke-opacity:1;display:inline"
+ id="g40610"
+ transform="matrix(0.784039,0,0,0.779055,172.50801,241.28815)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40612"
+ style="fill:none;stroke:url(#linearGradient42521);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 309.5,411.5 -3,3 m 0,1 2,2"
+ style="fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40614"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-x="-1.25"
+ inkscape:transform-center-y="1.25"
+ id="path40616"
+ style="fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 306.5,415.5 2,2"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.5;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40618"
+ width="1"
+ height="1.5"
+ x="307"
+ y="419" />
+ <rect
+ style="opacity:0.5;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40620"
+ width="1.5"
+ height="1"
+ x="311"
+ y="414" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 309.5,411.5 -3,3"
+ style="fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40622"
+ inkscape:transform-center-y="-0.75"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-1.0204512"
+ inkscape:transform-center-x="1.4653436"
+ id="path40624"
+ d="m 306.85514,408.97535 c -3.25557,0.003 -5.8936,2.6597 -5.87155,5.95078 0.0105,1.56055 0.63214,2.99542 1.61111,4.05762 2.7831,-7.37691 5.95805,-1.77373 7.49116,-9.06794 -0.92886,-0.60835 -2.04538,-0.9415 -3.23072,-0.94046 l 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient42525);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="415"
+ x="301.51614"
+ height="1"
+ width="1.4999696"
+ id="rect40626"
+ style="opacity:0.3;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="409.5"
+ x="306"
+ height="1.4999921"
+ width="1"
+ id="rect40628"
+ style="opacity:0.3;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:transform-center-y="-0.75"
+ id="path40630"
+ style="opacity:0.6;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 309.5,411.5 -3,3"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(9,297.99992)"
+ id="g40632"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g40634"
+ transform="translate(-1.5986633,-160.53013)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40636"
+ width="16"
+ height="16"
+ x="165.59866"
+ y="397.53015" />
+ <g
+ id="g40638"
+ transform="translate(2.6147745,150.03014)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect40640"
+ width="15.000031"
+ height="16"
+ x="162.99997"
+ y="247.5" />
+ <rect
+ ry="1.9578006"
+ rx="1.9578006"
+ y="250.00002"
+ x="164.48389"
+ height="13.000053"
+ width="11.999973"
+ id="rect40642"
+ style="fill:url(#linearGradient40788);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m 174.48389,251 1,1 0,9 -1,1 -8,0 -1,-1 0,-9 1,-1 8,0 z"
+ style="fill:none;stroke:url(#linearGradient40790);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path40644"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccc"
+ transform="translate(-0.0161112,10.500011)"
+ id="path40646"
+ d="m 165.25,238.25 1,-1 0.5,0 0.75,0.75 0.75,-0.75 0.5,0 0.75,0.75 0.75,-0.75 0.5,0 0.75,0.75 0.75,-0.75 0.5,0 0.75,0.83779 0.75,-0.83779 0.5,0 1,1 0,2.75 -0.75,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.5,-1 -0.5,1 -1,0 -0.75,-1 0,-2.75 z"
+ style="fill:url(#linearGradient40792);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 166.48389,249.00001 0,2 m 2,-2 0,2 m 2,-2 0,2 m 2,-2 0,2 m 2,-2 0,2"
+ style="fill:none;stroke:url(#linearGradient40794);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path40648"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="248"
+ x="168"
+ height="1"
+ width="7"
+ id="rect40650"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40652"
+ width="7"
+ height="1"
+ x="168"
+ y="246" />
+ <rect
+ y="244"
+ x="168"
+ height="1"
+ width="7"
+ id="rect40654"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40656"
+ width="1"
+ height="1"
+ x="174"
+ y="250" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40518"
+ transform="translate(18.999997,-40.99992)">
+ <g
+ style="display:inline"
+ transform="translate(60.98406,570.00002)"
+ id="g40521">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(0.01612278,22)"
+ id="g40523"
+ style="display:inline">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path40525"
+ d="m 296.49991,-1.4999999 -13.00008,0 0,-12.9999991 13.00008,0 0,12.9999991 0,0 0,0 0,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40545);stroke-width:1.00000036px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 284.50009,-2.5000021 0,-11.0000069 11.00001,0 -2.7e-4,11.000009 -10.99974,-2.1e-6 z"
+ id="path40527"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#9dac93;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 345,578 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z m 0,2 0,1 12,0 0,-1 -12,0 z"
+ id="path40529"
+ transform="translate(-61.000183,-592.00002)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient40547);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 295.99982,-1.9999789 -11.9999,0 0,-12.0000411 11.9999,0 0,12.0000411 0,0 0,0 0,0 z"
+ id="path40531"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="580"
+ x="347"
+ height="1"
+ width="0.99999863"
+ id="rect40533"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40535"
+ width="0.99999863"
+ height="1"
+ x="348"
+ y="581" />
+ <rect
+ y="582"
+ x="349"
+ height="1"
+ width="0.99999863"
+ id="rect40537"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40539"
+ width="0.99999863"
+ height="1"
+ x="348"
+ y="583" />
+ <rect
+ y="584"
+ x="347"
+ height="1"
+ width="0.99999863"
+ id="rect40541"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40543"
+ width="3"
+ height="1"
+ x="350"
+ y="584" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g24081"
+ transform="translate(405,-17.000053)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\x.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ transform="scale(1,-1)"
+ y="-652.00006"
+ x="104"
+ height="16"
+ width="16"
+ id="rect23916"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g24071">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23922"
+ d="m 118.5,637.6177 -1.25,-1.1177 -10.5,0 -1.25,1.25 0.0161,12.75006 0.9839,0.99994 11,0 1.01611,-0.99994 L 118.5,637.6177 z"
+ style="fill:url(#linearGradient26077);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 117,638 -10,0 0,1 10,0 0,-1 z"
+ id="path23926"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient26079);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 117.5,650.25006 -0.25,0.25 -10.5,0 -0.25,-0.25 0,-12.5 0.25,-0.25 10.5,0 0.25,0.25 0,12.5 z"
+ id="path23928"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23930"
+ width="1"
+ height="1.0000043"
+ x="115"
+ y="-639"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="scale(1,-1)" />
+ <path
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 108,641 0,4 4,0 0,-4 -4,0 z m 4,4 0,4 4,0 0,-4 -4,0 z"
+ id="rect23964"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24035"
+ d="m 108,649 0,-4 4,0 0,4 -4,0 z m 4,-4 0,-4 4,0 0,4 -4,0 z"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-648.5"
+ x="-115.5"
+ height="7"
+ width="7"
+ id="rect23986"
+ style="opacity:0.55;fill:none;stroke:url(#linearGradient26081);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,-1)" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient26083);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23971"
+ width="7"
+ height="7"
+ x="108.5"
+ y="641.5" />
+ </g>
+ </g>
+ <rect
+ y="534.99994"
+ x="131"
+ height="16"
+ width="16"
+ id="rect23324"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g23326"
+ transform="translate(426,-17.000053)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\x.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ transform="scale(1,-1)"
+ y="-652.00006"
+ x="104"
+ height="16"
+ width="16"
+ id="rect23328"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23330">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path23333"
+ d="m 118.5,637.6177 -1.25,-1.1177 -10.5,0 -1.25,1.25 0.0161,12.75006 0.9839,0.99994 11,0 1.01611,-0.99994 L 118.5,637.6177 z"
+ style="fill:url(#linearGradient23351);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 117,638 -10,0 0,1 10,0 0,-1 z"
+ id="path23335"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient23353);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 117.5,650.25006 -0.25,0.25 -10.5,0 -0.25,-0.25 0,-12.5 0.25,-0.25 10.5,0 0.25,0.25 0,12.5 z"
+ id="path23337"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23339"
+ width="1"
+ height="1.0000043"
+ x="115"
+ y="-639"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="scale(1,-1)" />
+ <path
+ style="fill:#b41500;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 108,641 0,4 4,0 0,-4 -4,0 z m 4,4 0,4 4,0 0,-4 -4,0 z"
+ id="path23341"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path23345"
+ d="m 108,649 0,-4 4,0 0,4 -4,0 z m 4,-4 0,-4 4,0 0,4 -4,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35476059;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-648.5"
+ x="-115.5"
+ height="7"
+ width="7"
+ id="rect23347"
+ style="opacity:0.45;fill:none;stroke:url(#linearGradient23355);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,-1)" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient23357);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23349"
+ width="7"
+ height="7"
+ x="108.5"
+ y="641.5" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ id="g42663"
+ transform="translate(-198,-247)"
+ style="display:inline;enable-background:new">
+ <rect
+ y="257"
+ x="203"
+ height="16"
+ width="16"
+ id="rect42665"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-39.983882,19.00809)"
+ id="g42667"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path42669"
+ d="m 244.51612,238.49191 -0.0161,3 7.98388,0 0.0161,-3 -7.98388,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 247.51612,241.49191 -0.0161,3 11,0 0.0161,-3 -11,0 z"
+ id="path42671"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 243.5,247.49191 -0.0161,3 12,0 0.0161,-3 -12,0 z"
+ id="path42673"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path42675"
+ d="m 250.48388,250.49191 -0.0161,3 7.01612,0 0.0161,-3 -7.01612,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path42677"
+ d="m 205.51612,259.5 c 0,-0.25 0,-1 0,-1 l 6,0"
+ style="fill:none;stroke:url(#linearGradient42685);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42687);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 208.51612,262.5 c 0,-0.25 0,-1 0,-1 l 9,0"
+ id="path42679"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path42681"
+ d="m 204.5,268.5 c 0,-0.25 0,-1 0,-1 l 10,0"
+ style="fill:none;stroke:url(#linearGradient42689);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path42683"
+ d="m 211.5,271.5 c 0,-0.25 0,-1 0,-1 l 5,0"
+ style="fill:none;stroke:url(#linearGradient42691);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g25594"
+ transform="translate(-306,-275)">
+ <g
+ style="display:inline"
+ transform="translate(363,59)"
+ id="g25596"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="0.80014729"
+ y="289"
+ x="389"
+ height="16"
+ width="16"
+ id="rect25598"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25600"
+ transform="translate(-177,71)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g25602"
+ transform="translate(480,287.5)">
+ <g
+ id="g25604"
+ transform="translate(-118.5,-200.5)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ id="g25606"
+ transform="translate(1,24)"
+ style="fill:#000000" />
+ </g>
+ </g>
+ <rect
+ rx="0"
+ y="348"
+ x="752"
+ height="16"
+ width="16"
+ id="rect25608"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path25610"
+ d="m 756.16666,348.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient25872);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path25612"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,817.54887,13.43979)"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask23591)"
+ transform="translate(725,-419)"
+ id="g25614"
+ style="display:inline">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25616"
+ width="9"
+ height="13.999984"
+ x="31"
+ y="768" />
+ <g
+ id="g25618">
+ <rect
+ y="771"
+ x="32"
+ height="1"
+ width="1"
+ id="rect25620"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25622"
+ width="1"
+ height="1"
+ x="32"
+ y="773" />
+ <rect
+ y="775"
+ x="32"
+ height="1"
+ width="1"
+ id="rect25624"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25626"
+ width="1"
+ height="1"
+ x="32"
+ y="777" />
+ <rect
+ y="779"
+ x="32"
+ height="1"
+ width="1"
+ id="rect25628"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25630"
+ width="1"
+ height="1"
+ x="32"
+ y="781" />
+ <rect
+ y="771"
+ x="34"
+ height="3"
+ width="3"
+ id="rect25632"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25634"
+ width="3"
+ height="3"
+ x="34"
+ y="775" />
+ <rect
+ y="779"
+ x="34"
+ height="3"
+ width="3"
+ id="rect25636"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25638"
+ width="1"
+ height="1"
+ x="38"
+ y="771" />
+ <rect
+ y="773"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25640"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25642"
+ width="1"
+ height="1"
+ x="38"
+ y="775" />
+ <rect
+ y="777"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25644"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25646"
+ width="1"
+ height="1"
+ x="38"
+ y="779" />
+ <rect
+ y="781"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25648"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25650"
+ width="1"
+ height="1"
+ x="32"
+ y="769.02289" />
+ <rect
+ y="769.02289"
+ x="38"
+ height="1"
+ width="1"
+ id="rect25652"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25654"
+ width="3"
+ height="2"
+ x="34"
+ y="768" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 754.5,353 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient25874);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25656"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753,352 4,0 0,-4 -4,4 z"
+ id="path25658"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 753.5,351.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path25660"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25988"
+ transform="translate(-152,-151)">
+ <g
+ transform="translate(-272,34)"
+ id="g25437"
+ style="display:inline;enable-background:new">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ id="g25439"
+ transform="translate(523,-99)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25442"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g25444">
+ <g
+ transform="translate(480,287.5)"
+ id="g25446"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(-118.5,-200.5)"
+ id="g25448" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g25450" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25452"
+ width="16"
+ height="16"
+ x="912"
+ y="190"
+ rx="0" />
+ <g
+ id="g25454">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path25456"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient26011);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter22979)"
+ id="path25458"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient26013);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25460"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ id="path25462"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 913.5,193.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path25464"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25582"
+ d="m 650,228 1,0 -10e-6,6.5 -1,0 L 650,228 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 654,227 0,2 -4,0 10e-6,-2 3.99999,0 z"
+ id="path25584"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.8571421,0,0,0.8,601.28577,-208.6)"
+ id="g25586"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:type="arc"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25588"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)" />
+ <path
+ clip-path="url(#clipPath20586)"
+ inkscape:transform-center-y="0.3813435"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path25590"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25592"
+ d="m 654,227 0,1 -4,0 10e-6,-1 3.99999,0 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25662"
+ d="m 645.5,226.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient26015);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25963"
+ transform="translate(-86,-139)">
+ <g
+ transform="translate(-262,-147)"
+ id="g25359"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(-34,169)"
+ id="g25361">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ id="g25363"
+ transform="translate(523,-99)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25365"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g25367">
+ <g
+ transform="translate(480,287.5)"
+ id="g25369"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(-118.5,-200.5)"
+ id="g25372" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g25374" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25376"
+ width="16"
+ height="16"
+ x="912"
+ y="190"
+ rx="0" />
+ <g
+ id="g25378">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path25380"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient25982);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter22999)"
+ id="path25382"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient25984);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25384"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ id="path25387"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 913.5,193.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path25389"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ d="m 889.5,372.5 1,0 m 0,-4 -8,0 m 5,2 -5,0 m 1.25,-8 6.75,0 m 0,4 -8,0 m 8,-2 -8,0"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25391"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient25986);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 621.5,214.5 0,2 -2,0"
+ id="path25668"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25933"
+ transform="translate(-107,-115)">
+ <g
+ id="g25393"
+ transform="translate(-296,-2.000004)"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ transform="translate(523,-99)"
+ id="g25396"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="0.80014729"
+ y="289"
+ x="389"
+ height="16"
+ width="16"
+ id="rect25398"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25400"
+ transform="translate(-177,71)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g25402"
+ transform="translate(480,287.5)">
+ <g
+ id="g25404"
+ transform="translate(-118.5,-200.5)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ id="g25406"
+ transform="translate(1,24)"
+ style="fill:#000000" />
+ </g>
+ </g>
+ <rect
+ rx="0"
+ y="190"
+ x="912"
+ height="16"
+ width="16"
+ id="rect25408"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25410">
+ <path
+ style="fill:url(#linearGradient25957);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path25413"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(15.27209,-110)"
+ style="fill:#0044aa;display:inline"
+ id="g25415">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25417"
+ d="m 902.72791,305 2,0.90909 0,9.09091 -2,0 0,-10 z"
+ style="fill:#214478"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25419"
+ d="m 901.72791,305 1,0 0.25,0.5 -1.25,0 0,-0.5 z"
+ style="fill:#214478"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path25421"
+ d="m 902.72791,305 6.75,0 0,1 -5.09127,0 -1.65873,-1 z"
+ style="fill:#214478"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="310"
+ x="904.72791"
+ height="1"
+ width="2.7499952"
+ id="rect25423"
+ style="fill:#214478" />
+ <rect
+ y="309.25"
+ x="907.22791"
+ height="2.5"
+ width="0.5"
+ id="rect25425"
+ style="fill:#214478" />
+ <rect
+ y="305"
+ x="909.22791"
+ height="2"
+ width="0.5"
+ id="rect25427"
+ style="fill:#214478" />
+ </g>
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ sodipodi:nodetypes="ccc"
+ id="path25429"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter23007)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25431"
+ style="fill:none;stroke:url(#linearGradient25959);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path25433"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path25435"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 913.5,193.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ id="path25670"
+ d="m 621.5,190.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient25961);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g25672"
+ transform="translate(-348,-155)">
+ <g
+ transform="translate(-126,60.000002)"
+ id="g25674">
+ <g
+ transform="translate(-34,-22.000002)"
+ id="g25676">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\common file transparent SMALL.png"
+ id="g25678"
+ transform="translate(523,-99)"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25680"
+ width="16"
+ height="16"
+ x="389"
+ y="289"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-177,71)"
+ id="g25682">
+ <g
+ transform="translate(480,287.5)"
+ id="g25684"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="translate(-118.5,-200.5)"
+ id="g25686" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(1,24)"
+ id="g25688" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25690"
+ width="16"
+ height="16"
+ x="912"
+ y="190"
+ rx="0" />
+ <g
+ id="g25692">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path25694"
+ d="m 916.16666,190.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient25886);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter23015)"
+ id="path25696"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,977.54887,-144.56021)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 914.5,195 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient25888);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path25698"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 913,194 4,0 0,-4 -4,4 z"
+ id="path25700"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 913.5,193.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path25702"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g25705"
+ transform="translate(910,-321.00012)"
+ mask="none"
+ clip-path="url(#clipPath22590)">
+ <rect
+ y="491.00012"
+ x="-29"
+ height="16"
+ width="16"
+ id="rect25707"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25709">
+ <g
+ id="g25711">
+ <path
+ id="path25713"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25715"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1.0000004"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
+ transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m -25.5,496.5 7.5,0 m -8.5,5.00012 3.5,-3.5"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25717"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient25890);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25719"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)" />
+ <path
+ id="path25721"
+ style="fill:none;stroke:url(#linearGradient25892);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.984366,-0.0226 M -26.5,501.50012 -21.5,496.5 m 5.996227,1.44466 L -20.25,493.5"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(3.25,0,0,3.25,-62.875,313.125)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path25723"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path25725"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(2,0,0,2,-46,385)" />
+ <path
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path25727"
+ style="fill:none;stroke:url(#linearGradient25894);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path25729"
+ style="fill:none;stroke:url(#linearGradient25897);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -6.734366,7.94478 3.280183,-3.10926 m -2,-2 6.25,0"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient25899);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,230.5 0,2 -2,0"
+ id="path25731"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g25822"
+ transform="translate(273,-334)">
+ <rect
+ y="407"
+ x="89"
+ height="16"
+ width="16"
+ id="rect25824"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g25826">
+ <path
+ style="fill:url(#linearGradient25927);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,408.5 0,11.49245 1.5,1.5 10.5,0.008 0,-11.99245 -8,-0.008 0,-1 -4,0 z"
+ id="path25828"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g25830"
+ style="display:inline" />
+ <path
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25929);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 92.5,413.74245 12,0.008 0,6.25 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.75755 0,-9e-4 z"
+ id="path25832"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-10.02344 2,0 0,1 L 100.5,410.5"
+ id="path25834"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 93,420.5 9.5,0"
+ id="path25836"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25838"
+ d="m 103.5,414.75 -10,-0.008 0,4.75755 -1.5,1.5 -1.5,-1.5"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient25931);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 93,409 0,2 -3,0 0,-2 3,0 z"
+ id="path25840"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path25842"
+ d="m 89.5,408.5 0,11.49245 1.5,1.5 12,0.008 1.5,-1.49245 0,-6.50755 -3,-0.008 0,-3.9849 -8,-0.008 0,-1 -4,0 0,4.5e-4 0,0 0,0 z"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(371,90.000008)"
+ id="g26093">
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26095"
+ width="16"
+ height="16"
+ x="117"
+ y="529" />
+ <g
+ style="display:inline"
+ id="g26097"
+ transform="translate(28.71596,210.64282)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="2.0305908"
+ ry="2.0305908"
+ y="326.84842"
+ x="88.784042"
+ height="6.0000124"
+ width="14"
+ id="rect26099"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ style="fill:none;stroke:url(#linearGradient26126);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect26101"
+ width="12"
+ height="4.00875"
+ x="89.784042"
+ y="327.84842"
+ ry="1.029202"
+ rx="1.029202" />
+ <rect
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect26103"
+ width="14"
+ height="4.9999971"
+ x="88.784042"
+ y="319.85718"
+ ry="2.0154257"
+ rx="2.0154257"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient26128);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect26105"
+ width="12.000008"
+ height="2.9999971"
+ x="89.784042"
+ y="320.85718"
+ ry="0.97821051"
+ rx="0.97821051" />
+ <rect
+ ry="0"
+ rx="0"
+ y="320.35718"
+ x="89.284042"
+ height="3.9999919"
+ width="8"
+ id="rect26107"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="0.97821051"
+ ry="0.97821051"
+ y="320.85718"
+ x="89.784042"
+ height="2.9999971"
+ width="12.000008"
+ id="rect26109"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient26130);stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ ry="0"
+ rx="0"
+ y="320.85718"
+ x="96.284042"
+ height="3.0000272"
+ width="0.99999988"
+ id="rect26111"
+ style="opacity:0.6;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g26113"
+ transform="matrix(-1,0,0,1,193.28404,-130.61032)"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <g
+ id="g26115">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26117"
+ width="1"
+ height="1"
+ x="91"
+ y="459.9675"
+ rx="0"
+ ry="0"
+ transform="matrix(-1,0,0,1,194,-1.1e-6)" />
+ <rect
+ ry="0"
+ rx="0"
+ y="458.9675"
+ x="92"
+ height="3"
+ width="1"
+ id="rect26119"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(-1,0,0,1,194,-1.1e-6)" />
+ <rect
+ ry="0"
+ rx="0"
+ y="459.9675"
+ x="92"
+ height="1"
+ width="1"
+ id="rect26121"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26123"
+ width="1"
+ height="3"
+ x="93"
+ y="458.9675"
+ rx="0"
+ ry="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g28119"
+ transform="translate(0,127.99999)">
+ <rect
+ y="302"
+ x="404"
+ height="16"
+ width="16.000004"
+ id="rect27916"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <g
+ id="g28110">
+ <path
+ id="path27918"
+ d="m 412,306.45213 c -3.54545,0 -5.90909,1.5 -6.49999,3.04787 0.5909,1.45213 2.95581,3.77094 6.49999,3.75 3.54709,-0.021 5.9091,-2.29787 6.50001,-3.75 -0.59091,-1.54787 -2.95455,-3.04787 -6.50001,-3.04787 z"
+ style="fill:url(#linearGradient28107);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccscz"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 434.99991,14.5 a 3.9999149,2.91429 0 1 1 -7.99982,0 3.9999149,2.91429 0 1 1 7.99982,0 z"
+ sodipodi:ry="2.91429"
+ sodipodi:rx="3.9999149"
+ sodipodi:cy="14.5"
+ sodipodi:cx="431"
+ id="path27920"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.7500463,0,0,1.0294111,88.73017,294.07354)" />
+ <path
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path27922"
+ style="fill:url(#linearGradient28099);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(2.249956,0,0,2.251405,267.75278,4.81032)" />
+ <path
+ sodipodi:nodetypes="ccscs"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 412,306.5 c -3.5,0 -5,1.5 -6.5,3 1.5,1.5 2.75,4 6.5,4 3.75,0 5,-2.5 6.5,-4 -1.5,-1.5 -3,-3 -6.5,-3 z"
+ id="path27924"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="307.91428"
+ x="411"
+ height="2"
+ width="2"
+ id="rect27926"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path27928"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="translate(347,172.91429)" />
+ </g>
+ </g>
+ <g
+ id="g27932"
+ transform="translate(4e-6,127.99999)">
+ <g
+ transform="translate(0.4838899,-6.2084382e-8)"
+ id="g27934">
+ <path
+ sodipodi:nodetypes="ccscz"
+ style="opacity:0.25;fill:url(#radialGradient27973);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 432.51611,305.45213 c -3,0 -7,2.04787 -5.5,4.04787 0.5,1.45213 2.49969,3.02073 5.49861,2.99979 3.00139,-0.021 4.82513,-1.62106 5.50139,-2.99995 2,-2.49984 -2.5,-4.04771 -5.5,-4.04771 z"
+ id="path27936"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path27938"
+ d="m 432.51611,305.45213 c -3,0 -7.75,2.04787 -6.25,4.04787 0.5,1.45213 3.25108,3.52094 6.25,3.5 3.00139,-0.021 5.82374,-2.12111 6.5,-3.5 2,-2.49984 -3.5,-4.04787 -6.5,-4.04787 z"
+ style="opacity:0.18000004;fill:url(#radialGradient27975);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccscz"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:none;stroke:url(#linearGradient27977);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 438.51611,309.5 c -2,4 -10,4 -12,0"
+ id="path27940"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27942"
+ d="m 426.01611,309.5 c 2,5 11,5 13,0"
+ style="opacity:0.3;fill:none;stroke:#000000;stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:0.25;fill:none;stroke:none"
+ id="rect27944"
+ width="15.983887"
+ height="16"
+ x="425.01611"
+ y="302" />
+ </g>
+ <g
+ id="g27416"
+ transform="translate(105,-82)">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect27418"
+ width="16.000004"
+ height="16"
+ x="404"
+ y="302" />
+ <g
+ id="g27420">
+ <path
+ sodipodi:nodetypes="ccscz"
+ style="fill:url(#linearGradient27448);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 412,306.45213 c -3.54545,0 -5.90909,1.5 -6.49999,3.04787 0.5909,1.45213 2.95581,3.77094 6.49999,3.75 3.54709,-0.021 5.9091,-2.29787 6.50001,-3.75 -0.59091,-1.54787 -2.95455,-3.04787 -6.50001,-3.04787 z"
+ id="path27422"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.7500463,0,0,1.0294111,88.73017,294.07354)"
+ sodipodi:type="arc"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path27424"
+ sodipodi:cx="431"
+ sodipodi:cy="14.5"
+ sodipodi:rx="3.9999149"
+ sodipodi:ry="2.91429"
+ d="m 434.99991,14.5 a 3.9999149,2.91429 0 1 1 -7.99982,0 3.9999149,2.91429 0 1 1 7.99982,0 z" />
+ <path
+ transform="matrix(2.249956,0,0,2.251405,267.75278,4.81032)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient27450);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path27426"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
+ <path
+ id="path27428"
+ d="m 412,306.5 c -3.5,0 -5,1.5 -6.5,3 1.5,1.5 2.75,4 6.5,4 3.75,0 5,-2.5 6.5,-4 -1.5,-1.5 -3,-3 -6.5,-3 z"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccscs"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect27430"
+ width="2"
+ height="2"
+ x="411"
+ y="307.91428" />
+ <path
+ transform="translate(347,172.91429)"
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path27432"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
+ </g>
+ </g>
+ <g
+ transform="translate(62.983887,-82)"
+ id="g27434">
+ <g
+ id="g27436"
+ transform="translate(0.4838899,-6.2084382e-8)">
+ <path
+ id="path27438"
+ d="m 432.51611,305.45213 c -3,0 -7,2.04787 -5.5,4.04787 0.5,1.45213 2.49969,3.02073 5.49861,2.99979 3.00139,-0.021 4.82513,-1.62106 5.50139,-2.99995 2,-2.49984 -2.5,-4.04771 -5.5,-4.04771 z"
+ style="opacity:0.25;fill:url(#radialGradient27452);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccscz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscz"
+ style="opacity:0.18000004;fill:url(#radialGradient27454);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 432.51611,305.45213 c -3,0 -7.75,2.04787 -6.25,4.04787 0.5,1.45213 3.25108,3.52094 6.25,3.5 3.00139,-0.021 5.82374,-2.12111 6.5,-3.5 2,-2.49984 -3.5,-4.04787 -6.5,-4.04787 z"
+ id="path27440"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27442"
+ d="m 438.51611,309.5 c -2,4 -10,4 -12,0"
+ style="opacity:0.25;fill:none;stroke:url(#linearGradient27456);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#000000;stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 426.01611,309.5 c 2,5 11,5 13,0"
+ id="path27444"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="302"
+ x="425.01611"
+ height="16"
+ width="15.983887"
+ id="rect27446"
+ style="opacity:0.25;fill:none;stroke:none" />
+ </g>
+ <g
+ transform="translate(147,170.00001)"
+ id="g27500">
+ <rect
+ style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27514"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g27516">
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path27518"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ id="path27520"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path27522"
+ d="m 33,338 2,0 0,1 -2,-10e-6 L 33,338 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect27524"
+ style="fill:#24221c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#736c54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27527"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path27529"
+ d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 0.48959,-2e-6 2.86976,-0.0067 3.35937,-0.0067 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 L 249.25,80 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 3.35937,-0.0067 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 C 252.11976,81.993327 249.7396,82 249.25,82 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z"
+ style="fill:url(#linearGradient27598);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 32.25,336.24999 1.25,0"
+ id="path27531"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path27533"
+ d="m 32.25,334.24999 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27535"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="37"
+ height="1"
+ width="0.25"
+ id="rect27537"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="336"
+ x="30.75"
+ height="1"
+ width="0.25"
+ id="rect27539"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27541"
+ width="0.25"
+ height="1"
+ x="30.75"
+ y="334" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.5"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ style="fill:url(#linearGradient27600);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path27543"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ transform="matrix(1.1428575,0,0,1.1249998,-252.2858,245.25001)" />
+ <path
+ transform="matrix(1.1428578,0,0,1.1562502,-252.28587,242.81248)"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ id="path27545"
+ style="opacity:0.6;fill:url(#radialGradient27602);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ inkscape:radius="0.5"
+ sodipodi:type="inkscape:offset" />
+ <path
+ id="path27547"
+ style="fill:none;stroke:url(#linearGradient27604);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient27606);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path27549"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
+ <path
+ transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)"
+ sodipodi:type="arc"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path27551"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ style="fill:none;stroke:url(#radialGradient27608);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path27554"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.85;fill:#3d3829;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27557"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 32.5,337.01145 3,-0.0115 0,1 -3,0.0114 0,-0.99999 0,9e-5 0,0 0,0 z"
+ id="path27564"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:url(#linearGradient27610);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 33,330 0,2.75 2,0 0,-2.75 -2,0 z"
+ id="path27566"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27585"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path27587"
+ style="fill:none;stroke:url(#radialGradient27612);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 32.875,333.12498 c 0,-1.39113 -0.517691,-2.25114 -1.113536,-2.77529 C 31.064459,329.73656 30.5,328.93567 30.5,327.93988 c 0,-1.84706 1.637,-3.43989 3.5,-3.43989 1.863,0 3.5,1.59283 3.5,3.43989 0,0.99579 -0.564459,1.79668 -1.261464,2.40981 -0.595845,0.52415 -1.113536,1.38416 -1.113536,2.77529"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 33,338.00001 0.5,0 0,1 L 33,339 l 0,-0.99999 z"
+ id="path27590"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27594"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect27596"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 263,16 0,3 1,0 0,-2 2,0 0,-1 -3,0 z"
+ id="rect28902"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g28080"
+ transform="translate(-823,-175)">
+ <rect
+ y="416"
+ x="870"
+ height="16"
+ width="16"
+ id="rect28083"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1.2930992,0,0,1.3011246,677.85367,159.07065)"
+ style="opacity:0.96000001;display:inline"
+ id="g28085">
+ <path
+ transform="matrix(1.1162596,0,0,1.1065394,67.801614,-350.49863)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path28087"
+ style="opacity:0.25;fill:url(#radialGradient28099);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient28101);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path28089"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-1.3568764,-0.3150232,0.3151738,-1.348049,102.81491,906.57916)" />
+ </g>
+ <path
+ style="fill:url(#linearGradient28103);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 883.5,426.5 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-3.5 2.5,-4.5 5,-10 2.5,5.5 5,6.5 5,10 z"
+ id="path28091"
+ sodipodi:nodetypes="csscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csscssc"
+ id="path28093"
+ d="m 878.5,418.40909 c 0.4375,0.96023 0.90625,1.78977 1.36328,2.53255 0.45703,0.74278 0.90234,1.3988 1.29297,2.01196 0.78125,1.22633 1.34375,2.28125 1.34375,3.5161 0,2.22473 -1.792,4.0303 -4,4.0303 -2.208,0 -4,-1.80557 -4,-4.0303 0,-2.41818 2.25,-4.2197 4,-8.06061 z"
+ style="fill:none;stroke:url(#linearGradient28105);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path28095"
+ sodipodi:cx="878.5"
+ sodipodi:cy="425"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1"
+ d="m 880,425 a 1.5,1 0 1 1 -3,0 1.5,1 0 1 1 3,0 z"
+ transform="matrix(0.6434675,-0.7329672,0.7942866,0.5945179,-26.858149,815.24158)" />
+ <path
+ inkscape:transform-center-y="-7.1785015"
+ inkscape:transform-center-x="-7.136318"
+ sodipodi:type="arc"
+ style="opacity:0.4;fill:url(#radialGradient28107);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69954133;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path28097"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.2857095,0,0,1.2857143,1210.8559,325.57143)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(-94.999994,403.00001)"
+ id="g30296"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect30298"
+ width="16"
+ height="16"
+ x="163"
+ y="195" />
+ <g
+ id="g30300">
+ <g
+ transform="translate(0.01612278,0)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g30302"
+ style="display:inline">
+ <g
+ style="fill:#ff943d;fill-opacity:1;stroke:none"
+ id="g30304">
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30306"
+ width="1"
+ height="2"
+ x="-199"
+ y="168.98387" />
+ <rect
+ y="207.98763"
+ x="174.98387"
+ height="2"
+ width="1"
+ id="rect30309"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="164.98387"
+ x="-199"
+ height="2"
+ width="1"
+ id="rect30311"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30313"
+ width="1"
+ height="2"
+ x="174.98387"
+ y="203.98763" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30315"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="207" />
+ <rect
+ y="203"
+ x="162.98387"
+ height="2"
+ width="1"
+ id="rect30318"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="167.97594"
+ x="-211"
+ height="2"
+ width="1"
+ id="rect30326"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30328"
+ width="1"
+ height="2"
+ x="-211"
+ y="171.97594" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30330"
+ width="1"
+ height="2"
+ x="-211"
+ y="163.98387" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30332"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="199" />
+ </g>
+ <g
+ style="fill:#532500;fill-opacity:1"
+ id="g30334">
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30336"
+ width="1"
+ height="2"
+ x="-199"
+ y="166.98387" />
+ <rect
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30338"
+ width="1"
+ height="2"
+ x="174.98387"
+ y="205.98763" />
+ <rect
+ y="205"
+ x="162.98387"
+ height="2"
+ width="1"
+ id="rect30340"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30342"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="209" />
+ <rect
+ y="165.97594"
+ x="-211"
+ height="2"
+ width="1"
+ id="rect30344"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30346"
+ width="1"
+ height="2"
+ x="-211"
+ y="169.97594" />
+ <rect
+ y="173.97594"
+ x="-211"
+ height="2"
+ width="1"
+ id="rect30348"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <rect
+ y="202"
+ x="174.98387"
+ height="2"
+ width="1"
+ id="rect30350"
+ style="fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect30353"
+ width="1"
+ height="2"
+ x="162.98387"
+ y="201" />
+ <rect
+ y="162.98387"
+ x="-199"
+ height="2"
+ width="1"
+ id="rect30355"
+ style="fill:#552c00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,1,0,0,0)" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path30357"
+ d="m 163.99999,199 6.51562,0 1.23438,3.25 3.25,1.20312 0,6.54688 -11,0 0,-11 z"
+ style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.781818,0,0,0.781818,38.760709,42.85549)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g30359"
+ style="display:inline">
+ <path
+ inkscape:transform-center-y="-6.3853012"
+ inkscape:transform-center-x="-6.3473305"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.78698397;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path30361"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:none;stroke:#28170b;stroke-width:4.47674513;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ id="path30363"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path30365"
+ d="m 168.5,205.5 0.96309,-0.98372"
+ style="fill:none;stroke:#000000;stroke-width:2.5581398;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.40697706;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 168.5,205.5 1.28285,-1.30349"
+ id="path30367"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g30369"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.878699,0,0,0.877142,14.70687,20.74499)">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient30389);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient30391);stroke-width:1.16848361;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30371"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.2468441,0,0,1.246865,503.16273,106.89331)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path30373"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ style="fill:none;stroke:#a05a2c;stroke-width:2.55814004;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.2790699;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 164.02704,208.99303 3.83721,-3.83721"
+ id="path30375"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path30377"
+ style="opacity:0.5;fill:url(#radialGradient30393);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69954133;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ <g
+ id="g30379"
+ style="opacity:0.96000001;display:inline"
+ transform="matrix(0.9729196,0,0,0.9789579,9.7047721,-0.8010785)">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient30395);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path30381"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)" />
+ <path
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path30383"
+ style="opacity:0.25;fill:url(#radialGradient30397);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path30385"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(1.2790738,0,0,1.2790735,89.840744,25.765779)" />
+ </g>
+ <path
+ id="path30387"
+ d="m 163.99999,199 0,11 1,0 0,-10 6,0 0,-1 -7,0 z"
+ style="opacity:0.12999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g28857">
+ <rect
+ y="241.00877"
+ x="68.001282"
+ height="16"
+ width="16"
+ id="rect27661"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.9168751,0,0,0.9161255,-39.818417,44.251476)"
+ id="g27663"
+ style="display:inline"
+ clip-path="url(#clipPath42711)">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient42435);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path27665"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none"
+ mask="none" />
+ <path
+ transform="matrix(0.6147126,0,0,0.6147118,47.3579,150.96368)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42437);stroke-width:1.77499008;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path27667"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(-167.99872,-18.991228)"
+ style="opacity:0.55"
+ id="g27669">
+ <path
+ style="fill:url(#linearGradient42432);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 243.50439,274.05251 -6.46154,-3.3e-4 0,-12.12435 6.46154,3.3e-4"
+ id="path27671"
+ sodipodi:nodetypes="cccc"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path27673"
+ d="m 243.50439,272.9503 -5.38461,-3.3e-4 0.001,-4.9503 -0.001,-4.96963 5.38461,3.3e-4"
+ style="fill:none;stroke:#ffffff;stroke-width:1.08949494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-167.74474,113.52244)"
+ style="display:inline;enable-background:new"
+ id="g27675">
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.49999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 73.54505,272.57627 1.06066,-2.47487"
+ id="path33728"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27679"
+ d="m 73.545051,272.22272 7.071067,-7.07107"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path33730"
+ d="m 78.494797,266.21231 2.651651,-0.88388"
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.49999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path42388"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42359"
+ style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g56105">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29107"
+ width="16"
+ height="16"
+ x="530"
+ y="52" />
+ <g
+ id="g56091">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path29110"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,2.75 -5.99999,3.24999 L 531,60.75 531,58 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#9e9e9e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,0.5 -6,3 L 531,58.56558 531,58 z"
+ id="path29112" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path29114"
+ d="M 531.00001,60.75 531,58.5 l 7.99996,3.99998 0.01,2.49885 -8.00991,-4.24883 -4e-5,0 z"
+ style="fill:#848484;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#383838;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544.99996,61.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path29116"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient56084);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58.5 0,2 7.49996,3.99998 5.5,-3 0,-2"
+ id="path29118"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58 7.49996,3.74998"
+ id="path29120"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29129);stroke-width:1.08012342;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path29122"
+ sodipodi:cx="749"
+ sodipodi:cy="420.25"
+ sodipodi:rx="2.5"
+ sodipodi:ry="1.75"
+ d="m 751.5,420.25 a 2.5,1.75 0 1 1 -5,0 2.5,1.75 0 1 1 5,0 z"
+ transform="matrix(1,0,0,0.8571429,-212,-302.2143)" />
+ <rect
+ style="fill:#66ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29125"
+ width="1"
+ height="1"
+ x="544"
+ y="61" />
+ </g>
+ </g>
+ <g
+ transform="translate(-0.1658249,128.41502)"
+ id="g27744">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27746"
+ width="16"
+ height="16"
+ x="47.165825"
+ y="364.58499" />
+ <g
+ id="g27748"
+ transform="matrix(1.032664,0,0,1.043556,-79.760429,254.38542)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:type="arc"
+ style="fill:#4169a5;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.22966909;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path27750"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)" />
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path27752"
+ style="fill:url(#linearGradient27767);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.666432,0,0,0.659342,42.69924,35.46375)" />
+ <path
+ transform="matrix(0.3631382,0,0,0.3593485,81.755824,69.904768)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#linearGradient27769);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path27755"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27757"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter13996)"
+ transform="matrix(0.9688184,0,0,0.9547322,-131.63668,47.640696)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccssscsscccscccccccccccccccsccccc"
+ id="path27761"
+ d="m 130.67404,112.3079 c 0.0244,0.78706 -0.15754,1.63085 0.59269,2.02213 0.71197,-0.0434 1.49133,0.64122 1.35667,1.40517 -0.26776,0.77861 0.14071,1.12325 0.95576,1.36401 0.57868,-0.0716 0.79053,-0.93546 0.87357,-1.36401 0.0948,-1.27121 0.51542,-1.09421 0.82108,-1.98991 -0.45733,-0.91502 -0.003,-1.04443 -0.72629,-1.43739 m -1.00945,-3.89288 c -0.4426,0.34378 -0.24372,1.04314 -0.66162,1.39841 -0.45372,0.13628 -0.78226,-0.0605 -1.16771,0.43164 -0.30841,1.10457 0.35004,1.22306 0.90205,1.10457 0.49538,-0.0502 0.61419,-0.94321 0.97928,-0.37853 0.0831,0.10976 0.71917,-0.0403 0.86266,0.18898 0.0669,0.10682 -0.11785,0.0255 -0.14729,0.18955 -0.0428,0.23847 0.27734,0.37341 0.372,0.3824 0.32089,0.0305 0.60005,0.92548 0.83846,1.05499 0,0.46738 0.0924,-0.6774 0.3515,-0.78703 0.22948,-0.0971 0.47929,0.10731 0.5,0 0.29928,-1.55081 -1.26113,-3.00604 -2.82933,-3.58498 z M 128.96474,107.5 c -0.6111,1.01384 0.85343,1.46103 1.73001,1.21329 0.57897,-0.37879 1.00716,-0.92331 0.55665,-1.21329 -0.20614,-0.1415 -2.07706,0.0431 -2.28666,0 l 0,0 0,0 0,0 z m -1.372,1.37253 c -0.49575,-0.14959 0.44952,-0.11945 0.45733,0.45751 0.1696,0.54756 -0.42801,0.23756 0,0.45752 0.70893,0.1644 0.35328,1.70031 -0.28114,1.56208 -0.56042,0.10119 -0.43915,0.95826 -1.64865,0.88279 -0.0836,0.0755 -1.04512,0.61593 -0.81421,1.21521 1.12968,0.30162 -0.36816,1.26478 -0.43867,0.55236 -0.15441,-0.49797 -0.62853,-1.11348 -0.43994,-1.68674 0.11734,-0.63627 0.5689,-1.12263 0.82646,-1.69865 0.36225,-0.61946 0.89084,-1.17688 1.57758,-1.42595 0.21411,-0.16799 0.46159,-0.41691 0.76124,-0.31613 l 0,0 0,0 0,0 z m -0.91467,5.03262 c -0.55163,-0.27585 -0.72934,0.28829 -0.60377,0.7984 0.15577,0.47138 0.52607,0.97695 0.72628,1.43739 0.40435,0.49619 1.512,1.34081 2.17883,1.67696 0.31768,0.16015 0.48418,0 0.24209,-0.23956 -0.31367,-0.6375 -1.14073,-1.94893 -0.48418,-2.15609 0.59647,-0.60342 0.34203,-1.58773 -0.48419,-1.43739 -0.54779,-0.25818 -0.75551,-0.39899 -1.38855,-0.0752 -0.0558,0.0743 -0.12403,0.006 -0.18651,-0.004 l 0,-5.1e-4 0,0 0,0 z"
+ style="fill:url(#linearGradient27771);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path27763"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient27773);stroke-width:1.45454657;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6657538,0,0,0.6588051,42.794535,35.527157)" />
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path27765"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.06052282,0,0,0.05989117,121.21686,103.80334)" />
+ </g>
+ </g>
+ <g
+ style="fill:none;stroke:#ffffff;stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(-323.1613,214)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g28643" />
+ <g
+ id="g29500" />
+ <g
+ transform="translate(1,24.000004)"
+ id="g29613"
+ style="opacity:0.3" />
+ <g
+ style="opacity:0.3"
+ id="g29692"
+ transform="translate(0,18)" />
+ <g
+ id="g34067"
+ transform="translate(0,2)">
+ <g
+ id="g31771"
+ transform="matrix(0,-1,1,0,249,491)">
+ <g
+ style="opacity:0.7;display:inline"
+ id="g31773"
+ transform="translate(257,86)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31775"
+ width="16"
+ height="16"
+ x="63"
+ y="48" />
+ </g>
+ <g
+ id="g31784"
+ transform="matrix(-1,0,0,1,656,0)">
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 323.5,137.5 0,9 3,0 3,0 3,0 0,-4 0,-5 -3,0 0,6 -3,0 0,-6 -3,0 z"
+ id="path31786"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31788"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 324.5,145.5 0,-7 1,0 m 6,0 -1,0 0,6 -4,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ transform="translate(0,21)"
+ style="opacity:0.8"
+ id="g31854">
+ <g
+ id="g31823">
+ <g
+ id="g31807">
+ <path
+ id="path31804"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 384.5,138.5 0,-3 3,0"
+ id="path31796"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,782,0)"
+ id="g31811">
+ <path
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 384.5,138.5 0,-3 3,0"
+ id="path31813"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31819"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g31831"
+ transform="matrix(1,0,0,-1,0,284)">
+ <g
+ id="g31833">
+ <path
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 384.5,138.5 0,-3 3,0"
+ id="path31842"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31845"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g31847"
+ transform="matrix(-1,0,0,1,782,0)">
+ <path
+ id="path31849"
+ d="m 384.5,138.5 0,-3 3,0"
+ style="fill:none;stroke:#00112b;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#b9d5ff;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 384.5,138.5 0,-3 3,0"
+ id="path31852"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ transform="matrix(-0.767131,0,0,0.788662,369.34347,270.08667)"
+ style="fill:#000000;fill-opacity:1"
+ id="g33443"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="matrix(-0.693332,0,0,0.663699,372.90657,295.34421)"
+ id="g33445"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g33447"
+ style="opacity:0.3"
+ transform="matrix(-1,0,0,1,762.99997,233.00003)" />
+ <g
+ id="g31977"
+ transform="translate(63,212.00001)">
+ <rect
+ ry="0"
+ rx="0"
+ y="281"
+ x="47"
+ height="16"
+ width="16"
+ id="rect31979"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g31981">
+ <g
+ transform="translate(-290.00001,409.99343)"
+ style="opacity:0.75;display:inline"
+ id="g31985">
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 341.00001,-115.99343 c 4.5365,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ id="path31987"
+ sodipodi:nodetypes="csc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path31994"
+ d="m 341.00001,-115.99343 c 4.49647,0 8.49999,-2.75 8.49999,-5.75 0,-1.75 -1.25,-4 -5.5,-4"
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-189.02763,408)"
+ id="g31998"
+ style="display:inline">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32000"
+ width="2.9998772"
+ height="3"
+ x="238.52776"
+ y="-115.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 241.02763,-115 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path32009"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-125.5"
+ x="241.52776"
+ height="3"
+ width="2.9998772"
+ id="rect32011"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32014"
+ d="m 244.02763,-125 c -0.65334,0 -1.30668,1e-5 -1.96003,1e-5 0,0.66667 0,1.33332 0,1.99999 0.65335,0 1.30669,-1e-5 1.96003,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g32016"
+ transform="translate(-474,676.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32018"
+ width="16"
+ height="16"
+ x="563"
+ y="-183" />
+ <g
+ id="g32020">
+ <g
+ style="opacity:0.75"
+ id="g32022"
+ transform="translate(476.04566,-283.51773)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path32025"
+ d="m 89.95451,104.01774 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.95451,103.98095 5,9.5 5,-9.5 -10,0 z"
+ id="path32028"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-181.49998"
+ x="574.50031"
+ height="3"
+ width="2.9998772"
+ id="rect32030"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32032"
+ width="2.9998772"
+ height="3"
+ x="564.50043"
+ y="-181.49998"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-171.5"
+ x="569.5"
+ height="3"
+ width="2.9998772"
+ id="rect32034"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 577.00046,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path32036"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32038"
+ d="m 572.00029,-170.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32040"
+ d="m 567.00059,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g32042"
+ transform="translate(83,212.00001)">
+ <rect
+ y="68"
+ x="281"
+ height="16"
+ width="16"
+ id="rect32044"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ id="g32046"
+ transform="matrix(0,-1,1,0,-254.00001,365.00041)">
+ <g
+ id="g32048"
+ style="opacity:0.7">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path32051"
+ style="fill:none;stroke:#1a1a1a;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m 69.5,325.5 0,10 12,0 0,-10 -12,0 z m 6,0 0,10 m 6,-5 -12,0"
+ style="fill:none;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32053"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32055"
+ width="2.9998772"
+ height="3"
+ x="80.500122"
+ y="323.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 83.00041,324.00001 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path32061"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="334.5"
+ x="80.49971"
+ height="3"
+ width="2.9998772"
+ id="rect32063"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32065"
+ d="m 83,335 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g25012"
+ transform="translate(-83.999998,191)">
+ <rect
+ transform="scale(-1,1)"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25014"
+ width="16.000032"
+ height="16"
+ x="-231.00003"
+ y="281" />
+ <g
+ transform="translate(235.00016,-1)"
+ id="g25016">
+ <g
+ id="g25018"
+ transform="translate(-376,510)"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path25020"
+ d="m 358.99997,-216.75 c -0.99997,-6.5 6.00003,-2.75 5,-9.25 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path25022"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.7;fill:url(#linearGradient25056);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path25024"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path25026"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="opacity:0.75;fill:url(#radialGradient25058);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path25028"
+ d="m 364.24984,-225.5 4.25016,1.75 c 1,5.75 -5.50003,2 -5.08381,8.85761 l -4.04561,-2.26888"
+ style="fill:none;stroke:url(#linearGradient25060);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 364.24997,-225.5 4.25003,1.75"
+ id="path25031"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-399.2499,383.75)"
+ id="g25033">
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25035"
+ width="2.9998772"
+ height="3"
+ x="391.75"
+ y="-99.25"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 394.24987,-98.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.66939 0,1.33877 0,2.00817 0.66668,0 1.33333,-10e-6 2,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path25039"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g25041"
+ transform="translate(-406.2499,380.75)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="-98.25"
+ x="392.74988"
+ height="3"
+ width="2.9998772"
+ id="rect25043"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25046"
+ d="m 395.24974,-97.75 c -0.66667,0 -1.33332,1e-5 -2,1e-5 0,0.666663 0,1.333317 0,1.99999 0.66668,0 1.33333,-1e-5 2,-1e-5 0,-0.666663 0,-1.333327 0,-1.99999 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -11.00003,286 c -0.66668,0 -1.33332,0 -2,0 0,-0.33334 0,-0.66666 0,-1 0.66668,0 1.33332,0 2,0 0,0.33334 0,0.66667 0,1 z"
+ id="path25048"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25050"
+ d="m -7.00003,285.53933 c -0.33334,0 -0.66666,10e-6 -1,10e-6 0,0.82281 0,1.64561 0,2.46844 0.33334,0 0.66666,-1e-5 1,-1e-5 0,-0.82282 0,-1.64562 0,-2.46844 l 0,0 0,0 0,0 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25052"
+ d="m -9.972188,286 c -0.342621,0 -0.685221,0 -1.027842,0 0,-0.66873 0,-1.33742 0,-2.00616 0.342621,0 0.685221,0 1.027842,0 0,0.66874 0,1.33745 0,2.00616 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -6.000162,287 c -0.33334,0 -0.66666,0 -1,0 0,0.33428 0,0.66856 0,1.00284 0.33334,0 0.66666,0 1,0 0,-0.33428 0,-0.66856 0,-1.00284 z"
+ id="path25054"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g32145"
+ transform="translate(147,191.00001)">
+ <g
+ transform="translate(-138,212)"
+ style="opacity:0.8;display:inline"
+ id="g32147">
+ <g
+ transform="translate(1.0551033e-6,0)"
+ id="g32149">
+ <g
+ style="display:inline"
+ transform="matrix(0.927273,0,0,1,85.654543,64)"
+ id="g32151"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\Browser icons ver 1\Outliner ICON CODES.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path32153"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.63466382;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.86925566;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z M 63.999982,17 64,19 l 2.156862,0 -1.8e-5,-2 -2.156862,0 0,0 0,0 0,0 z m 10.78431,0 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path32155"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.176776,0,0,1.176776,-12.47787,-2.548088)"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path32158"
+ style="fill:url(#radialGradient32241);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ d="M 70.499967,14.5 75.5,17.5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ececec;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path32161"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ style="opacity:0.8;fill:none;stroke:url(#radialGradient32243);stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path32165"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="cccccc"
+ transform="translate(-1.6176466e-5,0)"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ id="path32168"
+ d="m 74.784292,17 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path32172"
+ style="fill:none;stroke:#999999;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 65.5,17.5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32174"
+ style="fill:none;stroke:#cccccc;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 70.470586,14.5 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path32177"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 64,17 0,2 2.156844,0 0,-2 L 64,17 z"
+ id="path32179"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="13.25"
+ x="68.583321"
+ height="3.5"
+ width="3.774509"
+ id="rect32186"
+ style="opacity:0.05;fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path32193"
+ d="m 64.539197,18.5 0,-1 1.078431,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.03847623px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69.931347,8.5 0,-0.9673924 1.078413,0"
+ id="path32197"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path32199"
+ d="m 75.323509,18.500001 0,-1 1.078431,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="5"
+ x="61.843121"
+ height="16"
+ width="17.254898"
+ id="rect32201"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 155,80.5 -3,-1.870665"
+ id="path32206"
+ transform="matrix(1.0784311,0,0,1,-92.372519,-64)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.01000001;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 74.245078,17.500001 0,-1 1.078431,0"
+ id="path32208"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32215"
+ d="m 69.931352,9.5000005 1.078431,0"
+ style="opacity:0.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#666666;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path32218"
+ d="m 66.696014,17.499989 0,-1 -1.078431,0"
+ style="opacity:0.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#4c4c4c;stroke-width:1.03847575px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path32230"
+ d="m 147,80.5 3,-1.870665"
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 150.5,73.5 0,4"
+ id="path32235"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="78"
+ x="150.06403"
+ height="2"
+ width="2"
+ id="rect32237"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ rx="0"
+ ry="0"
+ y="289.5"
+ x="11.499837"
+ height="3"
+ width="2.9998772"
+ id="rect32239"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g52805"
+ transform="translate(185,94.000007)">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52807"
+ width="16"
+ height="16"
+ x="-75"
+ y="420" />
+ <g
+ transform="translate(-577.98389,452.95862)"
+ style="display:inline;enable-background:new"
+ id="g52809">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52811"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient53119);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ id="path52813"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52815"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient53121);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.38281,1.847656 2.36719,-2.347656 -1.5,-2 z"
+ id="path52817"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518.48389,-29.45862 -4,4.75 2,2.25 2,-2"
+ id="path52819"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52821"
+ d="m 518.98389,-29.70862 -4.75,5.5 1.75,1.75 3,-2.75 0,-4.5 z"
+ style="fill:url(#linearGradient53123);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 513.48389,-22.45862 5,-6"
+ id="path52823"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53125);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ id="path52825"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-185,34)"
+ id="g52827">
+ <rect
+ ry="0.019097222"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52829"
+ width="11"
+ height="11"
+ x="110"
+ y="386"
+ rx="0.019097222" />
+ <g
+ id="g52831">
+ <path
+ id="path52833"
+ d="m 116.53125,386.5 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.28156 0.12508,0.53133 0.3125,0.71875 L 113,392 c -0.18742,-0.18742 -0.46844,-0.5 -0.75,-0.5 l -0.75,0 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.56312 0.46813,1.03125 1.03125,1.03125 l 0.9375,0 c 0.0103,0 0.021,3e-4 0.0312,0 -3e-4,0.0102 0,0.021 0,0.0312 l 0,0.9375 c 0,0.56312 0.46813,1.03126 1.03125,1.03125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.28156 -0.10164,-0.53133 -0.28125,-0.71875 l 2.625,-2.625 c 0.18742,0.18742 0.43719,0.3125 0.71875,0.3125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.56312 -0.43688,-1.03125 -1,-1.03125 l -0.96875,0 c -0.0103,0 -0.021,-3e-4 -0.0312,0 3e-4,-0.0102 0,-0.021 0,-0.0312 l 0,-0.9375 c 0,-0.56312 -0.46813,-1.03125 -1.03125,-1.03125 l -0.9375,0 z"
+ style="fill:url(#linearGradient53127);fill-opacity:1;fill-rule:evenodd;stroke:#333333;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccsccccccccccccccscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52835"
+ d="m 111.5,393.5 0,-0.75 0.25,-0.25 1.75,0 3,-3 0,-1.75 0.25,-0.25 0.75,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 118.75,389.5 0.75,0 m -6,6 0,-0.75"
+ id="path52837"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52839"
+ width="1"
+ height="1"
+ x="114"
+ y="393" />
+ <rect
+ y="390"
+ x="117"
+ height="1"
+ width="1"
+ id="rect52841"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52845"
+ width="16"
+ height="16"
+ x="89"
+ y="514" />
+ <g
+ mask="url(#mask38474)"
+ transform="translate(-254.01612,339.00001)"
+ id="g52847">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect52849"
+ width="12.871031"
+ height="13.001007"
+ x="343.51614"
+ y="175.49899" />
+ <path
+ style="fill:url(#linearGradient53129);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344.01612,176 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m -3,3 -3,0 0,3 3,0 0,-3 z"
+ id="path52851"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path52853"
+ d="m 344.50621,187.50705 0,-11.00155 10.89034,0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient53131);stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-414.98389,546.98571)"
+ style="display:inline;enable-background:new"
+ id="g52855">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52857"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient53133);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ id="path52859"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52861"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient53135);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.37109,1.875 2.37891,-2.375 -1.5,-2 z"
+ id="path52863"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 519.48389,-30.45862 -5,5.75 2,2.25 3,-3"
+ id="path52865"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52867"
+ d="m 519.98389,-30.70862 -5.75,6.5 1.75,1.75 4,-3.75 0,-4.5 z"
+ style="fill:url(#linearGradient53137);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 513.48389,-22.45862 6,-7"
+ id="path52869"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53139);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ id="path52871"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g52873"
+ transform="translate(120,94.000007)">
+ <rect
+ y="420"
+ x="-52"
+ height="16"
+ width="16"
+ id="rect52875"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-556.98389,452.95862)"
+ style="display:inline;enable-background:new"
+ id="g52877">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52879"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient53141);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ id="path52881"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52883"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient53143);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.37109,1.875 2.37891,-2.375 -1.5,-2 z"
+ id="path52885"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 520.48389,-31.45862 -6,6.75 2,2.25 4,-4"
+ id="path52887"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52889"
+ d="m 520.98389,-31.95862 -6.75,7.75 1.75,1.75 5,-4.5 0,-5 z"
+ style="fill:url(#linearGradient53145);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 513.48389,-22.45862 7,-8.25"
+ id="path52891"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53147);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ id="path52893"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ mask="url(#mask57450)"
+ id="g52895"
+ style="display:inline"
+ transform="translate(-378.00003,264.99999)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path52897"
+ d="m 328.50261,168.45815 0.0576,-10.96002 10.94282,-0.0283"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#d2d2d2;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 328.50261,168.45815 0.0576,-10.96002 10.94282,-0.0283"
+ id="path52899"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(1,5.25126e-6,0,1,0,0)"
+ y="155.49829"
+ x="326.50003"
+ height="2.9999838"
+ width="2.9999995"
+ id="rect52901"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265" />
+ </g>
+ </g>
+ <g
+ transform="translate(318,94.000007)"
+ id="g52903"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52905"
+ width="16"
+ height="16"
+ x="-124"
+ y="420" />
+ <g
+ id="g52907"
+ transform="translate(-258,96.99999)"
+ mask="url(#mask32294)">
+ <path
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 142.5,327.5 c 0,1.2526 -0.5,2 -1.5,3 -1,1 0,3 -1.25,3 l -2.5,0 c -1.25,0 -0.25,-2 -1.25,-3 -1,-1 -1.5,-1.75686 -1.5,-3 0,-2.208 1.792,-4 4,-4 2.208,0 4,1.792 4,4 z"
+ id="path52909"
+ sodipodi:nodetypes="cssssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssssssc"
+ id="path52911"
+ d="m 142.5,327.5 c 0,1.2526 -0.5,2 -1.5,3 -1,1 0,3 -1.25,3 l -2.5,0 c -1.25,0 -0.25,-2 -1.25,-3 -1,-1 -1.5,-1.75686 -1.5,-3 0,-2.208 1.792,-4 4,-4 2.208,0 4,1.792 4,4 z"
+ style="fill:none;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 137.5,336.00001 2,0 0,1 -2,-10e-6 0,-0.99999 z"
+ id="path52913"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#24221c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52915"
+ width="5"
+ height="4.7498698"
+ x="136"
+ y="331.25"
+ rx="0.765625"
+ ry="0.765625" />
+ <rect
+ y="332.60001"
+ x="137"
+ height="2.55"
+ width="3"
+ id="rect52917"
+ style="fill:#a89858;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(1.0666667,0,0,1,-128.7,252.00668)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.021577613"
+ inkscape:original="M 249.25 79.96875 C 248.7604 79.96875 248.46875 80.255136 248.46875 80.5 C 248.46875 80.744863 248.76041 81.031252 249.25 81.03125 C 249.73959 81.031248 251.26039 81.03125 251.75 81.03125 C 252.23961 81.03125 252.53125 80.744873 252.53125 80.5 C 252.53125 80.255131 252.23961 79.968752 251.75 79.96875 L 249.25 79.96875 z M 249.25 81.96875 C 248.7604 81.96875 248.46875 82.255138 248.46875 82.5 C 248.46875 82.744863 248.76041 83.031253 249.25 83.03125 L 251.75 83.03125 C 252.23961 83.03125 252.53125 82.744875 252.53125 82.5 C 252.53125 82.255131 252.23961 81.968753 251.75 81.96875 C 251.26039 81.968747 249.7396 81.96875 249.25 81.96875 z "
+ style="fill:url(#linearGradient53149);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path52919"
+ d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 l 2.5,0 c 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 l -2.5,0 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 2.5,0 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 l -2.5,0 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path52921"
+ d="m 137.25,334.25 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 137.25,332.25 1.25,0"
+ id="path52923"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="334"
+ x="141"
+ height="1"
+ width="0.25"
+ id="rect52925"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52927"
+ width="0.25"
+ height="1"
+ x="141"
+ y="332" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52929"
+ width="0.25"
+ height="1"
+ x="135.75"
+ y="334" />
+ <rect
+ y="332"
+ x="135.75"
+ height="1"
+ width="0.25"
+ id="rect52931"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="translate(-112,254)"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ id="path52933"
+ style="fill:url(#linearGradient53151);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ inkscape:radius="0.5"
+ sodipodi:type="inkscape:offset" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.5"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ style="opacity:0.6;fill:url(#radialGradient53153);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path52935"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ transform="translate(-112,254)" />
+ <path
+ d="m 138.5,324.5 c 1.656,0 3,1.34699 3,3.00667 0,0.89477 -0.39063,1.69865 -1.01019,2.24958 C 139.96017,330.22723 139.5,331 139.5,332.25 m -1,-7.75 c -1.656,0 -3,1.34699 -3,3.00667 0,0.89477 0.39063,1.69865 1.01019,2.24958 C 137.03983,330.22723 137.5,331 137.5,332.25"
+ style="fill:none;stroke:url(#linearGradient53155);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path52937"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.8490785,0,0,0.8469086,71.921104,-98.093334)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path52939"
+ style="opacity:0.25;fill:url(#radialGradient53157);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path52941"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.99567,0,-0.00787885,1,74.34506,191)" />
+ <path
+ id="path52943"
+ style="fill:none;stroke:url(#radialGradient53159);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 138.5,324.5 c 1.656,0 3,1.34699 3,3.00667 0,0.89477 -0.39063,1.69865 -1.01019,2.24958 C 139.96017,330.22723 139.5,331 139.5,332.25 m -1,-7.75 c -1.656,0 -3,1.34699 -3,3.00667 0,0.89477 0.39063,1.69865 1.01019,2.24958 C 137.03983,330.22723 137.5,331 137.5,332.25"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="331"
+ x="136.01562"
+ height="0.75"
+ width="4.96875"
+ id="rect52945"
+ style="opacity:0.85;fill:#504416;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52947"
+ d="m 137.5,335.01146 2,0 0,1 -2,-10e-6 0,-0.99999 z"
+ style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52949"
+ d="m 138,329 0,3.75 1,0 0,-3.75 -1,0 z"
+ style="opacity:0.2;fill:url(#linearGradient53161);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="328"
+ x="137"
+ height="1"
+ width="3"
+ id="rect52951"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.3;fill:#d3bc5f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52953"
+ width="1"
+ height="1"
+ x="138"
+ y="328" />
+ <path
+ d="m 138.5,324.5 c 1.656,0 3,1.34699 3,3.00667 0,0.89477 -0.39063,1.69865 -1.01019,2.24958 C 139.96017,330.22723 139.5,331 139.5,332.25 m -1,-7.75 c -1.656,0 -3,1.34699 -3,3.00667 0,0.89477 0.39063,1.69865 1.01019,2.24958 C 137.03983,330.22723 137.5,331 137.5,332.25"
+ style="fill:none;stroke:url(#radialGradient53163);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path52955"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52957"
+ d="m 137.5,336.00001 0.5,0 0,1 -0.5,-10e-6 0,-0.99999 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-626.98389,452.95862)"
+ style="display:inline;enable-background:new"
+ id="g52959">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52961"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient53165);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ id="path52963"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path52965"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient53167);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.38281,1.847656 2.36719,-2.347656 -1.5,-2 z"
+ id="path52967"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 518.48389,-29.45862 -4,4.75 2,2.25 2,-2"
+ id="path52969"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path52971"
+ d="m 518.98389,-29.70862 -4.75,5.5 1.75,1.75 3,-2.75 0,-4.5 z"
+ style="fill:url(#linearGradient53169);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 513.48389,-22.45862 5,-6"
+ id="path52973"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53171);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ id="path52975"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g77742"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-870.9421,-297.02038)" />
+ <g
+ id="g33404"
+ transform="translate(-20.999997,23)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33341"
+ width="16"
+ height="16"
+ x="257"
+ y="113" />
+ <g
+ style="opacity:0.8;display:inline"
+ id="g33343"
+ transform="matrix(1.1658027,0,0,1.1657997,112.71027,-140.05607)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path33345"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1.33333421;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.643333,0,0,0.643335,44.424162,146.72855)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient33427);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path33347"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)" />
+ <path
+ transform="matrix(0.5361112,0,0,0.5361024,58.577433,159.38208)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33429);stroke-width:1.60001671;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path33349"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(5,-21)"
+ id="g33351">
+ <g
+ id="g33353"
+ transform="translate(169.04507,38.63228)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path33355"
+ d="m 90.45493,102.86772 -4.5e-4,6.03674 6.00045,-0.0367 4.5e-4,-6.03674 -6.00045,0.0367 z"
+ style="opacity:0.7;fill:none;stroke:#002255;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#afc6e9;fill-opacity:0.70588235;fill-rule:evenodd;stroke:#afc6e9;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.45493,102.86772 -4.5e-4,6.03674 6,0 4.5e-4,-6.03674 -6,0 z"
+ id="path33357"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="146.5"
+ x="264.50012"
+ height="3"
+ width="2.9998772"
+ id="rect33359"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33361"
+ width="2.9998772"
+ height="3"
+ x="257.50012"
+ y="139.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="146.49997"
+ x="257.49969"
+ height="3"
+ width="2.9998772"
+ id="rect33363"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 267.00027,146.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path33365"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path33367"
+ d="m 260,147 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path33369"
+ d="m 260.00029,140 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33371"
+ width="2.9998772"
+ height="3"
+ x="264.50085"
+ y="139.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path33373"
+ d="m 267.00101,139.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g50822"
+ transform="translate(74,89.000007)">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50824"
+ width="16"
+ height="16"
+ x="-27"
+ y="446" />
+ <g
+ transform="translate(-49,229)"
+ id="g50826"
+ style="opacity:0.5">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path50828"
+ style="fill:none;stroke:#1a1a1a;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 25.5,220 0,10.5 4,0 m -4,-5 c 0.125,0 4,0 4,0"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m 25.5,220 0,10.5 4,0 m -4,-5 c 0.125,0 4,0 4,0"
+ style="fill:none;stroke:#bcd0f5;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path50830"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient50870);fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50832"
+ width="7.000001"
+ height="3"
+ x="-26.5"
+ y="446.5" />
+ <g
+ transform="translate(-48,228)"
+ style="opacity:0.45"
+ id="g50834">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50836"
+ width="1"
+ height="1"
+ x="24"
+ y="226" />
+ <rect
+ y="231"
+ x="24"
+ height="1"
+ width="1"
+ id="rect50838"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path50840"
+ d="m -19.5,452.5 0,3 7,0 0,-3 -7,0 z m 0,6 0,3 7,0 0,-3 -7,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -25.5,448.5 0,-1 5,0"
+ id="path50842"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path50844"
+ d="m -18.5,454.5 0,-1 5,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -18.5,460.5 0,-1 5,0"
+ id="path50846"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="447.25"
+ x="-25"
+ height="1.75"
+ width="1"
+ id="rect50848"
+ style="opacity:0.4;fill:#000000;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.3;fill:#000000;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50850"
+ width="1"
+ height="2"
+ x="-18"
+ y="453" />
+ <rect
+ y="459"
+ x="-18"
+ height="2"
+ width="1"
+ id="rect50852"
+ style="opacity:0.3;fill:#000000;fill-opacity:0.70588235;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path50854"
+ d="m -23.5,448.5 0,-1 3,0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -16.5,454.5 0,-1 3,0"
+ id="path50856"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path50858"
+ d="m -16.5,460.5 0,-1 3,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="translate(-48,228)"
+ y="225"
+ x="24"
+ height="1"
+ width="1"
+ id="rect50860"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50862"
+ width="1"
+ height="1"
+ x="-23"
+ y="454" />
+ <rect
+ y="455"
+ x="-24"
+ height="1"
+ width="1"
+ id="rect50864"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect50866"
+ width="1"
+ height="1"
+ x="-24"
+ y="458" />
+ <rect
+ y="459"
+ x="-23"
+ height="1"
+ width="1"
+ id="rect50868"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g33837"
+ transform="translate(-42,23)">
+ <rect
+ style="opacity:0.01000001;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33464"
+ width="16"
+ height="16"
+ x="173"
+ y="134"
+ ry="0" />
+ <g
+ style="opacity:0.8;display:inline"
+ id="g33466"
+ transform="matrix(1.0761252,0,0,1.0761229,40.809522,-96.59025)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path33469"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient33831);stroke-width:1.44444537;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.643333,0,0,0.643335,44.424162,146.72855)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient33833);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path33471"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.5902213,-0.06639044,0.06727327,-0.5855229,199.31507,300.5352)" />
+ <path
+ transform="matrix(0.5227063,0,0,0.5226977,60.34688,160.96383)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33835);stroke-width:1.77780378;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path33473"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g33475"
+ transform="translate(-62.70896,-1.9304201)">
+ <path
+ style="fill:none;stroke:#003380;stroke-width:2.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 245.20896,142.43042 5,-5"
+ id="path33477"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:none;stroke:#2a7fff;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000233;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 244.54233,144.43041 1.33333,0 1.33332,-1.33332 0,-1.33335 -1.33332,-1.33332 -1.33332,-1e-5 -1.33333,1.33334 0,1.33333 1.33332,1.33333 z"
+ id="path33479"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path33483"
+ d="m 244.45896,144.43042 1.5,0 1.25,-1.25 0,-1.5 -1.3333,-1.25 -1.4167,0 -1.25,1.25 0,1.5 1.25,1.25 z"
+ style="fill:none;stroke:#0044aa;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 244.45896,143.93042 1.5,0 0.75,-0.75 0,-1.5 -0.75,-0.75 -1.5,0 -0.75,0.75 0,1.5 0.75,0.75 z"
+ id="path33481"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path33485"
+ d="m 245.20896,142.43042 5,-5"
+ style="fill:none;stroke:url(#linearGradient33585);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="141.93039"
+ x="244.709"
+ height="1"
+ width="1"
+ id="rect33487"
+ style="opacity:0.8;fill:#00112b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.99999976;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect33589"
+ width="16"
+ height="16"
+ x="215"
+ y="136" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(84,-124)"
+ id="g36191"
+ mask="url(#mask25369)">
+ <rect
+ y="281"
+ x="320"
+ height="16"
+ width="16"
+ id="rect36193"
+ style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 324.5,295.75 0,-13.5 m 7,13.5 0,-13.5"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36195"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36197"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 321.25001,285.50001 334.75,285.5 M 321.25001,292.50001 334.75,292.5"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36199"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 324.5,296.5 0,-14.99999 m 7,14.99999 0,-14.99999"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 320.5,285.50001 15,0 m -15,6.99999 15,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36201"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:transform-center-y="-6.547647"
+ inkscape:transform-center-x="-6.5102284"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient24523);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ id="path36205"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5002341,0,0,1.5000004,549.81053,465.24998)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="opacity:0.96000001;fill:#ff8400;fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 159.5,582.50001 0,5.40625 c 0.75032,0.38395 1.59977,0.59375 2.5,0.59375 0.90022,0 1.74968,-0.2098 2.5,-0.59375 l 0,-5.40625 -5,0 z"
+ id="path36207"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36209"
+ d="m 160.5,586.25001 0,-2.75 3,0"
+ style="opacity:0.76799999;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.96000001;fill:#ff8400;fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 165.5,587.25001 c -1.25,1 -2.5,1.25 -3,1.25 l 0,3 2.98688,0 0.0131,-4.25 2e-5,0 0,0 0,0 z"
+ id="path36211"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.672;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 163.5,590.50001 0,-2"
+ id="path36213"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="577"
+ x="152"
+ height="16"
+ width="16"
+ id="rect36215"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36217"
+ d="m 156.5,588.50001 1.5,-1.5"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.5002341,0,0,1.5000004,549.81053,465.24998)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36220"
+ style="opacity:0.48000004;fill:url(#radialGradient24519);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.5102284"
+ inkscape:transform-center-y="-6.547647" />
+ <path
+ inkscape:transform-center-y="-6.8594309"
+ inkscape:transform-center-x="-6.8191649"
+ sodipodi:type="arc"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:0.57272732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path36222"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5714299,0,0,1.5714268,568.21462,459.64301)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="opacity:0.96000001;fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 153.86319,591.13808 156.25,588.75001"
+ id="path36224"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.96000001;fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 156.5,588.50001 1.5,-1.5"
+ id="path36226"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.96000001"
+ id="g36228"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0988734,0,0,1.0981343,-23.179949,357.33845)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient24511);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient24513);stroke-width:0.79652983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path36230"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.14287,0,0,1.142863,463.9317,115.80133)" />
+ <g
+ id="g36232">
+ <path
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36234"
+ style="opacity:0.25;fill:url(#radialGradient24515);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient24517);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36236"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
+ </g>
+ <path
+ inkscape:transform-center-y="-5.7593212"
+ inkscape:transform-center-x="-3.1120555"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path36238"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.9100226,0,0,0.9106329,108.4468,80.751664)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36240"
+ d="m 153.75,591.25001 2.5,-2.5"
+ style="opacity:0.96000001;fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.672;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 153.25,591.00001 2.75,-2.75"
+ id="path36242"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36244"
+ d="m 164.5,585.25001 0,-2.75 -5,0 0,2.75"
+ style="opacity:0.48000004;fill:none;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g36246"
+ transform="translate(60,59)">
+ <rect
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36248"
+ width="16"
+ height="16"
+ x="71"
+ y="518" />
+ <g
+ id="g36250">
+ <g
+ mask="url(#mask18634)"
+ id="g36252"
+ transform="translate(-136,386)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path36254"
+ d="m 210,134.5 7.5,0 0,13 -10,0 0,-10.5 2.5,-2.5 z"
+ style="fill:url(#linearGradient37472);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ sodipodi:nodetypes="ccc"
+ id="path36256"
+ style="fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ d="m -48.384641,259.86235 2.000031,-0.008 -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36258"
+ d="m 207,138 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 207.5,137 0,10.5 10,0 0,-13 -7.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36260"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36262"
+ style="fill:none;stroke:url(#linearGradient37475);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 208.5,138.5 0,8 m 3,-11 5,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.01000001"
+ clip-path="url(#clipPath18524)"
+ transform="translate(-134,387)"
+ id="g36264">
+ <path
+ style="fill:url(#linearGradient37477);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 210,134.5 7.5,0 0,12 -10,0 0,-9.5 2.5,-2.5 z"
+ id="path36266"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -48.384641,259.86235 2.000031,-0.008 -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path36268"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,271.54887,-199.56022)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 207,138 4,0 0,-4 -4,4 z"
+ id="path36270"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path36272"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 207.5,137 0,9.5 10,0 0,-12 -7.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 208.5,138.5 0,7 m 3,-10 5,0"
+ style="fill:none;stroke:url(#linearGradient37479);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path36274"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g36276"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.781818,0,0,0.781818,-53.239298,365.85549)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36278"
+ style="fill:#ffffff;fill-opacity:0.1372549;stroke:#000000;stroke-width:0.78698397;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36280"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ style="fill:none;stroke:#28170b;stroke-width:4.47674513;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.5581398;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 168.5,205.5 0.96309,-0.98372"
+ id="path36282"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36284"
+ d="m 168.5,205.5 1.28285,-1.30349"
+ style="fill:none;stroke:#cccccc;stroke-width:1.40697706;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.878699,0,0,0.877142,14.70687,20.74499)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g36286">
+ <path
+ transform="matrix(-1.2468441,0,0,1.246865,503.16273,106.89331)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36288"
+ style="fill:url(#linearGradient37481);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37483);stroke-width:1.16848361;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ style="fill:none;stroke:#a05a2c;stroke-width:2.55814004;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 164.66657,209.31279 3.51745,-3.51744"
+ id="path36290"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36292"
+ d="m 164.02704,208.99303 3.83721,-3.83721"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.2790699;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-6.3853012"
+ inkscape:transform-center-x="-6.3473305"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient37485);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69954133;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36294"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="matrix(0.9729196,0,0,0.9789579,9.7047721,-0.8010785)"
+ style="opacity:0.96000001;display:inline"
+ id="g36296">
+ <path
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36298"
+ style="opacity:0.25;fill:url(#radialGradient37487);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37489);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36300"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
+ </g>
+ <path
+ transform="matrix(1.2790738,0,0,1.2790735,89.840744,25.765779)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path36302"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(42,41)"
+ id="g36304"
+ style="opacity:0.96000001;display:inline;enable-background:new">
+ <path
+ inkscape:transform-center-y="-6.5435007"
+ inkscape:transform-center-x="-6.5092113"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient37491);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ id="path36306"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5000024,0,0,1.4990511,528.75064,424.32781)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(42,87)"
+ id="g36308">
+ <rect
+ y="449"
+ x="89"
+ height="16"
+ width="16"
+ id="rect36310"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36312"
+ d="M 93.5,460.5 95,459"
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-6.8594309"
+ inkscape:transform-center-x="-6.8191649"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.57272732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36314"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.863188,463.13807 93.25,460.75"
+ id="path36316"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 93.5,460.5 2,-2"
+ id="path36318"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g36320"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0988734,0,0,1.0981343,-86.169279,229.32421)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37493);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37495);stroke-width:0.79652983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path36322"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" />
+ <g
+ id="g36324">
+ <path
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36326"
+ style="opacity:0.25;fill:url(#radialGradient37497);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37499);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36328"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
+ </g>
+ <path
+ inkscape:transform-center-y="-5.7593212"
+ inkscape:transform-center-x="-3.1120555"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path36330"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.9100226,0,0,0.9106329,108.4468,80.751664)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36332"
+ d="m 90.75,463.25 2.5,-2.5"
+ style="fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.25,463 93,460.25"
+ id="path36334"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 142,545 1,3e-5 0,-1 0,-1 3.5,0 0,-2 -3.5,0 0,-1 0,-1 -1,-3e-5 -2,2.5 0,1 z"
+ id="path36337"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339"
+ transform="translate(-294,339)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36341"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343">
+ <g
+ id="g36345"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349"
+ style="fill:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#ad2f94;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353"
+ style="fill:#0060f0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#00d4aa;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357"
+ style="fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#ffbf0e;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36363"
+ style="opacity:0.3;fill:url(#radialGradient37501);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36365"
+ style="fill:none;stroke:url(#linearGradient37503);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ transform="translate(105,41)"
+ id="g36367"
+ style="opacity:0.96000001;display:inline;enable-background:new">
+ <g
+ id="g36369"
+ transform="translate(0,87)">
+ <rect
+ y="449"
+ x="89"
+ height="16"
+ width="16"
+ id="rect36371"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36373"
+ d="M 93.5,460.5 95,459"
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-6.8594309"
+ inkscape:transform-center-x="-6.8191649"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.57272732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path36375"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.863188,463.13807 93.25,460.75"
+ id="path36377"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 93.5,460.5 95,459"
+ id="path36379"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g36381"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0988734,0,0,1.0981343,-86.169279,229.32421)">
+ <path
+ inkscape:transform-center-y="-4.9844055"
+ inkscape:transform-center-x="-4.9755572"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37505);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37507);stroke-width:0.79652983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ id="path36383"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" />
+ <g
+ id="g36385">
+ <path
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36387"
+ style="opacity:0.25;fill:url(#radialGradient37509);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37511);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36389"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
+ </g>
+ <path
+ inkscape:transform-center-y="-5.7593212"
+ inkscape:transform-center-x="-3.1120555"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="135"
+ sodipodi:cx="64"
+ id="path36391"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.9100226,0,0,0.9106329,108.4468,80.751664)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36393"
+ d="m 90.75,463.25 2.5,-2.5"
+ style="fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 90.25,463 93,460.25"
+ id="path36395"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:transform-center-y="-6.547647"
+ inkscape:transform-center-x="-6.5102284"
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient37513);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ id="path36397"
+ sodipodi:cx="258.5"
+ sodipodi:cy="78.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5002341,0,0,1.5000004,486.81053,424.24997)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g36399"
+ style="fill:#000000"
+ transform="translate(0,87)">
+ <g
+ id="g36401"
+ style="fill:#000000">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36403"
+ width="2"
+ height="6"
+ x="98"
+ y="452"
+ ry="0.453125" />
+ <rect
+ y="-102"
+ x="454"
+ height="6"
+ width="2"
+ id="rect36405"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)"
+ ry="0.65625" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(105,41)"
+ id="g36407"
+ style="opacity:0.96000001;display:inline;enable-background:new">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.5000024,0,0,1.4990511,507.75064,424.32781)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36409"
+ style="fill:url(#radialGradient37515);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.5092113"
+ inkscape:transform-center-y="-6.5435007" />
+ <g
+ id="g36411"
+ transform="translate(21,87)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36413"
+ width="16"
+ height="16"
+ x="89"
+ y="449" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 93.5,460.5 95,459"
+ id="path36415"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36417"
+ style="fill:none;stroke:#000000;stroke-width:0.57272732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.8191649"
+ inkscape:transform-center-y="-6.8594309" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36419"
+ d="M 90.863188,463.13807 93.25,460.75"
+ style="fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36421"
+ d="M 93.5,460.5 95,459"
+ style="fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1.0988734,0,0,1.0981343,-86.169279,229.32421)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g36423">
+ <path
+ transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36425"
+ style="fill:url(#linearGradient37517);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37519);stroke-width:0.79652983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-4.9755572"
+ inkscape:transform-center-y="-4.9844055" />
+ <g
+ id="g36427">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient37521);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36429"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)" />
+ <path
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36431"
+ style="opacity:0.25;fill:url(#radialGradient37523);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ transform="matrix(0.9100226,0,0,0.9106329,108.4468,80.751664)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path36433"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ inkscape:transform-center-x="-3.1120555"
+ inkscape:transform-center-y="-5.7593212" />
+ </g>
+ <path
+ style="fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 90.75,463.25 2.5,-2.5"
+ id="path36435"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36437"
+ d="M 90.25,463 93,460.25"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="-123"
+ x="541"
+ height="6"
+ width="2"
+ id="rect36439"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)"
+ ry="0.609375" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36441"
+ transform="translate(107,-124)">
+ <g
+ style="opacity:0.85;display:inline;enable-background:new"
+ transform="translate(-273,0)"
+ id="g36443"
+ mask="url(#mask25561)">
+ <rect
+ y="281"
+ x="320"
+ height="16"
+ width="16"
+ id="rect36445"
+ style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 325.5,295.75 0,-13.5 m 6,13.5 0,-13.5"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36447"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36449"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 321.25,286.5 13.49999,-10e-6 M 321.25001,292.50001 334.75,292.5"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36451"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 325.5,296.49999 0,-14.99999 m 6,15 0,-14.99999"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 320.5,286.5 15,0 m -15,6 15,0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path36453"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-21,0)"
+ id="g36455">
+ <g
+ transform="translate(-277.98388,250)"
+ id="g36457"
+ style="display:inline">
+ <path
+ transform="matrix(1.142871,0,0,1.142855,-27.218817,-5.0713453)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path36459"
+ style="fill:url(#linearGradient37525);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.69999641;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37527);stroke-width:1.16669464;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path36461"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.857099,0,0,0.857147,67.228993,5.071249)" />
+ </g>
+ <g
+ transform="translate(-210,147)"
+ id="g36463">
+ <rect
+ y="137"
+ x="282"
+ height="1"
+ width="1"
+ id="rect36465"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36467"
+ width="1"
+ height="1"
+ x="283"
+ y="138" />
+ <rect
+ y="139"
+ x="282"
+ height="1"
+ width="1"
+ id="rect36469"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36472"
+ width="1"
+ height="1"
+ x="281"
+ y="138" />
+ <rect
+ y="138"
+ x="283"
+ height="1"
+ width="1"
+ id="rect36474"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36476"
+ style="opacity:0.5">
+ <rect
+ y="137"
+ x="281"
+ height="1"
+ width="1"
+ id="rect36478"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="137"
+ x="283"
+ height="1"
+ width="1"
+ id="rect36480"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="139"
+ x="283"
+ height="1"
+ width="1"
+ id="rect36482"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="139"
+ x="281"
+ height="1"
+ width="1"
+ id="rect36484"
+ style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36486"
+ transform="translate(-44.309303,267.47333)">
+ <rect
+ y="309.52667"
+ x="49.309303"
+ height="16"
+ width="16"
+ id="rect36488"
+ style="opacity:0;fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:transform-center-y="-5"
+ inkscape:transform-center-x="5"
+ style="opacity:0.7"
+ id="g36490"
+ transform="translate(-396.6907,133.52667)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36492"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36494"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,1,-1,0,241.3093,-136.47333)"
+ id="g36496"
+ style="opacity:0.7"
+ inkscape:transform-center-x="-5"
+ inkscape:transform-center-y="-5">
+ <path
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36498"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36500"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ inkscape:transform-center-y="5"
+ inkscape:transform-center-x="-5"
+ style="opacity:0.7"
+ id="g36502"
+ transform="matrix(-1,0,0,-1,511.3093,501.52667)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36504"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36506"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-1,1,0,-126.6907,771.52667)"
+ id="g36508"
+ style="opacity:0.7"
+ inkscape:transform-center-x="5"
+ inkscape:transform-center-y="5">
+ <path
+ style="fill:none;stroke:#241f1c;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ id="path36510"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36512"
+ d="m 447.5,180.5 0,-2.25 0.75,-0.75 2.25,0"
+ style="fill:none;stroke:#e3dedb;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1.1870922,0,0,1.1818357,-168.36213,276.1664)"
+ id="g36514"
+ style="display:inline">
+ <g
+ id="g36516">
+ <g
+ style="display:inline;enable-background:new"
+ id="g36518"
+ transform="matrix(0.8423946,0,0,0.8461413,-192.36364,-120.73212)">
+ <path
+ inkscape:transform-center-y="-3"
+ inkscape:transform-center-x="3"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ id="path36520"
+ d="m 450.5,179 -0.83982,0.68197 L 449,180.5 l 0,0.5 1,0 0,1 1,0 0,1 0.25,0 0.66329,-1.10494 L 453,181.25 l 0,-0.25 -1,0 0,-1 -1,0 0,-1 -0.5,0 z"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 459,180.5 458.31803,179.66018 457.5,179 l -0.5,0 0,1 -1,0 0,1 -1,0 0,0.25 1.10494,0.66329 L 456.75,183 l 0.25,0 0,-1 1,0 0,-1 1,0 0,-0.5 z"
+ id="path36522"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:transform-center-x="-3"
+ inkscape:transform-center-y="-3"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="3"
+ inkscape:transform-center-x="-3"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ id="path36524"
+ d="m 457.5,189 0.83982,-0.68197 L 459,187.5 l 0,-0.5 -1,0 0,-1 -1,0 0,-1 -0.25,0 -0.66329,1.10494 L 455,186.75 l 0,0.25 1,0 0,1 1,0 0,1 0.5,0 z"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 449,187.5 0.68197,0.83982 L 450.5,189 l 0.5,0 0,-1 1,0 0,-1 1,0 0,-0.25 -1.10494,-0.66329 L 451.25,185 l -0.25,0 0,1 -1,0 0,1 -1,0 0,0.5 z"
+ id="path36526"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:transform-center-x="3"
+ inkscape:transform-center-y="3"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cssscczzzz"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36528"
+ d="m 190.07108,29.454411 c -3.02619,0 -5.48439,2.463313 -5.48438,5.5 0,3.036688 2.45819,5.500001 5.48438,5.5 3.02619,0 5.48437,-2.46331 5.48437,-5.5 0,-3.036689 -2.45818,-5.500001 -5.48437,-5.5 z m 0.0124,3.388115 c 1.26359,0 2.10599,0.846143 2.10599,2.115354 0,1.269211 -0.8424,2.115353 -2.10599,2.115353 -1.26359,0 -2.10598,-0.846141 -2.10598,-2.115353 0,-1.269212 0.84239,-2.115354 2.10598,-2.115354 l 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient37529);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.75983924;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.5547465,0,0,-0.5552803,116.84153,100.48096)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37531);stroke-width:2.28174472;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path36530"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36532"
+ style="fill:none;stroke:url(#linearGradient37533);stroke-width:3.21050167;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.3942416,0,0,-0.3946688,138.04864,81.514802)" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccc"
+ id="path36534"
+ d="m 190.94678,29.919785 -0.8687,-0.147436 -0.81609,0.147436 0,2.538424 0.8347,-0.01215 0.85009,0.01215 0,-2.538424 0,0 0,0 0,0 z m 1.68479,4.230706 0,0.846142 0,0.846141 2.52718,0 0.0755,-0.891284 -0.0755,-0.800999 -2.52718,0 0,0 0,0 0,0 z m -7.58155,0 -0.10953,0.819696 0.10953,0.872587 2.52718,0 0,-0.846141 0,-0.846142 -2.52718,0 z m 5.89676,3.17303 -0.8687,0.152099 -0.81609,-0.152099 0,2.74996 0.8347,0.07585 0.85009,-0.07585 0,-2.74996 z"
+ style="fill:#d40000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36536"
+ style="fill:none;stroke:url(#linearGradient37535);stroke-width:2.28174472;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.5547465,0,0,-0.5552803,116.84153,100.48096)" />
+ <path
+ transform="matrix(0.3942416,0,0,-0.3946688,138.04864,81.514802)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37537);stroke-width:3.21050167;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path36538"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g36540"
+ inkscape:label="Layer 1"
+ transform="translate(-211.14286,264.78067)">
+ <g
+ transform="translate(307.14286,-384.78067)"
+ id="g36542"
+ style="display:inline">
+ <rect
+ y="592"
+ x="182"
+ height="16"
+ width="16"
+ id="rect36544"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36546"
+ transform="translate(117.00001,391)">
+ <g
+ transform="translate(-203,-446)"
+ style="display:inline"
+ id="g36548">
+ <g
+ transform="matrix(0.9993234,0,0,1.0050357,164.07104,603.72198)"
+ style="opacity:0.96000001;display:inline"
+ id="g36550">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path36552"
+ d="m 118.00879,52.264848 10e-6,2.238708 -7.00472,3.482446 -6.00407,-2.984969 -1e-5,-2.238708 7.00473,-2.736203 6.00406,2.238726 0,0 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79609263;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36554"
+ d="m 105.00001,52.762325 7.00473,-2.736212 6.00406,2.238717 0,2.238716 -7.00473,1.492495 -6.00406,-0.995 0,-2.238716 0,0 0,0 0,0 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 105.00998,54.999895 -0.01,-1.988833 6.00407,2.984969 0.01,1.988833 -6.00406,-2.984969 -1e-5,0 z"
+ id="path36556"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36558"
+ d="m 118.0088,54.503556 -0.01,-1.988833 -6.99476,3.481308 c 0,2.570679 0,1.425722 0,1.989979 l 7.00473,-3.482454 3e-5,0 0,0 0,0 z"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient37539);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 269.25,657.25 0,1.5 5.75,3 6.75,-3.5 0,-1.5"
+ id="path36560"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 70,228.5 65,226"
+ id="path36562"
+ transform="translate(2.0099702,-15.001162)"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,1,433.97059,0)"
+ id="g36564">
+ <path
+ sodipodi:nodetypes="cssccssccssc"
+ id="path36566"
+ d="m 245.5,593.5 c 1.25,2.5 0.97056,4.5 0.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 0.0294,-4 -1.97056,-6.5 z m -5,0 c 2.75,1.25 2.97056,4.5 2.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 -0.72056,-5 -3.97056,-6.5 z m -1,4 c 1.97058,0 1.97058,2 1.97058,2.5 0,0.75 0,0.75 0,0 0,-0.5 0,-2.5 -1.97058,-2.5 z"
+ style="fill:none;stroke:url(#linearGradient37541);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssccssccssc"
+ id="path36568"
+ d="m 245.5,593.5 c 1.25,2.5 0.97056,4.5 0.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 0.0294,-4 -1.97056,-6.5 z m -5,0 c 2.75,1.25 2.97056,4.5 2.97056,6.5 0,0.75 1,0.75 1,0 0,-2.5 -0.72056,-5 -3.97056,-6.5 z m -1,4 c 1.97058,0 1.97058,1.5 1.97058,2.5 0,0.5 0,0.5 0,0 0,-1 0,-2.5 -1.97058,-2.5 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient37543);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36570"
+ transform="translate(21,254)">
+ <rect
+ y="321"
+ x="66"
+ height="20"
+ width="20"
+ id="rect36572"
+ style="opacity:0;fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-235,231)"
+ id="g36574"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(392,-78.06282)"
+ id="g36576"
+ style="display:inline;enable-background:new">
+ <g
+ id="g36578">
+ <g
+ mask="url(#mask13041)"
+ id="g36580"
+ transform="translate(-360,181.06282)">
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.46875,-12.53125 c -1.65264,0 -2.96875,1.066109 -2.96875,2.71875 l 0,2.5625 c 0,1.6526411 1.31612,2.71875 2.96875,2.71875 l 0.0625,0 c 1.65264,0 2.96875,-1.0661089 2.96875,-2.71875 l 0,-2.5625 c 0,-1.652641 -1.31612,-2.71875 -2.96875,-2.71875 l -0.0625,0 z M 279.5,-10.5 c 0.554,0 1,0.196 1,0.75 l 0,2.5 c 0,0.554 -0.446,0.75 -1,0.75 -0.554,0 -1,-0.196 -1,-0.75 l 0,-2.5 c 0,-0.554 0.446,-0.75 1,-0.75 z"
+ id="path36582"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-10"
+ x="277"
+ height="2.5"
+ width="1"
+ id="rect36584"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.5" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36586"
+ width="1"
+ height="1"
+ x="277.49176"
+ y="-11.287262"
+ ry="0.5" />
+ </g>
+ <g
+ mask="url(#mask13052)"
+ transform="translate(-360,191.06282)"
+ id="g36588">
+ <path
+ id="path36590"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.003609 -2.96875,2.65625 l 0,2.5625 c 0,1.6526411 1.34737,2.75 3,2.75 l 0.0625,0 c 1.65264,0 2.9375,-1.0973589 2.9375,-2.75 l 0,-2.5625 c 0,-1.652641 -1.31612,-2.65625 -2.96875,-2.65625 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.1335 1,0.6875 l 0,2.5 c 0,0.554 -0.41475,0.78125 -0.96875,0.78125 -0.554,0 -1.03125,-0.22725 -1.03125,-0.78125 l 0,-2.5 c 0,-0.554 0.446,-0.6875 1,-0.6875 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36592"
+ width="1"
+ height="2.5"
+ x="277"
+ y="-10"
+ ry="0.390625" />
+ <rect
+ y="-11"
+ x="278"
+ height="1"
+ width="1"
+ id="rect36594"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.5" />
+ </g>
+ </g>
+ <g
+ id="g36596" />
+ </g>
+ <rect
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36608"
+ width="1"
+ height="3"
+ x="311"
+ y="93" />
+ <rect
+ y="104"
+ x="311"
+ height="3"
+ width="1"
+ id="rect36610"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36612"
+ transform="translate(0,275)">
+ <g
+ transform="translate(-226,210)"
+ id="g36614"
+ style="display:inline;enable-background:new">
+ <path
+ id="path36616"
+ d="m 302.5,105.52631 0,-4"
+ style="fill:none;stroke:#2d2d2d;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask24466)"
+ transform="translate(23,116.0625)"
+ id="g36618">
+ <path
+ id="path36620"
+ d="m 279.46875,-12.59375 c -1.65264,0 -2.96875,1.066109 -2.96875,2.71875 l 0,2.5625 c 0,1.6526411 1.31612,2.78125 2.96875,2.78125 l 0.0625,0 c 1.65264,0 2.96875,-1.1286089 2.96875,-2.78125 l 0,-2.5625 c 0,-1.652641 -1.31612,-2.71875 -2.96875,-2.71875 l -0.0625,0 z m 0.0312,2.03125 c 0.554,0 1,0.196 1,0.75 l 0,2.5 c 0,0.554 -0.446,0.8125 -1,0.8125 -0.554,0 -1,-0.2585 -1,-0.8125 l 0,-2.5 c 0,-0.554 0.446,-0.75 1,-0.75 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36622"
+ width="1"
+ height="3.5"
+ x="277"
+ y="-11.0625"
+ ry="0.5" />
+ <rect
+ y="-12.0625"
+ x="278"
+ height="1"
+ width="1"
+ id="rect36624"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.5" />
+ </g>
+ <g
+ id="g36626"
+ mask="url(#mask24456)"
+ transform="translate(2e-6,-21.02385)">
+ <path
+ id="path36628"
+ d="m 302.5,118.49506 0,-3.99506"
+ style="fill:none;stroke:#2d2d2d;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(22.999998,128.02385)"
+ id="g36630"
+ mask="none">
+ <path
+ id="path36632"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.128609 -2.96875,2.78125 l 0,2.5 c 0,1.6526411 1.34737,2.75 3,2.75 l 0.0625,0 c 1.65264,0 2.9375,-1.0973589 2.9375,-2.75 l 0,-2.5 c 0,-1.652641 -1.31612,-2.78125 -2.96875,-2.78125 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.2585 1,0.8125 l 0,2.4375 c 0,0.554 -0.41475,0.78125 -0.96875,0.78125 -0.554,0 -1.03125,-0.22725 -1.03125,-0.78125 l 0,-2.4375 c 0,-0.554 0.446,-0.8125 1,-0.8125 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36634"
+ width="1"
+ height="3.5"
+ x="277"
+ y="-10"
+ ry="0.5" />
+ <rect
+ y="-11"
+ x="278"
+ height="1"
+ width="1"
+ id="rect36636"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ mask="none"
+ id="g36638"
+ transform="translate(22.999998,120)">
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 279.46875,-11.53125 c -1.65264,0 -2.96875,1.128609 -2.96875,2.78125 l 0,2.5 c 0,1.6526411 1.34737,2.75 3,2.75 l 0.0625,0 c 1.65264,0 2.9375,-1.0973589 2.9375,-2.75 l 0,-2.5 c 0,-1.652641 -1.31612,-2.78125 -2.96875,-2.78125 l -0.0625,0 z M 279.5,-9.5 c 0.554,0 1,0.2585 1,0.8125 l 0,2.4375 c 0,0.554 -0.41475,0.78125 -0.96875,0.78125 -0.554,0 -1.03125,-0.22725 -1.03125,-0.78125 l 0,-2.4375 c 0,-0.554 0.446,-0.8125 1,-0.8125 z"
+ id="path36640"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-10"
+ x="277"
+ height="3.5"
+ width="1"
+ id="rect36642"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36644"
+ width="1"
+ height="1"
+ x="278"
+ y="-11" />
+ </g>
+ <g
+ id="g36646"
+ mask="none"
+ transform="translate(21.999998,-0.00494)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36648"
+ d="m 280.5,118.5 0,-4"
+ style="opacity:0.55;fill:none;stroke:#1a1a1a;stroke-width:2.79440284;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36650"
+ d="m 280.5,118.5 0,-4"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.55;fill:none;stroke:#1a1a1a;stroke-width:2.79440284;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 302.5,105.52631 0,-4"
+ id="path36652"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 302.5,105.52631 0,-4"
+ id="path36654"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="99"
+ x="302"
+ height="1"
+ width="1"
+ id="rect36664"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ y="297"
+ x="66"
+ height="26"
+ width="20"
+ id="rect36666"
+ style="opacity:0;fill:#ececec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,530,548)"
+ style="opacity:0.9;display:inline;enable-background:new"
+ id="g36668">
+ <rect
+ style="opacity:0;fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36670"
+ width="16"
+ height="16"
+ x="488"
+ y="29" />
+ <g
+ id="g36672">
+ <path
+ sodipodi:nodetypes="csccccccccsssc"
+ id="path36674"
+ d="m 500.5,34.5 0,5 c 0,1.666667 0.25,1.75 1,3.25 l -1.25,1.75 -1.75,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -1,0 C 491,43 490.5,42.416667 490.5,40.75 l 0,-6.25 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ style="fill:url(#linearGradient37545);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 495.5,30.375 c -2.28774,0 -4.125,1.837258 -4.125,4.125 l 0,6.25 c 0,0.74605 0.0978,1.170828 0.28125,1.625 0.13101,0.324408 0.38353,0.789244 0.625,1.25 l 0.0937,0 1.5,-1.5 a 0.87292083,0.87292083 0 0 1 1.25,0 l 1.375,1.375 1.375,-1.375 a 0.87292083,0.87292083 0 0 1 1.1875,-0.03125 l 1.375,1.21875 0.1875,-0.1875 0,-0.4375 C 500.24057,42.152166 499.91254,41.661109 499.78125,41.125 499.62101,40.470677 499.625,39.833334 499.625,39 l 0,-4.5 c 0,-2.287742 -1.83726,-4.125 -4.125,-4.125 z"
+ id="path36676"
+ style="fill:none;stroke:url(#linearGradient37547);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 495.5 29.5 C 492.74 29.5 490.5 31.74 490.5 34.5 L 490.5 40.75 C 490.5 42.416667 491 43 491.75 44.5 L 492.75 44.5 L 494.5 42.75 L 496.25 44.5 L 496.75 44.5 L 498.5 42.75 L 500.5 44.5 L 501.5 43.5 L 501.5 42.5 C 500.5 41.25 500.5 40.666667 500.5 39 L 500.5 34.5 C 500.5 31.74 498.26 29.5 495.5 29.5 z "
+ inkscape:radius="-0.87283355"
+ sodipodi:type="inkscape:offset" />
+ <g
+ style="opacity:0.25;fill:#000000"
+ id="g36678">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 493,43.75 c 0,-0.212963 0,-5.75 0,-5.75 l 1.5,4.472222 L 493,43.75 z"
+ id="path36681"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36683"
+ d="m 497,44 c 0,-0.203703 -1,-6 -1,-6 l 2,3.428571 0,1.714286 L 497,44 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,990,0.25)"
+ id="g36685"
+ style="opacity:0.7;fill:#ffffff">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36687"
+ d="m 493,43.75 c 0,-0.212963 1,-6 1,-6 l 1,5 -1,1 -1,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 497,43.75 c 0,-0.203703 0,-6 0,-6 l 2,5 -1,1 -1,0 z"
+ id="path36689"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 490,43.25 c 0,-0.212963 1.5,-6.25 1.5,-6.25 l 0.5,5.5 -2,0.75 z"
+ id="path36691"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 500.5,34.5 0,4.5 c 0,1.666667 0,2.25 1,3.5 l 0,1 -1,1 -2,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -0.5,0 C 491,43 490.5,43.166667 490.5,41.5 l 0,-7 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ id="path36693"
+ sodipodi:nodetypes="cscccccccccsssc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36695"
+ d="m 56,139 0,1 -1,0 0,1 2,0 0,-2 -1,0 z"
+ style="opacity:0.8;fill:url(#linearGradient37549);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:url(#linearGradient37551);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 51,139 0,2 2,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36697"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(47,571)"
+ id="g36699"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 67,7.75 0,7.25 -1,0 -1,-2 -1,0 0,1 2,5 2,2 7,0 2,-3.25 0,-4 L 76.5,13 76,13 76,14 75,14 75,12.75 74.25,12 73,12 l 0,2 -1,0 0,-2 -1,-1 -1,0 0,3 -1,0 L 69,7.75 68.37057,7 67.643297,7 67,7.75 z"
+ id="path36701"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36703"
+ width="16"
+ height="16"
+ x="63"
+ y="6" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ id="path36705"
+ d="m 67,7.75 0,7.25 -1,0 0,-1 -1,-1 -1,0 0,1 2,5 2,2 7,0 2,-3.25 0,-4 L 76.5,13 76,13 76,14 75,14 75,12.75 74.25,12 73,12 l 0,2 -1,0 0,-2 -1,-1 -1,0 0,3 -1,0 L 69,7.75 68.37057,7 67.643297,7 67,7.75 z"
+ style="fill:url(#linearGradient37553);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient37555);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69,17 0,3 1,0 0,-3 -1,0 z m 2,0 0,3 1,0 0,-3 -1,0 z m 2,0 0,3 1,0 0,-3 -1,0 z"
+ id="path36707"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="15"
+ x="66"
+ height="1"
+ width="1"
+ id="rect36709"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36711"
+ width="1"
+ height="1"
+ x="66"
+ y="16" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37557);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 74.09375,12.25 -0.625,0 0,1.75 c 0.0031,0.12523 -0.04536,0.246239 -0.133933,0.334817 C 73.246239,14.423395 73.12523,14.4718 73,14.46875 L 72.5,14.5 m -1.65625,-3.25 -0.375,0 0,2.75 c 0.0031,0.12523 -0.04536,0.246239 -0.133933,0.334817 C 70.246239,14.423395 70.12523,14.4718 70,14.46875 L 69.5,14.5 M 64.46875,13.46875 64.5,14 l 1.870938,4.629172 1.847812,1.902078 6.53125,0 1.78125,-2.875 0,-4 -0.0625,-0.125 0,0.46875 c 0.0031,0.12523 -0.04536,0.246239 -0.133933,0.334817 C 76.246239,14.423395 76.12523,14.4718 76,14.46875 L 75.5,14.5 m -7.3125,-7.03125 -0.3125,0 L 67.5,8 l 0,7"
+ id="path36713"
+ sodipodi:nodetypes="cccscccccscccccccccccscccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:url(#radialGradient37559);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 66,15 0,-1 -1,-1 -1,0 0,1 2,5 0,-4 z"
+ id="path36715"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36882"
+ transform="translate(-21,254)">
+ <rect
+ ry="0"
+ rx="0"
+ y="323"
+ x="257"
+ height="16"
+ width="16"
+ id="rect36884"
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36886"
+ style="fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(21,69)">
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36888"
+ width="1"
+ height="2"
+ x="236"
+ y="262" />
+ <rect
+ y="-239.00793"
+ x="260"
+ height="2.0079346"
+ width="1"
+ id="rect36890"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36892"
+ width="1"
+ height="2"
+ x="236"
+ y="266" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36894"
+ width="2"
+ height="1"
+ x="236.99207"
+ y="269" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36896"
+ width="1"
+ height="1.9920638"
+ x="269"
+ y="-242.99207" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36898"
+ width="1"
+ height="1.9920638"
+ x="269"
+ y="-246.99207" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36900"
+ width="1"
+ height="2"
+ x="246.99207"
+ y="266" />
+ </g>
+ <g
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g36902">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36904"
+ width="1"
+ height="2"
+ x="257"
+ y="-331" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36906"
+ width="1"
+ height="2"
+ x="257"
+ y="-335" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36908"
+ width="1"
+ height="2"
+ x="257"
+ y="-339" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36910"
+ width="1"
+ height="2.0079362"
+ x="338"
+ y="259.99207" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36912"
+ width="1"
+ height="2.0079362"
+ x="338"
+ y="263.99207" />
+ <rect
+ y="-339"
+ x="267.99207"
+ height="2"
+ width="1"
+ id="rect36914"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ </g>
+ <rect
+ y="330"
+ x="258"
+ height="8"
+ width="10"
+ id="rect36916"
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36918"
+ transform="translate(-205,313.97063)">
+ <rect
+ style="fill:url(#linearGradient37571);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36920"
+ width="12"
+ height="10"
+ x="465.5"
+ y="10.5"
+ ry="1.5909902"
+ rx="1.5909902" />
+ <path
+ style="fill:url(#linearGradient37573);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 465,13.40909 0,4.59375 c 0,0.56244 0.36784,0.99717 0.84375,0.99716 l 11.3125,0.01065 c 0.47591,0 0.84375,-0.43471 0.84375,-0.99716 l 0,-4.59375 c -0.31371,0.37073 -0.76923,0.59091 -1.25,0.59091 L 466.25,14 c -0.48077,0 -0.93629,-0.22018 -1.25,-0.59091 l 0,0 0,0 0,0 z"
+ id="path36922"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.98531502"
+ y="10.52937"
+ x="465.5"
+ height="1.9999996"
+ width="12"
+ id="rect36924"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.4762714" />
+ <rect
+ ry="1.3782184"
+ y="10.5"
+ x="465.5"
+ height="10"
+ width="12"
+ id="rect36926"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.3782184" />
+ <rect
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36928"
+ width="9.9998779"
+ height="7.999999"
+ x="466.5"
+ y="11.5"
+ ry="0.44196323"
+ rx="0.39062494" />
+ <g
+ transform="matrix(0.7547901,0,0,1,414.01868,-484.99999)"
+ id="g36930">
+ <path
+ transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36932"
+ style="fill:none;stroke:#999999;stroke-width:2.90780973;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.92082453;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 69.531013,495.51105 0,-0.50001 c 0,-0.276 0.890314,-0.5 1.987308,-0.5 1.096993,0 1.987307,0.224 1.987307,0.5 l 0,0.50001"
+ id="path36934"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="495.01105"
+ x="70.193451"
+ height="1"
+ width="2.6497409"
+ id="rect36936"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g36938"
+ transform="matrix(1,0,0,0.6666667,331,-319.00002)">
+ <rect
+ y="496.5"
+ x="143"
+ height="1.5"
+ width="2"
+ id="rect36940"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#radialGradient37575);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36942"
+ width="2"
+ height="1.5"
+ x="143"
+ y="496.5" />
+ </g>
+ <rect
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36944"
+ width="1"
+ height="1"
+ x="468"
+ y="13" />
+ <g
+ transform="translate(1.1408497e-7,0.5000446)"
+ id="g36946">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89240623;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36948"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.187982,0,0,1.0569758,379.83032,-513.21497)" />
+ <path
+ transform="matrix(1.3827154,0,0,1.4028327,364.1482,-688.72206)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36950"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:0.71801031;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient37578);stroke-width:1.11641002;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36952"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.987526,0,0,0.8124641,394.9733,-392.80617)" />
+ <path
+ transform="matrix(0.9848328,0,0,0.9992585,395.19018,-485.12778)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36954"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:0.80643582;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37580);stroke-width:1.69505489;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36956"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.591154,0,0,0.5887513,425.87219,-279.05319)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient37582);stroke-width:0.80110824;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36958"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9913883,0,0,1.0058976,394.67318,-488.46061)" />
+ <path
+ transform="matrix(0.6941559,0,0,0.6920597,417.67198,-331.15708)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36960"
+ style="opacity:0.7;fill:url(#radialGradient37584);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36962"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.1975308,0,0,0.1999991,456.0926,-84.399595)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient37586);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36964"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-0.6760501,-0.1575078,0.1570322,-0.6740085,446.07727,367.34791)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36966"
+ d="m 476.49997,11.941967 0,7.174103"
+ style="opacity:0.05;fill:none;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 258,330 0,8 1,0 0,-7 1,0 0,-1 -2,0 z"
+ id="path36968"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36970"
+ transform="translate(62.999998,254)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36972"
+ width="16"
+ height="16"
+ x="215"
+ y="-339"
+ transform="scale(1,-1)" />
+ <path
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220,324 0,1 -2,0 0,2 -1,0 0,2 -1,0 0,6 1,0 0,2 1,0 2,0 0,-1 1,0 0,-2 1,0 0,-2 1,0 0,-1 1,0 3,0 0,-1 1,0 1,0 0,-4 -1,0 0,-1 -1,0 0,-1 -3,0 -1,0 -1,0 -1,0 -1,0 z"
+ id="path36974"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g36976"
+ transform="translate(1,84)">
+ <g
+ transform="translate(5,-6.0000002e-7)"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ id="g36980" />
+ </g>
+ <g
+ id="g37010"
+ style="fill:#321900">
+ <rect
+ transform="scale(1,-1)"
+ y="-324"
+ x="223"
+ height="1"
+ width="2"
+ id="rect37012"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37014"
+ width="2"
+ height="1"
+ x="219"
+ y="-325" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37016"
+ width="1"
+ height="1"
+ x="324"
+ y="227"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="226"
+ x="323"
+ height="1"
+ width="1"
+ id="rect37018"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="229"
+ x="328"
+ height="1"
+ width="1"
+ id="rect37020"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37022"
+ width="1"
+ height="2"
+ x="216"
+ y="-329"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-337"
+ x="216"
+ height="2"
+ width="1"
+ id="rect37024"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37026"
+ width="1"
+ height="1"
+ x="220"
+ y="-337"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-338"
+ x="219"
+ height="1"
+ width="1"
+ id="rect37028"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37030"
+ width="1"
+ height="1"
+ x="221"
+ y="-334"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37032"
+ width="1"
+ height="2"
+ x="215"
+ y="-333"
+ transform="scale(1,-1)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="228"
+ x="325"
+ height="1"
+ width="1"
+ id="rect37034"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37036"
+ width="1"
+ height="1"
+ x="329"
+ y="228" />
+ <rect
+ transform="scale(1,-1)"
+ y="-333"
+ x="222"
+ height="1"
+ width="1"
+ id="rect37038"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g37040"
+ style="fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37042"
+ width="2"
+ height="1"
+ x="221"
+ y="-324" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37044"
+ width="1"
+ height="2"
+ x="323"
+ y="225"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37046"
+ width="1"
+ height="1"
+ x="329"
+ y="227" />
+ <rect
+ transform="scale(1,-1)"
+ y="-331"
+ x="215"
+ height="2"
+ width="1"
+ id="rect37048"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37050"
+ width="1"
+ height="2"
+ x="215"
+ y="-335"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37052"
+ width="2"
+ height="1"
+ x="217"
+ y="-338"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-336"
+ x="221"
+ height="2"
+ width="1"
+ id="rect37054"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-332"
+ x="222"
+ height="1"
+ width="1"
+ id="rect37056"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37058"
+ width="1"
+ height="1"
+ x="217"
+ y="-327"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-326"
+ x="218"
+ height="1"
+ width="1"
+ id="rect37060"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37062"
+ width="2"
+ height="1"
+ x="326"
+ y="229" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37064"
+ width="1"
+ height="1"
+ x="223"
+ y="-331" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ id="path37066"
+ d="m 220.9438,324.0562 0,1 6,0 0,-1 -6,0 z m 6,1 0,1 1,0 0,-1 -1,0 z m 1,1 0,1 1,0 0,-1 -1,0 z m -7,-1 -2,0 0,1 2,0 0,-1 z m -2,1 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,2 1,0 0,-2 z m -1,2 -1,0 0,6 1,0 0,-6 z m 0,5.75 0,2.25 1,0 0,-2 -1,-0.25 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:url(#linearGradient106628);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 287.75,590.75 1.75,-1.5 1.99177,3.7253 1.75,-1 L 291.5,588.5 l 2.5,0 -6.25,-6.25 z"
+ id="path45378-1-5-6-2"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 287.54419,581.36742 7,7.25 -3,0 1.69346,3.25845 -1.75,1 -1.69346,-3.50845 -2.25,2.25 z"
+ id="path17835-7-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 288.34375,583.75 0,5.75"
+ id="path17845-9-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g37068"
+ transform="translate(126,86)">
+ <rect
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37070"
+ width="16"
+ height="16"
+ x="173"
+ y="491" />
+ <g
+ id="g37072">
+ <g
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none"
+ id="g37074"
+ transform="translate(-63.000001,168)">
+ <g
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none"
+ id="g37076">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 243.5,336.5 0,-12"
+ id="path37078"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,325.5 3,3 3,-3"
+ id="path37080"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37082"
+ d="m 240.5,335.5 3,-3 3,3"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none"
+ transform="matrix(0,1,-1,0,574,87)"
+ id="g37084">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37086"
+ d="m 243.5,336.5 0,-12"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37088"
+ d="m 240.5,325.5 3,3 3,-3"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,335.5 3,-3 3,3"
+ id="path37090"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g37092"
+ style="stroke:#c8c8c8;stroke-opacity:1">
+ <g
+ id="g37094"
+ style="stroke:#c8c8c8;stroke-opacity:1">
+ <g
+ style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="g37096"
+ transform="translate(-63.000001,168)">
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 243.5,336.5 0,-12"
+ id="path37098"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,325.5 3,3 3,-3"
+ id="path37100"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37102"
+ d="m 240.5,335.5 3,-3 3,3"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ transform="matrix(0,1,-1,0,511,255)"
+ id="g37104">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37106"
+ d="m 243.5,336.5 0,-12"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37108"
+ d="m 240.5,325.5 3,3 3,-3"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 240.5,335.5 3,-3 3,3"
+ id="path37110"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ transform="matrix(0.625,0,0,0.625,15.1875,291.9375)"
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37112"
+ sodipodi:cx="264.5"
+ sodipodi:cy="330.5"
+ sodipodi:rx="2"
+ sodipodi:ry="2"
+ d="m 266.5,330.5 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" />
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 175.75,495.75 175.5,495.5"
+ id="path37114"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37116"
+ d="m 177.5,493.5 0.25,0.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 180.5,492.25 0,2.5"
+ id="path37118"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 177,500 -1.75,1.75"
+ id="path37120"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37122"
+ d="m 174.25,498.5 2.5,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37124"
+ d="m 179.75,501.25 -2.5,2.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 185.75,495.25 -2.5,2.5"
+ id="path37126"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37128"
+ d="M 183.75,493.25 182,495"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 266.5,330.5 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z"
+ sodipodi:ry="2"
+ sodipodi:rx="2"
+ sodipodi:cy="330.5"
+ sodipodi:cx="264.5"
+ id="path37130"
+ style="fill:none;stroke:url(#linearGradient37588);stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.625,0,0,0.625,15.1875,291.9375)" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37132"
+ d="m 182.5,502.5 0,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 184.5,500.5 0,0"
+ id="path37134"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 185.5,498.5 1.25,0"
+ id="path37136"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37138"
+ transform="translate(147.01612,401.00818)">
+ <rect
+ transform="scale(1,-1)"
+ y="-87"
+ x="256.98419"
+ height="16"
+ width="16"
+ id="rect37140"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 266.48388,77.49182 c -1,0 -2,10e-6 -3,2e-5 0,0.99999 0,1.99999 0,2.99998 1,0 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 z"
+ id="path37142"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37144"
+ d="m 266.48388,83.49182 c -1,0 -2,10e-6 -3,10e-6 0,1 0,2 0,2.99999 1,-1e-5 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 261.48419,74.5 c -1,0 -2,1e-5 -3,1e-5 0,1 0,2 0,2.99999 1,-1e-5 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path37146"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 261.48419,80.5 c -1,0 -2,1e-5 -3,1e-5 0,1 0,2 0,2.99999 1,-1e-5 2,-1e-5 3,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path37148"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-189.01581,-315)"
+ style="opacity:0.55"
+ id="g37150">
+ <path
+ id="path37152"
+ d="m 460.50726,389.48364 c -1.00252,0 -2.00505,1e-5 -3.00757,1e-5 0,1.00272 0,2.00544 0,3.00817 1.00252,0 2.00505,-1e-5 3.00757,-1e-5 0,-1.00273 0,-2.00545 0,-3.00817 z"
+ style="fill:none;stroke:#000000;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 460.51514,395.48364 c -1.00252,0 -2.00505,1e-5 -3.00757,1e-5 0,1.00272 0,2.00544 0,3.00817 1.00252,0 2.00505,-1e-5 3.00757,-1e-5 0,-1.00273 0,-2.00545 0,-3.00817 z"
+ id="path37154"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 455.5,386.5 c -1.00252,0 -2.00505,10e-6 -3.00757,10e-6 0,1.00272 0,2.00544 0,3.00817 1.00252,0 2.00505,-10e-6 3.00757,-10e-6 0,-1.00273 0,-2.00545 0,-3.00817 z"
+ id="path37156"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-189.01581,-315)"
+ style="opacity:0.55"
+ id="g37158">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 457.99938,389.98364 c 0.6694,0 1.33879,1e-5 2.00819,1e-5 0,0.66939 0,1.33877 0,2.00817 -0.6694,0 -1.33879,-1e-5 -2.00819,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path37160"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path37162"
+ d="m 458.00726,395.98364 c 0.6694,0 1.33879,1e-5 2.00819,1e-5 0,0.66939 0,1.33877 0,2.00817 -0.6694,0 -1.33879,-1e-5 -2.00819,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path37164"
+ d="m 452.99212,387 c 0.6694,0 1.33879,10e-6 2.00819,10e-6 0,0.66939 0,1.33877 0,2.00817 -0.6694,0 -1.33879,-10e-6 -2.00819,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(420,44)"
+ id="g37166">
+ <rect
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37168"
+ width="16.000006"
+ height="16.000002"
+ x="26.016129"
+ y="428" />
+ <rect
+ y="428"
+ x="26"
+ height="16"
+ width="16"
+ id="rect37170"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1.0004639,0,0,0.9963165,-237.11238,367.28985)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g37172"
+ style="display:inline">
+ <path
+ transform="matrix(0.81218,0,0,0.815735,163.7897,-27.2907)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="fill:#724c4c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10749674;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37174"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37176"
+ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.16363633;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.7480284,0,0,0.7480284,172.26025,-19.267349)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:url(#linearGradient37590);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37178"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.7478104,0,0,0.7510504,172.29077,-19.598754)" />
+ <path
+ style="fill:url(#linearGradient37592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269.98748,62.965763 c -1.39411,0.455357 -2.67784,0.634788 -4.24803,3.011091 l 2.24896,0 1.99907,-3.011091 0,0 0,0 0,0 z m 0.99954,0 0,3.011091 2.99861,0 -1.99908,-3.011091 -0.99953,0 z m 2.99861,3.011091 0.99953,3.011091 1.99907,0 c 0.006,-0.929403 -0.1914,-1.917894 -0.74965,-3.011091 l -2.24895,0 0,0 0,0 0,0 z m 0.99953,3.011091 -3.99814,0 0,3.011092 2.49884,0 1.4993,-3.011092 z m -3.99814,3.011092 -2.99861,0 1.99907,3.011091 0.99954,0 0,-3.011091 0,0 0,0 0,0 z m -2.99861,0 -0.99954,-3.011092 -1.99907,0 c -0.006,0.929404 0.1914,1.917895 0.74965,3.011092 l 2.24896,0 0,0 0,0 0,0 z m -0.99954,-3.011092 3.99815,0 0,-3.011091 -2.49884,0 -1.49931,3.011091 0,0 0,0 0,0 z m 7.24312,3.011092 -1.85125,3.011091 c 1.3675,-0.485137 2.19971,-0.728674 3.85384,-3.011091 l -2.00259,0 z"
+ id="path37180"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path37182"
+ d="m 274.00069,72.011668 0.005,0.97479 -0.99045,0.01431 -0.0223,1.019377 -0.481,0.837285 c 0.77072,-0.321774 2.72643,-1.067855 3.69499,-2.816464 l -2.20604,-0.0293 -2e-4,2e-6 0,0 0,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.749782,0,0,0.752489,172.03052,-19.77379)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37185"
+ style="opacity:0.4;fill:url(#linearGradient37594);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.7010701,0,0,0.7040938,178.4346,-14.083074)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37596);stroke-width:1.14049816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path37187"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#aaccff;stroke-width:0;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 268.98793,64.973163 0,0.407752 -0.93706,0 0,0.595945 -0.56224,0 0,1.003697 -0.49977,0 0,1.505546 0.99953,0 0,-1.505546 0.4373,0 0,-0.595945 0.56224,0 0,-0.407752 1.53054,0 0,-1.003697 -1.53054,0 z"
+ id="path37189"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-499.98389,503.95862)"
+ style="display:inline;enable-background:new"
+ id="g37229">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37231"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:url(#radialGradient37608);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ id="path37233"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path37235"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ style="fill:none;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient37610);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.37109,1.875 2.37891,-2.375 -1.5,-2 z"
+ id="path37237"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b0000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 520.48389,-31.45862 -6,6.75 2,2.25 4,-4"
+ id="path37239"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37241"
+ d="m 520.98389,-31.95862 -6.75,7.75 1.75,1.75 5,-4.5 0,-5 z"
+ style="fill:url(#linearGradient37612);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 513.48389,-22.45862 7,-8.25"
+ id="path37243"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient37614);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ id="path37245"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37307"
+ transform="translate(-42,86)">
+ <g
+ id="g37309"
+ transform="translate(209,0)">
+ <rect
+ rx="0.015625"
+ y="393"
+ x="222"
+ height="9"
+ width="9"
+ id="rect37311"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.015625" />
+ <g
+ id="g37313"
+ transform="matrix(0.4224039,0.424791,0.4224039,-0.424791,74.64489,479.288)"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient37636);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.33543694;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 85.554034,278.09107 c 1.182038,0.59351 1.745531,1.60418 1.940766,2.40894 l 0.0052,0.2482 c 0,0.75 -0.75,1.75 -1.5,1.75 -0.75,0 -1.16648,-0.20985 -1.91648,-1.20806 -0.5,0 -0.676716,3.3e-4 -1.176716,3.3e-4 -0.75,0.99821 -1.156804,1.20773 -1.906804,1.20773 -0.75,0 -1.5,-1 -1.5,-1.75 l -0.0052,-0.2482 c 0.217441,-0.78256 0.749208,-1.83372 1.92792,-2.42058 l 0.07208,-4.57942 c -0.335564,-0.0958 -0.633693,-0.23081 -0.890995,-0.39497 -0.637372,-0.40663 -1.024226,-0.99226 -1.109005,-1.60503 l 0.0052,-0.2518 c 0,-0.75 0.68844,-1.71861 1.5,-1.75 0.71584,-0.0277 1.25,0 2,1.00179 l 1,0 c 0.749447,-1.00234 1.174653,-1.09387 2,-1.00179 0.745329,0.0832 1.5,1 1.5,1.75 l -0.0052,0.2518 c -0.122391,0.38782 -0.722942,1.77706 -2,2 l 0.05923,4.59106 4e-6,0 0,0 0,0 z"
+ id="path37315"
+ sodipodi:nodetypes="ccczcczccccsscsccscscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37317"
+ d="m 82.886207,273.9157 -0.02165,3.97041"
+ style="fill:none;stroke:#ffffff;stroke-width:1.66929841px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path37319"
+ d="M 82.4948,279.50001 C 80,278.75 79.891731,281.54098 81.141731,281.29098"
+ style="fill:none;stroke:#ffffff;stroke-width:0.83464772;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.83464754;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 82.320782,273.05364 c -2.405243,-1.28815 -1.663086,-3.01898 -0.56905,-2.28347"
+ id="path37321"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(315,0)"
+ id="g37323"
+ style="display:inline;enable-background:new">
+ <rect
+ ry="0.019097222"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37325"
+ width="11"
+ height="11"
+ x="110"
+ y="386"
+ rx="0.019097222" />
+ <g
+ id="g37327">
+ <path
+ id="path37329"
+ d="m 116.53125,386.5 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.28156 0.12508,0.53133 0.3125,0.71875 L 113,392 c -0.18742,-0.18742 -0.46844,-0.5 -0.75,-0.5 l -0.75,0 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.56312 0.46813,1.03125 1.03125,1.03125 l 0.9375,0 c 0.0103,0 0.021,3e-4 0.0312,0 -3e-4,0.0102 0,0.021 0,0.0312 l 0,0.9375 c 0,0.56312 0.46813,1.03126 1.03125,1.03125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.28156 -0.10164,-0.53133 -0.28125,-0.71875 l 2.625,-2.625 c 0.18742,0.18742 0.43719,0.3125 0.71875,0.3125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.56312 -0.43688,-1.03125 -1,-1.03125 l -0.96875,0 c -0.0103,0 -0.021,-3e-4 -0.0312,0 3e-4,-0.0102 0,-0.021 0,-0.0312 l 0,-0.9375 c 0,-0.56312 -0.46813,-1.03125 -1.03125,-1.03125 l -0.9375,0 z"
+ style="fill:url(#linearGradient37638);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccccccccsccccccccccccccscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37331"
+ d="m 111.5,393.5 0,-0.75 0.25,-0.25 1.75,0 3,-3 0,-1.75 0.25,-0.25 0.75,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 118.75,389.5 0.75,0 m -6,6 0,-0.75"
+ id="path37333"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37335"
+ width="1"
+ height="1"
+ x="114"
+ y="393" />
+ <rect
+ y="390"
+ x="117"
+ height="1"
+ width="1"
+ id="rect37337"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37339"
+ transform="translate(-84,65)">
+ <rect
+ transform="scale(-1,-1)"
+ y="-423"
+ x="-525"
+ height="16"
+ width="16"
+ id="rect37341"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g37343"
+ transform="translate(205.00003,252.00003)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\not used yet.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ transform="matrix(0.767131,0,0,0.788662,393.6565,37.08664)"
+ style="fill:#000000;fill-opacity:1"
+ id="g37345"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="matrix(0.693332,0,0,0.663699,390.0934,62.34418)"
+ id="g37347"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g37350"
+ style="opacity:0.3" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 304.99997,158.99997 c 0.66669,0 1.33337,1e-5 2.00006,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.66669,0 -1.33337,-1e-5 -2.00006,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path37352"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37354"
+ style="fill:none"
+ transform="translate(141,63)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 163.5,95.5 c 1,5e-6 2,1.1e-5 3,1.6e-5 0,0.999995 0,1.99999 0,2.999984 -1,-5e-6 -2,-1.1e-5 -3,-1.6e-5 0,-0.999994 0,-1.999989 0,-2.999984 z"
+ id="path37356"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37358"
+ d="m 163.5,101.5 c 1,1e-5 2,1e-5 3,2e-5 0,0.99999 0,1.99999 0,2.99998 -1,-1e-5 -2,-1e-5 -3,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 z"
+ style="fill:none;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265"
+ d="m 168.49997,92.49997 c 1,5e-6 2,1.1e-5 3,1.6e-5 0,0.999995 0,1.999995 0,2.999985 -1,-1e-5 -2,-1e-5 -3,-2e-5 0,-0.99999 0,-1.999986 0,-2.999981 l 0,0 0,0 0,0 z"
+ id="path37360"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path37362"
+ d="m 304.99997,164.99997 c 0.66669,0 1.33337,1e-5 2.00006,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.66669,0 -1.33337,-1e-5 -2.00006,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 309.99994,155.99994 c 0.66669,0 1.33337,1e-5 2.00006,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.66669,0 -1.33337,-1e-5 -2.00006,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path37364"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g37366"
+ transform="matrix(0.7614057,0,0,0.7675903,253.76942,219.40377)">
+ <g
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)"
+ id="g37368">
+ <path
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)"
+ sodipodi:type="arc"
+ style="fill:#ff5a19;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37370"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-2.8145849"
+ inkscape:transform-center-y="-3.2499984" />
+ <path
+ inkscape:transform-center-y="1.6729808e-05"
+ inkscape:transform-center-x="-3.2630798"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37372"
+ style="fill:#ad2f94;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)" />
+ <path
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)"
+ sodipodi:type="arc"
+ style="fill:#0060f0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37374"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-2.8145756"
+ inkscape:transform-center-y="3.2500173" />
+ <path
+ inkscape:transform-center-y="3.249994"
+ inkscape:transform-center-x="2.8145978"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37376"
+ style="fill:#00d4aa;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)" />
+ <path
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)"
+ sodipodi:type="arc"
+ style="fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path37378"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="3.2630773" />
+ <path
+ inkscape:transform-center-x="2.8145777"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37380"
+ style="fill:#ffbf0e;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ inkscape:transform-center-y="-3.2500006" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37382"
+ style="fill:none;stroke:#000000;stroke-width:1.29430985;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)" />
+ <path
+ transform="matrix(0.6594197,0,0,0.6608114,261.96791,180.02435)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37640);stroke-width:1.98156261;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path37384"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g37816"
+ transform="translate(0,2)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37759"
+ width="16"
+ height="16"
+ x="173"
+ y="617" />
+ <g
+ style="display:inline"
+ id="g37761"
+ transform="translate(-290,397)">
+ <g
+ id="g37779">
+ <g
+ id="g37781"
+ style="opacity:0.85"
+ transform="translate(20.029029,0)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path37783"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 444.54256,228.5 11.66489,0 0,0"
+ id="path37785"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g37787"
+ transform="translate(20.029029,0)">
+ <path
+ id="path37789"
+ d="m 444.47097,228.5 13,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path37791"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-58,340)"
+ id="g41151"
+ style="display:inline;enable-background:new">
+ <rect
+ y="48"
+ x="63"
+ height="16"
+ width="16"
+ id="rect41153"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1.0003553,0,0,0.9995949,18.983834,-41.953346)"
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g41155">
+ <rect
+ y="91.491928"
+ x="45.5"
+ height="13.003749"
+ width="12.995382"
+ id="rect41157"
+ style="fill:url(#linearGradient42322);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41159"
+ d="m 46.49945,103.49527 0,-11.002747 10.996287,0 0,11.002747 -10.996287,0 z"
+ style="fill:none;stroke:url(#linearGradient42324);stroke-width:1.0000248px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-15,340)"
+ id="g41161"
+ style="display:inline;enable-background:new">
+ <rect
+ y="48"
+ x="83"
+ height="16"
+ width="16"
+ id="rect41163"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.1658027,0,0,1.1657997,-59.289717,-204.05607)"
+ id="g41165"
+ style="display:inline">
+ <path
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23686147;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41167"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41169"
+ style="opacity:0.8;fill:url(#linearGradient42326);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ id="path41171"
+ style="fill:none;stroke:url(#linearGradient42328);stroke-width:0.51466751;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ d="m 134.27086,222.67786 c -0.8523,1.03645 -2.40069,1.91195 -5.35869,1.91195 -2.92931,0 -4.50028,-0.8755 -5.35806,-1.88283 m 5.3611,5.72324 c -1.3021,0 -2.35888,-2.40136 -2.35888,-5.36019 0,-2.95882 1.05678,-5.36019 2.35888,-5.36019 1.30211,0 2.35889,2.40137 2.35889,5.36019 0,2.9364 -1.03866,5.32486 -2.33081,5.35981"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41173"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42330);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41175"
+ transform="translate(-21,359)">
+ <rect
+ y="29"
+ x="47"
+ height="16"
+ width="16"
+ id="rect41177"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41179"
+ transform="translate(116,-325)">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -55,358.25 -6,-2.25 -6,2.25 0,7.5 6,3.25 6,-3.25 0,-7.5 z"
+ id="path41181"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:url(#linearGradient42332);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -55,365.75 0,-7.5 -6,-2.25 8.34e-4,13.04035 L -55,365.75 z"
+ id="path41183"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path41185"
+ d="m -67,365.75 0,-7.5 6,-2.25 8.34e-4,13.04035 L -67,365.75 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -67,358.25 6,-2.25 6,2.25 -6,2.75 -6,-2.75 z"
+ id="path41187"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41189"
+ d="M -66.499841,365.52276 -66.5,358.5 l 5.5,-2 5.5,2 0,7 -5.5,3 -5.499841,-2.97724 z"
+ style="fill:none;stroke:url(#linearGradient42334);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(3,417)"
+ id="g41191">
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41193"
+ width="16"
+ height="16"
+ x="128"
+ y="-29" />
+ <g
+ id="g41195">
+ <path
+ id="path41197"
+ style="fill:#999999;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 140,-21 c 1.125,1 3.5,0.25 3.5,-1 0,-1.5 0.47443,-1.637992 -2,-1.5 -0.1033,1.43128 -0.66697,1.819388 -1.5,2.5 z"
+ sodipodi:nodetypes="cscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscc"
+ d="m 132,-21 c -1.125,1 -3.5,0.25 -3.5,-1 0,-1.5 -0.47443,-1.637992 2,-1.5 0.1033,1.43128 0.66697,1.819388 1.5,2.5 z"
+ style="fill:#e6e6e6;fill-rule:evenodd;stroke:#000000;stroke-width:0.55000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path41199"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccsccccccc"
+ d="m 135.75,-25.5 -1.25,-2 -0.75,0 -3.25,2.75 0,1.25 c 0.15379,2.182132 1.3678,1.901463 3,4 l 0,4.5 c 0,1.5 1.5,1.5 2.5,1.5 1,0 2.5,0 2.5,-1.5 l 0,-4.5 c 1.62605,-2.090636 2.83897,-1.844587 3,-4 l 0,-1.25 -3.25,-2.75 -0.75,0 -1.25,2"
+ style="fill:url(#linearGradient42336);fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ id="path41201"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-16"
+ x="135"
+ height="1"
+ width="2"
+ id="rect41203"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="1"
+ style="fill:url(#linearGradient42338);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41205"
+ width="2.75"
+ height="2"
+ x="135"
+ y="-21"
+ rx="1" />
+ <rect
+ y="-21"
+ x="135"
+ height="1"
+ width="2"
+ id="rect41207"
+ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="translate(0.5,-0.46875)"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path41209"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42340);stroke-width:0.93034029;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path41211"
+ sodipodi:cx="133"
+ sodipodi:cy="-23"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(1.2143583,0,0,1.1512108,-28.054112,2.9290602)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path41213"
+ sodipodi:cx="133"
+ sodipodi:cy="-23"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(0.8392157,0,0,0.8382979,21.884318,-4.2140957)" />
+ <rect
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41215"
+ width="2"
+ height="1"
+ x="135"
+ y="-15" />
+ <path
+ id="path41217"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 131.88556,-21.103144 c 0.4583,0.371362 1.00745,1.072735 1.61444,1.853144 l 0,3.75 c 0,1.5 1.5,2 2.5,2 1,0 2.5,-0.5 2.5,-2 l 0,-3.75 c 0.64842,-0.833678 1.23114,-1.545786 1.70766,-1.936772 M 130.5,-23.5 l 0,-1.25 3,-2.75 1,0 1.25,1.75 0.5,0 1.25,-1.75 1,0 3,2.75 0,1.25"
+ sodipodi:nodetypes="ccccccccccccccccs"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2116904,0,0,1.1282344,-22.693138,2.3776257)"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path41219"
+ style="fill:none;stroke:url(#linearGradient42342);stroke-width:0.94079971;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.8392157,0,0,0.8382979,26.893134,-4.2140957)"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="-23"
+ sodipodi:cx="133"
+ id="path41221"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41223"
+ d="M 136.75,-24.75 138,-26.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 129.25,-22.25 0.5,-0.5"
+ id="path41225"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path41227"
+ d="m 142.75,-22.5 -0.25,-0.25"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41229"
+ transform="translate(169,365)">
+ <rect
+ y="23"
+ x="-80"
+ height="16"
+ width="16"
+ id="rect41231"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41233"
+ d="m -72,23.5 -1.5,4 8,0 0,-0.25 -6.5,-3.75 z"
+ style="fill:#ececec;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41235"
+ d="m -73.5,27.5 3,7 5,-7 -8,0 z"
+ style="fill:#c3c3c3;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41237"
+ d="m -65.5,27.5 -5,7 5,0 0,-7 z"
+ style="fill:#666666;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41239"
+ d="m -70.5,34.5 -1.5,4 6.5,-3.75 0,-0.25 -5,0"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41241"
+ d="m -78.5,34.5 0,0.25 6.5,3.75 1.5,-4 -8,0 z"
+ style="fill:#b3b3b3;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41243"
+ d="m -78.5,27.5 0,-0.25 6.5,-3.75 -1.5,4 -5,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41245"
+ d="m -73.5,27.5 -5,0 0,7 5,-7 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41247"
+ d="m -78.5,34.5 8,0 -3,-7 -5,7 z"
+ style="fill:#f2f2f2;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="star"
+ style="fill:none;stroke:#000000;stroke-width:0.76889962;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path41249"
+ sodipodi:sides="6"
+ sodipodi:cx="-72"
+ sodipodi:cy="31"
+ sodipodi:r1="7.2111025"
+ sodipodi:r2="6.244998"
+ sodipodi:arg1="0.52359878"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M -65.755002,34.605551 -72,38.211102 l -6.244998,-3.605551 0,-7.211102 L -72,23.788898 l 6.244998,3.605551 z"
+ transform="matrix(1.040833,0,0,1.0400629,2.9399768,-1.241949)" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path41251"
+ style="fill:none;stroke:url(#linearGradient42344);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -78.5,27.5 13,0 m -7,-3 -1,3 m -5,7 12.75,0 m -12.75,0 5,-6.75 3,6.75 5,-7 m -5,7 -1,3"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.8807051,0,0,0.9013876,-8.5892309,3.0569843)"
+ d="M -65.755002,34.605551 -72,38.211102 l -6.244998,-3.605551 0,-7.211102 L -72,23.788898 l 6.244998,3.605551 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="true"
+ sodipodi:arg2="1.0471976"
+ sodipodi:arg1="0.52359878"
+ sodipodi:r2="6.244998"
+ sodipodi:r1="7.2111025"
+ sodipodi:cy="31"
+ sodipodi:cx="-72"
+ sodipodi:sides="6"
+ id="path41253"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42346);stroke-width:1.12235165;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="star" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41255"
+ transform="translate(231,348)">
+ <rect
+ y="40"
+ x="-121"
+ height="16"
+ width="16"
+ id="rect41257"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(1.0003553,0,0,0.9995949,-165.01617,-49.953346)"
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g41259">
+ <rect
+ y="92.490814"
+ x="46.499645"
+ height="12.004883"
+ width="11.995742"
+ id="rect41261"
+ style="fill:url(#linearGradient42348);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80001998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41263"
+ d="m 47.49929,95.49203 0,-2.000811 1.999291,3e-6 0,2.000811 -1.999291,-3e-6 z"
+ style="fill:none;stroke:url(#linearGradient42350);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient42352);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 47.49929,99.493651 0,-1.999102 1.999291,-4e-6 0,1.999102 -1.999291,4e-6 z"
+ id="path41265"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41267"
+ d="m 47.49929,103.49527 0,-1.9991 1.999291,0 0,1.9991 -1.999291,0 z"
+ style="fill:none;stroke:url(#linearGradient42354);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient42356);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 51.497871,103.49527 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ id="path41269"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41271"
+ d="m 51.497869,99.49194 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ style="fill:none;stroke:url(#linearGradient42358);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient42360);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 51.497868,95.49203 1e-6,-2.000811 1.99929,0 -1e-6,2.000811 -1.99929,0 z"
+ id="path41273"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41275"
+ d="m 55.496451,103.49527 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ style="fill:none;stroke:url(#linearGradient42362);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:url(#linearGradient42364);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 55.496449,99.49194 0,-1.9991 1.99929,0 0,1.9991 -1.99929,0 z"
+ id="path41277"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path41279"
+ d="m 55.496448,95.49203 0,-2.000811 1.99929,0 0,2.000811 -1.99929,0 z"
+ style="fill:none;stroke:url(#linearGradient42366);stroke-width:1.00002491px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path41281"
+ style="fill:none;stroke:url(#linearGradient42368);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -110.5,43 0,11 m -4,-11 0,11 m 7.5,-3.5 -11,0 m 11,-4 -11,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41283"
+ transform="translate(275,332)">
+ <rect
+ y="56"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41285"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41287"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23034608;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8124999,0,0,0.813059,-327.25,-31.946343)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42370);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path41289"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.7451143,0.08386971,-0.08492794,0.7396793,-308.33359,-34.308811)" />
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-310.55192,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42372);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41291"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41293"
+ style="fill:none;stroke:url(#linearGradient42374);stroke-width:1.78040731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5610858,0,0,0.5622541,-294.05201,-2.3458915)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41295"
+ transform="translate(380,233)">
+ <rect
+ y="155"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41297"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41299"
+ d="m -220,156.5 c -3.036,0 -5.49999,1.12 -5.49999,2.5 l -1e-5,9 c 0,1.38 2.46399,2.5 5.49999,2.5 3.036,0 5.5,-1.12 5.5,-2.5 l 1e-5,-9 c 0,-1.38 -2.464,-2.5 -5.5,-2.5 z"
+ style="fill:url(#linearGradient42376);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient42378);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient42380);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -215.49145,159.5 c 0,1 -1.5,2 -4.50855,2 -3.00854,0 -4.49145,-1 -4.49145,-2 0,-1.5 2.25,-2.25 4.5,-2.25 2.25,0 4.5,0.75 4.5,2.25 z"
+ id="path41301"
+ sodipodi:nodetypes="czszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path41303"
+ d="m -214.99565,159.99149 c 0,1.12926 -1.66739,2.25851 -5.01168,2.25851 -3.34426,0 -4.99267,-1.12925 -4.99267,-2.25851"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient42382);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -220,156.5 c -3.49999,0 -5.49999,1.12 -5.49999,2.5 l -1e-5,8.5 c 0,2 2.46399,3 5.49999,3 3.036,0 5.50001,-1 5.50001,-3 l 0,-8.5 c 0,-1.38 -1.99999,-2.5 -5.5,-2.5 z"
+ id="path41305"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42384);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -224.5,160.5 0,6.5 c 0,0.9838 0.64285,2.5 4.5,2.5 3.85714,0 4.5,-1.5162 4.5,-2.5 l 0,-6.5"
+ id="path41307"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41309"
+ transform="translate(401,212)">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41311"
+ width="16"
+ height="16"
+ x="-228"
+ y="176" />
+ <path
+ sodipodi:nodetypes="cssscccscc"
+ id="path41313"
+ d="m -220,178.5 c -4.14,0 -7.40235,2.464 -7.40234,5.5 0,3.036 3.26234,5.5 7.40234,5.5 4.14,0 7.40234,-2.464 7.40234,-5.5 0,-3.036 -3.26233,-5.50001 -7.40234,-5.5 z m 0,4 c 1.2993,0 2.42742,0.39879 3.03125,1 -0.60383,0.60121 -1.73196,1 -3.03125,1 -1.29929,0 -2.42742,-0.39879 -3.03125,-1 0.60383,-0.60121 1.73196,-1 3.03125,-1 z"
+ style="fill:url(#linearGradient42386);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsscc"
+ id="path41315"
+ d="m -214.625,180.4375 c 1.5822,4.85564 -3.15377,7.27675 -11.84375,6.21875 l 0,0.0312 c 1.25689,1.67541 3.66207,2.8125 6.46875,2.8125 4.14,0 7.40625,-2.464 7.40625,-5.5 0,-1.34213 -0.64966,-2.57614 -1.71875,-3.53125 -0.10326,-0.0119 -0.20204,-0.024 -0.3125,-0.0312 z"
+ style="opacity:0.6;fill:url(#radialGradient42388);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -223.375,183.45313 c 1.90631,-1.46639 4.08905,-1.44306 6.1875,-0.53125 L -217,182.76563 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ id="path41317"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41319"
+ d="m -223.375,183.65625 0.5,-0.0312 c -0.0509,-0.0426 -0.11109,-0.08 -0.15625,-0.125 0.60383,-0.60121 1.73196,-1 3.03125,-1 0.99575,0 1.89552,0.24495 2.53125,0.625 L -217,182.96875 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ style="opacity:0.6;fill:url(#radialGradient42390);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42392);stroke-width:0.5962854;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path41321"
+ sodipodi:cx="-220"
+ sodipodi:cy="40.5"
+ sodipodi:rx="6.5"
+ sodipodi:ry="2.5"
+ d="m -213.5,40.5 a 6.5,2.5 0 1 1 -13,0 6.5,2.5 0 1 1 13,0 z"
+ transform="matrix(0.9999986,0,0,1.799999,-2.971883e-4,111.10004)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41323"
+ transform="translate(422,192)">
+ <rect
+ y="196"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41325"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccssscc"
+ id="path41327"
+ d="m -220,196.70312 -6.24219,10.18714 c -0.17094,0.32797 -0.25781,0.44407 -0.25781,0.85974 0,2.25 2.96003,3.75 6.5,3.75 3.53998,0 6.5,-1.5 6.5,-3.75 0,-0.41567 -0.0869,-0.53177 -0.2578,-0.85974 L -220,196.70312 z"
+ style="fill:url(#radialGradient42394);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42396);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -220,198.75 -5.29067,8.34531 c -0.1388,0.26737 -0.20933,0.56583 -0.20933,0.90469 0,1.3338 2.63213,2.56728 5.50644,2.56728 2.87432,0 5.49356,-1.23348 5.49356,-2.56728 0,-0.33886 -0.0706,-0.63732 -0.20932,-0.90469 L -220,198.75 z"
+ id="path41329"
+ sodipodi:nodetypes="ccssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.05;fill:none;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -226.5,208 c 0,-1.63609 2.96003,-3.5 6.5,-3.5 3.53998,0 6.5,1.75 6.5,3.5"
+ id="path41331"
+ sodipodi:nodetypes="css"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41333"
+ transform="translate(472,230)">
+ <rect
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41335"
+ width="16"
+ height="16"
+ x="-278"
+ y="137" />
+ <g
+ transform="translate(-22,0)"
+ id="g41337">
+ <path
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ d="m -243.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ id="path41339"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41341"
+ d="m -255.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41343"
+ style="opacity:0.7">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -252.25,139.5 8.5,0"
+ id="path41345"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41347"
+ d="m -252,139.5 8,0"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -254.5,139.5 0,-1 1,0"
+ id="path41349"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41351"
+ d="m -242.5,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g41353"
+ transform="translate(-327,-164)">
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="312.5"
+ x="52.5"
+ height="3"
+ width="2.9998772"
+ id="rect41355"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 54,314.25 c 3.75,1.75 8.5,2.36379 8.5,-2 0,-3 -3.5,-6.25 -5.5,-8.25"
+ id="path41357"
+ sodipodi:nodetypes="csc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 54,314.25 c 3.5,1.75 8.5,2.36741 8.5,-2 0,-3 -3.5,-6.25 -5.5,-8.25"
+ id="path41359"
+ sodipodi:nodetypes="csc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41361"
+ width="2.9998772"
+ height="3"
+ x="55.500122"
+ y="302.5"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="csc"
+ id="path41363"
+ d="m 54,314.25 c 3.5,1.75 8.5,2.33285 8.5,-2 0,-3 -3.5,-6.25 -5.5,-8.25"
+ style="fill:none;stroke:url(#linearGradient42398);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41365"
+ d="m 55,313 c -0.67541,0 -1.35081,10e-6 -2.02623,10e-6 0,0.66666 0,1.33332 0,1.99999 0.67542,0 1.35082,-10e-6 2.02623,-10e-6 0,-0.66666 0,-1.33333 0,-1.99999 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 58,303 c -0.666663,0 -1.333327,10e-6 -2,10e-6 0,0.66667 0,1.33332 0,1.99999 0.666673,0 1.333337,-10e-6 2,-10e-6 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path41367"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:#ececec;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 56.499999,304.5 0,-1 1,0"
+ id="path41369"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41371"
+ d="m 53.5,314.5 0,-1 1,0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41373"
+ d="m 56,315.66293 c -0.32001,0 -0.64002,-1e-5 -0.96003,-1e-5 0,-0.55431 0,-1.1086 0,-1.66292 0.32001,0 0.64002,10e-6 0.96003,10e-6 0,0.55431 0,1.10861 0,1.66292 z"
+ style="opacity:0.15;fill:#4b4b4b;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41375"
+ d="m 59,306 c -0.333333,0 -0.666667,-10e-6 -1,-10e-6 0,-0.66666 0,-1.33331 0,-1.99999 0.333333,0 0.666667,10e-6 1,10e-6 0,0.66667 0,1.33333 0,1.99999 z"
+ style="opacity:0.15;fill:#4b4b4b;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.15;fill:#1d1d1d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 56,316 c -0.32001,0 -0.64002,0 -0.96003,0 0,-0.21055 0,-0.42107 0,-0.63162 0.32001,0 0.64002,0 0.96003,0 0,0.21055 0,0.42107 0,0.63162 z"
+ id="path41377"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-21.421813,3.140625)"
+ id="g41379"
+ style="display:inline;enable-background:new" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41381"
+ transform="matrix(0,1,1,0,99,651)">
+ <rect
+ y="137"
+ x="-284"
+ height="16"
+ width="16"
+ id="rect41383"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="1.4999387"
+ ry="1.4999353"
+ y="149.5"
+ x="-271.5"
+ height="2.9999931"
+ width="2.9998772"
+ id="rect41385"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41387">
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -271.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ id="path41389"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41391"
+ d="m -283.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -282.50008,139.5 0,-1 1,0"
+ id="path41393"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41395"
+ d="m -270.50008,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41397"
+ style="opacity:0.7">
+ <path
+ id="path41399"
+ d="m -270.5,140.74992 0,8.5"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -280.25008,139.5 8.5,0"
+ id="path41401"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -281.49999,140.75 0,8.5"
+ id="path41403"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41405"
+ d="m -280.00008,139.5 8,0"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -270.5,140.99992 0,8"
+ id="path41407"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41409"
+ d="m -281.49999,141 0,8"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41411"
+ width="2.9998772"
+ height="2.999995"
+ x="-283.5"
+ y="149.5"
+ ry="1.4999362"
+ rx="1.4999387" />
+ <g
+ id="g41413">
+ <path
+ sodipodi:nodetypes="csc"
+ id="path41415"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ id="path41417"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path41419"
+ d="m 36.445698,40.205481 c 0,3.312 -2.660849,4.931507 -5.972849,4.931507 -3.312,0 -5.97285,-1.619507 -5.97285,-4.931507"
+ style="fill:none;stroke:url(#linearGradient42400);stroke-width:1.41714692;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.9208335,0,0,-1.2166667,-304.06042,199.41667)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41421"
+ d="m -269,150 c -0.66667,0 -1.33333,1e-5 -2,1e-5 0,0.66667 0,1.33332 0,1.99999 0.66667,0 1.33333,-1e-5 2,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -281,150 c -0.66667,0 -1.33333,1e-5 -2,1e-5 0,0.66667 0,1.33332 0,1.99999 0.66667,0 1.33333,-1e-5 2,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ id="path41423"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:#ececec;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -270.5,151.5 0,-1 1,0"
+ id="path41425"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="149"
+ x="-283"
+ height="1"
+ width="2.75"
+ id="rect41427"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41429"
+ width="2.75"
+ height="1"
+ x="-271.75"
+ y="149"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41431"
+ transform="translate(565.49991,277.875)">
+ <g
+ transform="translate(-23.5,-18.875)"
+ id="g41433"
+ style="opacity:0.8">
+ <rect
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41435"
+ width="16"
+ height="16"
+ x="-284.99991"
+ y="108" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ id="path41437"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41439"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -283.5,110.5 0,-1 1,0"
+ id="path41441"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41443"
+ d="m -271.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41445"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ id="path41447"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41449"
+ d="m -283.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -271.49992,122.5 0,-1 1,0"
+ id="path41451"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1.0019678,0,0,1,-97.100449,33.125005)"
+ id="g41453">
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:4.36388111;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41455"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41457"
+ style="fill:none;stroke:url(#linearGradient42402);stroke-width:2.18194032;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41459"
+ transform="translate(311,278)">
+ <g
+ transform="translate(0,-19)"
+ id="g41461"
+ style="opacity:0.8">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41463"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41465"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41467"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41469"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41471"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41473"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41475"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41477"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41479"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-57,33)"
+ id="g41481">
+ <rect
+ y="56"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41483"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41485"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23039246;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8124999,0,0,0.8129977,-327.25,-31.938622)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42404);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path41487"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.7451143,0.08386971,-0.08492794,0.7396793,-308.33359,-34.308811)" />
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-310.55192,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42406);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41489"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41491"
+ style="fill:none;stroke:url(#linearGradient42408);stroke-width:1.78040731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5610858,0,0,0.5622541,-294.05201,-2.3458915)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41493"
+ transform="translate(455,122.97748)">
+ <rect
+ y="244.02252"
+ x="-240.00009"
+ height="16"
+ width="16"
+ id="rect41495"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41497"
+ transform="translate(15.99992,107.02252)">
+ <path
+ id="path41499"
+ d="m -243.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#aaccff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline;enable-background:new"
+ d="m -255.5,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41501"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.5"
+ id="g41503">
+ <path
+ id="path41505"
+ d="m -252.25,138.49219 8.5,0"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -252,138.49219 8,0"
+ id="path41507"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path41509"
+ d="m -254.5,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -242.5,139.5 0,-1 1,0"
+ id="path41511"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41513"
+ width="2.9998772"
+ height="3"
+ x="-233.49988"
+ y="245.52252"
+ ry="1.4999387"
+ rx="1.4999387" />
+ <g
+ id="g41515"
+ transform="translate(68.499908,155.89752)">
+ <g
+ transform="matrix(1.0019678,0,0,1,-97.100449,33.125005)"
+ id="g41517">
+ <path
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:4.36388111;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41519"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41521"
+ style="fill:none;stroke:url(#linearGradient42410);stroke-width:2.18194032;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,-293.56324,-17.123443)" />
+ </g>
+ </g>
+ <rect
+ rx="1.4999387"
+ ry="1.4999387"
+ y="245.52252"
+ x="-233.49988"
+ height="3"
+ width="2.9998772"
+ id="rect41523"
+ style="opacity:0.25;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41525"
+ d="m -230.99988,246.02251 c -0.66667,0 -1.33333,10e-6 -2,10e-6 0,0.66667 0,1.33332 0,1.99999 0.66667,0 1.33333,-1e-5 2,-1e-5 0,-0.66666 0,-1.33332 0,-1.99999 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41527"
+ transform="translate(70.968338,302.76882)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41529"
+ width="16"
+ height="16"
+ x="64.231171"
+ y="-65.968338" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41531"
+ width="2.9998772"
+ height="2.9999931"
+ x="76.731178"
+ y="-53.468342"
+ ry="1.4999353"
+ rx="1.4999387" />
+ <g
+ transform="matrix(0,1,1,0,-202.96833,348.23118)"
+ id="g41533"
+ style="display:inline;enable-background:new">
+ <path
+ id="path41535"
+ d="m -271.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -283.50008,137.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41537"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41539"
+ d="m -282.50008,139.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -270.50008,139.5 0,-1 1,0"
+ id="path41541"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.7"
+ id="g41543">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -270.5,140.74992 0,8.5"
+ id="path41545"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41547"
+ d="m -280.25008,139.5 8.5,0"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41549"
+ d="m -281.49999,140.75 0,8.5"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -280.00008,139.5 8,0"
+ id="path41551"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41553"
+ d="m -270.5,140.99992 0,8"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -281.49999,141 0,8"
+ id="path41555"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ rx="1.4999387"
+ ry="1.4999362"
+ y="-53.468342"
+ x="64.731171"
+ height="2.999995"
+ width="2.9998772"
+ id="rect41557"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0,1,1,0,-202.96833,348.23118)"
+ id="g41559"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ id="path41561"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path41563"
+ d="m -270.5,150.5 c 0,-4.0296 -2.4502,-6 -5.5,-6 -3.0498,0 -5.5,1.9704 -5.5,6"
+ style="fill:none;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.9208335,0,0,-1.2166667,-304.06042,199.41667)"
+ style="fill:none;stroke:url(#linearGradient42412);stroke-width:1.41714692;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 36.445698,40.205481 c 0,3.312 -2.660849,4.931507 -5.972849,4.931507 -3.312,0 -5.97285,-1.619507 -5.97285,-4.931507"
+ id="path41565"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.6;display:inline;enable-background:new"
+ transform="translate(132.03151,-159.76882)"
+ id="g41567">
+ <path
+ transform="matrix(0.8124999,0,0,0.8131203,-292.24999,136.05677)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.98423982;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 133.84616,110 0,15.98779 L 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.416 3.584,-8 8,-8 l 1.84616,0 z"
+ id="path41569"
+ sodipodi:nodetypes="cccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csscccc"
+ id="path41571"
+ d="M 132.92501,125.94702 C 132.6215,125.98201 132.31284,126 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.11109 3.10616,-7.5011 7.09807,-7.94965 l 1.32084,-0.14976 1.81209,15.89838 -1.30599,0.14805 0,0 0,0 0,0 z"
+ style="opacity:0.8;fill:url(#linearGradient42414);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ transform="matrix(0.7451143,0.08449152,-0.08492794,0.7451633,-273.33359,132.91784)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccscc"
+ id="path41573"
+ d="m 132.71228,109.99971 0,16.00029 L 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.416 3.584,-8 8,-8 l 0.71228,-2.9e-4 z"
+ style="fill:none;stroke:url(#linearGradient42416);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ transform="matrix(0.6860851,0,0,0.6874876,-275.55192,150.87656)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="css"
+ id="path41575"
+ d="m 132,126 c -4.416,0 -8,-3.584 -8,-8 0,-4.416 3.584,-8 8,-8"
+ style="fill:none;stroke:url(#linearGradient42418);stroke-width:1.78040731;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ transform="matrix(0.5610858,0,0,0.5622541,-259.05201,165.65411)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -52.968334,79.231175 c 0,-0.66667 10e-6,-1.33333 10e-6,-2 0.66667,0 1.33332,0 1.99999,0 0,0.66667 -1e-5,1.33333 -1e-5,2 -0.66666,0 -1.33332,0 -1.99999,0 z"
+ id="path41577"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path41579"
+ d="m -52.968334,67.231175 c 0,-0.66667 10e-6,-1.33333 10e-6,-2 0.66667,0 1.33332,0 1.99999,0 0,0.66667 -1e-5,1.33333 -1e-5,2 -0.66666,0 -1.33332,0 -1.99999,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41581"
+ d="m -51.468334,77.731175 -1,0 0,1"
+ style="opacity:0.8;fill:#ececec;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41583"
+ width="2.75"
+ height="1"
+ x="65.231171"
+ y="-53.968342"
+ rx="0"
+ ry="0" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ rx="0"
+ y="-53.968342"
+ x="76.481178"
+ height="1"
+ width="2.75"
+ id="rect41585"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41587"
+ transform="translate(375,231.00851)">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41589"
+ width="16"
+ height="16"
+ x="-307"
+ y="136" />
+ <g
+ id="g41591"
+ transform="translate(-22.000001,28)"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41593"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41595"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41597"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41599"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41601"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41603"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41605"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41607"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41609"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g41611">
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41613"
+ d="m -299,137.5 c -3.036,0 -5.49999,1.12 -5.49999,2.5 l -10e-6,8 c 0,1.38 2.46399,2.5 5.49999,2.5 3.036,0 5.5,-1.12 5.5,-2.5 l 10e-6,-8 c 0,-1.38 -2.464,-2.5 -5.5,-2.5 z"
+ style="fill:url(#linearGradient42420);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient42422);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient42424);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -294.49145,140.5 c 0,1 -1.5,2 -4.50855,2 -3.00854,0 -4.49145,-1 -4.49145,-2 0,-1.5 2.25,-2.25 4.5,-2.25 2.25,0 4.5,0.75 4.5,2.25 z"
+ id="path41615"
+ sodipodi:nodetypes="czszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path41617"
+ d="m -293.99565,140.99149 c 0,1.12926 -1.66739,2.25851 -5.01168,2.25851 -3.34426,0 -4.99267,-1.12925 -4.99267,-2.25851"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient42426);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -299,137.5 c -3.49999,0 -5.49999,1.12 -5.49999,2.5 l -10e-6,7.5 c 0,2 2.46399,3 5.49999,3 3.036,0 5.50001,-1 5.50001,-3 l 0,-7.5 c 0,-1.38 -1.99999,-2.5 -5.5,-2.5 z"
+ id="path41619"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42428);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -303.5,141.5 0,5.5 c 0,0.9838 0.64285,2.5 4.5,2.5 3.85714,0 4.5,-1.5162 4.5,-2.5 l 0,-5.5"
+ id="path41621"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41623"
+ transform="translate(258.99995,102)">
+ <rect
+ transform="scale(-1,1)"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41625"
+ width="16.000032"
+ height="16"
+ x="195.99995"
+ y="265" />
+ <g
+ transform="translate(77.000139,146.99992)"
+ id="g41627">
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -287.5,118.5 c 10e-6,1.00003 10e-6,2.00005 2e-5,3.00008 0.99999,0 1.99998,0 2.99998,0 -10e-6,-1.00003 -10e-6,-2.00005 -2e-5,-3.00008 -0.99999,0 -1.99999,0 -2.99998,0 z"
+ id="path41629"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41631"
+ d="m -285.5,119.5 -1,0 0,1"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ style="opacity:0.5"
+ id="g41633"
+ transform="matrix(0,1,1,0,-425,402.00008)">
+ <path
+ id="path41635"
+ d="m -279.50016,139.5 6.00016,2e-5"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41637"
+ d="m -281.50008,141.5 0,2"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -280.00008,139.5 6.50008,2e-5"
+ id="path41639"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -281.49999,141 -9e-5,2.5"
+ id="path41641"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g41643"
+ transform="matrix(-1,0,0,-1,-484.99984,399)">
+ <path
+ id="path41645"
+ d="m -287.5,118.5 c 10e-6,1.00003 10e-6,2.00005 2e-5,3.00008 0.99999,0 1.99998,0 2.99998,0 -10e-6,-1.00003 -10e-6,-2.00005 -2e-5,-3.00008 -0.99999,0 -1.99999,0 -2.99998,0 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -285.5,119.5 -1,0 0,1"
+ id="path41647"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0,1,1,0,-425,402.00008)"
+ id="g41649"
+ style="opacity:0.5">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -279.50016,139.5 7,0"
+ id="path41652"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#aaccff;fill-opacity:0.75;fill-rule:evenodd;stroke:#003380;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -281.50008,141.5 0,2"
+ id="path41654"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41656"
+ d="m -280.00008,139.5 7.49992,0"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41658"
+ d="m -281.49999,141 -9e-5,2.5"
+ style="fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-191.99984,-17.000001)"
+ id="g41660"
+ style="display:inline;enable-background:new">
+ <g
+ id="g41662"
+ transform="translate(-376,510)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path41664"
+ d="m 358.99997,-216.75 c -0.99997,-6.5 6.00003,-2.75 5,-9.25 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cdcdcd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path41666"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.7;fill:url(#linearGradient42430);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ id="path41668"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path41670"
+ d="M 358.99997,-216.75 C 358,-223.25 365,-220 363.99997,-226 L 369,-224 c 1,7 -6,2 -5,10 l -5.00003,-2.75 z"
+ style="opacity:0.85;fill:url(#radialGradient42432);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.88812488px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path41672"
+ d="m 364.24984,-225.5 4.25016,1.75 c 1,5.75 -5.50003,2 -5.08381,8.85761 l -4.04561,-2.26888"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient42434);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 364.24997,-225.5 4.25003,1.75"
+ id="path41674"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-399.2499,383.75)"
+ id="g41676" />
+ <g
+ id="g41678"
+ transform="translate(-406.2499,380.75)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41680"
+ transform="translate(338.00016,191)">
+ <g
+ id="g41682"
+ transform="translate(56.999841,68)"
+ style="opacity:0.8;display:inline;enable-background:new">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41684"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41686"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41688"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41690"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41692"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41694"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41696"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41699"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41701"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="176"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41703"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:url(#linearGradient42436);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -220,178.5 c -4.14,0 -7.40235,2.464 -7.40234,5.5 0,3.036 3.26234,5.5 7.40234,5.5 4.14,0 7.40234,-2.464 7.40234,-5.5 0,-3.036 -3.26233,-5.50001 -7.40234,-5.5 z m 0,4 c 1.2993,0 2.42742,0.39879 3.03125,1 -0.60383,0.60121 -1.73196,1 -3.03125,1 -1.29929,0 -2.42742,-0.39879 -3.03125,-1 0.60383,-0.60121 1.73196,-1 3.03125,-1 z"
+ id="path41705"
+ sodipodi:nodetypes="cssscccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:url(#radialGradient42438);fill-rule:evenodd;stroke:none"
+ d="m -214.625,180.4375 c 1.5822,4.85564 -3.15377,7.27675 -11.84375,6.21875 l 0,0.0312 c 1.25689,1.67541 3.66207,2.8125 6.46875,2.8125 4.14,0 7.40625,-2.464 7.40625,-5.5 0,-1.34213 -0.64966,-2.57614 -1.71875,-3.53125 -0.10326,-0.0119 -0.20204,-0.024 -0.3125,-0.0312 z"
+ id="path41707"
+ sodipodi:nodetypes="cccsscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path41709"
+ d="m -223.375,183.45313 c 1.90631,-1.46639 4.08905,-1.44306 6.1875,-0.53125 L -217,182.76563 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:url(#radialGradient42440);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -223.375,183.65625 0.5,-0.0312 c -0.0509,-0.0426 -0.11109,-0.08 -0.15625,-0.125 0.60383,-0.60121 1.73196,-1 3.03125,-1 0.99575,0 1.89552,0.24495 2.53125,0.625 L -217,182.96875 c -0.60315,-4.39553 -10.23988,-3.57787 -6.375,0.6875 z"
+ id="path41711"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.9999986,0,0,1.799999,-2.971883e-4,111.10004)"
+ d="m -213.5,40.5 a 6.5,2.5 0 1 1 -13,0 6.5,2.5 0 1 1 13,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="6.5"
+ sodipodi:cy="40.5"
+ sodipodi:cx="-220"
+ id="path41713"
+ style="fill:none;stroke:url(#linearGradient42442);stroke-width:0.5962854;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41715"
+ transform="translate(300.99985,63)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41717"
+ width="16"
+ height="16"
+ x="-211.99985"
+ y="304" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ transform="translate(73.00016,196)"
+ id="g41719">
+ <rect
+ y="108"
+ x="-284.99991"
+ height="16"
+ width="16"
+ id="rect41721"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path41723"
+ d="m -272.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 -1.00003,0 -2.00005,-1e-5 -3.00008,-1e-5 0,-1 0,-1.99999 0,-2.99999 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -284.5,108.5 c 1.00003,1e-5 2.00005,1e-5 3.00008,2e-5 0,0.99999 0,1.99998 0,2.99998 -1.00003,-1e-5 -2.00005,-1e-5 -3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 z"
+ id="path41725"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41727"
+ d="m -283.5,110.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -271.5,110.5 0,-1 1,0"
+ id="path41729"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m -272.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99999 0,-2.99998 -1.00003,0 -2.00005,1e-5 -3.00008,1e-5 0,1 0,1.99999 0,2.99999 z"
+ id="path41731"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41733"
+ d="m -284.49992,123.5 c 1.00003,-1e-5 2.00005,-1e-5 3.00008,-2e-5 0,-0.99999 0,-1.99998 0,-2.99998 -1.00003,1e-5 -2.00005,1e-5 -3.00008,2e-5 0,0.99999 0,1.99999 0,2.99998 z"
+ style="fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:#003380;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -283.49992,122.5 0,-1 1,0"
+ id="path41735"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41737"
+ d="m -271.49992,122.5 0,-1 1,0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline"
+ id="g41739"
+ transform="matrix(1.1658027,0,0,1.1657997,-354.28956,51.94393)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41741"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.23686147;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42444);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path41743"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.6391427,-0.07194179,0.07284933,-0.6344823,204.68584,307.47408)" />
+ <path
+ transform="matrix(0.5885088,0,0,0.5897133,51.241774,153.48488)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42446);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41745"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ sodipodi:nodetypes="cscc"
+ id="path41747"
+ style="fill:none;stroke:url(#linearGradient42448);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ d="m -197.75642,311.54171 c -0.99362,1.2083 -2.79874,2.22895 -6.24718,2.22895 -3.415,0 -5.24644,-1.02065 -6.24644,-2.195"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41749"
+ transform="matrix(1,0,0,-1,496,768)">
+ <rect
+ transform="scale(-1,1)"
+ y="385"
+ x="202"
+ height="16"
+ width="16"
+ id="rect41751"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -203.5,396.5 0,3 -3,0"
+ id="path41753"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41755"
+ d="m -213.5,386.5 0,3 -3,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41757"
+ d="m -208.5,391.5 0,3 -3,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g41759"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,1,-118.8387,295.00001)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cz"
+ id="path41761"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85.6613,103.49999 9,-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path41763"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 9,-9"
+ style="fill:none;stroke:#d7e3f4;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path41765"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41767"
+ d="m -203,400 0,-4 -1,0 0,3 -3,0 0,1 4,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41769"
+ d="m -213,390 0,-4 -1,0 0,3 -3,0 0,1 4,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -208,395 0,-4 -1,0 0,3 -3,0 0,1 4,0 z"
+ id="path41771"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,-1,-420,786)"
+ style="opacity:0.2"
+ id="g41773">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -208,395 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path41775"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41777"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -211,392 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path41779"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path41781"
+ d="m -213,390 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42152"
+ transform="translate(272.99917,170)">
+ <g
+ transform="translate(83.990361,105)"
+ id="g42154"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42157"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42159"
+ style="fill:none;stroke:url(#linearGradient42462);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42464);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42161"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42466);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42163"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(81.056581,171.48366)"
+ id="g42165">
+ <path
+ id="path42168"
+ d="m 101.94425,50.518348 -5.000004,1.875 0,6.3125 5.000004,2.71875 5,-2.71875 0,-6.3125 -5,-1.875 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42170"
+ d="m 106.94413,58.696518 0,-6.29009 -5,-1.89415 c 0,2.16796 0,10.43646 0,10.91232 l 5,-2.72808 z"
+ style="fill:url(#linearGradient42468);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 96.944126,58.696518 0,-6.29009 5.000004,-1.89415 0,10.91232 -5.000004,-2.72808 z"
+ id="path42175"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42177"
+ d="m 96.944126,52.406428 5.000004,-1.89415 5,1.89415 -5,2.07396 -5.000004,-2.07396 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient42470);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 106.44413,52.406428 0,6.04208 -4.5,2.48007 -4.500004,-2.48007 0,-6.04208"
+ id="path42179"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42181"
+ transform="translate(335.99917,149.00001)">
+ <g
+ style="opacity:0.5"
+ id="g42183"
+ transform="translate(83.990367,126)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42185"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42472);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42187"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42189"
+ style="fill:none;stroke:url(#linearGradient42474);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42191"
+ style="fill:none;stroke:url(#linearGradient42477);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(321.49473,233.64631)"
+ id="g42193">
+ <g
+ id="g42195"
+ transform="translate(-38.4939,35.353694)">
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path42197"
+ d="m -98.999998,-25.5 c -2.485192,0 -4.499992,0.89481 -4.500002,2 l 0,7 c 0,1.10519 2.0148,2 4.500002,2 2.48519,0 4.499998,-1.1448 4.499998,-2.25 l 2e-6,-6.75 c 0,-1.10519 -2.01481,-2 -4.5,-2 z"
+ style="fill:url(#linearGradient42479);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ id="path42199"
+ d="m -102.5,-22 0,5 c 0,1.25 0.5,1.5 3.5,1.5 3,0 3.5,-0.25 3.5,-1.5 l 0,-5"
+ style="fill:none;stroke:url(#linearGradient42481);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="css"
+ id="path42201"
+ d="M -94.730509,-23.353486 C -94.748454,-21.92288 -95.5,-21.5 -99,-21.5 c -3.5,0 -4.24845,-0.42288 -4.24845,-1.848345"
+ style="fill:none;stroke:url(#linearGradient42483);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient42485);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -95.341215,-23.173655 c 0,0.873491 -0.648671,1.587005 -3.656631,1.582419 -3.011664,-0.0046 -3.656634,-0.708928 -3.656634,-1.582419 0,-0.87349 0.64497,-1.582418 3.656634,-1.582418 3.00796,0 3.656631,0.708928 3.656631,1.582418 z"
+ id="path42203"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -99,-25.5 c -4,0 -4.49999,0.89481 -4.5,2 l 0,6 c 0,1.10519 0,3.00433 4.50216,3.002164 C -94.5,-14.5 -94.5,-16.3948 -94.5,-17.5 l 0,-6 c 0,-1.10519 -0.5,-2 -4.5,-2 z"
+ id="path42205"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42207"
+ transform="translate(251.99917,191.00001)">
+ <g
+ transform="translate(83.990364,83.999999)"
+ id="g42209"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42211"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42213"
+ style="fill:none;stroke:url(#linearGradient42487);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42489);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42215"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42491);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42217"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="matrix(1.3088013,0,0,1.3078064,114.94487,78.842325)"
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g42219">
+ <rect
+ y="94.553505"
+ x="48.560436"
+ height="7.6462827"
+ width="7.6405811"
+ id="rect42221"
+ style="fill:url(#linearGradient42493);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.61147881;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42223"
+ d="m 49.324493,101.43525 0,-6.117109 6.112464,0 9.17e-4,6.117009 -6.113381,1e-4 0,0 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient42495);stroke-width:0.76434839px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42225"
+ transform="translate(293.99917,128.01655)">
+ <g
+ id="g42227">
+ <g
+ transform="translate(83.990364,146.98346)"
+ id="g42229"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42231"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42233"
+ style="fill:none;stroke:url(#linearGradient42497);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42499);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42235"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42501);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42237"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g42239"
+ transform="matrix(0.9864502,0,0,0.9977342,55.832396,47.37231)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42241"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.45345163;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient42503);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path42243"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.6289675,-0.07056955,0.07168957,-0.6223801,203.47957,305.88099)" />
+ <path
+ transform="matrix(0.5718707,0,0,0.5622842,53.438009,156.77386)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42505);stroke-width:1.77757704;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42245"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42247"
+ transform="translate(315,107)">
+ <g
+ transform="translate(83.990364,168)"
+ id="g42249"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42251"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42253"
+ style="fill:none;stroke:url(#linearGradient42507);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42509);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42255"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42511);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42257"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(67,168)"
+ id="g42259">
+ <rect
+ style="opacity:0;fill:#ffd5d5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42261"
+ width="14"
+ height="14"
+ x="109"
+ y="116" />
+ <g
+ transform="matrix(0,-0.7411719,0.7413284,0,26.310335,194.89046)"
+ id="g42263">
+ <rect
+ y="113"
+ x="89.000832"
+ height="16"
+ width="16"
+ id="rect42265"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.3039373,-0.2835816,-0.2811062,1.3154136,-8.365286,-135.94413)"
+ id="g42268"
+ style="display:inline">
+ <path
+ transform="matrix(0.6969446,0,0,0.6900977,36.918531,141.69345)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.52109182;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 139.87786,116.72728 c 0,4.416 -4.87654,8.89303 -9.18264,9.14567 -4.03231,0.23658 -6.86684,-2.60955 -6.61392,-6.64097 0.26963,-4.29785 4.87655,-8.89304 9.18265,-9.14567 4.03232,-0.23656 6.86685,2.60957 6.61391,6.64097 z"
+ id="path42273"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-0.6214741,-0.06030772,0.08065856,-0.6191475,201.43124,304.14414)"
+ style="opacity:0.8;fill:url(#linearGradient42513);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 140.14875,115.73726 c 0,4.416 -4.29905,10.26855 -8.71505,10.26855 -4.416,0 -7.23906,-1.65769 -7.23906,-6.07369 0,-4.416 4.28332,-9.5732 8.27188,-10.31985 3.26409,-0.61103 7.68223,1.70899 7.68223,6.12499 l 0,0 0,0 0,0 z"
+ id="path42275"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.5541229,-0.02016698,-0.02019099,0.5552959,58.152692,160.26124)"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient42515);stroke-width:1.90297282;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 139.88903,116.28509 c 0,4.416 -5.24736,9.49944 -9.66336,9.49944 -4.416,0 -6.16482,-1.70296 -6.16482,-6.11896 0,-4.416 5.24736,-9.49945 9.66336,-9.49945 4.416,0 6.16482,1.70297 6.16482,6.11897 l 0,0 0,0 0,0 z"
+ id="path42277"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\Browser icons ver 1\font_file SMALL.png"
+ transform="translate(10.00003,171.5)"
+ id="g42279">
+ <rect
+ y="237.5"
+ x="162.99997"
+ height="16"
+ width="16"
+ id="rect42282"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <g
+ id="g42285"
+ style="opacity:0.9">
+ <g
+ transform="translate(75.999999,-319.5)"
+ id="g42287"
+ style="fill:#ffcc00;stroke:#000000;stroke-width:1.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline">
+ <path
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m -167,235 0,9 1,0 0,-4 3,0 0,-1 -3,0 0,-4 5,0 0,-1 -6,0 0,1 z"
+ transform="translate(262.99997,326)"
+ id="path42289"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:#ffcc00;display:inline"
+ id="g42291"
+ transform="translate(75.999999,-319.5)">
+ <path
+ style="fill:url(#linearGradient42517)"
+ d="m -167,235 0,9 1,0 0,-4 3,0 0,-1 -3,0 0,-4 5,0 0,-1 -6,0 0,1 z"
+ transform="translate(262.99997,326)"
+ id="path42294"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.85;fill:#ffffff;display:inline"
+ d="m 171.99997,240.5 0,10 0.65625,0 0,-10 -0.65625,0 z"
+ id="path42296"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g42298">
+ <rect
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42300"
+ width="1.25"
+ height="1"
+ x="90"
+ y="43"
+ transform="translate(73.999969,208.5)" />
+ <rect
+ y="251.5"
+ x="167.74997"
+ height="1"
+ width="1.2500329"
+ id="rect42302"
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="238.5"
+ x="163.99997"
+ height="1"
+ width="1.2499995"
+ id="rect42304"
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42306"
+ width="1.250011"
+ height="1"
+ x="167.74997"
+ y="238.5" />
+ <rect
+ style="fill:none;stroke:#162d50;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42308"
+ width="1.0000029"
+ height="12.5"
+ x="165.99997"
+ y="239.25" />
+ </g>
+ <g
+ id="g42310"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ transform="translate(73.999969,208.5)"
+ y="43"
+ x="90"
+ height="1"
+ width="2"
+ id="rect42312"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42314"
+ width="2"
+ height="1"
+ x="166.99997"
+ y="251.5" />
+ <rect
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42316"
+ width="2"
+ height="1"
+ x="163.99997"
+ y="238.5" />
+ <rect
+ y="238.5"
+ x="166.99997"
+ height="1"
+ width="2"
+ id="rect42318"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="239.5"
+ x="165.99997"
+ height="12"
+ width="0.99999952"
+ id="rect42320"
+ style="fill:#e9f0fa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g35366"
+ transform="translate(333.02099,358)">
+ <rect
+ y="135"
+ x="-202"
+ height="16"
+ width="16"
+ id="rect35368"
+ style="opacity:0;fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)"
+ id="g35370"
+ style="opacity:0.35">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#f8dcdc;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#580000;stroke-width:1.22792602;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35372"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35374"
+ style="fill:none;stroke:url(#linearGradient35406);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)" />
+ <path
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35408);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35376"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ id="g35378"
+ transform="matrix(0.857703,0,0,0.8577018,-4.235469,19.278753)"
+ style="opacity:0.7">
+ <path
+ sodipodi:nodetypes="cssssszzs"
+ id="path35380"
+ d="m -222.5,141.5 c 1.52069,0 2.97702,-1.62476 3,-2.5 0.0525,-1.99931 1.5,-3.5 3.5,-3.5 2,0 3.5,1.568 3.5,3.5 0,1.84581 -1.5,3.50326 -3.5,3.5 -0.8997,-0.001 -2.5,1.5 -2.5,3 0,2.25 -1.75,4 -4,4 -2.25,0 -4,-1.75 -4,-4 0,-2.25 1.75,-4 4,-4 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.93272448;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-527,-167)"
+ d="m 311,303 c -1.75507,0 -3,1.24493 -3,3 0,0.81824 -0.48216,1.55558 -1.125,2.09375 C 306.23216,308.63192 305.39457,309 304.5,309 c -1.996,0 -3.5,1.504 -3.5,3.5 0,1.996 1.504,3.5 3.5,3.5 1.996,0 3.5,-1.504 3.5,-3.5 0,-0.88607 0.36895,-1.73024 0.90625,-2.375 0.5373,-0.64476 1.27281,-1.125 2.09375,-1.125 1.72989,0 3,-1.41958 3,-3 0,-1.67845 -1.25603,-3 -3,-3 z"
+ id="path35382"
+ style="opacity:0.8;fill:url(#linearGradient35410);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86598092;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.48985747"
+ sodipodi:type="inkscape:offset" />
+ <path
+ transform="translate(-527,-167)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.96440691"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="fill:none;stroke:url(#radialGradient35412);stroke-width:1.16590559;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35384"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z" />
+ <path
+ transform="matrix(0,-1,-1,0,90,450)"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path35386"
+ style="fill:none;stroke:url(#radialGradient35414);stroke-width:1.16590559;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset" />
+ </g>
+ <g
+ style="opacity:0.12999998"
+ id="g35388"
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35390"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#530505;stroke-width:1.22792602;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)" />
+ <path
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35416);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35392"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35394"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35418);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)" />
+ </g>
+ <g
+ style="opacity:0.9;display:inline;enable-background:new"
+ transform="matrix(0.8749996,0,0,0.8802811,-404.57262,-113.49608)"
+ id="g35396">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient35420);stroke-width:1.13942409;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35398"
+ sodipodi:cx="219.5"
+ sodipodi:cy="292.5"
+ sodipodi:rx="4"
+ sodipodi:ry="4"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ transform="translate(20,0)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#linearGradient35422);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35400"
+ sodipodi:cx="219.5"
+ sodipodi:cy="292.5"
+ sodipodi:rx="4"
+ sodipodi:ry="4"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ transform="matrix(0.875,0,0,0.875,47.4375,36.5625)" />
+ <path
+ transform="matrix(0.7060003,0,0,0.7060647,84.532933,85.976064)"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35402"
+ style="fill:none;stroke:url(#linearGradient35424);stroke-width:1.6138407;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.875,0,0,0.875,47.4375,36.5625)"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35404"
+ style="opacity:0.8;fill:url(#radialGradient35426);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ transform="translate(291,273.9804)"
+ id="g35428"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35430"
+ width="16"
+ height="16"
+ x="-202"
+ y="135" />
+ <g
+ style="opacity:0.35"
+ id="g35432"
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35434"
+ style="fill:#f8dcdc;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#580000;stroke-width:1.22792602;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)" />
+ <path
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35468);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35436"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35438"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35470);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)" />
+ </g>
+ <g
+ style="opacity:0.7"
+ transform="matrix(0.857703,0,0,0.8577018,-4.235469,19.278753)"
+ id="g35440">
+ <path
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.93272448;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -222.5,141.5 c 1.52069,0 2.97702,-1.62476 3,-2.5 0.0525,-1.99931 1.5,-3.5 3.5,-3.5 2,0 3.5,1.568 3.5,3.5 0,1.84581 -1.5,3.50326 -3.5,3.5 -0.8997,-0.001 -2.5,1.5 -2.5,3 0,2.25 -1.75,4 -4,4 -2.25,0 -4,-1.75 -4,-4 0,-2.25 1.75,-4 4,-4 z"
+ id="path35442"
+ sodipodi:nodetypes="cssssszzs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.48985747"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="opacity:0.8;fill:url(#linearGradient35472);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.86598092;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35444"
+ d="m 311,303 c -1.75507,0 -3,1.24493 -3,3 0,0.81824 -0.48216,1.55558 -1.125,2.09375 C 306.23216,308.63192 305.39457,309 304.5,309 c -1.996,0 -3.5,1.504 -3.5,3.5 0,1.996 1.504,3.5 3.5,3.5 1.996,0 3.5,-1.504 3.5,-3.5 0,-0.88607 0.36895,-1.73024 0.90625,-2.375 0.5373,-0.64476 1.27281,-1.125 2.09375,-1.125 1.72989,0 3,-1.41958 3,-3 0,-1.67845 -1.25603,-3 -3,-3 z"
+ transform="translate(-527,-167)" />
+ <path
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ id="path35446"
+ style="fill:none;stroke:url(#radialGradient35474);stroke-width:1.16590559;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ inkscape:radius="-0.96440691"
+ sodipodi:type="inkscape:offset"
+ transform="translate(-527,-167)" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.96440691"
+ inkscape:original="M 311 302.5 C 309 302.5 307.5 304 307.5 306 C 307.5 307.25 306.02069 308.5 304.5 308.5 C 302.25 308.5 300.5 310.25 300.5 312.5 C 300.5 314.75 302.25 316.5 304.5 316.5 C 306.75 316.5 308.5 314.75 308.5 312.5 C 308.5 311 309.75 309.5 311 309.5 C 313 309.5 314.5 307.84581 314.5 306 C 314.5 304.068 313 302.5 311 302.5 z "
+ style="fill:none;stroke:url(#radialGradient35476);stroke-width:1.16590559;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35448"
+ d="m 311,303.46875 c -1.5178,0 -2.53125,1.01345 -2.53125,2.53125 0,1.00544 -0.55807,1.86332 -1.28125,2.46875 -0.72318,0.60543 -1.66291,1 -2.6875,1 -1.74994,0 -3.03125,1.28131 -3.03125,3.03125 0,1.74994 1.28131,3.03125 3.03125,3.03125 1.74994,0 3.03125,-1.28131 3.03125,-3.03125 0,-1.01789 0.3963,-1.96306 1,-2.6875 0.6037,-0.72444 1.45799,-1.28125 2.46875,-1.28125 1.46823,0 2.53125,-1.20792 2.53125,-2.53125 0,-1.43282 -1.03531,-2.53125 -2.53125,-2.53125 z"
+ transform="matrix(0,-1,-1,0,90,450)" />
+ </g>
+ <g
+ transform="matrix(0.8692812,0,0,0.8692812,-279.33076,38.816971)"
+ id="g35450"
+ style="opacity:0.12999998">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#530505;stroke-width:1.22792602;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35452"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35454"
+ style="fill:none;stroke:url(#linearGradient35478);stroke-width:1.4523226;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.7910044,0,0,0.7931859,-7.3995492,27.410355)" />
+ <path
+ transform="matrix(0.644496,0,0,0.6462993,11.939574,44.742981)"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient35480);stroke-width:1.78243256;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path35456"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ id="g35458"
+ transform="matrix(0.8749996,0,0,0.8802811,-404.57262,-113.49608)"
+ style="opacity:0.9;display:inline;enable-background:new">
+ <path
+ transform="translate(20,0)"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35460"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient35482);stroke-width:1.13942409;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.875,0,0,0.875,47.4375,36.5625)"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ sodipodi:ry="4"
+ sodipodi:rx="4"
+ sodipodi:cy="292.5"
+ sodipodi:cx="219.5"
+ id="path35462"
+ style="opacity:0.8;fill:url(#linearGradient35484);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient35486);stroke-width:1.6138407;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35464"
+ sodipodi:cx="219.5"
+ sodipodi:cy="292.5"
+ sodipodi:rx="4"
+ sodipodi:ry="4"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ transform="matrix(0.7060003,0,0,0.7060647,84.532933,85.976064)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:url(#radialGradient35488);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29032254;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35466"
+ sodipodi:cx="219.5"
+ sodipodi:cy="292.5"
+ sodipodi:rx="4"
+ sodipodi:ry="4"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
+ transform="matrix(0.875,0,0,0.875,47.4375,36.5625)" />
+ </g>
+ </g>
+ <g
+ id="g34702"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\sphere with sky.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g35479"
+ transform="translate(30.046349,-38.039825)"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(-340.00002,-121.00001)"
+ id="g35481">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9e9af;stroke-width:0.58333313;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35483"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.7142856,0,0,1.7142871,-330.83199,-136.46043)" />
+ <path
+ transform="matrix(1.4285718,0,0,1.4285718,-198.61789,-81.960223)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35485"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e1e08e;stroke-width:0.69999987;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#adac2f;stroke-width:1.16666663;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35487"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(0.8571429,0,0,0.8571429,66.810813,28.039828)" />
+ </g>
+ <rect
+ y="71.039841"
+ x="123.95369"
+ height="2"
+ width="2"
+ id="rect35489"
+ style="fill:#f4eed7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="opacity:0.6"
+ transform="matrix(-1,0,0,1,194,-21)"
+ id="g35439">
+ <path
+ style="fill:url(#linearGradient35446);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ d="m 31.5,52.5 c -1.656,0 -3,1.343998 -3,3 0,0.02155 -4.53e-4,0.04106 0,0.0625 -1.138867,0.233417 -1.999999,1.229094 -2,2.4375 0,1.381035 1.120001,2.500001 2.5,2.5 l 6.5,0 c 1.656,0 3,-1.344001 3,-3 0,-1.656001 -1.344,-2.999999 -3,-3 -0.40365,0 -0.77337,0.105241 -1.125,0.25 C 34.035268,53.465989 32.89035,52.500001 31.5,52.5 z"
+ id="path34600"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35419"
+ style="fill:url(#linearGradient35450);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0,0.3125,-0.3124999,0,68.374988,14.250001)" />
+ <path
+ transform="matrix(0,0.2187504,-0.2187496,0,54.562456,29.374947)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35448);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path34624"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.08088095,0.3018518,-0.3018517,0.08088093,60.442218,8.1116116)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient35452);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path35435"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path35429"
+ style="fill:url(#linearGradient35454);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0,0.2812501,-0.2812497,0,64.937461,20.624986)" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.92788464"
+ inkscape:original="M 31.5 52.5 C 29.844 52.5 28.5 53.843998 28.5 55.5 C 28.5 55.521551 28.499547 55.541057 28.5 55.5625 C 27.361133 55.795917 26.500001 56.791594 26.5 58 C 26.5 59.381035 27.620001 60.500001 29 60.5 L 35.5 60.5 C 37.156 60.5 38.5 59.155999 38.5 57.5 C 38.5 55.843999 37.156 54.500001 35.5 54.5 C 35.09635 54.5 34.72663 54.605241 34.375 54.75 C 34.035268 53.465989 32.89035 52.500001 31.5 52.5 z "
+ style="fill:none;stroke:url(#linearGradient35718);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="path35703"
+ d="m 31.5,53.4375 c -1.153957,0 -2.0625,0.908541 -2.0625,2.0625 0,0.03455 7.4e-5,0.03475 0,0.03125 a 0.92797743,0.92797743 0 0 1 -0.75,0.9375 c -0.72055,0.147681 -1.249999,0.763662 -1.25,1.53125 0,0.879367 0.684082,1.562501 1.5625,1.5625 l 6.5,0 c 1.153956,0 2.0625,-0.908545 2.0625,-2.0625 0,-1.153957 -0.908543,-2.062499 -2.0625,-2.0625 -0.242369,0 -0.494949,0.03839 -0.78125,0.15625 A 0.92797743,0.92797743 0 0 1 33.46875,55 C 33.231438,54.103084 32.460566,53.437501 31.5,53.4375 z" />
+ </g>
+ <rect
+ y="31"
+ x="152"
+ height="16"
+ width="16"
+ id="rect34608"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.9059893,0,0,0.9161677,40.690483,-162.91268)"
+ id="g34610"
+ style="display:inline">
+ <path
+ transform="matrix(0.6879625,0,0,0.6812035,38.104167,142.74297)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.6033566;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path34612"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.6156869,-0.06867104,0.07017585,-0.6056363,201.96224,303.63852)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path34614"
+ style="opacity:0.8;fill:url(#linearGradient34618);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path34616"
+ style="fill:none;stroke:url(#linearGradient34620);stroke-width:2.02934265;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.5436035,0,0,0.5381576,57.159565,159.63177)" />
+ </g>
+ </g>
+ <g
+ style="stroke:#ffffff;display:inline"
+ transform="matrix(-1,0,0,-1,104.1613,262.99999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g34782">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path34784"
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34806"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path34696"
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-155,-228)"
+ style="opacity:0.12000002"
+ id="g36040" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g36398"
+ transform="translate(-20.999985,0)">
+ <rect
+ y="157"
+ x="89.000015"
+ height="16"
+ width="16"
+ id="rect36400"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36402">
+ <g
+ transform="translate(8.000015,151)"
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="g36404">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#00163c;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 88.999985,8 0,8"
+ id="path36407"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36410"
+ d="m 82.99997,20 6.000015,-4"
+ style="fill:none;stroke:#5d0606;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#183c00;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 94.99997,20 88.999985,16"
+ id="path36412"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:none;stroke:#5d0606;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36414"
+ width="2.0000153"
+ height="2.0000069"
+ x="89.999985"
+ y="170"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:none;stroke:#001e50;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36416"
+ width="2.0000153"
+ height="2.0000069"
+ x="96"
+ y="158"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4c8ff4;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 97,159 0,8"
+ id="path36418"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36420"
+ d="M 90.999985,171 97,167"
+ style="fill:none;stroke:#ef4e29;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="89.999985"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36422"
+ style="opacity:0.3;fill:none;stroke:#5d0606;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.499985,170.75 6,-4 1.5e-5,-7.25"
+ id="path36424"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="102"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36426"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#93e420;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 102.99998,171 97,167"
+ id="path36428"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="90"
+ height="2"
+ width="2"
+ id="rect36430"
+ style="fill:#eb512e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="158"
+ x="96"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36432"
+ style="opacity:0.3;fill:none;stroke:#001e50;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="158"
+ x="96.000023"
+ height="2"
+ width="2"
+ id="rect36434"
+ style="fill:#4c8ff4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient36452);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36436"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.3333333,0,0,1.3333343,3,147.66665)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6666679,0,0,0.6666668,49.999915,157.33333)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36438"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ style="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36440"
+ width="2.0000153"
+ height="2.0000069"
+ x="102"
+ y="170"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#95e51f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36442"
+ width="2"
+ height="2"
+ x="102.00002"
+ y="170"
+ rx="0"
+ ry="0" />
+ <g
+ id="g36444"
+ style="opacity:0.8">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36446"
+ d="m 96.5,159.5 0,-1 1,0"
+ style="fill:none;stroke:url(#linearGradient36454);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient36456);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.499985,171.5 0,-1 1,0"
+ id="path36448"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36450"
+ d="m 102.49999,171.5 0,-1 1,0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient36458);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g36498"
+ transform="translate(0,-20.999998)">
+ <g
+ style="display:inline;enable-background:new"
+ id="g35291"
+ transform="translate(105,358.99999)">
+ <rect
+ transform="scale(-1,-1)"
+ y="-66"
+ x="-210"
+ height="16"
+ width="16"
+ id="rect35293"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(22.999994,19)"
+ id="g35295">
+ <path
+ sodipodi:nodetypes="cccscccccc"
+ style="fill:url(#linearGradient36648);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 178.00001,33.5 -1.5,0 L 174,36 c -1.00699,1.006986 -0.0205,3.604505 2.1875,5.8125 2.208,2.207997 4.80551,3.194485 5.8125,2.1875 l 2.50001,-2.5 0,-1.5 -0.75,-1.75 -4,-4 -1.75,-0.75 z"
+ id="path35297"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ d="m 186.50001,35.5 -2.75,2.75 -1,-1 -1,-1 -1,-1 -1,-1 2.75,-2.75 1.25,0 1.5,1.25 1.25,1.5 0,1.25 z"
+ style="fill:url(#linearGradient36650);fill-rule:evenodd;stroke:none"
+ id="path35299"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccsccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 182.50001,31.5 -2.75,2.75 -1.75,-0.75 -1.5,0 L 174,36 c -1.00699,1.006986 -0.0205,3.604505 2.1875,5.8125 2.208,2.207997 4.80551,3.194485 5.8125,2.1875 l 2.50001,-2.5 0,-1.5 -0.75,-1.75 2.75,-2.75 0,-1 -1.25,-1.75 -1.75,-1.25 -1,0 z"
+ id="path35301"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35303"
+ d="m 174.75001,36.5 2.25,-2.25 1.5,0.25 1.5,0.75 1.5,1.25 1.25,1.5 0.75,1.5 0.25,1.5 -1.5,1.5"
+ style="fill:none;stroke:url(#linearGradient36652);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="6.2810509"
+ sodipodi:start="0"
+ transform="matrix(1.2491741,-1.2491602,0.7680871,0.768079,-75.108556,239.34027)"
+ d="m 182.21113,35 a 1.2111344,4.9951267 0 1 1 0,-0.01066"
+ sodipodi:ry="4.9951267"
+ sodipodi:rx="1.2111344"
+ sodipodi:cy="35"
+ sodipodi:cx="181"
+ id="path35305"
+ style="fill:#d3c656;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74147779;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#f3eebb;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74147779;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35307"
+ sodipodi:cx="181"
+ sodipodi:cy="35"
+ sodipodi:rx="1.1763829"
+ sodipodi:ry="5.5293522"
+ d="m 182.17638,35 a 1.1763829,5.5293522 0 1 1 -2.35276,0 1.1763829,5.5293522 0 1 1 2.35276,0 z"
+ transform="matrix(0.9589476,-0.9192618,0.5776079,0.5780619,-15.42366,185.77921)" />
+ <path
+ id="path35309"
+ d="M 182.25,43.75 C 182.25,42 182,41 179.5,38.5 177,36 175.75,35.75 174.25,35.75"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient36654);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="czs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35311"
+ d="m 180.50001,34.5 2,-2 1,0 1,1 1,1 0,1 -2,2"
+ style="fill:none;stroke:url(#linearGradient36656);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ style="fill:none;stroke:url(#linearGradient36658);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 184.50001,41.5 c 0,-1.75 0,-3 -2.5,-5.5 -2.5,-2.5 -4,-2.5 -5.5,-2.5"
+ id="path35313"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="opacity:0.65"
+ id="g35315">
+ <g
+ transform="translate(21,21)"
+ id="g35317">
+ <path
+ id="path35319"
+ d="m 174.5,40.5 0,3 3,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 175.5,42.5 179,39"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35321"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g35323"
+ transform="matrix(-1,0,0,-1,383,116)">
+ <g
+ id="g35325"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35327"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 5,-5"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35329"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35331"
+ d="m 188,51 0,4 -1,0 0,-3 -3,0 0,-1 4,0 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g35333">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35335"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#b5a731;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <rect
+ y="58"
+ x="200.75"
+ height="1.25"
+ width="1.25"
+ id="rect35337"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35339"
+ width="1.5"
+ height="1.5"
+ x="199.75"
+ y="58.75" />
+ <rect
+ y="59.75"
+ x="198.75"
+ height="1.5"
+ width="1.5"
+ id="rect35341"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(0,20.999991)"
+ id="g35343">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35345"
+ width="16"
+ height="16"
+ x="-273"
+ y="-404"
+ transform="scale(-1,-1)" />
+ <g
+ style="opacity:0.65"
+ transform="translate(63,338)"
+ id="g35347"
+ mask="url(#mask31861)">
+ <g
+ style="stroke:#9e872a;stroke-opacity:1"
+ transform="matrix(0,-1,1,0,104.00001,149.1613)"
+ id="g35349">
+ <path
+ transform="matrix(0,1,-1,0,149.1613,-83.00001)"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 187.5,53.75 0,-2.25 -2,0"
+ id="path35351"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0,-1,1,0,-6.83869,189.16129)"
+ sodipodi:nodetypes="cz"
+ id="path35353"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0,-1,1,0,33.1613,278.99999)"
+ id="path35355"
+ d="m 187.5,53.5 0,-2 -2,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0,1,-1,0,189.16129,6.83869)"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35357"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-89.8387,39.99999)"
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 187.5,53.5 0,-2 -2,0"
+ id="path35359"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-1,0,0,-1,182.3226,195.99998)"
+ sodipodi:nodetypes="cz"
+ id="path35361"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ id="path35363"
+ d="m 187.5,53.5 0,-2 -2,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35365"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(21,0)"
+ id="g35367">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g35369">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path35371"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path35373"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,3 -1,0 0,-2 -2,0 0,-1 3,0 z"
+ id="path35375"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g35377"
+ style="opacity:0.3"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ style="fill:#2b2600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35379"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g35381"
+ transform="matrix(-1,0,0,-1,383,116)">
+ <g
+ id="g35383"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35385"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 5.5,-5.5"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35387"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35391"
+ d="m 188,51 0,3 -1,0 0,-2 -2,0 0,-1 3,0 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.3"
+ id="g35393">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35395"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#2b2600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0,-1,1,0,144,239)"
+ inkscape:transform-center-y="-3.125"
+ inkscape:transform-center-x="3.125"
+ id="g35398">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g35400">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path35405"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path35407"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 85.6613,103.49999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,3 -1,0 0,-2 -2,0 0,-1 3,0 z"
+ id="path35409"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g35411"
+ style="opacity:0.3"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ style="fill:#2b2600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path35413"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-16,0)"
+ id="g35415">
+ <path
+ sodipodi:nodetypes="cz"
+ id="path35417"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 223.5,63.5 218,58"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35420"
+ d="m 225,65 -3,0 0,-1 2,0 0,-2 1,0 0,3 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0,-1,-1,0,611,-152)"
+ style="opacity:0.3"
+ id="g35422">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35424"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#2b2600;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g35426"
+ transform="translate(139.00002,324)"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(-340.00002,-121.00001)"
+ id="g35429">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9ddaf;stroke-width:0.49999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35431"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.9999998,0,0,2.0000014,-462.99991,-192.00026)" />
+ <path
+ transform="matrix(2.5714449,0,0,2.5714449,-728.43612,-302.00313)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35433"
+ style="opacity:0.15;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#fffc28;stroke-width:0.38888648;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.3;fill:#e1d98e;fill-opacity:1;fill-rule:nonzero;stroke:#f0d700;stroke-width:0.50000638;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35437"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.9999748,0,0,1.9999748,-462.98824,-191.99513)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#fbf7e5;fill-opacity:1;fill-rule:nonzero;stroke:#474213;stroke-width:0.63000238;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35439"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.428566,0,0,1.428566,-197.56891,-81.998957)" />
+ </g>
+ </g>
+ <rect
+ y="395"
+ x="264"
+ height="2"
+ width="2"
+ id="rect35441"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g35443"
+ transform="translate(147,358.99999)">
+ <rect
+ y="50"
+ x="131"
+ height="16"
+ width="16"
+ id="rect35445"
+ style="opacity:0;fill:#ffe680;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.85;fill:#f5efb2;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#38330e;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 144.5,63.5 -1,0 -2.5,-1 -1.5,3 -1,0 -1.5,-3 -2.5,1 -1,10e-7 0,-1.000001 1,-2.5 -3,-1.5 0,-1 3,-1.5 -1,-2.5 0,-1 1,0 2.5,1 1.5,-3 1,0 1.5,3 2.5,-1 1,0 0,1 -1,2.5 3,1.5 0,1 -3,1.5 1,2.5 0,1 z"
+ id="path35447"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g35449">
+ <path
+ transform="matrix(1.9999998,0,0,2.0000014,-790.00001,-327.00035)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35451"
+ style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#e9ddaf;stroke-width:0.49999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#fff6d5;stroke-width:0.38888386;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35453"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(2.5714622,0,0,2.5714622,-1055.4442,-437.00638)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#b5a51f;fill-opacity:1;fill-rule:nonzero;stroke:#463f00;stroke-width:0.39999822;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35455"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(2.0000089,0,0,2.0000089,-790.00413,-327.00163)" />
+ <rect
+ ry="2.5"
+ rx="2.5"
+ y="55"
+ x="136"
+ height="5"
+ width="5"
+ id="rect35457"
+ style="opacity:0.9;fill:#ffed55;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.9;fill:#fbfaef;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35459"
+ width="3.75"
+ height="3.75"
+ x="136.25"
+ y="55.25"
+ rx="1.875"
+ ry="1.875" />
+ <rect
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35461"
+ width="2"
+ height="2"
+ x="137"
+ y="56" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g35463"
+ transform="translate(189,316.99999)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35465"
+ width="16"
+ height="16"
+ x="152"
+ y="92" />
+ <g
+ clip-path="url(#clipPath31849)"
+ style="opacity:0.25;display:inline;filter:url(#filter30564);enable-background:new"
+ transform="matrix(1.6519496,0,0,1.6519309,-230.47015,-63.200317)"
+ id="g35467">
+ <path
+ transform="matrix(2.2376043,0,0,2.2484492,-801.20081,-335.84886)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path35469"
+ style="opacity:0.1;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#fff6aa;stroke-width:0.26988116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#ffe400;stroke-width:0.31863192;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35471"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.9004611,0,0,1.899214,-644.62036,-268.6269)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffeeaa;fill-opacity:1;fill-rule:nonzero;stroke:#b4b200;stroke-width:0.38825312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35473"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(1.5591172,0,0,1.559203,-486.06699,-203.16445)" />
+ </g>
+ <g
+ transform="translate(-55,-1)"
+ style="opacity:0.6"
+ id="g35477">
+ <g
+ id="g35480">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.5,102 0,4.5"
+ id="path35482"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#2b2600;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ id="path35484"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g35486">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path35488"
+ d="m 219.5,101.5 0,5.5"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35490"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ style="fill:none;stroke:#ffffd5;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0,1,-1,0,261,-124)"
+ id="g35493"
+ style="opacity:0.6">
+ <g
+ id="g35496">
+ <path
+ id="path35498"
+ d="m 219.5,102 0,4.5"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35500"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ style="fill:none;stroke:#2b2600;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g35502">
+ <path
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.5,101.5 0,5.5"
+ id="path35504"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffd5;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 221.75,105.25 -2.25,2.25 -2.25,-2.25"
+ id="path35506"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-41,41)"
+ style="opacity:0.65;display:inline;enable-background:new"
+ id="g35508">
+ <g
+ transform="translate(21,21)"
+ id="g35510">
+ <path
+ id="path35512"
+ d="m 174.5,40.5 0,3 3,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 175.5,42.5 5.75,-5.75"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35514"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g35516"
+ transform="matrix(-1,0,0,-1,383,116)">
+ <g
+ id="g35518"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35520"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 6.25,-6.25"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35522"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35524"
+ d="m 188,51 0,4 -1,0 0,-3 -3,0 0,-1 4,0 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g35526">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35528"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#b5a731;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <path
+ style="opacity:0.15;fill:#e1d18e;fill-opacity:1;fill-rule:nonzero;stroke:#ffeeaa;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30556);enable-background:accumulate"
+ d="m 161.5,95.5 3,3"
+ id="path35530"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path35532"
+ d="m 161.5,94.5 4,4"
+ style="opacity:0.25;fill:#ffdd55;fill-opacity:1;fill-rule:nonzero;stroke:#ffed55;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30552);enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#5a5310;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 161.5,93.5 5,5"
+ id="path35534"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path35536"
+ d="m 161.5,93.5 5,5"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#fbf7e5;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g35538"
+ transform="translate(168,295.99999)">
+ <rect
+ y="113.00001"
+ x="152"
+ height="16"
+ width="16"
+ id="rect35540"
+ style="opacity:0.01000001;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-21,21.000005)"
+ id="g35542">
+ <path
+ sodipodi:nodetypes="cscccc"
+ id="path35544"
+ d="m 177,94.75 c 0,0 -0.47556,3.774441 2.5,6.75 2.97556,2.97556 7,2.5 7,2.5 3.44436,-0.63991 2.99995,-3.42845 0.0937,-4.5 -1.83387,-3.557342 -2.66053,-4.290113 -5.09375,-5.09375 -0.64623,-3.372957 -3.91818,-2.771894 -4.5,0.34375 l 5e-5,0 z"
+ style="opacity:0.12000002;fill:#fff6aa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30544);enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssscccc"
+ id="path35546"
+ d="m 179.15625,93.71875 c 0,0 -0.3702,1.0264 -0.21875,2.1875 0.15145,1.1611 0.76936,2.613109 2.15625,4 1.38689,1.38689 2.8389,2.0048 4,2.15625 1.1611,0.15145 2.1875,-0.21875 2.1875,-0.21875 1.01828,-0.43147 1.49397,-1.60672 1.0625,-2.625 l -5.65501,-5.846474 c -1.32148,-1.409979 -2.40864,-0.889298 -3.53249,0.346474 z"
+ style="opacity:0.17000002;fill:#ffed55;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30580);enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.5121167,0,0,0.5121167,89.625148,47.477443)"
+ style="opacity:0.18000004;fill:#fff6aa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter30580);enable-background:accumulate"
+ d="m 179.15625,93.71875 c 0,0 -0.3702,1.0264 -0.21875,2.1875 0.15145,1.1611 0.76936,2.613109 2.15625,4 1.38689,1.38689 2.8389,2.0048 4,2.15625 1.1611,0.15145 2.1875,-0.21875 2.1875,-0.21875 1.01828,-0.43147 1.49397,-1.60672 1.0625,-2.625 l -5.65501,-5.846474 c -1.32148,-1.409979 -2.40864,-0.889298 -3.53249,0.346474 z"
+ id="path35548"
+ sodipodi:nodetypes="cssscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path35550"
+ d="m 176.5,93.5 c 0,0 5.75,-0.25 8.5,2.5 2.75,2.75 2.5,8.5 2.5,8.5"
+ style="fill:none;stroke:#5a5310;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#fbf7e5;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 176.5,93.5 c 0,0 5.75,-0.25 8.5,2.5 3,3 2.5,8.5 2.5,8.5"
+ id="path35552"
+ sodipodi:nodetypes="czs"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-42,63.000005)"
+ style="opacity:0.65;display:inline;enable-background:new"
+ id="g35554">
+ <g
+ transform="translate(21,21)"
+ id="g35556">
+ <path
+ id="path35558"
+ d="m 174.5,40.5 0,3 3,0"
+ style="fill:none;stroke:#2b2600;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 175.5,42.5 6.25,-6.25"
+ style="fill:none;stroke:#2b2600;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35561"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g35563"
+ transform="matrix(-1,0,0,-1,383,116)">
+ <g
+ id="g35566"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35568"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 85.6613,103.49999 7,-7"
+ style="opacity:0.85;fill:none;stroke:#f4f1d7;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path35570"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35572"
+ d="m 188,51 0,4 -1,0 0,-3 -3,0 0,-1 4,0 z"
+ style="fill:#fffbd5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g35574">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path35576"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#b5a731;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g36448"
+ transform="translate(41.84997,0.15003049)">
+ <g
+ transform="translate(105,416)"
+ id="g36297">
+ <g
+ id="g36211"
+ transform="translate(194.04507,17.48225)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36215"
+ d="m 90.45451,103.98095 0,7 7.00045,0.0368 0,-7 -7.00045,-0.0368 z"
+ style="opacity:0.8;fill:none;stroke:#333333;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cccccc;fill-opacity:0.15686275;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 90.45451,103.98095 4.5e-4,7.03677 7,0 -4.5e-4,-7.03677 -7,0 z"
+ id="path36228"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="127.49997"
+ x="290.50015"
+ height="3"
+ width="2.9998772"
+ id="rect36230"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36232"
+ width="2.9998772"
+ height="3"
+ x="282.49982"
+ y="119.5"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="127.49997"
+ x="282.50015"
+ height="3"
+ width="2.9998772"
+ id="rect36234"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 293.0003,127.99997 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 l 0,0 0,0 0,0 z"
+ id="path36237"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36239"
+ d="m 285.00045,128 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36241"
+ d="m 285,120 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36243"
+ width="2.9998772"
+ height="3"
+ x="290.49988"
+ y="119.49997"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36245"
+ d="m 293.00003,119.99997 c -0.6694,0 -1.3388,10e-6 -2.0082,10e-6 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36312"
+ width="16"
+ height="16"
+ x="383"
+ y="535" />
+ <g
+ id="g36314"
+ transform="translate(334.99992,111)">
+ <rect
+ y="429.54614"
+ x="48.499996"
+ height="9.9538488"
+ width="10.000013"
+ id="rect36316"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <rect
+ ry="0"
+ style="fill:url(#linearGradient36468);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36318"
+ width="9.0000706"
+ height="9.0003176"
+ x="49.000011"
+ y="430" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path36320"
+ d="m 49,430 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m 3,3 -3,0 0,3 3,0 0,-3 z m -6,3 0,-3 -3,0 0,3 3,0 z"
+ style="fill:url(#linearGradient36470);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36324"
+ d="m 57.50001,430.49999 -8.000011,10e-6 1.1e-5,7.99999 8,0 -1.1e-5,-7.99999"
+ style="fill:none;stroke:url(#linearGradient36472);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(250,-41.00755)"
+ id="g36511" />
+ <g
+ style="opacity:0.55;display:inline"
+ id="g35729"
+ transform="translate(69,-158)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35731"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
+ <g
+ transform="translate(1,0)"
+ id="g35733">
+ <g
+ transform="translate(-386,446.5)"
+ id="g35735">
+ <path
+ id="path35737"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path35739"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g35741">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path35743"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path35745"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient36713);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ id="path35747"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient36715);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35749"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient36717);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ id="path35751"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(90,-158)"
+ id="g35753"
+ style="opacity:0.55;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect35755"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35757"
+ transform="translate(1,0)">
+ <g
+ id="g35759"
+ transform="translate(-386,446.5)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ id="path35761"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path35763"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g35765"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path35767"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path35769"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path35772"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient36719);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect35774"
+ style="fill:url(#linearGradient36721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path35776"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient36723);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="181"
+ x="7.0214434"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35803">
+ <path
+ style="fill:none;stroke:#542b00;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 8.0048608,180.50566 0.036785,0 c 0.8181814,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.6586836,1.49472 -1.476865,1.49472 l -0.036785,0 c -0.8181897,0 -1.4768733,-0.66664 -1.4768733,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.6586836,-1.49473 1.4768733,-1.49473 z"
+ id="path35805"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 9.0203881,181.00394 c -0.6673195,0 -1.334639,1e-5 -2.0019585,1e-5 0,0.66706 0,1.33411 0,2.00119 0.6673195,0 1.334639,-1e-5 2.0019585,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path35807"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="182"
+ x="28"
+ height="8"
+ width="3.0000007"
+ id="rect37868-0-4"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35809"
+ transform="translate(65.984093,-55.50004)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.90196078;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect35811"
+ width="1.9820247"
+ height="8.0116062"
+ x="-38.454918"
+ y="237.00038"
+ transform="matrix(1,2.1226448e-5,0,1,0,0)" />
+ <rect
+ transform="matrix(1,3.6759233e-5,0,1,0,0)"
+ y="237.50137"
+ x="-37.984093"
+ height="7.0000257"
+ width="0.99999994"
+ id="rect35814"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path35816"
+ d="m -37.5,245 -0.9549,0.0112 0,-8.01161 1.982,4e-5"
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g106643">
+ <g
+ transform="translate(111,-158)"
+ id="g35778"
+ style="opacity:0.55;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect35780"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35782"
+ transform="translate(1,0)">
+ <g
+ id="g35785"
+ transform="translate(-386,446.5)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ id="path35787" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path35789"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc" />
+ <g
+ id="g35791"
+ transform="translate(179,-179)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path35793"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35795"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path35797"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient36725);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect35799"
+ style="fill:url(#linearGradient36727);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35801"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient36729);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37868-0-4-8"
+ width="3.0000007"
+ height="7.25"
+ x="54"
+ y="185" />
+ <g
+ id="g35818"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-1080.9861,-256)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1130.4859,445.25 0,-7.5 6,2.75 0,8 -6,-3.25 z"
+ id="path35820"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path35822"
+ d="m 1136.4859,448.5 -6,-3.25 0,-7.5"
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,532,25)"
+ id="g37386"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37388"
+ width="16"
+ height="16"
+ x="343"
+ y="195" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-2.196282,0,0,1.316799,1208.5661,-118.9575)"
+ id="g37390"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path37392"
+ d="m 392.96689,239.5639 -0.56915,0 -4.43932,4.36665 0,1.13912 4.43932,4.36665 0.56911,-1e-5 0,-9.87242 0,0 4e-5,1e-5 0,0 z"
+ style="fill:url(#linearGradient37396);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.58802557px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path37394"
+ d="m 392.51157,247.91748 0,-7.59417 -4.09783,3.98695 0,0.3797"
+ style="fill:none;stroke:url(#linearGradient37398);stroke-width:0.58802563px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#fffeaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect39658"
+ width="1"
+ height="0"
+ x="-25"
+ y="67" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect39660"
+ width="0"
+ height="1"
+ x="-24"
+ y="66" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g39029"
+ transform="matrix(0,1,1,0,248,835)">
+ <rect
+ style="opacity:0.01000001;fill:#909090;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38783"
+ width="16"
+ height="16"
+ x="-259"
+ y="72" />
+ <path
+ sodipodi:nodetypes="csasc"
+ id="path38785"
+ d="m -257.5,83.5 2,0 c 2,0 2.50929,2 4,2 1.49071,0 2,-2 4,-2 l 2,0"
+ style="fill:none;stroke:#001c46;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#aaccff;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -257.5,83.5 2,0 c 2,0 2.50929,2 4,2 1.49071,0 2,-2 4,-2 l 2,0"
+ id="path38787"
+ sodipodi:nodetypes="csasc"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="matrix(1,0,0,-1,-235,265)"
+ id="g38789">
+ <path
+ transform="translate(-1,2)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -16,180 0,6 -1,0 0,-1.75 -1,1.75 0,1.5 2,2.5 6,0 1,-2 0,-3.25 -0.75,-0.75 -0.25,0 0,1 -1,0 0,-1 -0.75,-0.75 -0.25,0 0,1.75 -1,0 0,-1.5 -0.75,-1 -0.25,0 0,2.5 -1,0 0,-5 -1,0 z"
+ id="path38791"
+ sodipodi:nodetypes="cccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g38794"
+ transform="translate(-1,2)">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccccc"
+ id="path38796"
+ d="m -16,179.5 0,6.5 -1,0 0,-2 -0.25,0 -0.75,2 0,1.5 2,2.5 6,0 1,-2 0,-3.25 -0.75,-0.75 -0.25,0 0,1 -1,0 0,-1 -0.75,-0.75 -0.25,0 0,1.75 -1,0 0,-1.5 -0.75,-1 -0.25,0 0,2.5 -1,0 0,-5.5 -1,0 z"
+ style="fill:url(#linearGradient39048);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -15,187 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+ id="path38799"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38801"
+ d="m -15,185 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -13,185 0,1 1,0 0,-1 -1,0 z"
+ id="path38803"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38805"
+ d="m -11,185 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient39050);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -18,186 0,1 1,0 0,-3 -0.25,0 -0.75,2 z"
+ id="path38807"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38810"
+ d="m -17.25,187.5 1.5,2 5.25,0 1,-2 0,-0.5"
+ style="fill:none;stroke:url(#linearGradient39052);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -14.00935,182.77669 0,1 1,0 0,-1 -1,0 z"
+ id="path38819"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38821"
+ d="m -11.978216,183.55574 0,1 1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -11.978216,183.55574 0,1 1,0 0,-1 -1,0 z"
+ id="path38823"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38825"
+ d="m -16,180 0,1 1,0 0,-1 -1,0 z"
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.40000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g39803"
+ transform="translate(-66,268)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\sss.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="-27"
+ x="155"
+ height="16"
+ width="15.999955"
+ id="rect39805"
+ style="opacity:0;fill:#808000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <g
+ style="opacity:0.6;display:inline;enable-background:new"
+ id="g39807">
+ <path
+ style="fill:url(#linearGradient39835-9);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 157.5,-26.5 c -1.10457,0 -2,0.895431 -2,2 0,1.104569 0.89543,2 2,2 0.0211,0 0.0415,6.5e-4 0.0625,0 0.005,0.02296 0.0259,0.03977 0.0312,0.0625 -0.63487,0.174633 -1.09375,0.747145 -1.09375,1.4375 0,0.828426 0.67157,1.5 1.5,1.5 0.69036,0 1.26287,-0.45888 1.4375,-1.09375 0.18381,0.04305 0.36556,0.09375 0.5625,0.09375 1.38071,0 2.5,-1.119289 2.5,-2.5 0,-1.380711 -1.11929,-2.5 -2.5,-2.5 -0.25351,0 -0.48817,0.05484 -0.71875,0.125 -0.32553,-0.663426 -0.9924,-1.125 -1.78125,-1.125 l 5e-5,0 z"
+ id="path39809"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0,0.1250004,0.1250004,0,143.24995,-37.50005)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient39837-4);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path39811"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path39813"
+ style="fill:url(#linearGradient39839-3);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0,0.25,0.2500001,0,130.49998,-56)" />
+ </g>
+ <g
+ transform="translate(45,-100)"
+ id="g39815">
+ <path
+ style="fill:#214478;stroke:none"
+ d="m 110.5,85.5 c 0,2.25 2,3 3.5,3 2.25,0 3.1933,-1.514034 4,-2.5 l 4.5,-5.5 3,0 0,-2 -4,0 -5.5,5.5 -1.25,-1.5 -3.25,0 -1,1 0,2 z"
+ id="path39817"
+ sodipodi:nodetypes="cszccccccccz"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cszccccccccz"
+ id="path39819"
+ d="m 110.5,85.5 c 0,2.25 2,3 3.5,3 2.25,0 3.46788,-1.244422 4.25,-2.25 L 120,84 l -2,-2 -1.5,1.5 -1,0 0,-1 -1,-1 -3,0 -1,1 0,3 z"
+ style="fill:url(#linearGradient39841-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cszccccccccccccccccz"
+ id="path39821"
+ d="m 110.5,85 c 0,2.25 1.5,3.5 3.75,3.5 2.25,0 3.50071,-1.469729 4.25,-2.5 l 4,-5.5 0.5,0 0.5,0 1,0 1,0 0,-2 -1,0 -1.11272,0 -0.88728,0 -1,0 -5,5 -1,0 0,-1 -1,-1 -3,0 -1,1 0,2.5 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path39823"
+ d="m 118,83 1,0 0,1 1,0 0,-1 -1,0 0,-1 -1,0 0,1 z"
+ style="fill:url(#linearGradient39843-3);stroke-width:1px"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39825"
+ d="m 111.5,82.5 0.75818,0.763059 1.5,0 0.75,-0.75"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="82"
+ x="112"
+ height="1"
+ width="2"
+ id="rect39827"
+ style="opacity:0.6;fill:#000000;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ y="83.5"
+ x="115"
+ height="1.4999981"
+ width="0.99994147"
+ id="rect39829"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39831"
+ d="m 124.5,79.5 -3,0 -5,5 -0.5,0"
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccsc"
+ id="path39833"
+ d="m 111.5,83.5 0,1.271428 c -0.0915,0.859266 0.18827,2.299909 2.00056,2.733557 3.70517,0.886581 6.00049,-3.943221 6.00049,-3.943221"
+ style="fill:none;stroke:url(#linearGradient39845-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-249,193)"
+ id="g41505"
+ style="display:inline">
+ <g
+ style="opacity:0.85"
+ id="g41507">
+ <rect
+ style="opacity:0.5;fill:url(#linearGradient41540);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41509"
+ width="7.8166504"
+ height="3"
+ x="-433.5"
+ y="82"
+ transform="scale(-1,1)" />
+ <rect
+ style="fill:url(#linearGradient41542);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41511"
+ width="8.9931746"
+ height="1"
+ x="-434"
+ y="83"
+ transform="scale(-1,1)" />
+ <rect
+ style="fill:#333333;fill-opacity:0.81960784;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41514"
+ width="2"
+ height="1"
+ x="-430.5"
+ y="83"
+ transform="scale(-1,1)" />
+ </g>
+ <g
+ id="g41613"
+ style="opacity:0.45">
+ <g
+ style="opacity:0.8"
+ id="g41516">
+ <rect
+ y="69"
+ x="422"
+ height="16"
+ width="16"
+ id="rect41518"
+ style="opacity:0.05;fill:url(#radialGradient41666);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41520">
+ <path
+ sodipodi:nodetypes="csscccc"
+ id="path41522"
+ d="m 422.51387,74.4375 c 2.14278,1.6383 5.29475,5.652 6.25,7.5625 0.5,1 1.05394,1.01957 1.5,0 0.875,-2 3.25,-4.75 4.75,-6 l -3.5,-4 c -1.25,1.83839 -2,3.25 -2.75,4.63304 -1.71617,-1.72583 -4.35859,-3.39262 -6.25,-4.13304"
+ style="fill:url(#linearGradient41668);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient41670);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g41524">
+ <g
+ id="g41526">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path41528"
+ d="m 422.51387,73.5 c 1.93909,0.815624 4.07262,1.664731 6,4 l 0.75,0 c 0.82427,-1.547027 1.51287,-2.596571 2.16161,-3.5"
+ style="fill:none;stroke:url(#linearGradient41672);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient41674);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 422.51387,73.5 c 1.93909,0.815624 5.41183,5.25 7,8 1.5,-3 2.75,-4 4.75,-6.25"
+ id="path41530"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient41676);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 428.5,78.5 c 0.95165,-1.519624 1.88025,-3.040081 2.92548,-4.5"
+ id="path41532"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient41582);fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:2.07584167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32513-1"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.4336871,0,0,0.4334311,376.83381,21.772579)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient32529-7);stroke-width:3.1984036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32517-6"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.3127677,0,0,0.3125443,475.3332,36.070149)" />
+ </g>
+ <g
+ transform="translate(-21.1375,-0.42)"
+ id="g42277">
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path42279"
+ style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 99.6375,267.92 1,-1 m -4,4 1,-1 m 5,-5 1,-1 m -10,10 1,-1 m -4,4 1,-1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ d="m 99.6375,267.92 1,-1 m -4,4 1,-1 m 5,-5 1,-1 m -10,10 1,-1 m -4,4 1,-1"
+ style="fill:none;stroke:#ffefaf;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path42281"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="stroke-width:1px"
+ d="M 69.435939,276.52168 71.5,274.5"
+ id="path42595"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g38699"
+ transform="translate(41.834175,191.41501)">
+ <rect
+ y="364.58499"
+ x="47.165825"
+ height="16"
+ width="16"
+ id="rect38701"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.032664,0,0,1.043556,-79.760429,254.38542)"
+ id="g38703">
+ <path
+ transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38705"
+ style="fill:#3771c8;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.22966909;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.666432,0,0,0.659342,42.69924,35.46375)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient38719);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path38707"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38709"
+ style="opacity:0.7;fill:url(#linearGradient38722);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.3631382,0,0,0.3593485,81.755824,69.904768)" />
+ <path
+ transform="matrix(0.9688184,0,0,0.9547322,-131.63668,47.640696)"
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:1.00161445px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter13996)"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ id="path38711"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient38724);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 130.67404,112.3079 c 0.0244,0.78706 -0.15754,1.63085 0.59269,2.02213 0.71197,-0.0434 1.49133,0.64122 1.35667,1.40517 -0.26776,0.77861 0.14071,1.12325 0.95576,1.36401 0.57868,-0.0716 0.79053,-0.93546 0.87357,-1.36401 0.0948,-1.27121 0.51542,-1.09421 0.82108,-1.98991 -0.45733,-0.91502 -0.003,-1.04443 -0.72629,-1.43739 m -1.00945,-3.89288 c -0.4426,0.34378 -0.24372,1.04314 -0.66162,1.39841 -0.45372,0.13628 -0.78226,-0.0605 -1.16771,0.43164 -0.30841,1.10457 0.35004,1.22306 0.90205,1.10457 0.49538,-0.0502 0.61419,-0.94321 0.97928,-0.37853 0.0831,0.10976 0.71917,-0.0403 0.86266,0.18898 0.0669,0.10682 -0.11785,0.0255 -0.14729,0.18955 -0.0428,0.23847 0.27734,0.37341 0.372,0.3824 0.32089,0.0305 0.60005,0.92548 0.83846,1.05499 0,0.46738 0.0924,-0.6774 0.3515,-0.78703 0.22948,-0.0971 0.47929,0.10731 0.5,0 0.29928,-1.55081 -1.26113,-3.00604 -2.82933,-3.58498 z M 128.96474,107.5 c -0.6111,1.01384 0.85343,1.46103 1.73001,1.21329 0.57897,-0.37879 1.00716,-0.92331 0.55665,-1.21329 -0.20614,-0.1415 -2.07706,0.0431 -2.28666,0 l 0,0 0,0 0,0 z m -1.372,1.37253 c -0.49575,-0.14959 0.44952,-0.11945 0.45733,0.45751 0.1696,0.54756 -0.42801,0.23756 0,0.45752 0.70893,0.1644 0.35328,1.70031 -0.28114,1.56208 -0.56042,0.10119 -0.43915,0.95826 -1.64865,0.88279 -0.0836,0.0755 -1.04512,0.61593 -0.81421,1.21521 1.12968,0.30162 -0.36816,1.26478 -0.43867,0.55236 -0.15441,-0.49797 -0.62853,-1.11348 -0.43994,-1.68674 0.11734,-0.63627 0.5689,-1.12263 0.82646,-1.69865 0.36225,-0.61946 0.89084,-1.17688 1.57758,-1.42595 0.21411,-0.16799 0.46159,-0.41691 0.76124,-0.31613 l 0,0 0,0 0,0 z m -0.91467,5.03262 c -0.55163,-0.27585 -0.72934,0.28829 -0.60377,0.7984 0.15577,0.47138 0.52607,0.97695 0.72628,1.43739 0.40435,0.49619 1.512,1.34081 2.17883,1.67696 0.31768,0.16015 0.48418,0 0.24209,-0.23956 -0.31367,-0.6375 -1.14073,-1.94893 -0.48418,-2.15609 0.59647,-0.60342 0.34203,-1.58773 -0.48419,-1.43739 -0.54779,-0.25818 -0.75551,-0.39899 -1.38855,-0.0752 -0.0558,0.0743 -0.12403,0.006 -0.18651,-0.004 l 0,-5.1e-4 0,0 0,0 z"
+ id="path38713"
+ sodipodi:nodetypes="ccccccccccccssscsscccscccccccccccccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.6657538,0,0,0.6588051,42.794535,35.527157)"
+ sodipodi:type="arc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient38726);stroke-width:1.45454657;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path38715"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.06052282,0,0,0.05989117,121.21686,103.80334)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path38717"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ </g>
+ </g>
+ <g
+ transform="translate(179.00003,444.99999)"
+ id="g37955"
+ style="display:inline">
+ <rect
+ y="90"
+ x="162"
+ height="16"
+ width="16"
+ id="rect37957"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="96.749977"
+ x="165.74995"
+ height="1.75"
+ width="2.5"
+ id="rect37959"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,2.75 -5.99999,3.24999 -6.00001,-3.24999 0,-2.75 z"
+ id="path37961"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.96000001;fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37963"
+ width="2"
+ height="7"
+ x="170.98643"
+ y="91.999977" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 164.99996,98.99998 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
+ id="path37965"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path37967"
+ d="m 164.99997,101.74998 -1e-5,-2.25 6,3 0.01,2.49885 -6.00995,-3.24885 -4e-5,0 0,0 0,0 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 176.99996,101.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path37969"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="97.999977"
+ x="165.99995"
+ height="1"
+ width="2"
+ id="rect37971"
+ style="fill:#aa0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37973"
+ width="2"
+ height="1"
+ x="165.99995"
+ y="96.999977" />
+ <rect
+ y="96.999977"
+ x="165.99995"
+ height="2"
+ width="1"
+ id="rect37975"
+ style="opacity:0.5;fill:#ffaaaa;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:url(#linearGradient38005);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 165.49996,99.49998 0,0 0,2 5.5,3 5.5,-3 0,-2"
+ id="path37977"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37979"
+ transform="translate(-114.00004,-232.99999)">
+ <rect
+ y="328.03571"
+ x="285"
+ height="3.9642856"
+ width="2"
+ id="rect37981"
+ style="opacity:0.3;fill:none;stroke:#1a1a1a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#550000;stroke-width:0.59999985;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37983"
+ sodipodi:cx="286"
+ sodipodi:cy="325"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.6666708,0,0,1.6666633,-190.66784,-215.66559)" />
+ <rect
+ y="328.49997"
+ x="285"
+ height="3.5000324"
+ width="2"
+ id="rect37985"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37987"
+ width="1"
+ height="3.5000324"
+ x="285"
+ y="328.49997" />
+ <path
+ transform="matrix(1.333351,0,0,1.333345,-95.338377,-107.33714)"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="325"
+ sodipodi:cx="286"
+ id="path37989"
+ style="fill:url(#linearGradient38007);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.59999985;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <rect
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37991"
+ width="1"
+ height="1"
+ x="284"
+ y="331" />
+ <rect
+ y="332"
+ x="285"
+ height="1"
+ width="2"
+ id="rect37993"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="331"
+ x="287"
+ height="1"
+ width="1"
+ id="rect37995"
+ style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 165.49996,98.99998 5.5,2.75"
+ id="path37997"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37999"
+ mask="url(#mask20957)">
+ <path
+ style="opacity:0.7;fill:none;stroke:#1a1a1a;stroke-width:2.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 168.25,102.75 -0.75,0.75 c -1,1 -0.75,1 -2,1 l -2.25,0"
+ id="path38001"
+ sodipodi:nodetypes="cccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path38003"
+ d="m 168.25,102.75 -0.75,0.75 c -1.25,1.17188 -0.75,1 -2,1 l -3,0"
+ style="fill:none;stroke:#ececec;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38023"
+ width="16"
+ height="16"
+ x="233.39999"
+ y="113.08"
+ rx="0"
+ ry="0" />
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38847"
+ width="16"
+ height="16"
+ x="190"
+ y="94.362419"
+ rx="0"
+ ry="0" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g43388-8"
+ transform="translate(588,446)">
+ <rect
+ y="26"
+ x="-79"
+ height="16"
+ width="16"
+ id="rect43390-2"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g43392-4"
+ clip-path="url(#clipPath43368-1)">
+ <rect
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43394-5"
+ width="6"
+ height="2"
+ x="-72.5"
+ y="31.5"
+ rx="0.79505396"
+ ry="0.79505396" />
+ <rect
+ ry="0.79505396"
+ rx="0.79505396"
+ y="28.5"
+ x="-75.5"
+ height="2"
+ width="6"
+ id="rect43396-5"
+ style="fill:#6996d7;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#6996d7;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43398-1"
+ width="6"
+ height="2"
+ x="-75.5"
+ y="36.5"
+ rx="0.74381745"
+ ry="0.74381745" />
+ <rect
+ ry="0.71819919"
+ rx="0.71819919"
+ y="39.5"
+ x="-72.5"
+ height="2"
+ width="6"
+ id="rect43400-7"
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path43402-1"
+ style="fill:none;stroke:#000000;stroke-width:2.9000001;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43404-1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43406-5"
+ style="opacity:0.4;fill:none;stroke:url(#radialGradient43410-4);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="opacity:0.4;fill:none;stroke:url(#radialGradient43412-8);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43408-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(273,441)"
+ id="g40240">
+ <path
+ id="path40242"
+ style="fill:#89a02c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 52.75,44.25 62.5,34.5 c 0,-1 -0.5,-1.5 -1,-2 -0.498692,-0.498692 -1,-1 -2,-1 l -9.75,9.75 c 1,0 1.501308,0.501308 2,1 0.5,0.5 1,1 1,2 z"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="31"
+ x="47"
+ height="16"
+ width="16"
+ id="rect40244"
+ style="opacity:0.01000001;fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccsccc"
+ d="M 60.75,36.25 62.5,34.5 c 0,-1 -0.5,-1.5 -1,-2 -0.498692,-0.498692 -1,-1 -2,-1 l -1.75,1.75 3,3 z"
+ style="fill:url(#linearGradient40270);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40246"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m 57.5,35.5 -1,-1 -6.75,6.75 1.75,0.25 6,-6 z"
+ style="fill:#bcd35f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40248"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40250"
+ style="fill:#445016;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 59.5,37.25 -1,-0.75 -6,6 0.25,1.5 6.75,-6.75 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path40252"
+ d="m 59.75,37.25 -3,-3"
+ style="fill:none;stroke:url(#linearGradient40272);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40274);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 60.75,36.25 -3,-3"
+ id="path40254"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient40276);fill-opacity:1;stroke-width:1px"
+ d="m 57.75,33.25 2.98375,3.003125 -1.0075,1.0075 -3.0225,-2.98375 L 57.75,33.25 z"
+ id="path40256"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#501616;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 61,36 1.5,-1.5 c 0,-1 -0.5,-1.5 -1,-2 -0.498692,-0.498692 -1,-1 -2,-1 L 58,33"
+ id="path40258"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path40260"
+ d="M 58.25,32.75 50,41 l -2,4 -0.5,0.5 0.25,0.75 0.75,0.25 0.5,-0.5 4,-2 8.25,-8.25"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccsc"
+ id="path40262"
+ d="M 50.25,41 48.5,44.25 49.75,45.5 53,43.75 C 53,43.25 52.5,42.5 52,42 51.501308,41.501308 50.75,41 50.25,41 z"
+ style="fill:url(#linearGradient40278);fill-opacity:1;stroke-width:1px"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#445016;stroke:#22280b;stroke-width:2.4000001;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 48.25,45.75 0.5,-0.5"
+ id="path40264"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path40266"
+ d="M 48.25,45.75 48.5,45.5"
+ style="fill:none;stroke:#9ab432;stroke-width:1.10000002;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round"
+ d="M 52.527427,43.527587 61.514313,34.48568"
+ id="path40268"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40603-2"
+ transform="translate(238,594)">
+ <rect
+ y="-122"
+ x="-44"
+ height="16"
+ width="16"
+ id="rect40445-4"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40447-5"
+ d="m -43.5,-116.75 12.5,-4.75 0.75,2 -13.25,5 0,-2.25 z"
+ style="fill:#1a1a1a;stroke:#000000;stroke-width:0.89999998;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-114.5"
+ x="-42.5"
+ height="7.9999971"
+ width="12.999988"
+ id="rect40449-5"
+ style="fill:url(#linearGradient39686-1);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40451-1"
+ width="1"
+ height="1.5"
+ x="-32"
+ y="-121" />
+ <rect
+ y="-119.41868"
+ x="-36"
+ height="1.5"
+ width="1"
+ id="rect40453-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40455-1"
+ width="1"
+ height="1.5"
+ x="-37"
+ y="-119.16868" />
+ <rect
+ y="-117.62802"
+ x="-41"
+ height="1.5"
+ width="1"
+ id="rect40457-1"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40459-5"
+ width="1"
+ height="1.5"
+ x="-40"
+ y="-117.87802" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40461-2"
+ width="13.999996"
+ height="2.0000052"
+ x="-43.5"
+ y="-114.5" />
+ <rect
+ y="-113"
+ x="-42"
+ height="1.7500292"
+ width="12.154154"
+ id="rect40490-7"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="rect40463-6"
+ d="m -40,-114 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round"
+ d="m -31.5,-120.5 -9.75,3.75"
+ id="path40474-1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient39688-9);stroke-width:1px;stroke-linejoin:round"
+ d="m -41.5,-107.5 0,-6 11,0 0,6 -11,0 z"
+ id="path40476-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#87aade;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -43,-116.75 1,0 1,1.75 0,2 -2,0 0,-3.75 z"
+ id="path40478-2"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#002255;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -41,-115 0,2 -2,0 0,0.75 2.75,0 0,-3 -1.25,-2.25 -1.5,0.25 0,0.5 1,0 1,1.75 z"
+ id="path40480-3"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40558-2"
+ d="m -41.5,-107.38206 0,-4.66445"
+ style="opacity:0.2;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40553-2"
+ width="1"
+ height="1.5"
+ x="-33"
+ y="-120.75" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40556-1"
+ width="1"
+ height="1.25"
+ x="-40"
+ y="-114" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ d="m -42.4975,-113.46527 0,-3.0928"
+ id="path40560-6"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(1,0)"
+ style="opacity:0.35"
+ id="g40590-8">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40586-5"
+ width="5"
+ height="0.9617852"
+ x="-38"
+ y="-110" />
+ <rect
+ y="-111"
+ x="-36"
+ height="3"
+ width="1.0280838"
+ id="rect40588-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ transform="translate(56,-67)"
+ id="g42945"
+ style="display:inline;enable-background:new">
+ <rect
+ y="602"
+ x="327"
+ height="16"
+ width="16"
+ id="rect42947"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g42949">
+ <g
+ style="opacity:0.85"
+ id="g42951">
+ <path
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 341.5161,616.38229 340.5,617.5 l -10.73389,-10e-6 -1.25,-1.25 L 328.5,605.5 l 13,0 0.0161,10.88229 z"
+ id="path42953"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42955"
+ d="m 340,616 -8.25,0 0,-1 8.25,0 0,1 z"
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38927"
+ width="11.970581"
+ height="8.0306396"
+ x="329.02942"
+ y="605.96936" />
+ <rect
+ y="605.96936"
+ x="329.02942"
+ height="8.0306396"
+ width="11.970581"
+ id="rect45307"
+ style="opacity:0.3;fill:url(#radialGradient45309);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42957"
+ d="m 340.48389,606.50001 c -3.66204,-3e-5 -7.70403,2e-5 -10.98389,-10e-6 l 0.002,10.00007 10.99778,-7e-5 -0.0161,-9.99999 2.1e-4,0 z"
+ style="fill:none;stroke:url(#linearGradient42965-7);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="615"
+ x="330"
+ height="1.0000043"
+ width="1"
+ id="rect42959"
+ style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.35;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 340.5,614 -11,0 0,-1 11,0 0,1 z"
+ id="path38929"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.25;fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter24186-3-2)"
+ d="m 337.7,606.7 0,2.75 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.75 2,0 z"
+ id="path42961"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path42963"
+ d="m 333.75,602.5 1.75,0 c 0,0 0,2 0,2 l 2,0 0,-2 1.75,0 0.25,0.25 0,2.5 -2,1.5 0,2.5 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.5 -2,-1.5 0,-2.5 0.25,-0.25 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:url(#linearGradient42967-6);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g29389"
+ transform="translate(-167,402.00001)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29391"
+ width="16"
+ height="16"
+ x="382"
+ y="217" />
+ <g
+ style="opacity:0.8;display:inline"
+ transform="matrix(0.6184922,0,0,0.6183145,308.52384,72.984237)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g29393">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ id="g29395"
+ style="display:inline">
+ <path
+ transform="matrix(0.872933,0,0,0.883992,56.29135,118.6984)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient29407);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.99653149;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path29397"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path29399"
+ style="fill:none;stroke:url(#linearGradient29409);stroke-width:4.85120249;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 134.19651,245.03757 -6.46038,0"
+ inkscape:connector-curvature="0" />
+ <g
+ style="fill:none;stroke:url(#linearGradient29413);stroke-width:1.90771151;stroke-opacity:1;display:inline"
+ id="g29401"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29403"
+ style="fill:none;stroke:url(#linearGradient29411);stroke-width:2.48091555;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.8313677,0,0,0.8366298,61.774434,124.29322)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 133.78064,245.05849 -5.65893,0"
+ style="fill:none;stroke:#000000;stroke-width:2.42560124;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path29405"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-167,402.00001)"
+ id="g41246"
+ style="display:inline">
+ <rect
+ y="217"
+ x="382"
+ height="16"
+ width="16"
+ id="rect41249"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41251"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.6184922,0,0,0.6183145,308.52384,72.984237)"
+ style="opacity:0.8;display:inline">
+ <g
+ style="display:inline"
+ id="g41253"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path41255"
+ style="fill:url(#linearGradient41266);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.99653149;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.872933,0,0,0.883992,56.29135,118.6984)" />
+ </g>
+ <path
+ d="m 134.19651,245.03757 -6.46038,0"
+ style="fill:none;stroke:url(#linearGradient41268);stroke-width:4.85120249;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ id="path41257"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g41260"
+ style="fill:none;stroke:url(#linearGradient41272);stroke-width:1.90771151;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.8313677,0,0,0.8366298,61.774434,124.29322)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient41270);stroke-width:2.48091555;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path41262"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ id="path41264"
+ style="fill:none;stroke:#000000;stroke-width:2.42560124;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 133.78064,245.05849 -5.65893,0"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40887">
+ <g
+ id="g40668">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39989"
+ width="16"
+ height="16"
+ x="215"
+ y="472"
+ rx="0"
+ ry="0" />
+ <g
+ id="g40555">
+ <rect
+ ry="1.7356256"
+ y="475.5"
+ x="215.5"
+ height="11.000039"
+ width="14.000015"
+ id="rect39993"
+ style="fill:url(#linearGradient40918);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.7356256" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path39996"
+ d="m 216.00001,479.40741 0,4.59259 c 0,0.56404 0.36784,1.00001 0.84375,1 l 11.3125,0 c 0.47591,0 0.84375,-0.43595 0.84375,-1 l 0,-4.59259 C 228.6863,479.7792 228.23078,480 227.75001,480 l -10.5,0 c -0.48077,0 -0.93629,-0.2208 -1.25,-0.59259 z"
+ style="fill:url(#linearGradient40920);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.5817194"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39999"
+ width="14.000005"
+ height="2.0000522"
+ x="215.5"
+ y="475.5"
+ ry="0.8750208" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40001"
+ width="14.000006"
+ height="10.999848"
+ x="215.5"
+ y="475.5"
+ ry="1.503511"
+ rx="1.503511" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.75859177;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40005"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.3955004,0,0,1.2452423,115.18334,-141.72474)" />
+ <rect
+ rx="0.5078125"
+ ry="0.4910686"
+ y="476.5"
+ x="216.5"
+ height="9.0000038"
+ width="12.000035"
+ id="rect40008"
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(1.5770887,0,0,1.5999841,100.49326,-321.69208)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path40010"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:0.62952662;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient40922);stroke-width:0.97061968;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40012"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1794014,0,0,0.8999954,131.50687,28.952303)" />
+ <path
+ transform="matrix(1.1827463,0,0,1.2,131.2458,-119.90002)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path40014"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:0.83938956;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient40924);stroke-width:1.26754272;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40016"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.790122,0,0,0.787736,161.87049,87.05649)" />
+ <path
+ transform="matrix(0.5963773,0,0,0.2000006,171.47609,375.5997)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path40020"
+ style="fill:none;stroke:#999999;stroke-width:2.89550138;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 216.48394,475.5 0,-0.50001 c 0,-0.276 0.67629,-0.5 1.50958,-0.5 0.83329,0 1.50958,0.224 1.50958,0.5 l 0,0.50001"
+ id="path40022"
+ sodipodi:nodetypes="csccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="475"
+ x="217"
+ height="1"
+ width="2"
+ id="rect40024"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="477"
+ x="226"
+ height="1"
+ width="2"
+ id="rect40026"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#radialGradient40926);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40028"
+ width="2"
+ height="1"
+ x="226"
+ y="477" />
+ <rect
+ y="478"
+ x="218"
+ height="1"
+ width="1"
+ id="rect40030"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#radialGradient40928);stroke-width:0.67151165;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40032"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1827463,0,0,1.2,131.2458,-119.90002)" />
+ <path
+ transform="matrix(0.8888868,0,0,0.8862026,154.16683,37.626266)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path40034"
+ style="fill:url(#radialGradient40930);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40036"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.1975308,0,0,0.1999991,207.09261,381.10045)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#radialGradient40932);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40043"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-0.8867575,0.06148883,-0.06130315,-0.8840797,323.44127,921.51187)" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.9986805,0,0,1,-92.569205,199)"
+ id="g25007-8"
+ style="display:inline;enable-background:new">
+ <rect
+ ry="1.2018067"
+ style="opacity:0.4;fill:none;stroke:#fac900;stroke-width:4.00264168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25009-2"
+ width="3.0039635"
+ height="3"
+ x="318.99011"
+ y="275"
+ rx="1.2018067" />
+ <rect
+ ry="1.2018068"
+ rx="1.2018068"
+ y="275"
+ x="318.99011"
+ height="3"
+ width="3.0039637"
+ id="rect25011-4"
+ style="opacity:0.8;fill:none;stroke:#e6b800;stroke-width:2.00132084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32046-5"
+ d="m 318.99011,278 c 0,-1.00003 3e-5,-2.00003 3e-5,-3.00006 1.00131,0 2.00262,0 3.00393,0 0,1.00003 -3e-5,2.00003 -3e-5,3.00006 -1.00131,0 -2.00262,0 -3.00393,0 z"
+ style="fill:#aa8800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25013-5"
+ d="m 318.48945,276 1.25165,-0.25 1.50199,0 1.25162,0.25001 0,1.00005 -1.25162,0.24994 -1.50199,0 -1.25165,-0.24995 0,-1.00005 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 319.99139,278.50006 -0.25029,-1.25006 0,-1.5 0.2503,-1.25 1.00137,0 0.25032,1.25 0,1.5 -0.25033,1.25006 -1.00137,0 0,0 0,0 0,0 z"
+ id="path25015-1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(259,168)"
+ mask="url(#mask38561)"
+ id="g40090" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
+ transform="scale(-1,1)"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40274"
+ width="16"
+ height="16"
+ x="-252"
+ y="514" />
+ <rect
+ y="514"
+ x="-272"
+ height="16"
+ width="16"
+ id="rect41293"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(1,0)"
+ id="g36512">
+ <rect
+ style="opacity:0.01000001;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36514"
+ width="16"
+ height="16"
+ x="109"
+ y="472" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient36549);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 110.5,472.5 13.98222,2e-5 0,14.96443 -13.98222,-2e-5 0,-14.96443 z"
+ id="path36516"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36518"
+ d="m 111.49999,485.48369 0,-11.00155 10.99999,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:url(#radialGradient36551);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 112,474 11,0 0,11 -11,0 0,-11 z"
+ id="path36521"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36523"
+ d="m 112.5,474.5 9.98224,0 0,10 -9.98224,0 0,-10 z"
+ style="fill:url(#linearGradient36553);fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#4d4d4d;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 112.5,484.5 0,-10 9.98224,0"
+ id="path36525"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39496">
+ <path
+ transform="matrix(0.2498674,0,0,0.249916,83.518554,451.9933)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient36555);stroke-width:4.00173378;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36527"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path36529"
+ d="m 119,475.50001 c -1.44825,0 -1.50029,0.42731 -1.50029,0.85462 l 2.2e-4,4.27306 c 0,0.85461 0.052,0.85461 1.50029,0.85461 1.44823,0 1.49984,0.0467 1.49984,-0.85461 l 0,-4.27306 c 0,-0.42731 -0.0518,-0.85462 -1.50006,-0.85462 z"
+ style="fill:url(#linearGradient36557);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient36559);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 118.99995,475.50001 c -1.44821,0 -1.50025,0.42731 -1.50025,0.85461 l 2.2e-4,4.27306 c 0,0.85462 0.052,0.85462 1.50025,0.85462 1.44821,0 1.49982,0.0467 1.49982,-0.85462 l 0,-4.27306 c 0,-0.4273 -0.0518,-0.85461 -1.50004,-0.85461 z"
+ id="path36531"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36533"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.1876323,0,0,0.1876688,91.733582,459.33847)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36535"
+ style="fill:#ffffff;stroke:url(#linearGradient36561);stroke-width:12.91347408;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.1154571,0,0,0.1168626,101.25809,467.69987)" />
+ <g
+ style="opacity:0.7"
+ id="g36537">
+ <path
+ transform="matrix(1.1428645,0,0,1.1428645,-416.36057,256.4986)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path36539"
+ style="opacity:0.15;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffdd55;stroke-width:0.87499446;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:#ffd42a;stroke-width:1.74999654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36541"
+ sodipodi:cx="464.5"
+ sodipodi:cy="192.5"
+ sodipodi:rx="1.75"
+ sodipodi:ry="1.75"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ transform="matrix(0.5714297,0,0,0.5714297,-150.92912,366.49979)" />
+ <rect
+ y="476"
+ x="113.99994"
+ height="1"
+ width="1"
+ id="rect36543"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36545"
+ width="2"
+ height="1"
+ x="118"
+ y="476" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36547"
+ style="fill:none;stroke:url(#linearGradient36563);stroke-width:4.00173378;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.2498674,0,0,0.249916,83.518554,451.9933)" />
+ </g>
+ </g>
+ <g
+ transform="translate(-810.9,-131)"
+ id="g40730"
+ style="display:inline;enable-background:new">
+ <g
+ id="g40736"
+ transform="translate(583.99999,91.500124)"
+ style="display:inline;enable-background:new" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g39239"
+ transform="translate(-369,-131)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path39241"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient39254);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:url(#radialGradient39256);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path39243"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient39258);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path39245"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ id="path39247"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path39249"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39251"
+ d="m 757.5,206.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient39260);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-705,268)"
+ id="g36639"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient36657);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path36641"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path36643"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient36659);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36646"
+ style="fill:none;stroke:url(#linearGradient36661);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36649"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path36653"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient36663);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path36655"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g37112"
+ transform="translate(-42,0)">
+ <g
+ transform="matrix(-1,0,0,1,887,548.02778)"
+ style="opacity:0.8;display:inline;enable-background:new"
+ id="g36742">
+ <rect
+ style="opacity:0;fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36744"
+ width="16"
+ height="16"
+ x="488"
+ y="29" />
+ <g
+ id="g36746">
+ <path
+ sodipodi:nodetypes="csccccccccsssc"
+ id="path36748"
+ d="m 500.5,34.5 0,5 c 0,1.666667 0.25,1.75 1,3.25 l -1.25,1.75 -1.75,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -1,0 C 491,43 490.5,42.416667 490.5,40.75 l 0,-6.25 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ style="fill:url(#linearGradient37132);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 495.5,30.375 c -2.28774,0 -4.125,1.837258 -4.125,4.125 l 0,6.25 c 0,0.74605 0.0978,1.170828 0.28125,1.625 0.13101,0.324408 0.38353,0.789244 0.625,1.25 l 0.0937,0 1.5,-1.5 a 0.87292083,0.87292083 0 0 1 1.25,0 l 1.375,1.375 1.375,-1.375 a 0.87292083,0.87292083 0 0 1 1.1875,-0.03125 l 1.375,1.21875 0.1875,-0.1875 0,-0.4375 C 500.24057,42.152166 499.91254,41.661109 499.78125,41.125 499.62101,40.470677 499.625,39.833334 499.625,39 l 0,-4.5 c 0,-2.287742 -1.83726,-4.125 -4.125,-4.125 z"
+ id="path36750"
+ style="fill:none;stroke:url(#linearGradient37134);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 495.5 29.5 C 492.74 29.5 490.5 31.74 490.5 34.5 L 490.5 40.75 C 490.5 42.416667 491 43 491.75 44.5 L 492.75 44.5 L 494.5 42.75 L 496.25 44.5 L 496.75 44.5 L 498.5 42.75 L 500.5 44.5 L 501.5 43.5 L 501.5 42.5 C 500.5 41.25 500.5 40.666667 500.5 39 L 500.5 34.5 C 500.5 31.74 498.26 29.5 495.5 29.5 z "
+ inkscape:radius="-0.87283355"
+ sodipodi:type="inkscape:offset" />
+ <g
+ style="opacity:0.25;fill:#000000"
+ id="g36752">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 493,43.75 c 0,-0.212963 0,-5.75 0,-5.75 l 1.5,4.472222 L 493,43.75 z"
+ id="path36754"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36756"
+ d="m 497,44 c 0,-0.203703 -1,-6 -1,-6 l 2,3.428571 0,1.714286 L 497,44 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,990,0.25)"
+ id="g36758"
+ style="opacity:0.7;fill:#ffffff">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path36760"
+ d="m 493,43.75 c 0,-0.212963 1,-6 1,-6 l 1,5 -1,1 -1,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 497,43.75 c 0,-0.203703 0,-6 0,-6 l 2,5 -1,1 -1,0 z"
+ id="path36762"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m 490,43.25 c 0,-0.212963 1.5,-6.25 1.5,-6.25 l 0.5,5.5 -2,0.75 z"
+ id="path36764"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 500.5,34.5 0,4.5 c 0,1.666667 0,2.25 1,3.5 l 0,1 -1,1 -2,-1.75 -1.75,1.75 -0.5,0 -1.75,-1.75 -1.75,1.75 -0.5,0 C 491,43 490.5,43.166667 490.5,41.5 l 0,-7 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+ id="path36766"
+ sodipodi:nodetypes="cscccccccccsssc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path36768"
+ d="m 56,139 0,1 -1,0 0,1 2,0 0,-2 -1,0 z"
+ style="opacity:0.8;fill:url(#linearGradient37136);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.8;fill:url(#linearGradient37138);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 51,139 0,2 2,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36770"
+ sodipodi:nodetypes="ccccccc"
+ transform="translate(441,-105)"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="opacity:0.65;fill:#000000;fill-rule:evenodd;stroke:#2b0000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 385.5,578.5 12,12"
+ id="path36738"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path36740"
+ d="m 385.5,578.5 12,12"
+ style="fill:none;stroke:#ff5555;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(87.000001,33.999969)"
+ id="g37053"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\render layers 2.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="459.00003"
+ x="-61.000011"
+ height="16"
+ width="16"
+ id="rect37055"
+ style="opacity:0.01000001;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.9778614,0.2092535,-0.2092535,0.9778614,137.19272,32.846168)"
+ style="display:inline;enable-background:new"
+ id="g37057"
+ inkscape:transform-center-x="6.529123"
+ inkscape:transform-center-y="4.2273311">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -98.435716,459.41623 9.935716,0.0838 0,10.99997 -9.935716,-0.0838 0,-10.99997 z"
+ id="path37059"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.8656081"
+ inkscape:original="M -98.4375 459.40625 L -98.4375 470.40625 L -88.5 470.5 L -88.5 459.5 L -98.4375 459.40625 z "
+ style="fill:url(#linearGradient37089);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37061"
+ d="m -97.5625,460.28125 0,9.25 8.1875,0.0937 0,-9.25 -8.1875,-0.0937 z" />
+ </g>
+ <g
+ id="g37063"
+ style="display:inline;enable-background:new"
+ transform="translate(38.999989,0)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path37065"
+ d="m -99.499989,459.50003 10.999989,-10e-6 0,10.99997 -10.999989,10e-6 0,-10.99997 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#linearGradient37091);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -97.999989,461 7.99998,0 0,8 -7.99998,0 0,-8 z"
+ id="path37067"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.5714297,0,0,0.5714297,-362.92909,351.49978)"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
+ sodipodi:ry="1.75"
+ sodipodi:rx="1.75"
+ sodipodi:cy="192.5"
+ sodipodi:cx="464.5"
+ id="path37069"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#d4aa00;stroke-width:1.74999654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path37071"
+ d="m -98.49992,460.49999 9.00002,0 0,9.00003 -9.00002,0 0,-9.00003 z"
+ style="fill:none;stroke:url(#linearGradient37093);stroke-width:0.99999952px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffe680;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37073"
+ width="1"
+ height="1"
+ x="-98"
+ y="461" />
+ <rect
+ y="461.5"
+ x="-94.500008"
+ height="5"
+ width="3"
+ id="rect37075"
+ style="fill:url(#linearGradient37096);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient37098);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37077"
+ width="3"
+ height="5"
+ x="-94.500008"
+ y="461.5"
+ rx="0.46547449"
+ ry="0.46547449" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37079"
+ width="2"
+ height="1"
+ x="-94.000008"
+ y="462" />
+ <path
+ transform="matrix(0.1904433,0,0,0.1904803,-120.13881,444.5233)"
+ sodipodi:type="arc"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#4d4d4d;stroke-width:5.25039816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path37081"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ ry="0.46547449"
+ rx="0.46547449"
+ y="461.5"
+ x="-94.500008"
+ height="5"
+ width="3"
+ id="rect37083"
+ style="fill:none;stroke:url(#linearGradient37100);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(0.07365497,0,0,0.07463961,-104.72475,458.19728)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient37102);stroke-width:20.23044777;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path37085"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37087"
+ style="fill:none;stroke:url(#linearGradient37104);stroke-width:5.25039816;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.1904433,0,0,0.1904803,-120.13881,444.5233)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37514"
+ transform="translate(-327.01257,-130.96121)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path37516"
+ d="m 757.01257,204.46121 9.48743,0.0388 0,14.99999 -13,0 0.0126,-11.53879 3.5,-3.5 -3e-5,0 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37518"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <g
+ id="g37520">
+ <rect
+ style="fill:#e9afaf;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37522"
+ width="9.9999914"
+ height="12"
+ x="-83"
+ y="94" />
+ <rect
+ y="101"
+ x="-83"
+ height="4.9999976"
+ width="9.9999924"
+ id="rect37524"
+ style="opacity:0.5;fill:#4b7fcd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="94"
+ x="-83"
+ height="6.8499999"
+ width="9.9999914"
+ id="rect37526"
+ style="opacity:0.3;fill:url(#radialGradient37553);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path37528"
+ d="m -83,100.00002 1,0 1,0.74999 1,-0.74999 1,0.99999 2,0 1.5,-0.75 1.5,0.75 0.999991,0 L -73,102 l -9.999991,0 -9e-6,-1.99998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37530"
+ width="2.0000029"
+ height="2.0000038"
+ x="-77"
+ y="96" />
+ <path
+ style="opacity:0.3;fill:#2b0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -83,102 10,0 0,1 -10,0 0,-1 z"
+ id="path37532"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37534"
+ d="m -77,102 2.000003,0 -0.750003,4 -0.5,0 -0.75,-4 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g37536"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37538"
+ d="m -82.5,105.5 0,-11 9,0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -82.5,105.5 0,-11 9,0 0,11 -9,0 z"
+ id="path37540"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#radialGradient37555);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 757.51257,204.46121 9,1e-5 0,14.99999 -13,0 0,-11 4,-4 z"
+ id="path37542"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="M 754.51257,209.96121 754.5,218.5 M 759.01257,205.46121 765.5,205.5"
+ style="opacity:0.1;fill:none;stroke:url(#linearGradient37558);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path37544"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753.01257,208.96121 5,0 0,-5 -5,5 z"
+ id="path37546"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="M 753.51257,207.96121 753.5,219.5 l 13,0 0,-14.99999 -9.48743,-0.0388 -3.5,3.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path37549"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37551"
+ d="m 758.51257,206.46121 0,3 -3,0"
+ style="fill:none;stroke:url(#linearGradient37561);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37514-4"
+ transform="translate(-726.01257,268.03879)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path37516-1"
+ d="m 757.01257,204.46121 9.48743,0.0388 0,14.99999 -13,0 0.0126,-11.53879 3.5,-3.5 -3e-5,0 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37518-1"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <g
+ id="g37520-3">
+ <rect
+ style="fill:#ebb5b5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37522-8"
+ width="9.9999914"
+ height="12"
+ x="-83"
+ y="94" />
+ <rect
+ y="101"
+ x="-83"
+ height="4.9999976"
+ width="9.9999924"
+ id="rect37524-7"
+ style="opacity:0.5;fill:#4b80cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="94"
+ x="-83"
+ height="6.8499999"
+ width="9.9999914"
+ id="rect37526-4"
+ style="opacity:0.3;fill:url(#radialGradient37553-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path37528-2"
+ d="m -83,100.00002 1,0 1,0.74999 1,-0.74999 1,0.99999 2,0 1.5,-0.75 1.5,0.75 0.999991,0 L -73,102 l -9.999991,0 -9e-6,-1.99998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37530-7"
+ width="2.0000029"
+ height="2.0000038"
+ x="-77"
+ y="96" />
+ <path
+ style="opacity:0.3;fill:#280b0b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -83,102 10,0 0,1 -10,0 0,-1 z"
+ id="path37532-7"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37534-9"
+ d="m -77,102 2.000003,0 -0.750003,4 -0.5,0 -0.75,-4 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g37536-3"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37538-1"
+ d="m -82.5,105.5 0,-11 9,0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -82.5,105.5 0,-11 9,0 0,11 -9,0 z"
+ id="path37540-9"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#radialGradient37555-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 757.51257,204.46121 9,1e-5 0,14.99999 -13,0 0,-11 4,-4 z"
+ id="path37542-8"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="M 754.51257,209.96121 754.5,218.5 M 759.01257,205.46121 765.5,205.5"
+ style="fill:none;stroke:url(#linearGradient37558-8);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path37544-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753.01257,208.96121 5,0 0,-5 -5,5 z"
+ id="path37546-5"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="M 753.51257,207.96121 753.5,219.5 l 13,0 0,-14.99999 -9.48743,-0.0388 -3.5,3.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path37549-0"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37551-2"
+ d="m 758.51257,206.46121 0,3 -3,0"
+ style="fill:none;stroke:url(#linearGradient37610-3);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-167.99999,190.99999)"
+ id="g71820">
+ <rect
+ y="365"
+ x="215"
+ height="16"
+ width="16"
+ id="rect71822"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(167.99999,-62.999991)"
+ id="g71824">
+ <rect
+ ry="0"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect71826"
+ width="13.016124"
+ height="12.953857"
+ x="48.499996"
+ y="429.54614" />
+ <rect
+ y="430"
+ x="50.016117"
+ height="11.046139"
+ width="11.000001"
+ id="rect71828"
+ style="fill:url(#linearGradient71834);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <path
+ style="fill:url(#linearGradient71836);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 49,430 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m 3,0 0,3 3,0 0,-3 -3,0 z m 0,3 -3,0 0,3 3,0 0,-3 z m 0,3 0,3 3,0 0,-3 -3,0 z m -3,0 -3,0 0,3 3,0 0,-3 z m -3,0 0,-3 -3,0 0,3 3,0 z"
+ id="path71830"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient71838);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 60.517703,430.5 -11.017704,0 0,11 11.017704,0 0,-11"
+ id="path71832"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="493"
+ x="488.00015"
+ height="16"
+ width="16"
+ id="rect37119"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path37123"
+ d="m 490.00015,501 7,-3 6,2.5 0,3.74998 -6.99999,3.74999 -6.00001,-3.24999 0,-3.74998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#2a2512;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37125"
+ d="m 490.00015,501 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37127"
+ d="m 497.00015,501.25 0,-3.24998 -6.5,2.74998 3.5,1.75 3,-1.25 z"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 497.00015,501.24998 0,-3.24998 5.5,2.24998 -3.5,1.75 -2,-0.75 z"
+ id="path37129"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path37131"
+ d="m 502.50015,500.5 -5.5,-2.25 -6.5,2.75"
+ style="fill:none;stroke:url(#linearGradient37201);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g39239-1"
+ transform="translate(-260.99985,289)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path39241-6"
+ d="m 756.16666,204.50001 6.33334,-1e-5 0,11.24999 -9,1e-5 -10e-6,-8.24999 2.66667,-3 z"
+ style="fill:url(#linearGradient37317);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:url(#radialGradient37319);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 756.16666,204.50001 762.5,204.75 l 0,10.75 -9,0 -10e-6,-7.99999 2.66667,-3 z"
+ id="path39243-8"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 754.5,209 0,5.5 m 3.5,-9 3.5,0"
+ style="fill:none;stroke:url(#linearGradient37321);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path39245-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ id="path39247-7"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 753.5,207.00001 0,8.49999 9,0 0,-11 -6.5,1e-5 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path39249-6"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39251-1"
+ d="m 757.5,206.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient37323);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37141"
+ d="m 493.00015,494 7.99985,0 0,11 -7.99981,0 -4e-5,-11 0,0 0,0 0,0 z"
+ style="opacity:0.7;fill:url(#linearGradient37338);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#c6b77c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 490.00016,504.74998 -10e-6,-3.24998 6,3 0.01,3.49883 -6.00995,-3.24885 -4e-5,0 z"
+ id="path37143"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37145"
+ d="m 503.00015,504.25 0,-3.24998 -7,3.49998 c 0,2.58362 0,2.93288 0,3.49998 l 7,-3.74998 z"
+ style="fill:#595235;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path37147"
+ d="m 490.50015,501.5 0,2.99998 5.5,3 6.5,-3.49998 0,-2.99998"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient37191);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37188);stroke-width:1.14999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 490.50015,501.5 5.5,3 6.5,-3.5"
+ id="path37149"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path38348"
+ d="m 491.5,500.75 4.5,2.5 5.5,-3"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g38317"
+ transform="translate(131,-30)">
+ <g
+ transform="translate(-45.97248,412)"
+ id="g38319">
+ <path
+ style="fill:url(#linearGradient38362);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 40.472488,166.25001 -1.250005,1.25 -12.483893,-1e-5 -1.25,-1.25 -5e-6,-11.75001 14.983898,1e-5 5e-6,11.75001 z"
+ id="path38330"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path38332"
+ d="m 38.972483,166.00001 -10.250003,0 0,-1 10.250003,0 0,1 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(110.97248,58)"
+ style="display:inline;enable-background:new"
+ id="g38334">
+ <g
+ id="g38336">
+ <rect
+ y="97.000008"
+ x="-85"
+ height="8.9999962"
+ width="14.000007"
+ id="rect38338"
+ style="fill:#d89090;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38340"
+ width="13.999992"
+ height="2.9999936"
+ x="-85"
+ y="103.00001" />
+ <rect
+ style="opacity:0.3;fill:url(#radialGradient38364);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38342"
+ width="14"
+ height="8.8499966"
+ x="-85"
+ y="97.000008" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -84.999997,101.00001 1.166667,0 1.166666,0.74999 1.166667,-0.74999 1.166666,0.99999 4.666666,1e-5 1.75,-0.75 1.75,0.75 1.166667,0 1e-5,0.99999 -13.999999,-1e-5 -10e-6,-1.99998 0,0 0,0 0,0 z"
+ id="path38344"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="99"
+ x="-77"
+ height="2.0000038"
+ width="2.0000029"
+ id="rect38346"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path38350"
+ d="m -85,103.0089 14.061944,0 0,1 -14.061944,0 0,-1 z"
+ style="opacity:0.3;fill:#280b0b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path38360"
+ d="m -71.75,105.5 -12.5,0"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -77,103 2.000003,0 -0.750003,2.75 -0.5,0 L -77,103 z"
+ id="path38352"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path38354"
+ d="m 39.472483,155.5 -13,0 0.01611,11 13.01389,-7e-5 -0.03,-10.99993 z"
+ style="fill:none;stroke:url(#linearGradient38367);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="165"
+ x="26.972481"
+ height="1.0000043"
+ width="1"
+ id="rect38356"
+ style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(63,473)"
+ style="display:inline;enable-background:new"
+ id="g38358" />
+ </g>
+ <g
+ id="g38738"
+ transform="translate(41.000016,-2e-5)">
+ <rect
+ y="472"
+ x="488"
+ height="16"
+ width="16"
+ id="rect43314"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(565,446)"
+ clip-path="url(#clipPath43368-7)"
+ id="g43300">
+ <rect
+ style="fill:#4e83d0;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43243"
+ width="6"
+ height="2"
+ x="-75.5"
+ y="28.5"
+ rx="0.79505396"
+ ry="0.79505396" />
+ <rect
+ ry="0.74381745"
+ rx="0.74381745"
+ y="36.5"
+ x="-75.5"
+ height="2"
+ width="6"
+ id="rect43245"
+ style="fill:#4e83d0;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43262"
+ width="6"
+ height="2"
+ x="-72.5"
+ y="39.5"
+ rx="0.71819919"
+ ry="0.71819919" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="fill:none;stroke:#000000;stroke-width:2.9000001;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43241"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41718"
+ style="fill:none;stroke:#ffffff;stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscscsc"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ style="opacity:0.35;fill:none;stroke:url(#radialGradient38734);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path43266"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43282"
+ style="opacity:0.35;fill:none;stroke:url(#radialGradient38736);stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m -68.50037,45.540088 c 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99787,-4.040088 0.002,-2 -4.9975,-2 -4.9975,-4 0,-2.030484 5.005,-1.959912 5,-4 0,-2 -5,-2 -5,-4 0,-2.030484 5.00037,-2 4.99537,-4.040088"
+ sodipodi:nodetypes="cscscsc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g39638-8"
+ transform="matrix(0.9986805,0,0,1,179.4308,202.99997)">
+ <rect
+ rx="1.2018067"
+ y="274.00003"
+ x="317.9888"
+ height="4.9999909"
+ width="5.006597"
+ id="rect39640-1"
+ style="opacity:0.25;fill:none;stroke:#fac900;stroke-width:4.00264168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="1.2018067" />
+ <rect
+ style="opacity:0.5;fill:none;stroke:#e6b800;stroke-width:2.00132084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39642-2"
+ width="5.0065966"
+ height="4.9999905"
+ x="317.9888"
+ y="274.00003"
+ rx="1.2018069"
+ ry="1.2018069" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path43508"
+ d="m 317.98879,278 0,-3 1.00132,-1 3.00396,0 1.00132,1 0,3 -1.00132,1 -3.00396,0 -1.00132,-1 z"
+ style="opacity:0.8;fill:#dcb000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#aa8800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 318.99011,278 c 0,-1.00003 3e-5,-2.00003 3e-5,-3.00006 1.00131,0 2.00262,0 3.00393,0 0,1.00003 -3e-5,2.00003 -3e-5,3.00006 -1.00131,0 -2.00262,0 -3.00393,0 z"
+ id="path39644-1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 317.98877,276 c 1.66888,0 3.33774,10e-6 5.00662,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.66888,0 -3.33774,-1e-5 -5.00662,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ id="path39646-4"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path39648-9"
+ d="m 319.99139,279.00006 c 0,-1.66671 10e-6,-3.33335 10e-6,-5.00006 0.33379,0 0.66758,0 1.00137,0 0,1.66671 -1e-5,3.33335 -1e-5,5.00006 -0.33379,0 -0.66758,0 -1.00137,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g28606">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
+ transform="matrix(0,-1,-1,0,0,0)"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22257"
+ width="16"
+ height="16"
+ x="-551"
+ y="-168" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path22271"
+ d="m 167.49999,535.50001 0,8 -9,0 0,-6 2,-2 7,0 z"
+ style="fill:url(#linearGradient28603);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect22281"
+ d="m 166.99999,538.00001 -2,0 0,3 2,0 0,-3 z m -3,0 -1.75,0 -1.25,1.25 0,1.75 3,0 0,-3 z"
+ style="fill:url(#linearGradient28600);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.75;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22285"
+ width="1"
+ height="1"
+ x="542"
+ y="162"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ id="rect22287"
+ d="m 166.99999,542.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="opacity:0.2;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect22291"
+ d="m 166.99999,536.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="opacity:0.8;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 158.74999,537.25001 4.75,4.75 0,1 -4.75,0 0,-5.75 z"
+ id="path22298"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient28593);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 152.49999,550.50001 0,-8 9,0 1.75,-1.5 0.25,0.5 0,7.75 -1.25,1.25 -9.75,0 z"
+ id="path22300"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 152.49999,550.50001 9.5,0 1.5,-1.5 0,-5.5 4,0 0,-8 -7,0 -2,2 0,5 -6,0 0,8 z"
+ id="path22304"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:url(#linearGradient28589);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 162.99999,544.00001 -1,1 -1,0 0,3 0.75,0 1.25,-1.25 0,-2.75 z m -3,1 -3,0 0,3 3,0 0,-3 z m -4,0 -3,0 0,3 3,0 0,-3 z"
+ id="rect22308"
+ sodipodi:nodetypes="ccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect22314"
+ d="m 161.99999,549.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect22322"
+ d="m 161.99999,543.00001 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z m -2,0 -1,0 0,1 1,0 0,-1 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 160.99999,542.00001 0,-0.5 -2,-2 0,2.5 2,0 z"
+ id="path22348"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22340"
+ style="fill:none;stroke:url(#linearGradient28583);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 158.99999,542.50001 2.5,0 0,-1 -2.25,-2.25 m 4.25,4.25 0,-2 -3,-3 0.5,-0.5"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient28580);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 162.49999,542.50001 -1,1 -8,0 0,6 8.25,0 1,-1"
+ id="path22342"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22345"
+ style="fill:none;stroke:url(#linearGradient28577);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 164.49999,542.50001 2,0 0,-6 -5.5,0 -1.5,1.5 0,0.5 3,3 0,1"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m 160.74999,536.50001 -1.25,1.25 0,0.75 3,3 0,1"
+ style="fill:none;stroke:url(#linearGradient28574);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path22368"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="542"
+ x="162"
+ height="6.25"
+ width="1"
+ id="rect38915"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37741"
+ transform="translate(197.70204,-38.325069)">
+ <g
+ id="g37905"
+ transform="translate(0.999999,1.000006)">
+ <g
+ id="g37699"
+ transform="translate(-40.718137,21.311275)"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ y="181.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37701"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37703"
+ width="0.99999899"
+ height="1"
+ x="170.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="168.0161"
+ height="1"
+ width="1"
+ id="rect37705"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37707"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="177.01379" />
+ <rect
+ y="179.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37709"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="177.01379"
+ x="174.0161"
+ height="1"
+ width="0.99999899"
+ id="rect37869"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37871"
+ width="1"
+ height="1"
+ x="172.0161"
+ y="177.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37873"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="185.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37875"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="183.01379" />
+ </g>
+ <g
+ transform="translate(-40.702034,21.325063)"
+ id="g37711"
+ style="fill:#000000">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37713"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="178.00002" />
+ <rect
+ y="180.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect37715"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37717"
+ width="1"
+ height="1"
+ x="167.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="169.00002"
+ height="1"
+ width="1"
+ id="rect37719"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37725"
+ width="1"
+ height="1"
+ x="171.00002"
+ y="177.00002" />
+ <rect
+ y="182.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect37727"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37865"
+ width="1"
+ height="1"
+ x="173"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="175"
+ height="1"
+ width="1"
+ id="rect37867"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37877"
+ width="1"
+ height="1"
+ x="166"
+ y="184" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37879"
+ width="1"
+ height="1"
+ x="166"
+ y="186" />
+ </g>
+ </g>
+ <path
+ id="path37737"
+ d="m 127.79796,207.82507 4e-5,-7.01372 6.99956,0.009 4e-4,0.0507 -4e-4,6.95427 -6.9996,0 0,-2.5e-4 z"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37928"
+ transform="matrix(-1,0,0,-1,260.59592,405.65013)">
+ <g
+ transform="translate(-39.718138,21.311267)"
+ id="g37930"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37932"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="181.01379" />
+ <rect
+ y="177.01379"
+ x="170.0161"
+ height="1"
+ width="0.99999899"
+ id="rect37934"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37936"
+ width="1"
+ height="1"
+ x="168.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37938"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37941"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="179.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37943"
+ width="0.99999899"
+ height="1"
+ x="174.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="172.0161"
+ height="1"
+ width="1"
+ id="rect37945"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="185.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37947"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="183.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37949"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="fill:#000000"
+ id="g37951"
+ transform="translate(-39.702035,21.325055)">
+ <rect
+ y="178.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect37953"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37955"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="180.00002" />
+ <rect
+ y="177.00002"
+ x="167.00002"
+ height="1"
+ width="1"
+ id="rect37958"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37960"
+ width="1"
+ height="1"
+ x="169.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="171.00002"
+ height="1"
+ width="1"
+ id="rect37962"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37964"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="182.00002" />
+ <rect
+ y="177.00002"
+ x="173"
+ height="1"
+ width="1"
+ id="rect37966"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37968"
+ width="1"
+ height="1"
+ x="175"
+ y="177.00002" />
+ <rect
+ y="184"
+ x="166"
+ height="1"
+ width="1"
+ id="rect37970"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="186"
+ x="166"
+ height="1"
+ width="1"
+ id="rect37972"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ </g>
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37338"
+ width="2.9998772"
+ height="3"
+ x="331.50012"
+ y="-161.5"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="168.5"
+ x="-324.49988"
+ height="3"
+ width="2.9998772"
+ id="rect37368"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ <g
+ id="g38402"
+ transform="translate(-21,0)">
+ <g
+ style="display:inline;enable-background:new"
+ id="g38076"
+ transform="translate(173.70204,-41.325069)">
+ <g
+ transform="translate(1,1.0000001)"
+ id="g38078">
+ <g
+ id="g38080"
+ transform="translate(-40.718137,21.311275)"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ y="181.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38082"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38084"
+ width="0.99999899"
+ height="1"
+ x="170.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="168.0161"
+ height="1"
+ width="1"
+ id="rect38086"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38088"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="177.01379" />
+ <rect
+ y="179.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38090"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="177.01379"
+ x="174.0161"
+ height="1"
+ width="0.99999899"
+ id="rect38092"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38094"
+ width="1"
+ height="1"
+ x="172.0161"
+ y="177.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38096"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="185.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38098"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="183.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38173"
+ width="0.99999899"
+ height="1"
+ x="178.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="176.0161"
+ height="1"
+ width="1"
+ id="rect38175"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="189.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38181"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="187.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38183"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(-40.70204,21.325054)"
+ id="g38100"
+ style="fill:#000000">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38102"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="178.00002" />
+ <rect
+ y="180.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect38104"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38106"
+ width="1"
+ height="1"
+ x="167.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="169.00002"
+ height="1"
+ width="1"
+ id="rect38108"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38110"
+ width="1"
+ height="1"
+ x="171.00002"
+ y="177.00002" />
+ <rect
+ y="182.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect38112"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38114"
+ width="1"
+ height="1"
+ x="173"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="175"
+ height="1"
+ width="1"
+ id="rect38116"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38118"
+ width="1"
+ height="1"
+ x="166"
+ y="184" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38120"
+ width="1"
+ height="1"
+ x="166"
+ y="186" />
+ <rect
+ y="177.00002"
+ x="177"
+ height="1"
+ width="1"
+ id="rect38169"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="188.00002"
+ x="166"
+ height="1"
+ width="1"
+ id="rect38177"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ <g
+ id="g38190"
+ transform="matrix(-1,0,0,-1,264.59592,410.65014)">
+ <g
+ transform="translate(-40.718137,21.311275)"
+ id="g38192"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38194"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="181.01379" />
+ <rect
+ y="177.01379"
+ x="170.0161"
+ height="1"
+ width="0.99999899"
+ id="rect38196"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38198"
+ width="1"
+ height="1"
+ x="168.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38200"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38203"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="179.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38205"
+ width="0.99999899"
+ height="1"
+ x="174.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="172.0161"
+ height="1"
+ width="1"
+ id="rect38207"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="185.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38209"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="183.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect38211"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38215"
+ width="1"
+ height="1"
+ x="176.0161"
+ y="177.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38219"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="187.01379" />
+ </g>
+ <g
+ style="fill:#000000"
+ id="g38225"
+ transform="translate(-40.70204,21.325054)">
+ <rect
+ y="178.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect38227"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38229"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="180.00002" />
+ <rect
+ y="177.00002"
+ x="167.00002"
+ height="1"
+ width="1"
+ id="rect38231"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38233"
+ width="1"
+ height="1"
+ x="169.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="171.00002"
+ height="1"
+ width="1"
+ id="rect38235"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38237"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="182.00002" />
+ <rect
+ y="177.00002"
+ x="173"
+ height="1"
+ width="1"
+ id="rect38239"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38241"
+ width="1"
+ height="1"
+ x="175"
+ y="177.00002" />
+ <rect
+ y="184"
+ x="166"
+ height="1"
+ width="1"
+ id="rect38243"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="186"
+ x="166"
+ height="1"
+ width="1"
+ id="rect38245"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38247"
+ width="1"
+ height="1"
+ x="177"
+ y="177.00002" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect38251"
+ width="1"
+ height="1"
+ x="166"
+ y="188.00002" />
+ </g>
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 301.5,168.92817 5e-5,-9.44187 11.99995,0 0,12.00195 -12,0.0118 0,-2.57183 0,-5e-5 z"
+ id="path37737-4"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37061-2"
+ width="2.9998772"
+ height="3"
+ x="305.5"
+ y="161.5"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="164.5"
+ x="303.50012"
+ height="3"
+ width="2.9998772"
+ id="rect38072"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38074"
+ width="2.9998772"
+ height="3"
+ x="306.50012"
+ y="165.5"
+ ry="0"
+ rx="0" />
+ </g>
+ <g
+ id="g38397"
+ transform="translate(20.999878,0)">
+ <rect
+ rx="0"
+ ry="0"
+ y="158.5"
+ x="283.50012"
+ height="3"
+ width="2.9998772"
+ id="rect38277"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38279"
+ width="2.9998772"
+ height="3"
+ x="280.50012"
+ y="167.5"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="164.5"
+ x="288.50024"
+ height="3"
+ width="2.9998772"
+ id="rect38281"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g38011"
+ transform="translate(436,-380)">
+ <rect
+ y="516"
+ x="-95"
+ height="16"
+ width="16"
+ id="rect36540"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g36458"
+ transform="translate(-122,1.3e-4)">
+ <g
+ id="g36460"
+ style="opacity:0.75"
+ transform="translate(-116,424.99975)">
+ <g
+ transform="translate(-179,199.50012)"
+ id="g36462">
+ <path
+ id="path36464"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.25,-2 0,-6.75 -4.25,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g36468">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ id="path36470"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ id="path36466"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient38049);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ id="path36474"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ id="path36472"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient38051);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ id="path36476"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.35;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36479"
+ width="1"
+ height="6.7500019"
+ x="149"
+ y="96.000122" />
+ <rect
+ y="96.000122"
+ x="150"
+ height="6.7500019"
+ width="1"
+ id="rect36481"
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ rx="0"
+ ry="0"
+ y="517.49976"
+ x="27.500006"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect36486"
+ style="fill:none;stroke:#8c4800;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:none;stroke:#8c4800;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36489"
+ width="2.9999485"
+ height="3.0001416"
+ x="27.500006"
+ y="524.49951"
+ ry="0"
+ rx="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path36496"
+ d="m 28.000006,520.49983 -0.5,0 0,-3.00014 2.99995,0"
+ style="fill:none;stroke:#5a2f00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#5a2f00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 28.000006,524.49978 -0.5,0 0,3.00014 2.99995,0"
+ id="path36499"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36503"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000051"
+ y="517.99988"
+ ry="0"
+ rx="0" />
+ <rect
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36507"
+ width="1.9999485"
+ height="2.0000772"
+ x="28.000051"
+ y="524.99982"
+ ry="0"
+ rx="0" />
+ </g>
+ <g
+ transform="translate(-309,277)"
+ id="g36761-1"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 223,243 0,10 1,0 0,-1 1,0 1,0 0,2 1,0 0,1 1,0 0,-1 1,0 0,-2 -1,0 0,-2 1,0 1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 z"
+ id="path36763-5"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g36765-2"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ transform="translate(5,-6.0000002e-7)">
+ <rect
+ y="243"
+ x="218"
+ height="10"
+ width="1"
+ id="rect36767-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="244"
+ x="219"
+ height="1"
+ width="1"
+ id="rect36769-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="245"
+ x="220"
+ height="1"
+ width="1"
+ id="rect36771-1"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="246"
+ x="221"
+ height="1"
+ width="1"
+ id="rect36773-4"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="247"
+ x="222"
+ height="1"
+ width="1"
+ id="rect36775-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="248"
+ x="223"
+ height="1"
+ width="1"
+ id="rect36777-3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="249"
+ x="224"
+ height="1"
+ width="1.0000017"
+ id="rect36779-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="219"
+ height="1"
+ width="1"
+ id="rect36781-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="251"
+ x="220"
+ height="1"
+ width="1"
+ id="rect36783-1"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="221"
+ height="2"
+ width="1"
+ id="rect36785-6"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="250"
+ x="222.25"
+ height="2"
+ width="0.75"
+ id="rect36787-8"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="252"
+ x="223"
+ height="1.9999931"
+ width="1"
+ id="rect36789-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="254"
+ x="222"
+ height="1.0000006"
+ width="1.5"
+ id="rect36791-7"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36793-6"
+ width="1.5"
+ height="1"
+ x="223.5"
+ y="250" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g37508"
+ transform="translate(525,27.999998)">
+ <g
+ style="opacity:0.7"
+ id="g37302"
+ transform="translate(-244,373.99988)">
+ <g
+ transform="translate(-179,199.50012)"
+ id="g37304">
+ <path
+ id="path37306"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g37308">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ id="path37311"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ id="path37313"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37530);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ id="path37316"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ id="path37318"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient37534);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ id="path37320"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37322"
+ width="1"
+ height="6.7500019"
+ x="149"
+ y="96.000122" />
+ <rect
+ y="96.000122"
+ x="150"
+ height="6.7500019"
+ width="1"
+ id="rect37324"
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g37284"
+ transform="translate(-524.98389,247.00001)">
+ <rect
+ y="218"
+ x="425"
+ height="16"
+ width="16"
+ id="rect37286"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(46.000035,99.00001)"
+ id="g37288"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g37290"
+ transform="translate(-3.542969e-5,0)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path37292"
+ style="fill:none;stroke:#000000;stroke-width:3.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.23389,129.74998 4.25,-4.24999 m 0.98389,1.99999 -1.48389,-1.49999 m 0.48389,2.49999 -1.4142,-1.41422"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 387.98389,129.99999 c 0.78065,0.78065 0.78065,2.21936 0,3 -0.78064,0.78065 -2.21935,0.78065 -3,0 -0.78064,-0.78064 -0.78064,-2.21935 0,-3 0.78065,-0.78064 2.21936,-0.78064 3,0 z"
+ style="fill:none;stroke:#000000;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path37504"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 388.23389,129.74998 4.25,-4.24999 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path37294"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37500"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 387.98389,129.99999 c 0.78064,0.78065 0.78064,2.21935 0,3 -0.78065,0.78065 -2.21936,0.78065 -3,0 -0.78065,-0.78065 -0.78065,-2.21935 0,-3 0.78064,-0.78065 2.21935,-0.78065 3,0 z"
+ sodipodi:nodetypes="czzzz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(1.99999,0,0,1.99999,571.48293,-823.49525)"
+ d="m -92,477.5 a 0.5,0.5 0 1 1 -1,0 0.5,0.5 0 1 1 1,0 z"
+ sodipodi:ry="0.5"
+ sodipodi:rx="0.5"
+ sodipodi:cy="477.5"
+ sodipodi:cx="-92.5"
+ id="path37506"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g37565">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.7668704,0,0,0.7668711,19.45715,14.604317)"
+ id="g10270-1"
+ style="opacity:0.3;display:inline;enable-background:new">
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.39093411;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10272-2"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path10275-3"
+ style="opacity:0.4;fill:url(#linearGradient38254);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <rect
+ y="178"
+ x="110"
+ height="16"
+ width="16"
+ id="rect37989"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="g38006"
+ transform="translate(-255.99996,227.9746)"
+ style="display:inline">
+ <rect
+ transform="matrix(1,5.251142e-6,0,1,0,0)"
+ y="-43.49577"
+ x="372.49994"
+ height="2.9999874"
+ width="3.0000761"
+ id="rect37525"
+ style="opacity:0.15;fill:none;stroke:#d5e5ff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="0"
+ ry="0" />
+ <rect
+ transform="matrix(1,-5.25127e-6,0,-1,0,0)"
+ y="40.991806"
+ x="372.99994"
+ height="2.0000756"
+ width="2.0000861"
+ id="rect38010"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ ry="0"
+ rx="0"
+ style="fill:#ebf3ff;fill-opacity:1;fill-rule:nonzero;stroke:#004cbe;stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38012"
+ width="3.0000761"
+ height="2.9999874"
+ x="372.49994"
+ y="-43.49577"
+ transform="matrix(1,5.251142e-6,0,1,0,0)" />
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ id="path37498"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="rect38140"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ style="fill:none;stroke:url(#linearGradient37509);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(41.928411,-437)"
+ id="g37575">
+ <rect
+ y="617"
+ x="173"
+ height="16"
+ width="16"
+ id="rect37577"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-290,397)"
+ id="g37579"
+ style="display:inline">
+ <g
+ id="g37582">
+ <g
+ transform="translate(20.029029,0)"
+ style="opacity:0.85"
+ id="g37584">
+ <path
+ d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37586"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path37588"
+ d="m 444.54256,228.5 11.66489,0 0,0"
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(20.029029,0)"
+ id="g37591">
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 444.47097,228.5 13,0"
+ id="path37593"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path37606"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g37577"
+ transform="translate(-105,-63)">
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ id="g37580"
+ transform="matrix(0.7668704,0,0,0.7668711,19.45715,14.604317)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37582"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.39093411;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient37613);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path37584"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ <path
+ transform="matrix(0.5705005,0,0,0.5705012,53.193935,156.18087)"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38120-7"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:2.28571391;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37586"
+ width="16"
+ height="16"
+ x="110"
+ y="178" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path37608"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient37615);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 114.5,192.5 -3,0 0,-3 m 13,0 0,3 -3,0 m -0.25,-13 3.25,0 0,3 m -13,0 0,-3 3,0"
+ id="path37610"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14409"
+ transform="translate(4.7892764e-7,23)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15296"
+ width="16"
+ height="16"
+ x="47"
+ y="92" />
+ <g
+ style="display:inline"
+ id="g15298"
+ transform="matrix(1.0756796,0,0,1.076923,-83.216744,-140.6923)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15301"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.11492968;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:url(#linearGradient14439-9);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path15303"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.6926913,-0.07795333,0.0789528,-0.6875008,210.6113,314.95068)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15305"
+ style="fill:none;stroke:url(#linearGradient14441-4);stroke-width:1.454548;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6391304,0,0,0.6383922,44.127271,148.16974)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14396"
+ transform="translate(4.7892764e-7,23)">
+ <rect
+ y="92"
+ x="68"
+ height="16"
+ width="16"
+ id="rect15309"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g15311"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(1.0829765,0,0,1.0830206,-86.990103,-142.06175)"
+ style="display:inline">
+ <g
+ transform="matrix(0.928617,0,0,0.931035,10.2435,15.47372)"
+ id="g15313">
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15315"
+ style="fill:#7c7c7c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10805392;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.8076551,0,0,0.8055247,44.427594,128.39229)" />
+ <path
+ transform="matrix(0.745771,0,0,0.7384254,52.598397,136.33161)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15317"
+ style="opacity:0.7;fill:url(#linearGradient14433-1);fill-opacity:1;fill-rule:nonzero"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient14435-7);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path15319"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.624995,0,0,0.625,68.0007,149.25)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15321"
+ style="fill:none;stroke:url(#linearGradient14437-6);stroke-width:1.4544518;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6837125,0,0,0.6818205,60.789416,142.9887)" />
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path15323"
+ d="m 147.27014,223.27443 c 0.22029,-2.14702 1.65545,-2.83866 3,-3"
+ style="fill:none;stroke:#ffffff;stroke-width:0.92336226px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:0.9233622px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter15421-1);enable-background:accumulate"
+ d="m 153.73381,225.66118 c 0,1 -1,2 -2,2"
+ id="path15325"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g37996"
+ transform="translate(113.00001,1)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37994"
+ width="16.000006"
+ height="16.000002"
+ x="-24.00001"
+ y="114" />
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37953"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.10749674;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.8125568,0,0,0.8127302,-123.25796,26.09414)" />
+ <path
+ id="path37970"
+ d="m -18,116.34375 c -1.706032,0.60248 -3.053766,1.95022 -3.65625,3.65625 l 3.65625,0 0,-3.65625 z m 0,3.65625 0,4 4,0 0,-4 -4,0 z m 4,0 3.65625,0 C -10.94623,118.29397 -12.29397,116.94623 -14,116.34375 L -14,120 z m 0,4 0,3.65625 c 1.70603,-0.60248 3.05377,-1.95022 3.65625,-3.65625 L -14,124 z m -4,0 -3.65625,0 c 0.602484,1.70603 1.950218,3.05377 3.65625,3.65625 L -18,124 z"
+ style="fill:url(#linearGradient38073-8);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.749378,0,0,0.7495379,-114.92287,33.554528)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#linearGradient38075-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23055196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path37963"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path37955"
+ style="fill:none;stroke:url(#linearGradient38077-1);stroke-width:1.45488834;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6874075,0,0,0.6872685,-106.73771,40.90046)" />
+ <path
+ style="opacity:0.7;fill:url(#linearGradient38079-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -18,116.34375 c -1.706032,0.60248 -3.053766,1.95022 -3.65625,3.65625 l 3.65625,0 0,-3.65625 z"
+ id="path37972"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(4.7892764e-7,23)"
+ id="g38272"
+ style="display:inline;enable-background:new">
+ <g
+ id="g37676">
+ <rect
+ y="92"
+ x="26"
+ height="16"
+ width="16"
+ id="rect38274"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ transform="matrix(-0.7606373,-0.08449162,0.08669728,-0.7451645,124.04885,199.0823)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38284"
+ style="opacity:0.75;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:1.23076892;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path38294"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ transform="matrix(0.8125001,0,0,0.8125002,-73.250026,4.1249738)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:none;stroke:url(#radialGradient38306-3);stroke-width:2.44404984;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path38296"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="10.07671"
+ d="m 140,118 a 8,10.07671 0 0 1 -15.99907,0.15349"
+ sodipodi:start="0"
+ sodipodi:end="3.12636"
+ transform="matrix(0.8077059,0,0,-0.2072667,-72.578821,124.6156)"
+ sodipodi:open="true" />
+ <path
+ transform="matrix(-0.7451139,-0.08394973,0.08492792,-0.7403854,122.33348,198.48526)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path15303-4"
+ style="opacity:0.15;fill:url(#linearGradient37646-4);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.780896,0,0,0.2786183,-69.081831,66.644097)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:1.50070953;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path38300"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 0 1 -15.99907,0.12186"
+ sodipodi:start="0"
+ sodipodi:end="3.12636"
+ sodipodi:open="true"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient37677);stroke-width:1.45454454;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path38298"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ transform="matrix(0.6875009,0,0,0.687501,-56.75013,18.874887)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:1.35088885;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path38302"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -5.7e-4,-0.0952"
+ sodipodi:start="0"
+ sodipodi:end="6.2712816"
+ sodipodi:open="true"
+ transform="matrix(0,0.7811136,-0.34375,0,74.562502,-3.1287373)" />
+ <path
+ transform="matrix(0.9374995,0,0,0.9374996,-89.749939,-10.62495)"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path38304"
+ style="opacity:0.18000004;fill:none;stroke:url(#linearGradient38313-7);stroke-width:1.0666672;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g39510"
+ transform="translate(-570,274)">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path44921"
+ d="m 653.5,356.5 -4,4 -7,0 -4,-4 0,-7 4,-4 7,0 4,4 0,7 z"
+ style="fill:url(#linearGradient39518);fill-opacity:1;fill-rule:nonzero;stroke:#550000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path44926"
+ d="m 652.5,356 -3.5,3.5 -6,0 -3.5,-3.5 0,-6 3.5,-3.5 6,0 3.5,3.5 0,6 z"
+ style="fill:none;stroke:url(#linearGradient39520);stroke-width:1.20000005;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39523);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 651.5,355.5 -2.75,3 -5.25,0 -3,-3 0,-5 3,-3 5,0 3,3 0,5 z"
+ id="path44954"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.6567169,0.6567169,-0.6567304,0.6567304,736.47216,94.047762)"
+ style="display:inline;enable-background:new"
+ id="g51749-0-4">
+ <path
+ id="path51751-1-8"
+ style="fill:none;stroke:#aa0000;stroke-width:2.69179726;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 132.08133,266.03337 -7.61363,0 m 3.80681,3.80673 0,-7.61347"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path51753-2-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.29206276;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 128.27451,269.8401 0,-7.61347 m 3.80682,3.80674 -7.61363,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(226,40)"
+ id="g39541">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39543"
+ width="16"
+ height="16"
+ x="-95"
+ y="516" />
+ <g
+ transform="translate(-122,1.3e-4)"
+ id="g39545">
+ <g
+ transform="translate(-116,424.99975)"
+ style="opacity:0.75"
+ id="g39547">
+ <g
+ id="g39549"
+ transform="translate(-179,199.50012)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.25,-2 0,-6.75 -4.25,-1.75 z"
+ id="path39551"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39553"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39556"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path39558"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39560"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient39630);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39562"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path39564"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient39632);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect39567"
+ style="opacity:0.35;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39569"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <rect
+ style="fill:none;stroke:#8c4800;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39571"
+ width="2.9999485"
+ height="3.0001416"
+ x="27.500006"
+ y="517.49976"
+ ry="0"
+ rx="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="524.49951"
+ x="27.500006"
+ height="3.0001416"
+ width="2.9999485"
+ id="rect39574"
+ style="fill:none;stroke:#8c4800;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="517.99988"
+ x="28.021444"
+ height="4"
+ width="3.9785564"
+ id="rect37868-0-5"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#5a2f00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 28.000006,520.49983 -0.5,0 0,-3.00014 2.99995,0"
+ id="path39576"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39583"
+ d="m 28.000006,524.49978 -0.5,0 0,3.00014 2.99995,0"
+ style="fill:none;stroke:#5a2f00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="517.99988"
+ x="28.000051"
+ height="2.0000772"
+ width="1.9999485"
+ id="rect39585"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="524.99988"
+ x="28"
+ height="1.999992"
+ width="3.9785564"
+ id="rect37868-0-1"
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="0"
+ ry="0"
+ y="524.99982"
+ x="28.000051"
+ height="2.0000772"
+ width="1.9999485"
+ id="rect39587"
+ style="fill:#ffd4a5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g39589"
+ transform="translate(-309,277)">
+ <path
+ id="path39596"
+ d="m 223,243 0,10 1,0 0,-1 1,0 1,0 0,2 1,0 0,1 1,0 0,-1 1,0 0,-2 -1,0 0,-2 1,0 1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 0,-1 -1,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(5,-6.0000002e-7)"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ id="g39599">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39601"
+ width="1"
+ height="10"
+ x="218"
+ y="243" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39603"
+ width="1"
+ height="1"
+ x="219"
+ y="244" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39605"
+ width="1"
+ height="1"
+ x="220"
+ y="245" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39607"
+ width="1"
+ height="1"
+ x="221"
+ y="246" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39609"
+ width="1"
+ height="1"
+ x="222"
+ y="247" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39611"
+ width="1"
+ height="1"
+ x="223"
+ y="248" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39613"
+ width="1.0000017"
+ height="1"
+ x="224"
+ y="249" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39615"
+ width="1"
+ height="1"
+ x="219"
+ y="252" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39617"
+ width="1"
+ height="1"
+ x="220"
+ y="251" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39619"
+ width="1"
+ height="2"
+ x="221"
+ y="252" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39621"
+ width="0.75"
+ height="2"
+ x="222.25"
+ y="250" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39623"
+ width="1"
+ height="1.9999931"
+ x="223"
+ y="252" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39625"
+ width="1.5"
+ height="1.0000006"
+ x="222"
+ y="254" />
+ <rect
+ y="250"
+ x="223.5"
+ height="1"
+ width="1.5"
+ id="rect39627"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g40247"
+ transform="translate(63,-21.000002)">
+ <rect
+ style="opacity:0;fill:#f6d0a6;fill-opacity:1;fill-rule:evenodd;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40250"
+ width="16"
+ height="15.99988"
+ x="5"
+ y="514.00012" />
+ <g
+ transform="translate(70,178)"
+ id="g40252">
+ <g
+ transform="translate(-386,446.5)"
+ id="g40254">
+ <path
+ id="path40257"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ style="fill:#422200;fill-opacity:1;fill-rule:evenodd;stroke:#281500;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#efa351;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path40259"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(179,-179)"
+ id="g40261">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#915515;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path40263"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#f5ca9b;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path40270"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient40280);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ id="path40272"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:url(#linearGradient40282);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40275"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40284);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ id="path40278"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(508.99432,90)"
+ id="g38556">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38558"
+ width="16"
+ height="16"
+ x="46"
+ y="-209.99432" />
+ <g
+ transform="translate(-113.99432,-362)"
+ id="g38560"
+ style="opacity:0.5">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path38563"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -93.5,422.5 12,0 0,-12 -12,0 0,12 z m 0,-6 12,0 m -6.00001,-5.99959 0,12"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:url(#linearGradient38689);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38570"
+ width="13"
+ height="13"
+ x="-94.000008"
+ y="410"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m -93.5,422.5 12,0 -1e-5,-11.99959 -12,0 1e-5,11.99959 z m 0,-6 12,0 m -6.00001,-5.99959 1e-5,11.99959"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path38572"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38574"
+ d="M -92.46875,415.53125 -92.5,411.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38693);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38695);stroke-width:1px;stroke-linecap:round"
+ d="M -86.46875,415.53125 -86.5,411.5 l 4,0"
+ id="path38577"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38697);stroke-width:1px;stroke-linecap:round"
+ d="M -92.46875,421.53125 -92.5,417.5 l 4,0"
+ id="path38579"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38581"
+ d="M -86.46875,421.53125 -86.5,417.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38701);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="48"
+ x="-207.99432"
+ height="9"
+ width="9.0000038"
+ id="rect37920-7"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g38583"
+ transform="translate(-137.99432,-356)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path38585"
+ d="m -70.5,411.5 0,-8 8,0 0,8 -8,0 z"
+ style="fill:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -70.5,411.5 0,-8 8,0"
+ id="path38588"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient38703);stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ d="M -68.46875,409.53125 -68.5,405.5 l 4,0"
+ id="path38590"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38592"
+ d="m -64.53125,405.5 0.03125,4.03125 -4,0"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient38706);stroke-width:1px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(505.99432,90)"
+ id="g38644">
+ <rect
+ y="-185.99432"
+ x="46"
+ height="16"
+ width="16"
+ id="rect38650"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ style="opacity:0.5"
+ id="g38652"
+ transform="translate(-98.99432,-362)">
+ <path
+ d="m -85.5,422.5 4,0 0,-12 -4,0 0,12 z m 0,-6 4,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path38654"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="410"
+ x="-86"
+ height="13"
+ width="4.9999924"
+ id="rect38657"
+ style="opacity:0.7;fill:url(#linearGradient38720);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path38659"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -85.49999,422.49959 -81.5,422.5 -81.50001,410.50041 -85.5,410.5 l 1e-5,11.99959 z m 0,-6 L -81.5,416.5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38723);stroke-width:1px;stroke-linecap:round"
+ d="M -84.46875,415.53125 -84.5,411.5 l 2,0"
+ id="path38661"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38663"
+ d="M -84.46875,421.53125 -84.5,417.5 l 2,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient38725);stroke-width:1px;stroke-linecap:round"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,1.7057638,-106.49432,-641.33135)"
+ id="g38665">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:#462400;stroke-width:0.76566803;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -71,412.03125 0,-8.2055 7,0 0,8.2055 -7,0 z"
+ id="path38668"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path38670"
+ d="m -69,407.19668 0,-2.19843 2.75,0"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38727);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38729);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -66,405.14481 0,2.19843 -2.75,0"
+ id="path38672"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38731);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -69,410.71416 0,-2.19843 2.75,0"
+ id="path38674"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path38676"
+ d="m -66,408.6623 0,2.19843 -2.75,-10e-6"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient38736);stroke-width:0.76566803px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39152"
+ transform="translate(507.99432,90)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39154"
+ width="16"
+ height="16"
+ x="46"
+ y="-229.99432" />
+ <g
+ transform="translate(-133.99432,-362)"
+ id="g39157"
+ style="opacity:0.55">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path39159"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -93.5,422.5 12,0 0,-12 -12,0 0,12 z m 0,-6 12,0 m -6.00001,-5.99959 0,12"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:url(#linearGradient39199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39161"
+ width="13"
+ height="13"
+ x="-94.000008"
+ y="410"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ d="m -93.5,422.5 12,0 -1e-5,-11.99959 -12,0 1e-5,11.99959 z m 0,-6 12,0 m -6.00001,-5.99959 1e-5,11.99959"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39163"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39165"
+ d="M -92.46875,415.53125 -92.5,411.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39201);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39203);stroke-width:1px;stroke-linecap:round"
+ d="M -86.46875,415.53125 -86.5,411.5 l 4,0"
+ id="path39167"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39205);stroke-width:1px;stroke-linecap:round"
+ d="M -92.46875,421.53125 -92.5,417.5 l 4,0"
+ id="path39169"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39171"
+ d="M -86.46875,421.53125 -86.5,417.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39207);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37922"
+ width="1.9785498"
+ height="10"
+ x="-215.97287"
+ y="48" />
+ <rect
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37896-1"
+ width="2.9785526"
+ height="10"
+ x="-227.99432"
+ y="48" />
+ <g
+ id="g39173"
+ transform="translate(-190.01023,-189.50001)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.90196078;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ id="rect39175"
+ width="1.9999995"
+ height="9.999959"
+ x="-38.484093"
+ y="236.00082"
+ transform="matrix(1,2.1226448e-5,0,1,0,0)" />
+ <rect
+ transform="matrix(1,3.6759233e-5,0,1,0,0)"
+ y="236.5014"
+ x="-37.984093"
+ height="8.9999657"
+ width="0.9999997"
+ id="rect39178"
+ style="fill:#ffcb91;fill-opacity:1;fill-rule:nonzero;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path39180"
+ d="m -37.484093,246.00001 -0.9549,0.0112 -0.0271,-10.01124 1.982,4e-5 0,1"
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="48"
+ x="-221.97287"
+ height="10"
+ width="2.9785526"
+ id="rect37920"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-184.01023,-189.50001)"
+ id="g39182">
+ <rect
+ transform="matrix(1,2.6522988e-5,0,1,0,0)"
+ y="236.00104"
+ x="-38.484093"
+ height="9.9999399"
+ width="1.9999998"
+ id="rect39184"
+ style="fill:none;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.90196078;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#ffcb91;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect39186"
+ width="0.99999994"
+ height="9.0000439"
+ x="-37.984093"
+ y="236.50175"
+ transform="matrix(1,4.7261927e-5,0,1,0,0)" />
+ <path
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ d="m -38.484093,237.00001 0.018,-1.00004 1.982,4e-5 0,1"
+ id="path39189"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,-252.97841,-189.50001)"
+ id="g39191">
+ <rect
+ transform="matrix(1,2.1226448e-5,0,1,0,0)"
+ y="236.00082"
+ x="-38.484093"
+ height="9.999959"
+ width="1.9999995"
+ id="rect39193"
+ style="fill:none;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.90196078;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#ffcb91;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect39195"
+ width="0.9999997"
+ height="8.9999657"
+ x="-37.984093"
+ y="236.5014"
+ transform="matrix(1,3.6759233e-5,0,1,0,0)" />
+ <path
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ d="m -37.484093,246.00001 -0.9549,0.0112 -0.0271,-10.01124 1.982,4e-5 0,1"
+ id="path39197"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39209"
+ transform="translate(508.99432,90)">
+ <rect
+ y="-251.99432"
+ x="46"
+ height="16"
+ width="16"
+ id="rect39211"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ transform="translate(-155.99432,-362)"
+ style="opacity:0.55"
+ id="g39213">
+ <path
+ d="m -93.5,422.5 12,0 0,-12 -12,0 0,12 z m 0,-6 12,0 m -6.00001,-5.99959 0,12"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39215"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="410"
+ x="-94.000008"
+ height="13"
+ width="13"
+ id="rect39217"
+ style="opacity:0.7;fill:url(#linearGradient39246);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="path39219"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -93.5,422.5 12,0 -1e-5,-11.99959 -12,0 1e-5,11.99959 z m 0,-6 12,0 m -6.00001,-5.99959 1e-5,11.99959"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39248);stroke-width:1px;stroke-linecap:round"
+ d="M -92.46875,415.53125 -92.5,411.5 l 4,0"
+ id="path39221"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39223"
+ d="M -86.46875,415.53125 -86.5,411.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39252);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39225"
+ d="M -92.46875,421.53125 -92.5,417.5 l 4,0"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39255);stroke-width:1px;stroke-linecap:round"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient39259);stroke-width:1px;stroke-linecap:round"
+ d="M -86.46875,421.53125 -86.5,417.5 l 4,0"
+ id="path39227"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ rx="0"
+ ry="0"
+ y="-251.49432"
+ x="-49.500275"
+ height="3"
+ width="2.9998772"
+ id="rect39229"
+ style="fill:none;stroke:#402100;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37866"
+ width="3.9785564"
+ height="4"
+ x="-250.99432"
+ y="47" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path39231"
+ d="m -250.99432,47 c 0,0.6694 10e-6,1.3388 10e-6,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -1e-5,-1.3388 -1e-5,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="47"
+ x="-243.97287"
+ height="4"
+ width="3.9785564"
+ id="rect37868"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:none;stroke:#402100;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39233"
+ width="2.9998772"
+ height="3"
+ x="-49.500305"
+ y="-244.5025"
+ ry="0"
+ rx="0" />
+ <rect
+ y="54"
+ x="-250.97287"
+ height="4"
+ width="3.9785564"
+ id="rect37870"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37896"
+ width="3.9785564"
+ height="4"
+ x="-243.97287"
+ y="54" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -244.00249,47 c 0,0.6694 1e-5,1.3388 1e-5,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -10e-6,-1.3388 -10e-6,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ id="path39235"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="0"
+ ry="0"
+ y="-251.5025"
+ x="-56.492096"
+ height="3"
+ width="2.9998772"
+ id="rect39237"
+ style="fill:none;stroke:#402100;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path39239"
+ d="m -251.0025,53.9918 c 0,0.6694 1e-5,1.3388 1e-5,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -1e-5,-1.3388 -1e-5,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(0,-1,1,0,0,0)"
+ style="fill:none;stroke:#402100;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39241"
+ width="2.9998772"
+ height="3"
+ x="-56.492096"
+ y="-244.49432"
+ ry="0"
+ rx="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -243.99432,53.9918 c 0,0.6694 10e-6,1.3388 10e-6,2.0082 0.66939,0 1.33877,0 2.00817,0 0,-0.6694 -1e-5,-1.3388 -1e-5,-2.0082 -0.66939,0 -1.33878,0 -2.00817,0 z"
+ id="path39244"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39098"
+ transform="translate(42,63)">
+ <rect
+ ry="0"
+ rx="0"
+ y="535"
+ x="488"
+ height="16"
+ width="16"
+ id="rect39095"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39082">
+ <g
+ mask="url(#mask38956)"
+ id="g38942"
+ transform="translate(0,-21)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path38944"
+ d="m 489.5,570.5 7.5,0 c 7.75,0 6.25,-9 2.5,-9 l -1,0"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssc"
+ style="fill:none;stroke:url(#linearGradient39115);stroke-width:1.39999998;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 489,570.5 8,0 c 7.75,0 6.25,-9 2.5,-9 l -1,0"
+ id="path38946"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccsccccccc"
+ id="path38948"
+ d="m 493.5,535.5 c -0.554,0 -1,0.446 -1,1 l 0,8 c 0,0.554 0.446,1 1,1 0.554,0 1,-0.446 1,-1 l 1.5,0 c 1.939,0 3.5,-1.561 3.5,-3.5 l 0,-1 c 0,-1.939 -1.561,-3.5 -3.5,-3.5 l -1.5,0 c 0,-0.554 -0.446,-1 -1,-1 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffeeaa;fill-opacity:1;fill-rule:evenodd;stroke:#28220b;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 492.5,539.5 -3,0 c -0.54593,0 -0.98543,-0.4395 -0.98543,-0.98544 0,-0.54593 0.4395,-0.98543 0.98543,-0.98543 l 3,0"
+ id="rect38938"
+ sodipodi:nodetypes="ccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39117);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 494.5,543.59375 1.5,0 c 1.45545,0 2.59375,-1.1383 2.59375,-2.59375 l 0,-1 c 0,-1.45545 -1.1383,-2.59375 -2.59375,-2.59375 l -1.5,0"
+ id="path39045"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.5"
+ rx="0.49151421"
+ y="536"
+ x="493"
+ height="9"
+ width="1"
+ id="rect38950"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:url(#linearGradient39119);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 494.5,542.5 1.5,0 c 0.94305,0 1.5,-0.55695 1.5,-1.5 l 0,-1 c 0,-0.94305 -0.55695,-1.5 -1.5,-1.5 l -1.5,0"
+ id="path39068"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39052"
+ width="1"
+ height="7"
+ x="494"
+ y="537"
+ rx="0.49151421"
+ ry="0.5" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path39076"
+ d="m 494.5,542.5 1.5,0 c 0.94305,0 1.5,-0.55695 1.5,-1.5 l 0,-1 c 0,-0.94305 -0.55695,-1.5 -1.5,-1.5 l -1.5,0"
+ style="fill:none;stroke:url(#linearGradient39122);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccscc"
+ id="path39534"
+ d="m 492.5,543.47087 -3,0 c -0.54593,0 -0.98543,-0.4395 -0.98543,-0.98544 0,-0.54593 0.4395,-0.98543 0.98543,-0.98543 l 3,0"
+ style="fill:#ffeeaa;fill-opacity:1;fill-rule:evenodd;stroke:#28220b;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-105,212.00008)"
+ id="g39237"
+ style="display:inline;enable-background:new">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
+ id="g39240"
+ transform="translate(5.4013367,9.4697686)"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39242"
+ width="16"
+ height="16"
+ x="125.59866"
+ y="397.53015" />
+ <g
+ style="display:inline"
+ transform="translate(2.6147745,160.52205)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g39244">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ id="g39246"
+ style="display:inline">
+ <path
+ transform="matrix(1.0155084,0,0,1.0286863,37.51084,101.58226)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient39261);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.8489247;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path39248"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ style="fill:none;stroke:url(#linearGradient39265);stroke-width:1.17973554;stroke-opacity:1;display:inline"
+ id="g39250"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path39252"
+ style="fill:none;stroke:url(#linearGradient39263);stroke-width:1.22986293;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(1.0337319,0,0,1.0470635,35.105336,99.413761)" />
+ </g>
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccc"
+ id="path39309"
+ transform="translate(105,-235.00008)"
+ d="m 32,645 0,1 -1,0 0,2 2,0 0,-1 2,0 0,2 -1,0 0,1.25 -1,0 0,1.75 2,0 0,-1.5 1,0 0,-1 1,0 0,-3.5 -1,0 0,-1 -4,0 z m 1,8 0,2 2,0 0,-2 -2,0 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 32,645 0,1 -1,0 0,2 2,0 0,-1 2,0 -0.02802,1.97638 -1,0 L 34,650.25 l -1,0 0,1.75 2,0 0,-1.5 1,0 0,-1 1,0 0,-3.5 -1,0 0,-1 -4,0 z m 1,8 0,2 2,0 0,-2 -2,0 z"
+ transform="translate(105,-235.00008)"
+ id="path11803-1"
+ sodipodi:nodetypes="cccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-3.0078133e-8,128.00008)"
+ id="g39694"
+ style="display:inline;enable-background:new">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
+ id="g39696"
+ transform="translate(5.4013367,9.4697686)"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39698"
+ width="16"
+ height="16"
+ x="125.59866"
+ y="397.53015" />
+ <g
+ style="display:inline"
+ transform="translate(2.6147745,160.52205)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g39700">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
+ id="g39702"
+ style="display:inline">
+ <path
+ transform="matrix(0.8835182,0,0,0.8949854,54.933548,117.35897)"
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient39261-4-5);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97574574;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39704"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ style="fill:none;stroke:url(#linearGradient39718);stroke-width:1.17973554;stroke-opacity:1;display:inline"
+ id="g39706"
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path39708"
+ style="fill:none;stroke:url(#linearGradient39716);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g39802"
+ style="opacity:0.7;stroke:#000000">
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:#000000"
+ d="m 138,413.99992 c 0.25,0 2,0 2,0 l 0,4 0.75,0 0,1 -3.5,0 0,-1 0.75,0 0,-3 c -0.66667,0 4.15703,0 -1.25,0 l 0.5,-1 0.75,0 z"
+ id="path39804"
+ sodipodi:nodetypes="cccccccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39806"
+ width="2"
+ height="2"
+ x="138"
+ y="410.99991"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g39798">
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path39710"
+ d="m 138,413.99992 c 0.25,0 2,0 2,0 l 0,4 0.75,0 0,1 -3.5,0 0,-1 0.75,0 0,-3 c -0.66667,0 4.15703,0 -1.25,0 l 0.5,-1 0.75,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="410.99991"
+ x="138"
+ height="2"
+ width="2"
+ id="rect39712"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g40264"
+ transform="translate(21,0)"
+ mask="url(#mask40306)">
+ <rect
+ ry="0"
+ style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40266"
+ width="13.016124"
+ height="12.953857"
+ x="195.49998"
+ y="11.546152" />
+ <rect
+ y="12.00001"
+ x="197.01611"
+ height="11.046139"
+ width="11.000001"
+ id="rect40268"
+ style="fill:url(#linearGradient40295);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <g
+ id="g40270"
+ transform="translate(146.99999,-417.99999)">
+ <g
+ transform="translate(-146.99999,417.99999)"
+ id="g40272">
+ <rect
+ style="fill:#106386;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40276"
+ width="3"
+ height="3"
+ x="196"
+ y="12" />
+ <rect
+ style="fill:#ba0036;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40278"
+ width="3"
+ height="3"
+ x="199"
+ y="15" />
+ <rect
+ y="12"
+ x="202"
+ height="3"
+ width="3"
+ id="rect40280"
+ style="fill:#9f0022;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="15"
+ x="205"
+ height="3"
+ width="3"
+ id="rect40282"
+ style="fill:#688c7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="18"
+ x="196"
+ height="3"
+ width="3"
+ id="rect40284"
+ style="fill:#b77100;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="21"
+ x="199"
+ height="3"
+ width="3"
+ id="rect40286"
+ style="fill:#a67c58;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#7a2537;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40288"
+ width="3"
+ height="3"
+ x="202"
+ y="18" />
+ <rect
+ style="fill:#869c2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40290"
+ width="3"
+ height="3"
+ x="205"
+ y="21" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient40297);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 207.51769,12.50001 -11.0177,0 0,11 11.0177,0 0,-11"
+ id="path40292"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39333"
+ transform="translate(0,-62.1)">
+ <rect
+ style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38951"
+ width="16"
+ height="16"
+ x="26"
+ y="198" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g39096-7"
+ transform="translate(26.00079,19.1)">
+ <rect
+ rx="1.3125"
+ ry="1.3125001"
+ y="180.53122"
+ x="5.4992032"
+ height="9.9687805"
+ width="10.000007"
+ id="rect39098-7"
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39100-7"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ style="fill:none;stroke:url(#linearGradient40733-0);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-1.00079,-19)"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ id="g39118-3">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="path39183-3"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect39114-5"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 9.49921,181.5 2,0"
+ id="path39106-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-1,-1,0,212.75,247.25)"
+ id="g38966">
+ <g
+ id="g38968"
+ transform="matrix(-1,0,0,-1,215.25,222.75)">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,38.5 0,5 5,0"
+ id="path38970"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path38972"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 175.5,42.5 5,-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-146.75,127.75)"
+ id="g38975">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g38977">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path38984"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path38987"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d=""
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ id="path38994"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g38996"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path38998"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g39000">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path39015"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path39017"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 78.1613,110.99999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,-175.75,-207.25)"
+ style="opacity:0.2"
+ id="g39020">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path39022"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g39306"
+ transform="translate(-1,-62)">
+ <rect
+ y="198"
+ x="6"
+ height="16"
+ width="16"
+ id="rect38948"
+ style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g39096"
+ transform="translate(1.00079,19)">
+ <rect
+ rx="1.3125"
+ ry="1.3125001"
+ y="180.53122"
+ x="5.4992032"
+ height="9.9687805"
+ width="10.000007"
+ id="rect39098"
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path39100"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ style="fill:none;stroke:url(#linearGradient40733);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-1.00079,-19)"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ id="g39118">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="path39183"
+ inkscape:connector-curvature="0" />
+ <path
+ id="rect39114"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 9.49921,181.5 2,0"
+ id="path39106"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39052"
+ transform="matrix(0,1,-1,0,199.75,171.75)">
+ <g
+ transform="matrix(-1,0,0,-1,215.25,222.75)"
+ id="g39054">
+ <path
+ id="path39056"
+ d="m 174.5,38.5 0,5 5,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 175.5,42.5 5,-5"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39058"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39060"
+ transform="translate(-146.75,127.75)">
+ <g
+ id="g39062"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39064"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d=""
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39066"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path39069"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g39071">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path39073"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39076"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39078"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 78.1613,110.99999 5.5,-5.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39080"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g39083"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-175.75,-207.25)">
+ <path
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path39085"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40848"
+ transform="translate(232,503)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40824"
+ width="16"
+ height="16"
+ x="-17"
+ y="94" />
+ <g
+ id="g39622"
+ transform="translate(-3.2236328e-6,0.9999981)">
+ <g
+ transform="translate(-83.999951,1.9073486e-6)"
+ style="opacity:0.6"
+ id="g40663">
+ <rect
+ style="fill:url(#linearGradient40875-3-9-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40665"
+ width="7.9999967"
+ height="9.9999981"
+ x="69.499954"
+ y="94.5"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient40877-5-5-9);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40667"
+ width="5.9999967"
+ height="7.9999981"
+ x="70.499954"
+ y="95.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g40669"
+ transform="translate(-85,-1)">
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40671"
+ width="8.0000029"
+ height="9.0000019"
+ x="73.5"
+ y="98.5"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="99"
+ x="74"
+ height="9"
+ width="7"
+ id="rect40673"
+ style="fill:url(#linearGradient40879-9-8-1);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ style="fill:none;stroke:#333333;stroke-width:0.7499997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 73.5,103.75 0,-5.25 4,0"
+ id="path40675"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient40881-8-0-8);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40677"
+ width="6.0000033"
+ height="7.0000019"
+ x="74.5"
+ y="99.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <rect
+ style="opacity:0.4;fill:url(#radialGradient40883-4-0-3);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="rect40679"
+ width="7.0000033"
+ height="8.0000019"
+ x="-11"
+ y="98"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ transform="translate(-122.97615,-9.9999881)"
+ id="g40681">
+ <path
+ id="path40683"
+ d="m 116.47121,117.5 -3.99506,0"
+ style="fill:none;stroke:#2d2d2d;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 114.4449,117.46875 c 0,-1.65264 1.12861,-2.96875 2.78125,-2.96875 l 1.5,0 c 1.65264,0 2.71875,1.31617 2.71875,2.9688 l 0,0.0625 c 0,1.65264 -1.06611,2.9687 -2.71875,2.9687 l -1.5,0 c -1.65264,0 -2.78125,-1.31612 -2.78125,-2.96875 l 0,-0.0625 z m 2.03125,0.0312 c 0,0.554 0.2585,0.99995 0.8125,0.99995 l 1.40625,-0.0312 c 0.554,0 0.78125,-0.41475 0.78125,-0.96875 0,-0.554 -0.22725,-1.03125 -0.78125,-1.03125 l -1.40625,0.0312 c -0.554,0 -0.8125,0.44605 -0.8125,1.00005 z"
+ id="path40685"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="116"
+ x="115"
+ height="2.47615"
+ width="1"
+ id="rect40687"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40689"
+ width="1"
+ height="1"
+ x="116"
+ y="115"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ id="path40691"
+ d="m 106.4449,117.4688 c 0,-1.65264 1.12861,-2.96875 2.78125,-2.96875 l 1.5,-5e-5 c 1.65264,0 2.71875,1.31617 2.71875,2.9688 l 0,0.0625 c 0,1.65264 -1.06611,2.9687 -2.71875,2.9687 l -1.5,5e-5 c -1.65264,0 -2.78125,-1.31612 -2.78125,-2.96875 l 0,-0.0625 z m 2.03125,0.0312 c 0,0.554 0.2585,1 0.8125,1 l 1.4375,-5e-5 c 0.554,0 0.75,-0.44595 0.75,-0.99995 0,-0.554 -0.196,-1.00005 -0.75,-1.00005 l -1.4375,5e-5 c -0.554,0 -0.8125,0.446 -0.8125,1 z"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccccccsccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40693"
+ width="0.99998814"
+ height="2.5000362"
+ x="115"
+ y="107.97615"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="106.97615"
+ x="116"
+ height="1"
+ width="1"
+ id="rect40695"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ style="opacity:0.55;fill:none;stroke:#1a1a1a;stroke-width:2.79440284;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 116.47121,117.5 -4.99506,-1e-5"
+ id="path40697"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 116.47121,117.5 -4.99506,-1e-5"
+ id="path40699"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="118.97615"
+ x="119"
+ height="1"
+ width="1"
+ id="rect40701"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40703"
+ width="1"
+ height="1"
+ x="115"
+ y="118.97615"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40705"
+ width="1"
+ height="1"
+ x="119"
+ y="111"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="111"
+ x="115"
+ height="1"
+ width="1"
+ id="rect40707"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40709"
+ width="1"
+ height="0.97614998"
+ x="117"
+ y="118"
+ transform="matrix(0,1,1,0,0,0)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g40697"
+ transform="translate(455.99408,547.99927)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\URL link 1.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="29"
+ x="-31"
+ height="16"
+ width="16"
+ id="rect40643"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g40513"
+ style="opacity:0.8">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path40465"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ style="fill:url(#linearGradient40511-7-9-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m -29.5,34 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient40507-4-8-1);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path40469"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#radialGradient40649-2-6-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ id="path40645"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m -31,33 4,0 0,-4 -4,4 z"
+ id="path40471"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m -30.5,32.00001 0,10.49999 11,-1e-5 0,-12.99999 -8.5,10e-6 -2.5,2.5 0,0 0,0 0,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40473"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40475"
+ d="m -26.5,31.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient40502-7-8-3);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40263"
+ transform="matrix(0.8738816,0,0,0.8823479,-135.18828,-60.939841)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:type="arc"
+ style="fill:#3771c8;fill-opacity:1;fill-rule:nonzero;stroke:#040910;stroke-width:1.45371544;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40265"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)" />
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40267"
+ style="fill:url(#linearGradient40635-7-2-2);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.666432,0,0,0.659342,42.69924,35.46375)" />
+ <path
+ transform="matrix(0.3631382,0,0,0.3593485,81.755824,69.904768)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.7;fill:url(#linearGradient40637-9-5-8);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path40269"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path40271"
+ d="m 274.98515,70.995347 c 0,0.953349 -1,1.906699 -2,1.906699"
+ style="opacity:0.5;fill:none;stroke:#ffe680;stroke-width:1.18410921px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter13996-9-7-7)"
+ transform="matrix(0.9688184,0,0,0.9547322,-131.63668,47.640696)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccssscsscccscccccccccccccccsccccc"
+ id="path40273"
+ d="m 130.67404,112.3079 c 0.0244,0.78706 -0.15754,1.63085 0.59269,2.02213 0.71197,-0.0434 1.49133,0.64122 1.35667,1.40517 -0.26776,0.77861 0.14071,1.12325 0.95576,1.36401 0.57868,-0.0716 0.79053,-0.93546 0.87357,-1.36401 0.0948,-1.27121 0.51542,-1.09421 0.82108,-1.98991 -0.45733,-0.91502 -0.003,-1.04443 -0.72629,-1.43739 m -1.00945,-3.89288 c -0.4426,0.34378 -0.24372,1.04314 -0.66162,1.39841 -0.45372,0.13628 -0.78226,-0.0605 -1.16771,0.43164 -0.30841,1.10457 0.35004,1.22306 0.90205,1.10457 0.49538,-0.0502 0.61419,-0.94321 0.97928,-0.37853 0.0831,0.10976 0.71917,-0.0403 0.86266,0.18898 0.0669,0.10682 -0.11785,0.0255 -0.14729,0.18955 -0.0428,0.23847 0.27734,0.37341 0.372,0.3824 0.32089,0.0305 0.60005,0.92548 0.83846,1.05499 0,0.46738 0.0924,-0.6774 0.3515,-0.78703 0.22948,-0.0971 0.47929,0.10731 0.5,0 0.29928,-1.55081 -1.26113,-3.00604 -2.82933,-3.58498 z M 128.96474,107.5 c -0.6111,1.01384 0.85343,1.46103 1.73001,1.21329 0.57897,-0.37879 1.00716,-0.92331 0.55665,-1.21329 -0.20614,-0.1415 -2.07706,0.0431 -2.28666,0 l 0,0 0,0 0,0 z m -1.372,1.37253 c -0.49575,-0.14959 0.44952,-0.11945 0.45733,0.45751 0.1696,0.54756 -0.42801,0.23756 0,0.45752 0.70893,0.1644 0.35328,1.70031 -0.28114,1.56208 -0.56042,0.10119 -0.43915,0.95826 -1.64865,0.88279 -0.0836,0.0755 -1.04512,0.61593 -0.81421,1.21521 1.12968,0.30162 -0.36816,1.26478 -0.43867,0.55236 -0.15441,-0.49797 -0.62853,-1.11348 -0.43994,-1.68674 0.11734,-0.63627 0.5689,-1.12263 0.82646,-1.69865 0.36225,-0.61946 0.89084,-1.17688 1.57758,-1.42595 0.21411,-0.16799 0.46159,-0.41691 0.76124,-0.31613 l 0,0 0,0 0,0 z m -0.91467,5.03262 c -0.55163,-0.27585 -0.72934,0.28829 -0.60377,0.7984 0.15577,0.47138 0.52607,0.97695 0.72628,1.43739 0.40435,0.49619 1.512,1.34081 2.17883,1.67696 0.31768,0.16015 0.48418,0 0.24209,-0.23956 -0.31367,-0.6375 -1.14073,-1.94893 -0.48418,-2.15609 0.59647,-0.60342 0.34203,-1.58773 -0.48419,-1.43739 -0.54779,-0.25818 -0.75551,-0.39899 -1.38855,-0.0752 -0.0558,0.0743 -0.12403,0.006 -0.18651,-0.004 l 0,-5.1e-4 0,0 0,0 z"
+ style="fill:url(#linearGradient40639-1-2-1);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40275"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient40641-9-2-7);stroke-width:1.78065979;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.6429129,0,0,0.6362007,45.809534,38.194473)" />
+ <path
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40277"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.06052282,0,0,0.05989117,121.21686,103.80334)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g41840"
+ transform="translate(497,652)">
+ <rect
+ y="-75"
+ x="-135"
+ height="16"
+ width="16"
+ id="rect41622"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g41624"
+ style="display:inline;enable-background:new"
+ transform="matrix(1,0,0,0.9999542,-104,-101.99865)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path41626"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ style="fill:url(#linearGradient41638-8-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m -29.5,34 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient41640-2-0);stroke-width:1.00002289px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path41628"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#radialGradient41642-5-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="M -27.80208,29.59375 -19.5,29.5 -19.53126,42.40625 -30.5,42.5 l 0.03125,-9.90625 2.66667,-3 z"
+ id="path41630"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m -31,33 4,0 0,-4 -4,4 z"
+ id="path41632"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m -30.5,32.00001 0,10.49999 11,-1e-5 0,-12.99999 -8.5,10e-6 -2.5,2.5 0,0 0,0 0,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80001831;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path41634"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path41636"
+ d="m -26.5,31.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient41644-5-4);stroke-width:1.00002289px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43546-0"
+ transform="matrix(0.9986805,0,0,1,-443.5692,-347.00003)">
+ <rect
+ rx="1.2018067"
+ y="274.00003"
+ x="317.9888"
+ height="4.9999909"
+ width="5.006597"
+ id="rect43548-7"
+ style="opacity:0.2;fill:none;stroke:#fac900;stroke-width:4.00264168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="1.2018067" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:#e6b800;stroke-width:2.00132084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43550-6"
+ width="5.0065966"
+ height="4.9999905"
+ x="317.9888"
+ y="274.00003"
+ rx="1.2018069"
+ ry="1.2018069" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path43552-3"
+ d="m 317.98879,278 0,-3 1.00132,-1 3.00396,0 1.00132,1 0,3 -1.00132,1 -3.00396,0 -1.00132,-1 z"
+ style="opacity:0.8;fill:#dcb000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#967800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 318.9901,278.50003 c 0,-1.33336 3e-5,-2.66664 3e-5,-4 1.00132,0 2.00263,0 3.00395,0 0,1.33336 -3e-5,2.66664 -3e-5,4 -1.00132,0 -2.00263,0 -3.00395,0 z"
+ id="path43554-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path43583-1"
+ d="m 318.48944,278.00003 c 0,-1.00002 4e-5,-1.99998 4e-5,-3 1.33509,0 2.67017,0 4.00526,0 0,1.00002 -4e-5,1.99998 -4e-5,3 -1.33509,0 -2.67017,0 -4.00526,0 z"
+ style="fill:#967800;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 317.98877,276 c 1.66888,0 3.33774,10e-6 5.00662,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.66888,0 -3.33774,-1e-5 -5.00662,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ id="path43556-5"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path43558-4"
+ d="m 319.99139,279.00006 c 0,-1.66671 10e-6,-3.33335 10e-6,-5.00006 0.33379,0 0.66758,0 1.00137,0 0,1.66671 -1e-5,3.33335 -1e-5,5.00006 -0.33379,0 -0.66758,0 -1.00137,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(378,684)"
+ style="display:inline;enable-background:new"
+ id="g39156">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40773"
+ width="16"
+ height="16"
+ x="-205"
+ y="-87" />
+ <g
+ transform="translate(-272,-181)"
+ style="opacity:0.6"
+ id="g40789">
+ <rect
+ style="fill:url(#linearGradient39136-2-0);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40791"
+ width="9.0000124"
+ height="10.000001"
+ x="68.5"
+ y="95.5"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient39138-8-6);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40793"
+ width="7.0000038"
+ height="8.0000086"
+ x="69.5"
+ y="96.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ id="g40795"
+ transform="translate(-273.00002,-181)">
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40797"
+ width="8.9999342"
+ height="10.000006"
+ x="73.500023"
+ y="99.5"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="100"
+ x="74.000023"
+ height="9"
+ width="8.0000086"
+ id="rect40799"
+ style="fill:url(#linearGradient39140-6-8);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ style="fill:none;stroke:#333333;stroke-width:0.7499997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 73.5,103.75 2e-5,-4.25 4,0"
+ id="path40801"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:url(#linearGradient39143-0-6);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="rect40803"
+ width="7.0000048"
+ height="8.0000267"
+ x="74.500023"
+ y="100.5"
+ rx="0"
+ ry="0" />
+ </g>
+ <g
+ style="fill:#800000"
+ id="g37993">
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37978"
+ width="2.00001"
+ height="1.0000038"
+ x="-198"
+ y="-77" />
+ <rect
+ y="-76"
+ x="-197.00002"
+ height="2"
+ width="1.0000153"
+ id="rect37980"
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37982"
+ width="1.0000153"
+ height="1"
+ x="-197.00002"
+ y="-79" />
+ <rect
+ y="-75"
+ x="-194.5"
+ height="1.0000088"
+ width="1.4999988"
+ id="rect37984"
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-76"
+ x="-195.00002"
+ height="1"
+ width="1.0000153"
+ id="rect37986"
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37988"
+ width="1.5000049"
+ height="1.0000198"
+ x="-194.5"
+ y="-77" />
+ <rect
+ style="fill:#800000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37990"
+ width="1.0000153"
+ height="5"
+ x="-193.00002"
+ y="-79" />
+ </g>
+ </g>
+ <g
+ id="g39528">
+ <g
+ clip-path="url(#clipPath40902)"
+ id="g40560"
+ transform="matrix(-1,0,0,1,90,-62)">
+ <rect
+ y="198"
+ x="6"
+ height="16"
+ width="16"
+ id="rect40562"
+ style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.4"
+ id="g40565"
+ transform="matrix(-1,0,0,1,21.999203,19)">
+ <rect
+ rx="1.3125"
+ ry="1.3125001"
+ y="180.53122"
+ x="5.4992032"
+ height="9.9687805"
+ width="10.000007"
+ id="rect40567"
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40569"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ style="fill:none;stroke:url(#linearGradient40679);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-1.00079,-19)"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ id="g40571">
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="path40573"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40575"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 9.49921,181.5 2,0"
+ id="path40577"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40581"
+ transform="matrix(0,1,-1,0,199.75,171.75)">
+ <g
+ transform="matrix(-1,0,0,-1,215.25,222.75)"
+ id="g40583">
+ <path
+ id="path40585"
+ d="m 174.5,38.5 0,5 5,0"
+ style="fill:none;stroke:#00112b;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 175.5,42.5 5,-5"
+ style="fill:none;stroke:#00112b;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40587"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40589"
+ transform="translate(-146.75,127.75)">
+ <g
+ id="g40591"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40593"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d=""
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40595"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40597"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g40599">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40602"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g40604"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ style="display:inline">
+ <path
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40606"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 78.1613,110.99999 5.5,-5.5"
+ style="fill:#abcdff;fill-opacity:1;stroke:#c3dbff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40609"
+ sodipodi:nodetypes="cz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g40611"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-175.75,-207.25)">
+ <path
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path40613"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-160.74474,8.5136728)"
+ style="display:inline;enable-background:new"
+ id="g27675-3">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27679-1"
+ d="m 73.191498,271.86917 7.071067,-7.07107"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ style="opacity:0.95;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path42388-0"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42359-1"
+ style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g39560">
+ <g
+ clip-path="url(#clipPath40897)"
+ id="g40506"
+ transform="matrix(-1,0,0,1,89,-62)">
+ <rect
+ style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40508"
+ width="16"
+ height="16"
+ x="26"
+ y="198" />
+ <g
+ transform="matrix(-1,0,0,1,46.99921,19)"
+ id="g39096-2"
+ style="opacity:0.4;display:inline;enable-background:new">
+ <rect
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39098-5"
+ width="10.000007"
+ height="9.9687805"
+ x="5.4992032"
+ y="180.53122"
+ ry="1.3125001"
+ rx="1.3125" />
+ <path
+ style="fill:none;stroke:url(#linearGradient40733-03);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 6.5,181.53121 7.99921,0 0,7.96879 -7.99921,0 0,-7.96879 z"
+ id="path39100-0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g39118-9"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ transform="translate(-1.00079,-19)">
+ <path
+ id="path39183-4"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 10.25,199 c -0.1385,0 -0.25,0.1115 -0.25,0.25 l 0,1.75 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-1.75 C 13,199.1115 12.8885,199 12.75,199 l -2.5,0 z"
+ id="rect39114-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path39106-8"
+ d="m 9.49921,181.5 2,0"
+ style="opacity:0.45;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-1,-1,0,212.75,247.25)"
+ id="g40522">
+ <g
+ id="g40526"
+ transform="matrix(-1,0,0,-1,215.25,222.75)">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#00112b;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 174.5,38.5 0,5 5,0"
+ id="path40528"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path40533"
+ style="fill:none;stroke:#00112b;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 175.5,42.5 5,-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-146.75,127.75)"
+ id="g40535">
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g40537">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path40539"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path40541"
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d=""
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ id="path40543"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g40545"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-29,-335)">
+ <path
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path40547"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g40549">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path40551"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cz"
+ id="path40553"
+ style="fill:#abcdff;fill-opacity:1;stroke:#c3dbff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 78.1613,110.99999 5.5,-5.5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,-175.75,-207.25)"
+ style="opacity:0.2"
+ id="g40556">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path40558"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g40888"
+ style="display:inline;enable-background:new"
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-194.74474,8.5136728)">
+ <path
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 73.191498,271.86917 7.071067,-7.07107"
+ id="path40890"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40892"
+ style="opacity:0.95;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path40894"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.5478212,-0.56064,0.5419177,0.5545983,197.19518,557.21673)"
+ id="g38570"
+ style="stroke-width:5.41920376;stroke-miterlimit:4;stroke-dasharray:none;display:inline" />
+ <g
+ transform="translate(-1.0992584e-6,128)"
+ id="g44264">
+ <g
+ id="g44266"
+ style="opacity:0.8;display:inline"
+ transform="translate(-138,212)">
+ <g
+ id="g44268"
+ transform="translate(1.0551033e-6,0)">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\Browser icons ver 1\Outliner ICON CODES.png"
+ id="g44270"
+ transform="matrix(0.927273,0,0,1,85.654543,64)"
+ style="display:inline">
+ <path
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ style="fill:none;stroke:#1a1a1a;stroke-width:3.63466382;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path44272"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44274"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z M 63.999982,17 64,19 l 2.156862,0 -1.8e-5,-2 -2.156862,0 0,0 0,0 0,0 z m 10.78431,0 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:none;stroke:#1a1a1a;stroke-width:1.86925566;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient44318);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path44276"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.176776,0,0,1.176776,-12.47787,-2.548088)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ id="path44278"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ececec;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 75.5,17.5"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-1.6176466e-5,0)"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path44280"
+ style="opacity:0.8;fill:none;stroke:url(#radialGradient44320);stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="M 70.499967,14.5 75.5,17.5 m -5.000033,-3 -4.999967,3 m 4.970586,-3 0,-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 74.784292,17 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ id="path44282"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M 70.499967,14.5 65.5,17.5"
+ style="fill:none;stroke:#999999;stroke-width:1.97310317;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path44284"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 70.470586,14.5 0,-6"
+ style="fill:none;stroke:#cccccc;stroke-width:2.07695079;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path44286"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44288"
+ d="m 69.392137,7 0,2 2.156862,0 0,-2 -2.156862,0 z"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44290"
+ d="m 64,17 0,2 2.156844,0 0,-2 L 64,17 z"
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.05;fill:#554400;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44292"
+ width="3.774509"
+ height="3.5"
+ x="68.583321"
+ y="13.25" />
+ <path
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.03847623px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 64.539197,18.5 0,-1 1.078431,0"
+ id="path44294"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44296"
+ d="m 69.931347,8.5 0,-0.9673924 1.078413,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 75.323509,18.500001 0,-1 1.078431,0"
+ id="path44298"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44300"
+ width="17.254898"
+ height="16"
+ x="61.843121"
+ y="5" />
+ <path
+ transform="matrix(1.0784311,0,0,1,-92.372519,-64)"
+ id="path44302"
+ d="m 155,80.5 -3,-1.870665"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccc"
+ id="path44304"
+ d="m 74.245078,17.500001 0,-1 1.078431,0"
+ style="opacity:0.01000001;fill:#d4aa00;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#666666;stroke-width:1.03847647px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 69.931352,9.5000005 1.078431,0"
+ id="path44306"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:#6a6a6a;fill-opacity:1;fill-rule:evenodd;stroke:#4c4c4c;stroke-width:1.03847575px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 66.696014,17.499989 0,-1 -1.078431,0"
+ id="path44308"
+ sodipodi:nodetypes="ccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 147,80.5 3,-1.870665"
+ id="path44310"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44312"
+ d="m 150.5,73.5 0,4"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44314"
+ width="2"
+ height="2"
+ x="150.06403"
+ y="78" />
+ </g>
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44316"
+ width="2.9998772"
+ height="3"
+ x="11.499837"
+ y="289.5"
+ ry="0"
+ rx="0" />
+ </g>
+ <g
+ id="g43843">
+ <g
+ transform="translate(20,-30.990313)"
+ id="g39499">
+ <g
+ style="opacity:0.5"
+ transform="translate(-20,8)"
+ id="g39466">
+ <rect
+ style="opacity:0;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39468"
+ width="16"
+ height="16"
+ x="47"
+ y="642" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path39470"
+ d="m 34.8125,650.5 c -0.469932,0.0628 -0.901978,0.36287 -1.125,0.78125 l -6,11 c -0.495227,0.9075 0.278677,2.21576 1.3125,2.21875 l 12,0 c 1.033823,-0.003 1.807727,-1.31125 1.3125,-2.21875 l -6,-11 c -0.282798,-0.52794 -0.905299,-0.85216 -1.5,-0.78125 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#ffdd55;fill-opacity:1;stroke:#2b0000;stroke-width:0.89999998;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="655"
+ x="34"
+ height="5"
+ width="2.0152419"
+ id="rect39472"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39474"
+ width="2.0152419"
+ height="1"
+ x="33.984756"
+ y="661" />
+ <path
+ id="path39476"
+ d="m 34.936406,651.39468 c -0.144491,0.0192 -0.31295,0.15614 -0.381583,0.28384 l -6.105329,11.1013 c -0.0509,0.0926 -0.05511,0.27404 0.0636,0.47307 0.118705,0.19902 0.275323,0.31508 0.381582,0.31538 l 12.210658,0 c 0.106265,-3e-4 0.262877,-0.11636 0.381583,-0.31538 0.118706,-0.19903 0.114499,-0.38055 0.06359,-0.47307 l -6.105329,-11.1013 c -0.08049,-0.14902 -0.33952,-0.30385 -0.508777,-0.28384 l 5e-6,0 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.5;fill:none;stroke:#ff0000;stroke-width:1.39999998;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ inkscape:connector-curvature="0" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:none;stroke:url(#linearGradient39508);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ d="m 34.936406,651.39468 c -0.144491,0.0192 -0.31295,0.15614 -0.381583,0.28384 l -6.105329,11.1013 c -0.0509,0.0926 -0.05511,0.27404 0.0636,0.47307 0.118705,0.19902 0.275323,0.31508 0.381582,0.31538 l 12.210658,0 c 0.106265,-3e-4 0.262877,-0.11636 0.381583,-0.31538 0.118706,-0.19903 0.114499,-0.38055 0.06359,-0.47307 l -6.105329,-11.1013 c -0.08049,-0.14902 -0.33952,-0.30385 -0.508777,-0.28384 l 5e-6,0 z"
+ id="path39478"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path43799"
+ d="M 54.75,622.5 50,631.25"
+ style="opacity:0.25;fill:none;stroke:#2b2200;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path43801"
+ d="m 29.5,631.5 9.5,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ transform="translate(21,0)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44081"
+ transform="translate(0,1)">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44079"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-22.005631)"
+ id="g43931">
+ <g
+ id="g43459">
+ <g
+ transform="translate(0,21)"
+ id="g43446">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path43448"
+ d="m 333.25,86.005631 -5.25,0 -1,-1 L 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43450"
+ d="M 331.25,80.244369 327,76 l -4.25,4.244369"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g43442">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333.25,86.005631 -5.25,0 -1,-1 L 327,76"
+ id="path42664"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 331.25,80.25 327,76.005631 322.75,80.25"
+ id="path42666"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 328.5,106.50563 5,0 m -7,-7.00563 0,6.50563"
+ id="path43773"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44954);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 322.25,101.00563 4.5,-4.499999 0.5,0 4.5,4.499999"
+ id="path44952"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g44124">
+ <rect
+ y="73"
+ x="341"
+ height="16"
+ width="16"
+ id="rect44077"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g44913"
+ transform="translate(0,1)">
+ <g
+ transform="matrix(-1,0,0,-1,698,183)"
+ id="g43652">
+ <path
+ sodipodi:nodetypes="csc"
+ id="path43654"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2 8,0.5"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43660"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,698,183)"
+ id="g43662">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2.25 8,0.5"
+ id="path43668"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path43666"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path43671"
+ d="m 354,78 0,-1 0,-1.5 -1,0 0,1.5 -1.5,0 0,1 1.5,0 1,0 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43747"
+ d="M 353.09375,76.40625 C 350.56802,73.88797 346.75,74 344.25,76"
+ style="fill:none;stroke:url(#linearGradient44944);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 350.5,78.5 4,0 0,-4"
+ id="path43750"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44931"
+ transform="translate(0,-1)">
+ <g
+ transform="translate(0,-21)"
+ id="g43636">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2.25 8,0.5"
+ id="path43623"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path43506"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,-21)"
+ id="g43632">
+ <path
+ sodipodi:nodetypes="csc"
+ id="path43584"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 5.75,2.25 8,0.5"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43502"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344,84 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ id="rect43547"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 347.5,82.5 -4.5,0 c -0.25,0 -0.5,0.25 -0.5,0.5 l 0,4.5"
+ id="path43761"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44942);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 345.59375,84.90625 c 2.07803,2.0719 5.36384,2.10325 7.53125,0.1875"
+ id="path43765"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g44097">
+ <rect
+ y="52"
+ x="320"
+ height="16"
+ width="16"
+ id="rect44095"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(42.999999,-42)"
+ id="g43952">
+ <g
+ transform="matrix(0,-1,1,0,183.99437,429)"
+ id="g43483">
+ <g
+ transform="translate(0,21)"
+ id="g43488">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43490"
+ d="M 327,86.255631 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43492"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g43494">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 327,86.255631 327,76"
+ id="path43496"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43498"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43776"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44485);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 284,97.25 -4.5,4.5 0,0.5 4.5,4.5"
+ id="path43780"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43860"
+ d="m 291.5,101.5 -8.99437,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-1,0)"
+ id="g44111">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44093"
+ width="16"
+ height="16"
+ x="341"
+ y="52" />
+ <g
+ transform="translate(41.97875,-42)"
+ id="g43941">
+ <g
+ id="g43467"
+ transform="matrix(0,-1,-1,0,409.02125,429)">
+ <g
+ id="g43469"
+ transform="translate(0,21)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 327,86.25 327,76"
+ id="path43471"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43473"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43475"
+ transform="translate(0,21)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43478"
+ d="M 327,86.25 327,76"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43481"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 308.5,106 2.75,-2.75"
+ id="path43778"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path43785"
+ d="m 308.75,97.25 c -0.25,0 -0.5,0.25 -0.5,0.5 m 2.26562,3.75 -8.99437,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient44950);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 309.02125,97.249998 4.5,4.500002 0,0.5 -4.5,4.5"
+ id="path44948"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g32752"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\v. 2.5.06\prvicons 2.5.06.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="180"
+ x="872"
+ height="192"
+ width="192"
+ id="rect30285"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.39191818;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ transform="translate(856,-203)"
+ id="g21955"
+ style="opacity:0.3;display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21957"
+ width="48"
+ height="48"
+ x="108"
+ y="430"
+ rx="2.4004419"
+ ry="0" />
+ <g
+ id="g21959">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21961"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient21977);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21963"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21965"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21967"
+ style="fill:none;stroke:url(#linearGradient21979);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21969"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21971"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21973"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21975"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g30335">
+ <g
+ id="g21367"
+ transform="translate(760,-202)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21369"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30321);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21371"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21373"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21375"
+ style="fill:none;stroke:url(#linearGradient30323);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21377"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21569"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21379"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21381"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="font-size:33.49144363px;font-style:normal;font-weight:normal;fill:#214478;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
+ d="m 891.07148,245 -0.0715,9 2.39012,0 C 896,254 896,253 896.5,251 l 0.5,0 0,7 -0.5,0 c -0.5,-2 -0.5,-3 -3.10988,-3 L 891,255 l 0,7 c 0,2.5 1,3.25 3.14146,3.39973 l -0.004,0.60029 L 885,266 l 0.004,-0.60029 C 887,265.25 888,264.5 888.00001,262 L 888,248 c 0,-2.5 -1,-3.25 -3,-3.5 l 0,-0.5 16,0 0,5 -0.5,0 c -0.50001,-1.99999 -1.5,-4 -4.5,-4 l -4.92852,0 z"
+ id="text13209"
+ sodipodi:nodetypes="ccccccccccccccccccccccc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21625"
+ transform="translate(904,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21627"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21629">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21647);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21631"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ style="opacity:0.5;fill:#000000;display:inline"
+ id="g16261"
+ transform="matrix(1.2499985,0,0,1,-87.6203,-147.85351)">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35099"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="598.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35101"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="600.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15690"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="602.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15692"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="604.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15694"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="606.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15696"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="608.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15698"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="610.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15700"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="612.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15732"
+ width="14.400002"
+ height="1"
+ x="167.69646"
+ y="614.85352"
+ rx="0.09920612"
+ ry="0.065390877" />
+ <g
+ transform="translate(150.89645,557.85352)"
+ id="g4849"
+ style="fill:#000000;display:inline">
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="29"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15736"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="31"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15738"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="33"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15740"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="35"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15742"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.055114571"
+ y="37"
+ x="16.799992"
+ height="1"
+ width="8.0000095"
+ id="rect15744"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ ry="0.065390304"
+ rx="0.0057410933"
+ y="617.85352"
+ x="184.49646"
+ height="0.99999124"
+ width="0.83333319"
+ id="rect16334"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21633"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21635"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21649);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21637"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21639"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21641"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21643"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g35119"
+ transform="translate(2,-160.99999)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ transform="translate(105.39645,589.71201)"
+ id="g16097">
+ <g
+ id="g16099"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)">
+ <radialGradient
+ id="radialGradient16101"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16103" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16105" />
+ </radialGradient>
+ <radialGradient
+ id="radialGradient16109"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16111" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16113" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ id="path16107" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#radialGradient21565);fill-rule:nonzero;stroke:none"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ id="path16117" />
+ </g>
+ <g
+ id="g16131"
+ transform="translate(105.39645,579.71201)"
+ style="display:inline">
+ <g
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ id="g16133">
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="114.5684"
+ fx="20.892099"
+ r="5.256"
+ cy="114.5684"
+ cx="20.892099"
+ id="radialGradient16135">
+ <stop
+ id="stop16137"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16140"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="64.567902"
+ fx="20.892099"
+ r="5.257"
+ cy="64.567902"
+ cx="20.892099"
+ id="radialGradient16142">
+ <stop
+ id="stop16144"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16146"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path35139"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35141"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ style="fill:url(#radialGradient21567);fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21645"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21572"
+ transform="translate(808,-203)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21574"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21576">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21594);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21578"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21580"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21582"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21596);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21584"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21586"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21588"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21590"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21592"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g30382">
+ <g
+ id="g23655"
+ transform="translate(760,-154)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path23657"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path23659"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path23661"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path23663"
+ style="fill:none;stroke:url(#linearGradient30370);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23665"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path23667"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path23669"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23671"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 888,295 1,0 0,14 -1,0 0,-14 z"
+ id="path23675"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23677"
+ d="m 900,294 1.00002,-1 0,14 -1.00002,0 0,-13 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path23679"
+ d="m 901.00003,292 0,2.25 -13.00002,2 0,-2.25 13.00002,-2 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23681"
+ transform="matrix(1.1428564,0,0,1.2000001,822.71436,-355.40005)">
+ <path
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23683"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ id="path23685"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ inkscape:transform-center-y="0.3813435"
+ clip-path="url(#clipPath20586)" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.38999999;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 901.00003,292 -1e-5,1 -13.00002,2 10e-6,-1 13.00002,-2 z"
+ id="path23694"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ transform="matrix(1.1428564,0,0,1.2000001,834.71436,-357.40005)"
+ id="g23717">
+ <path
+ sodipodi:type="arc"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23724"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)" />
+ <path
+ clip-path="url(#clipPath20586)"
+ inkscape:transform-center-y="0.3813435"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23726"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g23922"
+ transform="translate(-16,-220)"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g23924"
+ transform="translate(824,66)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect23926"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23928">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient23978);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path23930"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23932"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path23934"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient23980);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23936"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path23938"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path23940"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path23942"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path23944"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccc"
+ id="path23946"
+ d="m 952,530 0,10 1,0 1,0 11,0 1,0 1,0 0,-10 -15,0 z m 1,2 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient23982);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23948"
+ width="13"
+ height="5.5"
+ x="953"
+ y="-524" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23952"
+ transform="translate(76,0)"
+ d="m 876,514 0,17 15,0 0,-17 -1,0 0,1 -1,0 0,-1 -11,0 0,1 -1,0 0,-1 -1,0 z m 1,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
+ style="fill:url(#linearGradient23986);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 952,507 3,0 0,3 9,0 0,-3 3,0 0,7 -15,0 0,-7 z m 1,0 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z m 12,-4 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z"
+ id="path23954" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="507"
+ height="9"
+ width="3"
+ id="rect23956"
+ style="fill:url(#linearGradient23988);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23958"
+ width="9"
+ height="9"
+ x="512"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="523"
+ height="9"
+ width="9"
+ id="rect23960"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ transform="matrix(0,-0.5624971,0.5624971,0,893.12531,590.74965)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path23962"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23964"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,601.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path23966"
+ d="m 961.00001,519.00005 -3,0 0,-0.99992 0.99994,0 6e-5,-2.00008 -1,0 0,-1 1,0 0,-1 1.00006,0 0,4.00008 0.99994,0 0,0.99992 z" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,525 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path23968" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23970"
+ width="6"
+ height="9"
+ x="534"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ clip-path="url(#clipPath23877)"
+ id="g23972">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23974"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,612.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,536 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,1 -2,0 0,1 2,0 0,-1 z"
+ id="path23976" />
+ </g>
+ </g>
+ <g
+ transform="translate(208,88)"
+ id="g45475"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g22242"
+ transform="translate(696,-194)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect22244"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22246">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient22274);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path22249"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path22251"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path22253"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient22276);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path22264"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path22266"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path22268"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path22270"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path22272"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g21517"
+ inkscape:label="Layer 1"
+ transform="matrix(0.5406242,0,0,0.5829534,814.13667,247.65542)">
+ <path
+ transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)"
+ d="m 43.487067,38.98439 a 15.467961,5.3033009 0 1 1 -30.935922,0 15.467961,5.3033009 0 1 1 30.935922,0 z"
+ sodipodi:ry="5.3033009"
+ sodipodi:rx="15.467961"
+ sodipodi:cy="38.98439"
+ sodipodi:cx="28.019106"
+ id="path35486"
+ style="opacity:0.54857142;fill:url(#radialGradient21442);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssssssssscccsscccscccssccc"
+ d="m 16.048489,28.093447 c 0.0098,0.576682 0.196474,1.697902 0.471116,2.577425 0.581566,1.854137 1.56684,3.572658 2.939126,5.086496 1.407488,1.553118 3.138519,2.803227 5.139315,3.68976 2.105357,0.931573 4.384795,1.407488 6.750134,1.403741 2.365339,-0.005 4.644601,-0.488686 6.74896,-1.427017 2.00002,-0.895288 3.731043,-2.148391 5.13754,-3.705517 1.369207,-1.519844 2.352576,-3.241114 2.934089,-5.096258 0.294262,-0.938353 0.476921,-1.889392 0.553238,-2.845308 0.07331,-0.939306 0.04204,-1.883511 -0.09183,-2.823792 -0.259981,-1.835599 -0.896294,-3.556847 -1.872652,-5.12758 -0.895541,-1.441699 -2.047808,-2.70454 -3.417268,-3.766975 0,0 0.002,-0.002 0.002,-0.002 0,0 -13.828458,-10.6197195 -13.828458,-10.6197195 -0.01176,-0.00978 -0.02252,-0.019551 -0.03529,-0.028344 -0.909003,-0.6959264 -3.879837,-0.7738945 -4.87679,-0.075035 -1.01067,0.7057021 -1.091821,1.8092613 -0.195527,2.5482146 1.899775,1.4997633 2.656207,2.2801589 4.566507,3.7797379 0,0 -14.852491,0.167033 -14.852491,0.167033 -1.994685,0 -3.1682609,0.947915 -3.4153947,2.333683 -0.2180771,1.222836 0.7479213,2.738129 2.4800217,2.738129 2.956573,0.0039 5.942111,-0.0069 8.909215,-0.01272 0,0 -16.01999,12.453223 -16.01999,12.453223 -0.020527,0.01564 -0.041053,0.02933 -0.06158,0.04497 -1.4974197,1.148389 -1.9831951,3.059322 -1.0399808,4.268393 0.9598323,1.22959 2.9977653,1.230588 4.5147288,0.006 0,0 8.677593,-7.102098 8.677593,-7.102098 0,0 -0.12511,0.959824 -0.116333,1.535532 l 1e-6,2.6e-5 0,0 0,0 z"
+ id="path2482"
+ style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)"
+ d="m 42.75,25.75 a 11.5625,10.125 0 1 1 -23.125,0 11.5625,10.125 0 1 1 23.125,0 z"
+ sodipodi:ry="10.125"
+ sodipodi:rx="11.5625"
+ sodipodi:cy="25.75"
+ sodipodi:cx="31.1875"
+ id="path39153"
+ style="fill:url(#linearGradient21444);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.4857143;fill:none;stroke:url(#linearGradient21446);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 25.8125,6.40625 c -0.334829,4.572e-4 -0.72202,0.089606 -0.90625,0.21875 4.5e-4,0.010412 4.5e-4,0.020838 0,0.03125 -0.212626,0.1484635 -0.188235,0.1956271 -0.1875,0.1875 0.0092,0.010621 -0.0072,-4.246e-4 0.03125,0.03125 0.01962,0.00828 0.03527,0.012546 0.0625,0.03125 0.01676,0.01151 0.01357,0.014555 0.03125,0.03125 0.193748,0.1576058 4.954976,4.005164 4.954976,4.005164 0.489837,0.39864 0.677395,1.066352 0.46875,1.65625 -0.115662,0.32703 -0.422813,0.541217 -0.6875,0.59375 -0.264687,0.05253 -0.498447,0.03054 -0.71875,0.03125 -5.639658,0.05119 -16.87989,0.03851 -16.87989,0.03851 -0.4102,2.75e-4 -0.935835,0.115997 -1.34375,0.34375 -0.407915,0.227753 -0.6637862,0.523861 -0.6875002,0.90625 -0.024417,0.393728 0.098829,0.605767 0.3437502,0.78125 0.244921,0.175483 0.614978,0.25 0.875,0.25 0,0 8.8125,0 8.8125,0 0.600305,-7.28e-4 1.223895,0.311058 1.4375,0.9375 0.04676,0.137121 0.06335,0.269976 0.0625,0.40625 -8.49e-4,0.136274 -0.02214,0.268794 -0.09375,0.375 -0.143211,0.212412 -0.319507,0.298568 -0.5,0.4375 0,0 -15.7871819,12.746851 -15.856336,12.800078 C 5.0310984,30.500117 5,30.53125 5,30.53125 5.0100745,30.519077 5.000335,30.499512 5,30.5 L 4.8125,30.3125 c 0.012336,0.02165 0.014481,0.03307 0.03125,0.0625 0.063558,0.0774 0.125,0.15625 0.125,0.15625 -0.00585,0.0056 -0.031233,0.03124 -0.03125,0.03125 0,0 -0.043442,-0.09921 -0.09375,-0.1875 0.037843,0.09884 0.06253,0.218739 0.0625,0.21875 -0.4662091,0.37119 -0.7783348,0.889746 -0.875,1.28125 -0.1043319,0.422581 -0.046,0.62455 0.125,0.84375 0.2999827,0.384295 1.3975356,0.595547 2.40625,-0.21875 0,0 8.65625,-7.09375 8.65625,-7.09375 0.473718,-0.387074 1.1446,-0.458625 1.6875,-0.15625 0.544608,0.303331 0.798054,0.927572 0.71875,1.53125 0,0 -0.0626,0.908319 -0.0625,1.25 2e-6,0.0085 -1.19e-4,0.02348 0,0.03125 0.192796,2.523718 1.400736,4.762818 3.03125,6.71875 2.801818,3.089095 6.627659,4.401619 10.75,4.5625 4.113324,-0.043 7.964529,-1.606111 10.75,-4.625 2.546631,-3.125326 3.513872,-6.363859 3.15625,-9.375 C 44.891575,22.325847 43.222923,19.516566 40.4375,17.25 35.951885,13.599946 31.206991,10.168434 26.59375,6.625 26.57515,6.610386 26.56455,6.59802 26.5625,6.59375 26.43835,6.498703 26.144223,6.4057899 25.8125,6.40625 z"
+ id="path21414"
+ sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 25.708956,26.064593 c 0.07649,-1.397943 0.759369,-2.631914 1.78592,-3.505519 1.010226,-0.858782 2.366788,-1.383145 3.848625,-1.383145 1.480894,0 2.837456,0.524363 3.847446,1.383145 1.027685,0.873605 1.709741,2.106651 1.787122,3.504594 0.07927,1.438713 -0.49591,2.77459 -1.504012,3.764001 -1.027686,1.007933 -2.493008,1.640678 -4.130556,1.640678 -1.63849,0 -3.103814,-0.632745 -4.131451,-1.640678 -1.00914,-0.989411 -1.58234,-2.325288 -1.503094,-3.763076 l 0,0 0,0 0,0 z"
+ id="path2478"
+ style="fill:#3465a4;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
+ id="path39166"
+ d="m 25.8125,6.03125 c -0.404852,5.53e-4 -2.204797,-0.059029 -2.48145,0.1349032 -0.280209,0.195652 -0.335403,0.376484 -0.34375,0.46875 -0.0083,0.092266 -0.01539,0.17648 0.1875,0.34375 0.01899,0.015735 0.04457,0.014317 0.0625,0.03125 0.124258,0.101028 4.748869,4.1248618 4.748869,4.1248618 0.373658,0.304091 0.504393,0.795817 0.34375,1.25 -0.160635,0.454191 -0.580748,0.373449 -1.0625,0.375 -5.634142,0.05114 -15.087371,-0.129601 -15.087371,-0.129601 -0.952967,6.38e-4 -2.339958,0.524782 -2.4062504,1.59375 -0.063562,1.024947 0.9247974,1.4375 1.5937504,1.4375 0,-1e-6 8.8125,0 8.8125,0 0.488364,-5.92e-4 0.936141,0.225277 1.09375,0.6875 0.157609,0.462231 -0.01926,0.514621 -0.40625,0.8125 0,0 -16.086298,13.088586 -16.086298,13.088586 -0.00142,0.0014 -0.029829,-0.0014 -0.03125,0 -0.064037,0.04879 -0.054226,0.04875 -0.03125,0.03125 -0.5536758,0.424619 -0.9087886,1.004019 -1.03125,1.5 -0.1224536,0.495981 -0.04661,0.856152 0.1875,1.15625 0.4788333,0.613413 1.777612,0.754857 2.90625,-0.15625 1e-7,10e-7 8.65625,-7.09375 8.65625,-7.09375 0.361955,-0.295753 0.872897,-0.352437 1.28125,-0.125 0.408345,0.227436 0.623381,0.692814 0.5625,1.15625 0,-1e-6 -0.0997,0.953636 -0.09375,1.34375 0.09498,1.301756 0.451616,2.521825 0.989039,3.664234 C 20.799917,36.321089 27.770982,19.392853 44.1875,21.03125 43.339652,19.54368 42.151282,18.185293 40.65625,16.96875 36.159865,13.309932 31.42016,9.882897 26.8125,6.34375 26.805335,6.338858 26.788292,6.317553 26.78125,6.3125 26.570707,6.151312 26.216591,6.030689 25.8125,6.03125 z"
+ style="opacity:0.51999996;fill:url(#radialGradient21448);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.5"
+ id="g24847"
+ transform="translate(162,248)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24867);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24849"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24851"
+ style="opacity:0.07999998;fill:url(#linearGradient24869);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24853"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24871);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24855"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,4.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24857" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24859"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24861" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24863"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24873);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24865"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.5"
+ transform="translate(114,248)"
+ id="g24784">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z"
+ id="path24789"
+ style="fill:url(#linearGradient24809);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ style="opacity:0.07999998;fill:url(#linearGradient24811);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24791" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient24813);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ id="path24793"
+ sodipodi:nodetypes="csccsczc"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-ydpi="74.800003" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccssccc"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path24796"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24799"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 840.5,89 0,4.5"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24801" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24803"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ sodipodi:nodetypes="cccccccsc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsscccssssccc"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24805"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscc"
+ id="path24807"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ style="fill:none;stroke:url(#linearGradient24815);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ <g
+ transform="translate(0,-2)"
+ style="opacity:0.4;stroke:#3d361a;filter:url(#filter44473)"
+ id="g44424">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44406"
+ d="m 950.25,362 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44408"
+ d="M 948.25,354.25 944,350.00563 939.75,354.25"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ </g>
+ <g
+ transform="translate(617,273)"
+ id="g44334"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44336"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-21)"
+ id="g44338">
+ <g
+ id="g44340">
+ <g
+ transform="translate(0,21)"
+ id="g44342">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44344"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44346"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g44348">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ id="path44350"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path44352"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 328.5,107.5 5,0 m -7,-9 0,8.5 m -4.25,-7 4.5,-4.5"
+ id="path44354"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(66,248)"
+ id="g24818"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24839);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24821"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24823"
+ style="opacity:0.07999998;fill:url(#linearGradient24841);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24825"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-16 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,17 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24843);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24827"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,7.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24829" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24831"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,98.75 0,14.75 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-16 34,0 m -29,-10 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24833" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-16 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-8 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24835"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24845);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,96.500004 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,15.999996 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24837"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.4;filter:url(#filter44477)"
+ id="g44455">
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44446"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44449"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="cs"
+ id="path44451"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="ccc"
+ id="path44453"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(645,273.05)"
+ id="g44356"
+ style="display:inline;enable-background:new">
+ <rect
+ y="73"
+ x="341"
+ height="16"
+ width="16"
+ id="rect44358"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0,-21)"
+ id="g44360">
+ <g
+ id="g44362">
+ <g
+ id="g44364">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44366"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44368"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g44370">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44372"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44374"
+ sodipodi:nodetypes="cs" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path44376"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g44378"
+ transform="matrix(-1,0,0,-1,698,204)">
+ <g
+ id="g44380">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44382"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44384"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="g44386">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44388"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44390"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ id="path44392" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44402);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344.90625,106.59375 c 2.52573,2.51828 6.66805,2.52691 9.1875,0 l 0.5,-0.5"
+ id="path44394"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 350.5,99.5 4,0 0,-4"
+ id="path44396"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 347.5,103.5 -4.5,0 c -0.25,0 -0.5,0.25 -0.5,0.5 l 0,4.5"
+ id="path44398"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44404);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 345.59375,105.90625 c 2.07803,2.0719 5.36384,2.10325 7.53125,0.1875 L 354,105.25"
+ id="path44400"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g34977"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g21853-3"
+ transform="translate(856,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21855-8"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21857-6">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21875-7-1-0-1);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21859-9"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21861-8"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21863-6"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21877-3-2-7-2);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21865-6"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21867-2"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21869-3"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21871-8"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21873-2"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g34938"
+ transform="translate(63,-47)">
+ <path
+ id="path61236"
+ style="color:#000000;fill:url(#linearGradient34959-9-2-1);fill-opacity:1;fill-rule:nonzero;stroke:#ff0000;stroke-width:0.17893334;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 919.5,356.5067 0,-3 c 0,-1.73575 1.26424,-3 3,-3 l 5,0 c 1.73576,0 3,-1.26425 3,-3 l 0,-3.0064 2.5,0.006 c 2,0 3.5,2.5 3.5,6 0,3.5 -1.25,6 -3.5,6 -4.98134,0 -12.77318,0 -2.5,0 l 0,2.75 c 0,2.5 -2,3.24997 -5.5,3.24998 l 0,2e-5 c -3.5,0.0104 -5.5,-0.75 -5.5,-3.25 l 0,-2.7628"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssccsscsccsc" />
+ <path
+ sodipodi:nodetypes="cssssccsscsccsc"
+ inkscape:connector-curvature="0"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3.0064 -2.5,-0.006 c -2,0 -3.5,-2.5 -3.5,-6 0,-3.5 1.25,-6 3.5,-6 4.98134,0 12.77318,0 2.5,0 l 0,-2.75 c 0,-2.5 2,-3.24997 5.5,-3.24998 l 0,-2e-5 c 3.5,-0.0104 5.5,0.75 5.5,3.25 l 0,2.7628"
+ style="color:#000000;fill:url(#linearGradient34961-3-6-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.17893334;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61233" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccscccsccccsccccc"
+ id="path61167"
+ d="m 925,338.50002 c -3.5,10e-6 -5.5,0.74998 -5.5,3.24998 l 0,2.75 5.5,0 -8,0 c -2.25,0 -3.5,2.5 -3.5,6 0,3.5 1.5,6 3.5,6 l 2.5,0.0128 0,2.9872 c 0,2 2,3.01281 5.5,3.0128 3.5,-1e-5 5.5,-1.0128 5.5,-3.0128 l 0,-3 -5.5,0 8,0 c 2,0 3.5,-2.5 3.5,-6 0,-3.5 -1.5,-6 -3.5,-6 l -2.5,0.0128 0,-2.7628 c 0,-2.5 -2,-3.26045 -5.5,-3.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path61169"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.78431373;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 923,342 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path61220"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ d="m 929,359 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="359"
+ sodipodi:cx="928"
+ id="path61222"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <g
+ style="opacity:0.4"
+ id="g61345">
+ <path
+ style="fill:none;stroke:url(#linearGradient34963-5-9-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ id="path61333"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cszsc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient34965-1-5-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5 0,3 1.28917,5 2.5,5 l 1.5,0"
+ id="path61335"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccszsc" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ id="path61337"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 918.5,355.25 0,-1.75 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ id="path61339"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssc" />
+ <path
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)"
+ sodipodi:type="arc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34967-4-1-8);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61355"
+ sodipodi:cx="922"
+ sodipodi:cy="342"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 923,342 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
+ </g>
+ <g
+ style="opacity:0.8;stroke:#ff0000"
+ transform="matrix(-1,0,0,-1,1850,701)"
+ id="g34104">
+ <path
+ sodipodi:nodetypes="cszsc"
+ inkscape:connector-curvature="0"
+ id="path34106"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ style="fill:none;stroke:none" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path34108"
+ d="m 914.5,350.5 c 0,3 1.28917,5 2.5,5 l 1.5,0"
+ style="fill:none;stroke:url(#linearGradient34969-4-4-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path34110"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ style="fill:none;stroke:url(#linearGradient34971-5-0-9);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0"
+ id="path34113"
+ d="m 918.5,355.5 0,-2 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ style="fill:none;stroke:url(#radialGradient34973-2-5-7);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ d="m 923,342 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path34115"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34975-9-4-9);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5"
+ id="path34901"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccsc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g44575"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\fullscreen.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(168,-42)">
+ <g
+ id="g43593"
+ transform="matrix(-1,0,0,1,677,525)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 347.25,100.25 -4,-4"
+ id="path43595"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,100.25 0,-4.25 4.25,0"
+ id="path43597"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,-21,729)"
+ id="g44539">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44541"
+ d="m 347.25,100.25 -4,-4"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44543"
+ d="m 343,100.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43599"
+ transform="matrix(-1,0,0,1,677,517)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43601"
+ d="M 347.25,108.25 343,104"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43603"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 333.5,622.5 0,3 m -4,-5 4.5,0"
+ id="path44489"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 329.25,625 2,-2"
+ id="path44491"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333,622 0,1 0,1.5 -1,0 0,-1.5 -1.5,0 0,-1 1.5,0 1,0 z"
+ id="path43605"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1,0,0,-1,-21,737)"
+ id="g44545">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 347.25,108.25 343,104"
+ id="path44547"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44549"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path44551"
+ d="m 323.5,632.5 3,0 m -5,-4 0,4.5"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44553"
+ d="m 326,628.25 -2,2"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44555"
+ d="m 323,632 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44633"
+ transform="translate(189.0625,-42)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\fullscreen.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g44671"
+ transform="matrix(-1,0,0,-1,662.9375,1247)">
+ <g
+ id="g44635"
+ transform="matrix(-1,0,0,1,677,525)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 347.25,100.25 -4,-4"
+ id="path44637"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,100.25 0,-4.25 4.25,0"
+ id="path44639"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44647"
+ transform="matrix(-1,0,0,1,677,517)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44649"
+ d="M 347.25,108.25 343,104"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44651"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 332.5,621.5 -3,0 m 5,4 0,-4.5"
+ id="path44653"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 330,625.75 2,-2"
+ id="path44655"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 333,622 0,1 0,1.5 -1,0 0,-1.5 -1.5,0 0,-1 1.5,0 1,0 z"
+ id="path44657"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g44682"
+ transform="matrix(-1,0,0,-1,648.9375,1261)">
+ <g
+ transform="matrix(1,0,0,-1,-21,729)"
+ id="g44641">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44643"
+ d="m 347.25,100.25 -4,-4"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path44645"
+ d="m 343,100.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,-21,737)"
+ id="g44659">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 347.25,108.25 343,104"
+ id="path44661"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44663"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path44665"
+ d="m 322.5,631.5 0,-3 m 4,5 -4.5,0"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path44667"
+ d="m 326.75,629 -2,2"
+ style="opacity:0.93999993;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path44669"
+ d="m 323,632 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ clip-path="url(#clipPath45147)"
+ id="g45199">
+ <g
+ id="g45201"
+ clip-path="none"
+ transform="translate(1,1)">
+ <rect
+ y="261"
+ x="4"
+ height="16"
+ width="16"
+ id="rect45203"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-96.98388,244)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g45205"
+ style="display:inline">
+ <path
+ id="path45207"
+ style="fill:url(#linearGradient45220);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 105.48388,31.25 6.25,-6 c 0.49692,0.284098 0.2225,0.232267 0.76612,0.25 2.20206,0.07183 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -4,1.792 -4,4 0,0.58349 0.009,0.250006 0.23388,0.75 l -6.25,6 0,2 1,1 2,0 z"
+ sodipodi:nodetypes="ccsccccccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ d="m 115.5,21.5 -2.25,2.25 m -1,-5.5 c -1.75,0 -4,2.25 -2.5,5 l -1.26612,0.25 -5,5 0,1.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45209"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccsccccccccsccccccc"
+ d="m 105.48388,31.5 5.5,-5.5 0.25,-0.5 1.26612,0 c 2.73388,0 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -3.96454,1.25 -4,4 l -0.0161,1.25 -0.5,0.25 -5.5,5.5 0,2 1,1 2,0 -2e-5,0 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45211"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ d="m 109.98388,25 -5,5"
+ style="fill:none;stroke:#afc6e9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45214"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path45216"
+ style="fill:none;stroke:#336abd;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 109.48388,24.5 -4,4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45218"
+ width="1"
+ height="1"
+ x="103.98388"
+ y="29" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g45262">
+ <rect
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="rect45264"
+ width="16"
+ height="16"
+ x="-420"
+ y="577"
+ transform="scale(-1,1)" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 412,585 0,-6"
+ id="path45266"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path45268"
+ d="m 412,585 0,-6"
+ style="fill:none;stroke:#b3b3b3;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ style="fill:none;stroke:#ffffff;stroke-width:2.56570244;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g45270"
+ transform="matrix(0.5478212,-0.56064,0.5419177,0.5545983,197.19518,557.21673)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:open="true"
+ transform="matrix(0.9615911,0.00541935,0.00537191,0.9740527,43.776178,107.51876)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:4.37432003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path45272"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="0.063198177"
+ sodipodi:end="4.6607369" />
+ <path
+ sodipodi:end="4.6607369"
+ sodipodi:start="0.063198177"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path45274"
+ style="fill:none;stroke:#b3b3b3;stroke-width:2.65110302;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.9615911,0.00541935,0.00537191,0.9740527,43.776178,107.51876)"
+ sodipodi:open="true" />
+ <path
+ sodipodi:open="true"
+ transform="matrix(1.0558925,0.00528428,0.00523802,1.0695762,31.432317,96.175729)"
+ sodipodi:type="arc"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient45283);stroke-width:1.20716298;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path45276"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="0.063198177"
+ sodipodi:end="4.6607369" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="4.6607369"
+ sodipodi:start="0.063198177"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path45278"
+ style="opacity:0.75;fill:none;stroke:url(#linearGradient45285);stroke-width:1.44679213;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(0.8810135,0.00553476,0.00548631,0.8924309,54.323627,117.21103)" />
+ </g>
+ <path
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 411.5,585 0,-6"
+ id="path45280"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(517.99163,649)"
+ id="g45287">
+ <path
+ sodipodi:nodetypes="cccccccc"
+ d="m -120.49163,-67.5 c -3.75159,0.954856 -7.20393,6.261452 -9,9 l -3.5,-3.5 -0.25,0.5 3.99163,4 0.5,0 c 1.0421,-2.617689 4.16191,-8.585412 8.25837,-10 l 0,0 z"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path45290"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#0b1e00;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path45302"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path45294"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g42952"
+ style="display:inline;enable-background:new"
+ transform="translate(433,-61)">
+ <rect
+ y="554"
+ x="-113"
+ height="16"
+ width="16"
+ id="rect42954"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-252,462.99988)"
+ id="g42956">
+ <g
+ id="g42958"
+ transform="translate(-179,199.50012)">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ id="path42960"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g42962"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42964"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path42966"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42968"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient42988);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42970"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#f2f2f2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path42972"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient42990);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect42974"
+ style="opacity:0.18000004;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42976"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.7882544,0,0,0.7883038,-210.45268,388.9974)"
+ id="g42978"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42980"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42982"
+ style="opacity:0.8;fill:url(#linearGradient42992);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42984"
+ style="fill:none;stroke:url(#linearGradient42994);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" />
+ </g>
+ <path
+ id="path42986"
+ d="m -102.5625,554.75 c -0.0429,0.005 -0.0849,0.0154 -0.125,0.0312 l -4.5,1.75 c -0.1919,0.0756 -0.31653,0.26258 -0.3125,0.4688 l 0,6.5 c 0.003,0.18741 0.11203,0.35691 0.28125,0.4375 l 4.5,2.25 c 0.13787,0.0682 0.29963,0.0682 0.4375,0 l 4.499997,-2.25 c 0.169224,-0.0806 0.278188,-0.25009 0.28125,-0.4375 l 0,-6.5 c 0.004,-0.2062 -0.120622,-0.39315 -0.3125,-0.46875 l -4.499997,-1.75 c -0.0792,-0.0318 -0.16537,-0.0426 -0.25,-0.0312 l 0,-5e-5 z"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient42996);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43828">
+ <g
+ transform="translate(0,128)"
+ id="g24024">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22150"
+ width="16"
+ height="16"
+ x="299"
+ y="365" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path12337"
+ d="m 304.20488,366.47791 8.33334,0 0,13 -11,0 -1e-5,-10 2.66667,-3 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient14204);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2999758,0,0,1.2999988,365.56499,31.43979)"
+ sodipodi:nodetypes="ccc"
+ id="path12339"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12341"
+ d="m 301.01612,370 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12343"
+ style="fill:none;stroke:url(#linearGradient14198);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 302.51612,371.00001 0,7.5 m 3.5,-11 5.5,0"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 301.53822,368.97791 0,10.5 11,0 0,-13 -8.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path12345"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="translate(-454.0088,290)"
+ mask="url(#mask43822)"
+ sodipodi:nodetypes="cccccccc"
+ id="path43815"
+ d="m 765.0088,212.5 -3.9824,3.5 -0.0176,-2 -6.9736,0 -0.0132,-3 6.9868,0 0.004,-2 z"
+ style="opacity:0.93999993;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:transform-center-x="-2"
+ inkscape:transform-center-y="1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43838"
+ transform="translate(0,-21)"
+ style="opacity:0.4">
+ <g
+ id="g43840"
+ transform="translate(0,128)">
+ <rect
+ y="365"
+ x="299"
+ height="16"
+ width="16"
+ id="rect43842"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:url(#linearGradient43856);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 304.20488,366.47791 8.33334,0 0,13 -11,0 -1e-5,-10 2.66667,-3 0,0 0,0 0,0 z"
+ id="path43844"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ d="M -48.500031,260.50809 -46.5,260.5 l -3.1e-5,-1.99191"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:0.76923829px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1;display:inline;filter:url(#filter31351)"
+ id="path43846"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(1.2999758,0,0,1.2999988,365.56499,31.43979)"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 301.01612,370 4,0 0,-4 -4,4 z"
+ id="path43848"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 302.51612,371.00001 0,7.5 m 3.5,-11 5.5,0"
+ style="fill:none;stroke:url(#linearGradient43858);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path43850"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path43852"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 301.53822,368.97791 0,10.5 11,0 0,-13 -8.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:transform-center-y="1"
+ inkscape:transform-center-x="-2"
+ style="opacity:0.93999993;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m 765.0088,212.5 -3.9824,3.5 -0.0176,-2 -6.9736,0 -0.0132,-3 6.9868,0 0.004,-2 z"
+ id="path43854"
+ sodipodi:nodetypes="cccccccc"
+ mask="url(#mask43822)"
+ transform="translate(-454.0088,290)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g46790"
+ transform="translate(0,12)" />
+ <g
+ id="g46890" />
+ <g
+ id="g46912"
+ transform="translate(547.9924,59.00343)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\strands selection modes.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="107"
+ x="23"
+ height="16"
+ width="16"
+ id="rect46788"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(-1,0,0,1,0,12)" />
+ <g
+ style="opacity:0.55;display:inline;enable-background:new"
+ transform="translate(-22,30)"
+ id="g46766">
+ <g
+ id="g46768"
+ transform="translate(23.01472,-88)">
+ <path
+ id="path46770"
+ style="fill:none;stroke:url(#linearGradient46780);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46782);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46772"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(24.03125,-88)"
+ id="g46774">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ style="fill:none;stroke:url(#linearGradient46784);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46776"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46778"
+ style="fill:none;stroke:url(#linearGradient46786);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g46860"
+ transform="translate(18.998123,-58.00355)"
+ style="display:inline;enable-background:new">
+ <path
+ id="path46862"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ style="fill:none;stroke:#462300;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path46864"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(26.01365,-55.00527)"
+ id="g46866">
+ <path
+ style="fill:none;stroke:#462300;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ id="path46868"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path46870"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g46928"
+ transform="translate(547.9924,59.00343)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\strands selection modes.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ transform="translate(-20,0)"
+ id="g46800">
+ <rect
+ transform="scale(-1,1)"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect46802"
+ width="16"
+ height="16"
+ x="24"
+ y="119" />
+ <g
+ id="g46804"
+ transform="translate(-22,18)"
+ style="opacity:0.55;display:inline;enable-background:new">
+ <g
+ transform="translate(23.01472,-76)"
+ id="g46806">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46818);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46808"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46810"
+ style="fill:none;stroke:url(#linearGradient46820);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g46812"
+ transform="translate(24,-76)">
+ <path
+ id="path46814"
+ style="fill:none;stroke:url(#linearGradient46822);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ style="fill:none;stroke:url(#linearGradient46824);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46816"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-4.98635,-46.00527)"
+ id="g46872">
+ <path
+ style="fill:none;stroke:#462300;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ id="path46874"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path46876"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g46878"
+ transform="translate(-0.98635,-58.00527)"
+ style="display:inline;enable-background:new">
+ <path
+ id="path46880"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ style="fill:none;stroke:#462300;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path46882"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-4.023135,-51.99484)"
+ id="g46884">
+ <path
+ style="fill:none;stroke:#462300;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -52.01365,177.50527 0.03679,0 c 0.818181,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.658684,1.49472 -1.476865,1.49472 l -0.03679,0 c -0.81819,0 -1.476874,-0.66664 -1.476874,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.658684,-1.49473 1.476874,-1.49473 l 0,0 0,0 z"
+ id="path46886"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ d="m -50.998123,178.00355 c -0.66732,0 -1.334639,1e-5 -2.001959,1e-5 0,0.66706 0,1.33411 0,2.00119 0.66732,0 1.334639,-1e-5 2.001959,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path46888"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g46958"
+ transform="translate(547.9924,59.00343)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\strands selection modes.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ id="g46960"
+ transform="translate(22,12)">
+ <rect
+ y="107"
+ x="24"
+ height="16"
+ width="16"
+ id="rect46962"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ <g
+ style="opacity:0.55;display:inline;enable-background:new"
+ transform="translate(-22,18)"
+ id="g46964">
+ <g
+ id="g46966"
+ transform="translate(23.01472,-88)">
+ <path
+ id="path46968"
+ style="fill:none;stroke:url(#linearGradient46990);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46992);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46970"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(24.140625,-88)"
+ id="g46972">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ style="fill:none;stroke:url(#linearGradient46994);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46974"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46976"
+ style="fill:none;stroke:url(#linearGradient46996);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(23.01472,-88)"
+ id="g46978">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ style="fill:none;stroke:url(#linearGradient46998);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46980"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46982"
+ style="fill:none;stroke:url(#linearGradient47000);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M -34.51472,179.5 C -38,184.5 -37.5,189 -37.50346,190.5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(24,-58)"
+ id="g46984"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6.5 -4.96875,8"
+ style="fill:none;stroke:#462300;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path46986"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path46988"
+ style="fill:none;stroke:#ffc17d;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -28.53125,182.5 c -4.5,2 -4.96875,6 -4.96875,8"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-1,0)"
+ id="g24914">
+ <g
+ id="g25430"
+ transform="translate(0,-21)">
+ <rect
+ ry="0"
+ rx="0"
+ transform="translate(1,0)"
+ y="514"
+ x="446"
+ height="16"
+ width="16"
+ id="rect25424"
+ style="opacity:0;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ id="g24916"
+ transform="translate(337,128)">
+ <rect
+ rx="0.019097222"
+ y="386"
+ x="110"
+ height="11"
+ width="11"
+ id="rect24918"
+ style="opacity:0;fill:#736c54;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0.019097222" />
+ <g
+ id="g24920">
+ <path
+ sodipodi:nodetypes="cccccccccccsccccccccccccccscccc"
+ style="fill:url(#linearGradient25449);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 116.53125,386.5 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.28156 0.12508,0.53133 0.3125,0.71875 L 113,392 c -0.18742,-0.18742 -0.46844,-0.5 -0.75,-0.5 l -0.75,0 c -0.56312,0 -1.03125,0.46811 -1.03125,1.03125 l 0,0.9375 c 0,0.56312 0.46813,1.03125 1.03125,1.03125 l 0.9375,0 c 0.0103,0 0.021,3e-4 0.0312,0 -3e-4,0.0102 0,0.021 0,0.0312 l 0,0.9375 c 0,0.56312 0.46813,1.03126 1.03125,1.03125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.28156 -0.10164,-0.53133 -0.28125,-0.71875 l 2.625,-2.625 c 0.18742,0.18742 0.43719,0.3125 0.71875,0.3125 l 0.96875,0 c 0.56312,0 1,-0.46813 1,-1.03125 l 0,-0.9375 c 0,-0.56312 -0.43688,-1.03125 -1,-1.03125 l -0.96875,0 c -0.0103,0 -0.021,-3e-4 -0.0312,0 3e-4,-0.0102 0,-0.021 0,-0.0312 l 0,-0.9375 c 0,-0.56312 -0.46813,-1.03125 -1.03125,-1.03125 l -0.9375,0 z"
+ id="path24923"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 111.5,393.5 0,-0.75 0.25,-0.25 1.75,0 3,-3 0,-1.75 0.25,-0.25 0.75,0"
+ id="path24925"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path24927"
+ d="m 118.75,389.5 0.75,0 m -6,6 0,-0.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="393"
+ x="114"
+ height="1"
+ width="1"
+ id="rect24929"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24931"
+ width="1"
+ height="1"
+ x="117"
+ y="390" />
+ </g>
+ </g>
+ <g
+ transform="translate(22.915112,0.02875225)"
+ id="g24933">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 430.5,525.5329 0,2 1,1 2,0 2,-2.0329 0,-2 -1,-1 -2,0 -2,2.0329 z"
+ id="path24939"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path24941"
+ d="m 433.5,522.4671 0,1.75 1,1.25 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:none;stroke:url(#linearGradient25451);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 433.5,522.4671 0,2.0329 1,0.9671 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ id="path24945"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24954"
+ d="m 434.5,523.5 -2,0"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path24956"
+ d="m 430.5,525.5 0,2 1,1 2,0 2,-2 0,-2 -1,-1 -2,0 -2,2 z"
+ style="fill:none;stroke:url(#linearGradient25453);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 434.08489,525.47125 2.25,0"
+ id="path24958"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path24960"
+ d="M 434.33489,525.47125 436.5,525.4671"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="fill:url(#linearGradient40731);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25426"
+ width="0"
+ height="0.25"
+ x="462.25"
+ y="515"
+ transform="translate(1,0)"
+ rx="1.3125"
+ ry="0.25" />
+ </g>
+ <g
+ transform="translate(0.00572791,126.98898)"
+ id="g25026">
+ <rect
+ y="403.99695"
+ x="-382.01102"
+ height="16"
+ width="16"
+ id="rect25028"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,-1,1,0,0,0)" />
+ <g
+ id="g25030">
+ <rect
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ rx="2.1489482"
+ ry="2.143424"
+ y="-559.32709"
+ x="-33.931175"
+ height="5.651536"
+ width="8.4518671"
+ id="rect25032"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5" />
+ <rect
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="rect25034"
+ width="8.5198517"
+ height="5.5904222"
+ x="-28.308893"
+ y="-557.84644"
+ ry="2.1434233"
+ rx="2.1489475" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ id="path25036"
+ d="m 411.49427,375.51102 -0.5,-0.5 c -0.69131,-0.69131 -0.84611,-2.14587 0.0258,-3.01533 l 2.98873,-2.98076 c 0.87178,-0.86946 2.29697,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ style="fill:none;stroke:url(#linearGradient25117);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m -26.159946,-552.25601 c -1.190517,0 -2.148947,-0.95597 -2.148947,-2.14343"
+ id="rect25114"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:url(#radialGradient25457);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 411.49427,375.51102 -0.5,-0.5 c -0.69131,-0.69131 -0.84611,-2.14587 0.0258,-3.01533 l 2.98873,-2.98076 c 0.87178,-0.86946 2.29697,-0.69523 2.98828,-0.004 l 0.52541,0.52542"
+ id="path25455"
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccczz"
+ d="m 407.51079,379.37902 c 0.56229,0.50812 1.81497,0.33519 2.49825,-0.3481 l 2.96969,-3.09463 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.96969,3.09462 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 10e-6,-9e-5 0,0 0,0 z"
+ style="fill:none;stroke:url(#linearGradient25106);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path25038"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path25040"
+ style="opacity:0.7;fill:none;stroke:url(#radialGradient25048);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m 407.4987,379.35912 c 0.56229,0.50812 1.81497,0.33519 2.49825,-0.3481 l 2.98178,-3.07473 c 0.87062,-0.87061 0.69197,-2.30021 0.004,-2.98827 l -1.02382,-1.02382 c -0.69131,-0.69131 -2.11766,-0.86672 -2.98828,0.004 l -2.98178,3.07472 c -0.87062,0.87063 -0.62293,2.42889 -0.004,2.98829 l 1.51384,1.368 10e-6,-9e-5 0,0 0,0 z"
+ sodipodi:nodetypes="ccccccczz"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(-0.7071068,0.7071068,-0.7071068,-0.7071068,0,0)"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ d="m -27.628256,-559.32709 c 1.190517,0 2.148948,0.95597 2.148948,2.14343"
+ id="rect25127"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient25117);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 417.50245,369.52434 0.49841,0.4984 c 0.68807,0.68805 0.86319,2.11415 -0.004,2.98828 l -2.96882,2.99286 c -0.68052,0.68603 -1.74799,0.71589 -2.49825,0.34809 -0.18628,-0.0913 -0.39866,-0.20409 -0.53552,-0.34095 l -1,-1"
+ id="path25042"
+ sodipodi:nodetypes="csssssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23496"
+ transform="matrix(-1,0,0,1,614,0)">
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="299"
+ x="52"
+ height="16"
+ width="16"
+ id="rect23456"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23458"
+ transform="matrix(0,1,1,0,203.99437,-269)">
+ <g
+ id="g23460">
+ <g
+ id="g23462"
+ transform="translate(0,21)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3.25"
+ id="path23464"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 330.25,79.25563 327,76 l -3.25,3.25563"
+ id="path23466"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g23468"
+ transform="translate(0,21)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path23470"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path23473"
+ d="M 330.25,79.25563 327,76.005631 323.75,79.25563"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23475"
+ d="m 333.5,106.50563 0,-2.75"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="matrix(0,1,1,0,269,-203.99437)"
+ y="56"
+ x="303"
+ height="1"
+ width="1.5"
+ id="rect23492"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path23547"
+ d="m 330,100.50563 -1.25,-1.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23494"
+ width="1.5"
+ height="1"
+ x="99.00563"
+ y="328"
+ transform="matrix(0,1,1,0,0,0)" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23559);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 323.25,100.25563 c 0,0.25 0.25,0.5 0.5,0.5 m 2.75,-1.24437 0,7.74437 2.25,2.25 3.5,0 2,-2"
+ id="path23550"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path23552"
+ d="m 323.25,100.00563 3.5,-3.5 0.5,0 3.5,3.5"
+ style="fill:none;stroke:url(#linearGradient23557);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g23511"
+ transform="translate(-21,0)">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23513"
+ width="16"
+ height="16"
+ x="52"
+ y="299"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ transform="matrix(0,1,1,0,203.99437,-269)"
+ id="g23515">
+ <g
+ id="g23518">
+ <g
+ transform="translate(0,21)"
+ id="g23520">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path23523"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3.25"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path23525"
+ d="M 330.25,79.25563 327,76 l -3.25,3.25563"
+ style="fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g23527">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 327,76 0,10.00563 2,2 3,0 2,-2 0,-3"
+ id="path23530"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 330.25,79.25563 327,76.005631 323.75,79.25563"
+ id="path23532"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 326.5,99.5 0,6.50563 m 3,2.5 2,0 2,-2 0,-2.75"
+ id="path23534"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient23543);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 323.25,100.00563 3.5,-3.499999 0.5,0 3.5,3.499999"
+ id="path23536"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23539"
+ width="1.5"
+ height="1"
+ x="303"
+ y="56"
+ transform="matrix(0,1,1,0,269,-203.99437)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="328"
+ x="99.00563"
+ height="1"
+ width="1.5"
+ id="rect23541"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g23604"
+ transform="translate(0,-21)">
+ <g
+ id="g23590"
+ style="fill:#321900">
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23464"
+ width="1"
+ height="2"
+ x="-258"
+ y="-602"
+ transform="scale(-1,-1)" />
+ <rect
+ y="-606"
+ x="-258"
+ height="2"
+ width="1"
+ id="rect23466"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,-1)" />
+ <rect
+ transform="scale(-1,-1)"
+ y="-602"
+ x="-273"
+ height="2"
+ width="1"
+ id="rect23548"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23550"
+ width="1"
+ height="2"
+ x="-273"
+ y="-606" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23472"
+ width="1"
+ height="2"
+ x="598"
+ y="-268" />
+ <rect
+ y="-264"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23474"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <rect
+ y="-271.99207"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23476"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23480"
+ width="1"
+ height="2"
+ x="598"
+ y="-259.99207" />
+ <rect
+ y="-268"
+ x="607"
+ height="2"
+ width="1"
+ id="rect23540"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23542"
+ width="1"
+ height="2"
+ x="607"
+ y="-264" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23544"
+ width="1"
+ height="2"
+ x="607"
+ y="-271.99207" />
+ <rect
+ y="-259.99207"
+ x="607"
+ height="2"
+ width="1"
+ id="rect23546"
+ style="fill:#321900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ <g
+ id="g23572">
+ <rect
+ y="-270"
+ x="-608"
+ height="2"
+ width="1"
+ id="rect23461"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <rect
+ y="-600"
+ x="-273"
+ height="2"
+ width="1"
+ id="rect23468"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,-1)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23470"
+ width="1"
+ height="2"
+ x="-273"
+ y="-604"
+ transform="scale(-1,-1)" />
+ <rect
+ transform="matrix(0,-1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23478"
+ width="1"
+ height="2"
+ x="-608"
+ y="-266" />
+ <rect
+ y="-262"
+ x="-608"
+ height="2"
+ width="1"
+ id="rect23482"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23529"
+ width="1"
+ height="2"
+ x="598"
+ y="-262" />
+ <rect
+ y="-266"
+ x="598"
+ height="2"
+ width="1"
+ id="rect23531"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23533"
+ width="1"
+ height="2"
+ x="598"
+ y="-270" />
+ <rect
+ transform="matrix(0,-1,-1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23535"
+ width="2"
+ height="1"
+ x="-608"
+ y="-273" />
+ <rect
+ transform="scale(-1,-1)"
+ y="-600"
+ x="-258"
+ height="2"
+ width="1"
+ id="rect23525"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,-1)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23527"
+ width="1"
+ height="2"
+ x="-258"
+ y="-604" />
+ <rect
+ y="-608"
+ x="-258"
+ height="2"
+ width="1"
+ id="rect23537"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,-1)" />
+ </g>
+ <rect
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23637"
+ width="14"
+ height="8"
+ x="258"
+ y="599" />
+ <path
+ id="path23639"
+ d="m 259,600 13,0 0,-1 -14,0 0,8 1,0 0,-7 z"
+ style="opacity:0.12999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g23641"
+ transform="translate(40,359)">
+ <g
+ transform="translate(5,-6.0000002e-7)"
+ style="fill:#1a1a1a;display:inline;enable-background:new"
+ id="g23646" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21623-4"
+ transform="translate(-83.999976,274.99821)">
+ <g
+ transform="matrix(0.9999986,0,0,1,-170.19957,169.98079)"
+ id="g10260-6">
+ <g
+ transform="translate(39.10005,-0.04905017)"
+ id="g10262-3">
+ <rect
+ y="6.0700502"
+ x="325.10001"
+ height="15.979"
+ width="16.000025"
+ id="rect10264-4"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="g10266-9" />
+ </g>
+ </g>
+ <g
+ transform="matrix(-1,0,0,1,209,550)"
+ id="g27862"
+ style="display:inline">
+ <rect
+ y="69"
+ x="62"
+ height="16"
+ width="16"
+ id="rect27864"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1,0,0,1,461.01011,-167)"
+ id="g27866"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path27868"
+ d="m 392.5,239.5 -4.98989,4.75 0,0.5 4.98989,4.75 1.01011,-1e-5 0.0368,-9.96874 L 392.5,239.5 z"
+ style="fill:url(#linearGradient27872);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path27870"
+ d="m 392.51011,248.24999 0,-7.49999 -4,3.75"
+ style="fill:none;stroke:url(#linearGradient27874);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,70,704.00001)"
+ id="g27876"
+ style="display:inline">
+ <rect
+ y="69"
+ x="82"
+ height="16"
+ width="16"
+ id="rect27878"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g27880"
+ transform="matrix(0,-1,1,0,-153.98989,467.9919)"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="ccccccc"
+ style="color:#000000;fill:url(#linearGradient27886);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 392.49192,239.48989 -5.00001,4.75 0,0.5 5.00001,4.75 1,0 0,-10 -1,0 z"
+ id="path27882"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient27902);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 392.49191,248.23989 -4.00002,-3.75 4.00002,-3.75"
+ id="path27884"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-231,-21)"
+ id="g29960"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\screw modifier.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29962"
+ width="16"
+ height="16"
+ x="-336"
+ y="283"
+ transform="scale(-1,1)" />
+ <g
+ transform="translate(362,20.75)"
+ id="g29964"
+ mask="none"
+ clip-path="none">
+ <path
+ id="path29966"
+ d="m -35,273.5 0,-10.5 8,3.75 0,10.75 -8,-4 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient29988);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -35,273.5 0,-10.5 8,3.75 0,10.75 -8,-4 z"
+ id="path29968"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path29970"
+ d="m 334.5,287.75 -7,-3.25 0,9"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient29990);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.6827482,0,0,0.68258425,246.77037,137.93793)"
+ id="g29972"
+ style="opacity:0.75;display:inline;enable-background:new"
+ mask="url(#mask29419)"
+ clip-path="url(#clipPath28964)">
+ <path
+ transform="matrix(0.75,0,0,0.75,28.052144,135)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#162d50;stroke-width:1.75781369;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path29974"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,208.02475,314.325)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29976"
+ style="color:#000000;fill:url(#linearGradient29773-5);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.65;fill:none;stroke:#ffffff;stroke-width:2.56764865;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path29978"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ transform="matrix(0.5705005,0,0,0.5705012,51.746079,156.18087)" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g29980"
+ transform="matrix(0.6827482,0,0,0.68258425,236.77037,141.93793)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29982"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.56250119;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient29994);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path29984"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
+ <path
+ transform="matrix(0.5705005,0,0,0.5705012,53.193935,156.18087)"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29986"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:2.56764865;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g29313"
+ transform="translate(-21,2)"
+ style="opacity:0.5">
+ <rect
+ y="176"
+ x="425"
+ height="16"
+ width="16"
+ id="rect29315"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g29317"
+ transform="translate(263,148.99995)">
+ <g
+ transform="matrix(0.786268,0,0,0.7877987,82.392071,-41.848894)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g29320">
+ <path
+ transform="matrix(0.874026,0,0,0.873701,-3.948211,-5.552958)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29323"
+ style="fill:url(#linearGradient29334);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.16319752;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.398744,0,0,-0.395524,58.82401,144.1804)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29336);stroke-width:3.20095801;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path29326"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ transform="matrix(0.186538,0,0,-0.189699,145.3693,57.36304)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29338);stroke-width:5.31599474;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path29328"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29330"
+ style="fill:none;stroke:url(#linearGradient29340);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.566689,0,0,-0.562497,95.23056,101.3747)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29332"
+ style="fill:none;stroke:url(#linearGradient29342);stroke-width:2.35577321;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.424906,0,0,-0.424074,114.01316,85.183325)" />
+ </g>
+ </g>
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ y="-252"
+ x="52"
+ height="16"
+ width="16"
+ id="rect28680"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(97.00005,0)"
+ id="g32009">
+ <g
+ style="display:inline"
+ id="g32011"
+ transform="translate(-95,151)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32013"
+ width="16"
+ height="16"
+ x="3"
+ y="6" />
+ <g
+ transform="translate(64,9.999984)"
+ id="g32015"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path32032"
+ d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
+ style="fill:none;stroke:#002255;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#002255;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -58.250048,9.250016 -50,0.999884"
+ id="path32044"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path32050"
+ d="M -58.250048,9.250016 -50,0.999884"
+ style="fill:none;stroke:#4989e9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient32140);stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -58,8.999884 8,-8"
+ id="path32055"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#4989e9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
+ id="path32057"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path32059"
+ d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
+ style="opacity:0.5;fill:url(#linearGradient32142);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -47.25,-1.75 -54.75,1"
+ id="path32063"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path32068"
+ d="m -53,3 -5.750048,5.750016 0,0.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline"
+ id="g32070"
+ transform="translate(-93.000048,151)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32072"
+ width="16"
+ height="16"
+ x="43"
+ y="6" />
+ <g
+ transform="translate(64,10)"
+ id="g32074"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path32077"
+ d="m -18.25,9.25 8.249996,-8.2304767"
+ style="fill:none;stroke:#002255;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#002255;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -12.999997,-2.000002 5.9999268,1.448e-4 6.72e-5,5.9998542 -6.000002,0 8e-6,-5.999999 0,0 0,0 0,0 z"
+ id="path32079"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#4989e9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -18.25,9.25 8.249996,-8.24999"
+ id="path32081"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path32087"
+ d="m -18.000004,9.00001 8,-8"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient32144);stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path32089"
+ d="m -12.999992,-2 5.9999248,1.448e-4 L -7,4 l -6,0 8e-6,-6 z"
+ style="fill:#4989e9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.5;fill:url(#linearGradient32146);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -12.999992,-2 5.9999248,1.452e-4 L -7,4 l -6,0 8e-6,-6 z"
+ id="path32104"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32114"
+ d="m -12.749999,2.750002 0,-4.4999957 5.4999946,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -12.75,2.75 -6,6 0,0.75"
+ id="path32118"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g32120"
+ transform="translate(-97.000051,0)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32122"
+ width="16"
+ height="16"
+ x="26"
+ y="157" />
+ <g
+ transform="matrix(0.9187785,0,0,0.9204344,64.322274,161.35151)"
+ id="g32124"
+ style="display:inline">
+ <path
+ sodipodi:open="true"
+ inkscape:transform-center-y="-5.4395256"
+ inkscape:transform-center-x="5.4369478"
+ sodipodi:end="1.5729572"
+ sodipodi:start="0"
+ transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ sodipodi:ry="4.5"
+ sodipodi:rx="4.5"
+ sodipodi:cy="-32.5"
+ sodipodi:cx="49.5"
+ id="path32126"
+ style="fill:none;stroke:#002255;stroke-width:1.79768455;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#4989e9;stroke-width:0.9887265;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path32128"
+ sodipodi:cx="49.5"
+ sodipodi:cy="-32.5"
+ sodipodi:rx="4.5"
+ sodipodi:ry="4.5"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
+ sodipodi:start="0"
+ sodipodi:end="1.5729572"
+ inkscape:transform-center-x="5.4369478"
+ inkscape:transform-center-y="-5.4395256"
+ sodipodi:open="true"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:open="true"
+ inkscape:transform-center-y="-5.4395256"
+ inkscape:transform-center-x="5.4369478"
+ sodipodi:end="1.5729572"
+ sodipodi:start="0"
+ transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ sodipodi:ry="4.5"
+ sodipodi:rx="4.5"
+ sodipodi:cy="-32.5"
+ sodipodi:cx="49.5"
+ id="path32136"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient32148);stroke-width:0.9887265;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ sodipodi:type="arc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.29357874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path32138"
+ sodipodi:cx="49.5"
+ sodipodi:cy="-32.5"
+ sodipodi:rx="4.5"
+ sodipodi:ry="4.5"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ transform="matrix(-2.587958,0,0,-2.597682,100.48861,-75.018268)"
+ sodipodi:start="0"
+ sodipodi:end="1.5729572"
+ inkscape:transform-center-x="5.8103423"
+ inkscape:transform-center-y="-5.8447483"
+ sodipodi:open="true"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(315,-441)"
+ id="g31816">
+ <rect
+ style="opacity:0;color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.5999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31818"
+ width="16"
+ height="16"
+ x="-247"
+ y="514" />
+ <g
+ transform="translate(0,-21)"
+ id="g31820">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -245.25,538 12.5,0"
+ id="path31822"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31824"
+ d="m -245.25,538 12.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -245.5,538.5 -0.25,-0.5 0.25,-0.5 13,0"
+ id="path31826"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31828"
+ d="m -242.5,543.5 0,-1 7,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 0,-1 1,0"
+ id="path31830"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31832"
+ d="m -242.25,543 6.5,0"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#d2d2d2;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -242.25,543 6.5,0"
+ id="path31834"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31836"
+ d="m -242.5,543.5 -0.25,-0.5 0.25,-0.5 7,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -239.25,548 0.5,0"
+ id="path31838"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840"
+ d="m -239.25,548 0.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g31846"
+ transform="translate(191,-420)"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\sort a-z.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31848"
+ width="16"
+ height="16"
+ x="-186"
+ y="493" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -177.25,499 5.25,0 0,0.5 -5.03256,7.02015 0,0.5 L -171.75,507"
+ id="path31857"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path31859"
+ d="m -177.25,499 5.25,0 0,0.5 -5.03256,7.02015 0,0.5 L -171.75,507"
+ style="color:#000000;fill:none;stroke:url(#linearGradient31946);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -175.25,506.5 3.75,0 m -6.5,-8 6.25,0 m -1.75,2 -4,5.75 0,1"
+ id="path31861"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter50168-9);enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ d="m -183.4375,493.25 a 1.7525094,1.7525094 0 0 0 0.1875,3.5 l 1.875,0 0.125,0 c 0.30188,0 0.5,0.19814 0.5,0.5 l -2.25,0 a 1.750175,1.750175 0 0 0 -1.25,0.5 l -1,1 a 1.750175,1.750175 0 0 0 -0.5,1.25 l 0,2 a 1.750175,1.750175 0 0 0 0.5,1.25 l 1,1 a 1.750175,1.750175 0 0 0 1.25,0.5 l 2.5,0 a 1.750175,1.750175 0 0 0 1.25,-0.5 l 0.25,0.25 a 1.767767,1.767767 0 1 0 2.5,-2.5 l -0.75,-0.75 0,-1.9375 a 1.750175,1.750175 0 0 0 0,-0.5 1.750175,1.750175 0 0 0 0,-0.1875 l 0,-1.09375 a 1.750175,1.750175 0 0 0 0,-0.28125 1.750175,1.750175 0 0 0 -0.125,-0.6875 c -0.004,-0.0221 -0.0268,-0.0405 -0.0312,-0.0625 a 1.750175,1.750175 0 0 0 -0.0312,-0.0937 c -0.35614,-1.57819 -1.57955,-2.76466 -3.1875,-3.03125 a 1.750175,1.750175 0 0 0 -0.625,-0.125 l -0.1875,0 -1.8125,0 a 1.750175,1.750175 0 0 0 -0.1875,0 z m 1.1875,7.5 1.5,0 0,0.5 -1.5,0 0,-0.5 z"
+ id="path31869"
+ clip-path="url(#clipPath50172-0)"
+ mask="none"
+ transform="translate(-0.05279266,-2.0457936e-6)"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31871"
+ transform="translate(-0.25906372,0.25457764)"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -180.99094,494.73636 c 1.24765,0 2.25907,1.01142 2.25907,2.25906 m -0.009,0 0,4.75 1.25,1.25 m -2.75,-0.25 -2.5,0 -1,-1 0,-2 1,-1 4,0 m -4.25,-4 2,0"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -180.99094,494.73636 c 1.24765,0 2.25907,1.01142 2.25907,2.25906 m -0.009,0 0,4.75 1.25,1.25 m -2.75,-0.25 -2.5,0 -1,-1 0,-2 1,-1 4,0 m -4.25,-4 2,0"
+ style="color:#000000;fill:none;stroke:url(#linearGradient31948);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(-0.25906372,0.25457764)"
+ id="path31873"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path31875"
+ d="m -179.5,495.25 -1.25,-0.75 -2.75,0 -0.25,0.5 0.24997,0.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31879"
+ d="m -184.5,502 0,-2.25 1.25,-1.25 3.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31881"
+ d="m -182.25,502.5 2,0 0.75,-0.75 0,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g31883"
+ transform="translate(189,-315)">
+ <g
+ style="opacity:0.96000001;display:inline;enable-background:new"
+ id="g31885"
+ transform="translate(-307.59866,-9.53021)">
+ <g
+ id="g31887"
+ transform="translate(2.6147747,150.03012)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline">
+ <g
+ id="g31889">
+ <rect
+ transform="translate(-2.6147747,-150.03012)"
+ y="397.53015"
+ x="165.59866"
+ height="16"
+ width="16"
+ id="rect31891"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="247.5"
+ x="162.99997"
+ height="16"
+ width="15.000031"
+ id="rect31893"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="m 167.48389,249.00007 0,2 m 6,-2 0,2"
+ style="fill:none;stroke:#162d50;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path31896"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:url(#linearGradient31950);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect31898"
+ width="11.999973"
+ height="13.000053"
+ x="164.48389"
+ y="250.00002"
+ rx="1.0000547"
+ ry="1.0000547" />
+ <path
+ sodipodi:nodetypes="cc"
+ d="m 165.48389,262.00007 0,-11"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path31900"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31902"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient31952);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 175.48389,251.00007 0,11 -10,0 0,-11 10,0 z"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(346.98389,-98.49991)"
+ style="color:#000000;fill:url(#linearGradient31954);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -181.5,348.96875 c -0.0977,0 -0.2593,0.0405 -0.375,0.15625 -0.1157,0.1157 -0.15625,0.27731 -0.15625,0.375 l 0,7 2.53125,2.53125 10.53125,0 0,-1.15625 c -1.11643,-0.22954 -2,-1.19538 -2,-2.375 l 0,-6 c 0,-0.0977 -0.0405,-0.2593 -0.15625,-0.375 -0.1157,-0.1157 -0.27731,-0.15625 -0.375,-0.15625 l -10,0 z"
+ id="path31905"
+ sodipodi:nodetypes="cscccccccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(346.98389,-98.49991)"
+ style="color:#000000;fill:none;stroke:url(#linearGradient31956);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -181.5,349.5 0,6.75 2.25,2.25 9.7813,0.0312 -0.0313,-0.2812 c -1.11143,-0.43566 -2,-1.49177 -2,-2.75 l 0.0313,-6.00005 -10.0313,5e-5 z"
+ id="path31907"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="color:#000000;fill:url(#linearGradient31958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31909"
+ width="11.000002"
+ height="4.0000105"
+ x="164.98389"
+ y="250.50008"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 165.48389,254.50007 0,-3.5 10,0 0,3.5"
+ style="opacity:0.45;fill:none;stroke:url(#linearGradient31960);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path31912"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31914"
+ style="opacity:0.8;fill:none;stroke:#162d50;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 167.48389,249.00007 0,2 m 6,-2 0,2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -181.5,348.5 c -0.13851,0 -0.25527,0.0433 -0.375,0.0937 -0.23945,0.10094 -0.43031,0.2918 -0.53125,0.53125 -0.0505,0.11973 -0.0937,0.23649 -0.0937,0.375 l 0,7 0,4 c 0,0.55403 0.44597,1 1,1 l 10,0 c 0.55403,0 1,-0.44597 1,-1 l 0,-1 2,0 0,-2 c -1.09489,0 -2,-0.90511 -2,-2 l 0,-6 c 0,-0.125 -0.0391,-0.25781 -0.0937,-0.375 -0.10094,-0.23945 -0.2918,-0.43031 -0.53125,-0.53125 -0.11973,-0.0505 -0.23649,-0.0937 -0.375,-0.0937 l -10,0 z"
+ transform="translate(346.98389,-98.49991)"
+ id="path31917"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31919"
+ style="fill:none;stroke:url(#linearGradient31962);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 167.48389,249.00007 0,2 m 6,-2 0,2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -200.5,372.5 0.75,0 1.25,-1.25 0,-0.75"
+ id="path31921"
+ transform="translate(367.98389,-119.49993)"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31923"
+ d="m 173.48389,253.00007 0.75,0 1.25,-1.25 0,-0.75"
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path31925"
+ d="m 167.48389,252.00007 0.5,0 0.5,-0.5 0,-0.5"
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.7;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.48389,252.00007 0.5,0 0.5,-0.5 0,-0.5"
+ id="path31927"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 165.48389,254.00007 10,0"
+ id="path31929"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path31931"
+ d="m -170.5,359.5 c -3.30603,0.005 -5.7501,0 -9,0 l -1.75,-1.75"
+ style="opacity:0.5;color:#000000;fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(346.98389,-98.49991)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 170.48389,259.00009 c -0.25,0 -0.64081,-0.31307 -0.82432,-0.78241 -0.17644,-0.45125 -0.17568,-0.96756 -0.17568,-2.21759"
+ id="path31933"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31935"
+ d="m 173.48389,259.00009 c -0.25,0 -0.64081,-0.31307 -0.82432,-0.78241 -0.17644,-0.45125 -0.17568,-0.96756 -0.17568,-2.21759"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <rect
+ ry="0"
+ rx="0"
+ y="396"
+ x="-136"
+ height="1"
+ width="1"
+ id="rect31937"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31939"
+ width="1"
+ height="1"
+ x="-133"
+ y="396"
+ rx="0"
+ ry="0" />
+ <rect
+ y="398.25"
+ x="-136"
+ height="0.7500025"
+ width="0.50001091"
+ id="rect31941"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31943"
+ width="0.50001091"
+ height="0.7500025"
+ x="-133.00002"
+ y="398.25" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\screw modifier.png"
+ transform="translate(-105,-42)"
+ id="g31976">
+ <rect
+ y="283"
+ x="236"
+ height="16"
+ width="16"
+ id="rect31978"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path31980"
+ d="m 244,283.5 c -3.49999,0 -5.5,1 -5.49999,2.5 l -1e-5,1.75 3,3 0,6.5 1.25,1.25 2.5,0 1.25,-1.25 0,-6.5 3,-3 0,-1.75 c 0,-1.5 -1.99999,-2.5 -5.5,-2.5 z"
+ style="color:#000000;fill:url(#linearGradient32236);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:url(#linearGradient32238);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 244,287.5 c -3.49999,0 -5.5,-1 -5.49999,-2.5 l -1e-5,2.75 3,3 5,0 3,-3 0,-2.75 c 0,1.5 -1.99999,2.5 -5.5,2.5 z"
+ id="path31982"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czs"
+ id="path31985"
+ d="m 248.99999,286.24149 c 0,1.12925 -1.66739,2.25851 -5.01168,2.25851 -3.34426,0 -4.99267,-1.12926 -4.99267,-2.25851"
+ style="fill:none;stroke:url(#linearGradient32240);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 246.5,290.75 3,-3 0,-1.75 c 0,-1.5 -1.99999,-2.5 -5.5,-2.5 -3.49999,0 -5.5,1 -5.49999,2.5 l -1e-5,1.75 3,3"
+ id="path31989"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#89a9d9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.29137695;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 249,285.86765 c 0,0.99654 -1.81092,1.88235 -5,1.88235 -3.18906,0 -5,-0.88581 -5,-1.88235 0,-1.36765 2.61499,-2.11765 5,-2.11765 2.38501,0 5,0.75 5,2.11765 z"
+ id="path31991"
+ sodipodi:nodetypes="czszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31993"
+ d="m 239.5,287.5 3,3"
+ style="opacity:0.7;color:#000000;fill:none;stroke:url(#linearGradient32242);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path31996"
+ d="m 241.5,290.75 0,6.5 1.25,1.25 2.5,0 1.25,-1.25 0,-6.5"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:url(#linearGradient32244);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 242.5,291 0,5.75 0.75,0.75 1.5,0 0.75,-0.75 0,-6.25 3,-3"
+ id="path31998"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:url(#linearGradient32246);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 242.5,291 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -3,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -3,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -3,0 z m 0.75,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 1.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 z"
+ id="path32000"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:url(#linearGradient32248);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 242.5,292 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.75,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -2.75,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.75,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -2.75,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.75,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -2.75,0 z"
+ id="path32002"
+ sodipodi:nodetypes="csccscccsccscccsccscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 242.47368,287.53915 246,284"
+ id="path32004"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path32006"
+ d="m 243.5,287.5 3,-3"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\sequencer + image preview.png"
+ id="g32260"
+ transform="translate(147,0)">
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(-240,-247)"
+ id="g32262"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ mask="url(#mask29801)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32264"
+ width="16"
+ height="16"
+ x="203"
+ y="257" />
+ <g
+ style="display:inline;enable-background:new"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g32266"
+ transform="translate(-39.983882,19.00809)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 244.51612,238.49191 -0.0161,3 7.98388,0 0.0161,-3 -7.98388,0 z"
+ id="path32269"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path32276"
+ d="m 247.51612,241.49191 -0.0161,3 11,0 0.0161,-3 -11,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path32278"
+ d="m 249.48388,247.49191 -0.0161,3 7.01612,0 0.0161,-3 -7.01612,0 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:url(#linearGradient32296);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 205.51612,259.5 c 0,-0.25 0,-1 0,-1 l 6,0"
+ id="path32280"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32282"
+ d="m 208.51612,262.5 c 0,-0.25 0,-1 0,-1 l 9,0"
+ style="fill:none;stroke:url(#linearGradient32299);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32284"
+ d="m 210.5,268.5 c 0,-0.25 0,-1 0,-1 l 5,0"
+ style="fill:none;stroke:url(#linearGradient32301);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g32286"
+ transform="translate(-85,-411)">
+ <rect
+ y="427.5"
+ x="48.5"
+ height="9"
+ width="9"
+ id="rect32288"
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <rect
+ ry="0"
+ style="fill:url(#linearGradient32303);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32290"
+ width="5.9999886"
+ height="6"
+ x="50.000011"
+ y="429" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path32292"
+ d="m 50,429 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,2 -2,0 0,2 2,0 0,-2 z m -4,2 0,-2 -2,0 0,2 2,0 z"
+ style="fill:url(#linearGradient32305);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path32294"
+ d="m 56.50001,428.49999 -7.000011,10e-6 1.1e-5,6.99999 7,0 -1.1e-5,-6.99999"
+ style="fill:none;stroke:url(#linearGradient32307);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\mysterious PR.png"
+ transform="translate(-118,-465)"
+ id="g32309">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32311"
+ width="16"
+ height="16"
+ x="312"
+ y="685" />
+ <g
+ id="g32313">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g32315"
+ transform="matrix(0.927848,0,0,0.916217,160.82022,488.72362)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path32317"
+ style="fill:url(#linearGradient32353);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.22752953;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path32319"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient32355);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.68828432,0,0,0.69278557,229.1626,611.24321)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32321"
+ style="opacity:0.96000001;fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 322.5,689.5 -3,3 m 0,1 2,2"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 319.5,693.5 2,2"
+ style="opacity:0.96000001;fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32323"
+ inkscape:transform-center-y="1.25"
+ inkscape:transform-center-x="-1.25"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="697"
+ x="320"
+ height="1.5"
+ width="1"
+ id="rect32325"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="692"
+ x="324"
+ height="1"
+ width="1.5"
+ id="rect32327"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.96000001;fill:url(#linearGradient32357);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 319.85514,686.97535 c -3.25557,0.003 -5.8936,2.6597 -5.87155,5.95078 0.0105,1.56055 0.63214,2.99542 1.61111,4.05762 2.7831,-7.37691 5.95805,-1.77373 7.49116,-9.06794 -0.92886,-0.60835 -2.04538,-0.9415 -3.23072,-0.94046 l 0,0 0,0 0,0 z"
+ id="path32329"
+ inkscape:transform-center-x="1.4653436"
+ inkscape:transform-center-y="-1.0204512"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-2.5000099"
+ inkscape:transform-center-x="-3.00001"
+ id="path32331"
+ d="m 319.93245,687.49998 c -0.13655,0 -0.28922,0.0368 -0.43244,0.0521 l 0,4.94792 6,0 c -0.22415,-2.79556 -2.6077,-5 -5.56756,-5 z"
+ style="color:#000000;fill:#ff9e05;fill-opacity:1;fill-rule:evenodd;stroke:#d68c1a;stroke-width:1;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32333"
+ width="1.4999696"
+ height="1"
+ x="314.51614"
+ y="693" />
+ <rect
+ style="opacity:0.15;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32335"
+ width="1"
+ height="1.4999921"
+ x="319"
+ y="687.5" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 324.5,692.5 -5,0"
+ style="opacity:0.8;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32349"
+ inkscape:transform-center-y="-0.75"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.68828432,0,0,0.69278557,229.1626,611.24321)"
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient32359);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path32351"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\recently used.png"
+ transform="translate(32,-86.95)"
+ id="g32361">
+ <rect
+ y="664"
+ x="414"
+ height="16"
+ width="16"
+ id="rect32363"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g32365">
+ <g
+ style="opacity:0.8"
+ id="g32367"
+ transform="translate(23,1)">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g32369"
+ transform="matrix(0.927848,0,0,0.916217,240.82022,467.72362)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path32371"
+ style="fill:url(#linearGradient32426);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.19779229;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.80941061,0,0,0.82049866,65.263425,126.69853)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,265.50801,498.28815)"
+ id="g32373"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient32430);stroke-width:1.17973554;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.79894049,0,0,0.80499668,66.729242,128.65178)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient32428);stroke-width:1.59548569;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path32375"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32377"
+ style="opacity:0.96000001;fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 400.5,668.5 0,4 m 0,0 2,2"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 400.5,672.5 2,2"
+ style="opacity:0.96000001;fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32380"
+ inkscape:transform-center-y="1.25"
+ inkscape:transform-center-x="-1.25"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="676"
+ x="400"
+ height="2.5"
+ width="1"
+ id="rect32382"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="672"
+ x="404"
+ height="1"
+ width="2.5"
+ id="rect32384"
+ style="opacity:0.15;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:transform-center-y="-0.75"
+ id="path32387"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 400.5,668.5 0,4"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.96000001;fill:url(#linearGradient32432);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 400.30467,667.25 c -2.80257,0.003 -5.07354,2.32096 -5.05455,5.19291 0.009,1.36179 0.54419,2.61392 1.38693,3.54084 2.39585,-6.4374 5.12903,-1.54783 6.44881,-7.91306 -0.79962,-0.53087 -1.76077,-0.82159 -2.78119,-0.82069 l 0,0 0,0 0,0 z"
+ id="path32389"
+ inkscape:transform-center-x="1.2614492"
+ inkscape:transform-center-y="-0.89049022"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32391"
+ width="2.4838562"
+ height="1"
+ x="394.51614"
+ y="672" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32393"
+ width="1"
+ height="1.4999921"
+ x="400"
+ y="666.5" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 400.5,668.5 0,4"
+ style="opacity:0.57600002;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32396"
+ inkscape:transform-center-y="-0.75"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g32398">
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32400">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32403"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#0b1e00;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="color:#000000;fill:none;stroke:#0b1e00;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ id="path32411"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32413">
+ <path
+ style="fill:none;stroke:#8af01e;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path32416"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path32418"
+ d="m 417,669 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path32420"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ style="color:#000000;fill:none;stroke:#8af01e;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.5,670 0,-4.5 m 5,4 -2,0"
+ id="path32422"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ id="path32424"
+ d="m 428.5,671.21875 c -0.0591,-1.37274 -0.59591,-2.66246 -1.5,-3.6875 -1.09228,-1.23842 -2.62571,-1.96363 -4.1875,-2.09375 -1.55879,-0.12987 -3.16135,0.33951 -4.40625,1.4375 -3.3e-4,0.0104 -3.3e-4,0.0208 0,0.0312 L 417.5,667.75"
+ style="opacity:0.4;color:#000000;fill:none;stroke:url(#linearGradient32434);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(0,2)"
+ id="g31005">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31007"
+ width="16"
+ height="16"
+ x="425"
+ y="218" />
+ <g
+ style="display:inline"
+ id="g31009"
+ transform="translate(43.016148,98.00001)">
+ <g
+ transform="translate(-3.542969e-5,0)"
+ id="g31011"
+ style="display:inline">
+ <path
+ d="M 388.23389,129.74999 394.5,123.5 m 0.98389,1.99999 L 394,124 m 0.48389,2.49999 -1.4142,-1.41422"
+ style="fill:none;stroke:#000000;stroke-width:3.00000095;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31013"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path31021"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.04706,129.93681 c 0.81353,0.81353 0.81353,2.31284 0,3.12634 -0.81352,0.81354 -2.31283,0.81354 -3.12635,0 -0.81353,-0.8135 -0.81353,-2.31281 0,-3.12634 0.81352,-0.81352 2.31283,-0.81352 3.12635,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31015"
+ style="fill:none;stroke:url(#linearGradient31019);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="M 388.73389,129.24999 394.5,123.5 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czzzz"
+ d="m 388.01764,129.96629 c 0.79818,0.79819 0.79818,2.26923 0,3.06743 -0.7982,0.79819 -2.26925,0.79819 -3.06743,0 -0.79821,-0.7982 -0.79821,-2.26924 0,-3.06743 0.79818,-0.7982 2.26923,-0.7982 3.06743,0 z"
+ style="fill:none;stroke:url(#linearGradient31025);stroke-width:1.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31023"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
+ sodipodi:ry="0.71093756"
+ sodipodi:rx="0.70312506"
+ sodipodi:cy="122.5078"
+ sodipodi:cx="387.50003"
+ id="path31017"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g31159">
+ <g
+ style="opacity:0.8"
+ transform="translate(-21,2)"
+ id="g31037">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31039"
+ width="16"
+ height="16"
+ x="425"
+ y="218" />
+ <g
+ style="display:inline"
+ id="g31041"
+ transform="translate(43.016148,98.00001)">
+ <g
+ transform="translate(-3.542969e-5,0)"
+ id="g31043"
+ style="display:inline">
+ <path
+ d="M 388.23389,129.74999 394.5,123.5 m 0.98389,1.99999 L 394,124 m 0.48389,2.49999 -1.4142,-1.41422"
+ style="fill:none;stroke:#000000;stroke-width:3.00000095;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31045"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path31047"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.04706,129.93681 c 0.81353,0.81353 0.81353,2.31284 0,3.12634 -0.81352,0.81354 -2.31283,0.81354 -3.12635,0 -0.81353,-0.8135 -0.81353,-2.31281 0,-3.12634 0.81352,-0.81352 2.31283,-0.81352 3.12635,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31049"
+ style="fill:none;stroke:url(#linearGradient31055);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="M 388.73389,129.24999 394.5,123.5 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="czzzz"
+ d="m 388.01764,129.96629 c 0.79818,0.79819 0.79818,2.26923 0,3.06743 -0.7982,0.79819 -2.26925,0.79819 -3.06743,0 -0.79821,-0.7982 -0.79821,-2.26924 0,-3.06743 0.79818,-0.7982 2.26923,-0.7982 3.06743,0 z"
+ style="fill:none;stroke:url(#linearGradient31057);stroke-width:1.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31051"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
+ sodipodi:ry="0.71093756"
+ sodipodi:rx="0.70312506"
+ sodipodi:cy="122.5078"
+ sodipodi:cx="387.50003"
+ id="path31053"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g31031"
+ transform="matrix(0,1,-1,0,636.39781,-199.65488)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31033"
+ d="m 422.15488,229.89781 11,-11"
+ style="opacity:0.5;fill:#000000;fill-rule:evenodd;stroke:#2b0000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ff5555;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 422.15488,229.89781 11,-11"
+ id="path31035"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g31133"
+ transform="translate(0,-21)">
+ <rect
+ y="241"
+ x="383"
+ height="16"
+ width="16"
+ id="rect31089"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(3.016145,122.00001)"
+ id="g31091"
+ style="display:inline">
+ <g
+ style="display:inline"
+ id="g31093"
+ transform="translate(-3.542969e-5,0)">
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path31095"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.23389,129.74999 5.25,-5.25 m 0.98389,1.99999 -1.48389,-1.49999 m 0.48389,2.49999 -1.4142,-1.41422"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 388.04706,129.93681 c 0.81353,0.81353 0.81353,2.31284 0,3.12634 -0.81352,0.81354 -2.31283,0.81354 -3.12635,0 -0.81353,-0.8135 -0.81353,-2.31281 0,-3.12634 0.81352,-0.81352 2.31283,-0.81352 3.12635,0 z"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31097"
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 388.73389,129.24999 4.75,-4.75 m 0.98389,1.99999 -0.25,-0.25 m -0.75,1.25 -0.25,-0.25"
+ style="fill:none;stroke:url(#linearGradient31151);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path31099"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31101"
+ style="fill:none;stroke:url(#linearGradient31153);stroke-width:1.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.01764,129.96629 c 0.79818,0.79819 0.79818,2.26923 0,3.06743 -0.7982,0.79819 -2.26925,0.79819 -3.06743,0 -0.79821,-0.7982 -0.79821,-2.26924 0,-3.06743 0.79818,-0.7982 2.26923,-0.7982 3.06743,0 z"
+ sodipodi:nodetypes="czzzz"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path31103"
+ sodipodi:cx="387.50003"
+ sodipodi:cy="122.5078"
+ sodipodi:rx="0.70312506"
+ sodipodi:ry="0.71093756"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
+ transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)" />
+ </g>
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.3;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ d="m 389.5,229.65625 c -0.73878,0 -1.48012,0.26136 -2.03125,0.8125 -1.10229,1.10226 -1.10228,2.96023 0,4.0625 0.41335,0.41335 0.92256,0.67791 1.46875,0.78125 0.008,-0.004 0.0231,0.004 0.0312,0 0.76739,-0.40457 1.35785,-1.08414 1.65625,-1.90625 -0.0307,0.0416 -0.0579,0.0891 -0.0937,0.125 -0.49413,0.49412 -1.5684,0.49411 -2.0625,0 -0.49414,-0.49413 -0.49413,-1.56838 0,-2.0625 0.24705,-0.24706 0.63541,-0.375 1.03125,-0.375 0.39584,0 0.78419,0.12794 1.03125,0.375 0.12353,0.12353 0.21949,0.29083 0.28125,0.46875 -0.0858,-0.9079 -0.52654,-1.71591 -1.1875,-2.28125 -0.0405,-0.002 -0.0845,0 -0.125,0 z m -2.125,1.9375 c 0.37998,0 0.65625,0.27629 0.65625,0.65625 0,0.37998 -0.27627,0.6875 -0.65625,0.6875 -0.37092,0 -0.64331,-0.29002 -0.65625,-0.65625 0,-0.009 -3.2e-4,-0.0223 0,-0.0312 0.0129,-0.3662 0.28534,-0.65625 0.65625,-0.65625 z"
+ transform="translate(0,21)"
+ id="path31190"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g31059"
+ transform="translate(-42,23)">
+ <g
+ style="display:inline"
+ id="g31073"
+ transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,60.12783,410.54412)">
+ <g
+ id="g31075"
+ transform="translate(2.016112,1.00001)">
+ <path
+ d="m 388.60119,129.3396 4.94975,-4.94974 m 1.41421,1.41421 -1.23743,-1.23743 m 0.53033,1.94454 -1.23742,-1.23744"
+ style="fill:none;stroke:#100d04;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31077"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csssc"
+ id="path31113"
+ style="fill:none;stroke:#100d04;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 387.93695,130.00385 c 0.8043,0.80431 0.8043,2.10984 0,2.91414 -0.8043,0.80431 -2.10984,0.80431 -2.91414,0 -0.8043,-0.8043 -0.8043,-2.10983 0,-2.91414 0.8043,-0.80428 2.10984,-0.80428 2.91414,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path31079"
+ style="fill:none;stroke:url(#linearGradient31155);stroke-width:1.50000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ d="m 388.60119,129.3396 4.94975,-4.94974 m 1.41421,1.41421 -0.25,-0.25 m -0.4571,0.95711 -0.25,-0.25"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.05;fill:#181406;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path31081"
+ sodipodi:cx="387.50003"
+ sodipodi:cy="122.5078"
+ sodipodi:rx="0.70312506"
+ sodipodi:ry="0.71093756"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
+ transform="matrix(1.7719122,0,0,1.7719122,-300.13217,-85.612134)" />
+ <path
+ sodipodi:nodetypes="czzzz"
+ d="m 387.96588,129.97488 c 0.82029,0.8203 0.82029,2.15177 0,2.97206 -0.8203,0.82029 -2.15179,0.82029 -2.97206,0 -0.8203,-0.82029 -0.8203,-2.15176 0,-2.97206 0.82027,-0.82029 2.15176,-0.82029 2.97206,0 z"
+ style="fill:none;stroke:url(#linearGradient31157);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ id="path31109"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34332"
+ sodipodi:nodetypes="cc" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g40603-2-4"
+ transform="translate(448,657)">
+ <rect
+ y="-122"
+ x="-44"
+ height="16"
+ width="16"
+ id="rect40445-4-2"
+ style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path40447-5-3"
+ d="m -43.5,-116.75 12.5,-4.75 0.75,2 -13.25,5 0,-2.25 z"
+ style="fill:#1a1a1a;stroke:#000000;stroke-width:0.89999998;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-114.5"
+ x="-42.5"
+ height="7.9999971"
+ width="12.999988"
+ id="rect40449-5-9"
+ style="fill:url(#linearGradient16887);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40451-1-1"
+ width="1"
+ height="1.5"
+ x="-32"
+ y="-121" />
+ <rect
+ y="-119.41868"
+ x="-36"
+ height="1.5"
+ width="1"
+ id="rect40453-7-7"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40455-1-9"
+ width="1"
+ height="1.5"
+ x="-37"
+ y="-119.16868" />
+ <rect
+ y="-117.62802"
+ x="-41"
+ height="1.5"
+ width="1"
+ id="rect40457-1-4"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40459-5-8"
+ width="1"
+ height="1.5"
+ x="-40"
+ y="-117.87802" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40461-2-3"
+ width="13.999996"
+ height="2.0000052"
+ x="-43.5"
+ y="-114.5" />
+ <rect
+ y="-113"
+ x="-42"
+ height="1.7500292"
+ width="12.154154"
+ id="rect40490-7-9"
+ style="opacity:0.8;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="rect40463-6-4"
+ d="m -40,-114 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z m 4,0 0,1.25 2,0 0,-1.25 -2,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round"
+ d="m -31.5,-120.5 -9.75,3.75"
+ id="path40474-1-2"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient16889);stroke-width:1px;stroke-linejoin:round"
+ d="m -41.5,-107.5 0,-6 11,0 0,6 -11,0 z"
+ id="path40476-4-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#87aade;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -43,-116.75 1,0 1,1.75 0,2 -2,0 0,-3.75 z"
+ id="path40478-2-5"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#002255;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -41,-115 0,2 -2,0 0,0.75 2.75,0 0,-3 -1.25,-2.25 -1.5,0.25 0,0.5 1,0 1,1.75 z"
+ id="path40480-3-8"
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path40558-2-3"
+ d="m -41.5,-107.38206 0,-4.66445"
+ style="opacity:0.2;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40553-2-9"
+ width="1"
+ height="1.5"
+ x="-33"
+ y="-120.75" />
+ <rect
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40556-1-3"
+ width="1"
+ height="1.25"
+ x="-40"
+ y="-114" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round"
+ d="m -42.4975,-113.46527 0,-3.0928"
+ id="path40560-6-1"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(1,0)"
+ style="opacity:0.35"
+ id="g40590-8-8">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40586-5-0"
+ width="5"
+ height="0.9617852"
+ x="-38"
+ y="-110" />
+ <rect
+ y="-111"
+ x="-36"
+ height="3"
+ width="1.0280838"
+ id="rect40588-7-3"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55400002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55801">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26258-7"
+ width="16"
+ height="16"
+ x="47"
+ y="52" />
+ <g
+ transform="translate(74.95064,-440.02091)"
+ id="g26260-3">
+ <g
+ id="g26262-9">
+ <path
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26264-6"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26266-7"
+ style="fill:none;stroke:#28170b;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path26268-5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -9.5,6 6,-6"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26270-5"
+ style="fill:none;stroke:url(#linearGradient26282-0);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -27.5,502.5 l 6,-6 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient26284-9);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26272-4"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path26274-0"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
+ <path
+ transform="matrix(2,0,0,2,-46,385)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26276-1"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient26286-4);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26278-1"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -7.704183,9.08552 4.25,-4.25 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient26288-9);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path26280-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g24933-4"
+ transform="translate(-375.85,-461.8829)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path24939-9"
+ d="m 430.5,525.5329 0,2 1,1 2,0 2,-2.0329 0,-2 -1,-1 -2,0 -2,2.0329 z"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 433.5,522.4671 0,1.75 1,1.25 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ id="path24941-0"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24945-6"
+ d="m 433.5,522.4671 0,2.0329 1,0.9671 2,0 2,-1.9671 0,-2 -1,-1 -2,0 -2,1.9671 z"
+ style="fill:none;stroke:url(#linearGradient55785);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 434.5,523.5 -2,0"
+ id="path24954-1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient55787);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 430.5,525.5 0,2 1,1 2,0 2,-2 0,-2 -1,-1 -2,0 -2,2 z"
+ id="path24956-1"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path24958-1"
+ d="m 434.08489,525.47125 2.25,0"
+ style="fill:none;stroke:#000000;stroke-width:2.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 434.33489,525.47125 436.5,525.4671"
+ id="path24960-1" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55835">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect26258-7-4"
+ width="16"
+ height="16"
+ x="68"
+ y="52" />
+ <g
+ transform="translate(95.95064,-440.02091)"
+ id="g26260-3-6">
+ <g
+ id="g26262-9-1">
+ <path
+ sodipodi:nodetypes="cc"
+ d="M -15.594023,497.94339 -20.25,493.5"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26264-6-7"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
+ sodipodi:ry="1.0000004"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26266-7-7"
+ style="fill:none;stroke:#28170b;stroke-width:1.32768786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ id="path26268-5-3"
+ style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -25.5,496.5 7.5,0 m -9.5,6 6,-6"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26270-5-9"
+ style="fill:none;stroke:url(#linearGradient26282-0-8);stroke-width:0.92424375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -25.5,496.5 7.984366,-0.0226 M -27.5,502.5 l 6,-6 m 5.996227,1.44466 L -20.25,493.5"
+ style="fill:none;stroke:url(#linearGradient26284-9-6);stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26272-4-9"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path26274-0-6"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
+ <path
+ transform="matrix(2,0,0,2,-46,385)"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="57.5"
+ sodipodi:cx="13.5"
+ id="path26276-1-7"
+ style="fill:#2c5aa0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient26286-4-5);stroke-width:0.22536004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.10397505;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path26278-1-5"
+ sodipodi:cx="13.5"
+ sodipodi:cy="57.5"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m -20.515634,493.80534 c -0.07079,-0.45769 0.0843,-0.63855 0.5,-0.5 m -7.704183,9.08552 4.25,-4.25 m -2,-2 6.25,0"
+ style="fill:none;stroke:url(#linearGradient26288-9-5);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path26280-5-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(-1,0,0,-1,110.9,273.1)"
+ id="g39333-1"
+ style="display:inline;enable-background:new">
+ <g
+ transform="translate(26.00079,19.1)"
+ id="g39096-7-1"
+ style="display:inline;enable-background:new">
+ <g
+ id="g39118-3-3"
+ style="fill:#ffffff;display:inline;enable-background:new"
+ transform="translate(-1.00079,-19)" />
+ </g>
+ <g
+ id="g38966-7"
+ transform="matrix(0,-1,-1,0,212.75,247.25)">
+ <g
+ transform="matrix(-1,0,0,-1,215.25,222.75)"
+ id="g38968-4">
+ <path
+ inkscape:connector-curvature="0"
+ id="path38970-5"
+ d="m 174.5,38.5 0,5 5,0"
+ style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 175.5,42.5 5,-5"
+ style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path38972-1"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <g
+ id="g38975-0"
+ transform="translate(-146.75,127.75)">
+ <g
+ id="g38977-1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,272.1613,155.99999)"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path38984-8"
+ sodipodi:nodetypes="cz"
+ d="" />
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ style="opacity:0.85;fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path38987-2"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path38994-9"
+ d="m 188,51 0,6 -1,0 0,-5 -5,0 0,-1 6,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(-1,0,0,1,-29,-335)"
+ style="opacity:0.2"
+ id="g38996-7">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path38998-6"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g39000-4"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,118.4113,290.74999)"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39015-9"
+ sodipodi:nodetypes="cz"
+ d="" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 78.1613,110.99999 5.5,-5.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path39017-0"
+ sodipodi:nodetypes="cz" />
+ </g>
+ <g
+ id="g39020-8"
+ style="opacity:0.2"
+ transform="matrix(-1,0,0,1,-175.75,-207.25)">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.7;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -216,387 0,2 1,0 0,-1 1,0 0,-1 -2,0 z"
+ id="path39022-9"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55731">
+ <rect
+ y="51.97921"
+ x="25.950649"
+ height="16"
+ width="16"
+ id="rect42947-7"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-301.04935,-550.02079)"
+ id="g42949-4">
+ <g
+ style="opacity:0.85"
+ id="g42951-6">
+ <path
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 341.5161,616.38229 340.5,617.5 l -10.73389,-10e-6 -1.25,-1.25 L 328.5,605.5 l 13,0 0.0161,10.88229 z"
+ id="path42953-7"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42955-8"
+ d="m 340,616 -8.25,0 0,-1 8.25,0 0,1 z"
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38927-6"
+ width="11.970581"
+ height="8.0306396"
+ x="329.02942"
+ y="605.96936" />
+ <rect
+ y="605.96936"
+ x="329.02942"
+ height="8.0306396"
+ width="11.970581"
+ id="rect45307-5"
+ style="opacity:0.3;fill:url(#radialGradient45309-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path42957-3"
+ d="m 340.48389,606.50001 c -3.66204,-3e-5 -7.70403,2e-5 -10.98389,-10e-6 l 0.002,10.00007 10.99778,-7e-5 -0.0161,-9.99999 2.1e-4,0 z"
+ style="fill:none;stroke:url(#linearGradient42965-7-9);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ y="615"
+ x="330"
+ height="1.0000043"
+ width="1"
+ id="rect42959-9"
+ style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.35;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 340.5,614 -11,0 0,-1 11,0 0,1 z"
+ id="path38929-0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.25;fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter24186-3-2-5)"
+ d="m 337.7,606.7 0,2.75 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.75 2,0 z"
+ id="path42961-6"
+ sodipodi:nodetypes="ccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ id="path42963-7"
+ d="m 333.75,602.5 1.75,0 c 0,0 0,2 0,2 l 2,0 0,-2 1.75,0 0.25,0.25 0,2.5 -2,1.5 0,2.5 2,1.5 0,2.5 -0.25,0.25 -1.75,0 0,-2 -2,0 0,2 -1.75,0 -0.25,-0.25 0,-2.5 2,-1.5 0,-2.5 -2,-1.5 0,-2.5 0.25,-0.25 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:url(#linearGradient42967-6-4);stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g45287-4"
+ transform="translate(160.94228,123.97921)"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path45290-5"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -120.49163,-67.5 c -3.75159,0.954856 -7.20393,6.261452 -9,9 l -3.5,-3.5 -0.25,0.5 3.99163,4 0.5,0 c 1.0421,-2.617689 4.16191,-8.585412 8.25837,-10 l 0,0 z"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45302-1"
+ style="fill:none;stroke:#0b1e00;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path45294-9" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g55696">
+ <rect
+ transform="scale(-1,-1)"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45203-3"
+ width="16"
+ height="16"
+ x="-20.95064"
+ y="-67.97921" />
+ <g
+ style="display:inline"
+ id="g45205-1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="matrix(-1,0,0,-1,123.0839,85.1)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccccccccsccccc"
+ d="m 105.48388,31.25 6.25,-6 c 0.49692,0.284098 0.2225,0.232267 0.76612,0.25 2.20206,0.07183 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -4,1.792 -4,4 0,0.58349 0.009,0.250006 0.23388,0.75 l -6.25,6 0,2 1,1 2,0 z"
+ style="fill:url(#linearGradient55656);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path45207-7" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45209-9"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 115.5,21.5 -2.25,2.25 m -1,-5.5 c -1.75,0 -4,2.25 -2.5,5 l -1.26612,0.25 -5,5 0,1.75"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45211-9"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 105.48388,31.5 5.5,-5.5 0.25,-0.5 1.26612,0 c 2.73388,0 4,-1.792 4,-4 l -1,-1 -2.5,2.5 -0.5,-0.5 -1,-1 -0.5,-0.5 2.5,-2.5 -1,-1 c -2.208,0 -3.96454,1.25 -4,4 l -0.0161,1.25 -0.5,0.25 -5.5,5.5 0,2 1,1 2,0 -2e-5,0 z"
+ sodipodi:nodetypes="cccsccccccccsccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45214-0"
+ style="fill:none;stroke:#d7d7d7;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 109.98388,25 -5,5"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 109.48388,24.5 -4,4"
+ style="fill:none;stroke:#646464;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path45216-1" />
+ <rect
+ y="29"
+ x="103.98388"
+ height="1"
+ width="1"
+ id="rect45218-5"
+ style="fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(-409.04935,-611.97079)"
+ id="g32398-1">
+ <g
+ id="g32400-8"
+ transform="matrix(1,0,0,-1,73,774)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#0b1e00;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path32403-1"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path32411-7"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ style="color:#000000;fill:none;stroke:#0b1e00;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g32413-8"
+ transform="matrix(1,0,0,-1,73,774)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path32416-5"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#8af01e;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 417,669 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ id="path32418-2" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:none;stroke:#8af01e;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ id="path32420-2"
+ sodipodi:nodetypes="csc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path32422-4"
+ d="m 415.5,670 0,-4.5 m 5,4 -2,0"
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.4;color:#000000;fill:none;stroke:url(#linearGradient55624);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 428.5,671.21875 c -0.0591,-1.37274 -0.59591,-2.66246 -1.5,-3.6875 -1.09228,-1.23842 -2.62571,-1.96363 -4.1875,-2.09375 -1.55879,-0.12987 -3.16135,0.33951 -4.40625,1.4375 -3.3e-4,0.0104 -3.3e-4,0.0208 0,0.0312 L 417.5,667.75"
+ id="path32424-5"
+ sodipodi:nodetypes="cscccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g17770">
+ <rect
+ y="51.979202"
+ x="88.95063"
+ height="16"
+ width="16"
+ id="rect42954-1"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-49.94936,-39.370919)"
+ id="g42956-6">
+ <g
+ id="g42958-1"
+ transform="translate(-179,199.50012)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14490"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#281500;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g42962-0"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42964-9"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#915515;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path42966-1"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#efa351;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42968-5"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient55950);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42970-1"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#f5ca9b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path42972-5"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient55952);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect42974-8"
+ style="fill:url(#linearGradient55954);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42976-8"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.7882544,0,0,0.7883038,-8.4020402,-113.3734)"
+ id="g42978-1"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)"
+ sodipodi:type="arc"
+ style="fill:#f2b676;fill-opacity:1;fill-rule:nonzero;stroke:#281500;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42980-5"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42984-5"
+ style="fill:none;stroke:url(#linearGradient55956);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" />
+ <path
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42982-9"
+ style="opacity:0.8;fill:url(#linearGradient55958);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="matrix(0.875,0,0,0.875,-151.54375,-26.76875)"
+ id="g43952-8">
+ <g
+ transform="matrix(0,-1,1,0,183.99437,429)"
+ id="g43483-9">
+ <g
+ transform="translate(0,21)"
+ id="g43488-2">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43490-2"
+ d="M 327,86.255631 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.88571429;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43492-1"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:4.11428547;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g43494-2">
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 327,86.255631 327,76"
+ id="path43496-7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43498-9"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43776-0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.14285719;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient55988);stroke-width:1.14285719;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 284,97.25 -4.5,4.5 0,0.5 4.5,4.5"
+ id="path43780-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43860-6"
+ d="m 291.5,101.5 -8.99437,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.14285719;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56020">
+ <g
+ transform="translate(-28.94936,-39.370919)"
+ id="g42956-6-7">
+ <g
+ id="g42958-1-8"
+ transform="translate(-179,199.50012)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14490-2"
+ d="m 328.5,-107.25 -4.5,1.75 0,6.5 4.5,2.25 4.5,-2.25 0,-6.5 -4.5,-1.75 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#281500;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ id="g42962-0-2"
+ transform="translate(179,-179)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42964-9-7"
+ d="m 154,80 0,-6.5 -4.5,-1.75 0,10.5 L 154,80 z"
+ style="fill:#915515;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path42966-1-0"
+ d="m 324,-99.00012 0,-6.49988 4.5,-1.75 0.5,0.25 0,10 -0.5,0.25 -4.5,-2.25012 z"
+ style="fill:#efa351;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path42968-5-4"
+ d="m 332.5,-105.5 0,6.25 -4,2 -4,-2.00012 0,-6.24988"
+ style="fill:none;stroke:url(#linearGradient14559-8);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42970-1-3"
+ d="m 324,-105.5 4.5,-1.75 4.5,1.75 -4.5,2 -4.5,-2 z"
+ style="fill:#f5ca9b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path42972-5-8"
+ d="m 145.5,94.25012 c 0,0 4,1.75 4,1.75 l 4,-1.75"
+ style="opacity:0.95999995;fill:none;stroke:url(#linearGradient14561-9);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="96.000122"
+ x="149"
+ height="6.7500019"
+ width="1"
+ id="rect42974-8-0"
+ style="fill:url(#linearGradient14563-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.09599998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42976-8-4"
+ width="1"
+ height="6.7500019"
+ x="150"
+ y="96.000122" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.7882544,0,0,0.7883038,12.59796,-113.3734)"
+ id="g42978-1-6"
+ style="display:inline;enable-background:new">
+ <path
+ transform="matrix(0.6425292,0,0,0.642531,44.523834,146.81699)"
+ sodipodi:type="arc"
+ style="fill:#f2b676;fill-opacity:1;fill-rule:nonzero;stroke:#281500;stroke-width:1.97436094;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42980-5-8"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42984-5-2"
+ style="fill:none;stroke:url(#linearGradient14565-5);stroke-width:2.54167628;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.4991181,0,0,0.4991107,63.460522,163.7471)" />
+ <path
+ transform="matrix(-0.5858806,-0.06590218,0.06677852,-0.5812167,198.80048,299.96262)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42982-9-0"
+ style="opacity:0.8;fill:url(#linearGradient14567-8);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ transform="matrix(0.875,0,0,0.875,-149.68867,-26.76875)"
+ id="g43941-0">
+ <g
+ id="g43467-5"
+ transform="matrix(0,-1,-1,0,409.02125,429)">
+ <g
+ id="g43469-6"
+ transform="translate(0,21)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3.88571429;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 327,86.25 327,76"
+ id="path43471-7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:4.11428547;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path43473-1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g43475-6"
+ transform="translate(0,21)">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43478-9"
+ d="M 327,86.25 327,76"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43481-3"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#dcdcdc;stroke-width:2.28571439;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.37142861;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 308.5,106 2.75,-2.75"
+ id="path43778-6"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path43785-2"
+ d="m 308.75,97.25 c -0.25,0 -0.5,0.25 -0.5,0.5 m 2.26562,3.75 -8.99437,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1.14285719;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient55990);stroke-width:1.14285719;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 309.02125,97.249998 4.5,4.500002 0,0.5 -4.5,4.5"
+ id="path44948-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56270">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29107-06"
+ width="16"
+ height="16"
+ x="131"
+ y="52" />
+ <g
+ transform="translate(-399,2)"
+ id="g56091-7">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path29110-17"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,2.75 -5.99999,3.24999 L 531,60.75 531,58 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#9e9e9e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,0.5 -6,3 L 531,58.56558 531,58 z"
+ id="path29112-53" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path29114-1"
+ d="M 531.00001,60.75 531,58.5 l 7.99996,3.99998 0.01,2.49885 -8.00991,-4.24883 -4e-5,0 z"
+ style="fill:#848484;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#383838;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544.99996,61.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path29116-3"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient56084-9);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58.5 0,2 7.49996,3.99998 5.5,-3 0,-2"
+ id="path29118-7"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58 7.49996,3.74998"
+ id="path29120-1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29129-4);stroke-width:1.08012342;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path29122-40"
+ sodipodi:cx="749"
+ sodipodi:cy="420.25"
+ sodipodi:rx="2.5"
+ sodipodi:ry="1.75"
+ d="m 751.5,420.25 a 2.5,1.75 0 1 1 -5,0 2.5,1.75 0 1 1 5,0 z"
+ transform="matrix(1,0,0,0.8571429,-212,-302.2143)" />
+ <rect
+ style="fill:#66ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29125-3"
+ width="1"
+ height="1"
+ x="544"
+ y="61" />
+ </g>
+ <g
+ transform="matrix(0.53305487,0,0,0.53305487,-263.95264,-56.614058)"
+ id="g15021"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient15123);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path15023"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path15025"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient15125);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path15027"
+ style="fill:none;stroke:url(#linearGradient15127);stroke-width:1.03178871;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path15029"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="path15031"
+ style="fill:none;stroke:#000000;stroke-width:1.50078368;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15129);stroke-width:0.93798971;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path15033"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g15009"
+ transform="matrix(0.53305487,0,0,0.53305487,86.97987,-126.1707)">
+ <rect
+ y="344"
+ x="89"
+ height="16"
+ width="16"
+ id="rect15011"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g15013">
+ <rect
+ y="344.7504"
+ x="91.249611"
+ height="12.998481"
+ width="13"
+ id="rect15015"
+ style="fill:url(#linearGradient15131);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.50078368;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15017"
+ d="m 92.28796,356.69549 0,-10.90453 10.90641,0 0,10.90453 -10.90641,0 z"
+ style="fill:none;stroke:url(#linearGradient15133);stroke-width:0.56279385;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cszzcc"
+ id="path15019"
+ d="m 103.5,353.27516 c -0.37083,-1.1875 -1.21031,-1.72293 -1.9,-1.72929 -1.39235,-0.0134 -1.47709,3.98814 -2.999997,4 -1.491657,0.0119 -2.001315,-7 -3.5,-7 -1.52993,-10e-4 -1.18608,5.00645 -3.5,4.97929 l -1,0"
+ style="fill:none;stroke:url(#linearGradient15135);stroke-width:1.1255877;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g15035"
+ transform="matrix(0.53305487,0,0,0.53305487,-270.25684,-53.589044)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path15037"
+ d="m 757.01257,204.46121 9.48743,0.0388 0,14.99999 -13,0 0.0126,-11.53879 3.5,-3.5 -3e-5,0 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g15039"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <g
+ id="g15041">
+ <rect
+ style="fill:#ebb5b5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15043"
+ width="9.9999914"
+ height="12"
+ x="-83"
+ y="94" />
+ <rect
+ y="101"
+ x="-83"
+ height="4.9999976"
+ width="9.9999924"
+ id="rect15045"
+ style="opacity:0.5;fill:#4b80cd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="94"
+ x="-83"
+ height="6.8499999"
+ width="9.9999914"
+ id="rect15047"
+ style="opacity:0.3;fill:url(#radialGradient15137-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccccccc"
+ id="path15050"
+ d="m -83,100.00002 1,0 1,0.74999 1,-0.74999 1,0.99999 2,0 1.5,-0.75 1.5,0.75 0.999991,0 L -73,102 l -9.999991,0 -9e-6,-1.99998 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15052"
+ width="2.0000029"
+ height="2.0000038"
+ x="-77"
+ y="96" />
+ <path
+ style="opacity:0.3;fill:#280b0b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -83,102 10,0 0,1 -10,0 0,-1 z"
+ id="path15054"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path15056"
+ d="m -77,102 2.000003,0 -0.750003,4 -0.5,0 -0.75,-4 z"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g15058"
+ style="display:inline;enable-background:new"
+ transform="translate(838.01257,111.96121)">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15060"
+ d="m -82.5,105.5 0,-11 9,0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1.87597954px;stroke-linecap:round;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.87597954px;stroke-linecap:round;display:inline;enable-background:new"
+ d="m -82.5,105.5 0,-11 9,0 0,11 -9,0 z"
+ id="path15062"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.5;fill:url(#radialGradient15139-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 757.51257,204.46121 9,1e-5 0,14.99999 -13,0 0,-11 4,-4 z"
+ id="path15064"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="M 754.51257,209.96121 754.5,218.5 M 759.01257,205.46121 765.5,205.5"
+ style="fill:none;stroke:url(#linearGradient15141-6);stroke-width:1.03178871;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path15066"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753.01257,208.96121 5,0 0,-5 -5,5 z"
+ id="path15068"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="M 753.51257,207.96121 753.5,219.5 l 13,0 0,-14.99999 -9.48743,-0.0388 -3.5,3.5 z"
+ style="fill:none;stroke:#000000;stroke-width:1.50078368;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path15070"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path15072"
+ d="m 758.51257,206.46121 0,3 -3,0"
+ style="fill:none;stroke:url(#linearGradient15143-1);stroke-width:0.93798971;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56314">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29107-4"
+ width="16"
+ height="16"
+ x="152"
+ y="52" />
+ <g
+ transform="translate(-378,2)"
+ id="g56091-71">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path29110-7"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,2.75 -5.99999,3.24999 L 531,60.75 531,58 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#9e9e9e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 531,58 6,-2.5 7.99996,3.49998 0,0.5 -6,3 L 531,58.56558 531,58 z"
+ id="path29112-1" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path29114-0"
+ d="M 531.00001,60.75 531,58.5 l 7.99996,3.99998 0.01,2.49885 -8.00991,-4.24883 -4e-5,0 z"
+ style="fill:#848484;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#383838;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 544.99996,61.74998 0,-2.25 -6,3 c 0,2.58362 0,1.9329 0,2.5 l 6,-3.25 z"
+ id="path29116-7"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient56084-0);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58.5 0,2 7.49996,3.99998 5.5,-3 0,-2"
+ id="path29118-8"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 531.5,58 7.49996,3.74998"
+ id="path29120-7"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29129-1);stroke-width:1.08012342;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path29122-0"
+ sodipodi:cx="749"
+ sodipodi:cy="420.25"
+ sodipodi:rx="2.5"
+ sodipodi:ry="1.75"
+ d="m 751.5,420.25 a 2.5,1.75 0 1 1 -5,0 2.5,1.75 0 1 1 5,0 z"
+ transform="matrix(1,0,0,0.8571429,-212,-302.2143)" />
+ <rect
+ style="fill:#66ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29125-72"
+ width="1"
+ height="1"
+ x="544"
+ y="61" />
+ </g>
+ <g
+ transform="translate(-262.04935,-611.97079)"
+ id="g32365-0-5">
+ <g
+ style="opacity:0.8"
+ id="g32367-2-1"
+ transform="translate(23,1)">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g32369-7-1"
+ transform="matrix(0.927848,0,0,0.916217,240.82022,467.72362)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,265.50801,498.28815)"
+ id="g32373-2-0"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient32430-7-9-7);stroke-width:1.17973554;stroke-opacity:1;display:inline" />
+ </g>
+ <g
+ id="g32398-1-7">
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32400-8-4">
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path32403-1-2"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#0b1e00;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="color:#000000;fill:none;stroke:#0b1e00;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ id="path32411-7-3"
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(1,0,0,-1,73,774)"
+ id="g32413-8-5">
+ <path
+ style="fill:none;stroke:#8af01e;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path32416-5-1"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path32418-2-3"
+ d="m 417,669 0,-1 0,-1.5 1,0 0,1.5 1.5,0 0,1 -1.5,0 -1,0 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="csc"
+ id="path32420-2-7"
+ d="m 428,671.25 c -0.0541,-1.25729 -0.54273,-2.44429 -1.37516,-3.38809 -2.00926,-2.27808 -5.59675,-2.62117 -7.87484,-0.61191 L 417,669"
+ style="color:#000000;fill:none;stroke:#8af01e;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 415.5,670 0,-4.5 m 5,4 -2,0"
+ id="path32422-4-0"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cscccc"
+ id="path32424-5-0"
+ d="m 428.5,671.21875 c -0.0591,-1.37274 -0.59591,-2.66246 -1.5,-3.6875 -1.09228,-1.23842 -2.62571,-1.96363 -4.1875,-2.09375 -1.55879,-0.12987 -3.16135,0.33951 -4.40625,1.4375 -3.3e-4,0.0104 -3.3e-4,0.0208 0,0.0312 L 417.5,667.75"
+ style="opacity:0.4;color:#000000;fill:none;stroke:url(#linearGradient32434-5-8-9);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56410">
+ <g
+ transform="translate(190.95065,3.97921)"
+ id="g18875-2"
+ style="display:inline">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18877-3"
+ width="16"
+ height="16"
+ x="3"
+ y="69" />
+ <g
+ style="display:inline"
+ id="g18879-4"
+ transform="translate(0.01612278,0)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18881-0"
+ d="M 17.453876,82.25 16.233877,83.5 5.75,83.5 4.5,82.25 l -1e-7,-11.75 12.9652911,0 -0.01141,11.75 -5e-6,0 0,0 0,0 z"
+ style="fill:url(#linearGradient17222-4-4);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18883-5"
+ d="M 15.983877,81.999998 5.9838772,82 l 0,-0.999998 9.9999998,-2e-6 0,0.999998 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17224-0-9);stroke-width:0.99999976px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="M 5.4838772,82.500001 5.511418,71.499938 16.483877,71.5 l 0,11 -10.9999998,10e-7 z"
+ id="path18885-1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18887-7"
+ width="1"
+ height="1"
+ x="6.9838772"
+ y="81"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 197.45064,77.47921 9,0 m -9,2 9,0 m -9,2 9,0"
+ style="fill:none;stroke:url(#linearGradient56401);stroke-width:0.9999994px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1"
+ id="path19108-4"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g45287-4-9"
+ transform="translate(328.94228,144.9792)"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path45290-5-8"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -120.49163,-67.5 c -3.75159,0.954856 -7.20393,6.261452 -9,9 l -3.5,-3.5 -0.25,0.5 3.99163,4 0.5,0 c 1.0421,-2.617689 4.16191,-8.585412 8.25837,-10 l 0,0 z"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45302-1-2"
+ style="fill:none;stroke:#0b1e00;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path45294-9-3" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56383">
+ <rect
+ style="opacity:0;color:#000000;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.5999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect31818-2"
+ width="16"
+ height="16"
+ x="173"
+ y="73" />
+ <g
+ id="g45287-4-6"
+ transform="translate(307.94228,144.9792)"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path45290-5-0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -120.49163,-67.5 c -3.75159,0.954856 -7.20393,6.261452 -9,9 l -3.5,-3.5 -0.25,0.5 3.99163,4 0.5,0 c 1.0421,-2.617689 4.16191,-8.585412 8.25837,-10 l 0,0 z"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path45302-1-7"
+ style="fill:none;stroke:#0b1e00;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -120.5,-68.5 c -3.15098,1.124146 -6.99163,5 -8.99163,9 l -3.5,-3.5 -0.5,0.5 4,4 c 1.42501,-3.330356 5.5,-8.75 8.99163,-10"
+ style="fill:none;stroke:#9af23d;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path45294-9-7" />
+ </g>
+ <g
+ transform="translate(421.95065,-463.02079)"
+ id="g31820-9">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 0,-1 1,0"
+ id="path31830-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -239.25,548 0.5,0"
+ id="path31838-1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4"
+ d="m -239.25,548 0.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(425.95065,-463.02079)"
+ id="g31820-9-7">
+ <path
+ sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 0,-1 1,0"
+ id="path31830-7-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -239.25,548 0.5,0"
+ id="path31838-1-6"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3"
+ d="m -239.25,548 0.5,0"
+ style="color:#000000;fill:none;stroke:#d2d2d2;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -239.5,548.5 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56477">
+ <rect
+ y="73"
+ x="299"
+ height="16"
+ width="16"
+ id="rect25824-7"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(209.95065,-333.02079)"
+ id="g25826-2">
+ <path
+ style="fill:url(#linearGradient25927-1-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,408.5 0,11.49245 1.5,1.5 10.5,0.008 0,-11.99245 -8,-0.008 0,-1 -4,0 z"
+ id="path25828-2"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-361,287.99994)"
+ id="g25830-3"
+ style="display:inline" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-10.02344 2,0 0,1 L 100.5,410.5"
+ id="path25834-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 93,409 0,2 -3,0 0,-2 3,0 z"
+ id="path25840-3"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path25842-4"
+ d="m 89.5,408.5 0,11.49245 1.5,1.5 12,0.008 1.5,-1.49245 0,-6.50755 -3,-0.008 0,-3.9849 -8,-0.008 0,-1 -4,0 0,4.5e-4 0,0 0,0 z"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g56440">
+ <g
+ style="opacity:0.96000001;display:inline"
+ id="g40606-5"
+ transform="matrix(0.927848,0,0,0.916217,148.77086,-125.29717)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path40608-1"
+ style="fill:url(#linearGradient42519-8-7);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.22752953;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(0.784039,0,0,0.779055,173.45865,-94.73264)"
+ id="g40610-3"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient42523-5-8);stroke-width:1.17973554;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.87787,0,0,0.889264,55.67911,118.0341)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42521-3-0);stroke-width:1.44816053;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path40612-7"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path40614-9"
+ style="opacity:0.96000001;fill:none;stroke:#ffffff;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 310.45064,75.47921 -3,3 m 0,1 2,2"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 307.45064,79.47921 2,2"
+ style="opacity:0.96000001;fill:none;stroke:#aa0000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40616-6"
+ inkscape:transform-center-y="1.25"
+ inkscape:transform-center-x="-1.25" />
+ <rect
+ y="82.97921"
+ x="307.95065"
+ height="1.5"
+ width="1"
+ id="rect40618-1"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="77.97921"
+ x="311.95065"
+ height="1"
+ width="1.5"
+ id="rect40620-6"
+ style="opacity:0.48000004;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-0.75"
+ id="path40622-6"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 310.45064,75.47921 -3,3"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.96000001;fill:url(#linearGradient56428);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 307.80578,72.95456 c -3.25557,0.003 -5.8936,2.6597 -5.87155,5.95078 0.0105,1.56055 0.63214,2.99542 1.61111,4.05762 2.7831,-7.37691 5.95805,-1.77373 7.49116,-9.06794 -0.92886,-0.60835 -2.04538,-0.9415 -3.23072,-0.94046 l 0,0 0,0 0,0 z"
+ id="path40624-9"
+ inkscape:transform-center-x="1.4653436"
+ inkscape:transform-center-y="-1.0204512" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40626-3"
+ width="1.4999696"
+ height="1"
+ x="302.4668"
+ y="78.97921" />
+ <rect
+ style="opacity:0.28800001;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40628-5"
+ width="1"
+ height="1.4999921"
+ x="306.95065"
+ y="73.47921" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 310.45064,75.47921 -3,3"
+ style="opacity:0.57600002;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path40630-7"
+ inkscape:transform-center-y="-0.75" />
+ </g>
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect15838"
+ width="16"
+ height="16"
+ x="298.95065"
+ y="73.97921" />
+ <g
+ transform="translate(209.95065,-333.02079)"
+ id="g15840">
+ <g
+ style="display:inline"
+ id="g15844"
+ transform="translate(-361,287.99994)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path15846"
+ d="m 92.5,413.74245 12,0.008 0,6.25 -1.5,1.49245 -12,0.008 0,-2 1.5,0 0,-5.75755 0,-9e-4 z"
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25929-7-8);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15850"
+ d="m 93,420.5 9.5,0"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient15963-3);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 103.5,414.75 -10,-0.008 0,4.75755 -1.5,1.5 -1.5,-1.5"
+ id="path15852" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,419.99245 1.5,1.5 12,0.008 1.5,-1.49245 0,-6.50755 -3,-0.008"
+ id="path15856"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339-2"
+ transform="translate(62.95064,128.9792)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36341-7"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343-6">
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36363-9"
+ style="opacity:0.3;fill:url(#radialGradient37501-4-64);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <g
+ id="g36345-6"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349-3"
+ style="fill:#fa2929;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#ba0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351-4"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353-6"
+ style="fill:#8c0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#bb1010;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355-4"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357-2"
+ style="fill:#fa2929;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#ff7777;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359-5"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361-7"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36365-0"
+ style="fill:none;stroke:url(#linearGradient37503-1-7);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339-2-8"
+ transform="translate(83.95064,128.9792)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36341-7-6"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343-6-8">
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36363-9-4"
+ style="opacity:0.3;fill:url(#radialGradient37501-4-9-0);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <g
+ id="g36345-6-9"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349-3-1"
+ style="fill:#1fdf05;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#16ba00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351-4-7"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353-6-7"
+ style="fill:#109400;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#24bb10;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355-4-6"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357-2-5"
+ style="fill:#60f44c;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#87ff77;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359-5-2"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361-7-9"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36365-0-7"
+ style="fill:none;stroke:url(#linearGradient37503-1-9-9);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g36339-2-9"
+ transform="translate(104.94175,128.97922)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36341-7-4"
+ width="16"
+ height="16"
+ x="341"
+ y="238" />
+ <g
+ transform="translate(0,-12)"
+ id="g36343-6-2">
+ <path
+ transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36363-9-0"
+ style="opacity:0.3;fill:url(#radialGradient37501-4-6-8);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <g
+ id="g36345-6-4"
+ transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)">
+ <path
+ inkscape:transform-center-y="-3.2499984"
+ inkscape:transform-center-x="-2.8145849"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36349-3-5"
+ style="fill:#5050fb;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" />
+ <path
+ transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)"
+ sodipodi:type="arc"
+ style="fill:#0000ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36351-4-3"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="-3.2630798"
+ inkscape:transform-center-y="1.6729808e-05" />
+ <path
+ inkscape:transform-center-y="3.2500173"
+ inkscape:transform-center-x="-2.8145756"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36353-6-4"
+ style="fill:#00008c;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)" />
+ <path
+ transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)"
+ sodipodi:type="arc"
+ style="fill:#1010bb;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36355-4-4"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145978"
+ inkscape:transform-center-y="3.249994" />
+ <path
+ inkscape:transform-center-x="3.2630773"
+ sodipodi:end="5.7595865"
+ sodipodi:start="4.712389"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36357-2-9"
+ style="fill:#5050fb;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)" />
+ <path
+ inkscape:transform-center-y="-3.2500006"
+ transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
+ sodipodi:type="arc"
+ style="fill:#9a9afd;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path36359-5-4"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:start="4.712389"
+ sodipodi:end="5.7595865"
+ inkscape:transform-center-x="2.8145777" />
+ </g>
+ <path
+ transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path36361-7-0"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path36365-0-0"
+ style="fill:none;stroke:url(#linearGradient37503-1-1-1);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g42207-2"
+ transform="translate(230.94982,190.97922)">
+ <g
+ transform="translate(83.990364,83.999999)"
+ id="g42209-9"
+ style="opacity:0.5">
+ <path
+ transform="matrix(0.9361892,0,0,0.9375002,-26.576994,10.374973)"
+ sodipodi:type="arc"
+ style="fill:#ffd5d5;fill-opacity:0.58823529;fill-rule:nonzero;stroke:#800000;stroke-width:1.06741309;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42211-6"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path42213-0"
+ style="fill:none;stroke:url(#linearGradient42487-4-5);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" />
+ <path
+ transform="matrix(0.6848076,0,0,0.6867124,6.6184411,39.974237)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42489-5-9);stroke-width:1.45823753;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42215-8"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient42491-0-9);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path42217-3"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path17230"
+ style="fill:none;stroke:url(#linearGradient17232-8);stroke-width:3.2130022;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.31076006,0,0,0.31171146,55.992715,84.224347)" />
+ </g>
+ <g
+ transform="matrix(1.3088013,0,0,1.3078064,114.94487,78.842325)"
+ style="display:inline"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g42219-5" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16164">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18695-5"
+ width="16"
+ height="16"
+ x="173"
+ y="241" />
+ <g
+ id="g16145">
+ <g
+ transform="translate(-150.04936,350.7292)"
+ id="g18697-4">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path18699-1"
+ d="m 330,-107.75 -5,2 0.0372,6.324398 5,2.71875 4.99999,-2.71875 L 335,-105.75 l -5,-2 z"
+ style="fill:none;stroke:url(#linearGradient28405-0);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient18721-1-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 330.03717,-107.6131 -5,1.875 0,6.312498 5,2.71875 4.99999,-2.71875 0,-6.312498 -4.99999,-1.875 z"
+ id="path18719-9" />
+ <g
+ transform="translate(179,-179)"
+ id="g18703-1">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient18728-6-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 146.0019,73.295281 5,-1.894157 5,1.894157 -5,2.073959 -5,-2.073959 z"
+ id="path18707-3" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient18765-0-9);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 334.98437,-105.6875 -5,2.04687 0.0156,6.89063 5,-2.75 z"
+ id="path18763-6" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient18712-0-7);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-105.25 0.002,5.587357 -4.5,2.480073 -4.5,-2.480073 -0.002,-5.587357 4.5,-1.75 4.5,1.75 z"
+ id="path18709-9"
+ sodipodi:nodetypes="ccccccc" />
+ <g
+ style="opacity:0.7"
+ id="g18737-7" />
+ </g>
+ <g
+ id="g52877-0"
+ style="display:inline;enable-background:new"
+ transform="translate(-332.03324,273.93783)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#2968c3;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ id="path52879-3"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path52881-6"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ style="opacity:0.7;fill:url(#radialGradient53141-5-8);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ id="path52883-5"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path52885-6"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.37109,1.875 2.37891,-2.375 -1.5,-2 z"
+ style="fill:url(#linearGradient53143-6-3);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path52887-1"
+ d="m 520.48389,-31.45862 -6,6.75 2,2.25 4,-4"
+ style="fill:none;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient53145-1-0);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 520.98389,-31.95862 -6.75,7.75 1.75,1.75 5,-4.5 0,-5 z"
+ id="path52889-3"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path52891-3"
+ d="m 513.48389,-22.45862 7,-8.25"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path52893-4"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53147-9-4);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16082">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18695-2"
+ width="16"
+ height="16"
+ x="152"
+ y="241" />
+ <g
+ id="g16049">
+ <g
+ id="g16027">
+ <g
+ transform="translate(-20.81186,-5.9082992)"
+ id="g27791"
+ style="display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#181dff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#2f4cff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-13.91186,-7.9082992)"
+ id="g27791-5"
+ style="fill:none;display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-5"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-0"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#00cc19;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#34ff24;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-10.27839,-7.4632172)"
+ id="g27791-9"
+ style="display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-7"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-5"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#ffff0a;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#fcff7b;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-6.9118602,-5.9082992)"
+ id="g27791-0"
+ style="display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-54"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-1"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#ff0606;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#ff3131;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-4"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-17.39403,-7.3654702)"
+ id="g27791-5-2"
+ style="fill:none;display:inline;enable-background:new">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:3.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 173.5625,249.6875 0.5,0"
+ id="path31838-1-6-1-4-5-4"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path31840-4-3-0-6-0-6"
+ d="m 173.5625,249.6875 0.5,0"
+ style="color:#000000;fill:none;stroke:#00bc86;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#24ffea;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 173.3125,250.1875 -0.25,-0.5 0.25,-0.5 1,0"
+ id="path31844-1-3-6-4-7-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ id="g16016">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path18699-7"
+ d="m 159.95712,247.8542 -3.25648,1.32353 -1.7128,5.25087 5,2.71875 4.99999,-2.71875 -1.77423,-5.25087 z"
+ style="fill:none;stroke:#0b1728;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient16010);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 159.98133,247.9448 -3.25648,1.2408 -1.73704,5.243 5,2.71875 4.99999,-2.71875 -1.75,-5.243 z"
+ id="path18719-4" />
+ <g
+ transform="translate(8.95064,173.9792)"
+ id="g18703-0">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient15994);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 147.75124,75.228495 3.25648,-1.253486 3.25648,1.253486 -3.25648,1.372473 z"
+ id="path18707-0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient16005);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 163.2136,249.34317 -3.25648,1.32353 -0.006,6.4375 5,-2.75 z"
+ id="path18763-7" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient16002);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 162.79956,249.6191 1.65308,4.57246 -4.5,2.48007 -4.5,-2.48007 1.75043,-4.61666 2.79824,-1.11389 z"
+ id="path18709-5"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0"
+ id="path14332-7-5"
+ d="m 161.04227,247.90828 c 0.24495,-0.26634 0.39423,-0.62011 0.39423,-1.00834 0,-0.8284 -0.67974,-1.49994 -1.51825,-1.49994 -0.83851,0 -1.51825,0.67154 -1.51825,1.49994 0,0.43979 0.0353,0.57241 0.34052,0.84677"
+ style="fill:#e6e6e6;fill-opacity:1;stroke:#0b1728;stroke-width:2.80000019;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ transform="matrix(0.8540253,0,0,-1.199954,81.751209,396.89409)"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
+ sodipodi:ry="1.25"
+ sodipodi:rx="1.75"
+ sodipodi:cy="125"
+ sodipodi:cx="91.5"
+ id="path14336-5-6"
+ style="fill:#000000;fill-opacity:1;stroke:url(#linearGradient15989);stroke-width:1.28417933;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:type="arc" />
+ <rect
+ style="opacity:0.75;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect14340-2-4"
+ width="2.0011597"
+ height="2"
+ x="158.93533"
+ y="245.8999" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16224">
+ <rect
+ y="241"
+ x="194"
+ height="16"
+ width="16"
+ id="rect18695-5-8"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g16203">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect27661-6"
+ width="16"
+ height="16"
+ x="193.95064"
+ y="240.9792" />
+ <g
+ clip-path="url(#clipPath42711-8-1)"
+ style="display:inline;enable-background:new"
+ id="g27663-9"
+ transform="matrix(0.9168751,0,0,0.9161255,86.13094,44.221905)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0"
+ id="path27665-7"
+ d="m 140.02478,121.67739 -4.38034,-0.0133 0.0328,4.36819 -6.18368,-0.0323 -0.0643,-16 6.1827,-0.0158 -0.0143,4.42449 4.42553,-0.0164 z"
+ clip-path="none"
+ mask="none"
+ style="fill:url(#linearGradient15368-7);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.75,0,0,0.75,29.5,135)" />
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ style="fill:url(#linearGradient15326-8);fill-opacity:1;stroke:#183e75;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none"
+ clip-path="none"
+ d="m 135.64444,121.66409 -6.15088,-0.006 -0.0643,-7.28458 6.1684,0.0349 z"
+ id="path15284"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ transform="matrix(0.75,0,0,0.75,29.5,135)"
+ style="fill:none;stroke:#0b1728;stroke-width:1.45480967;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none"
+ clip-path="none"
+ d="m 140.02478,121.67739 -4.38034,-0.0133 0.0328,4.36819 -6.18368,-0.0323 -0.0643,-16 6.1827,-0.0158 -0.0143,4.42449 4.42553,-0.0164 z"
+ id="path15318"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccc" />
+ </g>
+ <g
+ id="g27669-3"
+ style="opacity:0.55;display:inline;enable-background:new"
+ transform="translate(-42.04936,-19.020799)">
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ sodipodi:nodetypes="cccc"
+ id="path27671-9"
+ d="M 243.50439,274.05251 237.04285,268 l 0.43058,-0.40461 6.03096,-5.66723"
+ style="fill:url(#linearGradient42432-3-3);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:url(#linearGradient15281-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.87159598;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 243.55198,273.44361 237.66157,268 l 5.84282,0.0171"
+ id="path15273"
+ sodipodi:nodetypes="ccc"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path27673-0-1"
+ d="m 200.70018,253.41671 -4.93656,-4.42903 4.93656,-4.57097"
+ style="fill:none;stroke:url(#linearGradient15620-8);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g27675-38"
+ style="display:inline;enable-background:new"
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-41.79538,113.49288)">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 73.545051,272.22272 7.071067,-7.07107"
+ id="path27679-2"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path42388-6"
+ style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path42359-8" />
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.6507937;display:inline;enable-background:new"
+ d="m 207.43504,247.49483 1.06248,0"
+ id="path15333"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.6507937;display:inline;enable-background:new"
+ d="m 203.9116,244.49483 1.51561,0"
+ id="path15333-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.6507937;display:inline;enable-background:new"
+ d="m 203.9116,247.51045 1.54686,0"
+ id="path15333-3"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1b4685;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 207.38817,249.47921 0.0703,0.004"
+ id="path15333-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#185e98;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 203.38817,249.47921 1.07811,0.0118"
+ id="path15333-2-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#143564;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 204.37254,253.47921 1.07811,0.0118"
+ id="path15333-2-7-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16281">
+ <rect
+ y="241"
+ x="236"
+ height="16"
+ width="16"
+ id="rect18695-5-0"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g38510"
+ style="display:inline;enable-background:new"
+ transform="translate(-0.04936017,-0.02079917)">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41297-5"
+ width="10"
+ height="16"
+ x="239"
+ y="241" />
+ <path
+ style="fill:url(#linearGradient15474-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 244,242.5 c -1.8975,0 -3.4375,1.12 -3.4375,2.5 l 0,2.6875 c -0.79985,0.58688 -1.28125,1.40301 -1.28125,2.4375 0,1.01219 0.48237,1.85277 1.28125,2.4375 l 0,1.4375 c 0,1.38 1.54,2.5 3.4375,2.5 1.8975,0 3.4375,-1.12 3.4375,-2.5 l 0,-1.375 c 0.82151,-0.58809 1.3125,-1.44988 1.3125,-2.5 0,-1.02039 -0.50216,-1.82067 -1.3125,-2.40625 l 0,-2.71875 c 0,-1.38 -1.54,-2.5 -3.4375,-2.5 z"
+ id="path41299-1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.44561403;fill:none;stroke:url(#linearGradient15467-9);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 246.78175,244.56297 c -0.49244,0.67079 -1.66895,1.05852 -2.78633,1.05852 -1.11738,0 -2.54413,-0.3096 -2.81106,-1.12463"
+ id="path41303-1"
+ sodipodi:nodetypes="czs" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path41307-7"
+ d="m 241.4192,253.61696 c 0.11987,0.88868 0.64962,2.00518 2.61584,2.01183 1.81407,0.006 2.49621,-1.01999 2.49621,-2.00379"
+ style="fill:none;stroke:#1b4685;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.64285715;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="czcsssc"
+ id="path15557"
+ d="m 247.22147,247.96875 c -0.5625,0.53865 -1.82275,0.90274 -3.1948,0.90274 -1.37205,0 -2.25345,-0.3128 -3.15167,-0.80899 -0.625,0.59375 -1.17803,1.9131 -0.72606,2.94175 0.61274,1.39456 1.58368,2.00791 3.99437,2.02034 2.38609,0.0123 3.13442,-0.85323 3.75195,-2.02459 0.57357,-1.08798 0.16996,-2.1875 -0.67379,-3.03125 z"
+ style="fill:none;stroke:url(#linearGradient15601-9);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path41305-9"
+ d="m 244,242.5 c -2.18749,0 -3.4375,1.12 -3.4375,2.5 l 0,2.3125 c -0.8822,0.72794 -1.4375,1.73295 -1.4375,2.84375 0,1.1108 0.5553,2.11581 1.4375,2.84375 l 0,0.5 c 0,2 1.54,3 3.4375,3 1.8975,0 3.4375,-1 3.4375,-3 l 0,-0.5 c 0.8822,-0.72794 1.4375,-1.73295 1.4375,-2.84375 0,-1.1108 -0.5553,-2.11581 -1.4375,-2.84375 l 0,-2.3125 c 0,-1.38 -1.24999,-2.5 -3.4375,-2.5 z"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g41715-3"
+ transform="matrix(0.75,0,0,0.625,396.9999,55.104854)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect41717-2"
+ width="16"
+ height="16"
+ x="-211.99985"
+ y="304" />
+ <g
+ style="opacity:0.8;display:inline;enable-background:new"
+ transform="translate(73.00016,196)"
+ id="g41719-6" />
+ <g
+ style="display:inline"
+ id="g41739-4"
+ transform="matrix(1.1658027,0,0,1.1657997,-354.28956,51.94393)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient15576-5);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 247.03531,249.33728 c -0.5,0.22615 -1.69837,0.52774 -2.8823,0.52774 -1.18393,0 -1.75974,-0.0315 -3.02667,-0.49649"
+ id="path41303-1-0"
+ sodipodi:nodetypes="czs" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 250.25295,253 c 0.73683,-0.72794 1.01313,-1.73295 1.01313,-2.84375 0,-1.1108 -0.2763,-2.11581 -1.01313,-2.84375"
+ id="path15603"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path15609"
+ d="m 249.80713,252.38128 c 0.53336,-0.70678 0.65533,-1.36527 0.65533,-2.22503 0,-0.80144 -0.27822,-1.5779 -0.65533,-2.18084"
+ style="fill:none;stroke:#aacee7;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.80392157;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 237.81491,253 c -0.73683,-0.72794 -1.01313,-1.73295 -1.01313,-2.84375 0,-1.1108 0.2763,-2.11581 1.01313,-2.84375"
+ id="path15603-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path15609-7"
+ d="m 238.26073,252.38128 c -0.53336,-0.70678 -0.65533,-1.36527 -0.65533,-2.22503 0,-0.80144 0.27822,-1.5779 0.65533,-2.18084"
+ style="fill:none;stroke:#aacee7;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.80392157;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g81264">
+ <rect
+ y="241"
+ x="278"
+ height="16"
+ width="16"
+ id="rect41153-9"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-0.96226475,0.05341077)"
+ id="g16521">
+ <rect
+ y="242.48071"
+ x="280.45062"
+ height="12.983693"
+ width="12.031255"
+ id="rect41157-7"
+ style="fill:url(#linearGradient81258);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.90000004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41159-4"
+ d="m 281.45064,253.1653 0.0312,-9.6861 3.81301,0.0312"
+ style="fill:none;stroke:url(#linearGradient81260);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.53174594;display:inline;enable-background:new"
+ d="m 291.50046,246.74298 -3.08218,7.80871"
+ id="path15817-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.48809521"
+ d="m 285.63278,246.41513 -3.2942,8.11179"
+ id="path15817"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#555555;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 286.48189,242.32295 0.0625,12.09375"
+ id="path15730"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59"
+ width="2.0172396"
+ height="2.0000157"
+ x="279.45065"
+ y="241.47917" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path41159-4-9"
+ d="m 287.42759,252.9156 -0.0313,-9.49861 3.85989,0.0312"
+ style="fill:none;stroke:url(#linearGradient81262);stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#1b4685;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 292.04439,242.6042 -5.18214,13.04504"
+ id="path15722"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1b4685;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 286.07564,242.5417 -5.19822,12.90441"
+ id="path15726"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-1"
+ width="2.0172396"
+ height="2.0000157"
+ x="285.47092"
+ y="241.53545" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-50"
+ width="2.0172396"
+ height="2.0000157"
+ x="285.47092"
+ y="254.48941" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-6"
+ width="2.0172396"
+ height="2.0000157"
+ x="291.48386"
+ y="254.48941" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-16"
+ width="2.0172396"
+ height="2.0000157"
+ x="291.45065"
+ y="241.47917" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-15"
+ width="2.0172396"
+ height="2.0000157"
+ x="279.48859"
+ y="254.48941" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16263">
+ <rect
+ y="241"
+ x="215"
+ height="16"
+ width="16"
+ id="rect18695-5-85"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g16254">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccscsscccscscccsccc"
+ inkscape:connector-curvature="0"
+ id="path15496"
+ d="m 220.26315,246.13546 c -0.0862,0.1378 -0.24068,0.22975 -0.40625,0.28125 -1.65981,0.47731 -3.15715,1.19818 -4.5,2.59375 -0.0159,0.0174 -0.0268,0.0393 -0.0312,0.0625 -0.001,0.0103 -0.001,0.0208 0,0.0312 -0.001,0.0103 -0.001,0.0208 0,0.0312 -0.001,0.0104 -0.001,0.0208 0,0.0312 0.0905,0.15733 0.21244,0.52956 0.25,0.8125 0.0551,0.41528 -0.0701,0.57924 -0.21875,0.8125 -0.0121,0.008 -0.0227,0.0191 -0.0312,0.0312 -0.001,0.0104 -0.001,0.0208 0,0.0312 -0.001,0.0103 -0.001,0.0208 0,0.0312 -0.001,0.0104 -0.001,0.0208 0,0.0312 0.008,0.0121 0.0191,0.0227 0.0312,0.0312 1.14704,1.20048 2.82583,2.11181 4.34375,2.15625 0.23229,0.01 0.47603,0.12502 0.59375,0.3125 0.16075,0.25148 0.43475,0.47431 0.75,0.65625 0.36481,0.21054 0.91885,0.30403 1.0936,0.3126 -0.22349,-0.50587 -0.17899,-0.77088 -0.0469,-0.99985 0.0995,-0.17241 0.27563,-0.29702 0.54688,-0.34375 1.23062,-0.212 2.86055,-0.63055 4.03125,-1.34375 0.29545,-0.18247 0.80307,-0.0462 1,0.25 0.55094,0.7385 1.45946,1.2674 2.03896,1.31646 -0.36853,-0.9196 -0.50376,-2.31287 -0.46489,-3.25371 0.0492,-1.1901 0.4842,-2.52395 1.04302,-3.51538 -0.16982,0.006 -0.65061,0.17808 -0.71074,0.20318 -0.7366,0.30737 -1.4716,0.94031 -1.90625,1.5625 -0.21933,0.29875 -0.71618,0.4032 -1,0.1875 -1.35724,-1.03154 -2.55364,-1.6969 -4.09375,-2.1875 -0.26943,-0.0858 -0.50165,-0.42209 -0.5,-0.71875 0.002,-0.30009 0.0702,-0.84684 0.12109,-1.07402 -0.58853,0.18102 -1.36128,0.81203 -1.93359,1.66737 z"
+ style="fill:none;stroke:url(#linearGradient38716-8);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;display:inline;enable-background:new" />
+ <path
+ style="fill:url(#radialGradient15517-8);fill-opacity:1;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 219.6786,253.82631 c -1.96642,-0.0576 -4.05614,-1.31113 -5.29929,-2.86623 0.0654,-0.19861 0.53326,-0.60538 0.48122,-0.99782 -0.0595,-0.44857 -0.37333,-0.70398 -0.47362,-0.96241 1.5443,-1.81083 3.32964,-2.734 5.24944,-3.28607 0.78991,-1.17883 1.845,-2.02236 3.60073,-2.29898 -0.23142,0.67492 -0.40517,1.48328 -0.41544,2.14499 1.60855,0.52209 2.84544,1.19775 4.24601,2.26976 1.05365,-1.50823 3.37131,-2.56597 4.4316,-1.95202 -0.84375,1.27451 -1.45665,2.90118 -1.50672,4.17975 -0.0491,1.25211 0.0947,2.42706 0.75517,3.90477 -1.30024,0.35961 -2.91498,-0.40691 -3.71178,-1.61649 -1.31489,0.80105 -3.03198,1.22409 -4.31307,1.42108 0.13331,0.35326 0.31382,0.79794 0.42375,1.41797 -1.5092,0.0506 -2.82758,-0.35645 -3.468,-1.3583 z"
+ id="path26202"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsccccccsccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path38361"
+ d="m 218.00011,250.69439 c -0.39287,0 -0.71132,-0.31189 -0.71132,-0.69657 0,-0.38468 0.31845,-0.69659 0.71132,-0.69659 0.39025,0 0.70763,0.30797 0.71128,0.69334 0,0.38793 -0.31844,0.69982 -0.71128,0.69982 z"
+ style="fill:none;stroke:url(#linearGradient15553-4);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.72222218;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ style="fill:none;stroke:#183e75;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 217.62649,250.02159 c -0.17675,0 -0.32002,-0.1385 -0.32002,-0.30932 0,-0.17083 0.14327,-0.30933 0.32002,-0.30933 0.17557,0 0.31836,0.13676 0.32,0.30789 0,0.17226 -0.14327,0.31076 -0.32,0.31076 z"
+ id="path26221"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15545-5);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.58823529;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 219.95124,248.20112 c 0.63267,0.99518 0.82685,2.28773 0.0962,3.39254"
+ id="path26223-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ transform="translate(-0.04936017,-0.02079917)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.21185222"
+ inkscape:original="M 222.25 244.5 C 221.66147 244.68102 220.88481 245.30091 220.3125 246.15625 C 220.2263 246.29405 220.07182 246.386 219.90625 246.4375 C 218.24644 246.91481 216.7491 247.63568 215.40625 249.03125 C 215.39035 249.04865 215.3794 249.07055 215.375 249.09375 C 215.374 249.10405 215.374 249.1146 215.375 249.125 C 215.374 249.1353 215.374 249.14585 215.375 249.15625 C 215.374 249.16665 215.374 249.1771 215.375 249.1875 C 215.4655 249.34483 215.58744 249.71706 215.625 250 C 215.6801 250.41528 215.5549 250.57924 215.40625 250.8125 C 215.39415 250.8205 215.3835 250.83165 215.375 250.84375 C 215.374 250.85415 215.374 250.8646 215.375 250.875 C 215.374 250.8853 215.374 250.89585 215.375 250.90625 C 215.374 250.91665 215.374 250.9271 215.375 250.9375 C 215.383 250.9496 215.39415 250.96025 215.40625 250.96875 C 216.55329 252.16923 218.23208 253.08056 219.75 253.125 C 219.98229 253.135 220.22603 253.25002 220.34375 253.4375 C 220.5045 253.68898 220.7785 253.91181 221.09375 254.09375 C 221.45856 254.30429 222.01275 254.39768 222.1875 254.40625 C 221.96401 253.90038 221.99291 253.63522 222.125 253.40625 C 222.2245 253.23384 222.41625 253.10923 222.6875 253.0625 C 223.91812 252.8505 225.54805 252.43195 226.71875 251.71875 C 227.0142 251.53628 227.52182 251.67255 227.71875 251.96875 C 228.26969 252.70725 229.1705 253.23219 229.75 253.28125 C 229.38147 252.36165 229.24238 250.97209 229.28125 250.03125 C 229.33045 248.84115 229.78493 247.52268 230.34375 246.53125 C 230.17393 246.53725 229.68513 246.69365 229.625 246.71875 C 228.8884 247.02612 228.1534 247.65906 227.71875 248.28125 C 227.49942 248.58 227.00257 248.68445 226.71875 248.46875 C 225.36151 247.43721 224.16511 246.77185 222.625 246.28125 C 222.35557 246.19545 222.12335 245.85916 222.125 245.5625 C 222.127 245.26241 222.19911 244.72718 222.25 244.5 z "
+ style="fill:none;stroke:url(#linearGradient15502-8);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path15500"
+ d="m 221.96875,244.90625 c -0.47698,0.2556 -1.02431,0.71077 -1.46875,1.375 -0.12408,0.19836 -0.33308,0.28211 -0.53125,0.34375 a 0.21187341,0.21187341 0 0 1 0,0.0312 c -1.62449,0.46715 -3.06989,1.15677 -4.375,2.5 -0.005,0.005 0.005,0.026 0,0.0312 0.1061,0.21524 0.2123,0.49726 0.25,0.78125 0.0568,0.42776 -0.0841,0.69165 -0.21875,0.90625 1.11129,1.13328 2.71326,1.98992 4.125,2.03125 0.29567,0.0127 0.61425,0.14029 0.78125,0.40625 0.1325,0.20728 0.35983,0.42268 0.65625,0.59375 0.20197,0.11656 0.49212,0.2047 0.71875,0.25 -0.0302,-0.11277 -0.0911,-0.24526 -0.0937,-0.34375 -0.005,-0.19698 0.0446,-0.36065 0.125,-0.5 0.13631,-0.23619 0.40186,-0.41416 0.71875,-0.46875 1.21549,-0.20939 2.80996,-0.62559 3.9375,-1.3125 0.21394,-0.13213 0.48738,-0.12178 0.71875,-0.0625 0.22418,0.0574 0.42522,0.18054 0.5625,0.375 0.41333,0.55404 1.07488,0.98799 1.5625,1.15625 -0.29258,-0.93531 -0.41043,-2.11125 -0.375,-2.96875 0.0456,-1.10343 0.44992,-2.25295 0.9375,-3.21875 -0.14571,0.0415 -0.29515,0.0995 -0.28125,0.0937 -0.68743,0.28685 -1.40343,0.91443 -1.8125,1.5 a 0.21187341,0.21187341 0 0 1 -0.0312,0 c -0.14786,0.2014 -0.35962,0.32934 -0.59375,0.375 -0.23413,0.0457 -0.48506,-0.002 -0.6875,-0.15625 -1.34443,-1.0218 -2.51369,-1.67283 -4.03125,-2.15625 -0.1942,-0.0618 -0.35572,-0.18089 -0.46875,-0.34375 -0.11303,-0.16286 -0.18863,-0.35845 -0.1875,-0.5625 0.001,-0.19898 0.0297,-0.41985 0.0625,-0.65625 z" />
+ <path
+ style="fill:none;stroke:url(#linearGradient15537-5);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 220.40065,247.42921 c 1.3319,1.37892 1.29257,3.57882 0.34306,4.70903"
+ id="path26223-2-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16592">
+ <rect
+ style="opacity:0;fill:#292929;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23518-8"
+ width="16"
+ height="16"
+ x="488"
+ y="262" />
+ <g
+ id="g16579">
+ <rect
+ y="268.95908"
+ x="495.95065"
+ height="1"
+ width="2"
+ id="rect23532-1-0"
+ style="opacity:0.8;fill:#1e56ab;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#0b1728;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 501.95064,269.22921 0,0.75008 0,2.99996 -3,1.5 c -3,1.5 -6.25,1.5 -10,1.49996 l -0.0183,-2.52715 c 0,0 3.366,-6.98108 4.33827,-8.04174 0.97227,-1.06066 4.00392,-2.08028 4.61579,-2.33915 3.72167,-0.006 4.09599,4.72641 4.06425,6.15804 z m -8,0.25 4.90625,-1.875 c 0.0715,-1.36645 -0.67378,-2.97927 -2.03429,-3.23624"
+ id="path23522-5"
+ sodipodi:nodetypes="scccccsccsccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="cccccccccc"
+ style="fill:#c2d4ef;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 493.95064,269.47921 4,-1.5 0.9375,-0.40625 3.0625,1.65625 0,0.75004 0,2.75 -3,1.5 -10,1.5 0,-1.75 c 0.5,-1 1.77456,-3.24182 5,-4.50004 z"
+ id="path23524-5" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ d="m 495.70064,264.97925 c -1.59411,1.20331 -2.85352,5.00657 -1.83419,6.55562 0.84654,1.28647 2.26188,0.99107 4.08419,0.44438"
+ style="fill:none;stroke:url(#linearGradient16573);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23542-7" />
+ <path
+ id="path14759-8"
+ d="m 497.43868,264.59926 c 0.80576,0.30416 1.37557,1.03323 1.48798,2.92233 l 3.02398,2.65977 c -0.14914,-2.63927 0.0915,-5.8212 -3.12879,-7.01803 -0.39922,-0.14837 -1.04358,-0.0621 -1.33996,0.0614 z"
+ style="fill:url(#linearGradient16570);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cssccsccscsscc"
+ id="path23526-4"
+ d="m 497.47415,263.23002 c -0.0305,0.0127 -2.69071,1.0899 -3.08515,1.28834 -0.97345,0.48973 -2.73962,3.32869 -3.70177,5.33135 l -1.74953,3.64155 0.013,2.49908 c 3.76795,10e-6 7,0 10,-1.5 l 3,-1.5 0,-3 c -0.71506,0.35798 -2.3836,1.1918 -3,1.5 -0.45529,0.22765 -0.90706,0.42996 -1.375,0.59375 -1.77534,0.39453 -3.51362,0.44764 -3.974,-0.67129 -0.58429,-1.42008 0.52872,-4.89528 2.24297,-6.11564 0.23077,-0.16428 1.56009,-0.67849 1.59569,-0.69629 z"
+ style="fill:url(#linearGradient16567);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path23528-6"
+ d="m 489.45064,275.4966 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
+ style="fill:none;stroke:url(#linearGradient16564);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:none;stroke:url(#linearGradient16561);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 489.45064,274.47921 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
+ id="path23540-9"
+ sodipodi:nodetypes="csc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscsc"
+ d="m 489.67253,273.44041 2.07721,-4.14016 c 0.98497,-1.9632 2.11086,-3.89476 3.15802,-4.3308 l 2.83577,-1.18084 c 0.92808,-0.35355 2.39677,0.78516 2.88291,1.66904 0.48613,0.88389 0.68121,2.03922 0.85799,4.29312"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient16558);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23546-3" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#1b4685;stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 497.15108,270.57068 c -0.87852,0.21783 -1.75,-0.0997 -1.75,-0.67783 0,-0.57817 0.44856,-1.11322 1.32701,-1.33132 0.77415,-0.19217 1.49604,0.10015 1.66916,0.65891 0.16722,0.53968 -0.3266,1.12224 -1.24617,1.35024 z"
+ id="path27309-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.37383178"
+ d="m 492.06936,275.51839 0.98651,-0.0593"
+ id="path27317-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14953">
+ <rect
+ y="198.9792"
+ x="4.9506397"
+ height="16"
+ width="16"
+ id="rect23018-5-4"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.94058502,0,0,0.94058502,0.9128606,12.74924)"
+ id="g56716">
+ <path
+ sodipodi:type="star"
+ style="fill:url(#linearGradient14951);fill-opacity:1;stroke:#000000;stroke-width:0.96882826;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path15855"
+ sodipodi:sides="5"
+ sodipodi:cx="13.700194"
+ sodipodi:cy="207.20645"
+ sodipodi:r1="7.1873641"
+ sodipodi:r2="3.3158474"
+ sodipodi:arg1="0.94697287"
+ sodipodi:arg2="1.5618338"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 17.898641,213.04008 -4.168729,-2.51791 -4.280439,2.47993 1.106473,-4.74277 -3.6812884,-3.3046 4.8525664,-0.41328 2.005278,-4.52229 1.892578,4.48735 4.920618,0.50967 -3.682889,3.18662 z"
+ inkscape:transform-center-x="-0.010954063"
+ inkscape:transform-center-y="-0.74285516"
+ transform="matrix(1.0972098,0,0,1.0975406,-2.0923019,-19.740595)" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.06316817;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 12.931855,202.51514 -1.201334,2.70994 c -0.137665,0.32193 -0.454082,0.55986 -0.800889,0.60222 l -2.9032248,0.26765 2.2358168,1.97391 c 0.261321,0.2395 0.380487,0.62447 0.300333,0.97022 l -0.667408,2.81032"
+ id="path15869"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(-0.04936017,-0.02079917)"
+ style="display:inline;enable-background:new"
+ id="g16432">
+ <rect
+ y="199"
+ x="68"
+ height="16"
+ width="16"
+ id="rect23008-0"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ transform="translate(-129.04638,24.90625)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g11015-1">
+ <path
+ style="fill:url(#linearGradient15744-9-8);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 205.54638,177.59375 -1,0 0,9 1,0 5,-3.75 0,-1.5 z"
+ id="path11017-5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path11019-7"
+ d="m 205.54638,185.34375 0,-6.5 4.03125,3.01562"
+ style="fill:none;stroke:url(#linearGradient10982-8-5);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:url(#linearGradient16268-9);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect10822-0-7"
+ width="9.2000065"
+ height="2.1999984"
+ x="202.39999"
+ y="71.400002"
+ rx="0"
+ ry="1.4168683"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient16302-5);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 72.27078,203.33478 0.475194,-7e-5"
+ id="path10824-4-2"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="translate(-0.04936017,-0.02079917)"
+ style="display:inline;enable-background:new"
+ id="g16424">
+ <rect
+ transform="scale(-1,1)"
+ y="198.89999"
+ x="-62.900002"
+ height="16"
+ width="16"
+ id="rect23008-0-8"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline;enable-background:new"
+ transform="matrix(-1,0,0,1,259.94638,24.80625)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g11015-1-2">
+ <path
+ style="fill:url(#linearGradient15744-9-0-9);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 205.54638,177.59375 -1,0 0,9 1,0 5,-3.75 0,-1.5 z"
+ id="path11017-5-5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11019-7-9"
+ d="m 205.54638,178.84375 4.03125,3.01562"
+ style="fill:none;stroke:url(#linearGradient10982-8-9-5);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:url(#linearGradient16268-5-0);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;enable-background:new"
+ id="rect10822-0-7-7"
+ width="9.2000065"
+ height="2.1999984"
+ x="202.29999"
+ y="-59.5"
+ rx="0"
+ ry="1.4168683"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient16302-3-4);stroke-width:1.00000012px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 58.62922,203.23478 -0.475194,-7e-5"
+ id="path10824-4-2-3"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56653">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.95065,114.97921 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z m -1,3 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ style="opacity:0.3;color:#000000;fill:#0027b4;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18242" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path38437-9"
+ d="m 289.95065,114.97921 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path18240"
+ d="m 289.95065,120.97921 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g27975"
+ style="display:inline;enable-background:new"
+ transform="translate(-0.04936017,-0.02079917)">
+ <rect
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36400-0-73"
+ width="16"
+ height="16"
+ x="278"
+ y="115" />
+ <g
+ id="g36402-8-9"
+ transform="translate(186.99836,-42.1)">
+ <rect
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36426-6-8"
+ width="2.0000153"
+ height="2.0000069"
+ x="102"
+ y="170"
+ rx="0"
+ ry="0" />
+ <g
+ id="g36404-0-04"
+ style="stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(8.000015,151)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient27963-5);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 85.65162,18.243282 88.999985,16"
+ id="path36410-3-3"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36407-9-8"
+ d="m 88.999985,8 0,8"
+ style="fill:none;stroke:#00163c;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36412-3-7"
+ d="M 94.99997,20 88.999985,16"
+ style="fill:none;stroke:#5d0606;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <rect
+ ry="0"
+ rx="0"
+ y="158"
+ x="96"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36416-1-8"
+ style="fill:none;stroke:#001e50;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36418-7-2"
+ d="m 97,159 0,8"
+ style="fill:none;stroke:#4c8ff4;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient27965-1);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 93.15039,169.65379 3.794367,-2.66484"
+ id="path36420-1-8"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36424-2-5"
+ d="M 92.728285,169.42532 96.499985,166.75 96.5,159.5"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient27967-9);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36428-6-8"
+ d="M 102.99998,171 97,167"
+ style="fill:none;stroke:#ef4e29;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <rect
+ style="opacity:0.3;fill:none;stroke:#001e50;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36432-1-2"
+ width="2.0000153"
+ height="2.0000069"
+ x="96"
+ y="158"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#4c8ff4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36434-5-5"
+ width="2"
+ height="2"
+ x="96.000023"
+ y="158"
+ rx="0"
+ ry="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.3333333,0,0,1.3333343,3,147.66665)"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path36436-4-6"
+ style="opacity:0.5;fill:url(#radialGradient27969-8);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ sodipodi:ry="1.5"
+ sodipodi:rx="1.5"
+ sodipodi:cy="14.5"
+ sodipodi:cx="70.5"
+ id="path36438-7-62"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0.6666679,0,0,0.6666668,49.999915,157.33333)" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="102"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36440-7-5"
+ style="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="170"
+ x="102.00002"
+ height="2"
+ width="2"
+ id="rect36442-2-0"
+ style="fill:#eb512e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="opacity:0.8"
+ id="g36444-2-2">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient27971-9);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 96.5,159.5 0,-1 1,0"
+ id="path36446-6-0"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient27973-6);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 102.49999,171.5 0,-1 1,0"
+ id="path36450-1-8"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56628">
+ <g
+ transform="translate(-0.04936017,-1.0207992)"
+ id="g18315"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path18244-7"
+ style="opacity:0.3;color:#000000;fill:#45eb0a;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269,122 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z m 0,-6 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z" />
+ <path
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269,116 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path38437-9-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 269,122 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ id="path38435-3-8-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="114.97919"
+ x="256.95062"
+ height="16"
+ width="16"
+ id="rect36400-0"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-2.0730802,-0.12079917)"
+ id="g17954"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient17973-0);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 261.67372,127.26538 3.34836,-2.24328"
+ id="path36410-3-3-7"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36407-9"
+ d="m 264.99997,117 0,8"
+ style="fill:none;stroke:#00163c;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36412-3"
+ d="m 270.99996,129 -5.99999,-4"
+ style="fill:none;stroke:#183c00;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36420-1-8-8"
+ d="m 261.17248,127.67589 3.79437,-2.66484"
+ style="fill:none;stroke:url(#linearGradient17975-1);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:none;stroke:#001e50;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36416-1"
+ width="2.0000153"
+ height="2.0000069"
+ x="263.99997"
+ y="116"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4c8ff4;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 264.99998,117 0,8"
+ id="path36418-7"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient17977-8);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 260.75037,127.44742 3.7717,-2.67532 2e-5,-7.25"
+ id="path36424-2-5-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="128"
+ x="269.99997"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36426-6"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4ee420;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.99996,129 -5.99998,-4"
+ id="path36428-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="116"
+ x="263.99997"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36432-1"
+ style="opacity:0.3;fill:none;stroke:#001e50;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="116"
+ x="264"
+ height="2"
+ width="2"
+ id="rect36434-5"
+ style="fill:#4c8ff4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient17979-7);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36436-4"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.3333333,0,0,1.3333343,170.99998,105.66665)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6666679,0,0,0.6666668,217.99989,115.33333)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36438-7"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ style="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#183c00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36440-7"
+ width="2.0000153"
+ height="2.0000069"
+ x="269.99997"
+ y="128"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#4ee51f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36442-2"
+ width="2"
+ height="2"
+ x="270"
+ y="128"
+ rx="0"
+ ry="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient17981-0);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 264.49998,117.5 0,-1 1,0"
+ id="path36446-6"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.72000002;fill:none;stroke:url(#linearGradient17983-9);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 270.49997,129.5 0,-1 1,0"
+ id="path36450-1"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g56680">
+ <g
+ transform="translate(-0.04936017,-1.0207992)"
+ id="g18312"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ id="path11174-1-9"
+ style="opacity:0.3;color:#000000;fill:#f82516;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 311,122 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z m -1,-9 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z" />
+ </g>
+ <rect
+ y="114.97919"
+ x="298.95062"
+ height="16"
+ width="16"
+ id="rect36400-0-73-7"
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path38435-3-8"
+ d="m 310.95065,114.97921 0,2.25 1,0 0,2.75 1,0 0,-2.75 1,0 0,-2.25 -1,0 0,2 -1,0 0,-2 -1,0 z"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path18240-3"
+ d="m 310.95065,120.97921 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.95063983,-0.12079917)"
+ id="g27760"
+ style="display:inline;enable-background:new">
+ <rect
+ style="fill:none;stroke:#183c00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36416-1-8-5"
+ width="2.0000153"
+ height="2.0000069"
+ x="302.98999"
+ y="116"
+ rx="0"
+ ry="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="128"
+ x="308.98999"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36426-6-8-0"
+ style="fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36410-3-3-7-4"
+ d="m 300.65,127.2387 3.34836,-2.24328"
+ style="fill:none;stroke:url(#linearGradient27998-5);stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36407-9-8-3"
+ d="m 303.98998,117 0,8"
+ style="fill:none;stroke:#183c00;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:url(#linearGradient28000-5);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 300.14876,127.64921 3.79437,-2.66484"
+ id="path36420-1-8-8-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36412-3-7-3"
+ d="m 309.98997,129 -5.99999,-4"
+ style="fill:none;stroke:#5d0606;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#4ee420;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 303.98999,117 0,8"
+ id="path36418-7-2-5"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path36424-2-5-6-9"
+ d="m 299.72665,127.42074 3.7717,-2.67532 2e-5,-7.25"
+ style="opacity:0.3;fill:none;stroke:url(#linearGradient28002-1);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ef4e29;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 309.98997,129 -5.99998,-4"
+ id="path36428-6-8-8"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="116"
+ x="302.98999"
+ height="2.0000069"
+ width="2.0000153"
+ id="rect36432-1-2-2"
+ style="opacity:0.3;fill:none;stroke:#183c00;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0"
+ rx="0"
+ y="116"
+ x="302.99002"
+ height="2"
+ width="2"
+ id="rect36434-5-5-9"
+ style="fill:#4ee51f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:url(#radialGradient28004-7);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36436-4-6-0"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.3333333,0,0,1.3333343,209.98999,105.66665)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(0.6666679,0,0,0.6666668,256.9899,115.33333)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;enable-background:new"
+ id="path36438-7-62-3"
+ sodipodi:cx="70.5"
+ sodipodi:cy="14.5"
+ sodipodi:rx="1.5"
+ sodipodi:ry="1.5"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ style="opacity:0.3;fill:#acc373;fill-opacity:1;fill-rule:nonzero;stroke:#5d0606;stroke-width:1.79999995;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36440-7-5-9"
+ width="2.0000153"
+ height="2.0000069"
+ x="308.98999"
+ y="128"
+ rx="0"
+ ry="0" />
+ <rect
+ style="fill:#eb512e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.3499999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36442-2-0-6"
+ width="2"
+ height="2"
+ x="308.99002"
+ y="128"
+ rx="0"
+ ry="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36446-6-0-8"
+ d="m 303.5,117.51562 0,-1 1,0"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient28006-8);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path36450-1-8-0"
+ d="m 309.47793,129.48277 0,-1 1,0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient28008-2);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23018-5-4-2"
+ width="16"
+ height="16"
+ x="29.270542"
+ y="209.19434" />
+ <g
+ transform="translate(21.04936,0.02079773)"
+ style="display:inline;enable-background:new"
+ id="g14953-0">
+ <rect
+ y="198.9792"
+ x="4.9506397"
+ height="16"
+ width="16"
+ id="rect23018-5-4-4"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.94058502,0,0,0.94058502,0.9128606,12.74924)"
+ id="g56716-9">
+ <path
+ sodipodi:type="star"
+ style="fill:url(#linearGradient14951-4);fill-opacity:1;stroke:#341b00;stroke-width:0.96882826;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path15855-2"
+ sodipodi:sides="5"
+ sodipodi:cx="13.700194"
+ sodipodi:cy="207.20645"
+ sodipodi:r1="7.1873641"
+ sodipodi:r2="3.3158474"
+ sodipodi:arg1="0.94697287"
+ sodipodi:arg2="1.5618338"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 17.898641,213.04008 -4.168729,-2.51791 -4.280439,2.47993 1.106473,-4.74277 -3.6812884,-3.3046 4.8525664,-0.41328 2.005278,-4.52229 1.892578,4.48735 4.920618,0.50967 -3.682889,3.18662 z"
+ inkscape:transform-center-x="-0.010954063"
+ inkscape:transform-center-y="-0.74285516"
+ transform="matrix(1.0972098,0,0,1.0975406,-2.0923019,-19.740595)" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.06316817;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ d="m 12.931855,202.51514 -1.201334,2.70994 c -0.137665,0.32193 -0.454082,0.55986 -0.800889,0.60222 l -2.9032248,0.26765 2.2358168,1.97391 c 0.261321,0.2395 0.380487,0.62447 0.300333,0.97022 l -0.667408,2.81032"
+ id="path15869-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(189,-229)"
+ id="g22900-8"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22902-0"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904-5"
+ style="opacity:0.6;stroke:#162d50">
+ <path
+ style="opacity:0.9;fill:none;stroke:#2d3239;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906-2"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#2d3239;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908-5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.9;fill:none;stroke:#e4e9f0;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22910-1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:url(#linearGradient22933-6);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935-6);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914-3"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916-2"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937-4);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918-7"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920-0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922-0"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22924-2"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path22926-3"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#e4e9f0;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22939-8);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928-8"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931-5"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient17039);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(210,-229)"
+ id="g22900-8-5"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22902-0-6"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904-5-2"
+ style="opacity:0.6;stroke:#162d50" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="fill:url(#linearGradient22933-6-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912-6-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935-6-2);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914-3-7"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916-2-2"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937-4-1);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918-7-7"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920-0-4"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922-0-2"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22924-2-7"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22939-8-6);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928-8-6"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931-5-7"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient17172);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-42,-40)"
+ id="g22900-8-3"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22902-0-4"
+ width="16"
+ height="16"
+ x="257"
+ y="449" />
+ <g
+ transform="translate(14.081669,359)"
+ id="g22904-5-8"
+ style="opacity:0.6;stroke:#162d50">
+ <path
+ style="opacity:0.9;fill:none;stroke:#333333;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 253.41833,95.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906-2-2"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.9;fill:none;stroke:#333333;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 255.41833,93.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908-5-8"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="opacity:0.9;fill:none;stroke:#eaeaea;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 267.5,454.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22910-1-6"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ style="opacity:0.8;fill:url(#linearGradient22933-6-87);fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ d="m 264.58167,451.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ id="path22912-6-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22935-6-22);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 258.5,459.5 1,0 1,-1 3.25,3"
+ id="path22914-3-3"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22916-2-6"
+ d="m 260.5,454.5 0,4.9091"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient22937-4-8);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22918-7-5"
+ d="m 258.5,455.5 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 262.59506,453.5 1,-1"
+ id="path22920-0-8"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 258.5,454.63598 1,0"
+ id="path22922-0-0"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22924-2-2"
+ d="m 262.59506,454.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path22926-3-1"
+ d="m 269.5,452.5 c 2.75,2.75 2.75,6.25 0,9"
+ style="opacity:0.9;fill:none;stroke:#eaeaea;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient22939-8-3);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 263.5,452.5 0,9"
+ id="path22928-8-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22931-5-2"
+ d="m 258.5,454.3 0,5.4"
+ style="fill:none;stroke:url(#linearGradient17172-9);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g17563">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22902-0-2"
+ width="16"
+ height="16"
+ x="215"
+ y="430" />
+ <g
+ id="g17546">
+ <path
+ style="opacity:0.6;fill:none;stroke:#643200;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 227.5,433.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22908-5-0-4"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.6;fill:none;stroke:#633300;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 225.5,435.5 c 1.5,1.5 1.5,3.5 0,5"
+ id="path22906-2-9-6"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path22910-1-4"
+ d="m 225.5,435.5 c 1.5,1.5 1.5,3.5 0,5"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient17582);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22912-6-7"
+ d="m 222.58167,432.5 -1.08167,0 -3,3 c 0,-0.554 -0.446,-1 -1,-1 l -1,0 c -0.554,0 -1,0.446 -1,1 l 0,5 c 0,0.554 0.446,1 1,1 l 1,0 c 0.554,0 1,-0.446 1,-1 l 3,3 1.08167,0 0,-11 z"
+ style="fill:url(#linearGradient17584);fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.84313725;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path22914-3-6"
+ d="m 216.5,440.5 1,0 1,-1 3.25,3"
+ style="fill:none;stroke:url(#linearGradient17586);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.65263157;fill:none;stroke:url(#linearGradient17588);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 218.5,435.5 0,4.9091"
+ id="path22916-2-0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 216.5,436.5 1,0"
+ id="path22918-7-2" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path22920-0-2"
+ d="m 220.59506,434.5 1,-1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22922-0-22"
+ d="m 216.5,435.63598 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 220.59506,435.5 1,-1"
+ id="path22924-2-9"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient17590);stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.5,433.5 c 2.75,2.75 2.75,6.25 0,9"
+ id="path22926-3-9"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22928-8-7"
+ d="m 221.5,433.5 0,9"
+ style="fill:none;stroke:url(#linearGradient17592);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient17594);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 216.5,435.3 0,5.4"
+ id="path22931-5-72" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 225.37642,435.40307 0.60225,0.61872"
+ id="path22922-0-22-4"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ style="fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ d="m 227.40936,433.37013 0.51386,0.59663"
+ id="path22922-0-22-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ y="597"
+ x="383"
+ height="16"
+ width="16"
+ id="rect18740-5"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.78985507,0,0,0.78985507,384.77042,545.63116)"
+ id="g18742-8"
+ style="display:inline;enable-background:new">
+ <rect
+ y="70.999992"
+ x="4.9838772"
+ height="9.0000172"
+ width="11.999999"
+ id="rect38458-5"
+ style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccc"
+ style="fill:url(#linearGradient17715);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.01284409;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 17.209985,82.052175 -1.174018,1.202898 -10.0887566,0 -1.2028894,-1.202898 -1e-7,-12.622124 12.4766491,0 -0.01099,12.622124 -5e-6,0 0,0 z"
+ id="path18744-0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 15.536259,81.328571 -6.3832127,2e-6 0,-0.999998 6.3832127,-2e-6 0,0.999998 z"
+ id="path18746-7"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18748-3"
+ d="m 5.9039809,82.132474 0.025569,-11.527305 10.1868001,5.7e-5 0,11.527247 z"
+ style="fill:none;stroke:url(#linearGradient17717);stroke-width:1.26605475px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ y="80.356544"
+ x="6.7951851"
+ height="1"
+ width="1"
+ id="rect18750-1"
+ style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43488-2-2"
+ transform="matrix(0,-0.75485957,0.75485957,0,327.67313,852.33908)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.57682419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 326.98536,85.889717 327,76"
+ id="path43490-2-2"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.57682419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 330.97424,79.255626 -3.97425,-3.974249 -3.97424,3.974249"
+ id="path43492-1-0"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g43494-2-5"
+ transform="matrix(0,-0.75485957,0.75485957,0,327.67313,852.33908)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path43496-7-5"
+ d="M 327,85.889717 327,76"
+ style="fill:none;stroke:#ebebeb;stroke-width:1.72217464;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path43498-9-6"
+ d="m 330.97424,79.255626 -3.97425,-3.974249 -3.97424,3.974249"
+ style="fill:none;stroke:#ebebeb;stroke-width:1.72217464;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.32474971;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 330.97424,79.255626 -2.24089,-2.206598"
+ id="path17874"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g17941">
+ <rect
+ transform="scale(-1,1)"
+ y="220.00047"
+ x="-546"
+ height="16"
+ width="16"
+ id="rect14357-6"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17935">
+ <rect
+ style="fill:#ec0606;fill-opacity:1;fill-rule:nonzero;stroke:#910000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43394-5-7"
+ width="6"
+ height="2"
+ x="540.12811"
+ y="231.61429"
+ rx="0.79505396"
+ ry="0.79505396" />
+ <path
+ sodipodi:nodetypes="czszcccc"
+ id="path14368-1"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;display:inline"
+ d="m 542.6613,230.54031 -4.34213,0.008 c -5.18824,0.0101 -5.3353,-2.04831 -3.33529,-4.04831 0.96487,-0.96488 3.61611,-2.89515 -1.50001,-5 m 6.83689,6.08925 2.34054,2.95106 m -2.32899,2.96017 2.32899,-2.96017"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 542.6613,230.54031 -4.34213,0.008 c -5.18824,0.0106 -5.3353,-2.04783 -3.33529,-4.04783 0.96487,-0.96488 3.83708,-2.76256 -1.50001,-5 m 6.83689,6.08877 2.34054,2.95106 m -2.32899,2.96017 2.32899,-2.96017"
+ style="fill:none;stroke:url(#linearGradient17932);stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000034;display:inline"
+ id="path14375-4"
+ sodipodi:nodetypes="czszcccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0.79505396"
+ rx="0.79505396"
+ y="220.375"
+ x="530.3125"
+ height="2"
+ width="6"
+ id="rect43396-5-4"
+ style="fill:#6996d7;fill-opacity:1;fill-rule:nonzero;stroke:#143564;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <g
+ id="g20086">
+ <rect
+ y="598"
+ x="299"
+ height="16"
+ width="16"
+ id="rect25569-8"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(1.1,-0.09992002)"
+ id="g20068">
+ <rect
+ y="605.5"
+ x="-312.5"
+ height="7.0000267"
+ width="10"
+ id="rect15044-4"
+ style="fill:url(#linearGradient20080);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="scale(-1,1)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15046-4"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 304.49848,605.5625 0,-2 c 0,-2 -0.62933,-3 -2.51731,-3.00008 -1.2779,5e-5 -2.17039,0.23501 -2.53494,1.78073"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient20199);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 304.49848,605.5625 0,-2.25 c 0,-1.75 -0.62933,-2.75 -2.51734,-2.75008 -1.27677,5e-5 -2.05659,0.20629 -2.29807,1.20103"
+ id="path15049-9"
+ sodipodi:nodetypes="cscc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ ry="0"
+ rx="0"
+ y="606.5"
+ x="303.5"
+ height="5"
+ width="8"
+ id="rect15051-2"
+ style="fill:none;stroke:url(#linearGradient20084);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19016-6"
+ d="m 304,607.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 304,609.5 7.5,0"
+ id="path19018-0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19020-2"
+ d="m 304,611.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36041-6"
+ width="1"
+ height="2.0000124"
+ x="307"
+ y="608" />
+ <rect
+ y="608"
+ x="307"
+ height="0.99994379"
+ width="0.99998754"
+ id="rect36043-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 308,608 0,2 -1,0 0,1 1,0 1,0 0,-1 0,-2 -1,0 z"
+ id="path36045-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(21,0)"
+ style="display:inline;enable-background:new"
+ id="g20086-7">
+ <rect
+ y="598"
+ x="299"
+ height="16"
+ width="16"
+ id="rect25569-8-3"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(1.1,-0.09992002)"
+ id="g20068-2">
+ <rect
+ y="605.5"
+ x="-312.5"
+ height="7.0000267"
+ width="10"
+ id="rect15044-4-1"
+ style="fill:url(#linearGradient20080-5);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="scale(-1,1)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15046-4-9"
+ style="fill:none;stroke:#000000;stroke-width:2.79999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 310.5,605.5 0,-2 c 0,-2 -0.75,-3 -3,-3.00008 -2.25,8e-5 -3,1.00008 -3,3.00008 l 0,2"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient20082-4);stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 310.5,605.5 c 0,0 0,-2.25 0,-2.25 0,-1.75 -0.75,-2.75 -3.00003,-2.75008 C 305.25,600.5 304.5,601.5 304.5,603.25 l 0,2.25005"
+ id="path15049-9-8"
+ sodipodi:nodetypes="csccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ ry="0"
+ rx="0"
+ y="606.5"
+ x="303.5"
+ height="5"
+ width="8"
+ id="rect15051-2-5"
+ style="fill:none;stroke:url(#linearGradient20084-9);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19016-6-0"
+ d="m 304,607.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 304,609.5 7.5,0"
+ id="path19018-0-2" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path19020-2-9"
+ d="m 304,611.5 7.5,0"
+ style="opacity:0.5;fill:none;stroke:#939dac;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36041-6-4"
+ width="1"
+ height="2.0000124"
+ x="307"
+ y="608" />
+ <rect
+ y="608"
+ x="307"
+ height="0.99994379"
+ width="0.99998754"
+ id="rect36043-2-8"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 308,608 0,2 -1,0 0,1 1,0 1,0 0,-1 0,-2 -1,0 z"
+ id="path36045-7-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-105.02687,272.93951)"
+ style="display:inline;enable-background:new"
+ id="g17107">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18696-0-4-1"
+ width="16"
+ height="16"
+ x="299"
+ y="325" />
+ <g
+ id="g17099">
+ <path
+ style="fill:url(#linearGradient16783-1-6-0-2);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="M 309.7702,332.24765 304.5,337.5 l -1,0 -1,1 -1,0 0,-1 1,-1 0,-1 5.2702,-5.25235 z"
+ id="path18700-1-3-9"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccc"
+ id="path17007-7"
+ d="M 309.7702,332.24765 304.5,337.5 l -1,0 -1,1 -1,0 0,-1 1,-1 0,-1 5.2702,-5.25235 z"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccszsccc"
+ id="path18711-5-8-1"
+ d="m 310.5,333.5 0,-2.75 c 1.1224,0 1.75,0 2.5,-0.75 0.75,-0.75 0.75,-2.25 0,-3 -0.75,-0.75 -2.25,-0.75 -3,0 -0.75,0.75 -0.75,1.49506 -0.75,2.5 l -2.75,0 4,4 z"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-x="-1.4435745"
+ inkscape:transform-center-y="-1.4192649"
+ style="fill:url(#linearGradient16778-3-5-3-2);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 309.22323,329.79745 c -0.11594,-0.12547 0.0486,-1.2642 0.81343,-2.11918 1.04731,-1.1688 1.89745,-0.8692 1.99021,-0.61778 1.02063,2.76644 -1.73024,3.89859 -2.80364,2.73696 z"
+ id="path18713-4-2-0"
+ sodipodi:nodetypes="csss"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path18715-9-8-1"
+ d="m 308.26612,330.5 c 0,0 0.25,0 0.25,0 l 0,-1"
+ style="opacity:0.98000004;fill:none;stroke:url(#linearGradient16775-4-9-5-6);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 303.25,335.75 4.17237,-4.0625"
+ id="path18705-8-4-0"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-42,231)"
+ style="display:inline;enable-background:new"
+ id="g17942-1">
+ <rect
+ y="304"
+ x="278"
+ height="16"
+ width="16"
+ id="rect22048-0-1-2"
+ style="opacity:0.01000001;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17930-6">
+ <rect
+ y="305.5"
+ x="281.5"
+ height="6.0211244"
+ width="9.0000076"
+ id="rect22050-0-1-6"
+ style="opacity:0.6;fill:#ffd6aa;fill-opacity:1;fill-rule:evenodd;stroke:#2b1600;stroke-width:0.40000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22056-3-7-1"
+ d="m 282.5,316.5 3,3 3,-3 -3,-3 -3,3 z"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 282.75,316.5 2.75,2.75 2.75,-2.75 -2.75,-2.75 -2.75,2.75 z"
+ id="path22058-8-8-7"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22060-3-9-9"
+ d="m 283.5,316.5 2,-2 2,2 -2,2 -2,-2 z"
+ style="fill:none;stroke:url(#linearGradient18148);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path22157-2-9-1"
+ d="m 287.75,308.25 0,0.5 2.5,2.5 0.5,0 2.5,-2.5 0,-0.5 -2.5,-2.5 -0.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#552c00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e98316;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 288,308.5 2.5,2.5 2.5,-2.5 -2.5,-2.5 -2.5,2.5 z"
+ id="path22159-1-9-5"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path22161-4-8-9"
+ d="M 288.64504,308.5 290.5,306.66161 292.35496,308.5 290.5,310.36049 z"
+ style="fill:none;stroke:url(#linearGradient17904-1);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 278.75,308.25 0,0.5 2.5,2.5 0.5,0 2.5,-2.5 0,-0.5 -2.5,-2.5 -0.5,0 -2.5,2.5 z"
+ id="path22208-0-8-1"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path22212-5-4-4"
+ d="m 279,308.5 2.5,2.5 2.5,-2.5 -2.5,-2.5 z"
+ style="fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ style="fill:none;stroke:url(#linearGradient17893-5);stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 279.64062,308.5 281.5,306.66406 283.35547,308.5 281.5,310.375 z"
+ id="path22214-3-8-8"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18831-4-3"
+ width="16"
+ height="16"
+ x="467"
+ y="451" />
+ <g
+ id="g16806">
+ <rect
+ y="472"
+ x="257"
+ height="16"
+ width="16"
+ id="rect35680"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:transform-center-y="2.2787562"
+ inkscape:transform-center-x="-0.78726"
+ id="g35844"
+ transform="translate(-186,256.02369)"
+ style="opacity:0.9;display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35846"
+ d="m 454.5,218.5 c -1.25,-1.5 -2.5,-1.5 -4,1 -1.5,-2.5 -2.75,-2.5 -4,-1"
+ style="opacity:0.85;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#f2f2f2;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 454.5,218.5 c -1.25,-1.5 -2.5,-1.5 -4,1 -1.5,-2.5 -2.75,-2.5 -4,-1"
+ id="path35848"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path35862"
+ d="m 264.5,485.5 -1,-1 -2,2 -2,-2 -1,1.02369"
+ style="opacity:0.76499999;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 264.5,485.5 -1,-1 -2,2 -2,-2 -1,1.02369"
+ id="path35864"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(-21,21)"
+ id="g38276">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.85;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 292.5,459.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ id="path35702"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35704"
+ d="m 292.5,459.5 c -1.25,-1.5 -3.5,-1.5 -5,1 -1.5,-2.5 -3.75,-2.5 -5,-1"
+ style="fill:none;stroke:#ececec;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ d="m 266.53125,480.65625 -0.0312,0.9375 m -0.85937,-1.07813 c 0.49634,0.0684 0.8328,0.24341 1.79687,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path16745" />
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ d="m 264.46875,474.79687 -0.0312,0.9375 m -0.85937,-1.07813 c 0.49634,0.0684 0.8328,0.24341 1.79687,0"
+ style="fill:none;stroke:#f0f0f0;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ id="path16745-9" />
+ </g>
+ <g
+ id="g37076-6-0-2"
+ style="opacity:0.96000001;stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
+ transform="translate(127.00485,107.03779)" />
+ <g
+ style="opacity:0.96000001;stroke:#c8c8c8;stroke-opacity:1;display:inline;enable-background:new"
+ id="g37094-7-8-1"
+ transform="translate(190.00485,-60.962214)">
+ <g
+ transform="translate(-63.000001,168)"
+ id="g37096-1-5-3"
+ style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <g
+ id="g37104-2-9-1"
+ transform="matrix(0,1,-1,0,511,255)"
+ style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <rect
+ style="opacity:0.01000001;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect45374-0"
+ width="16"
+ height="16"
+ x="383"
+ y="430" />
+ <g
+ transform="translate(105,0)"
+ style="opacity:0.3;display:inline;enable-background:new"
+ id="g17847-0">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path45378-1-5-0"
+ d="m 367.75,440.75 1.75,-1.5 2.5,5.25 1.75,-1 -2.25,-5 2.5,0 -6.25,-6.25 z"
+ style="fill:url(#linearGradient17833-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="430"
+ x="362"
+ height="16"
+ width="16"
+ id="rect45374-0-5-0"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ id="path17835-6"
+ d="m 367.5,431.5 7,7.25 -3,0 2.5,4.75 -1.75,1 -2.5,-5 -2.25,2.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path17845-4"
+ d="m 368.34375,433.75 0,5.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(84,0)"
+ style="display:inline;enable-background:new"
+ id="g17847-9">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path45378-1-5-6"
+ d="m 367.75,440.75 1.75,-1.5 2.5,5.25 1.75,-1 -2.25,-5 2.5,0 -6.25,-6.25 z"
+ style="fill:url(#linearGradient17833-8);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="430"
+ x="362"
+ height="16"
+ width="16"
+ id="rect45374-0-5-6"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ id="path17835-7"
+ d="m 367.5,431.5 7,7.25 -3,0 2.5,4.75 -1.75,1 -2.5,-5 -2.25,2.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path17845-9"
+ d="m 368.34375,433.75 0,5.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g10534-1"
+ transform="translate(189.0161,-397)">
+ <rect
+ y="428"
+ x="193.9839"
+ height="16"
+ width="16"
+ id="rect20642-6"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(-29.016109,339.00751)"
+ id="g20606-2">
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10953-7">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ style="fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.25,-1.53125 -1,-1 -1.53125,1.25 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ id="path10955-5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc"
+ id="path10957-4"
+ d="m 429.9998,196.99249 0,1.625 c -0.53409,0.12195 -1.02562,0.33162 -1.46875,0.625 l -1.53125,-1.25 -1,1 1.25,1.53125 c -0.29338,0.44313 -0.50305,0.93466 -0.625,1.46875 l -1.625,0 0,2 1.625,0 c 0.12195,0.53409 0.33162,1.02562 0.625,1.46875 l -1.25,1.53125 1,1 1.53125,-1.25 c 0.44313,0.29338 0.93466,0.50305 1.46875,0.625 l 0,1.625 2,0 0,-1.625 c 0.53409,-0.12195 1.02562,-0.33162 1.46875,-0.625 l 1.53125,1.25 1,-1 -1.25,-1.53125 c 0.29338,-0.44313 0.50305,-0.93466 0.625,-1.46875 l 1.625,0 0,-2 -1.625,0 c -0.12195,-0.53409 -0.33162,-1.02562 -0.625,-1.46875 l 1.5,-1.78125 -1,-1 -1.78125,1.5 c -0.44313,-0.29338 -0.93466,-0.50305 -1.46875,-0.625 l 0,-1.625 -2,0 z m -1,4 4,0 0,4 -4,0 0,-4 z"
+ style="fill:url(#linearGradient20796-9);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 434.9998,198.49249 -1.5,1.25 m -2,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.01806,0.29269 -1.5172,0.50569 m -1.49,1.50752 c -0.20864,0.49552 -0.41426,1.14284 -0.4928,1.48679 l -1.5,0 0,1 m 1.5,-5 -0.5,0.5 m 1.25,6.5 -1.25,1.5 m 6.5,-5.5 0,3.5 -3.5,0 m -3,-6 0.5,-0.5 1.5,1.25"
+ style="fill:none;stroke:#f9f9f9;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
+ id="path10959-0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="translate(-199.98388,-106)"
+ id="g10961-1">
+ <rect
+ ry="0"
+ rx="0"
+ y="202.46629"
+ x="430.49979"
+ height="8.1236582"
+ width="7.0000763"
+ id="rect10963-2"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ d="m 432.53795,204.5065 2.96201,0 m -2.96201,1.993 2.96201,0 m -2.96201,1.993 2.96201,0"
+ style="fill:none;stroke:#000000;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ id="path10965-7"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ rx="0"
+ y="202.48912"
+ x="430.49661"
+ height="8.0067444"
+ width="7.0067482"
+ id="rect10967-1"
+ style="fill:none;stroke:url(#linearGradient20798-1);stroke-width:0.99325603;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g79830">
+ <rect
+ y="73"
+ x="467"
+ height="16"
+ width="16"
+ id="rect52984-1"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g79032">
+ <g
+ style="display:inline;enable-background:new"
+ id="g39239-9"
+ transform="translate(-285,-131)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path39241-0"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="fill:url(#linearGradient39254-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.3;fill:url(#radialGradient39256-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path39243-2"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ style="fill:none;stroke:url(#linearGradient39258-9);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ id="path39245-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ id="path39247-4"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path39249-3"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path39251-7"
+ d="m 757.5,206.5 0,2 -2,0"
+ style="fill:none;stroke:url(#linearGradient16151);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccssc"
+ inkscape:connector-curvature="0"
+ id="path52980-3"
+ d="m 481.21875,81.25 c -0.34507,-0.155271 -0.69504,-0.245578 -1.125,-0.34375 L 479.9375,79 l -1,0 -1,0 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.75 -1.75,1.75 1.75,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L 471.9375,85 l 0,1 0,1 1.90625,0.15625 c 0.092,0.4031 0.17505,0.738019 0.3125,1.0625 m 2.96875,0 C 476.47574,87.692174 476.0625,86.902037 476.0625,86 c 0,-1.58782 1.28718,-2.875 2.875,-2.875 0.94357,0 1.75793,0.454854 2.28125,1.15625"
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path52982-4"
+ d="m 477.9375,79 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.5 -1.5,1.5 1.5,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L 471.9375,85 l 0,1 0,1 1.90625,0.15625 c 0.0981,0.429533 0.18992,0.780253 0.34375,1.125 l 2.8125,0 C 476.34893,87.730943 475.9375,86.919238 475.9375,86 c 0,-1.65685 1.34315,-3 3,-3 0.96105,0 1.7947,0.453338 2.34375,1.15625 l 0,-2.875 c -0.36595,-0.173211 -0.73124,-0.270823 -1.1875,-0.375 L 479.9375,79 l -1,0 -1,0 z m 3.34375,8.8125 c -0.12902,0.1662 -0.24569,0.333041 -0.40625,0.46875 l 0.40625,0 0,-0.46875 z"
+ style="color:#000000;fill:url(#linearGradient79029);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0"
+ id="rect52986-8"
+ d="M 481.28125,83.40625 C 480.661,82.839183 479.84801,82.5 478.9375,82.5 c -1.93397,0 -3.5,1.566029 -3.5,3.5 0,0.881253 0.34008,1.6682 0.875,2.28125"
+ style="fill:none;stroke:url(#linearGradient79025);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path52988-6"
+ d="m 476.4375,81.75 c 0.49914,-0.213 1.64896,-0.6698 2,-0.75 l 0,-0.75 0,-0.75 1,0 m -5.25,1.25 -0.5,0.5 z m 0.5,2.75 c -0.20864,0.49552 -0.6715,1.65605 -0.75,2 l -0.75,0 -0.75,0 0,1"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 473.43328,81.74394 1.25,-1.25"
+ id="path52990-8"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0"
+ id="rect52992-4"
+ d="M 481.28125,83.40625 C 480.661,82.839183 479.84801,82.5 478.9375,82.5 c -1.93397,0 -3.5,1.566029 -3.5,3.5 0,0.881253 0.34008,1.6682 0.875,2.28125"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient79020);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 468.49796,75.999224 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path39249-3-7"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <g
+ transform="translate(-42.000002,-84)"
+ style="display:inline;enable-background:new"
+ id="g81158-5">
+ <rect
+ y="325"
+ x="299"
+ height="16"
+ width="16.000002"
+ id="rect44300-0-5-3-4"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g81149-2">
+ <path
+ sodipodi:nodetypes="cssssssssssssssscssc"
+ inkscape:connector-curvature="0"
+ id="path41299-1-2-7-4-0"
+ d="m 306.46211,325.45009 c -1.82601,0 -3.30699,1.48105 -3.30699,3.30711 0,0.25952 0.0379,0.51035 0.087,0.75425 0.18833,0.93505 0.24637,1.73179 -0.11603,2.43677 -0.32404,0.63034 -0.67881,0.97731 -1.45039,1.27638 -1.27734,0.49511 -2.17564,1.6304 -2.17564,3.04602 0,0.7411 0.24647,1.42826 0.6672,1.97265 0.21236,0.27479 0.1962,0.24789 0.29008,0.34806 0.60044,0.64074 1.56724,0.98341 2.29168,0.95729 0.74932,-0.027 1.28404,-0.28854 1.8855,-0.60911 0.58287,-0.31066 0.97831,-0.70633 1.82755,-0.69624 0.70498,0.008 1.33214,0.39548 1.88546,0.75426 0.55206,0.35795 1.29426,0.55886 1.8275,0.55114 1.8258,-0.0264 3.30697,-1.48104 3.30697,-3.30711 0,-1.23932 -0.68675,-2.33495 -1.71151,-2.87196 -0.78932,-0.41364 -1.71989,-0.83441 -2.11757,-1.47945 -0.44817,-0.72695 0.029,-2.46582 0.029,-2.46582 0.0441,-0.21523 0.087,-0.43896 0.087,-0.66722 0,-1.82606 -1.48098,-3.30711 -3.30698,-3.30711 z"
+ style="fill:url(#linearGradient80406-8);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.89999998;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cscsscc"
+ inkscape:connector-curvature="0"
+ id="path15475-1-1-9"
+ d="m 306.46211,326.3494 c -1.34707,0 -2.40772,1.06069 -2.40772,2.4078 0,0.17324 0.0147,0.36498 0.058,0.5802 0.2006,0.99599 0.30102,2.03645 -0.20306,3.017 -0.3838,0.74661 -1.01301,1.33313 -1.91455,1.68257 -0.98238,0.38077 -1.59548,1.19286 -1.59548,2.23374 0.0793,1.22982 0.59501,1.65939 1.12899,2.05552"
+ style="fill:none;stroke:url(#linearGradient80403-6);stroke-width:0.99999988;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 306.5,333.5 -4,3 m 4,-3 4,3 m -4,-8 0,5"
+ style="fill:none;stroke:#acc1f5;stroke-width:2.29999995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path16558"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path15730-0-3-9-7"
+ style="fill:none;stroke:#474747;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 306.5,333.5 -4,3 m 4,-3 4,3 m -4,-8 0,5" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-8-3"
+ width="2.0172396"
+ height="2.0000157"
+ x="305.48901"
+ y="327.52499" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-82-7"
+ width="2.0172396"
+ height="2.0000157"
+ x="301.52026"
+ y="335.49374" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-9-2"
+ width="2.0172396"
+ height="2.0000157"
+ x="309.49374"
+ y="335.49374" />
+ <rect
+ style="fill:#d7e3f4;fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline;enable-background:new"
+ id="rect16285-9-59-6-1-6"
+ width="2.0172396"
+ height="2.0000157"
+ x="305.52499"
+ y="332.52499" />
+ </g>
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#000000;stroke-width:0.9560194;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path81543"
+ sodipodi:cx="478.90625"
+ sodipodi:cy="86.03125"
+ sodipodi:rx="2.34375"
+ sodipodi:ry="2.34375"
+ d="m 478.63139,88.358828 a 2.34375,2.34375 0 1 1 2.61786,-2.38697"
+ transform="matrix(1.0460001,0,0,1.0460077,-22.029739,-4.0047766)"
+ sodipodi:start="1.6883393"
+ sodipodi:end="6.2578421"
+ sodipodi:open="true" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g16724-8-3">
+ <rect
+ y="598"
+ x="152"
+ height="16"
+ width="16"
+ id="rect38813-3-2"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,76.587007,362.72598)"
+ id="g10876-8-5-8-64-4"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient16663-3-0-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 226.05286,111.6246 3.53553,0 1e-5,-3.53553 2.82843,0 0,3.53553 3.53553,0 -1e-5,2.82843 -3.53553,0 0,3.53553 -2.82843,0 0,-3.53553 -3.53553,0 z"
+ id="path10878-4-0-1-4-6"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16661-5-1-6"
+ d="m 235.06847,113.56915 0,-1.06066"
+ style="fill:none;stroke:#d4d4d4;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16659-5-9-6"
+ d="m 230.47227,114.62981 0,2.47487"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16657-8-5-2"
+ d="m 230.47227,108.97295 0,2.47488"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path10880-7-5-7-5-9"
+ d="m 226.93674,112.50849 0,1.06066"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ transform="translate(252,21)"
+ style="display:inline;enable-background:new"
+ id="g16724-8-1">
+ <rect
+ y="598"
+ x="152"
+ height="16"
+ width="16"
+ id="rect38813-3-1"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,76.587007,362.72598)"
+ id="g10876-8-5-8-64-9"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:url(#linearGradient16663-3-0-0);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 224.63864,111.6246 4.94975,0 0,-4.94974 2.82843,0 1e-5,4.94974 4.94973,0 -1e-5,2.82843 -4.94973,0 0,4.94975 -2.82843,0 0,-4.94975 -4.94975,0 z"
+ id="path10878-4-0-1-4-9"
+ sodipodi:nodetypes="ccccccccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16661-5-1-5"
+ d="m 236.48268,113.56915 0,-1.06066"
+ style="fill:none;stroke:#d4d4d4;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16659-5-9-5"
+ d="m 230.47227,114.62981 0,3.88908"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path16657-8-5-5"
+ d="m 230.47227,107.55874 0,3.88909"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path10880-7-5-7-5-6"
+ d="m 225.52253,112.50849 0,1.06066"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ id="g106636"
+ transform="translate(0.1767767,0.13258252)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path45378-1-5-6-2-9"
+ d="m 263.5625,590.375 1.75,-1.5 1.99177,3.7253 1.75,-1 -1.74177,-3.4753 2.5,0 -6.25,-6.25 z"
+ style="fill:url(#linearGradient106641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ id="path17835-7-2-5"
+ d="m 263.3125,581.125 7,7.25 -3,0 1.69346,3.25845 -1.75,1 -1.69346,-3.50845 -2.25,2.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path17845-9-1-1"
+ d="m 264.15625,583.375 0,5.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(0.02855492,0)"
+ style="display:inline;enable-background:new"
+ id="g15868-5">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18695-6-9-6"
+ width="15.971445"
+ height="16.000002"
+ x="110"
+ y="241" />
+ <g
+ id="g15853-0">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path15095-5"
+ d="m 117.9106,247.99675 0.007,7.98875 -5.98631,-3.26708 -0.0121,-7.34356 z"
+ style="opacity:0.63859648;fill:url(#radialGradient15836-5);fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path18719-6-9-0"
+ d="m 117.94049,242.95683 -5.85545,2.34692 6.10637,2.4934 -0.17358,8.22275 6.00064,-3.2989 0.0442,-7.36753 z"
+ style="fill:url(#linearGradient15851-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18703-4-7-7"
+ transform="matrix(1.2133883,0,0,1.2133883,-65.271004,156.45833)">
+ <path
+ id="path18707-3-8-5"
+ d="m 146.0019,73.295281 5,-2.007976 5,2.007976 -5,2.073959 z"
+ style="fill:url(#linearGradient15818-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path18763-2-5-8"
+ d="m 124.01757,245.38766 -6.11113,2.33515 0.39771,8.10095 5.71891,-3.11585 z"
+ style="fill:url(#linearGradient15846-4);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path18709-1-1-0"
+ d="m 114.36329,244.98044 3.58667,-1.46751 5.56035,2.22692 0.0356,6.65202 -4.34973,2.45342"
+ style="fill:none;stroke:url(#linearGradient15843-2);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18737-4-8-8"
+ style="opacity:0.7"
+ transform="matrix(1.2133883,0,0,1.2133883,-282.46751,373.65484)" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path15957-6"
+ d="m 118.29703,256.35166 5.94799,-3.23942 c 0.0419,-0.0185 0.0806,-0.0443 0.11369,-0.0758 0.0689,-0.0703 0.11042,-0.16699 0.1137,-0.26543 l -0.0379,-7.432 c 10e-4,-0.16462 -0.1103,-0.32426 -0.26543,-0.37919 l -6.06694,-2.42677 c -0.0474,-0.0224 -0.0992,-0.0354 -0.15167,-0.0379 l 1.2e-4,0 c -0.0524,0.002 -0.10423,0.0154 -0.15167,0.0379 l -5.53168,2.30782"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.4429636"
+ inkscape:original="M 111.90625 245.375 L 111.9375 252.71875 L 117.90625 256 L 117.90625 248 L 111.90625 245.375 z "
+ style="fill:none;stroke:url(#linearGradient16730);stroke-width:0.89999998;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path16571-2"
+ d="m 111.78125,244.9375 a 0.4430079,0.4430079 0 0 0 -0.3125,0.4375 l 0.0312,7.34375 a 0.4430079,0.4430079 0 0 0 0.21875,0.375 l 5.96875,3.28125 A 0.4430079,0.4430079 0 0 0 118.34375,256 l 0,-8 a 0.4430079,0.4430079 0 0 0 -0.25,-0.40625 l -6,-2.625 a 0.4430079,0.4430079 0 0 0 -0.3125,-0.0312 z" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient16562-7);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.31869,255.08504 -4.89325,-2.67466 -0.0154,-6.1798"
+ id="path16560-5"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="opacity:0.75333408;fill:none;stroke:url(#linearGradient15773-7);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.38888891"
+ d="m 112.44393,252.43208 3.76322,-1.57568"
+ id="path15671-3"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ <path
+ d="m -220,198.65625 -5.3125,8.6875 5.3125,3 5.28125,-3.0625 -5.28125,-8.625 z"
+ id="path29747"
+ style="opacity:0.55438597;fill:none;stroke:url(#linearGradient29763);stroke-width:1.14285719;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M -220 196.6875 L -226.71875 207.6875 L -220 211.5 L -213.3125 207.625 L -220 196.6875 z "
+ inkscape:radius="-1.0141826"
+ sodipodi:type="inkscape:offset" />
+ <g
+ id="g30046">
+ <rect
+ ry="0"
+ y="346"
+ x="5"
+ height="16"
+ width="16"
+ id="rect22783-6-9"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g29741"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient107138);fill-opacity:1;stroke:#5a130a;stroke-width:0.87646502;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path107107"
+ sodipodi:cx="12.90625"
+ sodipodi:cy="354.09375"
+ sodipodi:rx="2.46875"
+ sodipodi:ry="2.46875"
+ d="m 15.375,354.09375 a 2.46875,2.46875 0 1 1 -4.9375,0 2.46875,2.46875 0 1 1 4.9375,0 z"
+ transform="matrix(1.0268522,0,0,1.0268522,-0.28026938,-9.574472)" />
+ <path
+ d="m 15.375,354.09375 a 2.46875,2.46875 0 1 1 -4.9375,0 2.46875,2.46875 0 1 1 4.9375,0 z"
+ sodipodi:ry="2.46875"
+ sodipodi:rx="2.46875"
+ sodipodi:cy="354.09375"
+ sodipodi:cx="12.90625"
+ id="path107109"
+ style="fill:none;stroke:url(#linearGradient107140);stroke-width:1.17894268;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:0.52659577;stroke-dasharray:none;display:inline;enable-background:new"
+ sodipodi:type="arc"
+ transform="matrix(0.67857417,0,0,0.67857417,4.2225059,113.7564)" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 11.5,347.5 3,0"
+ id="path107322"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 11.5,360.5 3,0"
+ id="path107322-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 19.5,352.5 0,3"
+ id="path107322-9-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 6.5,352.5 0,3"
+ id="path107322-9-7-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 9.5606602,348.43934 -2.1213204,2.12132"
+ id="path107322-9-7-0-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 18.455806,357.38951 -2.12132,2.12132"
+ id="path107322-9-7-0-2-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 7.4688155,357.37826 2.12132,2.12132"
+ id="path107322-9-7-0-2-6-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 16.440233,348.49523 2.12132,2.12132"
+ id="path107322-9-7-0-2-6-1-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107450"
+ d="m 11.5,347.5 3,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107452"
+ d="m 11.5,360.5 3,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107454"
+ d="m 19.5,352.5 0,3"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107456"
+ d="m 6.5,352.5 0,3"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107458"
+ d="m 9.5606602,348.43934 -2.1213204,2.12132"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107460"
+ d="m 18.455806,357.38951 -2.12132,2.12132"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107462"
+ d="m 7.4688155,357.37826 2.12132,2.12132"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path107464"
+ d="m 16.440233,348.49523 2.12132,2.12132"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ </g>
+ </g>
+ <g
+ id="g30162">
+ <rect
+ ry="0"
+ y="346"
+ x="47"
+ height="16"
+ width="16"
+ id="rect22783-6"
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g30155">
+ <path
+ sodipodi:type="spiral"
+ style="fill:none;stroke:#1e1e1e;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path107466"
+ sodipodi:cx="56.5"
+ sodipodi:cy="353.8125"
+ sodipodi:expansion="0.63999999"
+ sodipodi:revolution="1.495979"
+ sodipodi:radius="7.3200541"
+ sodipodi:argument="-15.806237"
+ sodipodi:t0="0.095484339"
+ d="m 55.364822,352.64547 c 0.277148,-1.52497 2.279864,-1.6606 3.365012,-1.00195 1.811369,1.09946 1.937,3.62806 0.742803,5.22502 -1.598463,2.13758 -4.749991,2.24309 -6.743742,0.61214 -2.453842,-2.00732 -2.540329,-5.74156 -0.524915,-8.08474 2.369057,-2.75434 6.645845,-2.82434 9.3087,-0.45931 1.163266,1.03316 1.955747,2.44812 2.251586,3.97386"
+ transform="matrix(-1,0,0,1,112.28991,0.1875)"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ transform="matrix(-1,0,0,1,112.28991,0.1875)"
+ d="m 55.363791,352.64255 c 0.279362,-1.52663 2.284601,-1.66081 3.370811,-1.00022 1.812759,1.10247 1.936516,3.63442 0.739426,5.2325 -1.602239,2.13895 -4.757809,2.24207 -6.752762,0.60744 -2.455246,-2.01179 -2.538856,-5.75071 -0.519059,-8.09518 2.374165,-2.75579 6.656232,-2.82247 9.32045,-0.45241 1.457306,1.2964 2.314544,3.17928 2.379814,5.12465"
+ sodipodi:t0="0.093999997"
+ sodipodi:argument="-15.806237"
+ sodipodi:radius="7.4065847"
+ sodipodi:revolution="1.5209458"
+ sodipodi:expansion="0.63999999"
+ sodipodi:cy="353.8125"
+ sodipodi:cx="56.5"
+ id="path107468"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="spiral"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient30090);fill-opacity:1;stroke:#5a130a;stroke-width:1.21390676;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ id="path107107-5"
+ sodipodi:cx="12.90625"
+ sodipodi:cy="354.09375"
+ sodipodi:rx="2.46875"
+ sodipodi:ry="2.46875"
+ d="m 15.375,354.09375 a 2.46875,2.46875 0 1 1 -4.9375,0 2.46875,2.46875 0 1 1 4.9375,0 z"
+ transform="matrix(0.6590292,0,0,0.6590292,48.151531,120.63684)" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient30129);fill-opacity:1;stroke:none;stroke-width:2.5999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="m 48.25,351.96875 a 1.30013,1.30013 0 0 0 -1.03125,1.0625 c -0.560356,3.27054 0.822741,6.58876 3.4375,8.5625 a 1.3062537,1.3062537 0 0 0 1.5625,-0.0312 A 0.50389111,0.50389111 0 0 1 51.9375,361.5 c -3.258538,-1.90713 -4.860221,-5.92414 -3.625,-9.53125 a 1.30013,1.30013 0 0 0 -0.0625,0 z m 1.03125,0.21875 c -1.14015,3.1617 0.271743,6.74928 3.15625,8.4375 a 0.50389111,0.50389111 0 0 1 0.25,0.3125 1.3062537,1.3062537 0 0 0 -0.46875,-1.4375 c -1.845415,-1.393 -2.825384,-3.76735 -2.4375,-6.03125 a 1.30013,1.30013 0 0 0 -0.5,-1.28125 z"
+ id="path30105"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ sodipodi:type="spiral"
+ style="fill:none;stroke:url(#linearGradient30145);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path30107"
+ sodipodi:cx="56.5"
+ sodipodi:cy="353.8125"
+ sodipodi:expansion="0.63999999"
+ sodipodi:revolution="1.690941"
+ sodipodi:radius="7.9262452"
+ sodipodi:argument="-15.806237"
+ sodipodi:t0="0.86983246"
+ d="m 63.464088,351.79847 c 1.246144,3.40682 -0.280462,7.26967 -3.378975,9.08314"
+ transform="matrix(-1,0,0,1,112.28991,0.1875)" />
+ </g>
+ </g>
+ <image
+ y="178"
+ x="467"
+ id="image14814"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAArJJREFU
+OI2Nk0tIVXkcxz//c851sLJFKRFE1GaoRRSZFFgQvTQqo1NJDyiYJoWZ/UAEBa0iatGmh2WBlZhj
+hkjGBaOZoAE3XWY1m5FRKCgavfd6zrnn8X+1yLpO06Lv8gvfD7+noGE9X6gDaJlr1ORyoq5uviel
+sjNBqGbtPNDlfS18qfuBv7epnov33zBZGObCmZM0LK4jTgz/vE+JYsHJw3sAcJm/9D/ht+O/+/Xz
+LIW/XvNbfoTTHQe4crWPBUuW8/e7mHclQ++taxz/6ezql6ND0psb3tve6f9ycxyA6YlXAESp5eBx
+n4f3Bth18ChDPTfYvK8TJQMAnE/hwqtRf9GKjUxPjLFzg8v+tk0ASOuirEtr+xFG+rrZ0vYzcZxi
+tP0MaLnU/cB//WYKAN9v5uHAH8RSAFDJBIn2eNrbw6Y9nRTLAUEUI7X6DKC9eRlTkWJ6YoxYCra3
+buZR7xD1K5soFgX53nts2P0jpWJIFJRQSpNlEgAP4NydcSYLwwD09wwCUL+yCYAXT/tp3HGCcikk
+CooYY9EywdSIKmCyMEzLoSO4nsDgYBHEiWD0UQ/fN7YShRlheQprLVKDVgqlnWoLu9oOkx/oI9E5
+UuUxE3o8+/Uu67Yew/FqCcv/YiwoA67jzlZhqoC6xYvYuO8HntzvIkk9nj++zdptJ4jCkGimhLGg
+EQjHw3FctAXHqW6BmdAhCi2NracZ7b/Omi1HKZdKxFGAtmCEQOCglEZbS5rEYOYApkshlSRkbPAy
+q5oPEQZlZBpjjEXgAA7aWFzPI8sy0jTBYqtDTOMKf45cY832U1gjsUpirEEbTZxW+K6mFq0NMksJ
+g48XqJQGQNCwvgNoOXW2y19Ym0NLhbUaYS05F4w1oA3aGKTMqCSSOJH03zo/COTF7Dv/74W/QXmg
+6wPaEWghwWN1uQAAAABJRU5ErkJggg==
+"
+ height="16"
+ width="16" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer6"
+ inkscape:label="New Icons"
+ style="display:none">
+ <g
+ style="display:inline;enable-background:new"
+ id="g30250-6"
+ transform="matrix(-1,0,0,1,788.49395,-2.4863553)" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g33683-2"
+ transform="translate(42,296)">
+ <rect
+ y="176"
+ x="446"
+ height="16"
+ width="16"
+ id="rect18831-4"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(263.91329,149.04559)"
+ id="g11360-5"
+ style="display:inline">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient37097-2);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 190.07108,29.454411 c -3.02619,0 -5.48439,2.463313 -5.48438,5.5 0,3.036688 2.45819,5.500001 5.48438,5.5 3.02619,0 5.48437,-2.46331 5.48437,-5.5 0,-3.036689 -2.45818,-5.500001 -5.48437,-5.5 z m 0,2.98305 c 1.36546,0 2.53849,1.100464 2.53848,2.454803 0,1.354341 -1.17303,2.501413 -2.53848,2.501412 -1.36546,0 -2.47581,-1.14707 -2.47581,-2.501412 0,-1.354341 1.11035,-2.454805 2.47581,-2.454803 z"
+ id="path11362-5"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="csssccsssc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11364-7"
+ style="fill:none;stroke:url(#linearGradient15782-9);stroke-width:1.77120221;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.566689,0,0,-0.562497,115.2063,101.3747)" />
+ <path
+ transform="matrix(0.4330916,0,0,-0.424074,132.95389,85.01929)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient33681-3);stroke-width:2.33340454;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path11366-4"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g16706"
+ transform="translate(21,21)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect16672"
+ width="16"
+ height="16"
+ x="446"
+ y="451" />
+ <g
+ style="display:inline"
+ id="g16674"
+ transform="matrix(0.45569675,0,0,0.45569675,367.3696,443.07138)">
+ <path
+ sodipodi:nodetypes="csssc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path16676"
+ d="m 190.07108,29.454411 c -3.02619,0 -5.48439,2.463313 -5.48438,5.5 0,3.036688 2.45819,5.500001 5.48438,5.5 3.02619,0 5.48437,-2.46331 5.48437,-5.5 0,-3.036689 -2.45818,-5.500001 -5.48437,-5.5 z"
+ style="fill:url(#linearGradient16713);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.1944418;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.40900746,0,0,-0.40575459,136.02026,82.879096)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient16716);stroke-width:5.3867569;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ id="path16678"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path16680"
+ style="fill:none;stroke:url(#linearGradient16718);stroke-width:5.12052059;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+ sodipodi:type="arc"
+ transform="matrix(0.4330916,0,0,-0.424074,132.95389,85.01929)" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g52905"
+ transform="translate(398.95001,-42)">
+ <rect
+ y="367"
+ x="-372.95001"
+ height="16"
+ width="16"
+ id="rect52907"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52910"
+ d="m -368.95,374 5,-5"
+ style="fill:none;stroke:#000000;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <g
+ mask="url(#mask52637-8-8)"
+ id="g52912"
+ transform="translate(-18.95,-84)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m -352.5,465.5 2,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ style="color:#000000;fill:none;stroke:#3c0800;stroke-width:2.70000005;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path52914"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52916"
+ style="color:#000000;fill:none;stroke:#ed7432;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -353.25,465.5 2.75,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ mask="none"
+ sodipodi:nodetypes="ccccc"
+ d="m -353.25,465.5 2.75,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ style="color:#000000;fill:none;stroke:url(#linearGradient52998-5-5);stroke-width:1.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path52918"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ ry="1.5"
+ rx="1.5"
+ style="fill:none;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52920"
+ width="3"
+ height="3"
+ x="-371.45001"
+ y="-376.5"
+ transform="scale(1,-1)" />
+ <g
+ transform="matrix(-1,0,0,1,-711.95,-84)"
+ id="g52922"
+ mask="url(#mask52879-0-5)">
+ <path
+ id="path52924"
+ style="color:#000000;fill:none;stroke:#0b1728;stroke-width:2.70000005;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -353.5,465.5 3,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ d="m -354.2,465.5 3.7,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ style="color:#000000;fill:none;stroke:#7be10f;stroke-width:1.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path52926"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52928"
+ style="color:#000000;fill:none;stroke:url(#linearGradient53000-3-9);stroke-width:1.5;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -354.2,465.5 3.75,0 c 1.10456,0 2,-0.89543 2,-1.99999 l 0,-1.00001 -2.5,-2.5"
+ sodipodi:nodetypes="ccccc"
+ mask="none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ transform="scale(1,-1)"
+ y="-376.5"
+ x="-361.45001"
+ height="3"
+ width="3"
+ id="rect52930"
+ style="fill:none;stroke:#000000;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5"
+ ry="1.5" />
+ <path
+ style="fill:none;stroke:#b3b3b3;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -367.7,372.75 3.75,-3.75"
+ id="path52932"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="scale(1,-1)"
+ y="-376.5"
+ x="-371.45001"
+ height="3"
+ width="3"
+ id="rect52934"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5"
+ ry="1.5" />
+ <rect
+ ry="1.5"
+ rx="1.5"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52936"
+ width="3"
+ height="3"
+ x="-361.45001"
+ y="-376.5"
+ transform="scale(1,-1)" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52938"
+ d="m -368.45,372.5 4,-4 1,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="1.5"
+ rx="1.5"
+ style="fill:none;stroke:url(#linearGradient53002-6-2);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52940"
+ width="3"
+ height="3"
+ x="-371.45001"
+ y="-376.5"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-376.5"
+ x="-361.45001"
+ height="3"
+ width="3"
+ id="rect52942"
+ style="fill:none;stroke:url(#linearGradient58927);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.5"
+ ry="1.5" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(252,-210)"
+ id="g52978">
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -198,536 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.75 -1.75,1.75 1.75,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L -204,542 l 0,1 0,1 1.90625,0.15625 c 0.14227,0.6231 0.25145,1.07677 0.59375,1.59375 l -1.75,1.75 1.75,1.75 1.75,-1.75 c 0.51699,0.34229 0.97065,0.45148 1.59375,0.59375 L -198,550 l 1,0 1,0 0.15625,-1.90625 c 0.6231,-0.14227 1.07677,-0.25145 1.59375,-0.59375 l 1.75,1.75 1.75,-1.75 -1.75,-1.75 c 0.34229,-0.51699 0.45148,-0.97065 0.59375,-1.59375 L -190,544 l 0,-1 0,-1 -1.90625,-0.15625 c -0.14227,-0.6231 -0.25145,-1.07677 -0.59375,-1.59375 l 1.75,-1.75 -1.75,-1.75 -1.75,1.75 c -0.51699,-0.34229 -0.97065,-0.45148 -1.59375,-0.59375 L -196,536 l -1,0 -1,0 z m 1,4.125 c 1.58782,0 2.875,1.28718 2.875,2.875 0,1.58782 -1.28718,2.875 -2.875,2.875 -1.58782,0 -2.875,-1.28718 -2.875,-2.875 0,-1.58782 1.28718,-2.875 2.875,-2.875 z"
+ id="path52980"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path52982"
+ d="m -196,550 0.15625,-1.90625 c 0.6231,-0.14227 1.07677,-0.25145 1.59375,-0.59375 l 1.75,1.5 1.5,-1.5 -1.5,-1.75 c 0.34229,-0.51699 0.45148,-0.97065 0.59375,-1.59375 L -190,544 l 0,-1 0,-1 -1.90625,-0.15625 c -0.14227,-0.6231 -0.25145,-1.07677 -0.59375,-1.59375 l 1.5,-1.75 -1.5,-1.5 -1.75,1.5 c -0.51699,-0.34229 -0.97065,-0.45148 -1.59375,-0.59375 L -196,536 l -1,0 -1,0 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.5 -1.5,1.5 1.5,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L -204,542 l 0,1 0,1 1.90625,0.15625 c 0.14227,0.6231 0.25145,1.07677 0.59375,1.59375 l -1.5,1.75 1.5,1.5 1.75,-1.5 c 0.51699,0.34229 0.97065,0.45148 1.59375,0.59375 L -198,550 l 1,0 1,0 z m -1,-4 c -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 0,1.65685 -1.34315,3 -3,3 z"
+ style="color:#000000;fill:url(#linearGradient32854-6-2);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="535"
+ x="-205"
+ height="16"
+ width="16"
+ id="rect52984"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="6.4999995"
+ rx="6.4999995"
+ y="539.5"
+ x="-200.5"
+ height="6.981843"
+ width="6.981843"
+ id="rect52986"
+ style="fill:none;stroke:url(#linearGradient32856-3-2);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m -192.5,537.5 -1.25,1.25 m -2.75,-2.25 -1,0 0,1.5 c -0.35104,0.0802 -1.50086,0.537 -2,0.75 m -1.75,1.75 c -0.20864,0.49552 -0.67146,1.65605 -0.75,2 l -1.5,0 0,1 m 1.75,-5.75 -0.5,0.5 m 1,8 -1.25,1.25"
+ id="path52988"
+ sodipodi:nodetypes="cccccscccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52990"
+ d="m -202.5,538.75 1.25,-1.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient32858-7-2);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52992"
+ width="6.981843"
+ height="6.981843"
+ x="193.51816"
+ y="-546.48187"
+ rx="6.4999995"
+ ry="6.4999995"
+ transform="scale(-1,-1)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m -197.5,548.25 0,1.25 m 7,-7 -1.25,0"
+ id="path52994"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52996"
+ d="m -191.75,547.25 -1,1"
+ style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g32860"
+ transform="translate(231,-294)">
+ <rect
+ style="opacity:0;color:#000000;fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32862"
+ width="16"
+ height="16"
+ x="-226"
+ y="619" />
+ <path
+ sodipodi:nodetypes="cccsssscccc"
+ style="opacity:0.5;fill:url(#linearGradient32896-0-4);fill-opacity:1;stroke:none"
+ d="m -212.5,619.5 -2,0 -6.0625,6.0625 C -220.70928,625.548 -220.84942,625.5 -221,625.5 c -2.48528,0 -4.5,2.01473 -4.5,4.5 0,2.48527 2.01472,4.5 4.5,4.5 2.48528,0 4.5,-2.01473 4.5,-4.5 0,-0.14948 -0.017,-0.29176 -0.0312,-0.4375 l 6.0312,-6.0625 0,-2 -2,-2 z"
+ id="path32864"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m -177.09897,651.49231 a 2.4505157,2.4923096 0 1 1 -4.90103,0 2.4505157,2.4923096 0 1 1 4.90103,0 z"
+ sodipodi:ry="2.4923096"
+ sodipodi:rx="2.4505157"
+ sodipodi:cy="651.49231"
+ sodipodi:cx="-179.54948"
+ id="path32866"
+ style="color:#000000;fill:url(#linearGradient32899-8-3);fill-opacity:1;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.224232,0,0,1.2036922,-1.189782,-154.19619)" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path32868"
+ d="m -219.5,626.5 5.5,-5.5 0.5,-0.5 0.5,0.5 0.5,0.5"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-21,0)"
+ d="M -193.09375,620.46875 -198.875,626.25 a 0.95626367,0.95626367 0 0 1 -0.78125,0.25 c -0.29297,-0.0289 -0.39637,-0.0312 -0.34375,-0.0312 -1.96853,0 -3.53125,1.56273 -3.53125,3.53125 0,1.96852 1.56272,3.53125 3.53125,3.53125 1.96853,0 3.53125,-1.56273 3.53125,-3.53125 0,-0.0768 0.0155,-0.18427 0,-0.34375 a 0.95626367,0.95626367 0 0 1 0.25,-0.78125 l 5.75,-5.78125 0,-1.1875 -1.4375,-1.4375 -1.1875,0 z"
+ id="path32870"
+ style="fill:none;stroke:url(#radialGradient32901-4-9);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:original="M -193.5 619.5 L -199.5625 625.5625 C -199.70928 625.548 -199.84942 625.5 -200 625.5 C -202.48528 625.5 -204.5 627.51473 -204.5 630 C -204.5 632.48527 -202.48528 634.5 -200 634.5 C -197.51472 634.5 -195.5 632.48527 -195.5 630 C -195.5 629.85052 -195.51705 629.70824 -195.53125 629.5625 L -189.5 623.5 L -189.5 621.5 L -191.5 619.5 L -193.5 619.5 z "
+ inkscape:radius="-0.95616806"
+ sodipodi:type="inkscape:offset" />
+ <path
+ id="path32872"
+ d="m -217,624 0,1 -1,0 0,0.0312 -0.0312,0 0,0.96875 -0.96875,0 0,0.0312 -0.0312,0 0,1 -1,0 0,1 0,1 1,0 1,0 0,-1 1,0 0,-0.0312 0.0312,0 0,-0.96875 0.96875,0 0,-0.0312 0.0312,0 0,-1 1,0 0,-1 -1,0 0,-1 -1,0 z"
+ style="color:#000000;fill:url(#linearGradient32903-6-4);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(1.2638889,0,0,1.2222222,32.853009,-140.1836)"
+ d="m -201.22313,628.93835 a 0.80938911,0.80938911 0 1 1 -1.61878,0 0.80938911,0.80938911 0 1 1 1.61878,0 z"
+ sodipodi:ry="0.80938911"
+ sodipodi:rx="0.80938911"
+ sodipodi:cy="628.93835"
+ sodipodi:cx="-202.03252"
+ id="path32874"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path32877"
+ sodipodi:cx="-202.03252"
+ sodipodi:cy="628.93835"
+ sodipodi:rx="0.80938911"
+ sodipodi:ry="0.80938911"
+ d="m -201.22313,628.93835 a 0.80938911,0.80938911 0 1 1 -1.61878,0 0.80938911,0.80938911 0 1 1 1.61878,0 z"
+ transform="matrix(0.77047663,0,0,0.74507628,-63.8586,161.95861)" />
+ <path
+ transform="matrix(0.77047663,0,0,0.74507628,-64.708233,162.88548)"
+ d="m -201.22313,628.93835 a 0.80938911,0.80938911 0 1 1 -1.61878,0 0.80938911,0.80938911 0 1 1 1.61878,0 z"
+ sodipodi:ry="0.80938911"
+ sodipodi:rx="0.80938911"
+ sodipodi:cy="628.93835"
+ sodipodi:cx="-202.03252"
+ id="path32879"
+ style="opacity:0.7;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.97113496;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
+ d="m -213.5,621.5 -6,6"
+ id="path32881"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path32883"
+ d="m -212.5,619.5 -2,0 -6.0625,6.0625 C -220.70928,625.548 -220.84942,625.5 -221,625.5 c -2.48528,0 -4.5,2.01473 -4.5,4.5 0,2.48527 2.01472,4.5 4.5,4.5 2.48528,0 4.5,-2.01473 4.5,-4.5 0,-0.14948 -0.017,-0.29176 -0.0312,-0.4375 l 6.0312,-6.0625 0,-2 -2,-2 z"
+ style="fill:none;stroke:#000000;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccsssscccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="translate(-21,0)"
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="-0.95616806"
+ inkscape:original="M -193.5 619.5 L -199.5625 625.5625 C -199.70928 625.548 -199.84942 625.5 -200 625.5 C -202.48528 625.5 -204.5 627.51473 -204.5 630 C -204.5 632.48527 -202.48528 634.5 -200 634.5 C -197.51472 634.5 -195.5 632.48527 -195.5 630 C -195.5 629.85052 -195.51705 629.70824 -195.53125 629.5625 L -189.5 623.5 L -189.5 621.5 L -191.5 619.5 L -193.5 619.5 z "
+ style="fill:none;stroke:url(#radialGradient32905-9-5);stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path32886"
+ d="M -193.09375,620.46875 -198.875,626.25 a 0.95626367,0.95626367 0 0 1 -0.78125,0.25 c -0.29297,-0.0289 -0.39637,-0.0312 -0.34375,-0.0312 -1.96853,0 -3.53125,1.56273 -3.53125,3.53125 0,1.96852 1.56272,3.53125 3.53125,3.53125 1.96853,0 3.53125,-1.56273 3.53125,-3.53125 0,-0.0768 0.0155,-0.18427 0,-0.34375 a 0.95626367,0.95626367 0 0 1 0.25,-0.78125 l 5.75,-5.78125 0,-1.1875 -1.4375,-1.4375 -1.1875,0 z" />
+ <g
+ style="opacity:0.3;fill:#ffffff"
+ id="g32888">
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32890"
+ width="1"
+ height="0.98873287"
+ x="-217"
+ y="622.98871" />
+ <rect
+ y="624"
+ x="-216"
+ height="0.98873287"
+ width="1"
+ id="rect32892"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect32894"
+ width="1"
+ height="0.98873287"
+ x="-215"
+ y="624.98871" />
+ </g>
+ </g>
+ <g
+ id="g59188"
+ transform="translate(441,-963.36218)"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect59190"
+ width="16"
+ height="16"
+ x="26"
+ y="1036.3622" />
+ <g
+ transform="translate(-727,832.3622)"
+ id="g59192"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient106804);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 8.33334,-1e-5 0,13.99999 -11,1e-5 -10e-6,-10.99999 2.66667,-3 z"
+ id="path59194"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path59196"
+ d="m 756.16666,204.50001 8.33334,-1e-5 0,13.99999 -11,1e-5 -10e-6,-10.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient106806);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path59198"
+ style="fill:none;stroke:url(#linearGradient106808);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 754.5,209 0,9.5 m 3.5,-13 5.5,0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path59200"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path59202"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 753.5,207.00001 0,11.49999 11,-1e-5 0,-13.99999 -8.5,1e-5 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient106810);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path59204" />
+ </g>
+ <g
+ id="g59206"
+ transform="translate(26,2.12e-5)">
+ <g
+ transform="translate(42,3.0002)"
+ id="g59208">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#4381b3;fill-opacity:1;stroke:none"
+ d="m -32.5,1036.8622 c -3,0 -3,1.5128 -3,2.0128 l 0,0.9872 -0.5,0 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.9988 2.25,3 2.5,3 l 0.5,0 0,-1 c 0,-1.1046 0.89543,-2 2,-2 l 2,-0.013 c 1.10457,0 2,-0.8954 2,-2 l 0,-1.9872 c 0,-0.5 0,-2 -3,-2 l 0,0 0,2e-4 z"
+ id="path59210"
+ sodipodi:nodetypes="ccccsccccccccc" />
+ <rect
+ style="opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect59212"
+ width="0.99999928"
+ height="1.0468764"
+ x="-34"
+ y="1038.3153" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsccccccccc"
+ id="path59214"
+ d="m -32.5,1048.8622 c 3,0 3,-1.5128 3,-2.0128 l 0,-0.9872 0.5,0 c 0.25,0 2.5,-10e-4 2.5,-3 0,-2.9988 -2.25,-3 -2.5,-3 l -0.5,0 0,1 c 0,1.1046 -0.89543,2 -2,2 l -2,0.013 c -1.10457,0 -2,0.8954 -2,2 l 0,1.9872 c 0,0.5 0,2 3,2 l 0,0 0,-2e-4 z"
+ style="fill:#ffd43b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m -32.5,1036.8622 c -3,0 -3,1 -3,2.0128 l 0,0.9872 3.5,0 -4,0.013 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.9988 2.25,3 2.5,3 l 0.5,0 0,1 c 0,0.9872 0,1.9872 3,1.9872 3,0 3,-1.0128 3,-2 l 0,-1 -2.5,0 3,0 c 0.25,0 2.5,-10e-4 2.5,-3 0,-2.9988 -2.25,-3 -2.5,-3 l -0.5,0 0,-1 c 0,-1.0128 0,-2 -3,-2 l 0,-2e-4 z"
+ id="path59216"
+ sodipodi:nodetypes="cccccscccsccccscccz" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -29.5,1039.8622 0,1 c 0,1.1046 -0.89543,2 -2,2 l -2,0 c -1.10457,0 -2,0.8954 -2,2 l 0,1"
+ id="path59218"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cszs"
+ id="path59220"
+ d="m -30.5,1041.3622 0,-2.5 c 0,-0.5128 0.25,-1 -2,-1 -2.15993,0 -1.99997,0.4872 -2,1"
+ style="fill:none;stroke:url(#linearGradient106812);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient106814);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m -32.5,1040.8494 -3.49995,0.013 c -1.00005,0 -1.50005,0.7372 -1.5,2 5e-5,1.285 0.49995,2 1.5,2"
+ id="path59222"
+ sodipodi:nodetypes="cszs" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ d="m -34.5,1044.8494 c 0,-0.5 0.5,-1 1,-1 l 2,0.013 c 1.64438,0 3,-1.3428 3,-2.9872 m -6,3.9744 0,3.5"
+ style="fill:none;stroke:url(#linearGradient106816);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path59224" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path59226"
+ style="fill:none;stroke:url(#linearGradient106818);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m -31.5,1046.8494 1,0.013" />
+ </g>
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ transform="translate(172,-563.36218)"
+ id="g3978-5">
+ <rect
+ style="opacity:0;fill:#00ff00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="rect3980-2"
+ width="16"
+ height="15.999996"
+ x="211"
+ y="594.36218"
+ rx="0" />
+ <path
+ style="fill:#5590bf;fill-opacity:1;stroke:none"
+ d="m 219,594.875 c -3.5,10e-6 -3.5,1.5 -3.5,2 l 0,2 -0.5,0 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.99883 2.25,2.99999 2.5,3 l 0.5,0 0,-1 c 0,-1.10457 0.89543,-2 2,-2 l 3,0 c 1.10457,0 2,-0.89543 2,-2 l 0,-3 c 0,-0.5 0,-2.00001 -3.5,-2 z"
+ id="path3982-7"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect3984-6"
+ width="0.99999928"
+ height="1.0468764"
+ x="217"
+ y="596.31531" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect3986-1"
+ width="0.99999928"
+ height="1.0000014"
+ x="217"
+ y="596.36218" />
+ <path
+ id="path3988-4"
+ d="m 219,608.86218 c 3.5,-10e-6 3.5,-1.5 3.5,-2 l 0,-2 0.5,0 c 0.25,0 2.5,-10e-4 2.5,-3 0,-2.99883 -2.25,-2.99999 -2.5,-3 l -0.5,0 0,1 c 0,1.10457 -0.89543,2 -2,2 l -3,0 c -1.10457,0 -2,0.89543 -2,2 l 0,3 c 0,0.5 0,2.00001 3.5,2 z"
+ style="fill:#ffd43b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="606.36218"
+ x="220"
+ height="1.0000014"
+ width="0.99999928"
+ id="rect3990-2"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 219,594.875 c -3.5,10e-6 -3.5,0.98718 -3.5,2 l 0,1.98718 3.5,0 -4,0.0128 c -0.25,0 -2.5,10e-4 -2.5,3 0,2.99883 2.25,2.99999 2.5,3 l 0.5,0 0,2 c 0,0.9872 0,2.00001 3.5,2 3.5,-1e-5 3.5,-1.0128 3.5,-2 l 0,-2.0128 -3.5,0 4,0.0128 c 0.25,0 2.5,-0.001 2.5,-3 0,-2.99883 -2.25,-2.99999 -2.5,-3 l -0.5,0 0,-2 c 0,-1.0128 0,-2.00001 -3.5,-2 l 0,2e-5 0,0 z"
+ id="path3992-3"
+ sodipodi:nodetypes="cccccscccsccccsccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 222.5,598.86218 0,1 c 0,1.10457 -0.89543,2 -2,2 l -3,0 c -1.10457,0 -2,0.89543 -2,2 l 0,1"
+ id="path3994-2"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cszsc"
+ id="path3996-2"
+ d="m 221.5,600.86218 -5e-5,-3.98718 c -1e-5,-0.51282 0.23494,-0.98725 -2.49995,-1 -2.75,-0.0128 -2.49992,0.48718 -2.49995,1 l -5e-5,0.98718"
+ style="fill:none;stroke:url(#linearGradient106820);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient106822);stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 218.5,599.86218 -3.49995,0.0128 c -1.00005,0.004 -1.50005,0.73718 -1.5,2 5e-5,1.285 0.49995,2 1.5,2"
+ id="path3998-16"
+ sodipodi:nodetypes="cszs"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ d="m 216.5,603.86218 c 0,-0.5 0.5,-1 1,-1 l 3,0 c 1.64438,0 3,-1.3428 3,-2.98718 m -7,3.98718 0,3.5"
+ style="fill:none;stroke:url(#linearGradient106824);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path4000-8"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path4002-5"
+ style="fill:none;stroke:url(#linearGradient106826);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 219.5,605.86218 2.00005,0.0128"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g29932"
+ transform="translate(-126.00002,-168.00003)"
+ inkscape:export-filename="/home/wolter/Documenten/Blender/icons/v.2.5.08/tri.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="346.00003"
+ x="194.00002"
+ height="15.999971"
+ width="15.999971"
+ id="rect41325-5"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g29926">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.55;fill:url(#radialGradient29940);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 202,347.61523 -5.88637,9.59973 5.88637,3.34754 5.86428,-3.39174 z"
+ id="path41327-4"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path41331-0"
+ d="M 196.3125,357.5 202,354.4375 207.6875,357.5"
+ style="opacity:0.02749999;fill:none;stroke:#1a1a1a;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffb769;fill-opacity:1;fill-rule:nonzero;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 202.01289,347.79311 -5.76159,9.41263 5.71099,3.22682 z"
+ id="path35820-3-3-0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path35822-5"
+ d="m 201.96384,360.43934 -5.70169,-3.25 5.73419,-9.4114"
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g28913">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect29107-2-4"
+ width="16"
+ height="16"
+ x="89"
+ y="178" />
+ <g
+ transform="translate(0.7527954,0.10835392)"
+ id="g28861">
+ <g
+ id="g56091-4-3"
+ transform="translate(-440.6432,125.89164)">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 532,57.5 4,-1.5 7.99996,3.49998 0,1.71875 -3.99999,2.24999 L 532,59.21875 z"
+ id="path29110-0-9"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path29112-19-0"
+ d="m 532,57.5 4,-1.5 7.99996,3.49998 0,0.5 -4,2 L 532,58.06558 z"
+ style="fill:url(#linearGradient28911);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ style="fill:#252525;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="M 532.00001,59.21875 532,58 l 7.99996,3.99998 0.01,1.4676 -8.00991,-4.24883 z"
+ id="path29114-14-3"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path29116-5-9"
+ d="m 543.99996,61.21873 0,-1.21875 -4,2 c 0,2.58362 0,0.90165 0,1.46875 z"
+ style="fill:#151515;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path29120-9-7"
+ d="m 536.02638,56.53466 -3.36588,1.240071 7.30821,3.725249"
+ style="opacity:0.6;fill:none;stroke:#606060;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:#e5b363;fill-opacity:1;stroke:#2c1907;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 89.80793,186.9661 1.06791,0.55608 0.8071,-0.42744 c 0,0 -0.0863,-0.49795 0.29882,-0.94997 0.32255,-0.37859 0.61819,-0.48727 0.61819,-0.48727 L 92.6,184.97585 91.49415,184.4 c 0,0 -0.64899,0.0667 -1.26647,0.81355 -0.63732,0.7709 -0.41973,1.75255 -0.41973,1.75255 z"
+ id="path30129"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccscccscc" />
+ <path
+ style="fill:none;stroke:#ebd49a;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.71428576;stroke-dasharray:none"
+ d="m 91.42064,185.14551 c -0.22969,0.0907 -0.46636,0.27389 -0.62977,0.51928"
+ id="path30223"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:#e5b363;fill-opacity:1;stroke:#2c1907;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 95.76565,190.00646 1.06791,0.55608 0.8071,-0.42744 c 0,0 -0.0863,-0.49795 0.29882,-0.94997 0.32255,-0.37859 0.61819,-0.48727 0.61819,-0.48727 l 5e-5,-0.68165 -1.10585,-0.57585 c 0,0 -0.64899,0.0667 -1.26647,0.81355 -0.63732,0.7709 -0.41973,1.75255 -0.41973,1.75255 z"
+ id="path30129-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccscccscc" />
+ <path
+ style="fill:none;stroke:#ebd49a;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.71428576;stroke-dasharray:none"
+ d="m 97.37836,188.18587 c -0.22969,0.0907 -0.46636,0.27389 -0.62977,0.51928"
+ id="path30223-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:#e5b363;fill-opacity:1;stroke:#2c1907;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 92.80464,188.48176 1.06791,0.55608 0.8071,-0.42744 c 0,0 -0.0863,-0.49795 0.29882,-0.94997 0.32255,-0.37859 0.61819,-0.48727 0.61819,-0.48727 l 5e-5,-0.68165 -1.10585,-0.57585 c 0,0 -0.64899,0.0667 -1.26647,0.81355 -0.63732,0.7709 -0.41973,1.75255 -0.41973,1.75255 z"
+ id="path30129-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccscccscc" />
+ <path
+ style="fill:none;stroke:#ebd49a;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.71428576;stroke-dasharray:none"
+ d="m 94.41735,186.66117 c -0.22969,0.0907 -0.46636,0.27389 -0.62977,0.51928"
+ id="path30223-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/release/datafiles/blender_icons16.png b/release/datafiles/blender_icons16.png
new file mode 100644
index 0000000..64edb2a
Binary files /dev/null and b/release/datafiles/blender_icons16.png differ
diff --git a/release/datafiles/blender_icons32.png b/release/datafiles/blender_icons32.png
new file mode 100644
index 0000000..5a2a076
Binary files /dev/null and b/release/datafiles/blender_icons32.png differ
diff --git a/release/datafiles/fonts/droidsans.ttf.gz b/release/datafiles/fonts/droidsans.ttf.gz
index 439515e..a0e7502 100644
Binary files a/release/datafiles/fonts/droidsans.ttf.gz and b/release/datafiles/fonts/droidsans.ttf.gz differ
diff --git a/release/datafiles/locale/ar/LC_MESSAGES/blender.mo b/release/datafiles/locale/ar/LC_MESSAGES/blender.mo
index 079ca25..b663bcb 100644
Binary files a/release/datafiles/locale/ar/LC_MESSAGES/blender.mo and b/release/datafiles/locale/ar/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/ca/LC_MESSAGES/blender.mo b/release/datafiles/locale/ca/LC_MESSAGES/blender.mo
new file mode 100644
index 0000000..9787b0e
Binary files /dev/null and b/release/datafiles/locale/ca/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/cs/LC_MESSAGES/blender.mo b/release/datafiles/locale/cs/LC_MESSAGES/blender.mo
index 6e8e44b..a80c280 100644
Binary files a/release/datafiles/locale/cs/LC_MESSAGES/blender.mo and b/release/datafiles/locale/cs/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/de/LC_MESSAGES/blender.mo b/release/datafiles/locale/de/LC_MESSAGES/blender.mo
index 39a45db..ab0bf66 100644
Binary files a/release/datafiles/locale/de/LC_MESSAGES/blender.mo and b/release/datafiles/locale/de/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/eo/LC_MESSAGES/blender.mo b/release/datafiles/locale/eo/LC_MESSAGES/blender.mo
index 3bc9b4b..07ee618 100644
Binary files a/release/datafiles/locale/eo/LC_MESSAGES/blender.mo and b/release/datafiles/locale/eo/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/es/LC_MESSAGES/blender.mo b/release/datafiles/locale/es/LC_MESSAGES/blender.mo
index 1404ed5..727f9e8 100644
Binary files a/release/datafiles/locale/es/LC_MESSAGES/blender.mo and b/release/datafiles/locale/es/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/es_ES/LC_MESSAGES/blender.mo b/release/datafiles/locale/es_ES/LC_MESSAGES/blender.mo
index 206aff7..ec1ab02 100644
Binary files a/release/datafiles/locale/es_ES/LC_MESSAGES/blender.mo and b/release/datafiles/locale/es_ES/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/fa/LC_MESSAGES/blender.mo b/release/datafiles/locale/fa/LC_MESSAGES/blender.mo
index 1416ba0..7354ea1 100644
Binary files a/release/datafiles/locale/fa/LC_MESSAGES/blender.mo and b/release/datafiles/locale/fa/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/fr/LC_MESSAGES/blender.mo b/release/datafiles/locale/fr/LC_MESSAGES/blender.mo
index 215551e..37b2332 100644
Binary files a/release/datafiles/locale/fr/LC_MESSAGES/blender.mo and b/release/datafiles/locale/fr/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/he/LC_MESSAGES/blender.mo b/release/datafiles/locale/he/LC_MESSAGES/blender.mo
index 18d72c4..a7d7769 100644
Binary files a/release/datafiles/locale/he/LC_MESSAGES/blender.mo and b/release/datafiles/locale/he/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/hr/LC_MESSAGES/blender.mo b/release/datafiles/locale/hr/LC_MESSAGES/blender.mo
index 309a781..f9b8ca0 100644
Binary files a/release/datafiles/locale/hr/LC_MESSAGES/blender.mo and b/release/datafiles/locale/hr/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/hu/LC_MESSAGES/blender.mo b/release/datafiles/locale/hu/LC_MESSAGES/blender.mo
index 0492225..5e93f32 100644
Binary files a/release/datafiles/locale/hu/LC_MESSAGES/blender.mo and b/release/datafiles/locale/hu/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/id/LC_MESSAGES/blender.mo b/release/datafiles/locale/id/LC_MESSAGES/blender.mo
index 6b49cb9..95ceea5 100644
Binary files a/release/datafiles/locale/id/LC_MESSAGES/blender.mo and b/release/datafiles/locale/id/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/it/LC_MESSAGES/blender.mo b/release/datafiles/locale/it/LC_MESSAGES/blender.mo
index ca73236..2f0ce24 100644
Binary files a/release/datafiles/locale/it/LC_MESSAGES/blender.mo and b/release/datafiles/locale/it/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/ja/LC_MESSAGES/blender.mo b/release/datafiles/locale/ja/LC_MESSAGES/blender.mo
index b9f1bbb..95cb652 100644
Binary files a/release/datafiles/locale/ja/LC_MESSAGES/blender.mo and b/release/datafiles/locale/ja/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/ky/LC_MESSAGES/blender.mo b/release/datafiles/locale/ky/LC_MESSAGES/blender.mo
index 0ecc4de..1ebe68c 100644
Binary files a/release/datafiles/locale/ky/LC_MESSAGES/blender.mo and b/release/datafiles/locale/ky/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/languages b/release/datafiles/locale/languages
index 5e69a2f..b7b74ad 100644
--- a/release/datafiles/locale/languages
+++ b/release/datafiles/locale/languages
@@ -7,7 +7,7 @@
# Line starting with a # are comments!
#
# Automatically generated by bl_i18n_utils/update_languages_menu.py script.
-# Highest ID currently in use: 36
+# Highest ID currently in use: 39
#
0:Complete::
0:Default (Default):DEFAULT
@@ -28,13 +28,14 @@
14:Traditional Chinese (繁體中文):zh_TW
#
0:Starting::
+# No translation yet! #37:Amharic (አማርኛ):am_ET
# No translation yet! #22:Bulgarian (Български):bg_BG
-# No translation yet! #10:Catalan (Català):ca_AD
+10:Catalan (Català):ca_AD
11:Czech (Český):cs_CZ
# No translation yet! #23:Greek (Ελληνικά):el_GR
35:Esperanto (Esperanto):eo
36:Spanish from Spain (Español de España):es_ES
-34:Estonian (Eestlane):et_EE
+# No translation yet! #34:Estonian (Eestlane):et_EE
26:Persian (ﯽﺳﺭﺎﻓ):fa_IR
# No translation yet! #6:Finnish (Suomi):fi_FI
33:Hebrew (תירִבְעִ):he_IL
@@ -51,3 +52,5 @@
28:Serbian Latin (Srpski latinica):sr_RS at latin
7:Swedish (Svenska):sv_SE
30:Turkish (Türkçe):tr_TR
+# No translation yet! #38:Uzbek (Oʻzbek):uz_UZ
+# No translation yet! #39:Uzbek Cyrillic (Ўзбек):uz_UZ at cyrillic
diff --git a/release/datafiles/locale/nl/LC_MESSAGES/blender.mo b/release/datafiles/locale/nl/LC_MESSAGES/blender.mo
index 667c254..451cce5 100644
Binary files a/release/datafiles/locale/nl/LC_MESSAGES/blender.mo and b/release/datafiles/locale/nl/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/pt/LC_MESSAGES/blender.mo b/release/datafiles/locale/pt/LC_MESSAGES/blender.mo
index 4c58467..b118a44 100644
Binary files a/release/datafiles/locale/pt/LC_MESSAGES/blender.mo and b/release/datafiles/locale/pt/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/pt_BR/LC_MESSAGES/blender.mo b/release/datafiles/locale/pt_BR/LC_MESSAGES/blender.mo
index 91e0620..5001b4e 100644
Binary files a/release/datafiles/locale/pt_BR/LC_MESSAGES/blender.mo and b/release/datafiles/locale/pt_BR/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/ru/LC_MESSAGES/blender.mo b/release/datafiles/locale/ru/LC_MESSAGES/blender.mo
index 67ba4c4..49034fb 100644
Binary files a/release/datafiles/locale/ru/LC_MESSAGES/blender.mo and b/release/datafiles/locale/ru/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/sr/LC_MESSAGES/blender.mo b/release/datafiles/locale/sr/LC_MESSAGES/blender.mo
index f2ee55e..df42978 100644
Binary files a/release/datafiles/locale/sr/LC_MESSAGES/blender.mo and b/release/datafiles/locale/sr/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/sr at latin/LC_MESSAGES/blender.mo b/release/datafiles/locale/sr at latin/LC_MESSAGES/blender.mo
index c5ab15d..d5efeff 100644
Binary files a/release/datafiles/locale/sr at latin/LC_MESSAGES/blender.mo and b/release/datafiles/locale/sr at latin/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/sv/LC_MESSAGES/blender.mo b/release/datafiles/locale/sv/LC_MESSAGES/blender.mo
index a4dedbb..820d611 100644
Binary files a/release/datafiles/locale/sv/LC_MESSAGES/blender.mo and b/release/datafiles/locale/sv/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/tr/LC_MESSAGES/blender.mo b/release/datafiles/locale/tr/LC_MESSAGES/blender.mo
index c30888b..5e071cb 100644
Binary files a/release/datafiles/locale/tr/LC_MESSAGES/blender.mo and b/release/datafiles/locale/tr/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/uk/LC_MESSAGES/blender.mo b/release/datafiles/locale/uk/LC_MESSAGES/blender.mo
index 005d6ea..81e9f7f 100644
Binary files a/release/datafiles/locale/uk/LC_MESSAGES/blender.mo and b/release/datafiles/locale/uk/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/zh_CN/LC_MESSAGES/blender.mo b/release/datafiles/locale/zh_CN/LC_MESSAGES/blender.mo
index fe01566..1969d2b 100644
Binary files a/release/datafiles/locale/zh_CN/LC_MESSAGES/blender.mo and b/release/datafiles/locale/zh_CN/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/locale/zh_TW/LC_MESSAGES/blender.mo b/release/datafiles/locale/zh_TW/LC_MESSAGES/blender.mo
index 3354d6a..0864653 100644
Binary files a/release/datafiles/locale/zh_TW/LC_MESSAGES/blender.mo and b/release/datafiles/locale/zh_TW/LC_MESSAGES/blender.mo differ
diff --git a/release/datafiles/prvicons.sh b/release/datafiles/prvicons.sh
new file mode 100755
index 0000000..144dd9d
--- /dev/null
+++ b/release/datafiles/prvicons.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# This script updates icons from the SVG file
+
+inkscape prvicons.svg --without-gui --export-png=prvicons.png
diff --git a/release/datafiles/prvicons.svg b/release/datafiles/prvicons.svg
new file mode 100644
index 0000000..d373410
--- /dev/null
+++ b/release/datafiles/prvicons.svg
@@ -0,0 +1,19741 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="192"
+ height="192"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.3.1 r9886"
+ version="1.0"
+ sodipodi:docname="prvicons.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ style="display:inline;enable-background:new"
+ inkscape:export-filename="blender_icons.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <title
+ id="title49470">Blender icons v. 2.5.06</title>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient30958">
+ <stop
+ id="stop30960"
+ offset="0"
+ style="stop-color:#fff9cf;stop-opacity:1;" />
+ <stop
+ id="stop30962"
+ offset="1"
+ style="stop-color:#c7bc52;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29312">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop29314" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop29316" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient29304">
+ <stop
+ style="stop-color:#11233f;stop-opacity:1;"
+ offset="0"
+ id="stop29306" />
+ <stop
+ style="stop-color:#162d50;stop-opacity:0;"
+ offset="1"
+ id="stop29308" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27896">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27898" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27900" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient27854">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop27856" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop27858" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24343">
+ <stop
+ id="stop24345"
+ offset="0"
+ style="stop-color:#184990;stop-opacity:1;" />
+ <stop
+ id="stop24347"
+ offset="1"
+ style="stop-color:#c1d5f3;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25417">
+ <stop
+ id="stop25419"
+ offset="0"
+ style="stop-color:#60553b;stop-opacity:1;" />
+ <stop
+ id="stop25421"
+ offset="1"
+ style="stop-color:#b0a17f;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient25108">
+ <stop
+ id="stop25110"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop25112"
+ offset="1"
+ style="stop-color:#c6c6c6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient43807">
+ <stop
+ style="stop-color:#e31b1b;stop-opacity:1;"
+ offset="0"
+ id="stop43809" />
+ <stop
+ style="stop-color:#930000;stop-opacity:1;"
+ offset="1"
+ id="stop43811" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient38845">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38847" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38849" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38831">
+ <stop
+ style="stop-color:#182b42;stop-opacity:1;"
+ offset="0"
+ id="stop38833" />
+ <stop
+ id="stop38836"
+ offset="0.38971797"
+ style="stop-color:#598ac7;stop-opacity:1;" />
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1;"
+ offset="1"
+ id="stop38838" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38256">
+ <stop
+ id="stop38258"
+ offset="0"
+ style="stop-color:#e7e0c7;stop-opacity:1;" />
+ <stop
+ id="stop38260"
+ offset="1"
+ style="stop-color:#f1eddf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient71814">
+ <stop
+ style="stop-color:#6e0d00;stop-opacity:1;"
+ offset="0"
+ id="stop71816" />
+ <stop
+ style="stop-color:#6f2913;stop-opacity:0;"
+ offset="1"
+ id="stop71818" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37667">
+ <stop
+ id="stop37669"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop37671"
+ offset="1"
+ style="stop-color:black;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39080">
+ <stop
+ style="stop-color:#1a2a3d;stop-opacity:1;"
+ offset="0"
+ id="stop39082" />
+ <stop
+ id="stop39084"
+ offset="0.5"
+ style="stop-color:#95b0d1;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop39086" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40703">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37925">
+ <stop
+ id="stop37927"
+ offset="0"
+ style="stop-color:#e7cbab;stop-opacity:1;" />
+ <stop
+ id="stop37929"
+ offset="1"
+ style="stop-color:#af7333;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient36273">
+ <stop
+ id="stop36275"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop36277"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35411">
+ <stop
+ id="stop35414"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31356">
+ <stop
+ id="stop31358"
+ offset="0"
+ style="stop-color:#1a1a1a;stop-opacity:1" />
+ <stop
+ id="stop31360"
+ offset="1"
+ style="stop-color:#1a1a1a;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient28107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7228842,8.5733105e-8,-9.4831885e-8,0.7995973,71.917045,14.582004)"
+ cx="256.49512"
+ cy="81.396774"
+ fx="256.49512"
+ fy="81.396774"
+ r="3.779551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28105"
+ gradientUnits="userSpaceOnUse"
+ x1="875.73486"
+ y1="422.77902"
+ x2="885.04938"
+ y2="427.01648" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28887"
+ id="linearGradient28103"
+ gradientUnits="userSpaceOnUse"
+ x1="873.09998"
+ y1="422.09964"
+ x2="881.01172"
+ y2="429.23453" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28101"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.6572588,1.2500456,-1.6473175,2.2058465,774.83033,-697.31982)"
+ cx="76.180473"
+ cy="500.20651"
+ fx="76.180473"
+ fy="500.20651"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient28099"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient28887">
+ <stop
+ style="stop-color:#2158a7;stop-opacity:1;"
+ offset="0"
+ id="stop28889" />
+ <stop
+ style="stop-color:#2f73d5;stop-opacity:0.19607843;"
+ offset="1"
+ id="stop28891" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient44421"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient44557"
+ gradientUnits="userSpaceOnUse"
+ x1="209"
+ y1="238"
+ x2="226.625"
+ y2="251.71078" />
+ <linearGradient
+ id="linearGradient24168">
+ <stop
+ id="stop24170"
+ offset="0"
+ style="stop-color:#182437;stop-opacity:1;" />
+ <stop
+ id="stop24172"
+ offset="1"
+ style="stop-color:#2b4163;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24144">
+ <stop
+ id="stop24146"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.17958513"
+ id="stop24148" />
+ <stop
+ id="stop24150"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24101">
+ <stop
+ style="stop-color:#643400;stop-opacity:1;"
+ offset="0"
+ id="stop24103" />
+ <stop
+ id="stop24105"
+ offset="0.22606115"
+ style="stop-color:#ed983d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#fff0d5;stop-opacity:1;"
+ offset="1"
+ id="stop24107" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24081">
+ <stop
+ id="stop24083"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.3167825"
+ id="stop24085" />
+ <stop
+ id="stop24087"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23302">
+ <stop
+ id="stop23304"
+ offset="0"
+ style="stop-color:#b45d00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff982a;stop-opacity:1;"
+ offset="0.39332664"
+ id="stop23306" />
+ <stop
+ id="stop23308"
+ offset="1"
+ style="stop-color:#ffedd5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24735">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop24737" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop24739" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24727">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24729" />
+ <stop
+ id="stop24731"
+ offset="0.77520341"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24733" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24711">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24713" />
+ <stop
+ id="stop24715"
+ offset="0.21609697"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24717" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24695">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24697" />
+ <stop
+ id="stop24699"
+ offset="0.60401857"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24701" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24687">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24689" />
+ <stop
+ id="stop24691"
+ offset="0.59630167"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24693" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681" />
+ <stop
+ id="stop24683"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24671">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24673" />
+ <stop
+ id="stop24675"
+ offset="0.29527253"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24677" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23705">
+ <stop
+ id="stop23707"
+ offset="0"
+ style="stop-color:#d4d2bf;stop-opacity:1;" />
+ <stop
+ id="stop23709"
+ offset="1"
+ style="stop-color:#857f5d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23906">
+ <stop
+ id="stop23908"
+ offset="0"
+ style="stop-color:#ff921d;stop-opacity:1;" />
+ <stop
+ id="stop23910"
+ offset="1"
+ style="stop-color:#ffa751;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42459">
+ <stop
+ style="stop-color:#e7dfab;stop-opacity:1;"
+ offset="0"
+ id="stop42461" />
+ <stop
+ style="stop-color:#af9d33;stop-opacity:1;"
+ offset="1"
+ id="stop42463" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287"
+ y1="-276.1875"
+ x2="-281.4375"
+ y2="-271.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="171.42436"
+ y1="259.71194"
+ x2="170.20523"
+ y2="244.96393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24246"
+ gradientUnits="userSpaceOnUse"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(186,-105)"
+ x1="246.12868"
+ y1="283.63254"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(744,397)"
+ x1="-287.56247"
+ y1="-276.71042"
+ x2="-282.59851"
+ y2="-271.35284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient24276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,342.06514,-90.66358)"
+ x1="190.33647"
+ y1="266.7905"
+ x2="170.9689"
+ y2="247.58694" />
+ <linearGradient
+ id="linearGradient24143">
+ <stop
+ id="stop24145"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669" />
+ <stop
+ id="stop24147"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24687"
+ id="linearGradient24238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,304.84783,-86.57833)"
+ x1="120.2969"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ id="linearGradient24642">
+ <stop
+ style="stop-color:#d0dbe8;stop-opacity:1;"
+ offset="0"
+ id="stop24644" />
+ <stop
+ style="stop-color:#6ca3e9;stop-opacity:0;"
+ offset="1"
+ id="stop24646" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24632">
+ <stop
+ style="stop-color:#28394f;stop-opacity:1;"
+ offset="0"
+ id="stop24634" />
+ <stop
+ id="stop24636"
+ offset="0.17637014"
+ style="stop-color:#0d386a;stop-opacity:0.78431374;" />
+ <stop
+ id="stop24638"
+ offset="0.35274029"
+ style="stop-color:#18437d;stop-opacity:0.47058824;" />
+ <stop
+ style="stop-color:#154e94;stop-opacity:0;"
+ offset="1"
+ id="stop24640" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="radialGradient23167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9934369,-0.1143813,0.1033636,0.8977446,-30.451879,30.134649)"
+ cx="-0.10810681"
+ cy="294.60239"
+ fx="-0.10810681"
+ fy="294.60239"
+ r="6.6750002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23201"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-61,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.25"
+ y2="245" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="22.75"
+ y1="245"
+ x2="24.5"
+ y2="245" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23189">
+ <g
+ transform="translate(-28,49)"
+ id="g23193">
+ <rect
+ y="237"
+ x="22"
+ height="16"
+ width="9"
+ id="rect23195"
+ style="fill:url(#linearGradient23199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(-1,1)"
+ style="fill:url(#linearGradient23201);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23197"
+ width="9"
+ height="16"
+ x="-38"
+ y="237" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24206"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23379"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient23377"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient23375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="52.06274"
+ y1="96.767769"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient23373"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ id="linearGradient23974">
+ <stop
+ id="stop23976"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40983">
+ <stop
+ style="stop-color:#6a9ae0;stop-opacity:1;"
+ offset="0"
+ id="stop40985" />
+ <stop
+ style="stop-color:#5189db;stop-opacity:0;"
+ offset="1"
+ id="stop40987" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23280"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23278"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient23276"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient23274"
+ gradientUnits="userSpaceOnUse"
+ x1="144.8255"
+ y1="132.15414"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ id="linearGradient30777"
+ inkscape:collect="always">
+ <stop
+ id="stop30779"
+ offset="0"
+ style="stop-color:#acacac;stop-opacity:1" />
+ <stop
+ id="stop30781"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient29485">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop29487" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop29489" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.55821538"
+ width="2.1164308"
+ y="-1.0219563"
+ height="3.0439126"
+ id="filter20578"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="2.0410255"
+ id="feGaussianBlur20580" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath20586">
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34889"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
+ transform="matrix(1.870472,0.1894819,-0.6587894,2.4281336,319.59052,-798.11661)" />
+ </clipPath>
+ <radialGradient
+ id="aigrd2"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop15566" />
+ <stop
+ offset="1.0000000"
+ style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
+ id="stop15568" />
+ </radialGradient>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013" />
+ </filter>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106">
+ <path
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient58334">
+ <stop
+ id="stop58336"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8864">
+ <stop
+ id="stop8866"
+ offset="0"
+ style="stop-color:#b43214;stop-opacity:1;" />
+ <stop
+ id="stop8868"
+ offset="1"
+ style="stop-color:#e86830;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20324">
+ <stop
+ id="stop20326"
+ offset="0"
+ style="stop-color:#35241b;stop-opacity:1;" />
+ <stop
+ style="stop-color:#69390e;stop-opacity:0.8392157;"
+ offset="0.17637014"
+ id="stop20328" />
+ <stop
+ style="stop-color:#6c5b15;stop-opacity:0.67843139;"
+ offset="0.35274029"
+ id="stop20330" />
+ <stop
+ id="stop20332"
+ offset="1"
+ style="stop-color:#947b15;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37623">
+ <stop
+ id="stop37625"
+ offset="0"
+ style="stop-color:#e5e1ca;stop-opacity:1;" />
+ <stop
+ id="stop37627"
+ offset="1"
+ style="stop-color:#d6ca22;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient36116">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop36118" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop36120" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22852"
+ gradientUnits="userSpaceOnUse"
+ x1="133.94305"
+ y1="116.00471"
+ x2="117.29694"
+ y2="133.14267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22850"
+ gradientUnits="userSpaceOnUse"
+ x1="136.55727"
+ y1="125.87247"
+ x2="129.70895"
+ y2="118.00132" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22844"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ id="linearGradient22562">
+ <stop
+ style="stop-color:#001e50;stop-opacity:1;"
+ offset="0"
+ id="stop22564" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop22566" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient22842"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ id="linearGradient22556">
+ <stop
+ id="stop22558"
+ offset="0"
+ style="stop-color:#6a9bef;stop-opacity:1" />
+ <stop
+ style="stop-color:#bccee8;stop-opacity:0.58450705;"
+ offset="0.77941167"
+ id="stop22568" />
+ <stop
+ id="stop22560"
+ offset="1"
+ style="stop-color:#ccdaed;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22556"
+ id="linearGradient22840"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient22838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient22882">
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="0"
+ id="stop22884" />
+ <stop
+ id="stop22886"
+ offset="0.21233012"
+ style="stop-color:#323232;stop-opacity:0.49803922;" />
+ <stop
+ id="stop22888"
+ offset="0.54086536"
+ style="stop-color:#323232;stop-opacity:1;" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0.49803922;"
+ offset="0.83381736"
+ id="stop22890" />
+ <stop
+ style="stop-color:#323232;stop-opacity:0;"
+ offset="1"
+ id="stop22892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient22880"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ id="linearGradient35407">
+ <stop
+ id="stop35409"
+ offset="0"
+ style="stop-color:#a17306;stop-opacity:1;" />
+ <stop
+ style="stop-color:#cca649;stop-opacity:1;"
+ offset="0.43277758"
+ id="stop35411" />
+ <stop
+ id="stop35413"
+ offset="1"
+ style="stop-color:#f9f5e9;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient35391">
+ <stop
+ id="stop35393"
+ offset="0"
+ style="stop-color:#322800;stop-opacity:1;" />
+ <stop
+ id="stop35395"
+ offset="1"
+ style="stop-color:#6e4800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient34157">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop34159" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop34161" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient22457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-25.5"
+ y1="36.828632"
+ x2="-25.5"
+ y2="26.027344" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22455"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-354,-314.00002)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22453"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-18)"
+ x1="-27.299919"
+ y1="37"
+ x2="-25.5"
+ y2="23.414351" />
+ <linearGradient
+ id="linearGradient21609">
+ <stop
+ id="stop21611"
+ offset="0"
+ style="stop-color:black;stop-opacity:1" />
+ <stop
+ id="stop21613"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21609"
+ id="linearGradient20961"
+ gradientUnits="userSpaceOnUse"
+ x1="162"
+ y1="103.71875"
+ x2="165"
+ y2="103.75" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask20957">
+ <rect
+ y="101"
+ x="162"
+ height="5"
+ width="8"
+ id="rect20959"
+ style="fill:url(#linearGradient20961);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32335"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient19900">
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:1;"
+ offset="0"
+ id="stop19902" />
+ <stop
+ style="stop-color:#1a1a1a;stop-opacity:0;"
+ offset="1"
+ id="stop19904" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18105">
+ <stop
+ id="stop18107"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18056">
+ <stop
+ id="stop18058"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18060"
+ offset="1"
+ style="stop-color:#295498;stop-opacity:0.34057972;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19625">
+ <stop
+ id="stop19627"
+ offset="0"
+ style="stop-color:#2258a6;stop-opacity:1;" />
+ <stop
+ id="stop19629"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient20217"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient18821">
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:1;"
+ offset="0"
+ id="stop18823" />
+ <stop
+ style="stop-color:#fc6b58;stop-opacity:0;"
+ offset="1"
+ id="stop18825" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ id="linearGradient29149">
+ <stop
+ id="stop29151"
+ offset="0"
+ style="stop-color:#76adff;stop-opacity:1;" />
+ <stop
+ id="stop29153"
+ offset="1"
+ style="stop-color:#a5c9ff;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient21820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient21818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21816"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21814"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient21741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient21773"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9281768,0,0,0.9971589,401.42265,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22166"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22164"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22162"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22160"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient22158"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient22156"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22154"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15809">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop15811" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop15813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15437">
+ <stop
+ id="stop15439"
+ offset="0"
+ style="stop-color:#20529e;stop-opacity:1;" />
+ <stop
+ id="stop15441"
+ offset="1"
+ style="stop-color:#1d3f71;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15425">
+ <stop
+ style="stop-color:#8c0000;stop-opacity:1;"
+ offset="0"
+ id="stop15427" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14262">
+ <stop
+ id="stop14264"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath17188">
+ <path
+ style="fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 240.5,-19.90625 c -1.87005,0 -3.40625,1.536202 -3.40625,3.40625 l 0,2 c 0,1.87005 1.53621,3.40625 3.40625,3.40625 l 0,-2.8125 c -0.33932,0 -0.59375,-0.254431 -0.59375,-0.59375 l 0,-2 c 0,-0.339319 0.25443,-0.59375 0.59375,-0.59375 l 0,-2.8125 z"
+ id="path17190"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient18344">
+ <stop
+ style="stop-color:#6c6c6c;stop-opacity:1;"
+ offset="0"
+ id="stop18346" />
+ <stop
+ style="stop-color:#f0f0f0;stop-opacity:1;"
+ offset="1"
+ id="stop18348" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060">
+ <stop
+ id="stop5062"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient27957">
+ <stop
+ id="stop27959"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0.59290552"
+ id="stop27963" />
+ <stop
+ id="stop27961"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23647">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop23649" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop23651" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23390">
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000"
+ offset="0.0000000"
+ id="stop23392" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000"
+ offset="1.0000000"
+ id="stop23400" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16359">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16361" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16363" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.26,-38.98429)"
+ x1="386.09836"
+ y1="230.09529"
+ x2="388.35962"
+ y2="248.10277" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15744"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,679.30638,-38.92179)"
+ x1="390.61163"
+ y1="229.34804"
+ x2="390.55936"
+ y2="248.24983" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.203777,0,0,0.903901,837.9645,-18.01568)"
+ x1="383.67041"
+ y1="225.94354"
+ x2="385.60632"
+ y2="248.55901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15681"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.207032,0,0,0.903901,839.2424,-18.01568)"
+ x1="391.80222"
+ y1="230.5647"
+ x2="387.94211"
+ y2="247.83209" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13545"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="137.11284"
+ y2="126.19643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15878"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient20756">
+ <stop
+ style="stop-color:#932200;stop-opacity:1;"
+ offset="0"
+ id="stop20758" />
+ <stop
+ style="stop-color:#f8420a;stop-opacity:1;"
+ offset="1"
+ id="stop20760" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient13543"
+ gradientUnits="userSpaceOnUse"
+ x1="126.45676"
+ y1="110.59049"
+ x2="134.94949"
+ y2="122.08995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15693"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="215.07817"
+ y1="109.00085"
+ x2="235.90916"
+ y2="121.88217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1.253963,1,0,169,-94.7765)"
+ x1="228.5468"
+ y1="118.5"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.222225,0,0,1,-87.33412,169)"
+ x1="217.22589"
+ y1="107.25085"
+ x2="235.90916"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15854"
+ gradientUnits="userSpaceOnUse"
+ x1="381.56296"
+ y1="234.59885"
+ x2="393"
+ y2="247.99632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient13639"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.987"
+ y1="259.26602"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52023"
+ gradientUnits="userSpaceOnUse"
+ x1="390.75"
+ y1="244.5312"
+ x2="395.9375"
+ y2="250.9062" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient14661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="400.88739"
+ y1="257.4874"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52025"
+ gradientUnits="userSpaceOnUse"
+ x1="391.01859"
+ y1="241.86644"
+ x2="396.79285"
+ y2="247.83134" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient15995"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8329616,0,0,0.8433415,58.576199,29.193917)"
+ x1="399.08661"
+ y1="257.41327"
+ x2="385.88068"
+ y2="241.70195" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15993"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15997"
+ gradientUnits="userSpaceOnUse"
+ x1="381.5"
+ y1="231.7812"
+ x2="393.4375"
+ y2="247.1562" />
+ <linearGradient
+ id="linearGradient47130">
+ <stop
+ style="stop-color:#ed7b00;stop-opacity:1;"
+ offset="0"
+ id="stop47132" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop47134" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient52027"
+ gradientUnits="userSpaceOnUse"
+ x1="329.28757"
+ y1="244.97151"
+ x2="339.84518"
+ y2="254.18553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15436"
+ gradientUnits="userSpaceOnUse"
+ x1="319.75095"
+ y1="234.63918"
+ x2="333.94208"
+ y2="248.68198" />
+ <linearGradient
+ id="linearGradient32842">
+ <stop
+ style="stop-color:#183e75;stop-opacity:1;"
+ offset="0"
+ id="stop32844" />
+ <stop
+ style="stop-color:#1d3f71;stop-opacity:0;"
+ offset="1"
+ id="stop32846" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient13900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2541045,-1.3755453,0.900369,1.4754358,-3699.4512,2858.7)"
+ cx="2357.1072"
+ cy="826.77924"
+ fx="2357.1072"
+ fy="826.77924"
+ r="6.1896501" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40983"
+ id="linearGradient38692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2226.9963,823)"
+ x1="130.70599"
+ y1="18.44199"
+ x2="130.70599"
+ y2="21.94199" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15717"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15715"
+ gradientUnits="userSpaceOnUse"
+ x1="320.2735"
+ y1="25.109356"
+ x2="332.41409"
+ y2="37.468754" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15713"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15709"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="323.37836"
+ y1="30.3883"
+ x2="343.5636"
+ y2="53.758793" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15646"
+ gradientUnits="userSpaceOnUse"
+ x1="279.00009"
+ y1="-16.62501"
+ x2="291.93054"
+ y2="-6.3206272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15644"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-253)"
+ x1="25.437477"
+ y1="238.54002"
+ x2="51.01355"
+ y2="263.79816" />
+ <linearGradient
+ id="linearGradient20973">
+ <stop
+ id="stop20975"
+ offset="0"
+ style="stop-color:#15ff00;stop-opacity:1;" />
+ <stop
+ id="stop20977"
+ offset="1"
+ style="stop-color:#15ff00;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20962">
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:1;"
+ offset="0"
+ id="stop20965" />
+ <stop
+ style="stop-color:#00a8ff;stop-opacity:0;"
+ offset="1"
+ id="stop20967" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20036">
+ <stop
+ style="stop-color:#ffb55e;stop-opacity:1;"
+ offset="0"
+ id="stop20038" />
+ <stop
+ style="stop-color:#ff8400;stop-opacity:0;"
+ offset="1"
+ id="stop20040" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15574"
+ gradientUnits="userSpaceOnUse"
+ x1="197.63152"
+ y1="169.14206"
+ x2="190.41687"
+ y2="160.02296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15358"
+ gradientUnits="userSpaceOnUse"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15362"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15360"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,39.669142,20)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14517"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3959732"
+ y1="216.62332"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16069"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="17.011419"
+ y2="82.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient16067"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2859754,0,0,1,-440.36032,-147)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16063"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="6.9917974"
+ y1="219.61856"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16154"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16150"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.8504581"
+ y1="217.4549"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16174"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="2.911078"
+ y1="217.3624"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8520698,0,0,0.7746114,324.58589,47.486124)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ id="linearGradient13998">
+ <stop
+ id="stop14000"
+ offset="0"
+ style="stop-color:#f57d07;stop-opacity:1;" />
+ <stop
+ id="stop14002"
+ offset="1"
+ style="stop-color:white;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4343">
+ <stop
+ id="stop4345"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop4347"
+ offset="1"
+ style="stop-color:#fff9f9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,747.50001,337.33345)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15053"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.166667,-441,-81.66662)"
+ x1="43.647511"
+ y1="164.125"
+ x2="75.731438"
+ y2="164.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15705"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15703"
+ gradientUnits="userSpaceOnUse"
+ x1="146.80022"
+ y1="158.34668"
+ x2="150.08357"
+ y2="162.03282" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15701"
+ gradientUnits="userSpaceOnUse"
+ x1="148.71947"
+ y1="166.53206"
+ x2="147"
+ y2="165" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15699"
+ gradientUnits="userSpaceOnUse"
+ x1="122.84515"
+ y1="126.83902"
+ x2="149.88129"
+ y2="164.94562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15742"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="227.57907"
+ y1="118.47696"
+ x2="235"
+ y2="118.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.97577,-6.0080883)"
+ x1="222.4996"
+ y1="110.37873"
+ x2="233.08319"
+ y2="121" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-6.0080883)"
+ x1="230.95012"
+ y1="100.89436"
+ x2="230.74091"
+ y2="124.09359" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15778"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="135.54141"
+ y2="122.0597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15780"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15776"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10.767079)"
+ x1="132.35471"
+ y1="246.32236"
+ x2="129.81586"
+ y2="243.70523" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15774"
+ gradientUnits="userSpaceOnUse"
+ x1="103.53399"
+ y1="88.301094"
+ x2="136.3542"
+ y2="123.17216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15450"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15452"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient15448"
+ gradientUnits="userSpaceOnUse"
+ x1="132.12782"
+ y1="246.32236"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15446"
+ gradientUnits="userSpaceOnUse"
+ x1="87.969383"
+ y1="69.87941"
+ x2="135.40274"
+ y2="121.19196" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15582"
+ gradientUnits="userSpaceOnUse"
+ x1="9.062501"
+ y1="117.46875"
+ x2="24.625006"
+ y2="131.65625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15584"
+ gradientUnits="userSpaceOnUse"
+ x1="28.607456"
+ y1="116.80592"
+ x2="43.766914"
+ y2="131.5226" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15124"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient15122"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient16025"
+ gradientUnits="userSpaceOnUse"
+ x1="192.11751"
+ y1="122.12527"
+ x2="184.43379"
+ y2="112.34031" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.395521,0,0,-0.3955,275.223,171.0515)"
+ x1="213.51967"
+ y1="121.417"
+ x2="204.05295"
+ y2="111.7235" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.607961,0,0,0.607967,64.49194,51.63899)"
+ x1="213.53587"
+ y1="122.66508"
+ x2="203.33264"
+ y2="112.67535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15748"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="349.04059"
+ y1="143.70836"
+ x2="336.72485"
+ y2="117.00745" />
+ <linearGradient
+ id="linearGradient10585">
+ <stop
+ id="stop10587"
+ offset="0.0000000"
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;" />
+ <stop
+ id="stop10595"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4138">
+ <stop
+ style="stop-color:#6c432f;stop-opacity:1;"
+ offset="0"
+ id="stop4140" />
+ <stop
+ style="stop-color:#c0966d;stop-opacity:1;"
+ offset="1"
+ id="stop4142" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31320">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12678">
+ <stop
+ id="stop12680"
+ offset="0"
+ style="stop-color:#d40000;stop-opacity:1" />
+ <stop
+ id="stop12682"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13520"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.401389,-3.2412)"
+ x1="130.59862"
+ y1="121.2412"
+ x2="142.29109"
+ y2="133.53448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23215"
+ x1="147.07098"
+ y1="134.18185"
+ x2="129.67148"
+ y2="115.54105"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient23178">
+ <stop
+ style="stop-color:#ff992b;stop-opacity:1;"
+ offset="0"
+ id="stop23180" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop23182" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13973">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient13938">
+ <stop
+ id="stop13940"
+ offset="0"
+ style="stop-color:#6e0c00;stop-opacity:1;" />
+ <stop
+ id="stop13942"
+ offset="1"
+ style="stop-color:#ee3800;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14232">
+ <stop
+ style="stop-color:#fff32a;stop-opacity:1;"
+ offset="0"
+ id="stop14234" />
+ <stop
+ style="stop-color:#fff551;stop-opacity:0;"
+ offset="1"
+ id="stop14236" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient14418">
+ <stop
+ id="stop14420"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-26,2.9206276e-6)"
+ x1="474"
+ y1="73.999992"
+ x2="477.25"
+ y2="77.499992" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient14841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,1.4603138e-6)"
+ x1="474.84375"
+ y1="75"
+ x2="477.5"
+ y2="77.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18852"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18850"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18848"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18901"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(279.04534,461.00001)"
+ x1="151"
+ y1="-234"
+ x2="149.95467"
+ y2="-239.14549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.04419,461)"
+ x1="151"
+ y1="-234"
+ x2="150.25"
+ y2="-236.85815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280.99885,461)"
+ x1="150.11926"
+ y1="-235.21587"
+ x2="145.20955"
+ y2="-241.85452" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient18896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,459)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(280,461)"
+ x1="150.95467"
+ y1="-234.00002"
+ x2="147.41411"
+ y2="-239.28557" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17535"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17533"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17527"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18207">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18209" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop18211" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient18213"
+ x1="481.46063"
+ y1="219"
+ x2="519.44189"
+ y2="218.48816"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17506"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="148.15451"
+ y1="-216.25"
+ x2="157.91019"
+ y2="-216.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17504"
+ gradientUnits="userSpaceOnUse"
+ x1="107.15463"
+ y1="-227.83138"
+ x2="105.81714"
+ y2="-219.8996" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient17502"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="136.51436"
+ y2="-217.99782" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17500"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.000285,-20.002166)"
+ x1="135.30351"
+ y1="-219.54408"
+ x2="123.63815"
+ y2="-219.49783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17498"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-22)"
+ x1="157.97339"
+ y1="-215.99998"
+ x2="146.36111"
+ y2="-215.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient18670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2078427,0,0,1.0516432,-357.40769,69.427229)"
+ x1="362.28571"
+ y1="-45.098213"
+ x2="352.46426"
+ y2="-54.124699" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18666">
+ <rect
+ y="6"
+ x="62.921577"
+ height="14.000001"
+ width="15.098035"
+ id="rect18668"
+ style="fill:url(#linearGradient18670);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15592"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15590"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="135.54628"
+ y2="120.58403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15596"
+ gradientUnits="userSpaceOnUse"
+ x1="124.52369"
+ y1="112.22441"
+ x2="131.10667"
+ y2="118.10129" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient15594"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="134.62978"
+ y2="120.14633" />
+ <linearGradient
+ id="linearGradient14219">
+ <stop
+ id="stop14221"
+ offset="0"
+ style="stop-color:#ff8605;stop-opacity:1;" />
+ <stop
+ id="stop14223"
+ offset="1"
+ style="stop-color:#9c6700;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient31456">
+ <stop
+ style="stop-color:#2b1600;stop-opacity:1;"
+ offset="0"
+ id="stop31458" />
+ <stop
+ style="stop-color:#6e3900;stop-opacity:0;"
+ offset="1"
+ id="stop31460" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient19425">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop19427" />
+ <stop
+ id="stop19431"
+ offset="0.63109845"
+ style="stop-color:#fffffe;stop-opacity:0.65789473;" />
+ <stop
+ style="stop-color:#fffffe;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop19429" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient30208">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop30210" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop30212" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15782"
+ gradientUnits="userSpaceOnUse"
+ x1="125.19086"
+ y1="125.66204"
+ x2="132.98256"
+ y2="118" />
+ <linearGradient
+ id="linearGradient9030">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542">
+ <stop
+ id="stop37544"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30124">
+ <stop
+ style="stop-color:#1d4a8c;stop-opacity:1;"
+ offset="0"
+ id="stop30126" />
+ <stop
+ style="stop-color:#c1d4f2;stop-opacity:1;"
+ offset="1"
+ id="stop30128" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient15893">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop15895" />
+ <stop
+ id="stop15897"
+ offset="0.37679368"
+ style="stop-color:#b5ccf0;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b5ccf0;stop-opacity:1;"
+ offset="0.59786767"
+ id="stop15899" />
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="1"
+ id="stop15901" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient24000">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop24002" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop24004" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient32998">
+ <stop
+ style="stop-color:#2968c3;stop-opacity:1;"
+ offset="0"
+ id="stop33000" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop33002" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.9445,114.0045)"
+ x1="272.05627"
+ y1="24.537012"
+ x2="283.42514"
+ y2="37.115723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="radialGradient21517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.891843,0,0,0.909224,-173.99085,171.21624)"
+ cx="350.5"
+ cy="14.5"
+ fx="350.5"
+ fy="14.5"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21641"
+ gradientUnits="userSpaceOnUse"
+ x1="127.50285"
+ y1="114.74636"
+ x2="133.62564"
+ y2="120.24665" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient21643"
+ gradientUnits="userSpaceOnUse"
+ x1="126.15096"
+ y1="113.21745"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20796"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(159.9998,-41.00751)"
+ x1="261.44702"
+ y1="234.6606"
+ x2="274.30609"
+ y2="247.73561" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20798"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(199.9999,105.99249)"
+ x1="235.46884"
+ y1="103"
+ x2="228.71886"
+ y2="94.53125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.2344713"
+ y1="215.76874"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21864"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="19.011419"
+ y2="86" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient21902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="3.3268692"
+ y1="215.35608"
+ x2="33.15686"
+ y2="247.71701" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient21904"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.51141"
+ y2="85.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000006,0,0,1,258.9997,-237)"
+ x1="24.374985"
+ y1="238.33629"
+ x2="55.384842"
+ y2="269.1373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,16)"
+ x1="278.55817"
+ y1="-16.978563"
+ x2="291.577"
+ y2="-5.8786855" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient31650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.816279,0,-3.646264e-6,0.779872,56.32029,28.34496)"
+ cx="306.55292"
+ cy="11.818644"
+ fx="306.55292"
+ fy="11.818644"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="radialGradient31652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.580596,1.138426,-0.692447,0.961382,-175.3891,-329.6844)"
+ cx="312.80765"
+ cy="10.620173"
+ fx="312.80765"
+ fy="10.620173"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20962"
+ id="radialGradient31654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.48445,-0.00657397,0.00734631,1.660903,-154.1629,19.305572)"
+ cx="313.74268"
+ cy="15.619254"
+ fx="313.74268"
+ fy="15.619254"
+ r="4.25" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20973"
+ id="radialGradient31656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.756245,0,-3.378096e-6,0.722516,72.63115,31.07857)"
+ cx="309.0571"
+ cy="15.518281"
+ fx="309.0571"
+ fy="15.518281"
+ r="4.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31664"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8579582,0,0,0.9285714,7.397998,-211.96428)"
+ x1="-6.3249049"
+ y1="205.0083"
+ x2="32.351238"
+ y2="248.75177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9569715,-1,0,259,351.18743)"
+ x1="347.6467"
+ y1="216.75188"
+ x2="345.98633"
+ y2="243.92201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166667,0,0,0.9166667,24.364541,-55.041665)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="18.01141"
+ y2="84.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.9297203,-1.2117965,0,305.73028,342.22894)"
+ x1="346.15555"
+ y1="218.2382"
+ x2="346.58698"
+ y2="238.44429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31694"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient31696"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="64.998215"
+ y1="90.951675"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,105.5221,92.482413)"
+ x1="257.0376"
+ y1="10.838325"
+ x2="277.61203"
+ y2="31.019331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient31934"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7827973,0,0,0.9989462,77.082208,42.08484)"
+ x1="332.03717"
+ y1="68.624634"
+ x2="346.08932"
+ y2="83.002625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31936"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(262,-125)"
+ x1="79.329903"
+ y1="236"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient33666"
+ gradientUnits="userSpaceOnUse"
+ x1="124.14184"
+ y1="126.23546"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33668"
+ gradientUnits="userSpaceOnUse"
+ x1="125.45158"
+ y1="125.94608"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33670"
+ gradientUnits="userSpaceOnUse"
+ x1="142.97318"
+ y1="107.64013"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33681"
+ gradientUnits="userSpaceOnUse"
+ x1="139.93341"
+ y1="110.56118"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient33700"
+ gradientUnits="userSpaceOnUse"
+ x1="149.55772"
+ y1="98.630066"
+ x2="123.9021"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10540"
+ gradientUnits="userSpaceOnUse"
+ x1="130.95198"
+ y1="117.09563"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient11333"
+ gradientUnits="userSpaceOnUse"
+ x1="119.1647"
+ y1="106.08605"
+ x2="133.01006"
+ y2="119.79803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-425,393.99999)"
+ x1="225.6198"
+ y1="5.7625732"
+ x2="236.47855"
+ y2="14.103563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient28077"
+ x1="306.26187"
+ y1="272"
+ x2="307"
+ y2="263.55374"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="431.05026"
+ y1="121.42467"
+ x2="446.26407"
+ y2="110.49417" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28528"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="442.69827"
+ y1="107.56771"
+ x2="450.27414"
+ y2="122.95798" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-474,158.25)"
+ x1="437.57828"
+ y1="104.34499"
+ x2="447.96875"
+ y2="117.90625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient28532"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10982"
+ x1="207.04637"
+ y1="182.09375"
+ x2="213.7883"
+ y2="182.52524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient10984"
+ x1="212.04637"
+ y1="182.09375"
+ x2="222.35799"
+ y2="182.77524"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11762"
+ x1="371.98389"
+ y1="203"
+ x2="376.48389"
+ y2="203"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11764"
+ x1="366.98389"
+ y1="203"
+ x2="370.98389"
+ y2="202.75"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient11766"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient12427"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14219"
+ id="radialGradient12429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5007214,0.3131662,-0.3623683,0.5793905,300.02235,-93.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16359"
+ id="linearGradient12602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,456.04574,-116.51416)"
+ x1="88.079262"
+ y1="66.110847"
+ x2="95.954262"
+ y2="58.272621" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient12114"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1438.0001,-418)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1830.2675,-33.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1397.7474,-388.72044)"
+ x1="1984.5453"
+ y1="828.21777"
+ x2="1978.11"
+ y2="829.35315" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient12215"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient12217"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient12305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="257.24991"
+ y1="147.38998"
+ x2="262.24991"
+ y2="152.46707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient12307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1997014,-125.70008,-191.68873)"
+ x1="258.08322"
+ y1="147.87068"
+ x2="264.16571"
+ y2="153.8233" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13046"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-161.99999)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13041">
+ <rect
+ style="fill:url(#linearGradient13046);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect13043"
+ width="7"
+ height="8"
+ x="276"
+ y="-12" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient13056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-145.93749)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask13052">
+ <rect
+ y="4.0625"
+ x="276"
+ height="8"
+ width="7"
+ id="rect13054"
+ style="fill:url(#linearGradient13056);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="443.86667"
+ y1="133.98936"
+ x2="451.98389"
+ y2="143.58749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="453.61005"
+ y2="133.00301" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-636.98388,52.01562)"
+ x1="449.14645"
+ y1="136.18045"
+ x2="453.24457"
+ y2="138.7879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4138"
+ id="linearGradient14173"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-635.98388,53.01562)"
+ x1="456.03769"
+ y1="135.76678"
+ x2="454.31345"
+ y2="133.62801" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient13112"
+ gradientUnits="userSpaceOnUse"
+ x1="133.42287"
+ y1="120.62622"
+ x2="126.67323"
+ y2="113.20281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13114"
+ gradientUnits="userSpaceOnUse"
+ x1="120.77391"
+ y1="106.19939"
+ x2="144.64095"
+ y2="129.62753" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8289081,0,0,2.1560411,236.27148,-864.45588)"
+ x1="212"
+ y1="435.59741"
+ x2="211.99998"
+ y2="435.32159" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1035181,0,0,1,158.18497,-359.77344)"
+ x1="229.6875"
+ y1="440.51562"
+ x2="238.53125"
+ y2="440.57812" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23390"
+ id="radialGradient16034"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8126517,-0.04317018,0.04642643,1.9485655,-18.817545,-774.28453)"
+ cx="224.32494"
+ cy="441.84744"
+ fx="224.32494"
+ fy="441.84744"
+ r="6.7191267" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient16036"
+ gradientUnits="userSpaceOnUse"
+ x1="211.99998"
+ y1="435.7319"
+ x2="211.99998"
+ y2="436.07974"
+ gradientTransform="matrix(0.9803611,0,0,2.1560411,204.16345,-864.45588)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23647"
+ id="linearGradient16039"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(182,-359.75)"
+ x1="221.96414"
+ y1="439.75"
+ x2="238.87605"
+ y2="448.88205" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17656"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0008786,0,0,1.081555,-21.021535,-187.45087)"
+ x1="-12.839478"
+ y1="201"
+ x2="44.522621"
+ y2="256.70349" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.099576,0,0,1.0999923,190.46996,204.85062)"
+ x1="9.6310225"
+ y1="76"
+ x2="15"
+ y2="81" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,370.43125,-83.863716)"
+ x1="-5.6700387"
+ y1="250.87607"
+ x2="-46.452946"
+ y2="251.42462" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17714"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,280.08766,104.72255)"
+ x1="102.61966"
+ y1="50.742527"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient12655"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient12658"
+ gradientUnits="userSpaceOnUse"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,141.28585,391.96271)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient13513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8193413,0,0,0.8193419,-388.72692,-564.02452)"
+ x1="150.4086"
+ y1="104.61366"
+ x2="151.40744"
+ y2="105.64391" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient13527"
+ gradientUnits="userSpaceOnUse"
+ x1="328.95557"
+ y1="33.94022"
+ x2="331.74063"
+ y2="37.044456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient13529"
+ gradientUnits="userSpaceOnUse"
+ x1="328.38852"
+ y1="33.505165"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(68.016116,127.00002)"
+ x1="97.983887"
+ y1="127.99998"
+ x2="88.983887"
+ y2="115.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient14570"
+ gradientUnits="userSpaceOnUse"
+ x1="94.485573"
+ y1="122.13319"
+ x2="89.207298"
+ y2="125.83332" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14572"
+ gradientUnits="userSpaceOnUse"
+ x1="88.560204"
+ y1="127.88263"
+ x2="94.011101"
+ y2="123.83599" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient47130"
+ id="linearGradient13699"
+ x1="-162.89217"
+ y1="245"
+ x2="-174.18907"
+ y2="224.99274"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26282"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient26284"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26286"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14198"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient14204"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15195"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient15209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15211"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient15363"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9999519,0,0,0.9998051,-33.993941,254.01926)"
+ x1="101.21339"
+ y1="68.783279"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient15365"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,40.331334,244.81698)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10585"
+ id="linearGradient15367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.032977,0,0,1,128.82015,107.77516)"
+ x1="12.330792"
+ y1="246.97107"
+ x2="41.654194"
+ y2="247.3784" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient15383"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient14377"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.691866,0.00341)"
+ x1="86.452194"
+ y1="101.22832"
+ x2="110.48556"
+ y2="81.14637" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient16640"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(42,0)"
+ x1="85.874489"
+ y1="501.74075"
+ x2="26.561054"
+ y2="498.48148" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient16642"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient16644"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16646"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,300.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient16648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4624192,0,0,1.4467089,-36.975824,-224.99718)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient16650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient32447"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30231"
+ gradientUnits="userSpaceOnUse"
+ x1="441.48248"
+ y1="105.03784"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient30233"
+ gradientUnits="userSpaceOnUse"
+ x1="445.37457"
+ y1="112.86145"
+ x2="425.92511"
+ y2="84.928581" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30235"
+ gradientUnits="userSpaceOnUse"
+ x1="440.68439"
+ y1="106.0996"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30237"
+ gradientUnits="userSpaceOnUse"
+ x1="440.34833"
+ y1="105.74502"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30239"
+ gradientUnits="userSpaceOnUse"
+ x1="440.7211"
+ y1="104.97093"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23302"
+ id="linearGradient30241"
+ gradientUnits="userSpaceOnUse"
+ x1="414.99771"
+ y1="-35"
+ x2="414.99771"
+ y2="-36.625011" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24081"
+ id="linearGradient30243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.00461"
+ y1="-34"
+ x2="415.94211"
+ y2="-37.718761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient30247"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.41162"
+ y1="-34.342831"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30249"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30326"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30328"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30330"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30332"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30334"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30336"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30338"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30340"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30344"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30346"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30348"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30394"
+ gradientUnits="userSpaceOnUse"
+ x1="446.05634"
+ y1="112.72269"
+ x2="436.76331"
+ y2="100.6615" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30396"
+ gradientUnits="userSpaceOnUse"
+ x1="440.03735"
+ y1="103.53646"
+ x2="446.73828"
+ y2="111.74544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30398"
+ gradientUnits="userSpaceOnUse"
+ x1="447.06949"
+ y1="114.61743"
+ x2="432.36887"
+ y2="94.07222" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30400"
+ gradientUnits="userSpaceOnUse"
+ x1="438.92477"
+ y1="103.46223"
+ x2="446.00906"
+ y2="110.93529" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30402"
+ gradientUnits="userSpaceOnUse"
+ x1="439.0434"
+ y1="104.06953"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30404"
+ gradientUnits="userSpaceOnUse"
+ x1="439.04333"
+ y1="104.0401"
+ x2="445.36435"
+ y2="110.27587" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30406"
+ gradientUnits="userSpaceOnUse"
+ x1="415.00003"
+ y1="-33.99012"
+ x2="415"
+ y2="-36.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30408"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="415.41223"
+ y1="-31.506163"
+ x2="415.45193"
+ y2="-37.520515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.004608,0)"
+ x1="416.5"
+ y1="-29.933779"
+ x2="416.5"
+ y2="-37.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="416.5"
+ y1="-33.8125"
+ x2="416.46497"
+ y2="-39.140816" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30414"
+ gradientUnits="userSpaceOnUse"
+ x1="409.00003"
+ y1="-40.99012"
+ x2="413.49658"
+ y2="-34.707108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient30416"
+ gradientUnits="userSpaceOnUse"
+ x1="408.75"
+ y1="-35.483223"
+ x2="408.75"
+ y2="-40.000008" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-394.58897,440.54169)"
+ x1="326.51352"
+ y1="32.007874"
+ x2="347.91187"
+ y2="57.261913" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17431"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-400.00857,439.95001)"
+ x1="317.30908"
+ y1="22.7787"
+ x2="330.87869"
+ y2="38.161732" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask17570">
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ d="m -44,358 0,14 14,-14 -14,0 z"
+ id="path17572"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18682"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.9230835,365.8517,-147.63686)"
+ x1="27.405855"
+ y1="189.20862"
+ x2="35.029804"
+ y2="248.37102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18690"
+ gradientUnits="userSpaceOnUse"
+ x1="29.972469"
+ y1="164"
+ x2="29.972469"
+ y2="168"
+ gradientTransform="translate(359.05264,-81.98142)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="30.435225"
+ y1="202.99998"
+ x2="30.435225"
+ y2="251.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18756"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18779"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6923077,0,0,-0.6923079,29.049874,351.11545)"
+ x1="7.9951181"
+ y1="264.90152"
+ x2="32.267426"
+ y2="237.9342" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-122.98388,276)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5384613,0,0,0.538461,-189.69233,224.07704)"
+ x1="29.142912"
+ y1="161.42842"
+ x2="29.142912"
+ y2="252.42851" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.538461,-193.81309,224.07705)"
+ x1="29.871567"
+ y1="153.99983"
+ x2="29.871567"
+ y2="252.4285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18846"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.462416,0,0,0.461541,-193.81309,236.42243)"
+ x1="29.871567"
+ y1="174.58366"
+ x2="29.871567"
+ y2="259.08319" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18854"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2500001,0,0,2.2000001,-102.35484,177)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.8000001,-122.98388,285.5)"
+ x1="-55.936718"
+ y1="77.808868"
+ x2="-55.844753"
+ y2="84.217026" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.0000001,0,0,1.6000003,163.54205,53.499972)"
+ x1="-60.266121"
+ y1="74.0625"
+ x2="-54.766121"
+ y2="84.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32725"
+ gradientUnits="userSpaceOnUse"
+ x1="-88.0625"
+ y1="364"
+ x2="-44.983891"
+ y2="411.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-117.02574,313.78567)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient32729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6666675,0,0,0.6666633,-101.32265,336.66698)"
+ x1="61.983898"
+ y1="88.999977"
+ x2="89.770271"
+ y2="121.709" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-122.97299,306.4115)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient32749"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-123.05997,-52.467545)"
+ x1="326.72092"
+ y1="33.927608"
+ x2="352.03485"
+ y2="60.463093" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32751"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="-46.417774"
+ y1="1.9796312"
+ x2="-21.988398"
+ y2="27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-128.47957,-53.059225)"
+ x1="324.13901"
+ y1="28.882492"
+ x2="333.96365"
+ y2="39.250004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient17135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(18,0)"
+ x1="-51.6875"
+ y1="442.6875"
+ x2="-42.377892"
+ y2="452.20007" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17177"
+ gradientUnits="userSpaceOnUse"
+ x1="28.322077"
+ y1="160.10768"
+ x2="32.679554"
+ y2="164.34546" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient17179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-6.8461644e-7,-1.8,1.1087755,0.00352366,-193.46828,187.54551)"
+ cx="4.351675"
+ cy="81.592964"
+ fx="4.351675"
+ fy="81.592964"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18344"
+ id="radialGradient17181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5123107,0.9569981,-0.5028837,0.7946898,-131.57281,-236.33663)"
+ cx="244.14325"
+ cy="-14.13948"
+ fx="244.14325"
+ fy="-14.13948"
+ r="3.4000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17214"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17216"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17218"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2859748,0,0,1,-272.87621,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4289612,0,0,1,-326.93899,144.5)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17222"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="29.352921"
+ y1="199"
+ x2="29.352921"
+ y2="250" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17224"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient17226"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2868892,0,0,1,-644.69395,148)"
+ x1="348.06064"
+ y1="220.55545"
+ x2="363.71661"
+ y2="239.94608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,-18.1369,-168)"
+ x1="9.5404434"
+ y1="223.47467"
+ x2="36.247395"
+ y2="249.62102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2222204,0,-15.888744)"
+ x1="5.9836898"
+ y1="71.51989"
+ x2="16.733877"
+ y2="88" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="103.65562"
+ y1="49.547874"
+ x2="120.79755"
+ y2="57.84819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient18721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,244.3928,19.4113)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320"
+ id="linearGradient18728"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="linearGradient18765"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,309.42934,-349.44584)"
+ x1="-26.207859"
+ y1="252.77303"
+ x2="-5.4963508"
+ y2="253.15045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient35488"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35490"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient35492"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient35494"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35967"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.656002,0,0,0.656002,88.923481,27.003843)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath18524">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.1435655,0,0,1.1436475,512.11415,45.72091)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path18526"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.69954133;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.3473305"
+ inkscape:transform-center-y="-6.3853012" />
+ </clipPath>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask18634">
+ <path
+ sodipodi:nodetypes="ccccscc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 207,134 0,14 11,0 0,-7.5625 c -1.97252,-0.24738 -3.5,-1.89814 -3.5,-3.9375 0,-0.94675 0.35614,-1.81444 0.90625,-2.5 L 207,134 z"
+ id="path18636"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient18478"
+ gradientUnits="userSpaceOnUse"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18480"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-97.983877,565.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18739"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,43.55464,-148.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="16.173666"
+ y2="173.23431" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4343"
+ id="linearGradient18741"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5990464,-0.03583042,0.03242597,0.6546824,59.652868,-253.61658)"
+ x1="-12.264804"
+ y1="333.22653"
+ x2="-10.869003"
+ y2="334.86029" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18743"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(250.01612,148)"
+ x1="-190.37566"
+ y1="-180.13821"
+ x2="-189.34792"
+ y2="-182" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient19045"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,-461,-82.584001)"
+ x1="42.033173"
+ y1="164.51399"
+ x2="75.32457"
+ y2="164.51399" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient19047"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(298,-53.749881)"
+ x1="118.1319"
+ y1="157.11609"
+ x2="85.577972"
+ y2="157.54283" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient19049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3333334,0,0,0.8333334,767.51613,327.08335)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35583"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="4.952816"
+ y2="-27.882322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35585"
+ gradientUnits="userSpaceOnUse"
+ x1="-0.78523314"
+ y1="-33.408295"
+ x2="3.1666665"
+ y2="-29.550003" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35587"
+ gradientUnits="userSpaceOnUse"
+ x1="-3.5"
+ y1="-35.5"
+ x2="2.6932251"
+ y2="-29.488832" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35589"
+ gradientUnits="userSpaceOnUse"
+ x1="4.9341426"
+ y1="-29.678047"
+ x2="4.8398785e-16"
+ y2="-32.351803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35591"
+ gradientUnits="userSpaceOnUse"
+ x1="0.5079475"
+ y1="-32.317398"
+ x2="4.2000003"
+ y2="-28.597046" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient35593"
+ gradientUnits="userSpaceOnUse"
+ x1="2.8144052"
+ y1="-28.1"
+ x2="-4.375"
+ y2="-36.441402" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35595"
+ gradientUnits="userSpaceOnUse"
+ x1="-2.7708333"
+ y1="-35.5"
+ x2="1.1666667"
+ y2="-32" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient35740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707654,0,0,0.707942,-206.46148,-296.13985)"
+ x1="35.597904"
+ y1="158.14117"
+ x2="10.490564"
+ y2="176.41806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient35742"
+ gradientUnits="userSpaceOnUse"
+ x1="58.060974"
+ y1="-23.721956"
+ x2="40"
+ y2="-35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35744"
+ gradientUnits="userSpaceOnUse"
+ x1="46.1875"
+ y1="-28.59375"
+ x2="41.099998"
+ y2="-33.59375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36116"
+ id="linearGradient35746"
+ gradientUnits="userSpaceOnUse"
+ x1="46"
+ y1="-32"
+ x2="43.883884"
+ y2="-33.939339" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35748"
+ gradientUnits="userSpaceOnUse"
+ x1="41"
+ y1="-29"
+ x2="43"
+ y2="-27" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35750"
+ gradientUnits="userSpaceOnUse"
+ x1="48.662914"
+ y1="-27.071922"
+ x2="43.47097"
+ y2="-32.337086" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6.3,-4.7)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.200001"
+ y2="-28.640625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.315625,-3.75)"
+ x1="39.200001"
+ y1="-30.799999"
+ x2="41.325001"
+ y2="-28.765625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35756"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(3.3,0.3)"
+ x1="38.700001"
+ y1="-31.299999"
+ x2="40.012501"
+ y2="-29.799999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35772"
+ gradientUnits="userSpaceOnUse"
+ x1="51.912914"
+ y1="-24.696922"
+ x2="40.75"
+ y2="-35.75"
+ gradientTransform="translate(-0.75,4.75)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51774"
+ gradientUnits="userSpaceOnUse"
+ x1="135.32962"
+ y1="120.04005"
+ x2="130.7244"
+ y2="116.31882" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51776"
+ gradientUnits="userSpaceOnUse"
+ x1="130.9015"
+ y1="115.23484"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient51804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.43697,300.37199)"
+ x1="107.78085"
+ y1="50.778313"
+ x2="111.53449"
+ y2="46.679707" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.55698,300.497)"
+ x1="115.37703"
+ y1="51.021076"
+ x2="112.87534"
+ y2="51.021076" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient51808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,111.35699,300.55457)"
+ x1="110.57378"
+ y1="50.963791"
+ x2="108.07208"
+ y2="50.963791" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51810"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.36783,218.31526)"
+ x1="-13.691219"
+ y1="241.78653"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient51812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5192341,-0.5192341,0.5184617,0.5184617,100.13133,218.33837)"
+ x1="-9.0782614"
+ y1="249.96617"
+ x2="-2.9318311"
+ y2="240.68927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.5254431"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.89375,-187.79999)"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.091064"
+ y2="242.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68941"
+ gradientUnits="userSpaceOnUse"
+ x1="-41.065678"
+ y1="240.10526"
+ x2="-15.758821"
+ y2="244.11874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(440.2082,-188.0039)"
+ x1="-10.991813"
+ y1="237.9574"
+ x2="-7.0786314"
+ y2="246.7774" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(439.9582,-188.0039)"
+ x1="-5.1338587"
+ y1="244.08765"
+ x2="-14.193665"
+ y2="251.35759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8864"
+ id="linearGradient68947"
+ gradientUnits="userSpaceOnUse"
+ x1="-15.6"
+ y1="247.38559"
+ x2="-3.321322"
+ y2="245.68124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68949"
+ gradientUnits="userSpaceOnUse"
+ x1="-5.3499999"
+ y1="251.51265"
+ x2="-8.7065439"
+ y2="248.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient68951"
+ gradientUnits="userSpaceOnUse"
+ x1="-10.35"
+ y1="245.89999"
+ x2="-13.125"
+ y2="242.81946" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.25,0.2058042)"
+ x1="-12.538609"
+ y1="240.79787"
+ x2="0.92051411"
+ y2="237.27565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient68955"
+ gradientUnits="userSpaceOnUse"
+ x1="-7.20822"
+ y1="247.4906"
+ x2="-1.7751017"
+ y2="239.86711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient69009"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5466301,0,0,1.6489946,-293.01107,-16.485383)"
+ x1="582"
+ y1="49.294117"
+ x2="582"
+ y2="47.176472" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask69005">
+ <rect
+ style="fill:url(#linearGradient69009);fill-opacity:1;display:inline"
+ id="rect69007"
+ width="24.746082"
+ height="26.383913"
+ x="596.30127"
+ y="39.580433" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient20269"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient20275"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20283"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20303"
+ gradientUnits="userSpaceOnUse"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient20309"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient21567"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2798768,0,0,0.279916,6.0465962,-0.3619733)"
+ cx="20.892099"
+ cy="114.5684"
+ fx="20.892099"
+ fy="114.5684"
+ r="5.256" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21596"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21647"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21649"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient21977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient21979"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath22590">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22592"
+ width="12"
+ height="14"
+ x="-30"
+ y="490.00012" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.1666667,-737,357.33333)"
+ x1="771.0965"
+ y1="354.28479"
+ x2="772"
+ y2="358.85715" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask23591">
+ <rect
+ mask="none"
+ style="fill:url(#linearGradient23595);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23593"
+ width="11"
+ height="14"
+ x="30"
+ y="768" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath23877">
+ <rect
+ transform="scale(1,-1)"
+ y="-540"
+ x="952"
+ height="6"
+ width="15"
+ id="rect23879"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23978"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23980"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320"
+ id="linearGradient23982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.733333,808.99997,-697.8)"
+ x1="150.5"
+ y1="239.9987"
+ x2="150.5"
+ y2="237" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29485"
+ id="linearGradient23986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,715,364)"
+ x1="147.0625"
+ y1="243.76387"
+ x2="142.9375"
+ y2="243.69914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30777"
+ id="linearGradient23988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2857143,364,645.14283)"
+ x1="148"
+ y1="244.11113"
+ x2="144"
+ y2="244.11113" />
+ <linearGradient
+ id="linearGradient3564"
+ inkscape:collect="always">
+ <stop
+ id="stop3566"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop3568"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39155">
+ <stop
+ id="stop39157"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39159"
+ offset="1"
+ style="stop-color:#dadada;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39171"
+ inkscape:collect="always">
+ <stop
+ id="stop39173"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop39175"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient21442"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39155"
+ id="linearGradient21444"
+ gradientUnits="userSpaceOnUse"
+ x1="31.1875"
+ y1="18.875"
+ x2="29.875"
+ y2="34.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3564"
+ id="linearGradient21446"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06818845,0,0,0.06818845,22.51112,27.02885)"
+ x1="185.9903"
+ y1="193.33229"
+ x2="190.46461"
+ y2="-458.05771" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39171"
+ id="radialGradient21448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.647222,0,0,1.26792,-15.47413,-5.79794)"
+ cx="26.109201"
+ cy="19.668886"
+ fx="26.109201"
+ fy="19.668886"
+ r="20.278975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient22274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="32.076183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38721"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39281"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="71"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39283"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1944456,0,0,1.2000039,-34.222431,-14.950295)"
+ x1="175.17659"
+ y1="74.972061"
+ x2="176.40117"
+ y2="76.182281" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39285"
+ gradientUnits="userSpaceOnUse"
+ x1="165.19363"
+ y1="64.53186"
+ x2="176.15442"
+ y2="76.210785" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39287"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="172.30418"
+ y1="69.838829"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39289"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39291"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39293"
+ gradientUnits="userSpaceOnUse"
+ x1="171"
+ y1="70"
+ x2="177"
+ y2="77" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1718933,0,0,1.127086,-30.219387,-9.3173845)"
+ x1="175.1628"
+ y1="74.125008"
+ x2="176.84593"
+ y2="75.947906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39008"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39010"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39012"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39014"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39016"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39022"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39026"
+ x1="1127.7983"
+ y1="448.375"
+ x2="1153.0486"
+ y2="430.25"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418"
+ id="linearGradient57417"
+ gradientUnits="userSpaceOnUse"
+ x1="146.82516"
+ y1="134.65511"
+ x2="130.10634"
+ y2="117.10313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient57419"
+ gradientUnits="userSpaceOnUse"
+ x1="139.37782"
+ y1="126.3454"
+ x2="131.71249"
+ y2="118.34238" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57421"
+ gradientUnits="userSpaceOnUse"
+ x1="125.01582"
+ y1="110.86718"
+ x2="132.46898"
+ y2="119.54019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient57423"
+ gradientUnits="userSpaceOnUse"
+ x1="127.60629"
+ y1="112.12571"
+ x2="140.72693"
+ y2="126.72997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient57454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(258.00306,-231.00101)"
+ x1="75.25"
+ y1="393.25"
+ x2="73.5"
+ y2="391.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask57450">
+ <rect
+ y="154.99899"
+ x="326.00305"
+ height="15"
+ width="15"
+ id="rect57452"
+ style="fill:url(#linearGradient57454);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22891"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="174.99828"
+ y1="12.918247"
+ x2="167.59578"
+ y2="12.551482" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22893"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="169.47711"
+ y1="10.424105"
+ x2="169.47711"
+ y2="8.1183796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient22895"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.728189,0,0,1.727271,237.88848,243.63713)"
+ x1="169.41847"
+ y1="10.306772"
+ x2="169.4877"
+ y2="7.9604731" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="145.00008"
+ y1="11.99999"
+ x2="160.31258"
+ y2="19.34374" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-215.00008,249.00001)"
+ x1="149.00008"
+ y1="10.924165"
+ x2="171.37508"
+ y2="19.12499" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient22901"
+ gradientUnits="userSpaceOnUse"
+ x1="-68.25"
+ y1="263"
+ x2="-56"
+ y2="265.53439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22903"
+ gradientUnits="userSpaceOnUse"
+ x1="-66"
+ y1="264"
+ x2="-57"
+ y2="264.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32998"
+ id="linearGradient22905"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-357.88848,243.63713)"
+ x1="176.42079"
+ y1="12.946938"
+ x2="169.47711"
+ y2="12.36799" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient22933"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.081669,359)"
+ x1="245.63066"
+ y1="106.28436"
+ x2="245.80791"
+ y2="94.440376" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22935"
+ gradientUnits="userSpaceOnUse"
+ x1="268"
+ y1="462"
+ x2="256"
+ y2="459" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient22937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.999999,359)"
+ x1="247"
+ y1="99"
+ x2="247"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22939"
+ gradientUnits="userSpaceOnUse"
+ x1="263.5"
+ y1="455.25"
+ x2="263.5"
+ y2="460.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6,-5,182.8)"
+ x1="264"
+ y1="452"
+ x2="264"
+ y2="460.6622" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22970"
+ x1="-197.84375"
+ y1="399.90625"
+ x2="-191"
+ y2="409"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19625"
+ id="linearGradient23241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="476.76578"
+ y2="162.94037" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12678"
+ id="radialGradient23245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0982561,0,0,1.2662999,-45.858153,-42.45126)"
+ cx="470.15939"
+ cy="164.46814"
+ fx="470.15939"
+ fy="164.46814"
+ r="3.500145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23247"
+ gradientUnits="userSpaceOnUse"
+ x1="128.7561"
+ y1="115.77483"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23250"
+ gradientUnits="userSpaceOnUse"
+ x1="127.30917"
+ y1="111.48133"
+ x2="138.30522"
+ y2="124.69373" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23445"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="480.09564"
+ y1="163.08553"
+ x2="475.50031"
+ y2="162.92206" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient23447"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.37032"
+ y1="12.147777"
+ x2="175.38158"
+ y2="15.699567" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23533"
+ gradientUnits="userSpaceOnUse"
+ x1="155.82454"
+ y1="16.845156"
+ x2="158.41653"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.727201,9.075096e-6,0,1.728246,-147.7149,-10.37485)"
+ x1="171.03941"
+ y1="11.121979"
+ x2="175.33569"
+ y2="16.202652" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.8884,-5.3628832)"
+ x1="172.18394"
+ y1="11.912162"
+ x2="176.46956"
+ y2="16.427906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40847"
+ gradientUnits="userSpaceOnUse"
+ x1="156.00008"
+ y1="16.99999"
+ x2="159.00008"
+ y2="19.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient40965"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,14)"
+ x1="62.107086"
+ y1="223.54628"
+ x2="96.812675"
+ y2="258.38593" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="linearGradient40967"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-21,0)"
+ x1="79.04213"
+ y1="253.5"
+ x2="60.155113"
+ y2="234.7775" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24098"
+ x1="208.25"
+ y1="-133.89581"
+ x2="204.01923"
+ y2="-111.15749"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23510"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3008215,-8.6726798)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23512"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="110.16959"
+ y1="57.061836"
+ x2="117.55341"
+ y2="64.995972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23514"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.3010161,-8.6726854)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="54.252415"
+ y2="100.44998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23550"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,0.01738631)"
+ x1="468.07968"
+ y1="275.27036"
+ x2="510"
+ y2="266.99997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient23555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,3.959006e-5)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23581"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,404.07104,216.722)"
+ x1="116.75796"
+ y1="52.264809"
+ x2="103.18628"
+ y2="55.747272" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient23585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-1.0000037)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32842"
+ id="radialGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="radialGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0009003,-1.5278593,1.1592123,0.7594114,-59.938837,957.7287)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23562"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,461.68129,182.37748)"
+ x1="47.612946"
+ y1="93.555946"
+ x2="56.524509"
+ y2="101.25028" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient23565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,323.39462,186.24644)"
+ x1="115.45872"
+ y1="58.869785"
+ x2="106.20376"
+ y2="58.354706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient22847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728803,0,0,1.7265713,347.39462,166.24644)"
+ x1="110.54202"
+ y1="56.645538"
+ x2="115.53827"
+ y2="63.567348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2445337,0,0,1.5876961,523.20711,115.4619)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1004102,0,0,1.0993832,503.28129,157.47747)"
+ x1="29.506693"
+ y1="100.66651"
+ x2="34.276955"
+ y2="105.98901" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24054"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24066"
+ x1="202.5"
+ y1="143.84116"
+ x2="202.5"
+ y2="132.60213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-259,202)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient23738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23750"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.172144,59.49999,53.45766)"
+ x1="445.5"
+ y1="148.90862"
+ x2="433.5"
+ y2="148.69533" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23752"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6499984,0,0,0.5439483,434.02514,137.87435)"
+ x1="113.71248"
+ y1="158.24995"
+ x2="91.499992"
+ y2="158.24994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23754"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0052083,0,0,0.5057472,778.49218,365.83334)"
+ x1="-285.65732"
+ y1="-274.23453"
+ x2="-279.44821"
+ y2="-268.04858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23914"
+ gradientUnits="userSpaceOnUse"
+ x1="29.200638"
+ y1="160.18758"
+ x2="32.928555"
+ y2="164.13913" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23916"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.02887268,-1.2550276,0.795821,0.01830762,8.763469,168.20647)"
+ cx="11.708446"
+ cy="81.275032"
+ fx="11.708446"
+ fy="81.275032"
+ r="5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient23918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.01269957,-0.9297674,1.1086869,0.01514236,-16.51473,165.70609)"
+ cx="4.7455525"
+ cy="82.433929"
+ fx="4.7455525"
+ fy="82.433929"
+ r="5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24460"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(383,-37.999994)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24456">
+ <rect
+ y="108"
+ x="299"
+ height="17"
+ width="7"
+ id="rect24458"
+ style="fill:url(#linearGradient24460);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ mask="none" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(360,-142.95536)"
+ x1="-80"
+ y1="151"
+ x2="-80"
+ y2="152.24998" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask24466">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient24470);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24468"
+ width="7"
+ height="9"
+ x="276"
+ y="4.0625" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23971"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23973"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23975"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24099"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24539"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="107.39532"
+ y1="58.065113"
+ x2="127.70434"
+ y2="58.065113" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24541"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1000194,0,0,1.0998287,110.29549,-8.6726854)"
+ x1="30.389694"
+ y1="95.008034"
+ x2="65.52562"
+ y2="93.69249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="483.00034"
+ y1="163"
+ x2="476.68781"
+ y2="162.85956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24545"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24547"
+ gradientUnits="userSpaceOnUse"
+ x1="475.00034"
+ y1="155"
+ x2="469.75034"
+ y2="155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,-6e-5)"
+ x1="442.81525"
+ y1="290.49384"
+ x2="436.5"
+ y2="290.5249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105"
+ id="linearGradient24551"
+ gradientUnits="userSpaceOnUse"
+ x1="445.99902"
+ y1="288.5"
+ x2="407.3793"
+ y2="288.5" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath24168">
+ <path
+ style="fill:#808080;fill-rule:evenodd;stroke:none"
+ d="m 134.27489,222.11125 c -3.9249,-6.46418 -7.61892,6.46419 -11.54381,0 l 0,0 -1.61614,0 0,8.77283 14.77608,0 0,-8.77283 -1.61613,0 z"
+ id="path24170"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient24112"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="135.36497"
+ y2="120.87388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24114"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="302.84085"
+ y1="243.23151"
+ x2="308.82889"
+ y2="244.70323" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24118"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6879084,0,0,0.6879446,216.19282,166.82605)"
+ x1="121.7408"
+ y1="115.90587"
+ x2="130.01318"
+ y2="116.60553" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24121"
+ gradientUnits="userSpaceOnUse"
+ x1="135.698"
+ y1="122.92034"
+ x2="129.70906"
+ y2="117.15551" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24123"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="162.61801"
+ y1="4.5569806"
+ x2="180.11391"
+ y2="23.410421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24192"
+ gradientUnits="userSpaceOnUse"
+ x1="167.43744"
+ y1="23.749996"
+ x2="175.06059"
+ y2="32.144764"
+ gradientTransform="translate(-94.937441,240)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient24209"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-93.937441,254)"
+ x1="166.86487"
+ y1="12.306217"
+ x2="173.93744"
+ y2="19" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24268"
+ gradientUnits="userSpaceOnUse"
+ x1="186.74992"
+ y1="10.795519"
+ x2="189.24992"
+ y2="9.0189686"
+ gradientTransform="matrix(1,0,0,-0.985055,75.000075,275.63418)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient24277"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2000005,0,0,1.1817719,-50.700005,86.809844)"
+ x1="258.08322"
+ y1="148.24248"
+ x2="264.99994"
+ y2="154.24899" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327"
+ id="linearGradient24395"
+ x1="-27.5"
+ y1="268.76776"
+ x2="-39.875"
+ y2="277.4375"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15893"
+ id="linearGradient41127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,594,-42.40625)"
+ x1="409.45645"
+ y1="52.77837"
+ x2="402.30673"
+ y2="55.86327" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27957"
+ id="linearGradient41129"
+ gradientUnits="userSpaceOnUse"
+ x1="180.20316"
+ y1="8.0551176"
+ x2="192.75177"
+ y2="12.942369" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41172"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="268.21783"
+ y1="200.66605"
+ x2="284.9375"
+ y2="224.1875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient41174"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41963"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(274,-63.999901)"
+ x1="113.71248"
+ y1="158.24995"
+ x2="87.522514"
+ y2="157.99994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42069"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="266.93381"
+ y1="199.60616"
+ x2="291.45029"
+ y2="230.76723" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="276.39999"
+ y1="215.3125"
+ x2="265.70886"
+ y2="196.576" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42115"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(60,-342)"
+ x1="206"
+ y1="535"
+ x2="212"
+ y2="549" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9846154,-138.98388,3.9846124)"
+ x1="263"
+ y1="193.93752"
+ x2="296.25"
+ y2="239.89455" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01612278,0)"
+ x1="265.98389"
+ y1="195"
+ x2="290.98389"
+ y2="232" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient42292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.375,-66.483877,-73.5)"
+ cx="269.99997"
+ cy="197"
+ fx="269.99997"
+ fy="197"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40722"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9819031,0,0,0.9481466,-88.271503,-83.584533)"
+ x1="1.6577729"
+ y1="253.01927"
+ x2="-57.772419"
+ y2="253.62515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.977157,0,0,0.9835482,0.06815071,100.43848)"
+ x1="107.84375"
+ y1="57.374996"
+ x2="116.99999"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="241.17908"
+ y1="214.40446"
+ x2="279.89563"
+ y2="254.94975" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6025789,0,0,0.668336,263.48819,85.675422)"
+ x1="49.543404"
+ y1="230.81766"
+ x2="73.932747"
+ y2="247.27646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40738"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9120445,0,0,1,25.749745,8.9261515)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="308.97327"
+ y2="242" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40740"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.584271,0,0,0.661005,267.80323,78.438648)"
+ x1="51.682816"
+ y1="229.19724"
+ x2="73.932762"
+ y2="247.35141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40742"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9103441,0,0,0.989031,29.299938,2.5312404)"
+ x1="305.12527"
+ y1="239.03134"
+ x2="307.25021"
+ y2="241.62509" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40758"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(15.997359,-17.993456)"
+ x1="199.4335"
+ y1="294.81082"
+ x2="196.00264"
+ y2="259.99347" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40760"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,51.339144,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40762"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7501745,0,0,1.0021005,59.339161,-0.5240716)"
+ x1="207.19595"
+ y1="249.22464"
+ x2="207.81319"
+ y2="250.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40788"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="146.51619"
+ y1="217.52046"
+ x2="174.56255"
+ y2="252.52081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient40790"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18056"
+ id="linearGradient40792"
+ gradientUnits="userSpaceOnUse"
+ x1="170.42908"
+ y1="237.25"
+ x2="170.71698"
+ y2="249.15927" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient40794"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.5625"
+ y1="249.55817"
+ x2="168.5"
+ y2="240.10249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40545"
+ gradientUnits="userSpaceOnUse"
+ x1="279.38629"
+ y1="-16.946415"
+ x2="293.80472"
+ y2="-2.5475447" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40547"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9230687,0,0,0.9230801,261.38476,-234.15464)"
+ x1="43.921535"
+ y1="261.52924"
+ x2="29.429007"
+ y2="243.98439" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22249"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="387"
+ y1="410"
+ x2="388.78125"
+ y2="411.78125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="386.88852"
+ y1="409.84152"
+ x2="389.14081"
+ y2="412.45016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="387"
+ y1="409.86362"
+ x2="388.86676"
+ y2="411.88974" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23775"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9230769,0,0,-0.9258123,59.615385,471.81593)"
+ x1="-0.71355486"
+ y1="209.97131"
+ x2="37.5"
+ y2="252.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient23777"
+ gradientUnits="userSpaceOnUse"
+ x1="72.698921"
+ y1="599.20789"
+ x2="77.111115"
+ y2="604.11108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient23351"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23353"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient23355"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23357"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23599"
+ x1="191"
+ y1="158.72728"
+ x2="196.59441"
+ y2="167.67831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.89375,0,0,0.89375,20.29375,17.10625)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient22701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22704"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22711"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient22715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23132"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23134"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23147"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23177"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23179"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23183"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23185"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23187"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23231"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23235"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23239"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23257"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23563"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23566"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23568"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23587"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23626"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20324"
+ id="linearGradient23628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23635"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37623"
+ id="linearGradient23637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,741.54576,313.45452)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23799"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8181823,0,0,-0.8181822,345.54553,947.54573)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23801"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-288.54575,551.54554)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,107.45448,-82.54566)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,0.8181822,103.36356,-98.909308)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23807"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.8181822,-0.8181823,0,757.9094,309.36361)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8181823,0,0,-0.8181822,103.36356,963.90937)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23811"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.8181822,0.8181823,0,-304.90941,555.63645)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,850,297)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,366,1072)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23817"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-409,588)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23819"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(75,-187)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23821"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(70,-207)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,870,292)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,70,1092)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23827"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-429,593)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23829"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,125.8864,29.94755)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,616.05253,334.8864)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23833"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-179.05245,520.11368)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23835"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,311.11368,825.05254)"
+ x1="145.53571"
+ y1="627.08325"
+ x2="145.53571"
+ y2="623.12494" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23837"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6363637,0,0,0.6315788,122.70458,17.31597)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6363637,-0.6315788,0,628.68411,331.70458)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23841"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6363637,0,0,-0.6315788,314.2955,837.68414)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6363637,0.6315788,0,-191.68403,523.2955)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.53571"
+ y2="641.54156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,628.0905,358.45254)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23847"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.636363,0,0,-0.6357342,320.09081,851.14655)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23849"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-173.09051,543.4512)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24632"
+ id="linearGradient23851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,134.90918,50.757191)"
+ x1="145.5"
+ y1="627.5"
+ x2="145.5"
+ y2="623.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23853"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,0.6357342,131.72737,31.593709)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,0.6357342,-0.636363,0,640.81777,348.82507)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.636363,0,0,-0.6357342,131.72737,857.41243)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24642"
+ id="linearGradient23860"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.6357342,0.636363,0,-185.81777,540.18107)"
+ x1="150.5"
+ y1="647.75"
+ x2="150.5"
+ y2="642" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42685"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-54.000005,-120)"
+ x1="258.52756"
+ y1="388"
+ x2="279"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-46.000005,-117)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient22892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient22917"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22922"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient22928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient22950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient22952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="262.67139"
+ cy="74.072273"
+ fx="262.67139"
+ fy="74.072273"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient22954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37925"
+ id="linearGradient23890"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient23892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23906"
+ id="radialGradient23894"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0553103,1.0606182,-1.2516598,1.280294,67.321819,-297.60493)"
+ cx="262.07156"
+ cy="74.306007"
+ fx="262.07156"
+ fy="74.306007"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient23896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="radialGradient23898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23900"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient23902"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient23904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient24090"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient24092"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24094"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="263.21707"
+ cy="74.441246"
+ fx="263.21707"
+ fy="74.441246"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient24102"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24104"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="66.954422"
+ y1="240.03282"
+ x2="68.458534"
+ y2="246.96069" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143"
+ id="linearGradient24367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="244.37868"
+ y1="285.00754"
+ x2="237.75459"
+ y2="266.34406" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24695"
+ id="linearGradient24374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.97597"
+ y1="281.26645"
+ x2="116.37123"
+ y2="260.21841" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient24436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-150.99992,596.00357)"
+ x1="199.87271"
+ y1="272.29477"
+ x2="212.22493"
+ y2="287.50357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24811"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24813"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.539974"
+ y1="421.80756"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24815"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24839"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24841"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24144"
+ id="linearGradient24843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="64.019142"
+ y1="419.06366"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24727"
+ id="linearGradient24867"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,765.84783,-274.57833)"
+ x1="59.158501"
+ y1="437.02835"
+ x2="45.021851"
+ y2="349.81818" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24735"
+ id="linearGradient24869"
+ gradientUnits="userSpaceOnUse"
+ x1="807"
+ y1="101.5"
+ x2="841"
+ y2="101.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24711"
+ id="linearGradient24871"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,767.34783,-275.07833)"
+ x1="63.659767"
+ y1="422.46088"
+ x2="63.407566"
+ y2="347.78201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient24873"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-127,4e-6)"
+ x1="954"
+ y1="102"
+ x2="936"
+ y2="114.99999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25073"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25075"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient42055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="120.94298"
+ y1="281.27435"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient42057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24101"
+ id="linearGradient24132"
+ gradientUnits="userSpaceOnUse"
+ x1="445.77841"
+ y1="113.24564"
+ x2="426.11459"
+ y2="84.777061" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24599"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1489145,-0.69297,0.4772363,0.7912359,-113.08929,303.20064)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7236207,-0.7167103,1.004637,1.0143218,-131.254,253.93955)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31456"
+ id="linearGradient24797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.3967"
+ y1="310.77368"
+ x2="309.02371"
+ y2="308.51169" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24820"
+ x1="311.37668"
+ y1="311.88205"
+ x2="307.5"
+ y2="308.21875"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4011721,0.3766097,-0.7099042,0.7562044,179.21454,-58.566632)"
+ cx="207.04807"
+ cy="78.473343"
+ fx="207.04807"
+ fy="78.473343"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20036"
+ id="radialGradient43964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4543499,0.4687811,-0.6244606,0.6052369,161.562,-65.729731)"
+ cx="206.39249"
+ cy="78.443413"
+ fx="206.39249"
+ fy="78.443413"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,0)"
+ x1="248.69196"
+ y1="279.72827"
+ x2="269.3085"
+ y2="303.10999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient62558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,-33.03632,32.03632)"
+ x1="289.61554"
+ y1="320.55179"
+ x2="250.22783"
+ y2="282.28745" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient62560"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,59,638)"
+ x1="354.50601"
+ y1="283.61511"
+ x2="327.92044"
+ y2="300.96124" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25381"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25387"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25369">
+ <g
+ id="g25371"
+ transform="translate(-21,-21)">
+ <path
+ style="fill:url(#linearGradient25381);fill-rule:evenodd;stroke:none"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ id="path25373"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="4"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25375"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ style="fill:url(#linearGradient25383);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-x="-4"
+ sodipodi:nodetypes="cccc"
+ id="path25377"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ style="fill:url(#linearGradient25385);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:transform-center-y="4"
+ sodipodi:nodetypes="cccc"
+ id="path25379"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ style="fill:url(#linearGradient25387);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1,21)"
+ x1="342"
+ y1="288.5"
+ x2="344.01321"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,638,-40)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,699,599)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25579"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,60,660)"
+ x1="342"
+ y1="288.5"
+ x2="344.5"
+ y2="288.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask25561">
+ <g
+ transform="translate(-21,-21)"
+ id="g25563">
+ <path
+ inkscape:transform-center-x="4"
+ sodipodi:nodetypes="cccc"
+ id="path25565"
+ d="m 341,302 8,8 -8,8 0,-16 z"
+ style="fill:url(#linearGradient25573);fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient25575);fill-rule:evenodd;stroke:none"
+ d="m 357,302 -8,8 -8,-8 16,0 z"
+ id="path25567"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient25577);fill-rule:evenodd;stroke:none"
+ d="m 357,318 -8,-8 8,-8 0,16 z"
+ id="path25569"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-x="-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient25579);fill-rule:evenodd;stroke:none"
+ d="m 341,318 8,-8 8,8 -16,0 z"
+ id="path25571"
+ sodipodi:nodetypes="cccc"
+ inkscape:transform-center-y="4"
+ inkscape:connector-curvature="0" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25872"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,328.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,111)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="243.92192"
+ y1="-2.6686089"
+ x2="275.10107"
+ y2="26.600887" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25888"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25890"
+ gradientUnits="userSpaceOnUse"
+ x1="13.5"
+ y1="57.827747"
+ x2="11.472005"
+ y2="53.875874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13998"
+ id="linearGradient25892"
+ gradientUnits="userSpaceOnUse"
+ x1="-18.600719"
+ y1="501.96539"
+ x2="-26.642899"
+ y2="487.60382" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25894"
+ gradientUnits="userSpaceOnUse"
+ x1="15.027407"
+ y1="60.637787"
+ x2="13.5"
+ y2="57.750687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25897"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.03018343,0.1408617)"
+ x1="-32.067383"
+ y1="490.70178"
+ x2="-22.25"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25899"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-72.000001)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679"
+ id="linearGradient25927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-30.15217,152.41412)"
+ x1="121.79003"
+ y1="283.00519"
+ x2="114.66669"
+ y2="250.69945" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24671"
+ id="linearGradient25929"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-149,133.99245)"
+ x1="243.25"
+ y1="283.94504"
+ x2="235"
+ y2="253.00755" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25931"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-335,238.99245)"
+ x1="426.12415"
+ y1="179.12074"
+ x2="425"
+ y2="179.12285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25957"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25961"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-112)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient25982"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient25984"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient25986"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-136,-88.000005)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient26011"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,673.5,170.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient26013"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(830,-47)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26015"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,-76.000004)"
+ x1="753.39417"
+ y1="299.83005"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient26077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,82.8792,399.00004)"
+ x1="-7.445384"
+ y1="204.24995"
+ x2="33.682159"
+ y2="250.99995" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(80.02752,483.00004)"
+ x1="29.972469"
+ y1="164"
+ x2="36.972481"
+ y2="168.00002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient26081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-224,-1290)"
+ x1="113"
+ y1="646"
+ x2="111"
+ y2="644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26083"
+ gradientUnits="userSpaceOnUse"
+ x1="113"
+ y1="646"
+ x2="111.5"
+ y2="644.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26126"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.146465,141.05131)"
+ x1="71.762154"
+ y1="239.83469"
+ x2="76.956871"
+ y2="252.05081" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26128"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="72.340698"
+ y1="243.03008"
+ x2="73.234337"
+ y2="246.81651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient26130"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.831045,0,0,0.776773,36.165705,133.02478)"
+ x1="68.383354"
+ y1="239.95235"
+ x2="69.285805"
+ y2="247.29691" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27973"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27975"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28099"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient28107"
+ gradientUnits="userSpaceOnUse"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845"
+ gradientTransform="translate(-19,294.91429)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient27448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-19,294.91429)"
+ x1="461.66425"
+ y1="16.23234"
+ x2="432.875"
+ y2="14.936845" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27450"
+ gradientUnits="userSpaceOnUse"
+ x1="62.793919"
+ y1="133.73566"
+ x2="64.109718"
+ y2="135.18265" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient27452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39459,-0.991726,0.917787,0.36517,234.80511,750.0215)"
+ cx="450.06522"
+ cy="25.190212"
+ fx="450.06522"
+ fy="25.190212"
+ r="5.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121304,-0.696283,0.871429,0.151818,359.51331,621.7)"
+ cx="450.72842"
+ cy="19.250505"
+ fx="450.72842"
+ fy="19.250505"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,883.51417,295)"
+ x1="456.81198"
+ y1="15.545153"
+ x2="441.9628"
+ y2="13.21724" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27540"
+ gradientUnits="userSpaceOnUse"
+ x1="332.49747"
+ y1="38.166924"
+ x2="326.41843"
+ y2="31.22842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.011921e-5,12.000013)"
+ x1="326.483"
+ y1="31.446384"
+ x2="337.3125"
+ y2="41.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27544"
+ gradientUnits="userSpaceOnUse"
+ x1="329.18762"
+ y1="34.005215"
+ x2="331.44778"
+ y2="36.739578" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23705"
+ id="linearGradient27598"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24168"
+ id="linearGradient27600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27604"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8750002,0,0,0.83767,7.3124969,247.00379)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient27606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4564959,0.09949388,-0.06177986,1.3917691,-283.96093,-143.81911)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient27610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2,0,0,0.7333333,-467,262.53823)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient27612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3687636,0.09935874,-0.05957343,1.3898788,-272.60513,-143.17133)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient30389"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient30391"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient30393"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient30395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient30397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(422.99996,88.99998)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29129"
+ gradientUnits="userSpaceOnUse"
+ x1="732.9375"
+ y1="412.8125"
+ x2="753.40625"
+ y2="418.33594" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27767"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27769"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient27771"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="112.18942"
+ y1="114.71685"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient27773"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient31865"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.986122,0,0,0.986122,2.8033684,0.804927)"
+ cx="202"
+ cy="58"
+ fx="202"
+ fy="58"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask31861">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient31865);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path31863"
+ sodipodi:cx="202"
+ sodipodi:cy="58"
+ sodipodi:rx="11"
+ sodipodi:ry="11"
+ d="m 213,58 a 11,11 0 1 1 -22,0 11,11 0 1 1 22,0 z" />
+ </mask>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath31849">
+ <path
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 232.13187,93.950853 4.84276,0 4.23742,4.237465 0,4.842822 -9.08018,0 0,-9.080287 0,0 z"
+ id="path31851"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32298"
+ gradientUnits="userSpaceOnUse"
+ x1="-117.5"
+ y1="431.5"
+ x2="-119.5"
+ y2="429.5"
+ gradientTransform="translate(258,-96.99999)" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask32294">
+ <rect
+ y="323"
+ x="134"
+ height="16"
+ width="9"
+ id="rect32296"
+ style="fill:url(#linearGradient32298);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32241"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient32243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53119"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53121"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53123"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53125"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient53127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient53129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="362.79037"
+ y1="-159.88834"
+ x2="373.83752"
+ y2="-150.41035" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9900316,0,0,1,2.450297,0.00704954)"
+ x1="343.51892"
+ y1="175.19124"
+ x2="350.97491"
+ y2="183.3365" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53139"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53141"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53143"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53145"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53147"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42459"
+ id="linearGradient53149"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(220,-20.00667)"
+ x1="29.4034"
+ y1="100.99999"
+ x2="34.095703"
+ y2="101.15624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22562"
+ id="linearGradient53151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,227.625,0.9640803)"
+ x1="20.125"
+ y1="88.642494"
+ x2="34.125"
+ y2="104.89799" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6595012,0.7907318,-0.8990144,0.7498135,144.69896,-187.59854)"
+ cx="261.98364"
+ cy="74.083908"
+ fx="261.98364"
+ fy="74.083908"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75,0,0,0.7516675,115.625,254.97076)"
+ x1="27.166666"
+ y1="90.504448"
+ x2="35.166668"
+ y2="101.14744" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient53157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.53241"
+ cy="500.20956"
+ fx="75.53241"
+ fy="500.20956"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53159"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="135.14931"
+ cy="332.10181"
+ fx="135.14931"
+ fy="332.10181"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient53161"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-112,237.00668)"
+ x1="250.5"
+ y1="90.253998"
+ x2="250.5"
+ y2="95.252274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53163"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1055676,0.08927896,-0.05295416,1.2488779,-134.03789,-95.726825)"
+ cx="140.33667"
+ cy="333.05716"
+ fx="140.33667"
+ fy="333.05716"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient53165"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient53167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient53169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient53171"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23178"
+ id="linearGradient50870"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2e-6,0)"
+ x1="-22.902081"
+ y1="448"
+ x2="-14.000002"
+ y2="448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33427"
+ gradientUnits="userSpaceOnUse"
+ x1="124.40742"
+ y1="111.98244"
+ x2="136.04924"
+ y2="121.25749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33429"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient33585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7071068,-0.7071068,0.7071067,0.7071067,-140.04288,401.30258)"
+ x1="458.99997"
+ y1="89.363937"
+ x2="452.63602"
+ y2="90.071045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31356"
+ id="linearGradient33831"
+ gradientUnits="userSpaceOnUse"
+ x1="134.00002"
+ y1="116"
+ x2="142.00002"
+ y2="108" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient33833"
+ gradientUnits="userSpaceOnUse"
+ x1="124.75568"
+ y1="112.24533"
+ x2="132.97911"
+ y2="120.16792" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient33835"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="254.19829"
+ y1="2.1803131"
+ x2="277.86761"
+ y2="29.392145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37475"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37477"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-32.5,115.5045)"
+ x1="261.83936"
+ y1="11.593864"
+ x2="275.62497"
+ y2="26.679274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37479"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(124,-102.00001)"
+ x1="85.1875"
+ y1="239.125"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37481"
+ gradientUnits="userSpaceOnUse"
+ x1="270.60007"
+ y1="68.519989"
+ x2="258.00165"
+ y2="81.245804" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37483"
+ gradientUnits="userSpaceOnUse"
+ x1="256.67459"
+ y1="80.395966"
+ x2="262.88068"
+ y2="74.415245" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37485"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4829018,0,0,0.4829018,133.47136,40.782399)"
+ cx="257.35309"
+ cy="79.598709"
+ fx="257.35309"
+ fy="79.598709"
+ r="3.779551" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37487"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37489"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37491"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.5793179,0,-1.0159927e-7,-1.6412688,666.67947,207.37331)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37493"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37495"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37497"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37499"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37501"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
+ cx="135.83771"
+ cy="117.97826"
+ fx="135.83771"
+ fy="117.97826"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37503"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37505"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37507"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37509"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3336259,0,-8.5793649e-8,-1.3859393,603.17514,187.32668)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.3648614,0,-8.7803051e-8,-1.4184,611.24862,189.87526)"
+ cx="258.47122"
+ cy="78.512764"
+ fx="258.47122"
+ fy="78.512764"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient37517"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37519"
+ gradientUnits="userSpaceOnUse"
+ x1="256.38586"
+ y1="80.515495"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30124"
+ id="linearGradient37525"
+ gradientUnits="userSpaceOnUse"
+ x1="337.34329"
+ y1="43.328976"
+ x2="330.27045"
+ y2="35.276588" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37527"
+ gradientUnits="userSpaceOnUse"
+ x1="329.9158"
+ y1="35.5"
+ x2="335.27429"
+ y2="41.570362" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="166.89752"
+ y1="9.0567484"
+ x2="193.26451"
+ y2="38.642647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37531"
+ gradientUnits="userSpaceOnUse"
+ x1="127.93343"
+ y1="122.8346"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37533"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37535"
+ gradientUnits="userSpaceOnUse"
+ x1="122.86111"
+ y1="127.14286"
+ x2="133.77768"
+ y2="116.99384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37537"
+ gradientUnits="userSpaceOnUse"
+ x1="141.60255"
+ y1="108.39205"
+ x2="132"
+ y2="118.66972" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37539"
+ gradientUnits="userSpaceOnUse"
+ x1="266"
+ y1="659"
+ x2="285"
+ y2="659" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35391"
+ id="linearGradient37541"
+ gradientUnits="userSpaceOnUse"
+ x1="244.21062"
+ y1="600.74884"
+ x2="244.21062"
+ y2="602.96759" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35407"
+ id="linearGradient37543"
+ gradientUnits="userSpaceOnUse"
+ x1="235.29379"
+ y1="588.43396"
+ x2="245.93307"
+ y2="604.52502" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37545"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37547"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37553"
+ gradientUnits="userSpaceOnUse"
+ x1="86.248604"
+ y1="32"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="81"
+ y1="27"
+ x2="64.5"
+ y2="9.0000019" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient37557"
+ gradientUnits="userSpaceOnUse"
+ x1="70.78582"
+ y1="15.659542"
+ x2="79.465332"
+ y2="24.480759" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient37559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5997527,0.4726093,-0.6665451,0.8458611,35.480681,-28.765852)"
+ cx="63.013588"
+ cy="14.60904"
+ fx="63.013588"
+ fy="14.60904"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37571"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8666667,0,0,0.9166667,406.13333,-443.79167)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient37573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.9971589,396,-484.56523)"
+ x1="83.261826"
+ y1="502.54196"
+ x2="41.311054"
+ y2="501.10059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient37575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,321.60762,256.85923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37578"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37580"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2665671,0.04035316,-0.03648524,1.99062,-82.893589,-502.25433)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient37584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient37586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37588"
+ gradientUnits="userSpaceOnUse"
+ x1="264.10001"
+ y1="330.10001"
+ x2="264.89999"
+ y2="330.89999" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14232"
+ id="linearGradient37590"
+ gradientUnits="userSpaceOnUse"
+ x1="122.38876"
+ y1="108.82882"
+ x2="133.88583"
+ y2="121.20407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995363,0,0,-1.0036971,220.01067,167.35026)"
+ x1="51.37524"
+ y1="96.955269"
+ x2="44.999863"
+ y2="103.57072" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15437"
+ id="linearGradient37594"
+ gradientUnits="userSpaceOnUse"
+ x1="137.88235"
+ y1="124.67203"
+ x2="131.3092"
+ y2="117.24104" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37596"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37032"
+ y1="110.87843"
+ x2="139.86742"
+ y2="126.57021" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient37608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.684011,0.3442329,-1.2972142,1.1562236,739.67527,-1155.7895)"
+ cx="975.50568"
+ cy="690.68732"
+ fx="975.50568"
+ fy="690.68732"
+ r="2.333364" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.821004,429.95027,-161.55482)"
+ x1="108.71671"
+ y1="171.25618"
+ x2="105.85706"
+ y2="168.04703" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756"
+ id="linearGradient37612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8008385,0,0,0.8956408,540.31118,-183.20693)"
+ x1="-26.313976"
+ y1="178.07901"
+ x2="-28.432825"
+ y2="175.87964" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37614"
+ gradientUnits="userSpaceOnUse"
+ x1="510.29913"
+ y1="-20.435461"
+ x2="505.9494"
+ y2="-17.546936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37636"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-241.7085,428.4841)"
+ x1="387.30396"
+ y1="126.23978"
+ x2="332.88193"
+ y2="123.61623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37638"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37640"
+ gradientUnits="userSpaceOnUse"
+ x1="121.19734"
+ y1="105.94044"
+ x2="148.06364"
+ y2="137.6748" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42322"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1000194,0,0,1.0998287,-4.6508478,-9.2334126)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42326"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42328"
+ gradientUnits="userSpaceOnUse"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42330"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42332"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0041772,0,0,0.9688607,-81.584854,117.13687)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,-171.92846,305.72314)"
+ x1="107.96875"
+ y1="53.875"
+ x2="117"
+ y2="60.125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42336"
+ gradientUnits="userSpaceOnUse"
+ x1="154.24324"
+ y1="-11.628862"
+ x2="134.08138"
+ y2="-22.846634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42338"
+ gradientUnits="userSpaceOnUse"
+ x1="137.5"
+ y1="-18"
+ x2="135.25"
+ y2="-21" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42340"
+ gradientUnits="userSpaceOnUse"
+ x1="134.12642"
+ y1="-21.522242"
+ x2="132.29695"
+ y2="-23.945318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42342"
+ gradientUnits="userSpaceOnUse"
+ x1="134.6615"
+ y1="-21.3074"
+ x2="131.69801"
+ y2="-24.343456" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42344"
+ gradientUnits="userSpaceOnUse"
+ x1="-69.457596"
+ y1="31.914484"
+ x2="-76.564636"
+ y2="28.695114" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42346"
+ gradientUnits="userSpaceOnUse"
+ x1="-57.780041"
+ y1="48.005856"
+ x2="-78.812721"
+ y2="31" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42348"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9995967,0,0,1.0002103,-78.949724,-0.02739749)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42350"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.2998291,32.548709,64.760571)"
+ x1="51.497997"
+ y1="97.491707"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,79.011866)"
+ x1="51.497997"
+ y1="94.987144"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3000195,0,0,0.1998289,32.548709,83.013491)"
+ x1="51.497997"
+ y1="94.987129"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197983,83.013493)"
+ x1="48.998543"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,42.197981,79.010163)"
+ x1="48.99855"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,42.19798,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196563,83.013493)"
+ x1="48.998539"
+ y1="94.987114"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.1998289,46.196561,79.010163)"
+ x1="48.998547"
+ y1="94.995667"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2,0,0,0.2999998,46.19656,64.743076)"
+ x1="48.998554"
+ y1="97.494553"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42368"
+ gradientUnits="userSpaceOnUse"
+ x1="-109.125"
+ y1="52.625"
+ x2="-121.73741"
+ y2="38.387074" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42370"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42372"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42374"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42376"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-41,98)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42378"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42380"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-66.833415,127.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42382"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-57.134785,102.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42384"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-92.714287,177.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42386"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42388"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42390"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42392"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="radialGradient42394"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1226244,0.04761823,-0.1611956,3.8002759,59.188894,-553.59611)"
+ cx="-215.0979"
+ cy="201.01204"
+ fx="-215.0979"
+ fy="201.01204"
+ r="5.8999949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42396"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,4)"
+ x1="-224"
+ y1="201"
+ x2="-214.39445"
+ y2="195.27762" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="209.05762"
+ y1="290.00357"
+ x2="215.34009"
+ y2="277.00357" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42400"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42402"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42404"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="136.44698"
+ y2="123.20583" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42408"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42410"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="120.4313"
+ x2="93.029579"
+ y2="78.9655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1142111,0,0,-1,-174.01401,596.00357)"
+ x1="178.77469"
+ y1="550.50702"
+ x2="198.57239"
+ y2="559.03442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42414"
+ gradientUnits="userSpaceOnUse"
+ x1="112.48699"
+ y1="99.873772"
+ x2="133.62697"
+ y2="120.49951" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42418"
+ gradientUnits="userSpaceOnUse"
+ x1="102.83286"
+ y1="85.825607"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42420"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-120,79)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42422"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-223.42456"
+ y1="43.134327"
+ x2="-202.33263"
+ y2="39.110355" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6962506,0,0,0.8034158,-145.83341,108.95312)"
+ x1="-219.98772"
+ y1="40.355042"
+ x2="-220.82353"
+ y2="27.996962" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,-136.13478,83.33514)"
+ x1="-177.6924"
+ y1="63.26775"
+ x2="-170.82031"
+ y2="62.441177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-171.71429,158.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient42430"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1664.4413"
+ y1="720.01788"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient42432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1977.4047"
+ y2="829.72656" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42436"
+ gradientUnits="userSpaceOnUse"
+ x1="-211.04486"
+ y1="193.68091"
+ x2="-219.5"
+ y2="185.8125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42438"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.6261963,-1.575549,0.4790575,0.7985147,261.90894,-304.15053)"
+ cx="-216.5222"
+ cy="188.13423"
+ fx="-216.5222"
+ fy="188.13423"
+ r="6.9375" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient42440"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4767928,-0.2294888,0.06653313,0.7180687,315.70283,0.01290384)"
+ cx="-221.88463"
+ cy="182.64247"
+ fx="-221.88463"
+ fy="182.64247"
+ r="3.4576657" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42442"
+ gradientUnits="userSpaceOnUse"
+ x1="-225.00002"
+ y1="38.277779"
+ x2="-213"
+ y2="44.732624" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42444"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42446"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1658027,0,0,1.1657997,-354.28972,51.94393)"
+ x1="129.32576"
+ y1="223.61363"
+ x2="123.33967"
+ y2="217.06438" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42462"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42464"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42466"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.8370074,0,0,0.8129865,84.784966,-149.92038)"
+ x1="-4.9152389"
+ y1="252.69086"
+ x2="-45.689278"
+ y2="252.63284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,11.285548,8.325368)"
+ x1="111.03847"
+ y1="57.034107"
+ x2="117.16058"
+ y2="60.591385" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42472"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42474"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42477"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42479"
+ gradientUnits="userSpaceOnUse"
+ x1="-92.587807"
+ y1="-18.005362"
+ x2="-100.62162"
+ y2="-17.998919" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42481"
+ gradientUnits="userSpaceOnUse"
+ x1="-101"
+ y1="-16"
+ x2="-93"
+ y2="-17" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient42483"
+ gradientUnits="userSpaceOnUse"
+ x1="-87.491188"
+ y1="-22.830606"
+ x2="-102.96513"
+ y2="-22.166544" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42485"
+ gradientUnits="userSpaceOnUse"
+ x1="-98.997849"
+ y1="-23.173643"
+ x2="-98.997849"
+ y2="-25.872688" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42487"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42489"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42491"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient42493"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5290924,0,0,0.5294132,-17.313533,46.110999)"
+ x1="109.04134"
+ y1="75.666725"
+ x2="135.45256"
+ y2="103.11092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42495"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5350034,0,0,0.5349052,24.446207,45.843517)"
+ x1="47.655102"
+ y1="93.805557"
+ x2="59.057678"
+ y2="105.27895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42497"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42499"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42501"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42503"
+ gradientUnits="userSpaceOnUse"
+ x1="124.8772"
+ y1="110.75571"
+ x2="133.97179"
+ y2="117.77643" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42505"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="142.64723"
+ y2="129.05313" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42507"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient42509"
+ gradientUnits="userSpaceOnUse"
+ x1="123.26987"
+ y1="108.56933"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42511"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient42513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4749148,1.0023386,-1.2226848,-0.4749148,213.62384,41.735193)"
+ x1="118.95689"
+ y1="106.42961"
+ x2="135.14919"
+ y2="119.05286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5333554,1.1220467,-1.1447545,-0.5333554,196.63818,32.816067)"
+ x1="130.39502"
+ y1="116.31751"
+ x2="147.95374"
+ y2="134.687" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18207"
+ id="linearGradient42517"
+ gradientUnits="userSpaceOnUse"
+ x1="-132.24858"
+ y1="313.87549"
+ x2="-171.01999"
+ y2="223.69542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42519"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42521"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient42523"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42525"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,26.488451,35.562258)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35406"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35408"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35412"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35414"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35416"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35418"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35420"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35422"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35424"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35468"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35470"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9897912,0,0,0.9897912,2.2765631,2.9503441)"
+ x1="311.90765"
+ y1="311.2269"
+ x2="308.84512"
+ y2="308.51169" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1377775,-0.7111077,0.4395239,0.7032404,-101.13916,328.96745)"
+ cx="269.71231"
+ cy="237.2262"
+ fx="269.71231"
+ fy="237.2262"
+ r="7.03125" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35476"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.706663,-1.1377794,0.5688915,0.8533318,-282.47828,404.20327)"
+ cx="262.83905"
+ cy="245.91792"
+ fx="262.83905"
+ fy="245.91792"
+ r="7.03125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35478"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="140.66667"
+ y2="125.94853" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425"
+ id="linearGradient35480"
+ gradientUnits="userSpaceOnUse"
+ x1="119.94563"
+ y1="100.51657"
+ x2="138.25778"
+ y2="124.59384" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35482"
+ gradientUnits="userSpaceOnUse"
+ x1="220.14905"
+ y1="291.80676"
+ x2="226.09999"
+ y2="286.2493" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient35484"
+ gradientUnits="userSpaceOnUse"
+ x1="223.12212"
+ y1="296.15784"
+ x2="219.06912"
+ y2="291.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35486"
+ gradientUnits="userSpaceOnUse"
+ x1="217.56451"
+ y1="290.56451"
+ x2="224.01613"
+ y2="297.01614" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient35488"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3677588,0.3783715,-0.5696226,0.5536455,304.13863,47.532824)"
+ cx="219.00334"
+ cy="291.33972"
+ fx="219.00334"
+ fy="291.33972"
+ r="4" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient34618"
+ gradientUnits="userSpaceOnUse"
+ x1="125.59209"
+ y1="112.6446"
+ x2="133.11621"
+ y2="119.21729" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient34620"
+ gradientUnits="userSpaceOnUse"
+ x1="130.39502"
+ y1="116.31751"
+ x2="141.83322"
+ y2="132.30261" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35446"
+ gradientUnits="userSpaceOnUse"
+ x1="31"
+ y1="60.000004"
+ x2="34"
+ y2="54.000004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35448"
+ gradientUnits="userSpaceOnUse"
+ x1="135.46967"
+ y1="118"
+ x2="121.4286"
+ y2="101.14284" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35450"
+ gradientUnits="userSpaceOnUse"
+ x1="133.60002"
+ y1="118"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35452"
+ gradientUnits="userSpaceOnUse"
+ x1="132.30316"
+ y1="123.05057"
+ x2="128.8"
+ y2="114.8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411"
+ id="linearGradient35454"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient35718"
+ x1="28.130203"
+ y1="65.791054"
+ x2="32.5"
+ y2="55.066181"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient36452"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36454"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,137.60085,-8.4035259)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,131.60084,3.5964741)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient36273"
+ id="linearGradient36458"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4000084,0,0,0.4000084,143.60084,3.5964739)"
+ x1="-103.37495"
+ y1="417.87503"
+ x2="-101.49999"
+ y2="419.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37095"
+ gradientUnits="userSpaceOnUse"
+ x1="125.75312"
+ y1="111.40558"
+ x2="143.16118"
+ y2="129.27902" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient37097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0028571,0,0,0.9943503,-0.4404318,0.129119)"
+ x1="185.89514"
+ y1="30.343155"
+ x2="197.03207"
+ y2="42.717522" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="188"
+ y1="40.25"
+ x2="180.8125"
+ y2="32.46875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3,3)"
+ x1="187.8125"
+ y1="33.9375"
+ x2="184.25"
+ y2="30.15625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36652"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-3.0999952,2.9000005)"
+ x1="177.85001"
+ y1="33.537502"
+ x2="186.00626"
+ y2="43.381248" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36654"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,6.188671,1.0072576)"
+ x1="182.20605"
+ y1="39.645184"
+ x2="172.36885"
+ y2="31.368597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36656"
+ gradientUnits="userSpaceOnUse"
+ x1="181.14906"
+ y1="32.701904"
+ x2="186.00002"
+ y2="37.415516" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19900"
+ id="linearGradient36658"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9643891,0,0,0.9772371,9.438677,-2.4927424)"
+ x1="181.9404"
+ y1="40.924297"
+ x2="175.82253"
+ y2="34.272892" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient36470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36472"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36713"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36715"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36721"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36727"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient36729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient37396"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37398"
+ gradientUnits="userSpaceOnUse"
+ x1="389.51059"
+ y1="241.72565"
+ x2="388.20074"
+ y2="242.55887"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,0)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-2,-582)"
+ x1="-20"
+ y1="283"
+ x2="-20"
+ y2="284.5" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38561">
+ <g
+ id="g38563">
+ <rect
+ y="278"
+ x="-23"
+ height="13"
+ width="16"
+ id="rect38565"
+ style="fill:url(#linearGradient38570);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient38572);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38567"
+ width="16"
+ height="13"
+ x="-23"
+ y="-304" />
+ </g>
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-1" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-7-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-4-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-0-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-4-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-8-3" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-8-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7-6"
+ id="linearGradient39048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="96"
+ y1="42"
+ x2="68"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-4-2"
+ id="linearGradient39050"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="65"
+ y1="20"
+ x2="66"
+ y2="12" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-4"
+ id="linearGradient39052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,-83,199)"
+ x1="67.25"
+ y1="18"
+ x2="68"
+ y2="16" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-4-27"
+ id="linearGradient39835-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8422958,0,0,0.8364537,82.535678,2.9394266)"
+ x1="89.975014"
+ y1="-32.339718"
+ x2="88.492455"
+ y2="-33.303608" />
+ <linearGradient
+ id="linearGradient35411-4-27">
+ <stop
+ id="stop35414-0-9"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-9-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39837-4"
+ gradientUnits="userSpaceOnUse"
+ x1="131.02808"
+ y1="123.49161"
+ x2="128.7139"
+ y2="115.97001" />
+ <linearGradient
+ id="linearGradient35411-8-1-3">
+ <stop
+ id="stop35414-2-7-1"
+ offset="0"
+ style="stop-color:#2b5385;stop-opacity:1;" />
+ <stop
+ id="stop35416-4-1-2"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient35411-8-1-3"
+ id="linearGradient39839-3"
+ gradientUnits="userSpaceOnUse"
+ x1="136.35806"
+ y1="124.27161"
+ x2="130.48389"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-5-4"
+ id="linearGradient39841-3"
+ gradientUnits="userSpaceOnUse"
+ x1="115.15884"
+ y1="88.476723"
+ x2="109.18613"
+ y2="82.308861" />
+ <linearGradient
+ id="linearGradient23974-5-4">
+ <stop
+ id="stop23976-27-1"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-6-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-8"
+ id="linearGradient39843-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="101"
+ y1="84.25"
+ x2="97.75"
+ y2="81.5" />
+ <linearGradient
+ id="linearGradient1610-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-77"
+ id="linearGradient39845-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(21,0)"
+ x1="87.44548"
+ y1="81.439644"
+ x2="96.592278"
+ y2="89.708977" />
+ <linearGradient
+ id="linearGradient319-77">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-31" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41540"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0369025,0,0,1.5,-458.38567,-344)"
+ x1="23.959812"
+ y1="285"
+ x2="31.498274"
+ y2="285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient22882"
+ id="linearGradient41542"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1929722,0,0,0.5,-462.63135,-59)"
+ x1="24"
+ y1="285"
+ x2="31.538462"
+ y2="285" />
+ <linearGradient
+ id="linearGradient23974-4">
+ <stop
+ id="stop23976-20"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-9"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-37"
+ id="linearGradient32529-7"
+ gradientUnits="userSpaceOnUse"
+ x1="139.2112"
+ y1="111.35809"
+ x2="125.18381"
+ y2="128" />
+ <linearGradient
+ id="linearGradient319-37">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-60" />
+ </linearGradient>
+ <linearGradient
+ y2="125.77761"
+ x2="139.07738"
+ y1="115.76797"
+ x1="129.62384"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient41582"
+ xlink:href="#linearGradient23974-4"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="radialGradient41666"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8128508,0,0,0.8128508,80.474142,14.46897)"
+ cx="430.00003"
+ cy="77.3125"
+ fx="430.00003"
+ fy="77.3125"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.785748,0,0,0.78488,265.93616,46.1048)"
+ x1="210.08989"
+ y1="38.088879"
+ x2="199.27217"
+ y2="38.088879" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient41670"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(399.01387,-202)"
+ x1="28.4375"
+ y1="277"
+ x2="23.25"
+ y2="276.92188" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="437.98615"
+ y1="77"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41674"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="438.61115"
+ y1="78"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.01387,0)"
+ x1="441.98615"
+ y1="77.44017"
+ x2="424.75217"
+ y2="75.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient42432"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient42435"
+ gradientUnits="userSpaceOnUse"
+ x1="135.45557"
+ y1="122.90726"
+ x2="130.54761"
+ y2="116.54932" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient42437"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath42711">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect42713"
+ width="8.7252884"
+ height="17.464855"
+ x="127.4093"
+ y="214.76154" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient38796-7-9">
+ <stop
+ style="stop-color:#fc9694;stop-opacity:1;"
+ offset="0"
+ id="stop38798-6-8" />
+ <stop
+ style="stop-color:#e71609;stop-opacity:1;"
+ offset="1"
+ id="stop38800-1-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-87">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-78" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient24679-1">
+ <stop
+ style="stop-color:#3d361a;stop-opacity:1;"
+ offset="0"
+ id="stop24681-0" />
+ <stop
+ id="stop24683-7"
+ offset="0.45537567"
+ style="stop-color:#d1c595;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop24685-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38719"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38722"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973"
+ id="linearGradient38724"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.46314"
+ y1="113.45913"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38726"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39142"
+ gradientUnits="userSpaceOnUse"
+ x1="400.90442"
+ y1="68.853401"
+ x2="410.47467"
+ y2="77.877228" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-157.00004,-233.00002)"
+ x1="308"
+ y1="323"
+ x2="337.80573"
+ y2="337.517" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38007"
+ gradientUnits="userSpaceOnUse"
+ x1="285.39999"
+ y1="323.80002"
+ x2="286.60001"
+ y2="325" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-1">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-7"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43410-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-4" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-0"
+ id="radialGradient43412-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38796-7-9"
+ id="linearGradient40270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="59.622501"
+ y1="54.1525"
+ x2="60.981617"
+ y2="55.566177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="57.789688"
+ y2="54.130001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.5,-21)"
+ x1="60.25"
+ y1="56.5"
+ x2="56"
+ y2="52.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-87"
+ id="linearGradient40276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1.54625,-1)"
+ x1="63.666252"
+ y1="37.960625"
+ x2="60.676094"
+ y2="34.685287" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24679-1"
+ id="linearGradient40278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="52.17437"
+ y1="65.644958"
+ x2="50.371208"
+ y2="62.960247" />
+ <linearGradient
+ id="linearGradient24143-0">
+ <stop
+ id="stop24145-0"
+ offset="0"
+ style="stop-color:#2c2c2c;stop-opacity:1;" />
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0.5"
+ id="stop24669-1" />
+ <stop
+ id="stop24147-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-3-7"
+ id="linearGradient39686-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-70.605209"
+ y1="-121.58411"
+ x2="-28.177105"
+ y2="-89.026711" />
+ <linearGradient
+ id="linearGradient1610-3-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-1-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-9-4"
+ id="linearGradient39688-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(22,0)"
+ x1="-74"
+ y1="-124"
+ x2="-55.5975"
+ y2="-103.2075" />
+ <linearGradient
+ id="linearGradient319-5-9-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-24-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-6">
+ <stop
+ id="stop37544-18"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-92"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-3">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-3" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-41" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-1">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-9" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient59371">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop59373" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop59375" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-9-1"
+ id="linearGradient42965-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(301.02752,449.99999)"
+ x1="25.963812"
+ y1="155.66899"
+ x2="29.972469"
+ y2="168" />
+ <linearGradient
+ id="linearGradient319-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-92-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-55-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-06-1"
+ id="linearGradient42967-6"
+ gradientUnits="userSpaceOnUse"
+ x1="335.96875"
+ y1="607.09375"
+ x2="337.04251"
+ y2="628.20752" />
+ <linearGradient
+ id="linearGradient1610-06-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-8-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-1-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient41266"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41268"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient41270"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient41272"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="108"
+ y1="500"
+ x2="54.8125"
+ y2="500" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15809"
+ id="linearGradient40920"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.00001,-20)"
+ x1="88.874489"
+ y1="502.71924"
+ x2="41.311054"
+ y2="501.10059" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient40922"
+ gradientUnits="userSpaceOnUse"
+ x1="80.768944"
+ y1="504.67188"
+ x2="76.885078"
+ y2="501.58331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40924"
+ gradientUnits="userSpaceOnUse"
+ x1="89.526657"
+ y1="511.42972"
+ x2="78.000008"
+ y2="501.04794" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40926"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3949409,0.3949425,-0.4243709,0.4254619,404.60763,237.35923)"
+ cx="75.95578"
+ cy="492.15359"
+ fx="75.95578"
+ fy="492.15359"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient40928"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9435203,-2.1990242,1.1704696,1.0049395,-665.14472,173.40654)"
+ cx="79.959885"
+ cy="503.81497"
+ fx="79.959885"
+ fy="503.81497"
+ r="2.9089756" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262"
+ id="radialGradient40930"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8886193,0.8021825,-0.8051059,0.8972684,411.80247,-8.668512)"
+ cx="74.518959"
+ cy="499.99969"
+ fx="74.518959"
+ fy="499.99969"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient40932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.054749"
+ cy="499.87418"
+ fx="75.054749"
+ fy="499.87418"
+ r="3.1650217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-6"
+ id="linearGradient36549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1511102,0,0,-1.1511102,152.68442,762.00423)"
+ x1="-16.608393"
+ y1="199.5118"
+ x2="30.713354"
+ y2="245.13458" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="radialGradient36551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6959954,0.116912,-0.04402498,0.2620878,107.60035,414.99606)"
+ cx="32.193073"
+ cy="243.37001"
+ fx="32.193073"
+ fy="243.37001"
+ r="6.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24143-0"
+ id="linearGradient36553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,147.99998,720.60935)"
+ x1="32.204613"
+ y1="233.6039"
+ x2="35.615856"
+ y2="251.99768" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36555"
+ gradientUnits="userSpaceOnUse"
+ x1="148.76726"
+ y1="134.53409"
+ x2="114.11786"
+ y2="101.28939" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809"
+ id="linearGradient36557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="481.60803"
+ y1="163.09677"
+ x2="477.10818"
+ y2="163.00024" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient59371"
+ id="linearGradient36559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500181,0,0,0.8546123,-235.38338,339.18935)"
+ x1="473.79471"
+ y1="164.64572"
+ x2="463.90472"
+ y2="160.80888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-1"
+ id="linearGradient36561"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-3"
+ id="linearGradient36563"
+ gradientUnits="userSpaceOnUse"
+ x1="138.46678"
+ y1="124.90586"
+ x2="126.18426"
+ y2="116.14438" />
+ <linearGradient
+ id="linearGradient9030-7-8-6">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-4-9-2" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-0-2-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40809-2-2">
+ <stop
+ style="stop-color:#0059d7;stop-opacity:1;"
+ offset="0"
+ id="stop40811-1-6" />
+ <stop
+ style="stop-color:#b7d4ff;stop-opacity:1;"
+ offset="1"
+ id="stop40813-4-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-7-5-5">
+ <stop
+ id="stop20057-1-7-7"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-1-6-8"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16500-4-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-8-5-8" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-8-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37829">
+ <stop
+ id="stop37831"
+ offset="0"
+ style="stop-color:#3d361a;stop-opacity:1;" />
+ <stop
+ style="stop-color:#d1c595;stop-opacity:1;"
+ offset="0.5"
+ id="stop37833" />
+ <stop
+ id="stop37835"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8"
+ id="radialGradient39256"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient39258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ id="linearGradient40455-7">
+ <stop
+ id="stop40457-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36657"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8"
+ id="radialGradient36659"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient36661"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient36663"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37829"
+ id="linearGradient37089"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9999993,0,0,-0.9821923,165.4,716.20935)"
+ x1="261.17639"
+ y1="247.85646"
+ x2="253.86414"
+ y2="288.70752" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39080"
+ id="linearGradient37091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.888884,0,0,-0.8730569,136.66557,688.20759)"
+ x1="261.60016"
+ y1="247.008"
+ x2="263.60016"
+ y2="262.27994" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37093"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-124.99991,219.9903)"
+ x1="19.923029"
+ y1="232.59058"
+ x2="50.485012"
+ y2="265.9697" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40809-2-2"
+ id="linearGradient37096"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7500336,0,0,0.8546123,-239.89087,340.17205)"
+ x1="199.26254"
+ y1="144.5041"
+ x2="193.7029"
+ y2="144.5041" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-7-5-5"
+ id="linearGradient37098"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="579.625"
+ y1="54.299286"
+ x2="576.4375"
+ y2="49.84375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-670.99999,411.99999)"
+ x1="582.79974"
+ y1="56.363762"
+ x2="575.70361"
+ y2="49.87711" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-7-8-6"
+ id="linearGradient37102"
+ gradientUnits="userSpaceOnUse"
+ x1="129.74713"
+ y1="118"
+ x2="144.33401"
+ y2="132.61403" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-4-9-7"
+ id="linearGradient37104"
+ gradientUnits="userSpaceOnUse"
+ x1="140.78264"
+ y1="123.96156"
+ x2="132.25548"
+ y2="116.40535" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7"
+ id="radialGradient37553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.135666"
+ cy="95.970413"
+ fx="-73.135666"
+ fy="95.970413"
+ r="4.9999957" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37667"
+ id="radialGradient37555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4604901,-0.4901463,0.6187826,0.5813434,279.52277,457.42224)"
+ cx="756.98285"
+ cy="206.8443"
+ fx="756.98285"
+ fy="206.8443"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334"
+ id="linearGradient37558"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-94.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758.62622"
+ y2="305.53677" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1"
+ id="radialGradient37553-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7881042,0.01544832,-0.01690407,0.7184169,-16.705439,29.204304)"
+ cx="-73.227486"
+ cy="95.949913"
+ fx="-73.227486"
+ fy="95.949913"
+ r="4.9999957" />
+ <linearGradient
+ id="linearGradient40455-7-1">
+ <stop
+ id="stop40457-6-6"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-7"
+ id="radialGradient37555-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4769848,-0.5257394,0.6056598,0.5494938,269.68012,490.96577)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-9"
+ id="linearGradient37558-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="89.012573"
+ y1="243.96121"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-9">
+ <stop
+ id="stop58336-27"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-9"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-4">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-31" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-23" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(1,-94.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37610-3"
+ xlink:href="#linearGradient16500-4"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71834"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-10.025729,345.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient71814"
+ id="linearGradient71836"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-15.983875,338)"
+ x1="70.55275"
+ y1="97.5"
+ x2="79.355118"
+ y2="107.18619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient71838"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="61.465469"
+ y1="88.058716"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38256"
+ id="linearGradient37188"
+ gradientUnits="userSpaceOnUse"
+ x1="-22"
+ y1="36.47311"
+ x2="-18.85"
+ y2="22.485678"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(168.00015,169.99998)"
+ x1="308"
+ y1="323"
+ x2="343.26239"
+ y2="340" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37201"
+ gradientUnits="userSpaceOnUse"
+ x1="-26"
+ y1="38"
+ x2="-27"
+ y2="30.200407"
+ gradientTransform="translate(522.00015,466)" />
+ <linearGradient
+ id="linearGradient1610-7409">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-488" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-2" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient40578-4-8-5">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-5" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-17" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient58334-1">
+ <stop
+ id="stop58336-5"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-27"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-14">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-23" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-22" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-7409"
+ id="linearGradient37317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="272.92456"
+ y2="26.239208" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-5"
+ id="radialGradient37319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-1"
+ id="linearGradient37321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-14"
+ id="linearGradient37323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.1275"
+ y1="301.01553"
+ x2="758.77625"
+ y2="305.51749" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient37338"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(461.00015,453)"
+ x1="37"
+ y1="53"
+ x2="36.74033"
+ y2="44.322407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37132"
+ gradientUnits="userSpaceOnUse"
+ x1="510.25"
+ y1="36"
+ x2="494"
+ y2="36"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37134"
+ gradientUnits="userSpaceOnUse"
+ x1="492"
+ y1="33"
+ x2="503"
+ y2="43"
+ gradientTransform="matrix(-1,0,0,1,992,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37136"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient37138"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,551,105)"
+ x1="497.3125"
+ y1="35"
+ x2="483"
+ y2="35" />
+ <linearGradient
+ id="linearGradient40455-7-1-7">
+ <stop
+ id="stop40457-6-6-4"
+ offset="0"
+ style="stop-color:#fff991;stop-opacity:1;" />
+ <stop
+ id="stop40459-1-8-0"
+ offset="1"
+ style="stop-color:#fffbb9;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient38362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.923955,0,0,1,2.85168,-84)"
+ x1="-9.3937483"
+ y1="203.3882"
+ x2="28.275171"
+ y2="249.73875" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40455-7-1-7"
+ id="radialGradient38364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1033468,0.01995877,-0.02366572,0.9281732,7.8124646,13.285893)"
+ cx="-73.972397"
+ cy="94.935921"
+ fx="-73.972397"
+ fy="94.935921"
+ r="4.9999957" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38367"
+ gradientUnits="userSpaceOnUse"
+ x1="19.210167"
+ y1="143.17894"
+ x2="38.580528"
+ y2="167.11429"
+ gradientTransform="matrix(1,0,0,0.8461542,0,25.615323)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath43368-7">
+ <rect
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect43370-1"
+ width="16"
+ height="16"
+ x="-79"
+ y="26" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient43276-6">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop43278-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop43280-49" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.6406034,2.5104141,1.6060416,-127.46107,-65.792415)"
+ cx="-67.890839"
+ cy="33.548397"
+ fx="-67.890839"
+ fy="33.548397"
+ r="3.1501868" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43276-6"
+ id="radialGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4098275,-0.7183766,2.5885772,1.4767588,-130.41049,-65.518114)"
+ cx="-74.960228"
+ cy="34.896461"
+ fx="-74.960228"
+ fy="34.896461"
+ r="3.1501868" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient36718"
+ gradientUnits="userSpaceOnUse"
+ x1="400.90442"
+ y1="68.853401"
+ x2="410.47467"
+ y2="77.877228" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38051"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37530"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient37534"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ id="linearGradient1610-6">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-18" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-92" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient38254"
+ gradientUnits="userSpaceOnUse"
+ x1="124.19057"
+ y1="111.30384"
+ x2="134.62978"
+ y2="120.14633" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37509"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9"
+ id="linearGradient37613"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-6"
+ id="linearGradient37615"
+ gradientUnits="userSpaceOnUse"
+ x1="189.76083"
+ y1="248.13905"
+ x2="116.05637"
+ y2="183.6826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38073-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-14.752135"
+ y1="101.82622"
+ x2="-45.074585"
+ y2="68.279541" />
+ <linearGradient
+ id="linearGradient15425-4-9-8">
+ <stop
+ style="stop-color:#960000;stop-opacity:1;"
+ offset="0"
+ id="stop15427-5-8-24" />
+ <stop
+ style="stop-color:#c80000;stop-opacity:0;"
+ offset="1"
+ id="stop15429-8-2-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-1"
+ id="linearGradient38075-5"
+ gradientUnits="userSpaceOnUse"
+ x1="137.33838"
+ y1="124.67571"
+ x2="131.35606"
+ y2="118.00494" />
+ <linearGradient
+ id="linearGradient5060-1">
+ <stop
+ id="stop5062-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-1"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient38077-1"
+ gradientUnits="userSpaceOnUse"
+ x1="127.15736"
+ y1="111.48302"
+ x2="146.01884"
+ y2="136.15825" />
+ <linearGradient
+ id="linearGradient319-52">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-7614" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-232" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15425-4-9-8"
+ id="linearGradient38079-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,22)"
+ x1="-15"
+ y1="101"
+ x2="-22"
+ y2="94" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14418-6"
+ id="linearGradient14433-1"
+ gradientUnits="userSpaceOnUse"
+ x1="139.29807"
+ y1="127.35454"
+ x2="130.33557"
+ y2="115.81818" />
+ <linearGradient
+ id="linearGradient14418-6">
+ <stop
+ id="stop14420-8"
+ offset="0"
+ style="stop-color:#fa2509;stop-opacity:1;" />
+ <stop
+ id="stop14422-5"
+ offset="1"
+ style="stop-color:#fa2509;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14435-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.36379"
+ y1="110.81054"
+ x2="135.22182"
+ y2="120.76331" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14437-6"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="141.43347"
+ y2="127.52184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-2"
+ id="linearGradient14439-9"
+ gradientUnits="userSpaceOnUse"
+ x1="125.20553"
+ y1="111.38132"
+ x2="132.35237"
+ y2="118.69846" />
+ <linearGradient
+ id="linearGradient10069-2">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-79" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-52"
+ id="linearGradient14441-4"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient48327-1"
+ id="radialGradient38306-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4461753,0.01083717,0.0036163,6.752143,-191.34795,-740.3814)"
+ cx="131.99811"
+ cy="126.63337"
+ fx="131.99811"
+ fy="126.63337"
+ r="9.1978254" />
+ <linearGradient
+ id="linearGradient48327-1">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop48329-23" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="1"
+ id="stop48331-3" />
+ </linearGradient>
+ <linearGradient
+ y2="118.69846"
+ x2="132.35237"
+ y1="111.38132"
+ x1="125.20553"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient37646-4"
+ xlink:href="#linearGradient10069-74-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient10069-74-1">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-0-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-9-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-7409-3-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-48-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-82-6-27" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient38313-7"
+ gradientUnits="userSpaceOnUse"
+ x1="125.81818"
+ y1="111.81818"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-7409-3-7"
+ id="linearGradient37677"
+ gradientUnits="userSpaceOnUse"
+ x1="130.60338"
+ y1="115.87343"
+ x2="143.88347"
+ y2="129.27184" />
+ <linearGradient
+ id="linearGradient319-19">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-865" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-02" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-8-3-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-9-8-7" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-2-7-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-95-2-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-43-7-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-12-7-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient21327-6">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient20055-8-4">
+ <stop
+ id="stop20057-8-0"
+ offset="0"
+ style="stop-color:#0a2a5a;stop-opacity:1;" />
+ <stop
+ id="stop20059-2-0"
+ offset="1"
+ style="stop-color:#3771c8;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient39088">
+ <stop
+ id="stop39090"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop39092"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-83">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-24" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-11" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-95">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-10" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-64" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient11871-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop11873-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop11875-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-87" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-42" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40171"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40173"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40175"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="120.06789"
+ y2="54.6674" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40282"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,13)"
+ x1="-56.8125"
+ y1="329.06256"
+ x2="-47.214466"
+ y2="329.26965" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38693"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38703"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38706"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-157,821.03125)"
+ x1="-90.5"
+ y1="413.51562"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38720"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3846148,0,0,1,-211.38442,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38723"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient38725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,821.03125)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-7"
+ id="linearGradient38731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,-2.4825165)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient38736"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,-156,824.54874)"
+ x1="-89.75"
+ y1="413.98114"
+ x2="-86.75"
+ y2="416.32614" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39199"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39201"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39203"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39205"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39207"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient39246"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-420,490.00041)"
+ x1="301.5"
+ y1="-105.87541"
+ x2="340"
+ y2="-65.250412" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39248"
+ gradientUnits="userSpaceOnUse"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39255"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient39259"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,6)"
+ x1="-97"
+ y1="408"
+ x2="-88"
+ y2="413.51562" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient38961"
+ gradientUnits="userSpaceOnUse"
+ x1="488.5"
+ y1="568"
+ x2="495"
+ y2="568" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38956">
+ <rect
+ style="fill:url(#linearGradient38961);stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38958"
+ width="16"
+ height="12"
+ x="488"
+ y="560"
+ rx="0"
+ ry="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-83"
+ id="linearGradient39115"
+ gradientUnits="userSpaceOnUse"
+ x1="487.2518"
+ y1="531.95105"
+ x2="490.65796"
+ y2="580.63715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39117"
+ gradientUnits="userSpaceOnUse"
+ x1="496.49335"
+ y1="537.78113"
+ x2="498.40021"
+ y2="540.13623" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11871-3"
+ id="linearGradient39119"
+ gradientUnits="userSpaceOnUse"
+ x1="495.85294"
+ y1="541.69116"
+ x2="495.25"
+ y2="539.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-3"
+ id="linearGradient39122"
+ gradientUnits="userSpaceOnUse"
+ x1="494.38467"
+ y1="532.42651"
+ x2="496.21078"
+ y2="541.02698" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703"
+ id="linearGradient39261"
+ gradientUnits="userSpaceOnUse"
+ x1="122.25188"
+ y1="106.08706"
+ x2="147.08464"
+ y2="134.12131" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39263"
+ gradientUnits="userSpaceOnUse"
+ x1="116.75861"
+ y1="97.375854"
+ x2="145.729"
+ y2="137.52937" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39265"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient319-46">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-03" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-62" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-46"
+ id="linearGradient39508"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-20,0)"
+ x1="39.102718"
+ y1="641.73358"
+ x2="58.680996"
+ y2="661.93829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43807"
+ id="linearGradient39518"
+ gradientUnits="userSpaceOnUse"
+ x1="648.09674"
+ y1="355.85541"
+ x2="634.09503"
+ y2="341.23715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient39088"
+ id="linearGradient39520"
+ gradientUnits="userSpaceOnUse"
+ x1="696.63055"
+ y1="403.93069"
+ x2="643.71313"
+ y2="349.93216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-95"
+ id="linearGradient39523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8461524,0,0,0.8461523,99.385524,54.308237)"
+ x1="633.10468"
+ y1="338.95337"
+ x2="649.69073"
+ y2="354.92981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient39716"
+ gradientUnits="userSpaceOnUse"
+ x1="121.80637"
+ y1="106.4641"
+ x2="142.1468"
+ y2="132.44617" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient39718"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40189"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40295"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,136.97426,-72.21433)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient40297"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,131.027,-79.5885)"
+ x1="57.347244"
+ y1="82.75322"
+ x2="86.00116"
+ y2="112.03586" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask40306">
+ <path
+ id="path40308"
+ d="m 195,11.00001 0,14 0.5,0 13.5,-13.5 0,-0.5 -14,0 z"
+ style="fill:#ffffff;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40703-5-5"
+ id="linearGradient39261-4-5"
+ gradientUnits="userSpaceOnUse"
+ x1="128.09367"
+ y1="112.43961"
+ x2="145.20987"
+ y2="133.4879" />
+ <linearGradient
+ id="linearGradient40703-5-5">
+ <stop
+ style="stop-color:#143564;stop-opacity:1;"
+ offset="0"
+ id="stop40705-8-2" />
+ <stop
+ style="stop-color:#c1d7f8;stop-opacity:1;"
+ offset="1"
+ id="stop40707-8-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient38252-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop38254-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop38256-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient40511-7-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ id="linearGradient1610-74-9-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-0-8-7" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-9-3-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient40507-4-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-8-6-5">
+ <stop
+ id="stop58336-8-9-2"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-24-8-7"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient40649-2-6-6"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-5-6-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-17-2-4" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-11-3-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient40502-7-8-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40635-7-2-2"
+ gradientUnits="userSpaceOnUse"
+ x1="125.99933"
+ y1="111.2683"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ id="linearGradient319-5-6-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761-2-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-89-7-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40637-9-5-8"
+ gradientUnits="userSpaceOnUse"
+ x1="126.72586"
+ y1="112.53999"
+ x2="134.91479"
+ y2="122.36016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13973-3-7-8"
+ id="linearGradient40639-1-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(19.367382,0)"
+ x1="111.2239"
+ y1="112.62726"
+ x2="99.628899"
+ y2="99.029617" />
+ <linearGradient
+ id="linearGradient13973-3-7-8">
+ <stop
+ style="stop-color:#3c4c18;stop-opacity:1;"
+ offset="0"
+ id="stop13975-1-8-9" />
+ <stop
+ style="stop-color:#9aff31;stop-opacity:0;"
+ offset="1"
+ id="stop13977-2-0-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5-6-2"
+ id="linearGradient40641-9-2-7"
+ gradientUnits="userSpaceOnUse"
+ x1="127.63637"
+ y1="114.2303"
+ x2="143.69765"
+ y2="131.03783" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-74-9-1"
+ id="linearGradient41638-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,-270.46874,9.59825)"
+ x1="256.14325"
+ y1="5.6181068"
+ x2="278.79254"
+ y2="29.688427" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-8-6-5"
+ id="linearGradient41640-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-114,-208)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="radialGradient41642-5-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4545454,0.3636364,-0.3862167,0.4827711,-2.5397644,26.345139)"
+ cx="-27.749987"
+ cy="32.615383"
+ fx="-27.749987"
+ fy="32.615383"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-5-6-1"
+ id="linearGradient41644-5-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-784,-271)"
+ x1="754"
+ y1="300.5"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40875-3-9-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ id="linearGradient37542-3-0-7-6">
+ <stop
+ id="stop37544-1-6-6-5"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-2-1-7-0"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40877-5-5-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ id="linearGradient319-34-8-7-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-11-9-8-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-38-3-1-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient40879-9-8-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="171.50414"
+ y2="248.54021" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient40881-8-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-7-6-7-4"
+ id="radialGradient40883-4-0-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.06118084,-0.8594818,2.4629674,-0.1753088,-259.40057,190.15309)"
+ cx="77.721619"
+ cy="104.09358"
+ fx="77.721619"
+ fy="104.09358"
+ r="3.9999998" />
+ <linearGradient
+ id="linearGradient10069-7-6-7-4">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-81-3-2-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-6-7-5-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39136-2-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.695652,0,0,0.869703,-44.93485,-114.66358)"
+ x1="188.77448"
+ y1="259.745"
+ x2="164.0939"
+ y2="242.22473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39138-8-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(357.00001,373)"
+ x1="-287.75"
+ y1="-276.75"
+ x2="-276"
+ y2="-264.875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-3-0-7-6"
+ id="linearGradient39140-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.608695,0,0,0.760996,-26.1305,-84.76968)"
+ x1="130.70929"
+ y1="210.78392"
+ x2="174.35753"
+ y2="250.6842" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-34-8-7-0"
+ id="linearGradient39143-0-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(361.00001,376)"
+ x1="-283"
+ y1="-272"
+ x2="-277.01501"
+ y2="-267.26749" />
+ <linearGradient
+ id="linearGradient319-17-1-6">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40679"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25417"
+ id="linearGradient40731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.997161,-259.00079,67.35344)"
+ x1="280.0918"
+ y1="129.28557"
+ x2="267.20212"
+ y2="116.41341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6"
+ id="linearGradient40733"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-7"
+ id="linearGradient40733-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-17-1-6-8"
+ id="linearGradient40733-03"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,-259.00009,90.24189)"
+ x1="255.63673"
+ y1="99.513062"
+ x2="275.1503"
+ y2="129.36641" />
+ <linearGradient
+ id="linearGradient319-17-1-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-115-1-5-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-27-3-7-1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40897">
+ <rect
+ y="198"
+ x="-41"
+ height="16"
+ width="15"
+ id="rect40899"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath40902">
+ <rect
+ y="197"
+ x="-22"
+ height="17"
+ width="15"
+ id="rect40904"
+ style="opacity:0.45;fill:#80b3ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(-1,1)" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient38478"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(254.01612,-211.00101)"
+ x1="96.824379"
+ y1="393.90298"
+ x2="94.246101"
+ y2="391.21976" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask38474">
+ <rect
+ style="fill:url(#linearGradient38478);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38476"
+ width="15"
+ height="15"
+ x="343.01611"
+ y="174.99901" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.050372,0,0,1.050372,-3.551238,-0.730396)"
+ cx="70.5"
+ cy="14.5"
+ fx="70.5"
+ fy="14.5"
+ r="1.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient44320"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5399935,0.3131662,-0.3907892,0.5793905,38.141764,-16.056748)"
+ cx="70.470596"
+ cy="14.649424"
+ fx="70.470596"
+ fy="14.649424"
+ r="5.5192375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="121.22078"
+ y2="56.357628" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-19"
+ id="linearGradient42990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(207,-246.99988)"
+ x1="-56.5"
+ y1="342.0625"
+ x2="-49"
+ y2="341" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42992"
+ gradientUnits="userSpaceOnUse"
+ x1="126.55782"
+ y1="113.57294"
+ x2="132.41052"
+ y2="118.81034" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-95-2-7"
+ id="linearGradient42994"
+ gradientUnits="userSpaceOnUse"
+ x1="132"
+ y1="117.26753"
+ x2="142.72656"
+ y2="127.72736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-8-3-3"
+ id="linearGradient42996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(4.9999967,20)"
+ x1="-114.75"
+ y1="546.5"
+ x2="-110.5"
+ y2="542.5" />
+ <linearGradient
+ id="linearGradient44627">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop44629" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop44631" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10069-9-7-4-74">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-5-0" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-5-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient44939-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44402"
+ gradientUnits="userSpaceOnUse"
+ x1="351.15625"
+ y1="108.35222"
+ x2="345.40625"
+ y2="108.00847" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44404"
+ gradientUnits="userSpaceOnUse"
+ x1="351.71875"
+ y1="106.93575"
+ x2="347.1875"
+ y2="106.7795" />
+ <filter
+ inkscape:collect="always"
+ id="filter44473"
+ x="-0.12578467"
+ width="1.2515693"
+ y="-0.11472401"
+ height="1.229448"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.81235925"
+ id="feGaussianBlur44475" />
+ </filter>
+ <filter
+ inkscape:collect="always"
+ id="filter44477"
+ x="-0.12176471"
+ width="1.2435294"
+ y="-0.11828571"
+ height="1.2365714"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.8625"
+ id="feGaussianBlur44479" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44485"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="284.5"
+ y2="106.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44942"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-21)"
+ x1="351.71875"
+ y1="106.93575"
+ x2="339.125"
+ y2="105.092" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44944"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,698,183)"
+ x1="351.15625"
+ y1="108.35222"
+ x2="336.40625"
+ y2="106.19597" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44950"
+ gradientUnits="userSpaceOnUse"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102"
+ gradientTransform="matrix(-1,0,0,1,593.02125,-1.8e-6)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient44954"
+ gradientUnits="userSpaceOnUse"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath45147">
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccc"
+ id="path45149"
+ d="m 5,261 13,0 0,1 -1,0 0,1 1,0 0,1 -1,0 0,1 -1,0 0,2 2,0 0,-1 1,0 0,-1 1,0 0,1 1,0 0,-1 1,0 0,13 -17,0 0,-17 z"
+ style="opacity:0.2;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient45220"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,221,10)"
+ x1="115.84575"
+ y1="10.8125"
+ x2="106.125"
+ y2="19.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45283"
+ gradientUnits="userSpaceOnUse"
+ x1="125.86876"
+ y1="111.85698"
+ x2="130.88379"
+ y2="121.70699" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38252-9"
+ id="linearGradient45285"
+ gradientUnits="userSpaceOnUse"
+ x1="134.78751"
+ y1="122.29202"
+ x2="132.60205"
+ y2="117.96092" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-4-74"
+ id="radialGradient45309"
+ cx="336.42892"
+ cy="611.10455"
+ fx="336.42892"
+ fy="611.10455"
+ r="5.9852905"
+ gradientTransform="matrix(1.0070601,0.03386866,-0.03770425,1.1211085,20.665977,-85.772965)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44627"
+ id="linearGradient43826"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,1444.9824,-215)"
+ x1="689.47357"
+ y1="427"
+ x2="685.47357"
+ y2="427" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask43822">
+ <rect
+ y="208"
+ x="754"
+ height="9"
+ width="12"
+ id="rect43824"
+ style="opacity:0.93999993;fill:url(#linearGradient43826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient43856"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,61.53822,346.48241)"
+ x1="246.89435"
+ y1="-4.4418921"
+ x2="277.68143"
+ y2="30.743095" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient43858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(218.01612,129)"
+ x1="87.03125"
+ y1="241"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46780"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46782"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46784"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46786"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46818"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46820"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46822"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46824"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46992"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46994"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient46996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient46998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,140,-415)"
+ x1="172.5625"
+ y1="601.5"
+ x2="159.13864"
+ y2="585.28772" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient47000"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,237.98388,150.25)"
+ x1="249.64528"
+ y1="1.5973248"
+ x2="271.98389"
+ y2="35.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="412.10059"
+ cy="375.96332"
+ fx="412.10059"
+ fy="375.96332"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25106"
+ gradientUnits="userSpaceOnUse"
+ x1="408.91928"
+ y1="373.01221"
+ x2="410.55432"
+ y2="375.5058" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25117"
+ gradientUnits="userSpaceOnUse"
+ x1="411.05389"
+ y1="375.39175"
+ x2="407.62576"
+ y2="370.21317" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient25449"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,-346.7085,428.4841)"
+ x1="352.98236"
+ y1="314.11398"
+ x2="353.72073"
+ y2="297.92099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25451"
+ gradientUnits="userSpaceOnUse"
+ x1="436.54755"
+ y1="524.30481"
+ x2="434.49387"
+ y2="519.46057" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient25108"
+ id="linearGradient25453"
+ gradientUnits="userSpaceOnUse"
+ x1="432.0849"
+ y1="524.97125"
+ x2="433"
+ y2="526" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="radialGradient25457"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5274943,0,0,0.7696585,194.81546,86.715119)"
+ cx="410.73904"
+ cy="370.11554"
+ fx="410.73904"
+ fy="370.11554"
+ r="4.4262571" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279.75"
+ y1="101.5"
+ x2="283"
+ y2="105.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="279"
+ y1="102"
+ x2="281.75"
+ y2="102" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8"
+ id="linearGradient23559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,225,-182.99437)"
+ x1="292.25"
+ y1="106.5"
+ x2="289.5"
+ y2="109.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24341"
+ x1="413.9498"
+ y1="386.45807"
+ x2="406.7699"
+ y2="374.42419"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24343"
+ id="linearGradient24349"
+ gradientUnits="userSpaceOnUse"
+ x1="403.9577"
+ y1="367.62839"
+ x2="413.98795"
+ y2="374.07153" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6"
+ id="radialGradient24354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6402148,-1.1088846,0.8413297,0.4857498,104.42892,800.46622)"
+ cx="409.55594"
+ cy="52.367992"
+ fx="409.55594"
+ fy="52.367992"
+ r="3.8798895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34157"
+ id="linearGradient24511"
+ gradientUnits="userSpaceOnUse"
+ x1="270.66064"
+ y1="68.113258"
+ x2="257.38638"
+ y2="81.382545" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient24513"
+ gradientUnits="userSpaceOnUse"
+ x1="256.90005"
+ y1="80.100891"
+ x2="262.43726"
+ y2="74.562462" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29149"
+ id="radialGradient24515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.217888"
+ cy="500.66806"
+ fx="75.217888"
+ fy="500.66806"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18821"
+ id="radialGradient24517"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8728692,0.8400852,-1.1671853,1.2200916,594.18579,-173.07738)"
+ cx="75.554794"
+ cy="500.26215"
+ fx="75.554794"
+ fy="500.26215"
+ r="3.1650217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24519"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6691529,0,4.3047361e-8,0.6954014,84.50351,24.951375)"
+ cx="259.02887"
+ cy="77.962585"
+ fx="259.02887"
+ fy="77.962585"
+ r="3.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="radialGradient24523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3879142,0,8.9286134e-8,1.4423572,-101.87942,-32.970267)"
+ cx="259.55096"
+ cy="77.188034"
+ fx="259.55096"
+ fy="77.188034"
+ r="3.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="240.70209"
+ y1="-9.4293213"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient30368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="276.89801"
+ y2="31.515814" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="linearGradient30370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30208"
+ id="linearGradient25056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-1297,-948)"
+ x1="1663.8125"
+ y1="722"
+ x2="1661.8125"
+ y2="726.37006" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19425"
+ id="radialGradient25058"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1378252,-0.2988982,2.5269117,1.1651875,-1689.2674,-563.64056)"
+ cx="1662.2664"
+ cy="722.19189"
+ fx="1662.2664"
+ fy="722.19189"
+ r="5.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient25060"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,-1256.7473,-918.72044)"
+ x1="1984.3658"
+ y1="827.77124"
+ x2="1979.2772"
+ y2="827.32849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient29407"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29409"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29411"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient29413"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ id="linearGradient44939-8-7-1-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-4-5-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-0-2-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient37396-1"
+ gradientUnits="userSpaceOnUse"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)" />
+ <linearGradient
+ id="linearGradient37542-7">
+ <stop
+ id="stop37544-40"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-94"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient15742-5"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998"
+ gradientTransform="matrix(0,1,-1,0,634.98585,-146.00607)" />
+ <linearGradient
+ id="linearGradient37542-5">
+ <stop
+ id="stop37544-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-71"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27860"
+ x1="392.02036"
+ y1="241.13428"
+ x2="386.30408"
+ y2="241.31801"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient27872"
+ gradientUnits="userSpaceOnUse"
+ x1="392.0101"
+ y1="224.99998"
+ x2="392.0101"
+ y2="249.99998"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854"
+ id="linearGradient27874"
+ gradientUnits="userSpaceOnUse"
+ x1="390.87131"
+ y1="241.13428"
+ x2="386.74603"
+ y2="242.46706"
+ gradientTransform="matrix(-1,0,0,1,782.02022,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-5"
+ id="linearGradient27886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,1,0,146.99795,-188.00607)"
+ x1="392.0101"
+ y1="222.99998"
+ x2="392.0101"
+ y2="247.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27896"
+ id="linearGradient27902"
+ x1="388.70071"
+ y1="244.85669"
+ x2="391.17557"
+ y2="249.54126"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient10069-9-71">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-5" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient23974-2">
+ <stop
+ id="stop23976-2"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-1"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath28964">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#linearGradient28968);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 117.50984,228.63415 0,-15.01646 11.71735,5.49383 0,15.38271 -11.71735,-5.86008 z"
+ id="path28966"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-2"
+ id="linearGradient28968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-38.103703"
+ y1="266.11719"
+ x2="-20.826464"
+ y2="253.23859" />
+ <linearGradient
+ id="linearGradient319-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-761" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4646688,0,0,1.4650206,168.77325,-157.03253)"
+ x1="-26.511335"
+ y1="257.99881"
+ x2="-30.075666"
+ y2="259.87677" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29419">
+ <path
+ id="path29422"
+ d="m 117.50984,229.00041 0,-15.38272 11.71735,5.49383 0,15.74897 -11.71735,-5.86008 z"
+ style="opacity:0.5;fill:url(#linearGradient29424);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974"
+ id="linearGradient29988"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="-35.153767"
+ y1="271.58572"
+ x2="-23.636715"
+ y2="252.03563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-5"
+ id="linearGradient29990"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-113.93222,176.71918)"
+ x1="446.93222"
+ y1="105.28082"
+ x2="441.93222"
+ y2="120.28082" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-71"
+ id="linearGradient29994"
+ gradientUnits="userSpaceOnUse"
+ x1="123.80045"
+ y1="111.03492"
+ x2="131.72171"
+ y2="118.18078" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-6-8"
+ id="linearGradient29773-5"
+ gradientUnits="userSpaceOnUse"
+ x1="124.78239"
+ y1="111.13178"
+ x2="132.99687"
+ y2="118.98331" />
+ <linearGradient
+ id="linearGradient21327-6-8">
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:1;"
+ offset="0"
+ id="stop21329-3-4" />
+ <stop
+ style="stop-color:#1e3e70;stop-opacity:0;"
+ offset="1"
+ id="stop21331-4-0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient28526">
+ <stop
+ id="stop28528"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop28530"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-52-2">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-32-8" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-46-8" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-62-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-90-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient29334"
+ gradientUnits="userSpaceOnUse"
+ x1="121.74819"
+ y1="104.14172"
+ x2="140.18503"
+ y2="126.89457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069"
+ id="linearGradient29336"
+ gradientUnits="userSpaceOnUse"
+ x1="155.10138"
+ y1="91.071259"
+ x2="122.40444"
+ y2="127.60542" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient24000"
+ id="linearGradient29338"
+ gradientUnits="userSpaceOnUse"
+ x1="124.66362"
+ y1="126.19594"
+ x2="132"
+ y2="118" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29340"
+ gradientUnits="userSpaceOnUse"
+ x1="124.28249"
+ y1="126.88889"
+ x2="133.53401"
+ y2="116.55647" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29342"
+ gradientUnits="userSpaceOnUse"
+ x1="147.25899"
+ y1="101.45953"
+ x2="130.82327"
+ y2="119.554" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1138.1963"
+ y1="287.70486"
+ x2="1146.6705"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1286)"
+ x1="757.2467"
+ y1="367.52411"
+ x2="740.30865"
+ y2="405.3895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="745.48267"
+ y1="396.45972"
+ x2="737.62225"
+ y2="401.90442" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500"
+ id="linearGradient28583"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,1,0,-239.00001,1286)"
+ x1="743"
+ y1="402"
+ x2="752"
+ y2="400" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38845"
+ id="linearGradient28589"
+ gradientUnits="userSpaceOnUse"
+ x1="162.41054"
+ y1="413.87982"
+ x2="161.83331"
+ y2="406.47784"
+ gradientTransform="matrix(0,1,-1,0,574.99991,384.00001)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,558.99999,1288)"
+ x1="743.87036"
+ y1="396.04428"
+ x2="744.1059"
+ y2="423.54419" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient28600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,719.99999,383.00001)"
+ x1="148.56801"
+ y1="544.21143"
+ x2="163.11441"
+ y2="569.18829" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient38831"
+ id="linearGradient28603"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,449.99999,1678)"
+ x1="1141.2856"
+ y1="288.19919"
+ x2="1146.2682"
+ y2="291.35333" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-52-2"
+ id="radialGradient29805"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.94105289,0.01178942,-0.01073736,0.8570756,238.4669,249.70522)"
+ cx="-30.028414"
+ cy="19.425121"
+ fx="-30.028414"
+ fy="19.425121"
+ r="7" />
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask29801">
+ <rect
+ style="opacity:0.35;color:#000000;fill:url(#radialGradient29805);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.71217775;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect29803"
+ width="15"
+ height="16"
+ x="204"
+ y="257" />
+ </mask>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7"
+ id="linearGradient29884"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,780.92531,0)"
+ x1="389.73953"
+ y1="220.84622"
+ x2="389.59052"
+ y2="248.09296" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient29886"
+ gradientUnits="userSpaceOnUse"
+ x1="391.62881"
+ y1="243.48854"
+ x2="386.13718"
+ y2="244.68996" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath50172-0">
+ <path
+ id="path50174-8"
+ d="m -177.34375,498 a 1.001098,1.001098 0 1 0 0.0937,2 l 3.65625,0 -4.25,5.9375 a 1.0001,1.0001 0 0 0 -0.1875,0.59375 l 0,0.5 a 1.0001,1.0001 0 0 0 1,1 L -171.75,508 a 1.0001,1.0001 0 1 0 0,-2 l -3.6875,0.0312 4.25,-5.9375 A 1.0001,1.0001 0 0 0 -171,499.5 l 0,-0.5 a 1.0001,1.0001 0 0 0 -1,-1 l -5.25,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <radialGradient
+ id="radialGradient16142-7"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16144-4" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16146-0" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient37542-78">
+ <stop
+ id="stop37544-2"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-78"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-0" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-89" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37542-04-82">
+ <stop
+ id="stop37544-9-0"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-4-5"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-38-2">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-6-7" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-9-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30766-8"
+ inkscape:collect="always">
+ <stop
+ id="stop30768-7"
+ offset="0"
+ style="stop-color:#be0000;stop-opacity:1" />
+ <stop
+ id="stop30770-8"
+ offset="1"
+ style="stop-color:#ff5108;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient30752-0">
+ <stop
+ style="stop-color:#0c1b63;stop-opacity:1;"
+ offset="0"
+ id="stop30754-9" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop30756-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32140"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-64,-10)"
+ x1="18.773417"
+ y1="6.2494373"
+ x2="6.9718256"
+ y2="17.82831" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32142"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.701513,0.712657,0.712657,0.701513,50.5916,-449.6745)"
+ x1="385.62408"
+ y1="244.3396"
+ x2="401.63013"
+ y2="244.38875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32144"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-65.00001,-10.749995)"
+ x1="61.032951"
+ y1="5.9830923"
+ x2="46.491322"
+ y2="20.147326" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32146"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.199998,0,0,1.199999,-74.19988,-12.499988)"
+ x1="59.02124"
+ y1="6.0129876"
+ x2="44.509518"
+ y2="20.110929" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32148"
+ gradientUnits="userSpaceOnUse"
+ x1="47.348152"
+ y1="-25.553123"
+ x2="53.567928"
+ y2="-31.095215" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142-7"
+ id="linearGradient31946"
+ gradientUnits="userSpaceOnUse"
+ x1="-176.1799"
+ y1="508.33572"
+ x2="-193.07495"
+ y2="482.27924" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16142"
+ id="linearGradient31948"
+ gradientUnits="userSpaceOnUse"
+ x1="-178.00789"
+ y1="505.36523"
+ x2="-194.90294"
+ y2="479.30875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-78"
+ id="linearGradient31950"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-7.152175,20.92167)"
+ x1="155.37498"
+ y1="230.51552"
+ x2="181.25543"
+ y2="269.24564" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31952"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.765625"
+ y1="242.39062"
+ x2="96"
+ y2="251.40294" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-04-82"
+ id="linearGradient31954"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.043478,0,0,0.956667,-354.13606,119.42158)"
+ x1="148.47061"
+ y1="217.28368"
+ x2="171.77303"
+ y2="250.87756" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-38-2"
+ id="linearGradient31956"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="-259.99872"
+ y1="340.81195"
+ x2="-253.90541"
+ y2="345.10736" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30766-8"
+ id="linearGradient31958"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0017964,0,0,0.99629977,-0.31613165,0.94171311)"
+ x1="167.51979"
+ y1="252.44223"
+ x2="170.78137"
+ y2="261.69635" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-2"
+ id="linearGradient31960"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.000002,13.499998)"
+ x1="87.473038"
+ y1="238.21507"
+ x2="89.889603"
+ y2="243.80345" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30752-0"
+ id="linearGradient31962"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,10)"
+ x1="168.53265"
+ y1="244.52007"
+ x2="168.53265"
+ y2="239.5473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31964"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-237.5,45.5045)"
+ x1="263.35254"
+ y1="19.495501"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31966"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-238,44.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31968"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-243.5,51.5045)"
+ x1="260.25369"
+ y1="11.017987"
+ x2="275.43362"
+ y2="28.583914" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient31970"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-244,50.0045)"
+ x1="271.69839"
+ y1="22.713789"
+ x2="283.37738"
+ y2="36.874088" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31972"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-57.00003,-165.99191)"
+ x1="85.853188"
+ y1="239.5473"
+ x2="90.563423"
+ y2="242.99191" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31974"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-51,-172)"
+ x1="88"
+ y1="240.90625"
+ x2="92.8125"
+ y2="245.625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient28526"
+ id="linearGradient32236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-175.72238"
+ y1="66.323799"
+ x2="-183.03308"
+ y2="66.235535" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20055-8-4"
+ id="linearGradient32238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(423,225)"
+ x1="-174.51762"
+ y1="66.654762"
+ x2="-183.58472"
+ y2="65.917358" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62"
+ id="linearGradient32240"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9098462,0,0,0.9414558,406.86085,228.58514)"
+ x1="-180.7581"
+ y1="63.445515"
+ x2="-169.07387"
+ y2="62.182106" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.861107"
+ y2="-15.138513" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-62-8"
+ id="linearGradient32244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,371.28571,304.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-96.705353"
+ y2="-15.562586" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29312"
+ id="linearGradient32246"
+ gradientUnits="userSpaceOnUse"
+ x1="242.99834"
+ y1="291.5047"
+ x2="244.75"
+ y2="291.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient29304"
+ id="linearGradient32248"
+ gradientUnits="userSpaceOnUse"
+ x1="245.20622"
+ y1="294.49902"
+ x2="243.5"
+ y2="294.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-52.983883,-129)"
+ x1="258"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32299"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.983883,-126)"
+ x1="259.75"
+ y1="388"
+ x2="273"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32301"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.000005,-120)"
+ x1="257.75"
+ y1="388"
+ x2="272"
+ y2="388" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32303"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9166695,0,0,0.9203753,-9.025729,344.78566)"
+ x1="80.60067"
+ y1="108.47212"
+ x2="68.0271"
+ y2="94.239906" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient13938"
+ id="linearGradient32305"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-14.983875,337)"
+ x1="68.361542"
+ y1="95.337166"
+ x2="88.785263"
+ y2="116.62141" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)"
+ x1="58.761654"
+ y1="84.330009"
+ x2="81.383331"
+ y2="108.06429" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32353"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32355"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32357"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9050931,-7.9558708e-4,0.00612764,0.9147058,39.488451,313.56226)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32359"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient32426"
+ gradientUnits="userSpaceOnUse"
+ x1="114.15679"
+ y1="100.93772"
+ x2="137.5759"
+ y2="124.47867" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32428"
+ gradientUnits="userSpaceOnUse"
+ x1="131.12576"
+ y1="118"
+ x2="140.19273"
+ y2="125.82862" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient32430"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient32432"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.77915445,-6.9426235e-4,0.00527501,0.79821029,158.94945,341.39422)"
+ x1="299.70026"
+ y1="408.49368"
+ x2="322.08145"
+ y2="429.53806" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-7-1-7"
+ id="linearGradient32434"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-1,73,792.5)"
+ x1="346"
+ y1="128.5"
+ x2="368"
+ y2="123.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31025"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.1483,118.6716)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="85.347076"
+ y2="113.09817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.72300056,-0.72300056,0.72300056,0.72300056,254.24127,118.38327)"
+ x1="85.548706"
+ y1="100.22395"
+ x2="84.95932"
+ y2="122.23821" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.707107,-0.707107,0.707107,0.707107,257.14826,118.6716)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient30958"
+ id="linearGradient31157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.74301467,-0.74301467,0.74301467,0.74301467,250.58064,118.02214)"
+ x1="85.861206"
+ y1="99.348953"
+ x2="85.60022"
+ y2="105.88815" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-19-1"
+ id="linearGradient32854-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1666676,0,0,-1.1666676,119.15081,827.66691)"
+ x1="262.04343"
+ y1="233.0448"
+ x2="273.85818"
+ y2="247.32738" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-19-1">
+ <stop
+ id="stop37544-48-6-1-8-9"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-6-8"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-7-8-3-0-3"
+ id="linearGradient32856-3-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,-249.10439,522.04547)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient44939-8-4-7-8-3-0-3">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-40-2-4-2-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-9-4-9-8-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10069-9-7-5-4-6-5-0-3"
+ id="linearGradient32858-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.53706486,0,0,0.53706486,144.9138,-563.9364)"
+ x1="97.616623"
+ y1="39.47208"
+ x2="94.157646"
+ y2="35.759052" />
+ <linearGradient
+ id="linearGradient10069-9-7-5-4-6-5-0-3">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop10071-5-4-58-5-9-1-2-1" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop10073-43-0-4-0-8-0-4-9" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52637-8-8">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52641-2-8);fill-opacity:1;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52639-8-9"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52641-2-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-361.27885,-161.73915)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ id="linearGradient37542-7409-7-7-0-9-9">
+ <stop
+ id="stop37544-48-6-1-4-1-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop37546-82-1-0-9-3-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient52998-5-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-307"
+ y1="475"
+ x2="-303.00003"
+ y2="463.92236" />
+ <linearGradient
+ id="linearGradient319-31-8-9-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-23-2-8-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-34-4-4-2" />
+ </linearGradient>
+ <mask
+ maskUnits="userSpaceOnUse"
+ id="mask52879-0-5">
+ <rect
+ mask="none"
+ style="fill:url(#radialGradient52883-6-8);fill-opacity:1;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52881-7-3"
+ width="7.9918551"
+ height="8.9366941"
+ x="-354.95001"
+ y="458"
+ rx="0"
+ ry="0" />
+ </mask>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-7409-7-7-0-9-9"
+ id="radialGradient52883-6-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.39420438,-0.08239205,0.27256031,1.3040635,-362.22886,-161.73912)"
+ cx="-302.79681"
+ cy="462.0358"
+ fx="-302.79681"
+ fy="462.0358"
+ r="8" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-31-8-9-1"
+ id="linearGradient53000-3-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42,0)"
+ x1="-308.7684"
+ y1="476.0105"
+ x2="-304.76843"
+ y2="464.93286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34488-1-8"
+ id="linearGradient53002-6-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-839.95,-273.25)"
+ x1="469.49295"
+ y1="-101.22778"
+ x2="470.7515"
+ y2="-102.52942" />
+ <linearGradient
+ id="linearGradient34488-1-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop34490-0-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop34492-4-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient32877-9-6-8"
+ id="linearGradient32896-0-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-217.1391"
+ y1="626.39844"
+ x2="-213.69197"
+ y2="623.21643" />
+ <linearGradient
+ id="linearGradient32877-9-6-8">
+ <stop
+ style="stop-color:#b3b3b3;stop-opacity:1;"
+ offset="0"
+ id="stop32879-8-1-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop32881-4-3-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-4-9-5"
+ id="linearGradient32899-8-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-180.37465"
+ y1="650.94128"
+ x2="-177.70576"
+ y2="653.27765" />
+ <linearGradient
+ id="linearGradient33058-4-9-5">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-3-3-9" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-9-4-7" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32901-4-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1748275,-1.7208853,0.51495275,0.35155123,-289.20197,69.961171)"
+ cx="-197.66467"
+ cy="630.61389"
+ fx="-197.66467"
+ fy="630.61389"
+ r="7.03125" />
+ <linearGradient
+ id="linearGradient44939-8-4-8-6-8">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop44941-8-5-0-0-0" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop44943-2-5-8-6-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient33058-2-7-1-7"
+ id="linearGradient32903-6-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-218.31921"
+ y1="624.84143"
+ x2="-215.31401"
+ y2="628.46533" />
+ <linearGradient
+ id="linearGradient33058-2-7-1-7">
+ <stop
+ style="stop-color:#e5250b;stop-opacity:1;"
+ offset="0"
+ id="stop33060-1-8-8-5" />
+ <stop
+ style="stop-color:#460000;stop-opacity:1;"
+ offset="1"
+ id="stop33062-4-3-4-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient44939-8-4-8-6-8"
+ id="radialGradient32905-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.62164476,0.39733376,-0.55111069,0.86222272,269.0477,166.72227)"
+ cx="-202.18748"
+ cy="627"
+ fx="-202.18748"
+ fy="627"
+ r="7.03125" />
+ <linearGradient
+ y2="-102.52942"
+ x2="470.73633"
+ y1="-101.3037"
+ x1="469.52335"
+ gradientTransform="translate(-829.95,-273.25)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient58927"
+ xlink:href="#linearGradient34488-1-8"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-71-6-9-7"
+ id="linearGradient21875-7-1-0-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4126967,0,0,2.7035619,-536.07088,379.29465)"
+ x1="236.94902"
+ y1="-14.103641"
+ x2="278.34866"
+ y2="32.902874" />
+ <linearGradient
+ id="linearGradient1610-71-6-9-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-26-8-5-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-04-8-8-0" />
+ </linearGradient>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath13106-9-2-9-9">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient13110);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path34850-4-7-0-4"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </clipPath>
+ <filter
+ inkscape:collect="always"
+ x="-0.45600089"
+ width="1.9120018"
+ y="-0.50666559"
+ height="2.0133312"
+ id="filter63011-6-7-0-8"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.899998"
+ id="feGaussianBlur63013-0-1-0-8" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-6-6-2-4"
+ id="linearGradient21877-3-2-7-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.00001,58.00194)"
+ x1="160.14388"
+ y1="376.27383"
+ x2="174.29811"
+ y2="383.69843" />
+ <linearGradient
+ id="linearGradient5060-6-6-2-4">
+ <stop
+ id="stop5062-2-0-5-5"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-4-4-5-5"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4671-6-4-1-7"
+ id="linearGradient34959-9-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1666.1765"
+ y1="639.65356"
+ x2="1659.0875"
+ y2="629.23273" />
+ <linearGradient
+ id="linearGradient4671-6-4-1-7">
+ <stop
+ id="stop4673-7-6-4-1"
+ offset="0"
+ style="stop-color:#ffd43b;stop-opacity:1;" />
+ <stop
+ id="stop4675-8-0-8-1"
+ offset="1"
+ style="stop-color:#ffe873;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4689-1-6-4-2"
+ id="linearGradient34961-3-6-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
+ x1="1641.4773"
+ y1="607.50525"
+ x2="1663.2872"
+ y2="626.40344" />
+ <linearGradient
+ id="linearGradient4689-1-6-4-2">
+ <stop
+ id="stop4691-6-2-6-7"
+ offset="0"
+ style="stop-color:#5a9fd4;stop-opacity:1;" />
+ <stop
+ id="stop4693-0-4-8-6"
+ offset="1"
+ style="stop-color:#306998;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34963-5-9-1"
+ gradientUnits="userSpaceOnUse"
+ x1="922.89703"
+ y1="339.66599"
+ x2="924.10608"
+ y2="344.10001" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-88-8-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-2-5-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34965-1-5-2"
+ gradientUnits="userSpaceOnUse"
+ x1="919.09998"
+ y1="345.42163"
+ x2="922.104"
+ y2="355.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-8-9-5-5"
+ id="linearGradient34967-4-1-8"
+ gradientUnits="userSpaceOnUse"
+ x1="922.64624"
+ y1="342.71866"
+ x2="921.82654"
+ y2="341.98108" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-4-8-9-8-9-5-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-0-8-2-9-8-5-7" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-6-2-8-0-2-8-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34969-4-4-1"
+ gradientUnits="userSpaceOnUse"
+ x1="917.75"
+ y1="355.5"
+ x2="917.25"
+ y2="353" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34971-5-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="923"
+ y1="343.75"
+ x2="923"
+ y2="344.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="radialGradient34973-2-5-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4166677,-7.678944e-6,1.853542e-6,0.58333478,-1309.0016,145.80659)"
+ cx="924"
+ cy="349.20001"
+ fx="924"
+ fy="349.20001"
+ r="6" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-4-8-9-88-8-4"
+ id="linearGradient34975-9-4-9"
+ gradientUnits="userSpaceOnUse"
+ x1="921.34045"
+ y1="341.34042"
+ x2="922.16492"
+ y2="342.16492" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-4-6-7-7"
+ id="linearGradient47921-1-7-1-1"
+ gradientUnits="userSpaceOnUse"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-4-6-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-2-4-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-3-5-0-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-2-6-4-4"
+ id="linearGradient47923-2-8-9-9"
+ gradientUnits="userSpaceOnUse"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-2-6-4-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-1-1-8-8" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-6-5-8-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ id="linearGradient47925-8-5-2-2"
+ gradientUnits="userSpaceOnUse"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-5-1-45-4">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-7-9-5-5" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-6-6-1-5" />
+ </linearGradient>
+ <linearGradient
+ y2="609.36218"
+ x2="221"
+ y1="604.31494"
+ x1="219"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient49198-1-1"
+ xlink:href="#linearGradient3966-5-1-45-4"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-1-1-9-4-7-1"
+ id="linearGradient59244-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.40161"
+ y2="29.679312" />
+ <linearGradient
+ id="linearGradient1610-1-1-9-4-7-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-74-7-2-2-2-1" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-09-4-7-5-1-5" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient40578-4-8-4-0-5-2-4-7"
+ id="radialGradient59246-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ id="linearGradient40578-4-8-4-0-5-2-4-7">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop40580-8-9-8-9-4-6-9-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop40582-6-8-8-4-3-8-9-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient58334-24-8-2-6-0-2"
+ id="linearGradient59248-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ id="linearGradient58334-24-8-2-6-0-2">
+ <stop
+ id="stop58336-55-8-3-6-3-3"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop58338-17-2-3-3-0-2"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-11-1-4-3-1"
+ id="linearGradient59250-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-11-1-4-3-1">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-5-1-5-5-6" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-27-3-6-0-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3944-1-7-5-7-7"
+ id="linearGradient59252-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="215.99414"
+ y1="592.95746"
+ x2="218.99957"
+ y2="601.36218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3944-1-7-5-7-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3946-7-4-3-6-6" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3948-1-2-5-7-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3952-5-7-6-8-9"
+ id="linearGradient59254-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="213.00005"
+ y1="597.41553"
+ x2="216.00003"
+ y2="604.375" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3952-5-7-6-8-9">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3954-2-9-1-3-2" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3956-7-3-4-6-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient59256-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="218.06126"
+ y1="601.83856"
+ x2="219.5"
+ y2="606.11218" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3966-8-9-6-4-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3968-2-8-2-4-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3970-4-6-6-1-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3966-8-9-6-4-5"
+ id="linearGradient59258-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-251,440.9872)"
+ x1="219"
+ y1="604.31494"
+ x2="221"
+ y2="609.36218" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10000"
+ objecttolerance="10000"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="147.30844"
+ inkscape:cy="114.24342"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1912"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:snap-nodes="true"
+ inkscape:snap-bbox="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:object-nodes="false"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:window-maximized="1"
+ inkscape:bbox-paths="false"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-grids="true"
+ inkscape:snap-to-guides="false"
+ inkscape:snap-page="false"
+ units="px"
+ inkscape:snap-center="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid17394"
+ visible="true"
+ enabled="true"
+ spacingx="0.25px"
+ spacingy="0.25px"
+ empspacing="4"
+ color="#808080"
+ opacity="0.09803922"
+ dotted="false"
+ empcolor="#7f7f7f"
+ empopacity="0.25098039"
+ snapvisiblegridlinesonly="true"
+ originx="0px"
+ originy="0px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Blender icons v. 2.5.06</dc:title>
+ <dc:date>21.05.2012</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>Andrzej Ambroż</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:coverage />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/" />
+ <dc:description>This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed.</dc:description>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:prohibits
+ rdf:resource="http://creativecommons.org/ns#CommercialUse" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="bckgrnd"
+ style="display:none"
+ sodipodi:insensitive="true"
+ transform="translate(-872,-180)">
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect20607"
+ width="1083.874"
+ height="650"
+ x="-4"
+ y="-4" />
+ </g>
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23417"
+ sodipodi:nodetypes="cc"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23347"
+ sodipodi:nodetypes="cc"
+ d=""
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:label="ICONS"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline"
+ transform="translate(-872,-180)">
+ <g
+ id="g10203"
+ transform="translate(-211.20006,170)" />
+ <g
+ id="g15785"
+ transform="translate(-168.02763,373.00001)" />
+ <g
+ id="g15789"
+ transform="translate(-168.02763,380.00001)" />
+ <g
+ transform="translate(-163.02763,375.00001)"
+ id="g15795" />
+ <g
+ id="g15801"
+ transform="translate(-163.02763,371.00001)" />
+ <g
+ transform="translate(-163.02763,382.00001)"
+ id="g15807" />
+ <g
+ id="g14009"
+ transform="translate(1,-0.01245054)" />
+ <g
+ id="g23738"
+ transform="matrix(0.9375966,0,0,0.937515,141.13219,-26.987026)"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ <g
+ transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)"
+ id="g23740"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ <g
+ transform="translate(-1.863085e-7,0.53333)"
+ id="g23742"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ <g
+ transform="translate(0.533324,-1.066663)"
+ id="g23744"
+ style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="g16279"
+ transform="translate(318,7.00009)" />
+ <g
+ id="g16397"
+ transform="matrix(1.045454,0,0,1.0610941,-16.32706,109.05266)"
+ style="opacity:0.45"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g16403"
+ transform="matrix(1.000037,0,0,1.0187902,152.96764,39.785579)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.9375,0,0,0.9375,192.125,77.25821)"
+ id="g16405"
+ style="display:inline">
+ <g
+ id="g16407"
+ style="fill:#000000;fill-opacity:1"
+ transform="matrix(1,0,0,1.037041,0,-6.074721)" />
+ <g
+ transform="translate(-84.26666,-72.24656)"
+ id="g16409">
+ <g
+ transform="translate(1.070738,1.59725)"
+ id="g16411">
+ <g
+ id="g16413"
+ transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)">
+ <g
+ id="g16415"
+ transform="translate(-1.863085e-7,0.53333)">
+ <g
+ id="g16417"
+ transform="translate(0.533324,-1.066663)" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g16419"
+ transform="matrix(0.903797,0,0,0.872724,-4.64464,27.13735)" />
+ <g
+ id="g16421" />
+ </g>
+ </g>
+ <g
+ id="g16425"
+ transform="matrix(1.000872,0,0,1.0462972,140.88404,50.499099)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g28330"
+ transform="translate(315.99999,18.99998)" />
+ <g
+ id="g12156"
+ transform="translate(-130.97687,-108)" />
+ <g
+ id="g12249"
+ style="opacity:0.65;display:inline"
+ transform="translate(-98,462.06404)" />
+ <g
+ style="display:inline"
+ transform="translate(-53.00012,422.06403)"
+ id="g12255" />
+ <g
+ transform="translate(-98,483.06404)"
+ style="opacity:0.65;display:inline"
+ id="g12325" />
+ <g
+ id="g12327"
+ transform="translate(-53.00012,443.06403)"
+ style="display:inline" />
+ <g
+ id="g11534"
+ transform="translate(21,-1)" />
+ <g
+ id="g31245"
+ transform="matrix(0.425032,0.424791,0.425032,-0.424791,-342.55466,249.47119)"
+ style="display:inline" />
+ <g
+ transform="translate(-157,15.000007)"
+ style="opacity:0.5"
+ id="g13244" />
+ <g
+ id="g13375"
+ style="opacity:0.3"
+ transform="translate(-177.01509,15.000007)" />
+ <g
+ id="g13383"
+ style="opacity:0.5"
+ transform="translate(-143,15.000007)" />
+ <g
+ transform="matrix(-1.0226846,0,0,1.0218469,-86.775576,130.3547)"
+ id="g17210">
+ <g
+ id="g17212"
+ transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)">
+ <g
+ id="g17214"
+ transform="translate(-1.863085e-7,0.53333)">
+ <g
+ id="g17216"
+ transform="translate(0.533324,-1.066663)" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="translate(-174.00091,22.99815)"
+ id="g15532" />
+ <g
+ transform="translate(-111.96756,-108)"
+ id="g15923">
+ <g
+ id="g15925" />
+ </g>
+ <g
+ transform="translate(189.19394,55.494451)"
+ id="g15616" />
+ <g
+ id="g17117" />
+ <g
+ id="g17121"
+ transform="translate(9,0)" />
+ <g
+ transform="translate(6,4)"
+ id="g17128" />
+ <g
+ id="g17136"
+ transform="translate(1,6)" />
+ <g
+ id="g17149"
+ transform="translate(8,7)" />
+ <rect
+ style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17123"
+ width="1"
+ height="0"
+ x="90"
+ y="523" />
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(47,-247.0151)"
+ id="g51988" />
+ <g
+ style="display:inline"
+ id="g57337"
+ transform="translate(10,254)" />
+ <g
+ id="g23613" />
+ <rect
+ style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23719"
+ width="0"
+ height="0"
+ x="547"
+ y="255" />
+ <g
+ id="g24088"
+ transform="translate(341,-57.00032)" />
+ <g
+ transform="translate(361,-56.00032)"
+ id="g24276" />
+ <g
+ id="g22051"
+ transform="translate(67,200.06499)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ style="display:inline" />
+ <g
+ id="g40816"
+ transform="translate(-23,0)">
+ <g
+ id="g40830" />
+ </g>
+ <g
+ id="g23451"
+ transform="translate(-393.99971,438.98222)" />
+ <g
+ id="g23461"
+ transform="matrix(0.8342485,0,0,0.8354168,-433.47749,469.22699)" />
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(-65,-169.00755)"
+ id="g24176" />
+ <g
+ style="fill:none;stroke:#ffffff;stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(-323.1613,214)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g28643" />
+ <g
+ id="g29500" />
+ <g
+ transform="translate(1,24.000004)"
+ id="g29613"
+ style="opacity:0.3" />
+ <g
+ style="opacity:0.3"
+ id="g29692"
+ transform="translate(0,18)" />
+ <g
+ transform="matrix(-0.767131,0,0,0.788662,369.34347,270.08667)"
+ style="fill:#000000;fill-opacity:1"
+ id="g33443"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="matrix(-0.693332,0,0,0.663699,372.90657,295.34421)"
+ id="g33445"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g33447"
+ style="opacity:0.3"
+ transform="matrix(-1,0,0,1,762.99997,233.00003)" />
+ <g
+ id="g77742"
+ style="fill:#ffeeaa;display:inline"
+ transform="translate(-870.9421,-297.02038)" />
+ <g
+ style="stroke:#ffffff;display:inline"
+ transform="matrix(-1,0,0,-1,104.1613,262.99999)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g34782">
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path34784"
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34806"
+ sodipodi:nodetypes="cz"
+ d=""
+ inkscape:connector-curvature="0" />
+ <path
+ d=""
+ sodipodi:nodetypes="cz"
+ id="path34696"
+ style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(-1,0,0,1,-155,-228)"
+ style="opacity:0.12000002"
+ id="g36040" />
+ <g
+ style="fill:#d45500;fill-opacity:1;display:inline"
+ transform="translate(250,-41.00755)"
+ id="g36511" />
+ <rect
+ style="opacity:0;fill:#fffeaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect39658"
+ width="1"
+ height="0"
+ x="-25"
+ y="67" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect39660"
+ width="0"
+ height="1"
+ x="-24"
+ y="66" />
+ <g
+ transform="translate(259,168)"
+ mask="url(#mask38561)"
+ id="g40090" />
+ <g
+ transform="translate(-810.9,-131)"
+ id="g40730"
+ style="display:inline;enable-background:new">
+ <g
+ id="g40736"
+ transform="translate(583.99999,91.500124)"
+ style="display:inline;enable-background:new" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ transform="matrix(0.5478212,-0.56064,0.5419177,0.5545983,197.19518,557.21673)"
+ id="g38570"
+ style="stroke-width:5.41920376;stroke-miterlimit:4;stroke-dasharray:none;display:inline" />
+ <g
+ id="g32752"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\v. 2.5.06\prvicons v.2.5.06.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ y="180"
+ x="872"
+ height="192"
+ width="192"
+ id="rect30285"
+ style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.39191818;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ transform="translate(856,-203)"
+ id="g21955"
+ style="opacity:0.3;display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect21957"
+ width="48"
+ height="48"
+ x="108"
+ y="430"
+ rx="2.4004419"
+ ry="0" />
+ <g
+ id="g21959">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21961"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient21977);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21963"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21965"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21967"
+ style="fill:none;stroke:url(#linearGradient21979);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21969"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21971"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21973"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21975"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g30335">
+ <g
+ id="g21367"
+ transform="translate(760,-202)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21369"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30321);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path21371"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path21373"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21375"
+ style="fill:none;stroke:url(#linearGradient30323);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21377"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path21569"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path21379"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21381"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="font-size:33.49144363px;font-style:normal;font-weight:normal;fill:#214478;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
+ d="m 891.07148,245 -0.0715,9 2.39012,0 C 896,254 896,253 896.5,251 l 0.5,0 0,7 -0.5,0 c -0.5,-2 -0.5,-3 -3.10988,-3 L 891,255 l 0,7 c 0,2.5 1,3.25 3.14146,3.39973 l -0.004,0.60029 L 885,266 l 0.004,-0.60029 C 887,265.25 888,264.5 888.00001,262 L 888,248 c 0,-2.5 -1,-3.25 -3,-3.5 l 0,-0.5 16,0 0,5 -0.5,0 c -0.50001,-1.99999 -1.5,-4 -4.5,-4 l -4.92852,0 z"
+ id="text13209"
+ sodipodi:nodetypes="ccccccccccccccccccccccc" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21625"
+ transform="translate(904,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21627"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21629">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21647);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21631"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ style="opacity:0.5;fill:#000000;display:inline"
+ id="g16261"
+ transform="matrix(1.2499985,0,0,1,-87.6203,-147.85351)">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35099"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="598.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect35101"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="600.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15690"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="602.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15692"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="604.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15694"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="606.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15696"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="608.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15698"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="610.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15700"
+ width="17.600004"
+ height="1"
+ x="167.69646"
+ y="612.85352"
+ rx="0.12125195"
+ ry="0.065390877" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
+ id="rect15732"
+ width="14.400002"
+ height="1"
+ x="167.69646"
+ y="614.85352"
+ rx="0.09920612"
+ ry="0.065390877" />
+ <g
+ transform="translate(150.89645,557.85352)"
+ id="g4849"
+ style="fill:#000000;display:inline">
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="29"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15736"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="31"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15738"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="33"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15740"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.12125195"
+ y="35"
+ x="16.799992"
+ height="1"
+ width="17.600004"
+ id="rect15742"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="0.065390877"
+ rx="0.055114571"
+ y="37"
+ x="16.799992"
+ height="1"
+ width="8.0000095"
+ id="rect15744"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </g>
+ <rect
+ ry="0.065390304"
+ rx="0.0057410933"
+ y="617.85352"
+ x="184.49646"
+ height="0.99999124"
+ width="0.83333319"
+ id="rect16334"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21633"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21635"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21649);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21637"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21639"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21641"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21643"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g35119"
+ transform="translate(2,-160.99999)"
+ style="display:inline">
+ <g
+ style="display:inline"
+ transform="translate(105.39645,589.71201)"
+ id="g16097">
+ <g
+ id="g16099"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)">
+ <radialGradient
+ id="radialGradient16101"
+ cx="20.892099"
+ cy="114.5684"
+ r="5.256"
+ fx="20.892099"
+ fy="114.5684"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16103" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16105" />
+ </radialGradient>
+ <radialGradient
+ id="radialGradient16109"
+ cx="20.892099"
+ cy="64.567902"
+ r="5.257"
+ fx="20.892099"
+ fy="64.567902"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#F0F0F0"
+ id="stop16111" />
+ <stop
+ offset="1"
+ style="stop-color:#474747"
+ id="stop16113" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ id="path16107" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#radialGradient21565);fill-rule:nonzero;stroke:none"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ id="path16117" />
+ </g>
+ <g
+ id="g16131"
+ transform="translate(105.39645,579.71201)"
+ style="display:inline">
+ <g
+ transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
+ id="g16133">
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="114.5684"
+ fx="20.892099"
+ r="5.256"
+ cy="114.5684"
+ cx="20.892099"
+ id="radialGradient16135">
+ <stop
+ id="stop16137"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16140"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="64.567902"
+ fx="20.892099"
+ r="5.257"
+ cy="64.567902"
+ cx="20.892099"
+ id="radialGradient16142">
+ <stop
+ id="stop16144"
+ style="stop-color:#F0F0F0"
+ offset="0" />
+ <stop
+ id="stop16146"
+ style="stop-color:#474747"
+ offset="1" />
+ </radialGradient>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path35139"
+ d="m 12.85355,31.53813 c 0,0.552274 -0.447803,0.99986 -1,0.99986 -0.552477,0 -1,-0.447865 -1,-0.99986 0,-0.552554 0.447803,-1.00014 1,-1.00014 0.552197,0 1,0.447866 1,1.00014 l 0,0 0,0 0,0 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35141"
+ d="m 12.60355,31.288131 c 0,0.552274 -0.447803,0.999859 -1,0.999859 -0.552477,0 -1,-0.447865 -1,-0.999859 0,-0.552556 0.447803,-1.000141 1,-1.000141 0.552197,0 1,0.447866 1,1.000141 z"
+ style="fill:url(#radialGradient21567);fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21645"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g21572"
+ transform="translate(808,-203)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21574"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21576">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21594);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21578"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21580"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21582"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21596);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21584"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21586"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21588"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21590"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21592"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g30382">
+ <g
+ id="g23655"
+ transform="translate(760,-154)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path23657"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient30368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path23659"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path23661"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path23663"
+ style="fill:none;stroke:url(#linearGradient30370);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23665"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path23667"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106)" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path23669"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23671"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 888,295 1,0 0,14 -1,0 0,-14 z"
+ id="path23675"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23677"
+ d="m 900,294 1.00002,-1 0,14 -1.00002,0 0,-13 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path23679"
+ d="m 901.00003,292 0,2.25 -13.00002,2 0,-2.25 13.00002,-2 z"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23681"
+ transform="matrix(1.1428564,0,0,1.2000001,822.71436,-355.40005)">
+ <path
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)"
+ d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23683"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ id="path23685"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ inkscape:transform-center-y="0.3813435"
+ clip-path="url(#clipPath20586)" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.38999999;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 901.00003,292 -1e-5,1 -13.00002,2 10e-6,-1 13.00002,-2 z"
+ id="path23694"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ transform="matrix(1.1428564,0,0,1.2000001,834.71436,-357.40005)"
+ id="g23717">
+ <path
+ sodipodi:type="arc"
+ style="fill:#112b00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23724"
+ sodipodi:cx="53"
+ sodipodi:cy="554"
+ sodipodi:rx="4.5"
+ sodipodi:ry="2.25"
+ d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z"
+ transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)" />
+ <path
+ clip-path="url(#clipPath20586)"
+ inkscape:transform-center-y="0.3813435"
+ transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
+ d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z"
+ sodipodi:ry="2.25"
+ sodipodi:rx="4.5"
+ sodipodi:cy="554"
+ sodipodi:cx="53"
+ id="path23726"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter20578);enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ <g
+ id="g23922"
+ transform="translate(-16,-220)"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g23924"
+ transform="translate(824,66)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect23926"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g23928">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient23978);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path23930"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path23932"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path23934"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient23980);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path23936"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path23938"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path23940"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path23942"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path23944"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccc"
+ id="path23946"
+ d="m 952,530 0,10 1,0 1,0 11,0 1,0 1,0 0,-10 -15,0 z m 1,2 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:url(#linearGradient23982);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23948"
+ width="13"
+ height="5.5"
+ x="953"
+ y="-524" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23952"
+ transform="translate(76,0)"
+ d="m 876,514 0,17 15,0 0,-17 -1,0 0,1 -1,0 0,-1 -11,0 0,1 -1,0 0,-1 -1,0 z m 1,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z m -12,3 1,0 0,1 -1,0 0,-1 z m 12,0 1,0 0,1 -1,0 0,-1 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
+ style="fill:url(#linearGradient23986);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 952,507 3,0 0,3 9,0 0,-3 3,0 0,7 -15,0 0,-7 z m 1,0 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z m 12,-4 1,0 -1,0 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,3 0,1 1,0 0,-1 -1,0 z"
+ id="path23954" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="507"
+ height="9"
+ width="3"
+ id="rect23956"
+ style="fill:url(#linearGradient23988);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23958"
+ width="9"
+ height="9"
+ x="512"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ ry="0"
+ y="955"
+ x="523"
+ height="9"
+ width="9"
+ id="rect23960"
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ transform="matrix(0,-0.5624971,0.5624971,0,893.12531,590.74965)"
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path23962"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23964"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,601.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path23966"
+ d="m 961.00001,519.00005 -3,0 0,-0.99992 0.99994,0 6e-5,-2.00008 -1,0 0,-1 1,0 0,-1 1.00006,0 0,4.00008 0.99994,0 0,0.99992 z" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,525 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z"
+ id="path23968" />
+ <rect
+ style="fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect23970"
+ width="6"
+ height="9"
+ x="534"
+ y="955"
+ ry="0"
+ transform="matrix(0,1,1,0,0,0)" />
+ <g
+ clip-path="url(#clipPath23877)"
+ id="g23972">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path23974"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0,-0.5624964,0.5624964,0,893.12545,612.74956)" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 958,536 0,1 2,0 0,-1 -2,0 z m 2,1 0,1 1,0 0,-1 -1,0 z m 0,1 -1,0 0,1 1,0 0,-1 z m 0,1 0,1 1,0 0,-1 -1,0 z m 0,1 -2,0 0,1 2,0 0,-1 z"
+ id="path23976" />
+ </g>
+ </g>
+ <g
+ transform="translate(208,88)"
+ id="g45475"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g22242"
+ transform="translate(696,-194)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect22244"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g22246">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient22274);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path22249"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path22251"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path22253"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient22276);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path22264"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path22266"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path22268"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path22270"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path22272"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g21517"
+ inkscape:label="Layer 1"
+ transform="matrix(0.5406242,0,0,0.5829534,814.13667,247.65542)">
+ <path
+ transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)"
+ d="m 43.487067,38.98439 c 0,2.928932 -6.925242,5.303301 -15.467961,5.303301 -8.542719,0 -15.467961,-2.374369 -15.467961,-5.303301 0,-2.928932 6.925242,-5.303301 15.467961,-5.303301 8.542719,0 15.467961,2.374369 15.467961,5.303301 z"
+ sodipodi:ry="5.3033009"
+ sodipodi:rx="15.467961"
+ sodipodi:cy="38.98439"
+ sodipodi:cx="28.019106"
+ id="path35486"
+ style="opacity:0.54857142;fill:url(#radialGradient21442);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssssssssscccsscccscccssccc"
+ d="m 16.048489,28.093447 c 0.0098,0.576682 0.196474,1.697902 0.471116,2.577425 0.581566,1.854137 1.56684,3.572658 2.939126,5.086496 1.407488,1.553118 3.138519,2.803227 5.139315,3.68976 2.105357,0.931573 4.384795,1.407488 6.750134,1.403741 2.365339,-0.005 4.644601,-0.488686 6.74896,-1.427017 2.00002,-0.895288 3.731043,-2.148391 5.13754,-3.705517 1.369207,-1.519844 2.352576,-3.241114 2.934089,-5.096258 0.294262,-0.938353 0.476921,-1.889392 0.553238,-2.845308 0.07331,-0.939306 0.04204,-1.883511 -0.09183,-2.823792 -0.259981,-1.835599 -0.896294,-3.556847 -1.872652,-5.12758 -0.895541,-1.441699 -2.047808,-2.70454 -3.417268,-3.766975 0,0 0.002,-0.002 0.002,-0.002 0,0 -13.828458,-10.6197195 -13.828458,-10.6197195 -0.01176,-0.00978 -0.02252,-0.019551 -0.03529,-0.028344 -0.909003,-0.6959264 -3.879837,-0.7738945 -4.87679,-0.075035 -1.01067,0.7057021 -1.091821,1.8092613 -0.195527,2.5482146 1.899775,1.4997633 2.656207,2.2801589 4.566507,3.7797379 0,0 -14.852491,0.167033 -14.852491,0.167033 -1.994685,0 -3.1682609,0.947915 -3.4153947,2.333683 -0.2180771,1.222836 0.7479213,2.738129 2.4800217,2.738129 2.956573,0.0039 5.942111,-0.0069 8.909215,-0.01272 0,0 -16.01999,12.453223 -16.01999,12.453223 -0.020527,0.01564 -0.041053,0.02933 -0.06158,0.04497 -1.4974197,1.148389 -1.9831951,3.059322 -1.0399808,4.268393 0.9598323,1.22959 2.9977653,1.230588 4.5147288,0.006 0,0 8.677593,-7.102098 8.677593,-7.102098 0,0 -0.12511,0.959824 -0.116333,1.535532 l 1e-6,2.6e-5 0,0 0,0 z"
+ id="path2482"
+ style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)"
+ d="m 42.75,25.75 c 0,5.591883 -5.176708,10.125 -11.5625,10.125 -6.385792,0 -11.5625,-4.533117 -11.5625,-10.125 0,-5.591883 5.176708,-10.125 11.5625,-10.125 6.385792,0 11.5625,4.533117 11.5625,10.125 z"
+ sodipodi:ry="10.125"
+ sodipodi:rx="11.5625"
+ sodipodi:cy="25.75"
+ sodipodi:cx="31.1875"
+ id="path39153"
+ style="fill:url(#linearGradient21444);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.4857143;fill:none;stroke:url(#linearGradient21446);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
+ d="m 25.8125,6.40625 c -0.334829,4.572e-4 -0.72202,0.089606 -0.90625,0.21875 4.5e-4,0.010412 4.5e-4,0.020838 0,0.03125 -0.212626,0.1484635 -0.188235,0.1956271 -0.1875,0.1875 0.0092,0.010621 -0.0072,-4.246e-4 0.03125,0.03125 0.01962,0.00828 0.03527,0.012546 0.0625,0.03125 0.01676,0.01151 0.01357,0.014555 0.03125,0.03125 0.193748,0.1576058 4.954976,4.005164 4.954976,4.005164 0.489837,0.39864 0.677395,1.066352 0.46875,1.65625 -0.115662,0.32703 -0.422813,0.541217 -0.6875,0.59375 -0.264687,0.05253 -0.498447,0.03054 -0.71875,0.03125 -5.639658,0.05119 -16.87989,0.03851 -16.87989,0.03851 -0.4102,2.75e-4 -0.935835,0.115997 -1.34375,0.34375 -0.407915,0.227753 -0.6637862,0.523861 -0.6875002,0.90625 -0.024417,0.393728 0.098829,0.605767 0.3437502,0.78125 0.244921,0.175483 0.614978,0.25 0.875,0.25 0,0 8.8125,0 8.8125,0 0.600305,-7.28e-4 1.223895,0.311058 1.4375,0.9375 0.04676,0.137121 0.06335,0.269976 0.0625,0.40625 -8.49e-4,0.136274 -0.02214,0.268794 -0.09375,0.375 -0.143211,0.212412 -0.319507,0.298568 -0.5,0.4375 0,0 -15.7871819,12.746851 -15.856336,12.800078 C 5.0310984,30.500117 5,30.53125 5,30.53125 5.0100745,30.519077 5.000335,30.499512 5,30.5 L 4.8125,30.3125 c 0.012336,0.02165 0.014481,0.03307 0.03125,0.0625 0.063558,0.0774 0.125,0.15625 0.125,0.15625 -0.00585,0.0056 -0.031233,0.03124 -0.03125,0.03125 0,0 -0.043442,-0.09921 -0.09375,-0.1875 0.037843,0.09884 0.06253,0.218739 0.0625,0.21875 -0.4662091,0.37119 -0.7783348,0.889746 -0.875,1.28125 -0.1043319,0.422581 -0.046,0.62455 0.125,0.84375 0.2999827,0.384295 1.3975356,0.595547 2.40625,-0.21875 0,0 8.65625,-7.09375 8.65625,-7.09375 0.473718,-0.387074 1.1446,-0.458625 1.6875,-0.15625 0.544608,0.303331 0.798054,0.927572 0.71875,1.53125 0,0 -0.0626,0.908319 -0.0625,1.25 2e-6,0.0085 -1.19e-4,0.02348 0,0.03125 0.192796,2.523718 1.400736,4.762818 3.03125,6.71875 2.801818,3.089095 6.627659,4.401619 10.75,4.5625 4.113324,-0.043 7.964529,-1.606111 10.75,-4.625 2.546631,-3.125326 3.513872,-6.363859 3.15625,-9.375 C 44.891575,22.325847 43.222923,19.516566 40.4375,17.25 35.951885,13.599946 31.206991,10.168434 26.59375,6.625 26.57515,6.610386 26.56455,6.59802 26.5625,6.59375 26.43835,6.498703 26.144223,6.4057899 25.8125,6.40625 z"
+ id="path21414"
+ sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 25.708956,26.064593 c 0.07649,-1.397943 0.759369,-2.631914 1.78592,-3.505519 1.010226,-0.858782 2.366788,-1.383145 3.848625,-1.383145 1.480894,0 2.837456,0.524363 3.847446,1.383145 1.027685,0.873605 1.709741,2.106651 1.787122,3.504594 0.07927,1.438713 -0.49591,2.77459 -1.504012,3.764001 -1.027686,1.007933 -2.493008,1.640678 -4.130556,1.640678 -1.63849,0 -3.103814,-0.632745 -4.131451,-1.640678 -1.00914,-0.989411 -1.58234,-2.325288 -1.503094,-3.763076 l 0,0 0,0 0,0 z"
+ id="path2478"
+ style="fill:#3465a4;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
+ id="path39166"
+ d="m 25.8125,6.03125 c -0.404852,5.53e-4 -2.204797,-0.059029 -2.48145,0.1349032 -0.280209,0.195652 -0.335403,0.376484 -0.34375,0.46875 -0.0083,0.092266 -0.01539,0.17648 0.1875,0.34375 0.01899,0.015735 0.04457,0.014317 0.0625,0.03125 0.124258,0.101028 4.748869,4.1248618 4.748869,4.1248618 0.373658,0.304091 0.504393,0.795817 0.34375,1.25 -0.160635,0.454191 -0.580748,0.373449 -1.0625,0.375 -5.634142,0.05114 -15.087371,-0.129601 -15.087371,-0.129601 -0.952967,6.38e-4 -2.339958,0.524782 -2.4062504,1.59375 -0.063562,1.024947 0.9247974,1.4375 1.5937504,1.4375 0,-1e-6 8.8125,0 8.8125,0 0.488364,-5.92e-4 0.936141,0.225277 1.09375,0.6875 0.157609,0.462231 -0.01926,0.514621 -0.40625,0.8125 0,0 -16.086298,13.088586 -16.086298,13.088586 -0.00142,0.0014 -0.029829,-0.0014 -0.03125,0 -0.064037,0.04879 -0.054226,0.04875 -0.03125,0.03125 -0.5536758,0.424619 -0.9087886,1.004019 -1.03125,1.5 -0.1224536,0.495981 -0.04661,0.856152 0.1875,1.15625 0.4788333,0.613413 1.777612,0.754857 2.90625,-0.15625 1e-7,10e-7 8.65625,-7.09375 8.65625,-7.09375 0.361955,-0.295753 0.872897,-0.352437 1.28125,-0.125 0.408345,0.227436 0.623381,0.692814 0.5625,1.15625 0,-1e-6 -0.0997,0.953636 -0.09375,1.34375 0.09498,1.301756 0.451616,2.521825 0.989039,3.664234 C 20.799917,36.321089 27.770982,19.392853 44.1875,21.03125 43.339652,19.54368 42.151282,18.185293 40.65625,16.96875 36.159865,13.309932 31.42016,9.882897 26.8125,6.34375 26.805335,6.338858 26.788292,6.317553 26.78125,6.3125 26.570707,6.151312 26.216591,6.030689 25.8125,6.03125 z"
+ style="opacity:0.51999996;fill:url(#radialGradient21448);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ </g>
+ </g>
+ <g
+ style="opacity:0.5"
+ id="g24847"
+ transform="translate(162,248)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24867);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24849"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24851"
+ style="opacity:0.07999998;fill:url(#linearGradient24869);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24853"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24871);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24855"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,4.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24857" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24859"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24861" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24863"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24873);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24865"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.5"
+ transform="translate(114,248)"
+ id="g24784">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z"
+ id="path24789"
+ style="fill:url(#linearGradient24809);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ style="opacity:0.07999998;fill:url(#linearGradient24811);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24791" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient24813);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-18.5 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,19.5 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ id="path24793"
+ sodipodi:nodetypes="csccsczc"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-ydpi="74.800003" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccssccc"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path24796"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24799"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 840.5,89 0,4.5"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ d="m 848.5,95.5 0,18 c 0,1.25 0.25,3 -1.25,4"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24801" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24803"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-18 34,0 m -29,-8 c 0,0.5 0.5286,1 1,1 l 20,0"
+ sodipodi:nodetypes="cccccccsc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsscccssssccc"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24805"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-18 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-6 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscc"
+ id="path24807"
+ d="m 841.5,94.5 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,18 c 0,2.25 -1.25,3 -2.5,3"
+ style="fill:none;stroke:url(#linearGradient24815);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ <g
+ transform="translate(0,-2)"
+ style="opacity:0.4;stroke:#3d361a;filter:url(#filter44473)"
+ id="g44424">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44406"
+ d="m 950.25,362 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44408"
+ d="M 948.25,354.25 944,350.00563 939.75,354.25"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new" />
+ </g>
+ <g
+ transform="translate(617,273)"
+ id="g44334"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect44336"
+ width="16"
+ height="16"
+ x="320"
+ y="73" />
+ <g
+ transform="translate(0,-21)"
+ id="g44338">
+ <g
+ id="g44340">
+ <g
+ transform="translate(0,21)"
+ id="g44342">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path44344"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44346"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ transform="translate(0,21)"
+ id="g44348">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 333.25,87 -5.25,0 -1,-1 0,-10"
+ id="path44350"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M 331.25,79.25 327,75.005631 322.75,79.25"
+ id="path44352"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 328.5,107.5 5,0 m -7,-9 0,8.5 m -4.25,-7 4.5,-4.5"
+ id="path44354"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ </g>
+ <g
+ transform="translate(66,248)"
+ id="g24818"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccssssccc"
+ style="fill:url(#linearGradient24839);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path24821"
+ d="m 806.5,114.5 c 0,2.25 2,4 4,4 l 30,0 c 0.4163,0 1,-0.5 1,-1 l 0,-29 c 0,-0.5 -0.5,-1 -1,-1 l -21.02773,0.04419 C 818.98721,87.545209 818.5,87 818.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -10,0 c -0.5,0 -1,0.5 -1,1 l 0,31 z" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24823"
+ style="opacity:0.07999998;fill:url(#linearGradient24841);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 807.5,89.5 33,0 m -33,12 33,0 m -33,-4 33,0 m -33,-6 33,0 m -33,20 33,0 m -33,2 33,0 m -33,-18 33,0 m -33,-2 33,0 m -20,-6 -13,0 m 0,20 33,0 m -33,-2 33,0 m -33,-2 33,0 m -33,-4 33,0 m -33,10 33,0 m -33,6 33,0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="74.800003"
+ inkscape:export-xdpi="74.800003"
+ inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
+ sodipodi:nodetypes="csccsczc"
+ id="path24825"
+ d="m 844,118.5 c 3.5,0 5.5,-2 5.5,-5.5 l 0,-16 c -11.75604,-1.11e-4 -23.91623,0 -35.5,0 l 0,17 c 0,4.5 -7,4 -7,0.25 0,2 2.00002,3.73529 3,3.75 l 34,0.5 z"
+ style="fill:url(#linearGradient24843);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 807,87 12,0 0.0385,-3.33333 C 819.04423,83.166705 818.97512,83 818.5,83 l -10.92308,0 c -0.47512,0 -0.53846,0.16667 -0.53846,0.66667 L 807,87 z"
+ id="path24827"
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:nodetypes="ccssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 840.5,89 0,7.5"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path24829" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24831"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m 848.5,98.75 0,14.75 c 0,1.25 0.25,3 -1.25,4"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccsc"
+ d="m 818.5,83.5 -11,0 0,30 c 0,5 7,5 7,0 l 0,-16 34,0 m -29,-10 c 0,0.5 0.5286,1 1,1 l 20,0"
+ style="opacity:0.75;fill:none;stroke:#ffffff;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path24833" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 806.5,113.5 c 0,2.75 2,5 5,5 l 33,0 c 3,0 5,-2 5,-5 l 0,-16 c 0,-0.471405 -0.5286,-1 -1,-1 l -7,0 0,-8 c 0,-0.5 -0.5,-1 -1,-1 l -20.02773,0.04419 C 819.98721,87.54526 819.5,87 819.5,86.5 l 0,-3 c 0,-0.5 -0.5,-1 -1,-1 l -11,0 c -0.5,0 -1,0.5 -1,1 l 0,30 z"
+ id="path24835"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccsscccssssccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient24845);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 841.5,96.500004 -27,0 c -0.4714,0 -1,0.528595 -1,1 l 0,15.999996 c 0,2.25 -1.25,3 -2.5,3"
+ id="path24837"
+ sodipodi:nodetypes="csscc" />
+ </g>
+ <g
+ style="opacity:0.4;filter:url(#filter44477)"
+ id="g44455">
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44446"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="translate(645,252.05)"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44449"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="cs"
+ id="path44451"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-1,0,0,-1,1343,456.05)"
+ sodipodi:nodetypes="ccc"
+ id="path44453"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#3d361a;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ transform="translate(645,273.05)"
+ id="g44356"
+ style="display:inline;enable-background:new">
+ <rect
+ y="73"
+ x="341"
+ height="16"
+ width="16"
+ id="rect44358"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0,-21)"
+ id="g44360">
+ <g
+ id="g44362">
+ <g
+ id="g44364">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44366"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44368"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g44370">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44372"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44374"
+ sodipodi:nodetypes="cs" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path44376"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g44378"
+ transform="matrix(-1,0,0,-1,698,204)">
+ <g
+ id="g44380">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ id="path44382"
+ sodipodi:nodetypes="cs" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ id="path44384"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="g44386">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path44388"
+ d="m 343,108.25 0,-4.25 4.25,0"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cs"
+ id="path44390"
+ d="m 343.5,104.5 1.75,1.75 c 2.3454,2.33848 6.16153,2.34539 8.5,0 l 0.5,-0.5"
+ style="fill:none;stroke:#e6e6e6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344,105 0,1 0,1.5 1,0 0,-1.5 1.5,0 0,-1 -1.5,0 -1,0 z"
+ id="path44392" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44402);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 344.90625,106.59375 c 2.52573,2.51828 6.66805,2.52691 9.1875,0 l 0.5,-0.5"
+ id="path44394"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 350.5,99.5 4,0 0,-4"
+ id="path44396"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 347.5,103.5 -4.5,0 c -0.25,0 -0.5,0.25 -0.5,0.5 l 0,4.5"
+ id="path44398"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient44404);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 345.59375,105.90625 c 2.07803,2.0719 5.36384,2.10325 7.53125,0.1875 L 354,105.25"
+ id="path44400"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ </g>
+ <g
+ id="g34977"
+ style="display:inline;enable-background:new">
+ <g
+ style="display:inline"
+ id="g21853-3"
+ transform="translate(856,-154)"
+ inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 2\IMAGE BROWSER ICONS.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="430"
+ x="108"
+ height="48"
+ width="48"
+ id="rect21855-8"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g21857-6">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient21875-7-1-0-1);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 125.5,433.5 23,0 0,41 -33,0 0,-31 10,-10 z"
+ id="path21859-9"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 147.25,434.5 c -4.875,0 -21.75,0 -21.75,0 m -8.9447,8.5 -0.0553,30"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path21861-8"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21863-6"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="none"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m 117.5,443.75 9,-2.5 0,-6"
+ style="fill:none;stroke:url(#linearGradient21877-3-2-7-2);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path21865-6"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path21867-2"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 115.5,442.75 0,31.75 33,0 0,-41 -23.75,0 -9.25,9.25 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ clip-path="url(#clipPath13106-9-2-9-9)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path21869-3"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-6-7-0-8)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 116,443 0.0108,0.72434 L 126,441 l 0,-7 -1,0 -9,9 z"
+ id="path21871-8"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path21873-2"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 147.5,435 0,38.5 -30.5,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g34938"
+ transform="translate(63,-47)">
+ <path
+ id="path61236"
+ style="color:#000000;fill:url(#linearGradient34959-9-2-1);fill-opacity:1;fill-rule:nonzero;stroke:#ff0000;stroke-width:0.17893334;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 919.5,356.5067 0,-3 c 0,-1.73575 1.26424,-3 3,-3 l 5,0 c 1.73576,0 3,-1.26425 3,-3 l 0,-3.0064 2.5,0.006 c 2,0 3.5,2.5 3.5,6 0,3.5 -1.25,6 -3.5,6 -4.98134,0 -12.77318,0 -2.5,0 l 0,2.75 c 0,2.5 -2,3.24997 -5.5,3.24998 l 0,2e-5 c -3.5,0.0104 -5.5,-0.75 -5.5,-3.25 l 0,-2.7628"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssccsscsccsc" />
+ <path
+ sodipodi:nodetypes="cssssccsscsccsc"
+ inkscape:connector-curvature="0"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3.0064 -2.5,-0.006 c -2,0 -3.5,-2.5 -3.5,-6 0,-3.5 1.25,-6 3.5,-6 4.98134,0 12.77318,0 2.5,0 l 0,-2.75 c 0,-2.5 2,-3.24997 5.5,-3.24998 l 0,-2e-5 c 3.5,-0.0104 5.5,0.75 5.5,3.25 l 0,2.7628"
+ style="color:#000000;fill:url(#linearGradient34961-3-6-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.17893334;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61233" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccscccsccccsccccc"
+ id="path61167"
+ d="m 925,338.50002 c -3.5,10e-6 -5.5,0.74998 -5.5,3.24998 l 0,2.75 5.5,0 -8,0 c -2.25,0 -3.5,2.5 -3.5,6 0,3.5 1.5,6 3.5,6 l 2.5,0.0128 0,2.9872 c 0,2 2,3.01281 5.5,3.0128 3.5,-1e-5 5.5,-1.0128 5.5,-3.0128 l 0,-3 -5.5,0 8,0 c 2,0 3.5,-2.5 3.5,-6 0,-3.5 -1.5,-6 -3.5,-6 l -2.5,0.0128 0,-2.7628 c 0,-2.5 -2,-3.26045 -5.5,-3.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path61169"
+ d="m 930.5,344.5 0,3 c 0,1.73575 -1.26424,3 -3,3 l -5,0 c -1.73576,0 -3,1.26425 -3,3 l 0,3"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.78431373;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ d="m 923,342 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path61220"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ d="m 929,359 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="359"
+ sodipodi:cx="928"
+ id="path61222"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <g
+ style="opacity:0.4"
+ id="g61345">
+ <path
+ style="fill:none;stroke:url(#linearGradient34963-5-9-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ id="path61333"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cszsc" />
+ <path
+ style="fill:none;stroke:url(#linearGradient34965-1-5-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5 0,3 1.28917,5 2.5,5 l 1.5,0"
+ id="path61335"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccszsc" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ id="path61337"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 918.5,355.25 0,-1.75 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ id="path61339"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssc" />
+ <path
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)"
+ sodipodi:type="arc"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34967-4-1-8);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path61355"
+ sodipodi:cx="922"
+ sodipodi:cy="342"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 923,342 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z" />
+ </g>
+ <g
+ style="opacity:0.8;stroke:#ff0000"
+ transform="matrix(-1,0,0,-1,1850,701)"
+ id="g34104">
+ <path
+ sodipodi:nodetypes="cszsc"
+ inkscape:connector-curvature="0"
+ id="path34106"
+ d="m 920.5,343.25 0,-1.5 c 0,-1.75 1.5,-2.25 4.5,-2.25 3,0 4.5,0.5 4.5,2.25 l 0,4.75"
+ style="fill:none;stroke:none" />
+ <path
+ sodipodi:nodetypes="csc"
+ inkscape:connector-curvature="0"
+ id="path34108"
+ d="m 914.5,350.5 c 0,3 1.28917,5 2.5,5 l 1.5,0"
+ style="fill:none;stroke:url(#linearGradient34969-4-4-1);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path34110"
+ d="m 920.75,343.5 4.5,0 0.25,0.25 0,0.5"
+ style="fill:none;stroke:url(#linearGradient34971-5-0-9);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ sodipodi:nodetypes="cssssc"
+ inkscape:connector-curvature="0"
+ id="path34113"
+ d="m 918.5,355.5 0,-2 c 0,-2.25 1.75,-4 4,-4 l 4.5,0 c 1.75,0 2.5,-0.75 2.5,-2.5 l 0,-0.5"
+ style="fill:none;stroke:url(#radialGradient34973-2-5-7);stroke-linecap:round;stroke-linejoin:round" />
+ <path
+ d="m 923,342 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
+ sodipodi:ry="1"
+ sodipodi:rx="1"
+ sodipodi:cy="342"
+ sodipodi:cx="922"
+ id="path34115"
+ style="color:#000000;fill:none;stroke:url(#linearGradient34975-9-4-9);stroke-width:0.52766895;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc"
+ transform="matrix(1.5161021,0,0,1.5161021,-475.84616,-176.50693)" />
+ <path
+ style="fill:none;stroke:none"
+ d="m 925.5,345 0,0.25 -0.25,0.25 -8.25,0 c -1.5,0 -2.5,2 -2.5,5"
+ id="path34901"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccsc" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g46790"
+ transform="translate(0,12)" />
+ <g
+ id="g46890" />
+ <path
+ inkscape:connector-curvature="0"
+ d=""
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path34332"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
diff --git a/release/datafiles/splash_template.xcf b/release/datafiles/splash_template.xcf
new file mode 100644
index 0000000..6d7e7d4
Binary files /dev/null and b/release/datafiles/splash_template.xcf differ
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index aa7a679..599bfb5 100644
Binary files a/release/datafiles/startup.blend and b/release/datafiles/startup.blend differ
diff --git a/release/scripts/addons/add_curve_extra_objects/__init__.py b/release/scripts/addons/add_curve_extra_objects/__init__.py
index 2d1e82e..95c358f 100644
--- a/release/scripts/addons/add_curve_extra_objects/__init__.py
+++ b/release/scripts/addons/add_curve_extra_objects/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Extra Objects",
"author": "Multiple Authors",
"version": (0, 1),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "View3D > Add > Curve > Extra Objects",
"description": "Add extra curve object types",
"warning": "",
diff --git a/release/scripts/addons/add_curve_extra_objects/add_curve_aceous_galore.py b/release/scripts/addons/add_curve_extra_objects/add_curve_aceous_galore.py
index 185b012..85063de 100644
--- a/release/scripts/addons/add_curve_extra_objects/add_curve_aceous_galore.py
+++ b/release/scripts/addons/add_curve_extra_objects/add_curve_aceous_galore.py
@@ -20,7 +20,7 @@ bl_info = {
'name': 'Curveaceous Galore!',
'author': 'Jimmy Hazevoet, testscreenings',
'version': (0,2),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
'location': 'View3D > Add > Curve',
'description': 'Adds many different types of Curves',
'warning': '', # used for warning icon and text in addons panel
diff --git a/release/scripts/addons/add_curve_extra_objects/add_curve_torus_knots.py b/release/scripts/addons/add_curve_extra_objects/add_curve_torus_knots.py
index ca89e9c..cb974e1 100644
--- a/release/scripts/addons/add_curve_extra_objects/add_curve_torus_knots.py
+++ b/release/scripts/addons/add_curve_extra_objects/add_curve_torus_knots.py
@@ -21,7 +21,7 @@ bl_info = {
"name": "Torus Knots",
"author": "testscreenings",
"version": (0,1),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "View3D > Add > Curve",
"description": "Adds many types of (torus) knots",
"warning": "",
diff --git a/release/scripts/addons/add_curve_ivygen.py b/release/scripts/addons/add_curve_ivygen.py
index ab38d25..aade98a 100644
--- a/release/scripts/addons/add_curve_ivygen.py
+++ b/release/scripts/addons/add_curve_ivygen.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "IvyGen",
"author": "testscreenings, PKHG, TrumanBlending",
"version": (0, 1, 1),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "View3D > Add > Curve",
"description": "Adds generated ivy to a mesh object starting at the 3D"\
" cursor",
diff --git a/release/scripts/addons/add_curve_sapling/__init__.py b/release/scripts/addons/add_curve_sapling/__init__.py
index 2440516..9264e90 100644
--- a/release/scripts/addons/add_curve_sapling/__init__.py
+++ b/release/scripts/addons/add_curve_sapling/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Sapling",
"author": "Andrew Hale (TrumanBlending)",
"version": (0, 2, 6),
- "blender": (2, 6, 4),
+ "blender": (2, 64, 0),
"location": "View3D > Add > Curve",
"description": ("Adds a parametric tree. The method is presented by "
"Jason Weber & Joseph Penn in their paper 'Creation and Rendering of "
diff --git a/release/scripts/addons/add_mesh_BoltFactory/__init__.py b/release/scripts/addons/add_mesh_BoltFactory/__init__.py
index a3c580d..7488856 100644
--- a/release/scripts/addons/add_mesh_BoltFactory/__init__.py
+++ b/release/scripts/addons/add_mesh_BoltFactory/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "BoltFactory",
"author": "Aaron Keith",
"version": (3, 9),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "View3D > Add > Mesh",
"description": "Add a bolt or nut",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
diff --git a/release/scripts/addons/add_mesh_ant_landscape.py b/release/scripts/addons/add_mesh_ant_landscape.py
index 52c2856..be6393c 100644
--- a/release/scripts/addons/add_mesh_ant_landscape.py
+++ b/release/scripts/addons/add_mesh_ant_landscape.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "ANT Landscape",
"author": "Jimmy Hazevoet",
"version": (0,1,2),
- "blender": (2, 6, 1),
+ "blender": (2, 61, 0),
"location": "View3D > Add > Mesh",
"description": "Add a landscape primitive",
"warning": "", # used for warning icon and text in addons panel
diff --git a/release/scripts/addons/add_mesh_extra_objects/__init__.py b/release/scripts/addons/add_mesh_extra_objects/__init__.py
index 6e64e2b..a8c71ae 100644
--- a/release/scripts/addons/add_mesh_extra_objects/__init__.py
+++ b/release/scripts/addons/add_mesh_extra_objects/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Extra Objects",
"author": "Multiple Authors",
"version": (0, 3),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "View3D > Add > Mesh > Extra Objects",
"description": "Add extra object types",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py
index bd3ddfc..2fa128a 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_3d_function_surface.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "3D Function Surfaces",
"author": "Buerbaum Martin (Pontiac), Elod Csirmaz",
"version": (0, 3, 8),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Add > Mesh",
"description": "Create Objects using Math Formulas",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py
index 504fdcf..5cc5405 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_gears.py
@@ -23,7 +23,7 @@ bl_info = {
"name": "Gears",
"author": "Michel J. Anders (varkenvarken)",
"version": (2, 4, 2),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Add > Mesh > Gears ",
"description": "Adds a mesh Gear to the Add Mesh menu",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py
index 075d826..7d3db78 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_gemstones.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Gemstones",
"author": "Pontiac, Fourmadmen, Dreampainter",
"version": (0, 4),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Add > Mesh > Gemstones",
"description": "Adds various gemstone (Diamond & Gem) meshes.",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py
index b39cb42..e810e0d 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_honeycomb.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "HoneyComb",
"author": "Kayo Phoenix <kayo at illumium.org>",
"version": (0, 1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"api": 35853,
"location": "View3D > Add > Mesh > HoneyComb",
"description": "Adds HoneyComb Mesh",
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py
index 7b4ac56..3454618 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_polysphere.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Add PolySphere",
"author": "Andy Davies (metalliandy)",
"version": (0,1,6),
- "blender": (2, 6, 2),
+ "blender": (2, 62, 0),
"location": "View3D > Add > Mesh > PolySphere",
"description": "Adds a PolySphere (all quads) for sculpting",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py
index 7c9ee6c..9cca761 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_pyramid.py
@@ -23,7 +23,7 @@ bl_info = {
'name': 'Mesh Pyramid',
'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
'version': (0, 5),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
'location': 'View3D > Add > Mesh',
'description': 'Create an egyption-style step pyramid',
'warning': '', # used for warning icon and text in addons panel
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py
index 0be6a89..425d2bd 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_supertoroid.py
@@ -1,14 +1,14 @@
'''
-bl_addon_info = {
- 'name': 'Add Mesh: SuperToroid',
- 'author': 'DreamPainter',
- 'version': '1',
- 'blender': (2, 5, 3),
- 'location': 'View3D > Add > Mesh > SuperToroid',
- 'description': 'Add a SuperToroid mesh',
- 'url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
- 'Scripts/Add_Mesh/', # no url
- 'category': 'Add Mesh'}
+bl_info = {
+ "name": "Add Mesh: SuperToroid",
+ "author": "DreamPainter",
+ "version": (1, 0, 0),
+ "blender": (2, 53, 0),
+ "location": "View3D > Add > Mesh > SuperToroid",
+ "description": "Add a SuperToroid mesh",
+ "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" \
+ "Scripts/Add_Mesh/", # no url
+ "category": "Add Mesh"}
'''
import bpy
from bpy.props import FloatProperty,BoolProperty,IntProperty
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py
index 93030aa..2771dd7 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_teapot.py
@@ -26,13 +26,13 @@
# ***** END GPL LICENCE BLOCK *****
bl_info = {
- "name": "Teapot+",
- "author": "Anthony D'Agostino",
- "version": (1, 0),
- "blender": (2, 5, 7),
- "location": "View3D > Add > Mesh ",
- "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_Teapot",
- "category": "Add Mesh"}
+ "name": "Teapot+",
+ "author": "Anthony D'Agostino",
+ "version": (1, 0),
+ "blender": (2, 57, 0),
+ "location": "View3D > Add > Mesh ",
+ "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_Teapot",
+ "category": "Add Mesh"}
'''
import bpy, mathutils, io, operator, functools
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py
index 2ce4b2a..f69d12c 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_torusknot.py
@@ -26,14 +26,14 @@
# ***** END GPL LICENCE BLOCK *****
bl_info = {
- "name": "Torus Knot",
- "author": "Anthony D'Agostino",
- "version": (1, 0),
- "blender": (2, 5, 7),
- "location": "View3D > Add > Mesh ",
- "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_TorusKnot",
- "category": "Add Mesh"}
-'''
+ "name": "Torus Knot",
+ "author": "Anthony D'Agostino",
+ "version": (1, 0),
+ "blender": (2, 57, 0),
+ "location": "View3D > Add > Mesh ",
+ "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_TorusKnot",
+ "category": "Add Mesh"}
+'''
import bpy, mathutils, math
def create_mesh_object(context, verts, edges, faces, name):
diff --git a/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py b/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py
index f2e5e84..4ebf7e3 100644
--- a/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py
+++ b/release/scripts/addons/add_mesh_extra_objects/add_mesh_twisted_torus.py
@@ -24,7 +24,7 @@ bl_info = {
"name": "Twisted Torus",
"author": "Paulo_Gomes",
"version": (0, 11, 1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Add > Mesh ",
"description": "Adds a mesh Twisted Torus to the Add Mesh menu",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_pipe_joint.py b/release/scripts/addons/add_mesh_pipe_joint.py
index aa41532..9d1fcc0 100644
--- a/release/scripts/addons/add_mesh_pipe_joint.py
+++ b/release/scripts/addons/add_mesh_pipe_joint.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Pipe Joints",
"author": "Buerbaum Martin (Pontiac)",
"version": (0, 10, 7),
- "blender": (2, 6, 1),
+ "blender": (2, 61, 0),
"location": "View3D > Add > Mesh > Pipe Joints",
"description": "Add different types of pipe joints",
"warning": "",
diff --git a/release/scripts/addons/add_mesh_solid.py b/release/scripts/addons/add_mesh_solid.py
index 3eba5e6..cb874fe 100644
--- a/release/scripts/addons/add_mesh_solid.py
+++ b/release/scripts/addons/add_mesh_solid.py
@@ -21,7 +21,7 @@ bl_info = {
"name": "Regular Solids",
"author": "DreamPainter",
"version": (2, 0),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "View3D > Add > Mesh > Solids",
"description": "Add a regular solid",
"warning": "",
diff --git a/release/scripts/addons/animation_add_corrective_shape_key.py b/release/scripts/addons/animation_add_corrective_shape_key.py
index 230959e..a576d35 100644
--- a/release/scripts/addons/animation_add_corrective_shape_key.py
+++ b/release/scripts/addons/animation_add_corrective_shape_key.py
@@ -22,7 +22,7 @@ bl_info = {
'name': 'Corrective shape keys',
'author': 'Ivo Grigull (loolarge), Tal Trachtman',
'version': (1, 0),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
'location': 'Object Data > Shape Keys (Search: corrective) ',
'description': 'Creates a corrective shape key for the current pose',
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
diff --git a/release/scripts/addons/animation_animall.py b/release/scripts/addons/animation_animall.py
index c20f64b..c331f52 100644
--- a/release/scripts/addons/animation_animall.py
+++ b/release/scripts/addons/animation_animall.py
@@ -20,7 +20,7 @@ bl_info = {
'name': 'AnimAll',
'author': 'Daniel Salazar <zanqdo at gmail.com>',
'version': (0, 5),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
'location': 'Select a Mesh/Lattice/Curve: Tool Shelf > AnimAll panel',
'description': 'Allows animation of mesh, lattice and curve data (Shape Keys, VCols, VGroups, UVs, Points, Radius, Tilt)',
'warning': '',
diff --git a/release/scripts/addons/compositing_film_response/__init__.py b/release/scripts/addons/compositing_film_response/__init__.py
index b480c4b..82165d5 100644
--- a/release/scripts/addons/compositing_film_response/__init__.py
+++ b/release/scripts/addons/compositing_film_response/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Film Response Curves",
"author": "Brecht Van Lommel",
"version": (0, 1),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "Node Editor > Panels > Film Response",
"description": "Apply film response preset to RGB Curves node",
"warning": "",
diff --git a/release/scripts/addons/curve_simplify.py b/release/scripts/addons/curve_simplify.py
index b624a12..2c95ec1 100644
--- a/release/scripts/addons/curve_simplify.py
+++ b/release/scripts/addons/curve_simplify.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Simplify curves",
"author": "testscreenings",
"version": (1,),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "Search > Simplify Curves",
"description": "Simplifies 3D curves and fcurves",
"warning": "",
diff --git a/release/scripts/addons/development_api_navigator.py b/release/scripts/addons/development_api_navigator.py
index 5fc8573..2f12172 100644
--- a/release/scripts/addons/development_api_navigator.py
+++ b/release/scripts/addons/development_api_navigator.py
@@ -23,7 +23,7 @@ bl_info = {
"name": "API Navigator",
"author": "Dany Lebel (Axon_D)",
"version": (1, 0, 2),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "Text Editor > Properties > API Navigator Panel",
"description": "Allows exploration of the python api via the user interface",
"warning": "",
diff --git a/release/scripts/addons/development_icon_get.py b/release/scripts/addons/development_icon_get.py
index 1003218..b786dea 100644
--- a/release/scripts/addons/development_icon_get.py
+++ b/release/scripts/addons/development_icon_get.py
@@ -23,7 +23,7 @@ bl_info = {
'name': 'Icons',
'author': 'Crouch, N.tox, PKHG, Campbell Barton, Dany Lebel',
'version': (1, 5, 1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
'location': 'Text Editor > Properties or '\
'Console > Console Menu',
'warning': '',
diff --git a/release/scripts/addons/game_engine_save_as_runtime.py b/release/scripts/addons/game_engine_save_as_runtime.py
index 16b716a..e07efe3 100644
--- a/release/scripts/addons/game_engine_save_as_runtime.py
+++ b/release/scripts/addons/game_engine_save_as_runtime.py
@@ -20,7 +20,7 @@ bl_info = {
'name': 'Save As Game Engine Runtime',
'author': 'Mitchell Stokes (Moguri)',
'version': (0, 3, 1),
- "blender": (2, 6, 1),
+ "blender": (2, 61, 0),
'location': 'File > Export',
'description': 'Bundle a .blend file with the Blenderplayer',
'warning': '',
diff --git a/release/scripts/addons/io_anim_acclaim/__init__.py b/release/scripts/addons/io_anim_acclaim/__init__.py
index be8ce5b..4b5b423 100644
--- a/release/scripts/addons/io_anim_acclaim/__init__.py
+++ b/release/scripts/addons/io_anim_acclaim/__init__.py
@@ -23,17 +23,17 @@
bl_info = {
- 'name': "Acclaim Motion Capture Files (.asf, .amc)",
- 'author': "Daniel Monteiro Basso <daniel at basso.inf.br>",
- 'version': (2012, 2, 29, 1),
- 'blender': (2, 6, 2),
- 'location': "File > Import-Export",
- 'description': "Imports Acclaim Skeleton and Motion Capture Files",
- 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "name": "Acclaim Motion Capture Files (.asf, .amc)",
+ "author": "Daniel Monteiro Basso <daniel at basso.inf.br>",
+ "version": (2012, 2, 29, 1),
+ "blender": (2, 62, 0),
+ "location": "File > Import-Export",
+ "description": "Imports Acclaim Skeleton and Motion Capture Files",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Import-Export/Acclaim_Importer",
- 'tracker_url': "http://projects.blender.org/tracker/index.php?"
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"
"func=detail&aid=27127&group_id=153&atid=467",
- 'category': 'Import-Export'}
+ "category": "Import-Export"}
import re
diff --git a/release/scripts/addons/io_anim_bvh/__init__.py b/release/scripts/addons/io_anim_bvh/__init__.py
index 993bd73..5db5440 100644
--- a/release/scripts/addons/io_anim_bvh/__init__.py
+++ b/release/scripts/addons/io_anim_bvh/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "BioVision Motion Capture (BVH) format",
"author": "Campbell Barton",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export",
"description": "Import-Export BVH from armature objects",
"warning": "",
diff --git a/release/scripts/addons/io_anim_c3d/__init__.py b/release/scripts/addons/io_anim_c3d/__init__.py
index 8741c25..4ecc9da 100644
--- a/release/scripts/addons/io_anim_c3d/__init__.py
+++ b/release/scripts/addons/io_anim_c3d/__init__.py
@@ -23,17 +23,17 @@
bl_info = {
- 'name': "C3D Graphics Lab Motion Capture file (.c3d)",
- 'author': "Daniel Monteiro Basso <daniel at basso.inf.br>",
- 'version': (2012, 7, 11, 1),
- 'blender': (2, 6, 3),
- 'location': "File > Import",
- 'description': "Imports C3D Graphics Lab Motion Capture files",
- 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "name": "C3D Graphics Lab Motion Capture file (.c3d)",
+ "author": "Daniel Monteiro Basso <daniel at basso.inf.br>",
+ "version": (2012, 7, 11, 1),
+ "blender": (2, 63, 0),
+ "location": "File > Import",
+ "description": "Imports C3D Graphics Lab Motion Capture files",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Import-Export/C3D_Importer",
- 'tracker_url': "http://projects.blender.org/tracker/?func=detail&atid=467"
+ "tracker_url": "http://projects.blender.org/tracker/?func=detail&atid=467"
"&aid=29061&group_id=153",
- 'category': 'Import-Export'}
+ "category": 'Import-Export'}
import bpy
diff --git a/release/scripts/addons/io_anim_camera.py b/release/scripts/addons/io_anim_camera.py
index a49adae..376a056 100644
--- a/release/scripts/addons/io_anim_camera.py
+++ b/release/scripts/addons/io_anim_camera.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Export Camera Animation",
"author": "Campbell Barton",
"version": (0, 1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Export > Cameras & Markers (.py)",
"description": "Export Cameras & Markers (.py)",
"warning": "",
diff --git a/release/scripts/addons/io_anim_nuke_chan/__init__.py b/release/scripts/addons/io_anim_nuke_chan/__init__.py
index c025812..54bd709 100644
--- a/release/scripts/addons/io_anim_nuke_chan/__init__.py
+++ b/release/scripts/addons/io_anim_nuke_chan/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Nuke Animation Format (.chan)",
"author": "Michael Krupa",
"version": (1, 0),
- "blender": (2, 6, 1),
+ "blender": (2, 61, 0),
"location": "File > Import/Export > Nuke (.chan)",
"description": "Import/Export object's animation with nuke",
"warning": "",
diff --git a/release/scripts/addons/io_coat3D/__init__.py b/release/scripts/addons/io_coat3D/__init__.py
index 4cd6b8a..33faf0e 100644
--- a/release/scripts/addons/io_coat3D/__init__.py
+++ b/release/scripts/addons/io_coat3D/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "3D-Coat Applink",
"author": "Kalle-Samuli Riihikoski (haikalle)",
"version": (3, 5, 20),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "Scene > 3D-Coat Applink",
"description": "Transfer data between 3D-Coat/Blender",
"warning": "",
diff --git a/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py b/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py
index dd162a7..08f9c2b 100644
--- a/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py
+++ b/release/scripts/addons/io_convert_image_to_mesh_img/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "HiRISE DTM from PDS IMG",
"author": "Tim Spriggs (tims at uahirise.org)",
"version": (0, 1, 4),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "File > Import > HiRISE DTM from PDS IMG (.IMG)",
"description": "Import a HiRISE DTM formatted as a PDS IMG file",
"warning": "May consume a lot of memory",
diff --git a/release/scripts/addons/io_curve_svg/__init__.py b/release/scripts/addons/io_curve_svg/__init__.py
index db58a9f..4a90e5e 100644
--- a/release/scripts/addons/io_curve_svg/__init__.py
+++ b/release/scripts/addons/io_curve_svg/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Scalable Vector Graphics (SVG) 1.1 format",
"author": "JM Soler, Sergey Sharybin",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import > Scalable Vector Graphics (.svg)",
"description": "Import SVG as curves",
"warning": "",
diff --git a/release/scripts/addons/io_export_after_effects.py b/release/scripts/addons/io_export_after_effects.py
index a71348a..65f2127 100644
--- a/release/scripts/addons/io_export_after_effects.py
+++ b/release/scripts/addons/io_export_after_effects.py
@@ -19,18 +19,18 @@
# <pep8 compliant>
bl_info = {
- 'name': 'Export: Adobe After Effects (.jsx)',
- 'description': 'Export cameras, selected objects & camera solution 3D Markers to Adobe After Effects CS3 and above',
- 'author': 'Bartek Skorupa',
- 'version': (0, 6, 3),
- 'blender': (2, 6, 2),
- 'location': 'File > Export > Adobe After Effects (.jsx)',
+ "name": "Export: Adobe After Effects (.jsx)",
+ "description": "Export cameras, selected objects & camera solution 3D Markers to Adobe After Effects CS3 and above",
+ "author": "Bartek Skorupa",
+ "version": (0, 6, 3),
+ "blender": (2, 62, 0),
+ "location": "File > Export > Adobe After Effects (.jsx)",
"warning": "",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
"Scripts/Import-Export/Adobe_After_Effects",
"tracker_url": "https://projects.blender.org/tracker/index.php?"\
"func=detail&aid=29858",
- 'category': 'Import-Export',
+ "category": "Import-Export",
}
diff --git a/release/scripts/addons/io_export_directx_x.py b/release/scripts/addons/io_export_directx_x.py
index e4c7440..4532600 100644
--- a/release/scripts/addons/io_export_directx_x.py
+++ b/release/scripts/addons/io_export_directx_x.py
@@ -19,7 +19,7 @@ bl_info = {
"name": "DirectX Model Format (.x)",
"author": "Chris Foster (Kira Vakaan)",
"version": (2, 1, 3),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "File > Export > DirectX (.x)",
"description": "Export DirectX Model Format (.x)",
"warning": "",
diff --git a/release/scripts/addons/io_export_dxf/__init__.py b/release/scripts/addons/io_export_dxf/__init__.py
index 2ac22ba..c79ba5e 100644
--- a/release/scripts/addons/io_export_dxf/__init__.py
+++ b/release/scripts/addons/io_export_dxf/__init__.py
@@ -19,7 +19,7 @@ bl_info = {
"name": "Export Autocad DXF Format (.dxf)",
"author": "Remigiusz Fiedler (AKA migius), Vaclav Klecanda",
"version": (2, 1, 3),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "File > Export > Autodesk (.dxf)",
"description": "The script exports Blender geometry to DXF format r12 version.",
"warning": "Under construction! Visit Wiki for details.",
diff --git a/release/scripts/addons/io_export_pc2.py b/release/scripts/addons/io_export_pc2.py
index 440e4c2..37953d5 100644
--- a/release/scripts/addons/io_export_pc2.py
+++ b/release/scripts/addons/io_export_pc2.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Export Pointcache Format(.pc2)",
"author": "Florian Meyer (tstscr)",
"version": (1, 0),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Export > Pointcache (.pc2)",
"description": "Export mesh Pointcache data (.pc2)",
"warning": "",
diff --git a/release/scripts/addons/io_export_unreal_psk_psa.py b/release/scripts/addons/io_export_unreal_psk_psa.py
index d0baffc..90c5a97 100644
--- a/release/scripts/addons/io_export_unreal_psk_psa.py
+++ b/release/scripts/addons/io_export_unreal_psk_psa.py
@@ -19,8 +19,8 @@
bl_info = {
"name": "Export Unreal Engine Format(.psk/.psa)",
"author": "Darknet/Optimus_P-Fat/Active_Trash/Sinsoft/VendorX/Spoof",
- "version": (2, 6),
- "blender": (2, 6, 3),
+ "version": (2, 7),
+ "blender": (2, 65, 0),
"api": 36079,
"location": "File > Export > Skeletal Mesh/Animation Data (.psk/.psa)",
"description": "Export Skeleletal Mesh/Animation Data",
@@ -84,8 +84,8 @@ Credit to:
"""
NOTES for Jan 2012 refactor (Spoof)
- * THIS IS A WORK IN PROGRESS. These modifications were originally
- intended for internal use and are incomplete. Use at your own risk! *
+ * THIS IS A WORK IN PROGRESS. These modifications were originally
+ intended for internal use and are incomplete. Use at your own risk! *
TODO
@@ -102,11 +102,11 @@ CHANGES
- progress reporting while processing smooth groups
- more informative logging
- code refactor for clarity and modularity
- - naming conventions unified to use lowercase_with_underscore
- - C++ datatypes and PSK/PSA classes remain CamelCaseStyle for clarity
- - names such as 'ut' and 'unreal' unified to 'udk'
- - simplification of code structure
- - removed legacy code paths
+ - naming conventions unified to use lowercase_with_underscore
+ - C++ datatypes and PSK/PSA classes remain CamelCaseStyle for clarity
+ - names such as 'ut' and 'unreal' unified to 'udk'
+ - simplification of code structure
+ - removed legacy code paths
USAGE
@@ -116,9 +116,9 @@ control bones to aid in animation.
Taking advantage of this script requires the following methodology:
- * Place all exportable bones into a bone hierarchy extending from a single
- root. This root bone must have use_deform enabled. All other root bones
- in the armature must disable use_deform. *
+ * Place all exportable bones into a bone hierarchy extending from a single
+ root. This root bone must have use_deform enabled. All other root bones
+ in the armature must disable use_deform. *
The script searches for a root bone with use_deform set true and considers all
bones parented to it as part of the UDK skeletal mesh. Thus only these bones
@@ -129,7 +129,7 @@ bone hierarchies to the rig, and keyframe any element into actions. With this
approach you can build complex animation rigs in a similar vein to the Rigify
add-on, by Nathan Vegdahl. However...
- * Rigify is incompatible with this script *
+ * Rigify is incompatible with this script *
Rigify interlaces deformer bones within a single hierarchy making it difficult
to deconstruct for export. It also splits some meta-rig bones into multiple
@@ -159,85 +159,84 @@ from struct import pack
# Triangles specifed counter clockwise for front face
#
# defines for sizeofs
-SIZE_FQUAT = 16
-SIZE_FVECTOR = 12
-SIZE_VJOINTPOS = 44
-SIZE_ANIMINFOBINARY = 168
-SIZE_VCHUNKHEADER = 32
-SIZE_VMATERIAL = 88
-SIZE_VBONE = 120
-SIZE_FNAMEDBONEBINARY = 120
-SIZE_VRAWBONEINFLUENCE = 12
-SIZE_VQUATANIMKEY = 32
-SIZE_VVERTEX = 16
-SIZE_VPOINT = 12
-SIZE_VTRIANGLE = 12
-
-MaterialName = []
-
+SIZE_FQUAT = 16
+SIZE_FVECTOR = 12
+SIZE_VJOINTPOS = 44
+SIZE_ANIMINFOBINARY = 168
+SIZE_VCHUNKHEADER = 32
+SIZE_VMATERIAL = 88
+SIZE_VBONE = 120
+SIZE_FNAMEDBONEBINARY = 120
+SIZE_VRAWBONEINFLUENCE = 12
+SIZE_VQUATANIMKEY = 32
+SIZE_VVERTEX = 16
+SIZE_VPOINT = 12
+SIZE_VTRIANGLE = 12
+
+MaterialName = []
#===========================================================================
# Custom exception class
#===========================================================================
class Error( Exception ):
- def __init__(self, message):
- self.message = message
+ def __init__(self, message):
+ self.message = message
#===========================================================================
# Verbose logging with loop truncation
#===========================================================================
def verbose( msg, iteration=-1, max_iterations=4, msg_truncated="..." ):
- if bpy.context.scene.udk_option_verbose == True:
- # limit the number of times a loop can output messages
- if iteration > max_iterations:
- return
- elif iteration == max_iterations:
- print(msg_truncated)
- return
+ if bpy.context.scene.udk_option_verbose == True:
+ # limit the number of times a loop can output messages
+ if iteration > max_iterations:
+ return
+ elif iteration == max_iterations:
+ print(msg_truncated)
+ return
- print(msg)
-
+ print(msg)
+
#===========================================================================
# Log header/separator
#===========================================================================
def header( msg, justify='LEFT', spacer='_', cols=78 ):
-
- if justify == 'LEFT':
- s = '{:{spacer}<{cols}}'.format(msg+" ", spacer=spacer, cols=cols)
-
- elif justify == 'RIGHT':
- s = '{:{spacer}>{cols}}'.format(" "+msg, spacer=spacer, cols=cols)
-
- else:
- s = '{:{spacer}^{cols}}'.format(" "+msg+" ", spacer=spacer, cols=cols)
-
- return "\n" + s + "\n"
+
+ if justify == 'LEFT':
+ s = '{:{spacer}<{cols}}'.format(msg+" ", spacer=spacer, cols=cols)
+
+ elif justify == 'RIGHT':
+ s = '{:{spacer}>{cols}}'.format(" "+msg, spacer=spacer, cols=cols)
+
+ else:
+ s = '{:{spacer}^{cols}}'.format(" "+msg+" ", spacer=spacer, cols=cols)
+
+ return "\n" + s + "\n"
#===========================================================================
# Generic Object->Integer mapping
# the object must be usable as a dictionary key
#===========================================================================
class ObjMap:
-
- def __init__(self):
- self.dict = {}
- self.next = 0
-
- def get(self, obj):
- if obj in self.dict:
- return self.dict[obj]
- else:
- id = self.next
- self.next = self.next + 1
- self.dict[obj] = id
- return id
-
- def items(self):
- getval = operator.itemgetter(0)
- getkey = operator.itemgetter(1)
- return map(getval, sorted(self.dict.items(), key=getkey))
+
+ def __init__(self):
+ self.dict = {}
+ self.next = 0
+
+ def get(self, obj):
+ if obj in self.dict:
+ return self.dict[obj]
+ else:
+ id = self.next
+ self.next = self.next + 1
+ self.dict[obj] = id
+ return id
+
+ def items(self):
+ getval = operator.itemgetter(0)
+ getkey = operator.itemgetter(1)
+ return map(getval, sorted(self.dict.items(), key=getkey))
#===========================================================================
# RG - UNREAL DATA STRUCTS - CONVERTED FROM C STRUCTS GIVEN ON UDN SITE
@@ -246,258 +245,258 @@ class ObjMap:
#===========================================================================
class FQuat:
- def __init__(self):
- self.X = 0.0
- self.Y = 0.0
- self.Z = 0.0
- self.W = 1.0
-
- def dump(self):
- return pack('ffff', self.X, self.Y, self.Z, self.W)
-
- def __cmp__(self, other):
- return cmp(self.X, other.X) \
- or cmp(self.Y, other.Y) \
- or cmp(self.Z, other.Z) \
- or cmp(self.W, other.W)
-
- def __hash__(self):
- return hash(self.X) ^ hash(self.Y) ^ hash(self.Z) ^ hash(self.W)
-
- def __str__(self):
- return "[%f,%f,%f,%f](FQuat)" % (self.X, self.Y, self.Z, self.W)
+ def __init__(self):
+ self.X = 0.0
+ self.Y = 0.0
+ self.Z = 0.0
+ self.W = 1.0
+
+ def dump(self):
+ return pack('ffff', self.X, self.Y, self.Z, self.W)
+
+ def __cmp__(self, other):
+ return cmp(self.X, other.X) \
+ or cmp(self.Y, other.Y) \
+ or cmp(self.Z, other.Z) \
+ or cmp(self.W, other.W)
+
+ def __hash__(self):
+ return hash(self.X) ^ hash(self.Y) ^ hash(self.Z) ^ hash(self.W)
+
+ def __str__(self):
+ return "[%f,%f,%f,%f](FQuat)" % (self.X, self.Y, self.Z, self.W)
class FVector(object):
- def __init__(self, X=0.0, Y=0.0, Z=0.0):
- self.X = X
- self.Y = Y
- self.Z = Z
-
- def dump(self):
- return pack('fff', self.X, self.Y, self.Z)
-
- def __cmp__(self, other):
- return cmp(self.X, other.X) \
- or cmp(self.Y, other.Y) \
- or cmp(self.Z, other.Z)
-
- def _key(self):
- return (type(self).__name__, self.X, self.Y, self.Z)
-
- def __hash__(self):
- return hash(self._key())
-
- def __eq__(self, other):
- if not hasattr(other, '_key'):
- return False
- return self._key() == other._key()
-
- def dot(self, other):
- return self.X * other.X + self.Y * other.Y + self.Z * other.Z
-
- def cross(self, other):
- return FVector(self.Y * other.Z - self.Z * other.Y,
- self.Z * other.X - self.X * other.Z,
- self.X * other.Y - self.Y * other.X)
-
- def sub(self, other):
- return FVector(self.X - other.X,
- self.Y - other.Y,
- self.Z - other.Z)
+ def __init__(self, X=0.0, Y=0.0, Z=0.0):
+ self.X = X
+ self.Y = Y
+ self.Z = Z
+
+ def dump(self):
+ return pack('fff', self.X, self.Y, self.Z)
+
+ def __cmp__(self, other):
+ return cmp(self.X, other.X) \
+ or cmp(self.Y, other.Y) \
+ or cmp(self.Z, other.Z)
+
+ def _key(self):
+ return (type(self).__name__, self.X, self.Y, self.Z)
+
+ def __hash__(self):
+ return hash(self._key())
+
+ def __eq__(self, other):
+ if not hasattr(other, '_key'):
+ return False
+ return self._key() == other._key()
+
+ def dot(self, other):
+ return self.X * other.X + self.Y * other.Y + self.Z * other.Z
+
+ def cross(self, other):
+ return FVector(self.Y * other.Z - self.Z * other.Y,
+ self.Z * other.X - self.X * other.Z,
+ self.X * other.Y - self.Y * other.X)
+
+ def sub(self, other):
+ return FVector(self.X - other.X,
+ self.Y - other.Y,
+ self.Z - other.Z)
class VJointPos:
- def __init__(self):
- self.Orientation = FQuat()
- self.Position = FVector()
- self.Length = 0.0
- self.XSize = 0.0
- self.YSize = 0.0
- self.ZSize = 0.0
-
- def dump(self):
- return self.Orientation.dump() + self.Position.dump() + pack('4f', self.Length, self.XSize, self.YSize, self.ZSize)
+ def __init__(self):
+ self.Orientation = FQuat()
+ self.Position = FVector()
+ self.Length = 0.0
+ self.XSize = 0.0
+ self.YSize = 0.0
+ self.ZSize = 0.0
+
+ def dump(self):
+ return self.Orientation.dump() + self.Position.dump() + pack('4f', self.Length, self.XSize, self.YSize, self.ZSize)
class AnimInfoBinary:
- def __init__(self):
- self.Name = "" # length=64
- self.Group = "" # length=64
- self.TotalBones = 0
- self.RootInclude = 0
- self.KeyCompressionStyle = 0
- self.KeyQuotum = 0
- self.KeyPrediction = 0.0
- self.TrackTime = 0.0
- self.AnimRate = 0.0
- self.StartBone = 0
- self.FirstRawFrame = 0
- self.NumRawFrames = 0
-
- def dump(self):
- return pack('64s64siiiifffiii', str.encode(self.Name), str.encode(self.Group), self.TotalBones, self.RootInclude, self.KeyCompressionStyle, self.KeyQuotum, self.KeyPrediction, self.TrackTime, self.AnimRate, self.StartBone, self.FirstRawFrame, self.NumRawFrames)
+ def __init__(self):
+ self.Name = "" # length=64
+ self.Group = "" # length=64
+ self.TotalBones = 0
+ self.RootInclude = 0
+ self.KeyCompressionStyle = 0
+ self.KeyQuotum = 0
+ self.KeyPrediction = 0.0
+ self.TrackTime = 0.0
+ self.AnimRate = 0.0
+ self.StartBone = 0
+ self.FirstRawFrame = 0
+ self.NumRawFrames = 0
+
+ def dump(self):
+ return pack('64s64siiiifffiii', str.encode(self.Name), str.encode(self.Group), self.TotalBones, self.RootInclude, self.KeyCompressionStyle, self.KeyQuotum, self.KeyPrediction, self.TrackTime, self.AnimRate, self.StartBone, self.FirstRawFrame, self.NumRawFrames)
class VChunkHeader:
- def __init__(self, name, type_size):
- self.ChunkID = str.encode(name) # length=20
- self.TypeFlag = 1999801 # special value
- self.DataSize = type_size
- self.DataCount = 0
-
- def dump(self):
- return pack('20siii', self.ChunkID, self.TypeFlag, self.DataSize, self.DataCount)
+ def __init__(self, name, type_size):
+ self.ChunkID = str.encode(name) # length=20
+ self.TypeFlag = 1999801 # special value
+ self.DataSize = type_size
+ self.DataCount = 0
+
+ def dump(self):
+ return pack('20siii', self.ChunkID, self.TypeFlag, self.DataSize, self.DataCount)
class VMaterial:
- def __init__(self):
- self.MaterialName = "" # length=64
- self.TextureIndex = 0
- self.PolyFlags = 0 # DWORD
- self.AuxMaterial = 0
- self.AuxFlags = 0 # DWORD
- self.LodBias = 0
- self.LodStyle = 0
-
- def dump(self):
- #print("DATA MATERIAL:",self.MaterialName)
- return pack('64siLiLii', str.encode(self.MaterialName), self.TextureIndex, self.PolyFlags, self.AuxMaterial, self.AuxFlags, self.LodBias, self.LodStyle)
+ def __init__(self):
+ self.MaterialName = "" # length=64
+ self.TextureIndex = 0
+ self.PolyFlags = 0 # DWORD
+ self.AuxMaterial = 0
+ self.AuxFlags = 0 # DWORD
+ self.LodBias = 0
+ self.LodStyle = 0
+
+ def dump(self):
+ #print("DATA MATERIAL:",self.MaterialName)
+ return pack('64siLiLii', str.encode(self.MaterialName), self.TextureIndex, self.PolyFlags, self.AuxMaterial, self.AuxFlags, self.LodBias, self.LodStyle)
class VBone:
- def __init__(self):
- self.Name = "" # length = 64
- self.Flags = 0 # DWORD
- self.NumChildren = 0
- self.ParentIndex = 0
- self.BonePos = VJointPos()
-
- def dump(self):
- return pack('64sLii', str.encode(self.Name), self.Flags, self.NumChildren, self.ParentIndex) + self.BonePos.dump()
-
-#same as above - whatever - this is how Epic does it...
+ def __init__(self):
+ self.Name = "" # length = 64
+ self.Flags = 0 # DWORD
+ self.NumChildren = 0
+ self.ParentIndex = 0
+ self.BonePos = VJointPos()
+
+ def dump(self):
+ return pack('64sLii', str.encode(self.Name), self.Flags, self.NumChildren, self.ParentIndex) + self.BonePos.dump()
+
+#same as above - whatever - this is how Epic does it...
class FNamedBoneBinary:
- def __init__(self):
- self.Name = "" # length = 64
- self.Flags = 0 # DWORD
- self.NumChildren = 0
- self.ParentIndex = 0
- self.BonePos = VJointPos()
- self.IsRealBone = 0 # this is set to 1 when the bone is actually a bone in the mesh and not a dummy
-
- def dump(self):
- return pack('64sLii', str.encode(self.Name), self.Flags, self.NumChildren, self.ParentIndex) + self.BonePos.dump()
+ def __init__(self):
+ self.Name = "" # length = 64
+ self.Flags = 0 # DWORD
+ self.NumChildren = 0
+ self.ParentIndex = 0
+ self.BonePos = VJointPos()
+ self.IsRealBone = 0 # this is set to 1 when the bone is actually a bone in the mesh and not a dummy
+
+ def dump(self):
+ return pack('64sLii', str.encode(self.Name), self.Flags, self.NumChildren, self.ParentIndex) + self.BonePos.dump()
class VRawBoneInfluence:
- def __init__(self):
- self.Weight = 0.0
- self.PointIndex = 0
- self.BoneIndex = 0
-
- def dump(self):
- return pack('fii', self.Weight, self.PointIndex, self.BoneIndex)
+ def __init__(self):
+ self.Weight = 0.0
+ self.PointIndex = 0
+ self.BoneIndex = 0
+
+ def dump(self):
+ return pack('fii', self.Weight, self.PointIndex, self.BoneIndex)
class VQuatAnimKey:
- def __init__(self):
- self.Position = FVector()
- self.Orientation = FQuat()
- self.Time = 0.0
-
- def dump(self):
- return self.Position.dump() + self.Orientation.dump() + pack('f', self.Time)
+ def __init__(self):
+ self.Position = FVector()
+ self.Orientation = FQuat()
+ self.Time = 0.0
+
+ def dump(self):
+ return self.Position.dump() + self.Orientation.dump() + pack('f', self.Time)
class VVertex(object):
- def __init__(self):
- self.PointIndex = 0 # WORD
- self.U = 0.0
- self.V = 0.0
- self.MatIndex = 0 # BYTE
- self.Reserved = 0 # BYTE
- self.SmoothGroup = 0
-
- def dump(self):
- return pack('HHffBBH', self.PointIndex, 0, self.U, self.V, self.MatIndex, self.Reserved, 0)
-
- def __cmp__(self, other):
- return cmp(self.PointIndex, other.PointIndex) \
- or cmp(self.U, other.U) \
- or cmp(self.V, other.V) \
- or cmp(self.MatIndex, other.MatIndex) \
- or cmp(self.Reserved, other.Reserved) \
- or cmp(self.SmoothGroup, other.SmoothGroup )
-
- def _key(self):
- return (type(self).__name__, self.PointIndex, self.U, self.V, self.MatIndex, self.Reserved)
-
- def __hash__(self):
- return hash(self._key())
-
- def __eq__(self, other):
- if not hasattr(other, '_key'):
- return False
- return self._key() == other._key()
+ def __init__(self):
+ self.PointIndex = 0 # WORD
+ self.U = 0.0
+ self.V = 0.0
+ self.MatIndex = 0 # BYTE
+ self.Reserved = 0 # BYTE
+ self.SmoothGroup = 0
+
+ def dump(self):
+ return pack('HHffBBH', self.PointIndex, 0, self.U, self.V, self.MatIndex, self.Reserved, 0)
+
+ def __cmp__(self, other):
+ return cmp(self.PointIndex, other.PointIndex) \
+ or cmp(self.U, other.U) \
+ or cmp(self.V, other.V) \
+ or cmp(self.MatIndex, other.MatIndex) \
+ or cmp(self.Reserved, other.Reserved) \
+ or cmp(self.SmoothGroup, other.SmoothGroup )
+
+ def _key(self):
+ return (type(self).__name__, self.PointIndex, self.U, self.V, self.MatIndex, self.Reserved)
+
+ def __hash__(self):
+ return hash(self._key())
+
+ def __eq__(self, other):
+ if not hasattr(other, '_key'):
+ return False
+ return self._key() == other._key()
class VPointSimple:
- def __init__(self):
- self.Point = FVector()
+ def __init__(self):
+ self.Point = FVector()
- def __cmp__(self, other):
- return cmp(self.Point, other.Point)
-
- def __hash__(self):
- return hash(self._key())
+ def __cmp__(self, other):
+ return cmp(self.Point, other.Point)
+
+ def __hash__(self):
+ return hash(self._key())
- def _key(self):
- return (type(self).__name__, self.Point)
+ def _key(self):
+ return (type(self).__name__, self.Point)
- def __eq__(self, other):
- if not hasattr(other, '_key'):
- return False
- return self._key() == other._key()
+ def __eq__(self, other):
+ if not hasattr(other, '_key'):
+ return False
+ return self._key() == other._key()
class VPoint(object):
- def __init__(self):
- self.Point = FVector()
- self.SmoothGroup = 0
-
- def dump(self):
- return self.Point.dump()
-
- def __cmp__(self, other):
- return cmp(self.Point, other.Point) \
- or cmp(self.SmoothGroup, other.SmoothGroup)
-
- def _key(self):
- return (type(self).__name__, self.Point, self.SmoothGroup)
-
- def __hash__(self):
- return hash(self._key()) \
- ^ hash(self.SmoothGroup)
-
- def __eq__(self, other):
- if not hasattr(other, '_key'):
- return False
- return self._key() == other._key()
+ def __init__(self):
+ self.Point = FVector()
+ self.SmoothGroup = 0
+
+ def dump(self):
+ return self.Point.dump()
+
+ def __cmp__(self, other):
+ return cmp(self.Point, other.Point) \
+ or cmp(self.SmoothGroup, other.SmoothGroup)
+
+ def _key(self):
+ return (type(self).__name__, self.Point, self.SmoothGroup)
+
+ def __hash__(self):
+ return hash(self._key()) \
+ ^ hash(self.SmoothGroup)
+
+ def __eq__(self, other):
+ if not hasattr(other, '_key'):
+ return False
+ return self._key() == other._key()
class VTriangle:
- def __init__(self):
- self.WedgeIndex0 = 0 # WORD
- self.WedgeIndex1 = 0 # WORD
- self.WedgeIndex2 = 0 # WORD
- self.MatIndex = 0 # BYTE
- self.AuxMatIndex = 0 # BYTE
- self.SmoothingGroups = 0 # DWORD
-
- def dump(self):
- return pack('HHHBBL', self.WedgeIndex0, self.WedgeIndex1, self.WedgeIndex2, self.MatIndex, self.AuxMatIndex, self.SmoothingGroups)
+ def __init__(self):
+ self.WedgeIndex0 = 0 # WORD
+ self.WedgeIndex1 = 0 # WORD
+ self.WedgeIndex2 = 0 # WORD
+ self.MatIndex = 0 # BYTE
+ self.AuxMatIndex = 0 # BYTE
+ self.SmoothingGroups = 0 # DWORD
+
+ def dump(self):
+ return pack('HHHBBL', self.WedgeIndex0, self.WedgeIndex1, self.WedgeIndex2, self.MatIndex, self.AuxMatIndex, self.SmoothingGroups)
# END UNREAL DATA STRUCTS
#===========================================================================
@@ -507,97 +506,97 @@ class VTriangle:
# as sections consisting of a header and then a list of data structures
#===========================================================================
class FileSection:
-
- def __init__(self, name, type_size):
- self.Header = VChunkHeader(name, type_size)
- self.Data = [] # list of datatypes
-
- def dump(self):
- data = self.Header.dump()
- for i in range(len(self.Data)):
- data = data + self.Data[i].dump()
- return data
-
- def UpdateHeader(self):
- self.Header.DataCount = len(self.Data)
+
+ def __init__(self, name, type_size):
+ self.Header = VChunkHeader(name, type_size)
+ self.Data = [] # list of datatypes
+
+ def dump(self):
+ data = self.Header.dump()
+ for i in range(len(self.Data)):
+ data = data + self.Data[i].dump()
+ return data
+
+ def UpdateHeader(self):
+ self.Header.DataCount = len(self.Data)
#===========================================================================
# PSK
#===========================================================================
class PSKFile:
-
- def __init__(self):
- self.GeneralHeader = VChunkHeader("ACTRHEAD", 0)
- self.Points = FileSection("PNTS0000", SIZE_VPOINT) # VPoint
- self.Wedges = FileSection("VTXW0000", SIZE_VVERTEX) # VVertex
- self.Faces = FileSection("FACE0000", SIZE_VTRIANGLE) # VTriangle
- self.Materials = FileSection("MATT0000", SIZE_VMATERIAL) # VMaterial
- self.Bones = FileSection("REFSKELT", SIZE_VBONE) # VBone
- self.Influences = FileSection("RAWWEIGHTS", SIZE_VRAWBONEINFLUENCE) # VRawBoneInfluence
-
- #RG - this mapping is not dumped, but is used internally to store the new point indices
- # for vertex groups calculated during the mesh dump, so they can be used again
- # to dump bone influences during the armature dump
- #
- # the key in this dictionary is the VertexGroup/Bone Name, and the value
- # is a list of tuples containing the new point index and the weight, in that order
- #
- # Layout:
- # { groupname : [ (index, weight), ... ], ... }
- #
- # example:
- # { 'MyVertexGroup' : [ (0, 1.0), (5, 1.0), (3, 0.5) ] , 'OtherGroup' : [(2, 1.0)] }
-
- self.VertexGroups = {}
-
- def AddPoint(self, p):
- self.Points.Data.append(p)
-
- def AddWedge(self, w):
- self.Wedges.Data.append(w)
-
- def AddFace(self, f):
- self.Faces.Data.append(f)
-
- def AddMaterial(self, m):
- self.Materials.Data.append(m)
-
- def AddBone(self, b):
- self.Bones.Data.append(b)
-
- def AddInfluence(self, i):
- self.Influences.Data.append(i)
-
- def UpdateHeaders(self):
- self.Points.UpdateHeader()
- self.Wedges.UpdateHeader()
- self.Faces.UpdateHeader()
- self.Materials.UpdateHeader()
- self.Bones.UpdateHeader()
- self.Influences.UpdateHeader()
-
- def dump(self):
- self.UpdateHeaders()
- data = self.GeneralHeader.dump() + self.Points.dump() + self.Wedges.dump() + self.Faces.dump() + self.Materials.dump() + self.Bones.dump() + self.Influences.dump()
- return data
-
- def GetMatByIndex(self, mat_index):
- if mat_index >= 0 and len(self.Materials.Data) > mat_index:
- return self.Materials.Data[mat_index]
- else:
- m = VMaterial()
- # modified by VendorX
- m.MaterialName = MaterialName[mat_index]
- self.AddMaterial(m)
- return m
-
- def PrintOut(self):
- print( "{:>16} {:}".format( "Points", len(self.Points.Data) ) )
- print( "{:>16} {:}".format( "Wedges", len(self.Wedges.Data) ) )
- print( "{:>16} {:}".format( "Faces", len(self.Faces.Data) ) )
- print( "{:>16} {:}".format( "Materials", len(self.Materials.Data) ) )
- print( "{:>16} {:}".format( "Bones", len(self.Bones.Data) ) )
- print( "{:>16} {:}".format( "Influences", len(self.Influences.Data) ) )
+
+ def __init__(self):
+ self.GeneralHeader = VChunkHeader("ACTRHEAD", 0)
+ self.Points = FileSection("PNTS0000", SIZE_VPOINT) # VPoint
+ self.Wedges = FileSection("VTXW0000", SIZE_VVERTEX) # VVertex
+ self.Faces = FileSection("FACE0000", SIZE_VTRIANGLE) # VTriangle
+ self.Materials = FileSection("MATT0000", SIZE_VMATERIAL) # VMaterial
+ self.Bones = FileSection("REFSKELT", SIZE_VBONE) # VBone
+ self.Influences = FileSection("RAWWEIGHTS", SIZE_VRAWBONEINFLUENCE) # VRawBoneInfluence
+
+ #RG - this mapping is not dumped, but is used internally to store the new point indices
+ # for vertex groups calculated during the mesh dump, so they can be used again
+ # to dump bone influences during the armature dump
+ #
+ # the key in this dictionary is the VertexGroup/Bone Name, and the value
+ # is a list of tuples containing the new point index and the weight, in that order
+ #
+ # Layout:
+ # { groupname : [ (index, weight), ... ], ... }
+ #
+ # example:
+ # { 'MyVertexGroup' : [ (0, 1.0), (5, 1.0), (3, 0.5) ] , 'OtherGroup' : [(2, 1.0)] }
+
+ self.VertexGroups = {}
+
+ def AddPoint(self, p):
+ self.Points.Data.append(p)
+
+ def AddWedge(self, w):
+ self.Wedges.Data.append(w)
+
+ def AddFace(self, f):
+ self.Faces.Data.append(f)
+
+ def AddMaterial(self, m):
+ self.Materials.Data.append(m)
+
+ def AddBone(self, b):
+ self.Bones.Data.append(b)
+
+ def AddInfluence(self, i):
+ self.Influences.Data.append(i)
+
+ def UpdateHeaders(self):
+ self.Points.UpdateHeader()
+ self.Wedges.UpdateHeader()
+ self.Faces.UpdateHeader()
+ self.Materials.UpdateHeader()
+ self.Bones.UpdateHeader()
+ self.Influences.UpdateHeader()
+
+ def dump(self):
+ self.UpdateHeaders()
+ data = self.GeneralHeader.dump() + self.Points.dump() + self.Wedges.dump() + self.Faces.dump() + self.Materials.dump() + self.Bones.dump() + self.Influences.dump()
+ return data
+
+ def GetMatByIndex(self, mat_index):
+ if mat_index >= 0 and len(self.Materials.Data) > mat_index:
+ return self.Materials.Data[mat_index]
+ else:
+ m = VMaterial()
+ # modified by VendorX
+ m.MaterialName = MaterialName[mat_index]
+ self.AddMaterial(m)
+ return m
+
+ def PrintOut(self):
+ print( "{:>16} {:}".format( "Points", len(self.Points.Data) ) )
+ print( "{:>16} {:}".format( "Wedges", len(self.Wedges.Data) ) )
+ print( "{:>16} {:}".format( "Faces", len(self.Faces.Data) ) )
+ print( "{:>16} {:}".format( "Materials", len(self.Materials.Data) ) )
+ print( "{:>16} {:}".format( "Bones", len(self.Bones.Data) ) )
+ print( "{:>16} {:}".format( "Influences", len(self.Influences.Data) ) )
#===========================================================================
# PSA
@@ -617,933 +616,951 @@ class PSKFile:
#===========================================================================
class PSAFile:
- def __init__(self):
- self.GeneralHeader = VChunkHeader("ANIMHEAD", 0)
- self.Bones = FileSection("BONENAMES", SIZE_FNAMEDBONEBINARY) #FNamedBoneBinary
- self.Animations = FileSection("ANIMINFO", SIZE_ANIMINFOBINARY) #AnimInfoBinary
- self.RawKeys = FileSection("ANIMKEYS", SIZE_VQUATANIMKEY) #VQuatAnimKey
- # this will take the format of key=Bone Name, value = (BoneIndex, Bone Object)
- # THIS IS NOT DUMPED
- self.BoneLookup = {}
-
- def AddBone(self, b):
- self.Bones.Data.append(b)
-
- def AddAnimation(self, a):
- self.Animations.Data.append(a)
-
- def AddRawKey(self, k):
- self.RawKeys.Data.append(k)
-
- def UpdateHeaders(self):
- self.Bones.UpdateHeader()
- self.Animations.UpdateHeader()
- self.RawKeys.UpdateHeader()
-
- def GetBoneByIndex(self, bone_index):
- if bone_index >= 0 and len(self.Bones.Data) > bone_index:
- return self.Bones.Data[bone_index]
-
- def IsEmpty(self):
- return (len(self.Bones.Data) == 0 or len(self.Animations.Data) == 0)
-
- def StoreBone(self, b):
- self.BoneLookup[b.Name] = [-1, b]
-
- def UseBone(self, bone_name):
- if bone_name in self.BoneLookup:
- bone_data = self.BoneLookup[bone_name]
-
- if bone_data[0] == -1:
- bone_data[0] = len(self.Bones.Data)
- self.AddBone(bone_data[1])
- #self.Bones.Data.append(bone_data[1])
-
- return bone_data[0]
-
- def GetBoneByName(self, bone_name):
- if bone_name in self.BoneLookup:
- bone_data = self.BoneLookup[bone_name]
- return bone_data[1]
-
- def GetBoneIndex(self, bone_name):
- if bone_name in self.BoneLookup:
- bone_data = self.BoneLookup[bone_name]
- return bone_data[0]
-
- def dump(self):
- self.UpdateHeaders()
- return self.GeneralHeader.dump() + self.Bones.dump() + self.Animations.dump() + self.RawKeys.dump()
-
- def PrintOut(self):
- print( "{:>16} {:}".format( "Bones", len(self.Bones.Data) ) )
- print( "{:>16} {:}".format( "Animations", len(self.Animations.Data) ) )
- print( "{:>16} {:}".format( "Raw keys", len(self.RawKeys.Data) ) )
+ def __init__(self):
+ self.GeneralHeader = VChunkHeader("ANIMHEAD", 0)
+ self.Bones = FileSection("BONENAMES", SIZE_FNAMEDBONEBINARY) #FNamedBoneBinary
+ self.Animations = FileSection("ANIMINFO", SIZE_ANIMINFOBINARY) #AnimInfoBinary
+ self.RawKeys = FileSection("ANIMKEYS", SIZE_VQUATANIMKEY) #VQuatAnimKey
+ # this will take the format of key=Bone Name, value = (BoneIndex, Bone Object)
+ # THIS IS NOT DUMPED
+ self.BoneLookup = {}
+
+ def AddBone(self, b):
+ self.Bones.Data.append(b)
+
+ def AddAnimation(self, a):
+ self.Animations.Data.append(a)
+
+ def AddRawKey(self, k):
+ self.RawKeys.Data.append(k)
+
+ def UpdateHeaders(self):
+ self.Bones.UpdateHeader()
+ self.Animations.UpdateHeader()
+ self.RawKeys.UpdateHeader()
+
+ def GetBoneByIndex(self, bone_index):
+ if bone_index >= 0 and len(self.Bones.Data) > bone_index:
+ return self.Bones.Data[bone_index]
+
+ def IsEmpty(self):
+ return (len(self.Bones.Data) == 0 or len(self.Animations.Data) == 0)
+
+ def StoreBone(self, b):
+ self.BoneLookup[b.Name] = [-1, b]
+
+ def UseBone(self, bone_name):
+ if bone_name in self.BoneLookup:
+ bone_data = self.BoneLookup[bone_name]
+
+ if bone_data[0] == -1:
+ bone_data[0] = len(self.Bones.Data)
+ self.AddBone(bone_data[1])
+ #self.Bones.Data.append(bone_data[1])
+
+ return bone_data[0]
+
+ def GetBoneByName(self, bone_name):
+ if bone_name in self.BoneLookup:
+ bone_data = self.BoneLookup[bone_name]
+ return bone_data[1]
+
+ def GetBoneIndex(self, bone_name):
+ if bone_name in self.BoneLookup:
+ bone_data = self.BoneLookup[bone_name]
+ return bone_data[0]
+
+ def dump(self):
+ self.UpdateHeaders()
+ return self.GeneralHeader.dump() + self.Bones.dump() + self.Animations.dump() + self.RawKeys.dump()
+
+ def PrintOut(self):
+ print( "{:>16} {:}".format( "Bones", len(self.Bones.Data) ) )
+ print( "{:>16} {:}".format( "Animations", len(self.Animations.Data) ) )
+ print( "{:>16} {:}".format( "Raw keys", len(self.RawKeys.Data) ) )
#===========================================================================
# Helpers to create bone structs
#===========================================================================
def make_vbone( name, parent_index, child_count, orientation_quat, position_vect ):
- bone = VBone()
- bone.Name = name
- bone.ParentIndex = parent_index
- bone.NumChildren = child_count
- bone.BonePos.Orientation = orientation_quat
- bone.BonePos.Position.X = position_vect.x
- bone.BonePos.Position.Y = position_vect.y
- bone.BonePos.Position.Z = position_vect.z
- #these values seem to be ignored?
- #bone.BonePos.Length = tail.length
- #bone.BonePos.XSize = tail.x
- #bone.BonePos.YSize = tail.y
- #bone.BonePos.ZSize = tail.z
- return bone
+ bone = VBone()
+ bone.Name = name
+ bone.ParentIndex = parent_index
+ bone.NumChildren = child_count
+ bone.BonePos.Orientation = orientation_quat
+ bone.BonePos.Position.X = position_vect.x
+ bone.BonePos.Position.Y = position_vect.y
+ bone.BonePos.Position.Z = position_vect.z
+ #these values seem to be ignored?
+ #bone.BonePos.Length = tail.length
+ #bone.BonePos.XSize = tail.x
+ #bone.BonePos.YSize = tail.y
+ #bone.BonePos.ZSize = tail.z
+ return bone
def make_namedbonebinary( name, parent_index, child_count, orientation_quat, position_vect, is_real ):
- bone = FNamedBoneBinary()
- bone.Name = name
- bone.ParentIndex = parent_index
- bone.NumChildren = child_count
- bone.BonePos.Orientation = orientation_quat
- bone.BonePos.Position.X = position_vect.x
- bone.BonePos.Position.Y = position_vect.y
- bone.BonePos.Position.Z = position_vect.z
- bone.IsRealBone = is_real
- return bone
+ bone = FNamedBoneBinary()
+ bone.Name = name
+ bone.ParentIndex = parent_index
+ bone.NumChildren = child_count
+ bone.BonePos.Orientation = orientation_quat
+ bone.BonePos.Position.X = position_vect.x
+ bone.BonePos.Position.Y = position_vect.y
+ bone.BonePos.Position.Z = position_vect.z
+ bone.IsRealBone = is_real
+ return bone
def make_fquat( bquat ):
- quat = FQuat()
- #flip handedness for UT = set x,y,z to negative (rotate in other direction)
- quat.X = -bquat.x
- quat.Y = -bquat.y
- quat.Z = -bquat.z
- quat.W = bquat.w
- return quat
-
+ quat = FQuat()
+ #flip handedness for UT = set x,y,z to negative (rotate in other direction)
+ quat.X = -bquat.x
+ quat.Y = -bquat.y
+ quat.Z = -bquat.z
+ quat.W = bquat.w
+ return quat
+
def make_fquat_default( bquat ):
- quat = FQuat()
- #print(dir(bquat))
- quat.X = bquat.x
- quat.Y = bquat.y
- quat.Z = bquat.z
- quat.W = bquat.w
- return quat
+ quat = FQuat()
+ #print(dir(bquat))
+ quat.X = bquat.x
+ quat.Y = bquat.y
+ quat.Z = bquat.z
+ quat.W = bquat.w
+ return quat
#===========================================================================
#RG - check to make sure face isnt a line
#===========================================================================
def is_1d_face( face, mesh ):
- #ID Vertex of id point
- v0 = face.vertices[0]
- v1 = face.vertices[1]
- v2 = face.vertices[2]
-
- return (mesh.vertices[v0].co == mesh.vertices[v1].co \
- or mesh.vertices[v1].co == mesh.vertices[v2].co \
- or mesh.vertices[v2].co == mesh.vertices[v0].co)
- return False
+ #ID Vertex of id point
+ v0 = face.vertices[0]
+ v1 = face.vertices[1]
+ v2 = face.vertices[2]
+
+ return (mesh.vertices[v0].co == mesh.vertices[v1].co \
+ or mesh.vertices[v1].co == mesh.vertices[v2].co \
+ or mesh.vertices[v2].co == mesh.vertices[v0].co)
+ return False
#===========================================================================
# Smoothing group
# (renamed to seperate it from VVertex.SmoothGroup)
#===========================================================================
class SmoothingGroup:
-
- static_id = 1
-
- def __init__(self):
- self.faces = []
- self.neighboring_faces = []
- self.neighboring_groups = []
- self.id = -1
- self.local_id = SmoothingGroup.static_id
- SmoothingGroup.static_id += 1
-
- def __cmp__(self, other):
- if isinstance(other, SmoothingGroup):
- return cmp( self.local_id, other.local_id )
- return -1
-
- def __hash__(self):
- return hash(self.local_id)
-
- # searches neighboring faces to determine which smoothing group ID can be used
- def get_valid_smoothgroup_id(self):
- temp_id = 1
- for group in self.neighboring_groups:
- if group != None and group.id == temp_id:
- if temp_id < 0x80000000:
- temp_id = temp_id << 1
- else:
- raise Error("Smoothing Group ID Overflowed, Smoothing Group evidently has more than 31 neighboring groups")
-
- self.id = temp_id
- return self.id
-
- def make_neighbor(self, new_neighbor):
- if new_neighbor not in self.neighboring_groups:
- self.neighboring_groups.append( new_neighbor )
-
- def contains_face(self, face):
- return (face in self.faces)
-
- def add_neighbor_face(self, face):
- if not face in self.neighboring_faces:
- self.neighboring_faces.append( face )
-
- def add_face(self, face):
- if not face in self.faces:
- self.faces.append( face )
+
+ static_id = 1
+
+ def __init__(self):
+ self.faces = []
+ self.neighboring_faces = []
+ self.neighboring_groups = []
+ self.id = -1
+ self.local_id = SmoothingGroup.static_id
+ SmoothingGroup.static_id += 1
+
+ def __cmp__(self, other):
+ if isinstance(other, SmoothingGroup):
+ return cmp( self.local_id, other.local_id )
+ return -1
+
+ def __hash__(self):
+ return hash(self.local_id)
+
+ # searches neighboring faces to determine which smoothing group ID can be used
+ def get_valid_smoothgroup_id(self):
+ temp_id = 1
+ for group in self.neighboring_groups:
+ if group != None and group.id == temp_id:
+ if temp_id < 0x80000000:
+ temp_id = temp_id << 1
+ else:
+ raise Error("Smoothing Group ID Overflowed, Smoothing Group evidently has more than 31 neighboring groups")
+
+ self.id = temp_id
+ return self.id
+
+ def make_neighbor(self, new_neighbor):
+ if new_neighbor not in self.neighboring_groups:
+ self.neighboring_groups.append( new_neighbor )
+
+ def contains_face(self, face):
+ return (face in self.faces)
+
+ def add_neighbor_face(self, face):
+ if not face in self.neighboring_faces:
+ self.neighboring_faces.append( face )
+
+ def add_face(self, face):
+ if not face in self.faces:
+ self.faces.append( face )
def determine_edge_sharing( mesh ):
-
- edge_sharing_list = dict()
-
- for edge in mesh.edges:
- edge_sharing_list[edge.key] = []
-
- for face in mesh.tessfaces:
- for key in face.edge_keys:
- if not face in edge_sharing_list[key]:
- edge_sharing_list[key].append(face) # mark this face as sharing this edge
-
- return edge_sharing_list
+
+ edge_sharing_list = dict()
+
+ for edge in mesh.edges:
+ edge_sharing_list[edge.key] = []
+
+ for face in mesh.tessfaces:
+ for key in face.edge_keys:
+ if not face in edge_sharing_list[key]:
+ edge_sharing_list[key].append(face) # mark this face as sharing this edge
+
+ return edge_sharing_list
def find_edges( mesh, key ):
- """ Temp replacement for mesh.findEdges().
- This is painfully slow.
- """
- for edge in mesh.edges:
- v = edge.vertices
- if key[0] == v[0] and key[1] == v[1]:
- return edge.index
+ """ Temp replacement for mesh.findEdges().
+ This is painfully slow.
+ """
+ for edge in mesh.edges:
+ v = edge.vertices
+ if key[0] == v[0] and key[1] == v[1]:
+ return edge.index
def add_face_to_smoothgroup( mesh, face, edge_sharing_list, smoothgroup ):
-
- if face in smoothgroup.faces:
- return
-
- smoothgroup.add_face(face)
-
- for key in face.edge_keys:
-
- edge_id = find_edges(mesh, key)
-
- if edge_id != None:
-
- # not sharp
- if not( mesh.edges[edge_id].use_edge_sharp):
-
- for shared_face in edge_sharing_list[key]:
- if shared_face != face:
- # recursive
- add_face_to_smoothgroup( mesh, shared_face, edge_sharing_list, smoothgroup )
- # sharp
- else:
- for shared_face in edge_sharing_list[key]:
- if shared_face != face:
- smoothgroup.add_neighbor_face( shared_face )
+
+ if face in smoothgroup.faces:
+ return
+
+ smoothgroup.add_face(face)
+
+ for key in face.edge_keys:
+
+ edge_id = find_edges(mesh, key)
+
+ if edge_id != None:
+
+ # not sharp
+ if not( mesh.edges[edge_id].use_edge_sharp):
+
+ for shared_face in edge_sharing_list[key]:
+ if shared_face != face:
+ # recursive
+ add_face_to_smoothgroup( mesh, shared_face, edge_sharing_list, smoothgroup )
+ # sharp
+ else:
+ for shared_face in edge_sharing_list[key]:
+ if shared_face != face:
+ smoothgroup.add_neighbor_face( shared_face )
def determine_smoothgroup_for_face( mesh, face, edge_sharing_list, smoothgroup_list ):
-
- for group in smoothgroup_list:
- if (face in group.faces):
- return
-
- smoothgroup = SmoothingGroup();
- add_face_to_smoothgroup( mesh, face, edge_sharing_list, smoothgroup )
-
- if not smoothgroup in smoothgroup_list:
- smoothgroup_list.append( smoothgroup )
+
+ for group in smoothgroup_list:
+ if (face in group.faces):
+ return
+
+ smoothgroup = SmoothingGroup();
+ add_face_to_smoothgroup( mesh, face, edge_sharing_list, smoothgroup )
+
+ if not smoothgroup in smoothgroup_list:
+ smoothgroup_list.append( smoothgroup )
def build_neighbors_tree( smoothgroup_list ):
- for group in smoothgroup_list:
- for face in group.neighboring_faces:
- for neighbor_group in smoothgroup_list:
- if neighbor_group.contains_face( face ) and neighbor_group not in group.neighboring_groups:
- group.make_neighbor( neighbor_group )
- neighbor_group.make_neighbor( group )
+ for group in smoothgroup_list:
+ for face in group.neighboring_faces:
+ for neighbor_group in smoothgroup_list:
+ if neighbor_group.contains_face( face ) and neighbor_group not in group.neighboring_groups:
+ group.make_neighbor( neighbor_group )
+ neighbor_group.make_neighbor( group )
#===========================================================================
# parse_smooth_groups
#===========================================================================
def parse_smooth_groups( mesh ):
-
- print("Parsing smooth groups...")
-
- t = time.clock()
- smoothgroup_list = []
- edge_sharing_list = determine_edge_sharing(mesh)
- #print("faces:",len(mesh.tessfaces))
- interval = math.floor(len(mesh.tessfaces) / 100)
- if interval == 0: #if the faces are few do this
- interval = math.floor(len(mesh.tessfaces) / 10)
- #print("FACES:",len(mesh.tessfaces),"//100 =" "interval:",interval)
- for face in mesh.tessfaces:
- #print(dir(face))
- determine_smoothgroup_for_face(mesh, face, edge_sharing_list, smoothgroup_list)
- # progress indicator, writes to console without scrolling
- if face.index > 0 and (face.index % interval) == 0:
- print("Processing... {}%\r".format( int(face.index / len(mesh.tessfaces) * 100) ), end='')
- sys.stdout.flush()
- print("Completed" , ' '*20)
-
- verbose("len(smoothgroup_list)={}".format(len(smoothgroup_list)))
-
- build_neighbors_tree(smoothgroup_list)
-
- for group in smoothgroup_list:
- group.get_valid_smoothgroup_id()
-
- print("Smooth group parsing completed in {:.2f}s".format(time.clock() - t))
- return smoothgroup_list
+
+ print("Parsing smooth groups...")
+
+ t = time.clock()
+ smoothgroup_list = []
+ edge_sharing_list = determine_edge_sharing(mesh)
+ #print("faces:",len(mesh.tessfaces))
+ interval = math.floor(len(mesh.tessfaces) / 100)
+ if interval == 0: #if the faces are few do this
+ interval = math.floor(len(mesh.tessfaces) / 10)
+ #print("FACES:",len(mesh.tessfaces),"//100 =" "interval:",interval)
+ for face in mesh.tessfaces:
+ #print(dir(face))
+ determine_smoothgroup_for_face(mesh, face, edge_sharing_list, smoothgroup_list)
+ # progress indicator, writes to console without scrolling
+ if face.index > 0 and (face.index % interval) == 0:
+ print("Processing... {}%\r".format( int(face.index / len(mesh.tessfaces) * 100) ), end='')
+ sys.stdout.flush()
+ print("Completed" , ' '*20)
+
+ verbose("len(smoothgroup_list)={}".format(len(smoothgroup_list)))
+
+ build_neighbors_tree(smoothgroup_list)
+
+ for group in smoothgroup_list:
+ group.get_valid_smoothgroup_id()
+
+ print("Smooth group parsing completed in {:.2f}s".format(time.clock() - t))
+ return smoothgroup_list
#===========================================================================
# http://en.wikibooks.org/wiki/Blender_3D:_Blending_Into_Python/Cookbook#Triangulate_NMesh
# blender 2.50 format using the Operators/command convert the mesh to tri mesh
#===========================================================================
def triangulate_mesh( object ):
-
- verbose(header("triangulateNMesh"))
- #print(type(object))
- scene = bpy.context.scene
-
- me_ob = object.copy()
- me_ob.data = object.to_mesh(bpy.context.scene, True, 'PREVIEW') #write data object
- bpy.context.scene.objects.link(me_ob)
- bpy.context.scene.update()
- bpy.ops.object.mode_set(mode='OBJECT')
- for i in scene.objects:
- i.select = False # deselect all objects
-
- me_ob.select = True
- scene.objects.active = me_ob
-
- print("Copy and Convert mesh just incase any way...")
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')# select all the face/vertex/edge
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.quads_convert_to_tris()
- bpy.context.scene.update()
-
- bpy.ops.object.mode_set(mode='OBJECT')
-
- bpy.context.scene.udk_option_triangulate = True
-
- verbose("Triangulated mesh")
-
- me_ob.data = me_ob.to_mesh(bpy.context.scene, True, 'PREVIEW') #write data object
- bpy.context.scene.update()
- return me_ob
+
+ verbose(header("triangulateNMesh"))
+ #print(type(object))
+ scene = bpy.context.scene
+
+ me_ob = object.copy()
+ me_ob.data = object.to_mesh(bpy.context.scene, True, 'PREVIEW') #write data object
+ bpy.context.scene.objects.link(me_ob)
+ bpy.context.scene.update()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for i in scene.objects:
+ i.select = False # deselect all objects
+
+ me_ob.select = True
+ scene.objects.active = me_ob
+
+ print("Copy and Convert mesh just incase any way...")
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')# select all the face/vertex/edge
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.quads_convert_to_tris()
+ bpy.context.scene.update()
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ bpy.context.scene.udk_option_triangulate = True
+
+ verbose("Triangulated mesh")
+
+ me_ob.data = me_ob.to_mesh(bpy.context.scene, True, 'PREVIEW') #write data object
+ bpy.context.scene.update()
+ return me_ob
#copy mesh data and then merge them into one object
def meshmerge(selectedobjects):
- bpy.ops.object.mode_set(mode='OBJECT')
- cloneobjects = []
+ bpy.ops.object.mode_set(mode='OBJECT') #object mode and not edit mode
+ cloneobjects = [] #object holder for copying object data
if len(selectedobjects) > 1:
- print("selectedobjects:",len(selectedobjects))
+ print("selectedobjects:",len(selectedobjects)) #print select object
count = 0 #reset count
- for count in range(len( selectedobjects)):
+ for count in range(len( selectedobjects)):
#print("Index:",count)
if selectedobjects[count] != None:
me_da = selectedobjects[count].data.copy() #copy data
me_ob = selectedobjects[count].copy() #copy object
#note two copy two types else it will use the current data or mesh
- me_ob.data = me_da
+ me_ob.data = me_da #assign the data
bpy.context.scene.objects.link(me_ob)#link the object to the scene #current object location
- print("Index:",count,"clone object",me_ob.name)
- cloneobjects.append(me_ob)
- #bpy.ops.object.mode_set(mode='OBJECT')
+ print("Index:",count,"clone object",me_ob.name) #print clone object
+ cloneobjects.append(me_ob) #add object to the array
for i in bpy.data.objects: i.select = False #deselect all objects
count = 0 #reset count
- #bpy.ops.object.mode_set(mode='OBJECT')
+ #begin merging the mesh together as one
for count in range(len( cloneobjects)):
if count == 0:
bpy.context.scene.objects.active = cloneobjects[count]
print("Set Active Object:",cloneobjects[count].name)
cloneobjects[count].select = True
- bpy.ops.object.join()
+ bpy.ops.object.join() #join object together
if len(cloneobjects) > 1:
bpy.types.Scene.udk_copy_merge = True
return cloneobjects[0]
-
+
#sort the mesh center top list and not center at the last array. Base on order while select to merge mesh to make them center.
def sortmesh(selectmesh):
- print("MESH SORTING...")
- centermesh = []
- notcentermesh = []
- for countm in range(len(selectmesh)):
- if selectmesh[countm].location.x == 0 and selectmesh[countm].location.y == 0 and selectmesh[countm].location.z == 0:
- centermesh.append(selectmesh[countm])
- else:
- notcentermesh.append(selectmesh[countm])
- selectmesh = []
- for countm in range(len(centermesh)):
- selectmesh.append(centermesh[countm])
- for countm in range(len(notcentermesh)):
- selectmesh.append(notcentermesh[countm])
- if len(selectmesh) == 1:
- return selectmesh[0]
- else:
- return meshmerge(selectmesh)
+ print("MESH SORTING...")
+ centermesh = []
+ notcentermesh = []
+ for countm in range(len(selectmesh)):
+ #if object are center add here
+ if selectmesh[countm].location.x == 0 and selectmesh[countm].location.y == 0 and selectmesh[countm].location.z == 0:
+ centermesh.append(selectmesh[countm])
+ else:#if not add here for not center
+ notcentermesh.append(selectmesh[countm])
+ selectmesh = []
+ #add mesh object in order for merge object
+ for countm in range(len(centermesh)):
+ selectmesh.append(centermesh[countm])
+ for countm in range(len(notcentermesh)):
+ selectmesh.append(notcentermesh[countm])
+ if len(selectmesh) == 1: #if there one mesh just do some here
+ return selectmesh[0] #return object mesh
+ else:
+ return meshmerge(selectmesh) #return merge object mesh
#===========================================================================
# parse_mesh
#===========================================================================
def parse_mesh( mesh, psk ):
- #bpy.ops.object.mode_set(mode='OBJECT')
- #error ? on commands for select object?
- print(header("MESH", 'RIGHT'))
- print("Mesh object:", mesh.name)
- scene = bpy.context.scene
- for i in scene.objects: i.select = False # deselect all objects
- scene.objects.active = mesh
- setmesh = mesh
- mesh = triangulate_mesh(mesh)
- if bpy.types.Scene.udk_copy_merge == True:
- bpy.context.scene.objects.unlink(setmesh)
- #print("FACES----:",len(mesh.data.tessfaces))
- verbose("Working mesh object: {}".format(mesh.name))
-
- #collect a list of the material names
- print("Materials...")
-
- mat_slot_index = 0
-
- for slot in mesh.material_slots:
-
- print(" Material {} '{}'".format(mat_slot_index, slot.name))
- MaterialName.append(slot.name)
- #if slot.material.texture_slots[0] != None:
- #if slot.material.texture_slots[0].texture.image.filepath != None:
- #print(" Texture path {}".format(slot.material.texture_slots[0].texture.image.filepath))
- #create the current material
- v_material = psk.GetMatByIndex(mat_slot_index)
- v_material.MaterialName = slot.name
- v_material.TextureIndex = mat_slot_index
- v_material.AuxMaterial = mat_slot_index
- mat_slot_index += 1
- verbose(" PSK index {}".format(v_material.TextureIndex))
-
- #END slot in mesh.material_slots
-
- # object_mat = mesh.materials[0]
- #object_material_index = mesh.active_material_index
- #FIXME ^ this is redundant due to "= face.material_index" in face loop
-
- wedges = ObjMap()
- points = ObjMap()
- points_linked = {}
-
- discarded_face_count = 0
-
- smoothgroup_list = parse_smooth_groups(mesh.data)
-
- print("{} faces".format(len(mesh.data.tessfaces)))
-
- print("Smooth groups active:", bpy.context.scene.udk_option_smoothing_groups)
-
- for face in mesh.data.tessfaces:
-
- smoothgroup_id = 0x80000000
-
- for smooth_group in smoothgroup_list:
- if smooth_group.contains_face(face):
- smoothgroup_id = smooth_group.id
- break
-
- #print ' -- Dumping UVs -- '
- #print current_face.uv_textures
- # modified by VendorX
- object_material_index = face.material_index
-
- if len(face.vertices) != 3:
- raise Error("Non-triangular face (%i)" % len(face.vertices))
-
- #RG - apparently blender sometimes has problems when you do quad to triangle
- # conversion, and ends up creating faces that have only TWO points -
- # one of the points is simply in the vertex list for the face twice.
- # This is bad, since we can't get a real face normal for a LINE, we need
- # a plane for this. So, before we add the face to the list of real faces,
- # ensure that the face is actually a plane, and not a line. If it is not
- # planar, just discard it and notify the user in the console after we're
- # done dumping the rest of the faces
-
- if not is_1d_face(face, mesh.data):
-
- wedge_list = []
- vect_list = []
-
- #get or create the current material
- psk.GetMatByIndex(object_material_index)
-
- face_index = face.index
- has_uv = False
- face_uv = None
-
- if len(mesh.data.uv_textures) > 0:
- has_uv = True
- uv_layer = mesh.data.tessface_uv_textures.active
- face_uv = uv_layer.data[face_index]
- #size(data) is number of texture faces. Each face has UVs
- #print("DATA face uv: ",len(faceUV.uv), " >> ",(faceUV.uv[0][0]))
-
- for i in range(3):
- vert_index = face.vertices[i]
- vert = mesh.data.vertices[vert_index]
- uv = []
- #assumes 3 UVs Per face (for now)
- if (has_uv):
- if len(face_uv.uv) != 3:
- print("WARNING: face has more or less than 3 UV coordinates - writing 0,0...")
- uv = [0.0, 0.0]
- else:
- uv = [face_uv.uv[i][0],face_uv.uv[i][1]] #OR bottom works better # 24 for cube
- else:
- #print ("No UVs?")
- uv = [0.0, 0.0]
-
- #flip V coordinate because UEd requires it and DOESN'T flip it on its own like it
- #does with the mesh Y coordinates. this is otherwise known as MAGIC-2
- uv[1] = 1.0 - uv[1]
-
- # clamp UV coords if udk_option_clamp_uv is True
- if bpy.context.scene.udk_option_clamp_uv:
- if (uv[0] > 1):
- uv[0] = 1
- if (uv[0] < 0):
- uv[0] = 0
- if (uv[1] > 1):
- uv[1] = 1
- if (uv[1] < 0):
- uv[1] = 0
-
- # RE - Append untransformed vector (for normal calc below)
- # TODO: convert to Blender.Mathutils
- vect_list.append( FVector(vert.co.x, vert.co.y, vert.co.z) )
-
- # Transform position for export
- #vpos = vert.co * object_material_index
- vpos = mesh.matrix_local * vert.co
-
- # Create the point
- p = VPoint()
- p.Point.X = vpos.x
- p.Point.Y = vpos.y
- p.Point.Z = vpos.z
- if bpy.context.scene.udk_option_smoothing_groups:#is this necessary?
- p.SmoothGroup = smoothgroup_id
-
- lPoint = VPointSimple()
- lPoint.Point.X = vpos.x
- lPoint.Point.Y = vpos.y
- lPoint.Point.Z = vpos.z
-
- if lPoint in points_linked:
- if not(p in points_linked[lPoint]):
- points_linked[lPoint].append(p)
- else:
- points_linked[lPoint] = [p]
-
- # Create the wedge
- w = VVertex()
- w.MatIndex = object_material_index
- w.PointIndex = points.get(p) # store keys
- w.U = uv[0]
- w.V = uv[1]
- if bpy.context.scene.udk_option_smoothing_groups:#is this necessary?
- w.SmoothGroup = smoothgroup_id
- index_wedge = wedges.get(w)
- wedge_list.append(index_wedge)
-
- #print results
- #print("result PointIndex={}, U={:.6f}, V={:.6f}, wedge_index={}".format(
- # w.PointIndex,
- # w.U,
- # w.V,
- # index_wedge))
-
- #END for i in range(3)
-
- # Determine face vertex order
-
- # TODO: convert to Blender.Mathutils
- # get normal from blender
- no = face.normal
- # convert to FVector
- norm = FVector(no[0], no[1], no[2])
- # Calculate the normal of the face in blender order
- tnorm = vect_list[1].sub(vect_list[0]).cross(vect_list[2].sub(vect_list[1]))
- # RE - dot the normal from blender order against the blender normal
- # this gives the product of the two vectors' lengths along the blender normal axis
- # all that matters is the sign
- dot = norm.dot(tnorm)
-
- tri = VTriangle()
- # RE - magic: if the dot product above > 0, order the vertices 2, 1, 0
- # if the dot product above < 0, order the vertices 0, 1, 2
- # if the dot product is 0, then blender's normal is coplanar with the face
- # and we cannot deduce which side of the face is the outside of the mesh
- if dot > 0:
- (tri.WedgeIndex2, tri.WedgeIndex1, tri.WedgeIndex0) = wedge_list
- elif dot < 0:
- (tri.WedgeIndex0, tri.WedgeIndex1, tri.WedgeIndex2) = wedge_list
- else:
- dindex0 = face.vertices[0];
- dindex1 = face.vertices[1];
- dindex2 = face.vertices[2];
-
- mesh.data.vertices[dindex0].select = True
- mesh.data.vertices[dindex1].select = True
- mesh.data.vertices[dindex2].select = True
-
- raise Error("Normal coplanar with face! points:", mesh.data.vertices[dindex0].co, mesh.data.vertices[dindex1].co, mesh.data.vertices[dindex2].co)
-
- face.select = True
- #print("smooth:",(current_face.use_smooth))
- #not sure if this right
- #tri.SmoothingGroups
- if face.use_smooth == True:
- tri.SmoothingGroups = 1
- else:
- tri.SmoothingGroups = 0
-
- #tri.SmoothingGroups = 1
- tri.MatIndex = object_material_index
-
- if bpy.context.scene.udk_option_smoothing_groups:
- tri.SmoothingGroups = smoothgroup_id
-
- psk.AddFace(tri)
-
- #END if not is_1d_face(current_face, mesh.data)
-
- else:
- discarded_face_count += 1
-
- #END face in mesh.data.faces
-
- print("{} points".format(len(points.dict)))
-
- for point in points.items():
- psk.AddPoint(point)
-
- if len(points.dict) > 32767:
- raise Error("Mesh vertex limit exceeded! {} > 32767".format(len(points.dict)))
-
- print("{} wedges".format(len(wedges.dict)))
-
- for wedge in wedges.items():
- psk.AddWedge(wedge)
-
- # alert the user to degenerate face issues
- if discarded_face_count > 0:
- print("WARNING: Mesh contained degenerate faces (non-planar)")
- print(" Discarded {} faces".format(discarded_face_count))
-
- #RG - walk through the vertex groups and find the indexes into the PSK points array
- #for them, then store that index and the weight as a tuple in a new list of
- #verts for the group that we can look up later by bone name, since Blender matches
- #verts to bones for influences by having the VertexGroup named the same thing as
- #the bone
-
- #[print(x, len(points_linked[x])) for x in points_linked]
- #print("pointsindex length ",len(points_linked))
- #vertex group
-
- # all vertex groups of the mesh (obj)...
- for obj_vertex_group in mesh.vertex_groups:
-
- #print(" bone group build:",obj_vertex_group.name)#print bone name
- #print(dir(obj_vertex_group))
- verbose("obj_vertex_group.name={}".format(obj_vertex_group.name))
-
- vertex_list = []
-
- # all vertices in the mesh...
- for vertex in mesh.data.vertices:
- #print(dir(vertex))
- # all groups this vertex is a member of...
- for vgroup in vertex.groups:
-
- if vgroup.group == obj_vertex_group.index:
-
- vertex_weight = vgroup.weight
- p = VPointSimple()
- vpos = mesh.matrix_local * vertex.co
- p.Point.X = vpos.x
- p.Point.Y = vpos.y
- p.Point.Z = vpos.z
-
- for point in points_linked[p]:
- point_index = points.get(point) #point index
- v_item = (point_index, vertex_weight)
- vertex_list.append(v_item)
-
- #bone name, [point id and wieght]
- #print("Add Vertex Group:",obj_vertex_group.name, " No. Points:",len(vertex_list))
- psk.VertexGroups[obj_vertex_group.name] = vertex_list
-
- # remove the temporary triangulated mesh
- if bpy.context.scene.udk_option_triangulate == True:
- verbose("Removing temporary triangle mesh: {}".format(mesh.name))
- bpy.ops.object.mode_set(mode='OBJECT') # OBJECT mode
- mesh.parent = None # unparent to avoid phantom links
- bpy.context.scene.objects.unlink(mesh) # unlink
+ #bpy.ops.object.mode_set(mode='OBJECT')
+ #error ? on commands for select object?
+ print(header("MESH", 'RIGHT'))
+ print("Mesh object:", mesh.name)
+ scene = bpy.context.scene
+ for i in scene.objects: i.select = False # deselect all objects
+ scene.objects.active = mesh
+ setmesh = mesh
+ mesh = triangulate_mesh(mesh)
+ if bpy.types.Scene.udk_copy_merge == True:
+ bpy.context.scene.objects.unlink(setmesh)
+ #print("FACES----:",len(mesh.data.tessfaces))
+ verbose("Working mesh object: {}".format(mesh.name))
+
+ #collect a list of the material names
+ print("Materials...")
+
+ mat_slot_index = 0
+
+ for slot in mesh.material_slots:
+
+ print(" Material {} '{}'".format(mat_slot_index, slot.name))
+ MaterialName.append(slot.name)
+ #if slot.material.texture_slots[0] != None:
+ #if slot.material.texture_slots[0].texture.image.filepath != None:
+ #print(" Texture path {}".format(slot.material.texture_slots[0].texture.image.filepath))
+ #create the current material
+ v_material = psk.GetMatByIndex(mat_slot_index)
+ v_material.MaterialName = slot.name
+ v_material.TextureIndex = mat_slot_index
+ v_material.AuxMaterial = mat_slot_index
+ mat_slot_index += 1
+ verbose(" PSK index {}".format(v_material.TextureIndex))
+
+ #END slot in mesh.material_slots
+
+ # object_mat = mesh.materials[0]
+ #object_material_index = mesh.active_material_index
+ #FIXME ^ this is redundant due to "= face.material_index" in face loop
+
+ wedges = ObjMap()
+ points = ObjMap() #vertex
+ points_linked = {}
+
+ discarded_face_count = 0
+
+ smoothgroup_list = parse_smooth_groups(mesh.data)
+
+ print("{} faces".format(len(mesh.data.tessfaces)))
+
+ print("Smooth groups active:", bpy.context.scene.udk_option_smoothing_groups)
+
+ for face in mesh.data.tessfaces:
+
+ smoothgroup_id = 0x80000000
+
+ for smooth_group in smoothgroup_list:
+ if smooth_group.contains_face(face):
+ smoothgroup_id = smooth_group.id
+ break
+
+ #print ' -- Dumping UVs -- '
+ #print current_face.uv_textures
+ # modified by VendorX
+ object_material_index = face.material_index
+
+ if len(face.vertices) != 3:
+ raise Error("Non-triangular face (%i)" % len(face.vertices))
+
+ #RG - apparently blender sometimes has problems when you do quad to triangle
+ # conversion, and ends up creating faces that have only TWO points -
+ # one of the points is simply in the vertex list for the face twice.
+ # This is bad, since we can't get a real face normal for a LINE, we need
+ # a plane for this. So, before we add the face to the list of real faces,
+ # ensure that the face is actually a plane, and not a line. If it is not
+ # planar, just discard it and notify the user in the console after we're
+ # done dumping the rest of the faces
+
+ if not is_1d_face(face, mesh.data):
+
+ wedge_list = []
+ vect_list = []
+
+ #get or create the current material
+ psk.GetMatByIndex(object_material_index)
+
+ face_index = face.index
+ has_uv = False
+ face_uv = None
+
+ if len(mesh.data.uv_textures) > 0:
+ has_uv = True
+ uv_layer = mesh.data.tessface_uv_textures.active
+ face_uv = uv_layer.data[face_index]
+ #size(data) is number of texture faces. Each face has UVs
+ #print("DATA face uv: ",len(faceUV.uv), " >> ",(faceUV.uv[0][0]))
+
+ for i in range(3):
+ vert_index = face.vertices[i]
+ vert = mesh.data.vertices[vert_index]
+ uv = []
+ #assumes 3 UVs Per face (for now)
+ if (has_uv):
+ if len(face_uv.uv) != 3:
+ print("WARNING: face has more or less than 3 UV coordinates - writing 0,0...")
+ uv = [0.0, 0.0]
+ else:
+ uv = [face_uv.uv[i][0],face_uv.uv[i][1]] #OR bottom works better # 24 for cube
+ else:
+ #print ("No UVs?")
+ uv = [0.0, 0.0]
+
+ #flip V coordinate because UEd requires it and DOESN'T flip it on its own like it
+ #does with the mesh Y coordinates. this is otherwise known as MAGIC-2
+ uv[1] = 1.0 - uv[1]
+
+ # clamp UV coords if udk_option_clamp_uv is True
+ if bpy.context.scene.udk_option_clamp_uv:
+ if (uv[0] > 1):
+ uv[0] = 1
+ if (uv[0] < 0):
+ uv[0] = 0
+ if (uv[1] > 1):
+ uv[1] = 1
+ if (uv[1] < 0):
+ uv[1] = 0
+
+ # RE - Append untransformed vector (for normal calc below)
+ # TODO: convert to Blender.Mathutils
+ vect_list.append( FVector(vert.co.x, vert.co.y, vert.co.z) )
+
+ # Transform position for export
+ #vpos = vert.co * object_material_index
+
+ #should fixed this!!
+ vpos = mesh.matrix_local * vert.co
+ if bpy.context.scene.udk_option_scale < 0 or bpy.context.scene.udk_option_scale > 1:
+ #print("OK!")
+ vpos.x = vpos.x * bpy.context.scene.udk_option_scale
+ vpos.y = vpos.y * bpy.context.scene.udk_option_scale
+ vpos.z = vpos.z * bpy.context.scene.udk_option_scale
+ #print("scale pos:", vpos)
+ # Create the point
+ p = VPoint()
+ p.Point.X = vpos.x
+ p.Point.Y = vpos.y
+ p.Point.Z = vpos.z
+ if bpy.context.scene.udk_option_smoothing_groups:#is this necessary?
+ p.SmoothGroup = smoothgroup_id
+
+ lPoint = VPointSimple()
+ lPoint.Point.X = vpos.x
+ lPoint.Point.Y = vpos.y
+ lPoint.Point.Z = vpos.z
+
+ if lPoint in points_linked:
+ if not(p in points_linked[lPoint]):
+ points_linked[lPoint].append(p)
+ else:
+ points_linked[lPoint] = [p]
+
+ # Create the wedge
+ w = VVertex()
+ w.MatIndex = object_material_index
+ w.PointIndex = points.get(p) # store keys
+ w.U = uv[0]
+ w.V = uv[1]
+ if bpy.context.scene.udk_option_smoothing_groups:#is this necessary?
+ w.SmoothGroup = smoothgroup_id
+ index_wedge = wedges.get(w)
+ wedge_list.append(index_wedge)
+
+ #print results
+ #print("result PointIndex={}, U={:.6f}, V={:.6f}, wedge_index={}".format(
+ # w.PointIndex,
+ # w.U,
+ # w.V,
+ # index_wedge))
+
+ #END for i in range(3)
+
+ # Determine face vertex order
+
+ # TODO: convert to Blender.Mathutils
+ # get normal from blender
+ no = face.normal
+ # convert to FVector
+ norm = FVector(no[0], no[1], no[2])
+ # Calculate the normal of the face in blender order
+ tnorm = vect_list[1].sub(vect_list[0]).cross(vect_list[2].sub(vect_list[1]))
+ # RE - dot the normal from blender order against the blender normal
+ # this gives the product of the two vectors' lengths along the blender normal axis
+ # all that matters is the sign
+ dot = norm.dot(tnorm)
+
+ tri = VTriangle()
+ # RE - magic: if the dot product above > 0, order the vertices 2, 1, 0
+ # if the dot product above < 0, order the vertices 0, 1, 2
+ # if the dot product is 0, then blender's normal is coplanar with the face
+ # and we cannot deduce which side of the face is the outside of the mesh
+ if dot > 0:
+ (tri.WedgeIndex2, tri.WedgeIndex1, tri.WedgeIndex0) = wedge_list
+ elif dot < 0:
+ (tri.WedgeIndex0, tri.WedgeIndex1, tri.WedgeIndex2) = wedge_list
+ else:
+ dindex0 = face.vertices[0];
+ dindex1 = face.vertices[1];
+ dindex2 = face.vertices[2];
+
+ mesh.data.vertices[dindex0].select = True
+ mesh.data.vertices[dindex1].select = True
+ mesh.data.vertices[dindex2].select = True
+
+ raise Error("Normal coplanar with face! points:", mesh.data.vertices[dindex0].co, mesh.data.vertices[dindex1].co, mesh.data.vertices[dindex2].co)
+
+ face.select = True
+ #print("smooth:",(current_face.use_smooth))
+ #not sure if this right
+ #tri.SmoothingGroups
+ if face.use_smooth == True:
+ tri.SmoothingGroups = 1
+ else:
+ tri.SmoothingGroups = 0
+
+ #tri.SmoothingGroups = 1
+ tri.MatIndex = object_material_index
+
+ if bpy.context.scene.udk_option_smoothing_groups:
+ tri.SmoothingGroups = smoothgroup_id
+
+ psk.AddFace(tri)
+
+ #END if not is_1d_face(current_face, mesh.data)
+
+ else:
+ discarded_face_count += 1
+
+ #END face in mesh.data.faces
+
+ print("{} points".format(len(points.dict)))
+
+ for point in points.items():
+ psk.AddPoint(point)
+
+ if len(points.dict) > 32767:
+ raise Error("Mesh vertex limit exceeded! {} > 32767".format(len(points.dict)))
+
+ print("{} wedges".format(len(wedges.dict)))
+
+ for wedge in wedges.items():
+ psk.AddWedge(wedge)
+
+ # alert the user to degenerate face issues
+ if discarded_face_count > 0:
+ print("WARNING: Mesh contained degenerate faces (non-planar)")
+ print(" Discarded {} faces".format(discarded_face_count))
+
+ #RG - walk through the vertex groups and find the indexes into the PSK points array
+ #for them, then store that index and the weight as a tuple in a new list of
+ #verts for the group that we can look up later by bone name, since Blender matches
+ #verts to bones for influences by having the VertexGroup named the same thing as
+ #the bone
+
+ #[print(x, len(points_linked[x])) for x in points_linked]
+ #print("pointsindex length ",len(points_linked))
+ #vertex group
+
+ # all vertex groups of the mesh (obj)...
+ for obj_vertex_group in mesh.vertex_groups:
+
+ #print(" bone group build:",obj_vertex_group.name)#print bone name
+ #print(dir(obj_vertex_group))
+ verbose("obj_vertex_group.name={}".format(obj_vertex_group.name))
+
+ vertex_list = []
+
+ # all vertices in the mesh...
+ for vertex in mesh.data.vertices:
+ #print(dir(vertex))
+ # all groups this vertex is a member of...
+ for vgroup in vertex.groups:
+ if vgroup.group == obj_vertex_group.index:
+ vertex_weight = vgroup.weight
+ p = VPointSimple()
+ vpos = mesh.matrix_local * vertex.co
+ if bpy.context.scene.udk_option_scale < 0 or bpy.context.scene.udk_option_scale > 1:
+ vpos.x = vpos.x * bpy.context.scene.udk_option_scale
+ vpos.y = vpos.y * bpy.context.scene.udk_option_scale
+ vpos.z = vpos.z * bpy.context.scene.udk_option_scale
+ p.Point.X = vpos.x
+ p.Point.Y = vpos.y
+ p.Point.Z = vpos.z
+
+ for point in points_linked[p]:
+ point_index = points.get(point) #point index
+ v_item = (point_index, vertex_weight)
+ vertex_list.append(v_item)
+
+ #bone name, [point id and wieght]
+ #print("Add Vertex Group:",obj_vertex_group.name, " No. Points:",len(vertex_list))
+ psk.VertexGroups[obj_vertex_group.name] = vertex_list
+
+ # remove the temporary triangulated mesh
+ if bpy.context.scene.udk_option_triangulate == True:
+ verbose("Removing temporary triangle mesh: {}".format(mesh.name))
+ bpy.ops.object.mode_set(mode='OBJECT') # OBJECT mode
+ mesh.parent = None # unparent to avoid phantom links
+ bpy.context.scene.objects.unlink(mesh) # unlink
#===========================================================================
# Collate bones that belong to the UDK skeletal mesh
#===========================================================================
def parse_armature( armature, psk, psa ):
-
- print(header("ARMATURE", 'RIGHT'))
- verbose("Armature object: {} Armature data: {}".format(armature.name, armature.data.name))
-
- # generate a list of root bone candidates
- root_candidates = [b for b in armature.data.bones if b.parent == None and b.use_deform == True]
-
- # should be a single, unambiguous result
- if len(root_candidates) == 0:
- raise Error("Cannot find root for UDK bones. The root bone must use deform.")
-
- if len(root_candidates) > 1:
- raise Error("Ambiguous root for UDK. More than one root bone is using deform.")
-
- # prep for bone collection
- udk_root_bone = root_candidates[0]
- udk_bones = []
- BoneUtil.static_bone_id = 0 # replaces global
-
- # traverse bone chain
- print("{: <3} {: <48} {: <20}".format("ID", "Bone", "Status"))
- print()
- recurse_bone(udk_root_bone, udk_bones, psk, psa, 0, armature.matrix_local)
-
- # final validation
- if len(udk_bones) < 3:
- raise Error("Less than three bones may crash UDK (legacy issue?)")
-
- # return a list of bones making up the entire udk skel
- # this is passed to parse_animation instead of working from keyed bones in the action
- return udk_bones
+
+ print(header("ARMATURE", 'RIGHT'))
+ verbose("Armature object: {} Armature data: {}".format(armature.name, armature.data.name))
+
+ # generate a list of root bone candidates
+ root_candidates = [b for b in armature.data.bones if b.parent == None and b.use_deform == True]
+
+ # should be a single, unambiguous result
+ if len(root_candidates) == 0:
+ raise Error("Cannot find root for UDK bones. The root bone must use deform.")
+
+ if len(root_candidates) > 1:
+ raise Error("Ambiguous root for UDK. More than one root bone is using deform.")
+
+ # prep for bone collection
+ udk_root_bone = root_candidates[0]
+ udk_bones = []
+ BoneUtil.static_bone_id = 0 # replaces global
+
+ # traverse bone chain
+ print("{: <3} {: <48} {: <20}".format("ID", "Bone", "Status"))
+ print()
+ recurse_bone(udk_root_bone, udk_bones, psk, psa, 0, armature.matrix_local)
+
+ # final validation
+ if len(udk_bones) < 3:
+ raise Error("Less than three bones may crash UDK (legacy issue?)")
+
+ # return a list of bones making up the entire udk skel
+ # this is passed to parse_animation instead of working from keyed bones in the action
+ return udk_bones
#===========================================================================
-# bone current bone
-# bones bone list
-# psk the PSK file object
-# psa the PSA file object
+# bone current bone
+# bones bone list
+# psk the PSK file object
+# psa the PSA file object
# parent_id
# parent_matrix
-# indent text indent for recursive log
+# indent text indent for recursive log
#===========================================================================
def recurse_bone( bone, bones, psk, psa, parent_id, parent_matrix, indent="" ):
-
- status = "Ok"
-
- bones.append(bone);
-
- if not bone.use_deform:
- status = "No effect"
-
- # calc parented bone transform
- if bone.parent != None:
- quat = make_fquat(bone.matrix.to_quaternion())
- quat_parent = bone.parent.matrix.to_quaternion().inverted()
- parent_head = quat_parent * bone.parent.head
- parent_tail = quat_parent * bone.parent.tail
- translation = (parent_tail - parent_head) + bone.head
-
- # calc root bone transform
- else:
- translation = parent_matrix * bone.head # ARMATURE OBJECT Location
- rot_matrix = bone.matrix * parent_matrix.to_3x3() # ARMATURE OBJECT Rotation
- quat = make_fquat_default(rot_matrix.to_quaternion())
-
- bone_id = BoneUtil.static_bone_id # ALT VERS
- BoneUtil.static_bone_id += 1 # ALT VERS
-
- child_count = len(bone.children)
-
- psk.AddBone( make_vbone(bone.name, parent_id, child_count, quat, translation) )
- psa.StoreBone( make_namedbonebinary(bone.name, parent_id, child_count, quat, translation, 1) )
-
- #RG - dump influences for this bone - use the data we collected in the mesh dump phase to map our bones to vertex groups
- if bone.name in psk.VertexGroups:
-
- vertex_list = psk.VertexGroups[bone.name]
- #print("vertex list:", len(vertex_list), " of >" ,bone.name )
- for vertex_data in vertex_list:
-
- point_index = vertex_data[0]
- vertex_weight = vertex_data[1]
- influence = VRawBoneInfluence()
- influence.Weight = vertex_weight
- influence.BoneIndex = bone_id
- influence.PointIndex = point_index
- #print (" AddInfluence to vertex {}, weight={},".format(point_index, vertex_weight))
- psk.AddInfluence(influence)
-
- else:
- status = "No vertex group"
- #FIXME overwriting previous status error?
-
- print("{:<3} {:<48} {:<20}".format(bone_id, indent+bone.name, status))
-
- #bone.matrix_local
- #recursively dump child bones
-
- for child_bone in bone.children:
- recurse_bone(child_bone, bones, psk, psa, bone_id, parent_matrix, " "+indent)
+
+ status = "Ok"
+
+ bones.append(bone);
+
+ if not bone.use_deform:
+ status = "No effect"
+
+ # calc parented bone transform
+ if bone.parent != None:
+ quat = make_fquat(bone.matrix.to_quaternion())
+ quat_parent = bone.parent.matrix.to_quaternion().inverted()
+ parent_head = quat_parent * bone.parent.head
+ parent_tail = quat_parent * bone.parent.tail
+ translation = (parent_tail - parent_head) + bone.head
+
+ # calc root bone transform
+ else:
+ translation = parent_matrix * bone.head # ARMATURE OBJECT Location
+ rot_matrix = bone.matrix * parent_matrix.to_3x3() # ARMATURE OBJECT Rotation
+ quat = make_fquat_default(rot_matrix.to_quaternion())
+ #udk_option_scale bones here?
+ if bpy.context.scene.udk_option_scale < 0 or bpy.context.scene.udk_option_scale > 1:
+ translation.x = translation.x * bpy.context.scene.udk_option_scale
+ translation.y = translation.y * bpy.context.scene.udk_option_scale
+ translation.z = translation.z * bpy.context.scene.udk_option_scale
+ bone_id = BoneUtil.static_bone_id # ALT VERS
+ BoneUtil.static_bone_id += 1 # ALT VERS
+
+ child_count = len(bone.children)
+
+ psk.AddBone( make_vbone(bone.name, parent_id, child_count, quat, translation) )
+ psa.StoreBone( make_namedbonebinary(bone.name, parent_id, child_count, quat, translation, 1) )
+
+ #RG - dump influences for this bone - use the data we collected in the mesh dump phase to map our bones to vertex groups
+ if bone.name in psk.VertexGroups:
+ vertex_list = psk.VertexGroups[bone.name]
+ #print("vertex list:", len(vertex_list), " of >" ,bone.name )
+ for vertex_data in vertex_list:
+ point_index = vertex_data[0]
+ vertex_weight = vertex_data[1]
+ influence = VRawBoneInfluence()
+ influence.Weight = vertex_weight
+ influence.BoneIndex = bone_id
+ influence.PointIndex = point_index
+ #print (" AddInfluence to vertex {}, weight={},".format(point_index, vertex_weight))
+ psk.AddInfluence(influence)
+ else:
+ status = "No vertex group"
+ #FIXME overwriting previous status error?
+
+ print("{:<3} {:<48} {:<20}".format(bone_id, indent+bone.name, status))
+
+ #bone.matrix_local
+ #recursively dump child bones
+
+ for child_bone in bone.children:
+ recurse_bone(child_bone, bones, psk, psa, bone_id, parent_matrix, " "+indent)
# FIXME rename? remove?
class BoneUtil:
- static_bone_id = 0 # static property to replace global
+ static_bone_id = 0 # static property to replace global
#===========================================================================
-# armature the armature
-# udk_bones list of bones to be exported
-# actions_to_export list of actions to process for export
-# psa the PSA file object
+# armature the armature
+# udk_bones list of bones to be exported
+# actions_to_export list of actions to process for export
+# psa the PSA file object
#===========================================================================
def parse_animation( armature, udk_bones, actions_to_export, psa ):
-
- print(header("ANIMATION", 'RIGHT'))
-
- context = bpy.context
- anim_rate = context.scene.render.fps
-
- verbose("Armature object: {}".format(armature.name))
- print("Scene: {} FPS: {} Frames: {} to {}".format(context.scene.name, anim_rate, context.scene.frame_start, context.scene.frame_end))
- print("Processing {} action(s)".format(len(actions_to_export)))
- print()
- if armature.animation_data == None:
- print("None Actions Set! skipping...")
- return
- restoreAction = armature.animation_data.action # Q: is animation_data always valid?
-
- restoreFrame = context.scene.frame_current # we already do this in export_proxy, but we'll do it here too for now
- raw_frame_index = 0 # used to set FirstRawFrame, seperating actions in the raw keyframe array
-
- # action loop...
- for action in actions_to_export:
-
- # removed: check for armature with no animation; all it did was force you to add one
-
- if not len(action.fcurves):
- print("{} has no keys, skipping".format(action.name))
- continue
- '''
- if bpy.context.scene.udk_option_selectanimations:
- print("Action Set is selected!")
- bready = False
- for actionlist in bpy.context.scene.udkas_list:
- if actionlist.name == action.name and actionlist.bmatch == True and actionlist.bexport == True:
- bready = True
- print("Added Action Set:",action.name)
- break
- if bready == False:#don't export it
- print("Skipping Action Set:",action.name)
- continue
- '''
- # apply action to armature and update scene
- armature.animation_data.action = action
- context.scene.update()
-
- # min/max frames define range
- framemin, framemax = action.frame_range
- start_frame = int(framemin)
- end_frame = int(framemax)
- scene_range = range(start_frame, end_frame + 1)
- frame_count = len(scene_range)
-
- # create the AnimInfoBinary
- anim = AnimInfoBinary()
- anim.Name = action.name
- anim.Group = "" # unused?
- anim.NumRawFrames = frame_count
- anim.AnimRate = anim_rate
- anim.FirstRawFrame = raw_frame_index
-
- print("{}, frames {} to {} ({} frames)".format(action.name, start_frame, end_frame, frame_count))
-
- # removed: bone lookup table
-
- # build a list of pose bones relevant to the collated udk_bones
- # fixme: could be done once, prior to loop?
- udk_pose_bones = []
- for b in udk_bones:
- for pb in armature.pose.bones:
- if b.name == pb.name:
- udk_pose_bones.append(pb)
- break;
-
- # sort in the order the bones appear in the PSA file
- ordered_bones = {}
- ordered_bones = sorted([(psa.UseBone(b.name), b) for b in udk_pose_bones], key=operator.itemgetter(0))
-
- # NOTE: posebone.bone references the obj/edit bone
- # REMOVED: unique_bone_indexes is redundant?
-
- # frame loop...
- for i in range(frame_count):
-
- frame = scene_range[i]
-
- #verbose("FRAME {}".format(i), i) # test loop sampling
-
- # advance to frame (automatically updates the pose)
- context.scene.frame_set(frame)
-
- # compute the key for each bone
- for bone_data in ordered_bones:
-
- bone_index = bone_data[0]
- pose_bone = bone_data[1]
- pose_bone_matrix = mathutils.Matrix(pose_bone.matrix)
-
- if pose_bone.parent != None:
- pose_bone_parent_matrix = mathutils.Matrix(pose_bone.parent.matrix)
- pose_bone_matrix = pose_bone_parent_matrix.inverted() * pose_bone_matrix
-
- head = pose_bone_matrix.to_translation()
- quat = pose_bone_matrix.to_quaternion().normalized()
-
- if pose_bone.parent != None:
- quat = make_fquat(quat)
- else:
- quat = make_fquat_default(quat)
-
- vkey = VQuatAnimKey()
- vkey.Position.X = head.x
- vkey.Position.Y = head.y
- vkey.Position.Z = head.z
- vkey.Orientation = quat
-
- # frame delta = 1.0 / fps
- vkey.Time = 1.0 / float(anim_rate) # according to C++ header this is "disregarded"
-
- psa.AddRawKey(vkey)
-
- # END for bone_data in ordered_bones
-
- raw_frame_index += 1
-
- # END for i in range(frame_count)
-
- anim.TotalBones = len(ordered_bones) # REMOVED len(unique_bone_indexes)
- anim.TrackTime = float(frame_count) # frame_count/anim.AnimRate makes more sense, but this is what actually works in UDK
-
- verbose("anim.TotalBones={}, anim.TrackTime={}".format(anim.TotalBones, anim.TrackTime))
-
- psa.AddAnimation(anim)
-
- # END for action in actions
-
- # restore
- armature.animation_data.action = restoreAction
- context.scene.frame_set(restoreFrame)
+
+ print(header("ANIMATION", 'RIGHT'))
+
+ context = bpy.context
+ anim_rate = context.scene.render.fps
+
+ verbose("Armature object: {}".format(armature.name))
+ print("Scene: {} FPS: {} Frames: {} to {}".format(context.scene.name, anim_rate, context.scene.frame_start, context.scene.frame_end))
+ print("Processing {} action(s)".format(len(actions_to_export)))
+ print()
+ if armature.animation_data == None: #if animation data was not create for the armature it will skip the exporting action set(s)
+ print("None Actions Set! skipping...")
+ return
+ restoreAction = armature.animation_data.action # Q: is animation_data always valid?
+
+ restoreFrame = context.scene.frame_current # we already do this in export_proxy, but we'll do it here too for now
+ raw_frame_index = 0 # used to set FirstRawFrame, seperating actions in the raw keyframe array
+
+ # action loop...
+ for action in actions_to_export:
+
+ # removed: check for armature with no animation; all it did was force you to add one
+
+ if not len(action.fcurves):
+ print("{} has no keys, skipping".format(action.name))
+ continue
+ '''
+ if bpy.context.scene.udk_option_selectanimations:
+ print("Action Set is selected!")
+ bready = False
+ for actionlist in bpy.context.scene.udkas_list:
+ if actionlist.name == action.name and actionlist.bmatch == True and actionlist.bexport == True:
+ bready = True
+ print("Added Action Set:",action.name)
+ break
+ if bready == False:#don't export it
+ print("Skipping Action Set:",action.name)
+ continue
+ '''
+ # apply action to armature and update scene
+ # note if loop all actions that is not armature it will override and will break armature animation.
+ armature.animation_data.action = action
+ context.scene.update()
+
+ # min/max frames define range
+ framemin, framemax = action.frame_range
+ start_frame = int(framemin)
+ end_frame = int(framemax)
+ scene_range = range(start_frame, end_frame + 1)
+ frame_count = len(scene_range)
+
+ # create the AnimInfoBinary
+ anim = AnimInfoBinary()
+ anim.Name = action.name
+ anim.Group = "" # unused?
+ anim.NumRawFrames = frame_count
+ anim.AnimRate = anim_rate
+ anim.FirstRawFrame = raw_frame_index
+
+ print("{}, frames {} to {} ({} frames)".format(action.name, start_frame, end_frame, frame_count))
+
+ # removed: bone lookup table
+
+ # build a list of pose bones relevant to the collated udk_bones
+ # fixme: could be done once, prior to loop?
+ udk_pose_bones = []
+ for b in udk_bones:
+ for pb in armature.pose.bones:
+ if b.name == pb.name:
+ udk_pose_bones.append(pb)
+ break;
+
+ # sort in the order the bones appear in the PSA file
+ ordered_bones = {}
+ ordered_bones = sorted([(psa.UseBone(b.name), b) for b in udk_pose_bones], key=operator.itemgetter(0))
+
+ # NOTE: posebone.bone references the obj/edit bone
+ # REMOVED: unique_bone_indexes is redundant?
+
+ # frame loop...
+ for i in range(frame_count):
+
+ frame = scene_range[i]
+
+ #verbose("FRAME {}".format(i), i) # test loop sampling
+
+ # advance to frame (automatically updates the pose)
+ context.scene.frame_set(frame)
+
+ # compute the key for each bone
+ for bone_data in ordered_bones:
+
+ bone_index = bone_data[0]
+ pose_bone = bone_data[1]
+ pose_bone_matrix = mathutils.Matrix(pose_bone.matrix)
+
+ if pose_bone.parent != None:
+ pose_bone_parent_matrix = mathutils.Matrix(pose_bone.parent.matrix)
+ pose_bone_matrix = pose_bone_parent_matrix.inverted() * pose_bone_matrix
+
+ head = pose_bone_matrix.to_translation()
+ quat = pose_bone_matrix.to_quaternion().normalized()
+
+ if pose_bone.parent != None:
+ quat = make_fquat(quat)
+ else:
+ quat = make_fquat_default(quat)
+
+ #scale animation position here?
+ if bpy.context.scene.udk_option_scale < 0 or bpy.context.scene.udk_option_scale > 1:
+ head.x = head.x * bpy.context.scene.udk_option_scale
+ head.y = head.y * bpy.context.scene.udk_option_scale
+ head.z = head.z * bpy.context.scene.udk_option_scale
+
+ vkey = VQuatAnimKey()
+ vkey.Position.X = head.x
+ vkey.Position.Y = head.y
+ vkey.Position.Z = head.z
+ vkey.Orientation = quat
+
+ # frame delta = 1.0 / fps
+ vkey.Time = 1.0 / float(anim_rate) # according to C++ header this is "disregarded"
+
+ psa.AddRawKey(vkey)
+
+ # END for bone_data in ordered_bones
+
+ raw_frame_index += 1
+
+ # END for i in range(frame_count)
+
+ anim.TotalBones = len(ordered_bones) # REMOVED len(unique_bone_indexes)
+ anim.TrackTime = float(frame_count) # frame_count/anim.AnimRate makes more sense, but this is what actually works in UDK
+
+ verbose("anim.TotalBones={}, anim.TrackTime={}".format(anim.TotalBones, anim.TrackTime))
+
+ psa.AddAnimation(anim)
+
+ # END for action in actions
+
+ # restore
+ armature.animation_data.action = restoreAction
+ context.scene.frame_set(restoreFrame)
#===========================================================================
# Collate actions to be exported
@@ -1551,144 +1568,154 @@ def parse_animation( armature, udk_bones, actions_to_export, psa ):
# RETURNS list of actions
#===========================================================================
def collate_actions():
- verbose(header("collate_actions"))
- actions_to_export = []
-
- for action in bpy.data.actions:
- if bpy.context.scene.udk_option_selectanimations:
- print("Action Set is selected!")
- bready = False
- for actionlist in bpy.context.scene.udkas_list:
- if actionlist.name == action.name and actionlist.bmatch == True and actionlist.bexport == True:
- bready = True
- print("Added Action Set:",action.name)
- break
- if bready == False:#don't export it
- print("Skipping Action Set:",action.name)
- continue
- verbose(" + {}".format(action.name))
- actions_to_export.append(action)
-
- return actions_to_export
+ verbose(header("collate_actions"))
+ actions_to_export = []
+
+ for action in bpy.data.actions:
+ if bpy.context.scene.udk_option_selectanimations: # check if needed to select actions set for exporting it
+ print("Action Set is selected!")
+ bready = False
+ for actionlist in bpy.context.scene.udkas_list: #list the action set from the list
+ if actionlist.name == action.name and actionlist.bmatch == True and actionlist.bexport == True:
+ bready = True
+ print("Added Action Set:",action.name)
+ break
+ if bready == False:#don't export it
+ print("Skipping Action Set:",action.name)
+ continue
+ verbose(" + {}".format(action.name)) #action set name
+ actions_to_export.append(action) #add to the action array
+
+ return actions_to_export
#===========================================================================
# Locate the target armature and mesh for export
# RETURNS armature, mesh
#===========================================================================
def find_armature_and_mesh():
- verbose(header("find_armature_and_mesh", 'LEFT', '<', 60))
-
- context = bpy.context
- active_object = context.active_object
- armature = None
- mesh = None
-
- # TODO:
- # this could be more intuitive
- #bpy.ops.object.mode_set(mode='OBJECT')
-
- if bpy.context.scene.udk_option_selectobjects:
- print("select mode:")
- if len(bpy.context.scene.udkArm_list) > 0:
- print("Armature Name:",bpy.context.scene.udkArm_list[bpy.context.scene.udkArm_list_idx].name)
- for obj in bpy.context.scene.objects:
- if obj.name == bpy.context.scene.udkArm_list[bpy.context.scene.udkArm_list_idx].name:
- armature = obj
- break
- else:
- raise Error("There is no Armature in the list!")
- meshselected = []
- parented_meshes = [obj for obj in armature.children if obj.type == 'MESH']
- for obj in armature.children:
- #print(dir(obj))
- if obj.type == 'MESH' and obj.select == True:
- bexportmesh = False
- #print("PARENT MESH:",obj.name)
- for udkmeshlist in bpy.context.scene.udkmesh_list:
- if obj.name == udkmeshlist.name and udkmeshlist.bexport == True:
- bexportmesh = True
- break
- if bexportmesh == True:
- print("Mesh Name:",obj.name," < SELECT TO EXPORT!")
- meshselected.append(obj)
- print("MESH COUNT:",len(meshselected))
- # try the active object
- if active_object and active_object.type == 'MESH' and len(meshselected) == 0:
- if active_object.parent == armature:
- mesh = active_object
- else:
- raise Error("The selected mesh is not parented to the armature")
-
- # otherwise, expect a single mesh parented to the armature (other object types are ignored)
- else:
- print("Number of meshes:",len(parented_meshes))
- print("Number of meshes (selected):",len(meshselected))
- if len(parented_meshes) == 1:
- mesh = parented_meshes[0]
-
- elif len(parented_meshes) > 1:
- if len(meshselected) >= 1:
- mesh = sortmesh(meshselected)
- else:
- raise Error("More than one mesh(s) parented to armature. Select object(s)!")
- else:
- raise Error("No mesh parented to armature")
- else:
- print("normal mode:")
- # try the active object
- if active_object and active_object.type == 'ARMATURE':
- armature = active_object
- bpy.ops.object.mode_set(mode='OBJECT')
- # otherwise, try for a single armature in the scene
- else:
- #bpy.ops.object.mode_set(mode='OBJECT')
- all_armatures = [obj for obj in bpy.context.scene.objects if obj.type == 'ARMATURE']
-
- if len(all_armatures) == 1:
- armature = all_armatures[0]
- elif len(all_armatures) > 1:
- raise Error("Please select an armature in the scene")
- else:
- raise Error("No armatures in scene")
-
- verbose("Found armature: {}".format(armature.name))
-
- meshselected = []
- parented_meshes = [obj for obj in armature.children if obj.type == 'MESH']
- for obj in armature.children:
- #print(dir(obj))
- if obj.type == 'MESH' and obj.select == True:
- meshselected.append(obj)
- # try the active object
- if active_object and active_object.type == 'MESH' and len(meshselected) == 0:
- if active_object.parent == armature:
- mesh = active_object
- else:
- raise Error("The selected mesh is not parented to the armature")
-
- # otherwise, expect a single mesh parented to the armature (other object types are ignored)
- else:
- print("Number of meshes:",len(parented_meshes))
- print("Number of meshes (selected):",len(meshselected))
- if len(parented_meshes) == 1:
- mesh = parented_meshes[0]
-
- elif len(parented_meshes) > 1:
- if len(meshselected) >= 1:
- mesh = sortmesh(meshselected)
- else:
- raise Error("More than one mesh(s) parented to armature. Select object(s)!")
- else:
- raise Error("No mesh parented to armature")
-
- verbose("Found mesh: {}".format(mesh.name))
- if mesh == None or armature == None:
- raise Error("Check Mesh and Armature are list!")
- if len(armature.pose.bones) == len(mesh.vertex_groups):
- print("Armature and Mesh Vertex Groups matches Ok!")
- else:
- raise Error("Armature bones:" + str(len(armature.pose.bones)) + " Mesh Vertex Groups:" + str(len(mesh.vertex_groups)) +" doesn't match!")
- return armature, mesh
+ verbose(header("find_armature_and_mesh", 'LEFT', '<', 60))
+
+ context = bpy.context
+ active_object = context.active_object
+ armature = None
+ mesh = None
+
+ # TODO:
+ # this could be more intuitive
+ #bpy.ops.object.mode_set(mode='OBJECT')
+
+ if bpy.context.scene.udk_option_selectobjects: #if checked select object true do list object on export
+ print("select mode:")
+ if len(bpy.context.scene.udkArm_list) > 0:
+ print("Armature Name:",bpy.context.scene.udkArm_list[bpy.context.scene.udkArm_list_idx].name)
+ for obj in bpy.context.scene.objects:
+ if obj.name == bpy.context.scene.udkArm_list[bpy.context.scene.udkArm_list_idx].name:
+ armature = obj
+ break
+ else:
+ raise Error("There is no Armature in the list!")
+ meshselected = []
+ parented_meshes = [obj for obj in armature.children if obj.type == 'MESH']
+ for obj in armature.children:
+ #print(dir(obj))
+ if obj.type == 'MESH' and obj.select == True:
+ bexportmesh = False
+ #print("PARENT MESH:",obj.name)
+ for udkmeshlist in bpy.context.scene.udkmesh_list:
+ if obj.name == udkmeshlist.name and udkmeshlist.bexport == True:
+ bexportmesh = True
+ break
+ if bexportmesh == True:
+ print("Mesh Name:",obj.name," < SELECT TO EXPORT!")
+ meshselected.append(obj)
+ print("MESH COUNT:",len(meshselected))
+ # try the active object
+ if active_object and active_object.type == 'MESH' and len(meshselected) == 0:
+ if active_object.parent == armature:
+ mesh = active_object
+ else:
+ raise Error("The selected mesh is not parented to the armature")
+
+ # otherwise, expect a single mesh parented to the armature (other object types are ignored)
+ else:
+ print("Number of meshes:",len(parented_meshes))
+ print("Number of meshes (selected):",len(meshselected))
+ if len(parented_meshes) == 1:
+ mesh = parented_meshes[0]
+
+ elif len(parented_meshes) > 1:
+ if len(meshselected) >= 1:
+ mesh = sortmesh(meshselected)
+ else:
+ raise Error("More than one mesh(s) parented to armature. Select object(s)!")
+ else:
+ raise Error("No mesh parented to armature")
+ else: #if not check for select function from the list work the code here
+ print("normal mode:")
+ # try the active object
+ if active_object and active_object.type == 'ARMATURE':
+ armature = active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+ # otherwise, try for a single armature in the scene
+ else:
+ #bpy.ops.object.mode_set(mode='OBJECT')
+ all_armatures = [obj for obj in bpy.context.scene.objects if obj.type == 'ARMATURE']
+
+ if len(all_armatures) == 1:
+ armature = all_armatures[0]
+ elif len(all_armatures) > 1:
+ raise Error("Please select an armature in the scene")
+ else:
+ raise Error("No armatures in scene")
+
+ verbose("Found armature: {}".format(armature.name))
+
+ meshselected = []
+ parented_meshes = [obj for obj in armature.children if obj.type == 'MESH']
+ for obj in armature.children:
+ #print(dir(obj))
+ if obj.type == 'MESH' and obj.select == True:
+ meshselected.append(obj)
+ # try the active object
+ if active_object and active_object.type == 'MESH' and len(meshselected) == 0:
+ if active_object.parent == armature:
+ mesh = active_object
+ else:
+ raise Error("The selected mesh is not parented to the armature")
+
+ # otherwise, expect a single mesh parented to the armature (other object types are ignored)
+ else:
+ print("Number of meshes:",len(parented_meshes))
+ print("Number of meshes (selected):",len(meshselected))
+ if len(parented_meshes) == 1:
+ mesh = parented_meshes[0]
+
+ elif len(parented_meshes) > 1:
+ if len(meshselected) >= 1:
+ mesh = sortmesh(meshselected)
+ else:
+ raise Error("More than one mesh(s) parented to armature. Select object(s)!")
+ else:
+ raise Error("No mesh parented to armature")
+
+ verbose("Found mesh: {}".format(mesh.name))
+ if mesh == None or armature == None:
+ raise Error("Check Mesh and Armature are list!")
+ if len(armature.pose.bones) == len(mesh.vertex_groups):
+ print("Armature and Mesh Vertex Groups matches Ok!")
+ else:
+ raise Error("Armature bones:" + str(len(armature.pose.bones)) + " Mesh Vertex Groups:" + str(len(mesh.vertex_groups)) +" doesn't match!")
+
+ #this will check if object need to be rebuild.
+ if bpy.context.scene.udk_option_rebuildobjects:
+ #print("INIT... REBUILDING...")
+ print("REBUILDING ARMATURE...")
+ #if deform mesh
+ armature = rebuildarmature(armature) #rebuild the armature to raw . If there IK constraint it will ignore it.
+ print("REBUILDING MESH...")
+ mesh = rebuildmesh(mesh) #rebuild the mesh to raw data format.
+
+ return armature, mesh
#===========================================================================
# Returns a list of vertex groups in the mesh. Can be modified to filter
@@ -1696,225 +1723,245 @@ def find_armature_and_mesh():
# UNUSED
#===========================================================================
def collate_vertex_groups( mesh ):
- verbose("collate_vertex_groups")
- groups = []
-
- for group in mesh.vertex_groups:
-
- groups.append(group)
- verbose(" " + group.name)
-
- return groups
-
+ verbose("collate_vertex_groups")
+ groups = []
+
+ for group in mesh.vertex_groups:
+
+ groups.append(group)
+ verbose(" " + group.name)
+
+ return groups
+
#===========================================================================
# Main
#===========================================================================
def export(filepath):
- print(header("Export", 'RIGHT'))
- bpy.types.Scene.udk_copy_merge = False #in case fail to export set this to default
- t = time.clock()
- context = bpy.context
-
- print("Blender Version {}.{}.{}".format(bpy.app.version[0], bpy.app.version[1], bpy.app.version[2]))
- print("Filepath: {}".format(filepath))
-
- verbose("PSK={}, PSA={}".format(context.scene.udk_option_export_psk, context.scene.udk_option_export_psa))
-
- # find armature and mesh
- # [change this to implement alternative methods; raise Error() if not found]
- udk_armature, udk_mesh = find_armature_and_mesh()
-
- # check misc conditions
- if not (udk_armature.scale.x == udk_armature.scale.y == udk_armature.scale.z == 1):
- raise Error("bad armature scale: armature object should have uniform scale of 1 (ALT-S)")
-
- if not (udk_mesh.scale.x == udk_mesh.scale.y == udk_mesh.scale.z == 1):
- raise Error("bad mesh scale: mesh object should have uniform scale of 1 (ALT-S)")
-
- if not (udk_armature.location.x == udk_armature.location.y == udk_armature.location.z == 0):
- raise Error("bad armature location: armature should be located at origin (ALT-G)")
-
- if not (udk_mesh.location.x == udk_mesh.location.y == udk_mesh.location.z == 0):
- raise Error("bad mesh location: mesh should be located at origin (ALT-G)")
-
- # prep
- psk = PSKFile()
- psa = PSAFile()
-
- # step 1
- parse_mesh(udk_mesh, psk)
-
- # step 2
- udk_bones = parse_armature(udk_armature, psk, psa)
-
- # step 3
- if context.scene.udk_option_export_psa == True:
- actions = collate_actions()
- parse_animation(udk_armature, udk_bones, actions, psa)
-
- # write files
- print(header("Exporting", 'CENTER'))
-
- psk_filename = filepath + '.psk'
- psa_filename = filepath + '.psa'
-
- if context.scene.udk_option_export_psk == True:
-
- print("Skeletal mesh data...")
- psk.PrintOut()
- file = open(psk_filename, "wb")
- file.write(psk.dump())
- file.close()
- print("Exported: " + psk_filename)
- print()
-
- if context.scene.udk_option_export_psa == True:
-
- print("Animation data...")
- if not psa.IsEmpty():
- psa.PrintOut()
- file = open(psa_filename, "wb")
- file.write(psa.dump())
- file.close()
- print("Exported: " + psa_filename)
-
- else:
- print("No Animation (.psa file) to export")
-
- print()
-
- print("Export completed in {:.2f} seconds".format((time.clock() - t)))
+ print(header("Export", 'RIGHT'))
+ bpy.types.Scene.udk_copy_merge = False #in case fail to export set this to default
+ t = time.clock()
+ context = bpy.context
+
+ print("Blender Version {}.{}.{}".format(bpy.app.version[0], bpy.app.version[1], bpy.app.version[2]))
+ print("Filepath: {}".format(filepath))
+
+ verbose("PSK={}, PSA={}".format(context.scene.udk_option_export_psk, context.scene.udk_option_export_psa))
+
+ # find armature and mesh
+ # [change this to implement alternative methods; raise Error() if not found]
+ udk_armature, udk_mesh = find_armature_and_mesh()
+
+ # check misc conditions
+ if not (udk_armature.scale.x == udk_armature.scale.y == udk_armature.scale.z == 1):
+ raise Error("bad armature scale: armature object should have uniform scale of 1 (ALT-S)")
+
+ if not (udk_mesh.scale.x == udk_mesh.scale.y == udk_mesh.scale.z == 1):
+ raise Error("bad mesh scale: mesh object should have uniform scale of 1 (ALT-S)")
+
+ if not (udk_armature.location.x == udk_armature.location.y == udk_armature.location.z == 0):
+ raise Error("bad armature location: armature should be located at origin (ALT-G)")
+
+ if not (udk_mesh.location.x == udk_mesh.location.y == udk_mesh.location.z == 0):
+ raise Error("bad mesh location: mesh should be located at origin (ALT-G)")
+
+ # prep
+ psk = PSKFile()
+ psa = PSAFile()
+
+ # step 1
+ parse_mesh(udk_mesh, psk)
+
+ # step 2
+ udk_bones = parse_armature(udk_armature, psk, psa)
+
+ # step 3
+ if context.scene.udk_option_export_psa == True:
+ actions = collate_actions()
+ parse_animation(udk_armature, udk_bones, actions, psa)
+
+ # write files
+ print(header("Exporting", 'CENTER'))
+
+ psk_filename = filepath + '.psk'
+ psa_filename = filepath + '.psa'
+
+ if context.scene.udk_option_export_psk == True:
+ print("Skeletal mesh data...")
+ psk.PrintOut()
+ file = open(psk_filename, "wb")
+ file.write(psk.dump())
+ file.close()
+ print("Exported: " + psk_filename)
+ print()
+
+ if context.scene.udk_option_export_psa == True:
+ print("Animation data...")
+ if not psa.IsEmpty():
+ psa.PrintOut()
+ file = open(psa_filename, "wb")
+ file.write(psa.dump())
+ file.close()
+ print("Exported: " + psa_filename)
+ else:
+ print("No Animation (.psa file) to export")
+
+ print()
+
+ #if objects are rebuild do the unlink
+ if bpy.context.scene.udk_option_rebuildobjects:
+ print("Unlinking Objects")
+ print("Armature Object Name:",udk_armature.name) #display object name
+ bpy.context.scene.objects.unlink(udk_armature) #remove armature from the scene
+ print("Mesh Object Name:",udk_mesh.name) #display object name
+ bpy.context.scene.objects.unlink(udk_mesh) #remove mesh from the scene
+
+ print("Export completed in {:.2f} seconds".format((time.clock() - t)))
#===========================================================================
# Operator
#===========================================================================
class Operator_UDKExport( bpy.types.Operator ):
- bl_idname = "object.udk_export"
- bl_label = "Export now"
- __doc__ = "Export to UDK"
-
- def execute(self, context):
- print( "\n"*8 )
-
- scene = bpy.context.scene
-
- scene.udk_option_export_psk = (scene.udk_option_export == '0' or scene.udk_option_export == '2')
- scene.udk_option_export_psa = (scene.udk_option_export == '1' or scene.udk_option_export == '2')
-
- filepath = get_dst_path()
-
- # cache settings
- restore_frame = scene.frame_current
-
- message = "Finish Export!"
- try:
- export(filepath)
-
- except Error as err:
- print(err.message)
- message = err.message
-
- # restore settings
- scene.frame_set(restore_frame)
-
- self.report({'ERROR'}, message)
-
- # restore settings
- scene.frame_set(restore_frame)
-
- return {'FINISHED'}
+ bl_idname = "object.udk_export"
+ bl_label = "Export now"
+ __doc__ = "Export to UDK"
+
+ def execute(self, context):
+ print( "\n"*8 )
+
+ scene = bpy.context.scene
+
+ scene.udk_option_export_psk = (scene.udk_option_export == '0' or scene.udk_option_export == '2')
+ scene.udk_option_export_psa = (scene.udk_option_export == '1' or scene.udk_option_export == '2')
+
+ filepath = get_dst_path()
+
+ # cache settings
+ restore_frame = scene.frame_current
+
+ message = "Finish Export!"
+ try:
+ export(filepath)
+
+ except Error as err:
+ print(err.message)
+ message = err.message
+
+ # restore settings
+ scene.frame_set(restore_frame)
+
+ self.report({'ERROR'}, message)
+
+ # restore settings
+ scene.frame_set(restore_frame)
+
+ return {'FINISHED'}
#===========================================================================
# Operator
#===========================================================================
class Operator_ToggleConsole( bpy.types.Operator ):
- bl_idname = "object.toggle_console"
- bl_label = "Toggle console"
- __doc__ = "Show or hide the console"
-
- #def invoke(self, context, event):
- # bpy.ops.wm.console_toggle()
- # return{'FINISHED'}
- def execute(self, context):
- bpy.ops.wm.console_toggle()
- return {'FINISHED'}
+ bl_idname = "object.toggle_console"
+ bl_label = "Toggle console"
+ __doc__ = "Show or hide the console"
+
+ #def invoke(self, context, event):
+ # bpy.ops.wm.console_toggle()
+ # return{'FINISHED'}
+ def execute(self, context):
+ bpy.ops.wm.console_toggle()
+ return {'FINISHED'}
#===========================================================================
# Get filepath for export
#===========================================================================
def get_dst_path():
- if bpy.context.scene.udk_option_filename_src == '0':
- if bpy.context.active_object:
- path = os.path.split(bpy.data.filepath)[0] + "\\" + bpy.context.active_object.name# + ".psk"
- else:
- #path = os.path.split(bpy.data.filepath)[0] + "\\" + "Unknown";
- path = os.path.splitext(bpy.data.filepath)[0]# + ".psk"
- else:
- path = os.path.splitext(bpy.data.filepath)[0]# + ".psk"
- return path
+ if bpy.context.scene.udk_option_filename_src == '0':
+ if bpy.context.active_object:
+ path = os.path.split(bpy.data.filepath)[0] + "\\" + bpy.context.active_object.name# + ".psk"
+ else:
+ #path = os.path.split(bpy.data.filepath)[0] + "\\" + "Unknown";
+ path = os.path.splitext(bpy.data.filepath)[0]# + ".psk"
+ else:
+ path = os.path.splitext(bpy.data.filepath)[0]# + ".psk"
+ return path
#Added by [MGVS]
bpy.types.Scene.udk_option_filename_src = EnumProperty(
- name = "Filename",
- description = "Sets the name for the files",
- items = [ ('0', "From object", "Name will be taken from object name"),
- ('1', "From Blend", "Name will be taken from .blend file name") ],
- default = '0')
-
+ name = "Filename",
+ description = "Sets the name for the files",
+ items = [ ('0', "From object", "Name will be taken from object name"),
+ ('1', "From Blend", "Name will be taken from .blend file name") ],
+ default = '0')
+
bpy.types.Scene.udk_option_export_psk = BoolProperty(
- name = "bool export psa",
- description = "bool for exporting this psk format",
- default = True)
+ name = "bool export psa",
+ description = "Boolean for exporting psk format (Skeleton Mesh)",
+ default = True)
bpy.types.Scene.udk_option_export_psa = BoolProperty(
- name = "bool export psa",
- description = "bool for exporting this psa format",
- default = True)
+ name = "bool export psa",
+ description = "Boolean for exporting psa format (Animation Data)",
+ default = True)
bpy.types.Scene.udk_option_clamp_uv = BoolProperty(
- name = "Clamp UV",
- description = "Clamp UV co-ordinates to [0-1]",
- default = False)
-
+ name = "Clamp UV",
+ description = "True is to limit Clamp UV co-ordinates to [0-1]. False is unrestricted (x,y). ",
+ default = False)
+
bpy.types.Scene.udk_copy_merge = BoolProperty(
- name = "merge mesh",
- description = "Deal with unlinking the mesh to be remove while exporting the object.",
- default = False)
+ name = "Merge Mesh",
+ description = "This will copy the mesh(s) and merge the object together and unlink the mesh to be remove while exporting the object.",
+ default = False)
bpy.types.Scene.udk_option_export = EnumProperty(
- name = "Export",
- description = "What to export",
- items = [ ('0', "Mesh only", "Exports the PSK file for the skeletal mesh"),
- ('1', "Animation only", "Export the PSA file for animations"),
- ('2', "Mesh & Animation", "Export both PSK and PSA files") ],
- default = '2')
+ name = "Export",
+ description = "What to export",
+ items = [ ('0', "Mesh only", "Exports the PSK file for the Skeletal Mesh"),
+ ('1', "Animation only", "Export the PSA file for Action Set(s)(Animations Data)"),
+ ('2', "Mesh & Animation", "Export both PSK and PSA files(Skeletal Mesh/Animation(s) Data)") ],
+ default = '2')
bpy.types.Scene.udk_option_verbose = BoolProperty(
- name = "Verbose",
- description = "Verbose console output",
- default = False)
+ name = "Verbose",
+ description = "Verbose console output",
+ default = False)
bpy.types.Scene.udk_option_smoothing_groups = BoolProperty(
- name = "Smooth Groups",
- description = "Activate hard edges as smooth groups",
- default = True)
+ name = "Smooth Groups",
+ description = "Activate hard edges as smooth groups",
+ default = True)
bpy.types.Scene.udk_option_triangulate = BoolProperty(
- name = "Triangulate Mesh",
- description = "Convert Quads to Triangles",
- default = False)
-
+ name = "Triangulate Mesh",
+ description = "Convert Quads to Triangles",
+ default = False)
+
bpy.types.Scene.udk_option_selectanimations = BoolProperty(
- name = "Select Animation(s)",
- description = "Select aimation(s) for export to psa file.",
- default = False)
-
+ name = "Select Animation(s)",
+ description = "Select animation(s) for export to psa file.",
+ default = False)
+
bpy.types.Scene.udk_option_selectobjects = BoolProperty(
- name = "Select Object(s)",
- description = "Select aimation(s) for export to psa file.",
- default = False)
+ name = "Select Object(s)",
+ description = "Select Armature and Mesh(s). Just make sure mesh(s) is parent to armature.",
+ default = False)
+
+bpy.types.Scene.udk_option_rebuildobjects = BoolProperty(
+ name = "Rebuild Objects",
+ description = "In case of deform skeleton mesh and animations data. This will rebuild objects from raw format on export when checked.",
+ default = False)
+
+bpy.types.Scene.udk_option_ignoreactiongroupnames = BoolProperty(
+ name = "Ignore Action Group Names",
+ description = "This will Ignore Action Set Group Names Check With Armature Bones. It will override armature to set action set.",
+ default = False)
+
+bpy.types.Scene.udk_option_scale = FloatProperty(
+ name = "UDK Scale",
+ description = "In case you don't want to scale objects manually. This will just scale position when on export for the skeleton mesh and animation data.",
+ default = 1)
#===========================================================================
# User interface
@@ -1961,7 +2008,7 @@ class OBJECT_OT_UTSelectedFaceSmooth(bpy.types.Operator):
self.report({'INFO'}, "Didn't Select Mesh Object!")
print("----------------------------------------")
return{'FINISHED'}
-
+
class OBJECT_OT_MeshClearWeights(bpy.types.Operator):
bl_idname = "object.meshclearweights" # XXX, name???
bl_label = "Remove Vertex Weights"#"Remove Mesh vertex weights"
@@ -1973,7 +2020,7 @@ class OBJECT_OT_MeshClearWeights(bpy.types.Operator):
for vg in obj.vertex_groups:
obj.vertex_groups.remove(vg)
self.report({'INFO'}, "Mesh Vertex Groups Remove!")
- break
+ break
return{'FINISHED'}
def unpack_list(list_of_tuples):
@@ -1981,121 +2028,166 @@ def unpack_list(list_of_tuples):
for t in list_of_tuples:
l.extend(t)
return l
-
+
+def rebuildmesh(obj):
+ #make sure it in object mode
+ print("Mesh Object Name:",obj.name)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for i in bpy.context.scene.objects: i.select = False #deselect all objects
+ obj.select = True
+ bpy.context.scene.objects.active = obj
+
+ me_ob = bpy.data.meshes.new(("Re_"+obj.name))
+ mesh = obj.data
+ faces = []
+ verts = []
+ smoothings = []
+ uvfaces = []
+ #print("creating array build mesh...")
+ mmesh = obj.to_mesh(bpy.context.scene,True,'PREVIEW')
+ uv_layer = mmesh.tessface_uv_textures.active
+ for face in mmesh.tessfaces:
+ smoothings.append(face.use_smooth)#smooth or flat in boolean
+ if uv_layer != None:#check if there texture data exist
+ faceUV = uv_layer.data[face.index]
+ uvs = []
+ for uv in faceUV.uv:
+ uvs.append((uv[0],uv[1]))
+ uvfaces.append(uvs)
+ #print((face.vertices[:]))
+ if len(face.vertices) == 3:
+ faces.extend([(face.vertices[0],face.vertices[1],face.vertices[2],0)])
+ else:
+ faces.extend([(face.vertices[0],face.vertices[1],face.vertices[2],face.vertices[3])])
+ #vertex positions
+ for vertex in mesh.vertices:
+ verts.append(vertex.co.to_tuple())
+ #vertices weight groups into array
+ vertGroups = {} #array in strings
+ for vgroup in obj.vertex_groups:
+ vlist = []
+ for v in mesh.vertices:
+ for vg in v.groups:
+ if vg.group == vgroup.index:
+ vlist.append((v.index,vg.weight))
+ #print((v.index,vg.weight))
+ vertGroups[vgroup.name] = vlist
+
+ #print("creating mesh object...")
+ #me_ob.from_pydata(verts, [], faces)
+ me_ob.vertices.add(len(verts))
+ me_ob.tessfaces.add(len(faces))
+ me_ob.vertices.foreach_set("co", unpack_list(verts))
+ me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
+ me_ob.tessfaces.foreach_set("use_smooth", smoothings)#smooth array from face
+
+ #check if there is uv faces
+ if len(uvfaces) > 0:
+ uvtex = me_ob.tessface_uv_textures.new(name="retex")
+ for i, face in enumerate(me_ob.tessfaces):
+ blender_tface = uvtex.data[i] #face
+ mfaceuv = uvfaces[i]
+ if len(mfaceuv) == 3:
+ blender_tface.uv1 = mfaceuv[0];
+ blender_tface.uv2 = mfaceuv[1];
+ blender_tface.uv3 = mfaceuv[2];
+ if len(mfaceuv) == 4:
+ blender_tface.uv1 = mfaceuv[0];
+ blender_tface.uv2 = mfaceuv[1];
+ blender_tface.uv3 = mfaceuv[2];
+ blender_tface.uv4 = mfaceuv[3];
+
+ me_ob.update()#need to update the information to able to see into the secne
+ obmesh = bpy.data.objects.new(("Re_"+obj.name),me_ob)
+ bpy.context.scene.update()
+ #Build tmp materials
+ materialname = "ReMaterial"
+ for matcount in mesh.materials:
+ matdata = bpy.data.materials.new(materialname)
+ me_ob.materials.append(matdata)
+ #assign face to material id
+ for face in mesh.tessfaces:
+ me_ob.faces[face.index].material_index = face.material_index
+ #vertices weight groups
+ for vgroup in vertGroups:
+ group = obmesh.vertex_groups.new(vgroup)
+ for v in vertGroups[vgroup]:
+ group.add([v[0]], v[1], 'ADD')# group.add(array[vertex id],weight,add)
+ bpy.context.scene.objects.link(obmesh)
+ #print("Mesh Material Count:",len(me_ob.materials))
+ matcount = 0
+ #print("MATERIAL ID OREDER:")
+ for mat in me_ob.materials:
+ #print("-Material:",mat.name,"INDEX:",matcount)
+ matcount += 1
+ print("Mesh Object Name:",obmesh.name)
+ bpy.context.scene.update()
+ return obmesh
+
class OBJECT_OT_UTRebuildMesh(bpy.types.Operator):
bl_idname = "object.utrebuildmesh" # XXX, name???
- bl_label = "Rebuild"#"Rebuild Mesh"
+ bl_label = "Rebuild Mesh"#"Rebuild Mesh"
__doc__ = """It rebuild the mesh from scrape from the selected mesh object. Note the scale will be 1:1 for object mode. To keep from deforming"""
def invoke(self, context, event):
print("----------------------------------------")
print("Init Mesh Bebuild...")
bselected = False
+ bpy.ops.object.mode_set(mode='OBJECT')
for obj in bpy.data.objects:
if obj.type == 'MESH' and obj.select == True:
- for i in bpy.context.scene.objects: i.select = False #deselect all objects
- obj.select = True
- bpy.context.scene.objects.active = obj
- bpy.ops.object.mode_set(mode='OBJECT')
- me_ob = bpy.data.meshes.new(("Re_"+obj.name))
- mesh = obj.data
- faces = []
- verts = []
- smoothings = []
- uvfaces = []
- print("creating array build mesh...")
- mmesh = obj.to_mesh(bpy.context.scene,True,'PREVIEW')
- uv_layer = mmesh.tessface_uv_textures.active
- for face in mmesh.tessfaces:
- smoothings.append(face.use_smooth)#smooth or flat in boolean
- if uv_layer != None:#check if there texture data exist
- faceUV = uv_layer.data[face.index]
- uvs = []
- for uv in faceUV.uv:
- uvs.append((uv[0],uv[1]))
- uvfaces.append(uvs)
- print((face.vertices[:]))
- if len(face.vertices) == 3:
- faces.extend([(face.vertices[0],face.vertices[1],face.vertices[2],0)])
- else:
- faces.extend([(face.vertices[0],face.vertices[1],face.vertices[2],face.vertices[3])])
- #vertex positions
- for vertex in mesh.vertices:
- verts.append(vertex.co.to_tuple())
- #vertices weight groups into array
- vertGroups = {} #array in strings
- for vgroup in obj.vertex_groups:
- vlist = []
- for v in mesh.vertices:
- for vg in v.groups:
- if vg.group == vgroup.index:
- vlist.append((v.index,vg.weight))
- #print((v.index,vg.weight))
- vertGroups[vgroup.name] = vlist
-
- print("creating mesh object...")
- #me_ob.from_pydata(verts, [], faces)
- me_ob.vertices.add(len(verts))
- me_ob.tessfaces.add(len(faces))
- me_ob.vertices.foreach_set("co", unpack_list(verts))
- me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
- me_ob.tessfaces.foreach_set("use_smooth", smoothings)#smooth array from face
-
- #check if there is uv faces
- if len(uvfaces) > 0:
- uvtex = me_ob.tessface_uv_textures.new(name="retex")
- for i, face in enumerate(me_ob.tessfaces):
- blender_tface = uvtex.data[i] #face
- mfaceuv = uvfaces[i]
- if len(mfaceuv) == 3:
- blender_tface.uv1 = mfaceuv[0];
- blender_tface.uv2 = mfaceuv[1];
- blender_tface.uv3 = mfaceuv[2];
- if len(mfaceuv) == 4:
- blender_tface.uv1 = mfaceuv[0];
- blender_tface.uv2 = mfaceuv[1];
- blender_tface.uv3 = mfaceuv[2];
- blender_tface.uv4 = mfaceuv[3];
-
- me_ob.update()#need to update the information to able to see into the secne
- obmesh = bpy.data.objects.new(("Re_"+obj.name),me_ob)
- bpy.context.scene.update()
- #Build tmp materials
- materialname = "ReMaterial"
- for matcount in mesh.materials:
- matdata = bpy.data.materials.new(materialname)
- me_ob.materials.append(matdata)
- #assign face to material id
- for face in mesh.tessfaces:
- me_ob.faces[face.index].material_index = face.material_index
- #vertices weight groups
- for vgroup in vertGroups:
- group = obmesh.vertex_groups.new(vgroup)
- for v in vertGroups[vgroup]:
- group.add([v[0]], v[1], 'ADD')# group.add(array[vertex id],weight,add)
- bpy.context.scene.objects.link(obmesh)
- print("Mesh Material Count:",len(me_ob.materials))
- matcount = 0
- print("MATERIAL ID OREDER:")
- for mat in me_ob.materials:
- print("-Material:",mat.name,"INDEX:",matcount)
- matcount += 1
- print("Object Name:",obmesh.name)
- bpy.context.scene.update()
- bselected = True
- break
- if bselected:
- self.report({'INFO'}, "Rebuild Mesh Finish!")
- print("Finish Mesh Build...")
- else:
- self.report({'INFO'}, "Didn't Select Mesh Object!")
- print("Didn't Select Mesh Object!")
+ rebuildmesh(obj)
+ self.report({'INFO'}, "Rebuild Mesh Finish!")
+ print("Finish Mesh Build...")
print("----------------------------------------")
return{'FINISHED'}
-
+
+def rebuildarmature(obj):
+ currentbone = [] #select armature for roll copy
+ print("Armature Name:",obj.name)
+ objectname = "ArmatureDataPSK"
+ meshname ="ArmatureObjectPSK"
+ armdata = bpy.data.armatures.new(objectname)
+ ob_new = bpy.data.objects.new(meshname, armdata)
+ bpy.context.scene.objects.link(ob_new)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for i in bpy.context.scene.objects: i.select = False #deselect all objects
+ ob_new.select = True
+ bpy.context.scene.objects.active = obj
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in obj.data.edit_bones:
+ if bone.parent != None:
+ currentbone.append([bone.name,bone.roll])
+ else:
+ currentbone.append([bone.name,bone.roll])
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for i in bpy.context.scene.objects: i.select = False #deselect all objects
+ bpy.context.scene.objects.active = ob_new
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ for bone in obj.data.bones:
+ bpy.ops.object.mode_set(mode='EDIT')
+ newbone = ob_new.data.edit_bones.new(bone.name)
+ newbone.head = bone.head_local
+ newbone.tail = bone.tail_local
+ for bonelist in currentbone:
+ if bone.name == bonelist[0]:
+ newbone.roll = bonelist[1]
+ break
+ if bone.parent != None:
+ parentbone = ob_new.data.edit_bones[bone.parent.name]
+ newbone.parent = parentbone
+
+ ob_new.animation_data_create()#create animation data
+ if obj.animation_data != None:#check for animation
+ ob_new.animation_data.action = obj.animation_data.action #just make sure it here to do the animations if exist
+ print("Armature Object Name:",ob_new.name)
+ return ob_new
+
class OBJECT_OT_UTRebuildArmature(bpy.types.Operator):
bl_idname = "object.utrebuildarmature" # XXX, name???
- bl_label = "Rebuild" #Rebuild Armature
+ bl_label = "Rebuild Armature" #Rebuild Armature
__doc__ = """If mesh is deform when importing to unreal engine try this. It rebuild the bones one at the time by select one armature object scrape to raw setup build. Note the scale will be 1:1 for object mode. To keep from deforming"""
def invoke(self, context, event):
@@ -2104,99 +2196,55 @@ class OBJECT_OT_UTRebuildArmature(bpy.types.Operator):
bselected = False
for obj in bpy.data.objects:
if obj.type == 'ARMATURE' and obj.select == True:
- currentbone = [] #select armature for roll copy
- print("Armature Name:",obj.name)
- objectname = "ArmatureDataPSK"
- meshname ="ArmatureObjectPSK"
- armdata = bpy.data.armatures.new(objectname)
- ob_new = bpy.data.objects.new(meshname, armdata)
- bpy.context.scene.objects.link(ob_new)
- bpy.ops.object.mode_set(mode='OBJECT')
- for i in bpy.context.scene.objects: i.select = False #deselect all objects
- ob_new.select = True
- bpy.context.scene.objects.active = obj
-
- bpy.ops.object.mode_set(mode='EDIT')
- for bone in obj.data.edit_bones:
- if bone.parent != None:
- currentbone.append([bone.name,bone.roll])
- else:
- currentbone.append([bone.name,bone.roll])
- bpy.ops.object.mode_set(mode='OBJECT')
- for i in bpy.context.scene.objects: i.select = False #deselect all objects
- bpy.context.scene.objects.active = ob_new
- bpy.ops.object.mode_set(mode='EDIT')
-
- for bone in obj.data.bones:
- bpy.ops.object.mode_set(mode='EDIT')
- newbone = ob_new.data.edit_bones.new(bone.name)
- newbone.head = bone.head_local
- newbone.tail = bone.tail_local
- for bonelist in currentbone:
- if bone.name == bonelist[0]:
- newbone.roll = bonelist[1]
- break
- if bone.parent != None:
- parentbone = ob_new.data.edit_bones[bone.parent.name]
- newbone.parent = parentbone
- print("Bone Count:",len(obj.data.bones))
- print("Hold Bone Count",len(currentbone))
- print("New Bone Count",len(ob_new.data.edit_bones))
- print("Rebuild Armture Finish:",ob_new.name)
- bpy.context.scene.update()
- bselected = True
- break
- if bselected:
- self.report({'INFO'}, "Rebuild Armature Finish!")
- else:
- self.report({'INFO'}, "Didn't Select Armature Object!")
+ rebuildarmature(obj)
+ self.report({'INFO'}, "Rebuild Armature Finish!")
print("End of Rebuild Armature.")
print("----------------------------------------")
return{'FINISHED'}
class UDKActionSetListPG(bpy.types.PropertyGroup):
- bool = BoolProperty(default=False)
- string = StringProperty()
- actionname = StringProperty()
- bmatch = BoolProperty(default=False,name="Match", options={"HIDDEN"},description = "This check against bone names and action group names matches and override boolean if true.")
- bexport = BoolProperty(default=False,name="Export",description = "Check this to export the animation")
- template_list_controls = StringProperty(default="bmatch:bexport", options={"HIDDEN"})
+ bool = BoolProperty(default=False)
+ string = StringProperty()
+ actionname = StringProperty()
+ bmatch = BoolProperty(default=False,name="Match", options={"HIDDEN"},description = "This check against bone names and action group names matches and override boolean if true.")
+ bexport = BoolProperty(default=False,name="Export",description = "Check this to export the animation")
+ template_list_controls = StringProperty(default="bmatch:bexport", options={"HIDDEN"})
bpy.utils.register_class(UDKActionSetListPG)
bpy.types.Scene.udkas_list = CollectionProperty(type=UDKActionSetListPG)
bpy.types.Scene.udkas_list_idx = IntProperty()
class UDKObjListPG(bpy.types.PropertyGroup):
- bool = BoolProperty(default=False)
- string = StringProperty()
- bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This will be ignore when exported")
- bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "This will be ignore when exported")
- otype = StringProperty(name="Type",description = "This will be ignore when exported")
- template_list_controls = StringProperty(default="otype:bselect", options={"HIDDEN"})
+ bool = BoolProperty(default=False)
+ string = StringProperty()
+ bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This will be ignore when exported")
+ bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "This will be ignore when exported")
+ otype = StringProperty(name="Type",description = "This will be ignore when exported")
+ template_list_controls = StringProperty(default="otype:bselect", options={"HIDDEN"})
bpy.utils.register_class(UDKObjListPG)
bpy.types.Scene.udkobj_list = CollectionProperty(type=UDKObjListPG)
bpy.types.Scene.udkobj_list_idx = IntProperty()
class UDKMeshListPG(bpy.types.PropertyGroup):
- bool = BoolProperty(default=False)
- string = StringProperty()
- bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This object will be export when true.")
- bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "Make sure you have Mesh is parent to Armature.")
- otype = StringProperty(name="Type",description = "This will be ignore when exported")
- template_list_controls = StringProperty(default="bselect:bexport", options={"HIDDEN"})
+ bool = BoolProperty(default=False)
+ string = StringProperty()
+ bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This object will be export when true.")
+ bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "Make sure you have Mesh is parent to Armature.")
+ otype = StringProperty(name="Type",description = "This will be ignore when exported")
+ template_list_controls = StringProperty(default="bselect:bexport", options={"HIDDEN"})
bpy.utils.register_class(UDKMeshListPG)
bpy.types.Scene.udkmesh_list = CollectionProperty(type=UDKMeshListPG)
bpy.types.Scene.udkmesh_list_idx = IntProperty()
class UDKArmListPG(bpy.types.PropertyGroup):
- bool = BoolProperty(default=False)
- string = StringProperty()
- bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This will be ignore when exported")
- bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "This will be ignore when exported")
- otype = StringProperty(name="Type",description = "This will be ignore when exported")
- template_list_controls = StringProperty(default="", options={"HIDDEN"})
+ bool = BoolProperty(default=False)
+ string = StringProperty()
+ bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This will be ignore when exported")
+ bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "This will be ignore when exported")
+ otype = StringProperty(name="Type",description = "This will be ignore when exported")
+ template_list_controls = StringProperty(default="", options={"HIDDEN"})
bpy.utils.register_class(UDKArmListPG)
bpy.types.Scene.udkArm_list = CollectionProperty(type=UDKArmListPG)
@@ -2204,247 +2252,317 @@ bpy.types.Scene.udkArm_list_idx = IntProperty()
class Panel_UDKExport( bpy.types.Panel ):
- bl_label = "UDK Export"
- bl_idname = "OBJECT_PT_udk_tools"
- #bl_space_type = "PROPERTIES"
- #bl_region_type = "WINDOW"
- #bl_context = "object"
- bl_space_type = "VIEW_3D"
- bl_region_type = "TOOLS"
-
- #def draw_header(self, context):
- # layout = self.layout
- #obj = context.object
- #layout.prop(obj, "select", text="")
-
- #@classmethod
- #def poll(cls, context):
- # return context.active_object
-
- def draw(self, context):
- layout = self.layout
- path = get_dst_path()
-
- object_name = ""
- #if context.object:
- # object_name = context.object.name
- if context.active_object:
- object_name = context.active_object.name
- row10 = layout.row()
- row10.prop(context.scene, "udk_option_smoothing_groups")
- row10.prop(context.scene, "udk_option_clamp_uv")
- row10.prop(context.scene, "udk_option_verbose")
- #layout.prop(context.scene, "udk_option_smoothing_groups")
- #layout.prop(context.scene, "udk_option_clamp_uv")
- #layout.prop(context.scene, "udk_option_verbose")
- row = layout.row()
- row.label(text="Active object: " + object_name)
- #layout.separator()
- layout.prop(context.scene, "udk_option_filename_src")
- row = layout.row()
- row.label(text=path)
- #layout.separator()
- layout.prop(context.scene, "udk_option_export")
-
- row10 = layout.row()
-
- row10.prop(context.scene, "udk_option_selectanimations")
- row10.prop(context.scene, "udk_option_selectobjects")
-
- if context.scene.udk_option_selectobjects:
- layout.operator("object.selobjectpdate")
- #layout.template_list(context.scene, "udkobj_list", context.scene, "udkobj_list_idx",prop_list="template_list_controls", rows=5)
- layout.label(text="ARMATURE")
- layout.template_list(context.scene, "udkArm_list", context.scene, "udkArm_list_idx",prop_list="template_list_controls", rows=3)
- layout.label(text="MESH")
- layout.template_list(context.scene, "udkmesh_list", context.scene, "udkmesh_list_idx",prop_list="template_list_controls", rows=5)
-
- if context.scene.udk_option_selectanimations:
- layout.operator("action.setanimupdate")
- layout.label(text="Action Set(s)")
- layout.template_list(context.scene, "udkas_list", context.scene, "udkas_list_idx",prop_list="template_list_controls", rows=5)
- test = layout.separator()
- #test.operator("object.udk_export")
- row11 = layout.row()
- row11.operator("object.udk_export")
- row11.operator("object.toggle_console")
- layout.label(text="Armature")
- row12 = layout.row()
- row12.operator(OBJECT_OT_UTRebuildArmature.bl_idname)
- layout.label(text="Mesh")
- row13 = layout.row()
- row13.operator(OBJECT_OT_MeshClearWeights.bl_idname)
- row13.operator(OBJECT_OT_UTSelectedFaceSmooth.bl_idname)
- row13.operator(OBJECT_OT_UTRebuildMesh.bl_idname)
- #row13.box(name="Test")
-
+ bl_label = "UDK Export"
+ bl_idname = "OBJECT_PT_udk_tools"
+ #bl_space_type = "PROPERTIES"
+ #bl_region_type = "WINDOW"
+ #bl_context = "object"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+
+ #def draw_header(self, context):
+ # layout = self.layout
+ #obj = context.object
+ #layout.prop(obj, "select", text="")
+
+ #@classmethod
+ #def poll(cls, context):
+ # return context.active_object
+
+ def draw(self, context):
+ layout = self.layout
+ path = get_dst_path()
+
+ object_name = ""
+ #if context.object:
+ # object_name = context.object.name
+ if context.active_object:
+ object_name = context.active_object.name
+ row10 = layout.row()
+ row10.prop(context.scene, "udk_option_smoothing_groups")
+ row10.prop(context.scene, "udk_option_clamp_uv")
+ row10.prop(context.scene, "udk_option_verbose")
+ row = layout.row()
+ row.label(text="Active object: " + object_name)
+ #layout.separator()
+ layout.prop(context.scene, "udk_option_filename_src")
+ row = layout.row()
+ row.label(text=path)
+ #layout.separator()
+ layout.prop(context.scene, "udk_option_export")
+ layout.prop(context.scene, "udk_option_selectobjects")
+
+ if context.scene.udk_option_selectobjects:
+ layout.operator("object.selobjectpdate")
+ layout.label(text="ARMATURE")
+ layout.template_list(context.scene, "udkArm_list", context.scene, "udkArm_list_idx",prop_list="template_list_controls", rows=3)
+ layout.label(text="MESH")
+ layout.template_list(context.scene, "udkmesh_list", context.scene, "udkmesh_list_idx",prop_list="template_list_controls", rows=5)
+ layout.prop(context.scene, "udk_option_selectanimations")
+ if context.scene.udk_option_selectanimations:
+ layout.operator("action.setanimupdate")
+ layout.label(text="Action Set(s)")
+ layout.template_list(context.scene, "udkas_list", context.scene, "udkas_list_idx",prop_list="template_list_controls", rows=5)
+ test = layout.separator()
+ layout.prop(context.scene, "udk_option_scale")
+ layout.prop(context.scene, "udk_option_rebuildobjects")
+ #layout.prop(context.scene, "udk_option_ignoreactiongroupnames")
+ row11 = layout.row()
+ row11.operator("object.udk_export")
+ row11.operator("object.toggle_console")
+ layout.operator(OBJECT_OT_UTRebuildArmature.bl_idname)
+ layout.label(text="Mesh")
+ layout.operator(OBJECT_OT_MeshClearWeights.bl_idname)
+ layout.operator(OBJECT_OT_UTSelectedFaceSmooth.bl_idname)
+ layout.operator(OBJECT_OT_UTRebuildMesh.bl_idname)
+ layout.operator(OBJECT_OT_UDKCheckMeshLines.bl_idname)
+
def udkupdateobjects():
- my_objlist = bpy.context.scene.udkArm_list
- objectl = []
- for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
- if objarm.type == 'ARMATURE':
- objectl.append(objarm)
- for _objd in objectl:#check if list has in udk list
- bfound_obj = False
- for _obj in my_objlist:
- if _obj.name == _objd.name and _obj.otype == _objd.type:
- _obj.bselect = _objd.select
- bfound_obj = True
- break
- if bfound_obj == False:
- #print("ADD ARMATURE...")
- my_item = my_objlist.add()
- my_item.name = _objd.name
- my_item.bselect = _objd.select
- my_item.otype = _objd.type
- removeobject = []
- for _udkobj in my_objlist:
- bfound_objv = False
- for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
- if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
- bfound_objv = True
- break
- if bfound_objv == False:
- removeobject.append(_udkobj)
- #print("remove check...")
- for _item in removeobject: #loop remove object from udk list object
- count = 0
- for _obj in my_objlist:
- if _obj.name == _item.name and _obj.otype == _item.otype:
- my_objlist.remove(count)
- break
- count += 1
-
- my_objlist = bpy.context.scene.udkmesh_list
- objectl = []
- for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
- if objarm.type == 'MESH':
- objectl.append(objarm)
- for _objd in objectl:#check if list has in udk list
- bfound_obj = False
- for _obj in my_objlist:
- if _obj.name == _objd.name and _obj.otype == _objd.type:
- _obj.bselect = _objd.select
- bfound_obj = True
- break
- if bfound_obj == False:
- my_item = my_objlist.add()
- my_item.name = _objd.name
- my_item.bselect = _objd.select
- my_item.otype = _objd.type
- removeobject = []
- for _udkobj in my_objlist:
- bfound_objv = False
- for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
- if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
- bfound_objv = True
- break
- if bfound_objv == False:
- removeobject.append(_udkobj)
- #print("remove check...")
- for _item in removeobject: #loop remove object from udk list object
- count = 0
- for _obj in my_objlist:
- if _obj.name == _item.name and _obj.otype == _item.otype:
- my_objlist.remove(count)
- break
- count += 1
-
+ my_objlist = bpy.context.scene.udkArm_list
+ objectl = []
+ for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
+ if objarm.type == 'ARMATURE':
+ objectl.append(objarm)
+ for _objd in objectl:#check if list has in udk list
+ bfound_obj = False
+ for _obj in my_objlist:
+ if _obj.name == _objd.name and _obj.otype == _objd.type:
+ _obj.bselect = _objd.select
+ bfound_obj = True
+ break
+ if bfound_obj == False:
+ #print("ADD ARMATURE...")
+ my_item = my_objlist.add()
+ my_item.name = _objd.name
+ my_item.bselect = _objd.select
+ my_item.otype = _objd.type
+ removeobject = []
+ for _udkobj in my_objlist:
+ bfound_objv = False
+ for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
+ if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
+ bfound_objv = True
+ break
+ if bfound_objv == False:
+ removeobject.append(_udkobj)
+ #print("remove check...")
+ for _item in removeobject: #loop remove object from udk list object
+ count = 0
+ for _obj in my_objlist:
+ if _obj.name == _item.name and _obj.otype == _item.otype:
+ my_objlist.remove(count)
+ break
+ count += 1
+
+ my_objlist = bpy.context.scene.udkmesh_list
+ objectl = []
+ for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
+ if objarm.type == 'MESH':
+ objectl.append(objarm)
+ for _objd in objectl:#check if list has in udk list
+ bfound_obj = False
+ for _obj in my_objlist:
+ if _obj.name == _objd.name and _obj.otype == _objd.type:
+ _obj.bselect = _objd.select
+ bfound_obj = True
+ break
+ if bfound_obj == False:
+ my_item = my_objlist.add()
+ my_item.name = _objd.name
+ my_item.bselect = _objd.select
+ my_item.otype = _objd.type
+ removeobject = []
+ for _udkobj in my_objlist:
+ bfound_objv = False
+ for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
+ if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
+ bfound_objv = True
+ break
+ if bfound_objv == False:
+ removeobject.append(_udkobj)
+ #print("remove check...")
+ for _item in removeobject: #loop remove object from udk list object
+ count = 0
+ for _obj in my_objlist:
+ if _obj.name == _item.name and _obj.otype == _item.otype:
+ my_objlist.remove(count)
+ break
+ count += 1
+
class OBJECT_OT_UDKObjUpdate(bpy.types.Operator):
- bl_idname = "object.selobjectpdate"
- bl_label = "Update Object(s)"
- __doc__ = "This will update the filter of the mesh and armature."
- actionname = bpy.props.StringProperty()
+ bl_idname = "object.selobjectpdate"
+ bl_label = "Update Object(s)"
+ __doc__ = "This will update the filter of the mesh and armature."
+ actionname = bpy.props.StringProperty()
- def execute(self, context):
- udkupdateobjects()
- return{'FINISHED'}
+ def execute(self, context):
+ udkupdateobjects()
+ return{'FINISHED'}
+
+def udkcheckmeshline():
+ objmesh = None
+ for obj in bpy.context.scene.objects:
+ if obj.type == 'MESH' and obj.select == True:
+ objmesh = obj
+ objmesh = triangulate_mesh(objmesh) #create a copy of the mesh
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for i in bpy.context.scene.objects: i.select = False # deselect all objects
+ objmesh.select = True
+ bpy.context.scene.objects.active = objmesh #set active mesh
+ wedges = ObjMap()
+ points = ObjMap()
+ bpy.ops.object.mode_set(mode='EDIT') #set in edit mode
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.context.tool_settings.mesh_select_mode = (True, False, False) #select vertices
+
+ if objmesh != None:
+ print("found mesh")
+ print(objmesh)
+ print(objmesh.data.tessfaces)
+ vertex_list = []
+ for face in objmesh.data.tessfaces:
+ wedge_list = []
+ vect_list = []
+ for i in range(3):
+ vert_index = face.vertices[i]
+ vert = objmesh.data.vertices[vert_index]
+ vect_list.append( FVector(vert.co.x, vert.co.y, vert.co.z) )
+ vpos = objmesh.matrix_local * vert.co
+ p = VPoint()
+ p.Point.X = vpos.x
+ p.Point.Y = vpos.y
+ p.Point.Z = vpos.z
+ w = VVertex()
+ w.PointIndex = points.get(p) # store keys
+ index_wedge = wedges.get(w)
+ wedge_list.append(index_wedge)
+ no = face.normal
+ norm = FVector(no[0], no[1], no[2])
+ tnorm = vect_list[1].sub(vect_list[0]).cross(vect_list[2].sub(vect_list[1]))
+ dot = norm.dot(tnorm)
+
+ tri = VTriangle()
+ if dot > 0:
+ (tri.WedgeIndex2, tri.WedgeIndex1, tri.WedgeIndex0) = wedge_list
+ elif dot < 0:
+ (tri.WedgeIndex0, tri.WedgeIndex1, tri.WedgeIndex2) = wedge_list
+ else:
+ dindex0 = face.vertices[0];
+ dindex1 = face.vertices[1];
+ dindex2 = face.vertices[2];
+ vertex_list.append(dindex0)
+ vertex_list.append(dindex1)
+ vertex_list.append(dindex2)
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for vertex in objmesh.data.vertices: #loop all vertex in the mesh list
+ for vl in vertex_list: #loop for error vertex
+ if vertex.index == vl: #if match set to select
+ vertex.select = True
+ break
+ bpy.ops.object.mode_set(mode='EDIT') #set in edit mode to see the select vertex
+ objmesh.data.update() # update object
+ bpy.context.scene.update() #update scene
+ message = "MESH PASS"
+ if len(vertex_list) > 0:
+ message = "MESH FAIL"
+ return message
+
+class OBJECT_OT_UDKCheckMeshLines(bpy.types.Operator):
+ bl_idname = "object.udkcheckmeshline"
+ bl_label = "Check Mesh Vertices"
+ __doc__ = """Select the mesh for export test. This will create dummy mesh to see which area are broken. If the vertices share the same position it will causes an bug."""
+
+ def execute(self, context):
+ message = udkcheckmeshline()
+ self.report({'ERROR'}, message)
+ return{'FINISHED'}
class OBJECT_OT_ActionSetAnimUpdate(bpy.types.Operator):
- bl_idname = "action.setanimupdate"
- bl_label = "Update Action Set(s)"
- __doc__ = "Select Armture to match the action set groups. All bones keys must be set to match with number of bones."
- actionname = bpy.props.StringProperty()
+ bl_idname = "action.setanimupdate"
+ bl_label = "Update Action Set(s)"
+ __doc__ = "Select Armture to match the action set groups. All bones keys must be set to match with number of bones."
+ actionname = bpy.props.StringProperty()
- def execute(self, context):
- my_sett = bpy.context.scene.udkas_list
-
- bones = []
- armature = None
- armatures = []
- armatureselected = []
- for objarm in bpy.context.scene.objects:
- if objarm.type == 'ARMATURE':
- #print("ADDED ARMATURE...")
- armatures.append(objarm)
- if objarm.select == True:
- armatureselected.append(objarm)
-
- if len(armatureselected) == len(armatures) == 1:
- armature = armatures[0]
- if len(armatures) == 1:
- armature = armatures[0]
- if len(armatureselected) == 1:
- armature = armatureselected[0]
-
- if armature != None:
- for bone in armature.pose.bones:
- bones.append(bone.name)
-
- for action in bpy.data.actions:#action list
- bfound = False
- count = 0
- for actionbone in action.groups:
- #print("Pose bone name: ",actionbone.name)
- for b in bones:
- if b == actionbone.name:
- count += 1
- #print(b," : ",actionbone.name)
- break
- for actionlist in my_sett:
- if action.name == actionlist.name:
- bactionfound = True
- if len(bones) == len(action.groups) == count:
- actionlist.bmatch = True
- else:
- actionlist.bmatch = False
- bfound = True
- break
- if bfound != True:
- my_item = my_sett.add()
- #print(dir(my_item.bmatch))
- my_item.name = action.name
- my_item.template_list_controls = "bmatch:bexport"
- if len(bones) == len(action.groups) == count:
- my_item.bmatch = True
- else:
- my_item.bmatch = False
- removeactions = []
- #check action list and data actions
- for actionlist in bpy.context.scene.udkas_list:
- bfind = False
- notfound = 0
- for act in bpy.data.actions:
- if actionlist.name == act.name:
- bfind = True
- else:
- notfound += 1
- #print("ACT NAME:",actionlist.name," COUNT",notfound)
- if notfound == len(bpy.data.actions):
- #print("remove :",actionlist.name)
- removeactions.append(actionlist.name)
- #print("Not in the action data list:",len(removeactions))
- #remove list or chnages in the name the template list
- for actname in removeactions:
- actioncount = 0
- for actionlist in my_sett:
- #print("action name:",actionlist.name)
- if actionlist.name == actname:
- my_sett.remove(actioncount);
- break
- actioncount += 1
- return{'FINISHED'}
-
+ def execute(self, context):
+ my_sett = bpy.context.scene.udkas_list
+
+ bones = []
+ armature = None
+ armatures = []
+ armatureselected = []
+ for objarm in bpy.context.scene.objects:
+ if objarm.type == 'ARMATURE':
+ #print("ADDED ARMATURE...")
+ armatures.append(objarm)
+ if objarm.select == True:
+ armatureselected.append(objarm)
+
+ if len(armatureselected) == len(armatures) == 1:
+ armature = armatures[0]
+ if len(armatures) == 1:
+ armature = armatures[0]
+ if len(armatureselected) == 1:
+ armature = armatureselected[0]
+
+ if armature != None:
+ for bone in armature.pose.bones:
+ bones.append(bone.name)
+
+ for action in bpy.data.actions:#action list
+ bfound = False
+ count = 0
+ for actionbone in action.groups:
+ #print("Pose bone name: ",actionbone.name)
+ for b in bones:
+ if b == actionbone.name:
+ count += 1
+ #print(b," : ",actionbone.name)
+ break
+ for actionlist in my_sett:
+ if action.name == actionlist.name:
+ bactionfound = True
+ if len(bones) == len(action.groups) == count:
+ actionlist.bmatch = True
+ else:
+ actionlist.bmatch = False
+ bfound = True
+ break
+ if bfound != True:
+ my_item = my_sett.add()
+ #print(dir(my_item.bmatch))
+ my_item.name = action.name
+ my_item.template_list_controls = "bmatch:bexport"
+ if len(bones) == len(action.groups) == count:
+ my_item.bmatch = True
+ else:
+ my_item.bmatch = False
+ removeactions = []
+ #check action list and data actions
+ for actionlist in bpy.context.scene.udkas_list:
+ bfind = False
+ notfound = 0
+ for act in bpy.data.actions:
+ if actionlist.name == act.name:
+ bfind = True
+ else:
+ notfound += 1
+ #print("ACT NAME:",actionlist.name," COUNT",notfound)
+ if notfound == len(bpy.data.actions):
+ #print("remove :",actionlist.name)
+ removeactions.append(actionlist.name)
+ #print("Not in the action data list:",len(removeactions))
+ #remove list or chnages in the name the template list
+ for actname in removeactions:
+ actioncount = 0
+ for actionlist in my_sett:
+ #print("action name:",actionlist.name)
+ if actionlist.name == actname:
+ my_sett.remove(actioncount);
+ break
+ actioncount += 1
+ return{'FINISHED'}
+
class ExportUDKAnimData(bpy.types.Operator):
"""Export Skeleton Mesh / Animation Data file(s)"""
bl_idname = "export_anim.udk" # this is important since its how bpy.ops.export.udk_anim_data is constructed
@@ -2466,6 +2584,8 @@ class ExportUDKAnimData(bpy.types.Operator):
udk_option_verbose = bpy.types.Scene.udk_option_verbose
udk_option_filename_src = bpy.types.Scene.udk_option_filename_src
udk_option_export = bpy.types.Scene.udk_option_export
+ udk_option_scale = bpy.types.Scene.udk_option_scale
+ udk_option_rebuildobjects = bpy.types.Scene.udk_option_rebuildobjects
@classmethod
def poll(cls, context):
@@ -2473,14 +2593,16 @@ class ExportUDKAnimData(bpy.types.Operator):
def execute(self, context):
scene = bpy.context.scene
- scene.udk_option_export_psk = (scene.udk_option_export == '0' or scene.udk_option_export == '2')
- scene.udk_option_export_psa = (scene.udk_option_export == '1' or scene.udk_option_export == '2')
-
+ scene.udk_option_export_psk = (scene.udk_option_export == '0' or scene.udk_option_export == '2')
+ scene.udk_option_export_psa = (scene.udk_option_export == '1' or scene.udk_option_export == '2')
+ bpy.context.scene.udk_option_scale = self.udk_option_scale
+ bpy.context.scene.udk_option_rebuildobjects = self.udk_option_rebuildobjects
+
filepath = get_dst_path()
-
- # cache settings
+
+ # cache settings
restore_frame = scene.frame_current
-
+
message = "Finish Export!"
try:
export(filepath)
@@ -2488,8 +2610,8 @@ class ExportUDKAnimData(bpy.types.Operator):
except Error as err:
print(err.message)
message = err.message
-
- # restore settings
+
+ # restore settings
scene.frame_set(restore_frame)
self.report({'WARNING', 'INFO'}, message)
@@ -2499,7 +2621,7 @@ class ExportUDKAnimData(bpy.types.Operator):
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
-
+
def menu_func(self, context):
default_path = os.path.splitext(bpy.data.filepath)[0] + ".psk"
self.layout.operator(ExportUDKAnimData.bl_idname, text="Skeleton Mesh / Animation Data (.psk/.psa)").filepath = default_path
@@ -2508,20 +2630,20 @@ def menu_func(self, context):
# Entry
#===========================================================================
def register():
- #print("REGISTER")
- bpy.utils.register_module(__name__)
- bpy.types.INFO_MT_file_export.append(menu_func)
-
+ #print("REGISTER")
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_file_export.append(menu_func)
+
def unregister():
- #print("UNREGISTER")
- bpy.utils.unregister_module(__name__)
- bpy.types.INFO_MT_file_export.remove(menu_func)
-
+ #print("UNREGISTER")
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_file_export.remove(menu_func)
+
if __name__ == "__main__":
- #print("\n"*4)
- print(header("UDK Export PSK/PSA 2.6", 'CENTER'))
- register()
-
+ #print("\n"*4)
+ print(header("UDK Export PSK/PSA 2.6", 'CENTER'))
+ register()
+
#loader
#filename = "D:/Projects/BlenderScripts/io_export_udk_psa_psk_alpha.py"
#exec(compile(open(filename).read(), filename, 'exec'))
diff --git a/release/scripts/addons/io_import_gimp_image_to_scene.py b/release/scripts/addons/io_import_gimp_image_to_scene.py
index bc09c75..e9aaf86 100644
--- a/release/scripts/addons/io_import_gimp_image_to_scene.py
+++ b/release/scripts/addons/io_import_gimp_image_to_scene.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Import GIMP Image to Scene (.xcf/.xjt)",
"author": "Daniel Salazar (ZanQdo)",
"version": (2, 0, 0),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import > GIMP Image to Scene(.xcf/.xjt)",
"description": "Imports GIMP multilayer image files as a series of multiple planes",
"warning": "XCF import requires xcftools installed",
@@ -35,7 +35,7 @@ This script imports GIMP layered image files into 3D Scenes (.xcf, .xjt)
"""
def main(File, Path, LayerViewers, MixerViewers, LayerOffset,
- LayerScale, OpacityMode, PremulAlpha, ShadelessMats,
+ LayerScale, OpacityMode, AlphaMode, ShadelessMats,
SetCamera, SetupCompo, GroupUntagged, Ext):
#-------------------------------------------------
@@ -238,7 +238,7 @@ def main(File, Path, LayerViewers, MixerViewers, LayerOffset,
Render.resolution_x = ResX
Render.resolution_y = ResY
Render.resolution_percentage = 100
- if PremulAlpha: Render.alpha_mode = 'PREMUL'
+ Render.alpha_mode = 'TRANSPARENT'
#-------------------------------------------------
# 3D VIEW SETTINGS
@@ -347,7 +347,7 @@ def main(File, Path, LayerViewers, MixerViewers, LayerOffset,
Img = bpy.data.images.new(NameShort, 128, 128)
Img.source = 'FILE'
- if PremulAlpha: Img.use_premultiply = True
+ Img.alpha_mode = AlphaMode
Img.filepath = '%s%s%s' % (PathSaveRaw, Name, ExtSave)
UVFace = Active.data.uv_textures[0].data[0]
@@ -391,7 +391,7 @@ def main(File, Path, LayerViewers, MixerViewers, LayerOffset,
Img = bpy.data.images.new(NameShort+'_A', 128, 128)
Img.source = 'FILE'
- if PremulAlpha: Img.use_premultiply = True
+ Img.alpha_mode = AlphaMode
Img.filepath = '%s%s_A%s' % (PathSaveRaw, Name, ExtSave)
Tex.image = Img
@@ -560,9 +560,12 @@ class GIMPImageToScene(bpy.types.Operator):
description="Add Viewer nodes to each Mix node",
default=True)
- PremulAlpha = BoolProperty(name="Premuliply Alpha",
- description="Set Image and Render settings to premultiplied alpha",
- default=True)
+ AlphaMode = EnumProperty(name="Alpha Mode",
+ description="Representation of alpha information in the RGBA pixels",
+ items=(
+ ('STRAIGHT', 'Texture Alpha Factor', 'Transparent RGB and alpha pixels are unmodified'),
+ ('PREMUL', 'Material Alpha Value', 'Transparent RGB pixels are multiplied by the alpha channel')),
+ default='STRAIGHT')
ShadelessMats = BoolProperty(name="Shadeless Material",
description="Set Materials as Shadeless",
@@ -608,7 +611,7 @@ class GIMPImageToScene(bpy.types.Operator):
box.prop(self, 'OpacityMode', icon='GHOST')
if self.OpacityMode == 'COMPO' and self.SetupCompo == False:
box.label('Tip: Enable Node Compositing', icon='INFO')
- box.prop(self, 'PremulAlpha', icon='IMAGE_RGB_ALPHA')
+ box.prop(self, 'AlphaMode', icon='IMAGE_RGB_ALPHA')
box.prop(self, 'ShadelessMats', icon='SOLID')
box.prop(self, 'LayerOffset')
box.prop(self, 'LayerScale')
@@ -630,7 +633,7 @@ class GIMPImageToScene(bpy.types.Operator):
LayerViewers = self.LayerViewers
MixerViewers = self.MixerViewers
OpacityMode = self.OpacityMode
- PremulAlpha = self.PremulAlpha
+ AlphaMode = self.AlphaMode
ShadelessMats = self.ShadelessMats
SetCamera = self.SetCamera
SetupCompo = self.SetupCompo
@@ -645,7 +648,7 @@ class GIMPImageToScene(bpy.types.Operator):
# Call Main Function
if Ext:
main(filename, directory, LayerViewers, MixerViewers, LayerOffset,
- LayerScale, OpacityMode, PremulAlpha, ShadelessMats,
+ LayerScale, OpacityMode, AlphaMode, ShadelessMats,
SetCamera, SetupCompo, GroupUntagged, Ext)
else:
self.report({'ERROR'},"Selected file wasn't valid, try .xcf or .xjt")
diff --git a/release/scripts/addons/io_import_images_as_planes.py b/release/scripts/addons/io_import_images_as_planes.py
index d072453..5f872e1 100644
--- a/release/scripts/addons/io_import_images_as_planes.py
+++ b/release/scripts/addons/io_import_images_as_planes.py
@@ -20,15 +20,13 @@ bl_info = {
"name": "Import Images as Planes",
"author": "Florian Meyer (tstscr), mont29, matali",
"version": (1, 7),
- "blender": (2, 6, 5),
+ "blender": (2, 65, 0),
"location": "File > Import > Images as Planes or Add > Mesh > Images as Planes",
- "description": "Imports images and creates planes with the appropriate "
- "aspect ratio. The images are mapped to the planes.",
+ "description": "Imports images and creates planes with the appropriate aspect ratio. "
+ "The images are mapped to the planes.",
"warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Add_Mesh/Planes_from_Images",
- "tracker_url": "https://projects.blender.org/tracker/index.php?"
- "func=detail&aid=21751",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Add_Mesh/Planes_from_Images",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=21751",
"category": "Import-Export"}
import bpy
@@ -51,11 +49,11 @@ from bpy_extras.image_utils import load_image
# -----------------------------------------------------------------------------
# Global Vars
+DEFAULT_EXT = "*"
+
EXT_FILTER = getattr(collections, "OrderedDict", dict)((
- ("*", ((), "All image formats",
- "Import all know image (or movie) formats.")),
- ("jpeg", (("jpeg", "jpg", "jpe"), "JPEG ({})",
- "Joint Photographic Experts Group")),
+ (DEFAULT_EXT, ((), "All image formats", "Import all know image (or movie) formats.")),
+ ("jpeg", (("jpeg", "jpg", "jpe"), "JPEG ({})", "Joint Photographic Experts Group")),
("png", (("png", ), "PNG ({})", "Portable Network Graphics")),
("tga", (("tga", "tpic"), "Truevision TGA ({})", "")),
("tiff", (("tiff", "tif"), "TIFF ({})", "Tagged Image File Format")),
@@ -69,33 +67,27 @@ EXT_FILTER = getattr(collections, "OrderedDict", dict)((
("mov", (("mov", "qt"), "QuickTime ({})", "")),
("mp4", (("mp4", ), "MPEG-4 ({})", "MPEG-4 Part 14")),
("ogg", (("ogg", "ogv"), "OGG Theora ({})", "")),
- ))
+))
# XXX Hack to avoid allowing videos with Cycles, crashes currently!
-VID_EXT_FILTER = {e for ext_k, ext_v in EXT_FILTER.items()
- if ext_k in {"avi", "mov", "mp4", "ogg"}
- for e in ext_v[0]}
+VID_EXT_FILTER = {e for ext_k, ext_v in EXT_FILTER.items() if ext_k in {"avi", "mov", "mp4", "ogg"} for e in ext_v[0]}
CYCLES_SHADERS = (
('BSDF_DIFFUSE', "Diffuse", "Diffuse Shader"),
('EMISSION', "Emission", "Emission Shader"),
- ('BSDF_DIFFUSE_BSDF_TRANSPARENT', "Diffuse & Transparent",
- "Diffuse and Transparent Mix"),
- ('EMISSION_BSDF_TRANSPARENT', "Emission & Transparent",
- "Emission and Transparent Mix")
+ ('BSDF_DIFFUSE_BSDF_TRANSPARENT', "Diffuse & Transparent", "Diffuse and Transparent Mix"),
+ ('EMISSION_BSDF_TRANSPARENT', "Emission & Transparent", "Emission and Transparent Mix")
)
# -----------------------------------------------------------------------------
# Misc utils.
def gen_ext_filter_ui_items():
- return ((k,
- name.format(", ".join("." + e for e in exts)) if "{}" in name else name,
- desc)
- for k, (exts, name, desc) in EXT_FILTER.items())
+ return tuple((k, name.format(", ".join("." + e for e in exts)) if "{}" in name else name, desc)
+ for k, (exts, name, desc) in EXT_FILTER.items())
def is_image_fn(fn, ext_key):
- if ext_key == "*":
+ if ext_key == DEFAULT_EXT:
return True # Using Blender's image/movie filter.
ext = os.path.splitext(fn)[1].lstrip(".").lower()
return ext in EXT_FILTER[ext_key][0]
@@ -162,20 +154,16 @@ def clean_node_tree(node_tree):
# Operator
class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
- """Create mesh plane(s) from image files """ \
- """with the appropiate aspect ratio"""
-
+ """Create mesh plane(s) from image files with the appropiate aspect ratio"""
bl_idname = "import_image.to_plane"
bl_label = "Import Images as Planes"
bl_options = {'REGISTER', 'UNDO'}
# -----------
# File props.
- files = CollectionProperty(type=bpy.types.OperatorFileListElement,
- options={'HIDDEN', 'SKIP_SAVE'})
+ files = CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'})
- directory = StringProperty(maxlen=1024, subtype='FILE_PATH',
- options={'HIDDEN', 'SKIP_SAVE'})
+ directory = StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'})
# Show only images/videos, and directories!
filter_image = BoolProperty(default=True, options={'HIDDEN', 'SKIP_SAVE'})
@@ -185,17 +173,14 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
# --------
# Options.
- align = BoolProperty(name="Align Planes", default=True,
- description="Create Planes in a row")
+ align = BoolProperty(name="Align Planes", default=True, description="Create Planes in a row")
- align_offset = FloatProperty(name="Offset", min=0, soft_min=0, default=0.1,
- description="Space between Planes")
+ align_offset = FloatProperty(name="Offset", min=0, soft_min=0, default=0.1, description="Space between Planes")
- # Callback which will update File window's filter options accordingly
- # to extension setting.
+ # Callback which will update File window's filter options accordingly to extension setting.
def update_extensions(self, context):
is_cycles = context.scene.render.engine == 'CYCLES'
- if self.extension == "*":
+ if self.extension == DEFAULT_EXT:
self.filter_image = True
# XXX Hack to avoid allowing videos with Cycles, crashes currently!
self.filter_movie = True and not is_cycles
@@ -205,17 +190,14 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
self.filter_movie = False
if is_cycles:
# XXX Hack to avoid allowing videos with Cycles!
- flt = ";".join(("*." + e for e in EXT_FILTER[self.extension][0]
- if e not in VID_EXT_FILTER))
+ flt = ";".join(("*." + e for e in EXT_FILTER[self.extension][0] if e not in VID_EXT_FILTER))
else:
- flt = ";".join(("*." + e
- for e in EXT_FILTER[self.extension][0]))
+ flt = ";".join(("*." + e for e in EXT_FILTER[self.extension][0]))
self.filter_glob = flt
# And now update space (file select window), if possible.
space = bpy.context.space_data
# XXX Can't use direct op comparison, these are not the same objects!
- if (space.type != 'FILE_BROWSER' or
- space.operator.bl_rna.identifier != self.bl_rna.identifier):
+ if (space.type != 'FILE_BROWSER' or space.operator.bl_rna.identifier != self.bl_rna.identifier):
return
space.params.use_filter_image = self.filter_image
space.params.use_filter_movie = self.filter_movie
@@ -223,8 +205,7 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
# XXX Seems to be necessary, else not all changes above take effect...
bpy.ops.file.refresh()
extension = EnumProperty(name="Extension", items=gen_ext_filter_ui_items(),
- description="Only import files of this type",
- update=update_extensions)
+ description="Only import files of this type", update=update_extensions)
# -------------------
# Plane size options.
@@ -245,53 +226,41 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
# -------------------------
# Blender material options.
t = bpy.types.Material.bl_rna.properties["use_shadeless"]
- use_shadeless = BoolProperty(name=t.name, default=False,
- description=t.description)
+ use_shadeless = BoolProperty(name=t.name, default=False, description=t.description)
- use_transparency = BoolProperty(name="Use Alpha", default=False,
- description="Use alphachannel for "
- "transparency")
+ use_transparency = BoolProperty(name="Use Alpha", default=False, description="Use alphachannel for transparency")
t = bpy.types.Material.bl_rna.properties["transparency_method"]
- items = ((it.identifier, it.name, it.description) for it in t.enum_items)
- transparency_method = EnumProperty(name="Transp. Method",
- description=t.description,
- items=items)
+ items = tuple((it.identifier, it.name, it.description) for it in t.enum_items)
+ transparency_method = EnumProperty(name="Transp. Method", description=t.description, items=items)
t = bpy.types.Material.bl_rna.properties["use_transparent_shadows"]
- use_transparent_shadows = BoolProperty(name=t.name, default=False,
- description=t.description)
+ use_transparent_shadows = BoolProperty(name=t.name, default=False, description=t.description)
#-------------------------
# Cycles material options.
- shader = EnumProperty(name="Shader", items=CYCLES_SHADERS,
- description="Node shader to use")
+ shader = EnumProperty(name="Shader", items=CYCLES_SHADERS, description="Node shader to use")
overwrite_node_tree = BoolProperty(name="Overwrite Material", default=True,
- description="Overwrite existing "
- "Material with new nodetree (based "
- "on material name)")
+ description="Overwrite existing Material with new nodetree "
+ "(based on material name)")
# --------------
# Image Options.
- t = bpy.types.Image.bl_rna.properties["use_premultiply"]
- use_premultiply = BoolProperty(name=t.name, default=False,
- description=t.description)
+ t = bpy.types.Image.bl_rna.properties["alpha_mode"]
+ alpha_mode_items = tuple((e.identifier, e.name, e.description) for e in t.enum_items)
+ alpha_mode = EnumProperty(name=t.name, items=alpha_mode_items, default=t.default, description=t.description)
t = bpy.types.IMAGE_OT_match_movie_length.bl_rna
- match_len = BoolProperty(name=t.name, default=True,
- description=t.description)
+ match_len = BoolProperty(name=t.name, default=True, description=t.description)
t = bpy.types.Image.bl_rna.properties["use_fields"]
- use_fields = BoolProperty(name=t.name, default=False,
- description=t.description)
+ use_fields = BoolProperty(name=t.name, default=False, description=t.description)
t = bpy.types.ImageUser.bl_rna.properties["use_auto_refresh"]
- use_auto_refresh = BoolProperty(name=t.name, default=True,
- description=t.description)
+ use_auto_refresh = BoolProperty(name=t.name, default=True, description=t.description)
- relative = BoolProperty(name="Relative", default=True,
- description="Apply relative paths")
+ relative = BoolProperty(name="Relative", default=True, description="Apply relative paths")
def draw(self, context):
engine = context.scene.render.engine
@@ -317,7 +286,7 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
box.label("Material Settings: (Blender)", icon='MATERIAL')
box.prop(self, "use_shadeless")
box.prop(self, "use_transparency")
- box.prop(self, "use_premultiply")
+ box.prop(self, "alpha_mode")
row = box.row()
row.prop(self, "transparency_method", expand=True)
box.prop(self, "use_transparent_shadows")
@@ -345,9 +314,7 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
if not bpy.data.is_saved:
self.relative = False
- # the add utils don't work in this case
- # because many objects are added
- # disable relevant things beforehand
+ # the add utils don't work in this case because many objects are added disable relevant things beforehand
editmode = context.user_preferences.edit.use_enter_edit_mode
context.user_preferences.edit.use_enter_edit_mode = False
if (context.active_object and
@@ -372,14 +339,12 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
self.set_image_options(img)
textures.append(self.create_image_textures(context, img))
- materials = (self.create_material_for_texture(tex)
- for tex in textures)
+ materials = (self.create_material_for_texture(tex) for tex in textures)
elif engine == 'CYCLES':
materials = (self.create_cycles_material(img) for img in images)
- planes = tuple(self.create_image_plane(context, mat)
- for mat in materials)
+ planes = tuple(self.create_image_plane(context, mat) for mat in materials)
context.scene.update()
if self.align:
@@ -410,7 +375,7 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
fact = 1 / self.factor / context.scene.unit_settings.scale_length * 0.0254 / 2
x = px * fact
y = py * fact
- else: # self.size_mode == 'DPBU'
+ else: # elif self.size_mode == 'DPBU'
fact = 1 / self.factor / 2
x = px * fact
y = py * fact
@@ -448,8 +413,7 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
offset += (plane.dimensions.x / 2.0)
def generate_paths(self):
- return (fn.name for fn in self.files
- if is_image_fn(fn.name, self.extension)), self.directory
+ return (fn.name for fn in self.files if is_image_fn(fn.name, self.extension)), self.directory
# Internal
def create_image_textures(self, context, image):
@@ -490,14 +454,14 @@ class IMPORT_OT_image_to_plane(Operator, AddObjectHelper):
return material
def set_image_options(self, image):
- image.use_premultiply = self.use_premultiply
+ image.alpha_mode = self.alpha_mode
image.use_fields = self.use_fields
if self.relative:
image.filepath = bpy.path.relpath(image.filepath)
def set_texture_options(self, context, texture):
- texture.use_alpha = self.use_transparency
+ texture.image.use_alpha = self.use_transparency
texture.image_user.use_auto_refresh = self.use_auto_refresh
if self.match_len:
ctx = context.copy()
diff --git a/release/scripts/addons/io_import_scene_dxf.py b/release/scripts/addons/io_import_scene_dxf.py
index f0cc671..f45d964 100644
--- a/release/scripts/addons/io_import_scene_dxf.py
+++ b/release/scripts/addons/io_import_scene_dxf.py
@@ -17,19 +17,19 @@
# ##### END GPL LICENSE BLOCK #####
bl_info = {
- 'name': 'Import Autocad DXF Format (.dxf)',
- 'author': 'Thomas Larsson, Remigiusz Fiedler',
- 'version': (0, 1, 6),
- 'blender': (2, 6, 3),
- 'location': 'File > Import > Autocad (.dxf)',
- 'description': 'Import files in the Autocad DXF format (.dxf)',
- 'warning': 'Under construction! Visit Wiki for details.',
- 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/'\
- 'Scripts/Import-Export/DXF_Importer',
- 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
- 'func=detail&aid=23480',
- 'support': 'OFFICIAL',
- 'category': 'Import-Export',
+ "name": "Import Autocad DXF Format (.dxf)",
+ "author": "Thomas Larsson, Remigiusz Fiedler",
+ "version": (0, 1, 6),
+ "blender": (2, 63, 0),
+ "location": "File > Import > Autocad (.dxf)",
+ "description": "Import files in the Autocad DXF format (.dxf)",
+ "warning": "Under construction! Visit Wiki for details.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Import-Export/DXF_Importer",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=23480",
+ "support": "OFFICIAL",
+ "category": "Import-Export",
}
"""
diff --git a/release/scripts/addons/io_import_scene_lwo.py b/release/scripts/addons/io_import_scene_lwo.py
index fac7ff9..e711718 100644
--- a/release/scripts/addons/io_import_scene_lwo.py
+++ b/release/scripts/addons/io_import_scene_lwo.py
@@ -20,7 +20,7 @@ bl_info= {
"name": "Import LightWave Objects",
"author": "Ken Nign (Ken9)",
"version": (1, 2),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import > LightWave Object (.lwo)",
"description": "Imports a LWO file including any UV, Morph and Color maps. "\
"Can convert Skelegons to an Armature.",
diff --git a/release/scripts/addons/io_import_scene_mhx.py b/release/scripts/addons/io_import_scene_mhx.py
index c1c9145..0ac4f04 100644
--- a/release/scripts/addons/io_import_scene_mhx.py
+++ b/release/scripts/addons/io_import_scene_mhx.py
@@ -40,7 +40,7 @@ bl_info = {
'name': 'Import: MakeHuman (.mhx)',
'author': 'Thomas Larsson',
'version': (1, 14, 1),
- "blender": (2, 6, 4),
+ "blender": (2, 65, 0),
'location': "File > Import > MakeHuman (.mhx)",
'description': 'Import files in the MakeHuman eXchange format (.mhx)',
'warning': '',
@@ -840,7 +840,7 @@ def parseTexture(args, tokens):
tex.use_nodes = True
parseNodeTree(tex.node_tree, val, sub)
else:
- defaultKey(key, val, sub, "tex", ['use_nodes', 'use_textures', 'contrast'], globals(), locals())
+ defaultKey(key, val, sub, "tex", ['use_nodes', 'use_textures', 'contrast', 'use_alpha'], globals(), locals())
return tex
@@ -998,7 +998,7 @@ def parseImage(args, tokens):
return None
img.name = imgName
else:
- defaultKey(key, val, sub, "img", ['depth', 'dirty', 'has_data', 'size', 'type'], globals(), locals())
+ defaultKey(key, val, sub, "img", ['depth', 'dirty', 'has_data', 'size', 'type', 'use_premultiply'], globals(), locals())
print ("Image %s" % img )
loadedData['Image'][imgName] = img
return img
@@ -2058,7 +2058,7 @@ def correctRig(args):
ob = loadedData['Object'][human]
except:
return
- ob.MhxShapekeyDrivers = (toggle&T_Shapekeys and toggle&T_ShapeDrivers)
+ ob.MhxShapekeyDrivers = (toggle&T_Shapekeys != 0 and toggle&T_ShapeDrivers != 0)
bpy.context.scene.objects.active = ob
bpy.ops.object.mode_set(mode='POSE')
amt = ob.data
@@ -3027,7 +3027,7 @@ class ImportMhx(bpy.types.Operator, ImportHelper):
scale = FloatProperty(name="Scale", description="Default meter, decimeter = 1.0", default = theScale)
advanced = BoolProperty(name="Advanced settings", description="Use advanced import settings", default=False)
for (prop, name, desc, flag) in MhxBoolProps:
- expr = '%s = BoolProperty(name="%s", description="%s", default=toggleSettings&%s)' % (prop, name, desc, flag)
+ expr = '%s = BoolProperty(name="%s", description="%s", default=(toggleSettings&%s != 0))' % (prop, name, desc, flag)
exec(expr)
@@ -3070,7 +3070,7 @@ class ImportMhx(bpy.types.Operator, ImportHelper):
readDefaults()
self.scale = theScale
for (prop, name, desc, flag) in MhxBoolProps:
- expr = 'self.%s = toggle&%s' % (prop, flag)
+ expr = 'self.%s = (toggle&%s != 0)' % (prop, flag)
exec(expr)
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
@@ -4013,8 +4013,11 @@ def fk2ikArm(context, suffix):
rig = context.object
auto = context.scene.tool_settings.use_keyframe_insert_auto
print("Snap FK Arm%s" % suffix)
- (uparmIk, loarmIk, elbow, elbowPt, wrist) = getSnapBones(rig, "ArmIK", suffix)
- (uparmFk, loarmFk, elbowPtFk, handFk) = getSnapBones(rig, "ArmFK", suffix)
+ snapIk,cnsIk = getSnapBones(rig, "ArmIK", suffix)
+ (uparmIk, loarmIk, elbow, elbowPt, wrist) = snapIk
+ snapFk,cnsFk = getSnapBones(rig, "ArmFK", suffix)
+ (uparmFk, loarmFk, elbowPtFk, handFk) = snapFk
+ muteConstraints(cnsFk, True)
matchPoseRotation(uparmFk, uparmFk, auto)
matchPoseScale(uparmFk, uparmFk, auto)
@@ -4025,6 +4028,8 @@ def fk2ikArm(context, suffix):
if rig["MhaHandFollowsWrist" + suffix]:
matchPoseRotation(handFk, wrist, auto)
matchPoseScale(handFk, wrist, auto)
+
+ muteConstraints(cnsFk, False)
return
@@ -4033,8 +4038,11 @@ def ik2fkArm(context, suffix):
scn = context.scene
auto = scn.tool_settings.use_keyframe_insert_auto
print("Snap IK Arm%s" % suffix)
- (uparmIk, loarmIk, elbow, elbowPt, wrist) = getSnapBones(rig, "ArmIK", suffix)
- (uparmFk, loarmFk, elbowPtFk, handFk) = getSnapBones(rig, "ArmFK", suffix)
+ snapIk,cnsIk = getSnapBones(rig, "ArmIK", suffix)
+ (uparmIk, loarmIk, elbow, elbowPt, wrist) = snapIk
+ snapFk,cnsFk = getSnapBones(rig, "ArmFK", suffix)
+ (uparmFk, loarmFk, elbowPtFk, handFk) = snapFk
+ muteConstraints(cnsIk, True)
#rig["MhaElbowFollowsShoulder" + suffix] = False
#rig["MhaElbowFollowsWrist" + suffix] = False
@@ -4044,6 +4052,7 @@ def ik2fkArm(context, suffix):
matchPoseTranslation(elbow, elbowPtFk, auto)
matchPoseTranslation(elbowPt, elbowPtFk, auto)
setInverse(rig, elbowPt)
+ muteConstraints(cnsIk, False)
return
@@ -4051,14 +4060,23 @@ def fk2ikLeg(context, suffix):
rig = context.object
auto = context.scene.tool_settings.use_keyframe_insert_auto
print("Snap FK Leg%s" % suffix)
- (uplegIk, lolegIk, kneePt, ankleIk, legIk, legFk, footIk, toeIk) = getSnapBones(rig, "LegIK", suffix)
- (uplegFk, lolegFk, kneePtFk, footFk, toeFk) = getSnapBones(rig, "LegFK", suffix)
-
+ snapIk,cnsIk = getSnapBones(rig, "LegIK", suffix)
+ (uplegIk, lolegIk, kneePt, ankleIk, legIk, legFk, footIk, toeIk) = snapIk
+ snapFk,cnsFk = getSnapBones(rig, "LegFK", suffix)
+ (uplegFk, lolegFk, kneePtFk, footFk, toeFk) = snapFk
+ muteConstraints(cnsFk, True)
+
+ if not rig["MhaLegIkToAnkle" + suffix]:
+ matchPoseRotation(footFk, footFk, auto)
+ matchPoseRotation(toeFk, toeFk, auto)
+
matchPoseRotation(uplegFk, uplegFk, auto)
matchPoseScale(uplegFk, uplegFk, auto)
matchPoseRotation(lolegFk, lolegFk, auto)
matchPoseScale(lolegFk, lolegFk, auto)
+
+ muteConstraints(cnsFk, False)
return
@@ -4067,8 +4085,11 @@ def ik2fkLeg(context, suffix):
scn = context.scene
auto = scn.tool_settings.use_keyframe_insert_auto
print("Snap IK Leg%s" % suffix)
- (uplegIk, lolegIk, kneePt, ankleIk, legIk, legFk, footIk, toeIk) = getSnapBones(rig, "LegIK", suffix)
- (uplegFk, lolegFk, kneePtFk, footFk, toeFk) = getSnapBones(rig, "LegFK", suffix)
+ snapIk,cnsIk = getSnapBones(rig, "LegIK", suffix)
+ (uplegIk, lolegIk, kneePt, ankleIk, legIk, legFk, footIk, toeIk) = snapIk
+ snapFk,cnsFk = getSnapBones(rig, "LegFK", suffix)
+ (uplegFk, lolegFk, kneePtFk, footFk, toeFk) = snapFk
+ muteConstraints(cnsIk, True)
#rig["MhaKneeFollowsHip" + suffix] = False
#rig["MhaKneeFollowsFoot" + suffix] = False
@@ -4085,8 +4106,11 @@ def ik2fkLeg(context, suffix):
setInverse(rig, kneePt)
if not legIkToAnkle:
matchPoseTranslation(ankleIk, footFk, auto)
+
+ muteConstraints(cnsIk, False)
return
-
+
+
#
# setInverse(rig, pb):
#
@@ -4103,66 +4127,6 @@ def setInverse(rig, pb):
bpy.ops.object.mode_set(mode='POSE')
return
-
-"""
-def clearInverse(rig, pb):
- rig.data.bones.active = pb.bone
- pb.bone.select = True
- bpy.ops.object.mode_set(mode='OBJECT')
- bpy.ops.object.mode_set(mode='POSE')
- for cns in pb.constraints:
- if cns.type == 'CHILD_OF':
- bpy.ops.constraint.childof_clear_inverse(constraint=cns.name, owner='BONE')
- bpy.ops.object.mode_set(mode='OBJECT')
- bpy.ops.object.mode_set(mode='POSE')
- return
-
-
-def fixAnkle(rig, suffix, scn):
- layers = list(rig.data.layers)
- try:
- rig.data.layers = 32*[True]
- setInverse(rig, rig.pose.bones["Ankle" + suffix])
- scn.frame_current = scn.frame_current
- finally:
- rig.data.layers = layers
- return
-
-
-def clearAnkle(rig, suffix, scn):
- layers = list(rig.data.layers)
- try:
- rig.data.layers = 32*[True]
- clearInverse(rig, rig.pose.bones["Ankle" + suffix])
- scn.frame_current = scn.frame_current
- finally:
- rig.data.layers = layers
- return
-
-
-class VIEW3D_OT_FixAnkleButton(bpy.types.Operator):
- bl_idname = "mhx.fix_ankle"
- bl_label = "Fix ankle"
- bl_description = "Set inverse for ankle Child-of constraints"
- bl_options = {'UNDO'}
- suffix = StringProperty()
-
- def execute(self, context):
- fixAnkle(context.object, self.suffix, context.scene)
- return{'FINISHED'}
-
-
-class VIEW3D_OT_ClearAnkleButton(bpy.types.Operator):
- bl_idname = "mhx.clear_ankle"
- bl_label = "Clear ankle"
- bl_description = "Clear inverse for ankle Child-of constraints"
- bl_options = {'UNDO'}
- suffix = StringProperty()
-
- def execute(self, context):
- clearAnkle(context.object, self.suffix, context.scene)
- return{'FINISHED'}
-"""
#
#
#
@@ -4178,10 +4142,19 @@ SnapBones = {
def getSnapBones(rig, key, suffix):
names = SnapBones[key]
pbones = []
+ constraints = []
for name in names:
pb = rig.pose.bones[name+suffix]
pbones.append(pb)
- return tuple(pbones)
+ for cns in pb.constraints:
+ if cns.type == 'LIMIT_ROTATION' and not cns.mute:
+ constraints.append(cns)
+ return tuple(pbones),constraints
+
+
+def muteConstraints(constraints, value):
+ for cns in constraints:
+ cns.mute = value
class VIEW3D_OT_MhxSnapFk2IkButton(bpy.types.Operator):
@@ -4193,6 +4166,8 @@ class VIEW3D_OT_MhxSnapFk2IkButton(bpy.types.Operator):
def execute(self, context):
bpy.ops.object.mode_set(mode='POSE')
rig = context.object
+ if rig.MhxSnapExact:
+ rig["MhaRotationLimits"] = 0.0
(prop, old) = setSnapProp(rig, self.data, 1.0, context, False)
if prop[:6] == "MhaArm":
fk2ikArm(context, prop[-2:])
@@ -4211,6 +4186,8 @@ class VIEW3D_OT_MhxSnapIk2FkButton(bpy.types.Operator):
def execute(self, context):
bpy.ops.object.mode_set(mode='POSE')
rig = context.object
+ if rig.MhxSnapExact:
+ rig["MhaRotationLimits"] = 0.0
(prop, old) = setSnapProp(rig, self.data, 0.0, context, True)
if prop[:6] == "MhaArm":
ik2fkArm(context, prop[-2:])
@@ -4313,6 +4290,16 @@ class MhxFKIKPanel(bpy.types.Panel):
self.toggleButton(row, rig, "MhaLegIk_L", " 5", " 4")
self.toggleButton(row, rig, "MhaLegIk_R", " 21", " 20")
+ layout.label("IK Influence")
+ row = layout.row()
+ row.label("Arm")
+ row.prop(rig, '["MhaArmIk_L"]', text="")
+ row.prop(rig, '["MhaArmIk_R"]', text="")
+ row = layout.row()
+ row.label("Leg")
+ row.prop(rig, '["MhaLegIk_L"]', text="")
+ row.prop(rig, '["MhaLegIk_R"]', text="")
+
try:
ok = (rig["MhxVersion"] >= 12)
except:
@@ -4321,6 +4308,13 @@ class MhxFKIKPanel(bpy.types.Panel):
layout.label("Snapping only works with MHX version 1.12 and later.")
return
+ layout.separator()
+ layout.label("Snapping")
+ row = layout.row()
+ row.label("Rotation Limits")
+ row.prop(rig, '["MhaRotationLimits"]', text="")
+ row.prop(rig, "MhxSnapExact", text="Exact Snapping")
+
layout.label("Snap Arm bones")
row = layout.row()
row.label("FK Arm")
@@ -4340,16 +4334,7 @@ class MhxFKIKPanel(bpy.types.Panel):
row.label("IK Leg")
row.operator("mhx.snap_ik_fk", text="Snap L IK Leg").data = "MhaLegIk_L 4 5 12"
row.operator("mhx.snap_ik_fk", text="Snap R IK Leg").data = "MhaLegIk_R 20 21 28"
- """
- row = layout.row()
- row.label("Ankle")
- row.operator("mhx.fix_ankle", text="Fix L Ankle").suffix = "_L"
- row.operator("mhx.fix_ankle", text="Fix R Ankle").suffix = "_R"
- row = layout.row()
- row.label("")
- row.operator("mhx.clear_ankle", text="Clear L Ankle").suffix = "_L"
- row.operator("mhx.clear_ankle", text="Clear R Ankle").suffix = "_R"
- """
+
def toggleButton(self, row, rig, prop, fk, ik):
if rig[prop] > 0.5:
@@ -4690,6 +4675,7 @@ def register():
bpy.types.Object.MhxMesh = BoolProperty(default=False)
bpy.types.Object.MhxRig = StringProperty(default="")
bpy.types.Object.MhxRigify = BoolProperty(default=False)
+ bpy.types.Object.MhxSnapExact = BoolProperty(default=False)
bpy.types.Object.MhxShapekeyDrivers = BoolProperty(default=True)
bpy.types.Object.MhxStrength = FloatProperty(
name = "Expression strength",
diff --git a/release/scripts/addons/io_import_scene_unreal_psa_psk.py b/release/scripts/addons/io_import_scene_unreal_psa_psk.py
index 822f49e..6825511 100644
--- a/release/scripts/addons/io_import_scene_unreal_psa_psk.py
+++ b/release/scripts/addons/io_import_scene_unreal_psa_psk.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Import Unreal Skeleton Mesh (.psk)/Animation Set (psa)",
"author": "Darknet, flufy3d, camg188",
"version": (2, 2),
- "blender": (2, 6, 4),
+ "blender": (2, 64, 0),
"location": "File > Import > Skeleton Mesh (.psk)/Animation Set (psa)",
"description": "Import Skeleleton Mesh/Animation Data",
"warning": "",
@@ -47,6 +47,7 @@ Imports a *psk file to a new mesh
import bpy
import mathutils
import math
+# XXX Yuck! 'from foo import *' is really bad!
from mathutils import *
from math import *
from bpy.props import *
@@ -58,7 +59,8 @@ from bpy.props import *
bpy.types.Scene.unrealbonesize = FloatProperty(
name="Bone Length",
description="Bone Length from head to tail distance",
- default=1,min=0.001,max=1000)
+ default=1, min=0.001, max=1000
+)
#output log in to txt file
DEBUGLOG = False
@@ -68,33 +70,35 @@ bonesize = 1.0
from bpy_extras.io_utils import unpack_list, unpack_face_list
class md5_bone:
- bone_index=0
- name=""
- bindpos=[]
- bindmat=[]
- origmat=[]
- head=[]
- tail=[]
+ bone_index = 0
+ name = ""
+ bindpos = []
+ bindmat = []
+ origmat = []
+ head = []
+ tail = []
scale = []
- parent=""
- parent_index=0
- blenderbone=None
- roll=0
+ parent = ""
+ parent_index = 0
+ blenderbone = None
+ roll = 0
def __init__(self):
- self.bone_index=0
- self.name=""
- self.bindpos=[0.0]*3
- self.scale=[0.0]*3
- self.head=[0.0]*3
- self.tail=[0.0]*3
- self.bindmat=[None]*3 #is this how you initilize a 2d-array
- for i in range(3): self.bindmat[i] = [0.0]*3
- self.origmat=[None]*3 #is this how you initilize a 2d-array
- for i in range(3): self.origmat[i] = [0.0]*3
- self.parent=""
- self.parent_index=0
- self.blenderbone=None
+ self.bone_index = 0
+ self.name = ""
+ self.bindpos = [0.0] * 3
+ self.scale = [0.0] * 3
+ self.head = [0.0] * 3
+ self.tail = [0.0] * 3
+ self.bindmat = [None] * 3 # is this how you initilize a 2d-array
+ for i in range(3):
+ self.bindmat[i] = [0.0] * 3
+ self.origmat = [None] * 3 #is this how you initilize a 2d-array
+ for i in range(3):
+ self.origmat[i] = [0.0] * 3
+ self.parent = ""
+ self.parent_index = 0
+ self.blenderbone = None
def dump(self):
print ("bone index: ", self.bone_index)
@@ -104,28 +108,28 @@ class md5_bone:
print ("parent: ", self.parent)
print ("parent index: ", self.parent_index)
print ("blenderbone: ", self.blenderbone)
-
+
def getheadpos(pbone,bones):
- pos_head = [0.0]*3
+ pos_head = [0.0] * 3
#pos = mathutils.Vector((x,y,z)) * pbone.origmat
pos = pbone.bindmat.to_translation()
-
+
"""
tmp_bone = pbone
while tmp_bone.name != tmp_bone.parent.name:
pos = pos * tmp_bone.parent.bindmat
tmp_bone = tmp_bone.parent
"""
-
+
pos_head[0] = pos.x
pos_head[1] = pos.y
pos_head[2] = pos.z
-
+
return pos_head
-
+
def gettailpos(pbone,bones):
- pos_tail = [0.0]*3
+ pos_tail = [0.0] * 3
ischildfound = False
childbone = None
childbonelist = []
@@ -136,7 +140,7 @@ def gettailpos(pbone,bones):
childbonelist.append(bone)
if ischildfound:
- tmp_head = [0.0]*3
+ tmp_head = [0.0] * 3
for bone in childbonelist:
tmp_head[0] += bone.head[0]
tmp_head[1] += bone.head[1]
@@ -147,15 +151,14 @@ def gettailpos(pbone,bones):
return tmp_head
else:
tmp_len = 0.0
- tmp_len += (pbone.head[0] - pbone.parent.head[0])**2
- tmp_len += (pbone.head[1] - pbone.parent.head[1])**2
- tmp_len += (pbone.head[2] - pbone.parent.head[2])**2
- tmp_len = tmp_len**0.5 * 0.5
+ tmp_len += (pbone.head[0] - pbone.parent.head[0]) ** 2
+ tmp_len += (pbone.head[1] - pbone.parent.head[1]) ** 2
+ tmp_len += (pbone.head[2] - pbone.parent.head[2]) ** 2
+ tmp_len = tmp_len ** 0.5 * 0.5
pos_tail[0] = pbone.head[0] + tmp_len * pbone.bindmat[0][0]
pos_tail[1] = pbone.head[1] + tmp_len * pbone.bindmat[1][0]
pos_tail[2] = pbone.head[2] + tmp_len * pbone.bindmat[2][0]
-
return pos_tail
def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
@@ -166,72 +169,72 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
print ("--------------------------------------------------")
print (" DEBUG Log:",bDebugLogPSK)
print ("Importing file: ", infile)
-
+
pskfile = open(infile,'rb')
if (DEBUGLOG):
logpath = infile.replace(".psk", ".txt")
print("logpath:",logpath)
logf = open(logpath,'w')
-
+
def printlog(strdata):
if (DEBUGLOG):
logf.write(strdata)
-
+
objName = infile.split('\\')[-1].split('.')[0]
-
+
me_ob = bpy.data.meshes.new(objName)
print("objName:",objName)
printlog(("New Mesh = " + me_ob.name + "\n"))
#read general header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
#not using the general header at this time
#==================================================================================================
# vertex point
#==================================================================================================
#read the PNTS0000 header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
recCount = indata[3]
- printlog(( "Nbr of PNTS0000 records: " + str(recCount) + "\n"))
+ printlog(("Nbr of PNTS0000 records: " + str(recCount) + "\n"))
counter = 0
verts = []
verts2 = []
while counter < recCount:
counter = counter + 1
- indata = unpack('3f',pskfile.read(12))
- #print(indata[0],indata[1],indata[2])
- verts.extend([(indata[0],indata[1],indata[2])])
- verts2.extend([(indata[0],indata[1],indata[2])])
- #print([(indata[0],indata[1],indata[2])])
- printlog(str(indata[0]) + "|" +str(indata[1]) + "|" +str(indata[2]) + "\n")
- #Tmsh.vertices.append(NMesh.Vert(indata[0],indata[1],indata[2]))
-
+ indata = unpack('3f', pskfile.read(12))
+ #print(indata[0], indata[1], indata[2])
+ verts.extend([(indata[0], indata[1], indata[2])])
+ verts2.extend([(indata[0], indata[1], indata[2])])
+ #print([(indata[0], indata[1], indata[2])])
+ printlog(str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) + "\n")
+ #Tmsh.vertices.append(NMesh.Vert(indata[0], indata[1], indata[2]))
+
#==================================================================================================
# UV
#==================================================================================================
#read the VTXW0000 header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
recCount = indata[3]
- printlog( "Nbr of VTXW0000 records: " + str(recCount)+ "\n")
+ printlog("Nbr of VTXW0000 records: " + str(recCount)+ "\n")
counter = 0
UVCoords = []
#UVCoords record format = [index to PNTS, U coord, v coord]
printlog("[index to PNTS, U coord, v coord]\n");
while counter < recCount:
counter = counter + 1
- indata = unpack('hhffhh',pskfile.read(16))
- UVCoords.append([indata[0],indata[2],indata[3]])
- printlog(str(indata[0]) + "|" +str(indata[2]) + "|" +str(indata[3])+"\n")
- #print('mat index %i',indata(4))
- #print([indata[0],indata[2],indata[3]])
- #print([indata[1],indata[2],indata[3]])
-
+ indata = unpack('hhffhh', pskfile.read(16))
+ UVCoords.append([indata[0], indata[2], indata[3]])
+ printlog(str(indata[0]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "\n")
+ #print('mat index %i', indata(4))
+ #print([indata[0], indata[2], indata[3]])
+ #print([indata[1], indata[2], indata[3]])
+
#==================================================================================================
# Face
#==================================================================================================
#read the FACE0000 header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
recCount = indata[3]
- printlog( "Nbr of FACE0000 records: "+ str(recCount) + "\n")
+ printlog("Nbr of FACE0000 records: " + str(recCount) + "\n")
#PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
#associate MatIdx to an image, associate SmthGrp to a material
SGlist = []
@@ -243,54 +246,55 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
printlog("nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp \n")
while counter < recCount:
counter = counter + 1
- indata = unpack('hhhbbi',pskfile.read(12))
- printlog(str(indata[0]) + "|" +str(indata[1]) + "|" +str(indata[2])+ "|" +str(indata[3])+ "|" +str(indata[4])+ "|" +str(indata[5]) + "\n")
+ indata = unpack('hhhbbi', pskfile.read(12))
+ printlog(str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "|" +
+ str(indata[4]) + "|" + str(indata[5]) + "\n")
#indata[0] = index of UVCoords
#UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
#UVCoords[indata[0]][0] = index to PNTS
PNTSA = UVCoords[indata[2]][0]
PNTSB = UVCoords[indata[1]][0]
PNTSC = UVCoords[indata[0]][0]
- #print(PNTSA,PNTSB,PNTSC) #face id vertex
- #faces.extend([0,1,2,0])
- faces.extend([(PNTSA,PNTSB,PNTSC,0)])
+ #print(PNTSA, PNTSB, PNTSC) #face id vertex
+ #faces.extend([0, 1, 2, 0])
+ faces.extend([(PNTSA, PNTSB, PNTSC, 0)])
uv = []
u0 = UVCoords[indata[2]][1]
v0 = UVCoords[indata[2]][2]
- uv.append([u0,1.0 - v0])
+ uv.append([u0, 1.0 - v0])
u1 = UVCoords[indata[1]][1]
v1 = UVCoords[indata[1]][2]
- uv.append([u1,1.0 - v1])
+ uv.append([u1, 1.0 - v1])
u2 = UVCoords[indata[0]][1]
v2 = UVCoords[indata[0]][2]
- uv.append([u2,1.0 - v2])
- faceuv.append([uv,indata[3],indata[4],indata[5]])
-
- #print("material:",indata[3])
- #print("UV: ",u0,v0)
+ uv.append([u2, 1.0 - v2])
+ faceuv.append([uv, indata[3], indata[4], indata[5]])
+
+ #print("material:", indata[3])
+ #print("UV: ", u0, v0)
#update the uv var of the last item in the Tmsh.faces list
# which is the face just added above
- ##Tmsh.faces[-1].uv = [(u0,v0),(u1,v1),(u2,v2)]
+ ##Tmsh.faces[-1].uv = [(u0, v0), (u1, v1), (u2, v2)]
#print("smooth:",indata[5])
#collect a list of the smoothing groups
facesmooth.append(indata[5])
#print(indata[5])
if SGlist.count(indata[5]) == 0:
SGlist.append(indata[5])
- print("smooth:",indata[5])
+ print("smooth:", indata[5])
#assign a material index to the face
#Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
- printlog( "Using Materials to represent PSK Smoothing Groups...\n")
+ printlog("Using Materials to represent PSK Smoothing Groups...\n")
#==========
# skip something...
#==========
-
+
#==================================================================================================
# Material
#==================================================================================================
##
#read the MATT0000 header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
recCount = indata[3]
printlog("Nbr of MATT0000 records: " + str(recCount) + "\n" )
printlog(" - Not importing any material data now. PSKs are texture wrapped! \n")
@@ -298,25 +302,24 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
materialcount = 0
while counter < recCount:
counter = counter + 1
- indata = unpack('64s6i',pskfile.read(88))
+ indata = unpack('64s6i', pskfile.read(88))
materialcount += 1
- print("Material",counter)
- print("Mat name %s",indata[0])
+ print("Material", counter)
+ print("Mat name %s", indata[0])
##
-
#==================================================================================================
# Bones (Armature)
#==================================================================================================
#read the REFSKEL0 header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
recCount = indata[3]
printlog( "Nbr of REFSKEL0 records: " + str(recCount) + "\n")
#REFSKEL0 fields - Name|Flgs|NumChld|PrntIdx|Qw|Qx|Qy|Qz|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize
-
+
Bns = []
bone = []
-
+
md5_bones = []
bni_dict = {}
#==================================================================================================
@@ -326,11 +329,11 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
print ("---PRASE--BONES---")
printlog("Name|Flgs|NumChld|PrntIdx|Qx|Qy|Qz|Qw|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize\n")
while counter < recCount:
- indata = unpack('64s3i11f',pskfile.read(120))
+ indata = unpack('64s3i11f', pskfile.read(120))
#print( "DATA",str(indata))
-
+
bone.append(indata)
-
+
createbone = md5_bone()
#temp_name = indata[0][:30]
temp_name = indata[0]
@@ -339,7 +342,10 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
temp_name = temp_name.rstrip(" ")
temp_name = temp_name.strip()
temp_name = temp_name.strip( bytes.decode(b'\x00'))
- printlog(temp_name + "|" +str(indata[1]) + "|" +str(indata[2])+ "|" +str(indata[3])+ "|" +str(indata[4])+ "|" +str(indata[5]) + "|" +str(indata[6]) + "|" +str(indata[7]) + "|" +str(indata[8])+ "|" +str(indata[9])+ "|" +str(indata[10])+ "|" +str(indata[11]) + "|" +str(indata[12]) + "|" +str(indata[13]) + "|" +str(indata[14])+ "\n")
+ printlog(temp_name + "|" + str(indata[1]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "|" +
+ str(indata[4]) + "|" + str(indata[5]) + "|" + str(indata[6]) + "|" + str(indata[7]) + "|" +
+ str(indata[8]) + "|" + str(indata[9]) + "|" + str(indata[10]) + "|" + str(indata[11]) + "|" +
+ str(indata[12]) + "|" + str(indata[13]) + "|" + str(indata[14]) + "\n")
createbone.name = temp_name
createbone.bone_index = counter
createbone.parent_index = indata[3]
@@ -349,42 +355,42 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
createbone.scale[0] = indata[12]
createbone.scale[1] = indata[13]
createbone.scale[2] = indata[14]
-
+
bni_dict[createbone.name] = createbone.bone_index
-
+
#w,x,y,z
if (counter == 0):#main parent
- createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6])).to_matrix()
- createbone.origmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6])).to_matrix()
+ createbone.bindmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
+ createbone.origmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
else:
- createbone.bindmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6])).to_matrix()
- createbone.origmat = mathutils.Quaternion((indata[7],-indata[4],-indata[5],-indata[6])).to_matrix()
+ createbone.bindmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
+ createbone.origmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
- createbone.bindmat = mathutils.Matrix.Translation(mathutils.Vector((indata[8],indata[9],indata[10]))) * createbone.bindmat.to_4x4()
+ createbone.bindmat = mathutils.Matrix.Translation(mathutils.Vector((indata[8], indata[9], indata[10]))) * \
+ createbone.bindmat.to_4x4()
-
md5_bones.append(createbone)
counter = counter + 1
bnstr = (str(indata[0]))
Bns.append(bnstr)
-
+
for pbone in md5_bones:
- pbone.parent = md5_bones[pbone.parent_index]
+ pbone.parent = md5_bones[pbone.parent_index]
for pbone in md5_bones:
if pbone.name != pbone.parent.name:
- pbone.bindmat = pbone.parent.bindmat * pbone.bindmat
+ pbone.bindmat = pbone.parent.bindmat * pbone.bindmat
#print(pbone.name)
#print(pbone.bindmat)
#print("end")
else:
pbone.bindmat = pbone.bindmat
-
+
for pbone in md5_bones:
- pbone.head = getheadpos(pbone,md5_bones)
-
+ pbone.head = getheadpos(pbone, md5_bones)
+
for pbone in md5_bones:
- pbone.tail = gettailpos(pbone,md5_bones)
+ pbone.tail = gettailpos(pbone, md5_bones)
for pbone in md5_bones:
pbone.parent = md5_bones[pbone.parent_index].name
@@ -392,15 +398,15 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
bonecount = 0
for armbone in bone:
temp_name = armbone[0][:30]
- #print ("BONE NAME: ",len(temp_name))
+ #print ("BONE NAME: ", len(temp_name))
temp_name=str((temp_name))
#temp_name = temp_name[1]
- #print ("BONE NAME: ",temp_name)
- bonecount +=1
+ #print ("BONE NAME: ", temp_name)
+ bonecount += 1
print ("-------------------------")
print ("----Creating--Armature---")
print ("-------------------------")
-
+
#================================================================================================
#Check armature if exist if so create or update or remove all and addnew bone
#================================================================================================
@@ -419,7 +425,8 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
#ob_new.data = armdata
bpy.context.scene.objects.link(ob_new)
#bpy.ops.object.mode_set(mode='OBJECT')
- for i in bpy.context.scene.objects: i.select = False #deselect all objects
+ for i in bpy.context.scene.objects:
+ i.select = False #deselect all objects
ob_new.select = True
#set current armature to edit the bone
bpy.context.scene.objects.active = ob_new
@@ -436,7 +443,7 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
bpy.ops.object.mode_set(mode='EDIT')#Go to edit mode for the bones
newbone = ob_new.data.edit_bones.new(bone.name)
#parent the bone
- #print("DRI:",dir(newbone))
+ #print("DRI:", dir(newbone))
parentbone = None
#note bone location is set in the real space or global not local
bonesize = bpy.types.Scene.unrealbonesize
@@ -444,7 +451,7 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
pos_x = bone.bindpos[0]
pos_y = bone.bindpos[1]
pos_z = bone.bindpos[2]
- #print( "LINKING:" , bone.parent ,"j")
+ #print("LINKING:" , bone.parent ,"j")
parentbone = ob_new.data.edit_bones[bone.parent]
newbone.parent = parentbone
rotmatrix = bone.bindmat
@@ -480,53 +487,59 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
newbone.roll = math.radians(-90.0)
"""
bpy.context.scene.update()
-
+
#==================================================================================================
#END BONE DATA BUILD
#==================================================================================================
VtxCol = []
for x in range(len(Bns)):
#change the overall darkness of each material in a range between 0.1 and 0.9
- tmpVal = ((float(x)+1.0)/(len(Bns))*0.7)+0.1
+ tmpVal = ((float(x) + 1.0) / (len(Bns)) * 0.7) + 0.1
tmpVal = int(tmpVal * 256)
- tmpCol = [tmpVal,tmpVal,tmpVal,0]
+ tmpCol = [tmpVal, tmpVal, tmpVal, 0]
#Change the color of each material slightly
if x % 3 == 0:
- if tmpCol[0] < 128: tmpCol[0] += 60
- else: tmpCol[0] -= 60
+ if tmpCol[0] < 128:
+ tmpCol[0] += 60
+ else:
+ tmpCol[0] -= 60
if x % 3 == 1:
- if tmpCol[1] < 128: tmpCol[1] += 60
- else: tmpCol[1] -= 60
+ if tmpCol[1] < 128:
+ tmpCol[1] += 60
+ else:
+ tmpCol[1] -= 60
if x % 3 == 2:
- if tmpCol[2] < 128: tmpCol[2] += 60
- else: tmpCol[2] -= 60
+ if tmpCol[2] < 128:
+ tmpCol[2] += 60
+ else:
+ tmpCol[2] -= 60
#Add the material to the mesh
VtxCol.append(tmpCol)
-
+
#==================================================================================================
# Bone Weight
#==================================================================================================
#read the RAWW0000 header
- indata = unpack('20s3i',pskfile.read(32))
+ indata = unpack('20s3i', pskfile.read(32))
recCount = indata[3]
- printlog( "Nbr of RAWW0000 records: " + str(recCount) +"\n")
+ printlog("Nbr of RAWW0000 records: " + str(recCount) +"\n")
#RAWW0000 fields: Weight|PntIdx|BoneIdx
RWghts = []
counter = 0
while counter < recCount:
counter = counter + 1
- indata = unpack('fii',pskfile.read(12))
- RWghts.append([indata[1],indata[2],indata[0]])
- #print("weight:",[indata[1],indata[2],indata[0]])
+ indata = unpack('fii', pskfile.read(12))
+ RWghts.append([indata[1], indata[2], indata[0]])
+ #print("weight:", [indata[1], indata[2], indata[0]])
#RWghts fields = PntIdx|BoneIdx|Weight
RWghts.sort()
- printlog( "Vertex point and groups count =" + str(len(RWghts)) + "\n")
+ printlog("Vertex point and groups count =" + str(len(RWghts)) + "\n")
printlog("PntIdx|BoneIdx|Weight")
for vg in RWghts:
- printlog( str(vg[0]) + "|" + str(vg[1]) + "|" + str(vg[2]) + "\n")
-
+ printlog(str(vg[0]) + "|" + str(vg[1]) + "|" + str(vg[2]) + "\n")
+
#Tmsh.update_tag()
-
+
#set the Vertex Colors of the faces
#face.v[n] = RWghts[0]
#RWghts[1] = index of VtxCol
@@ -540,37 +553,36 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
n = n + 1
TmpCol = VtxCol[RWghts[n][1]]
#check if a vertex has more than one influence
- if n != len(RWghts)-1:
- if RWghts[n][0] == RWghts[n+1][0]:
+ if n != len(RWghts) - 1:
+ if RWghts[n][0] == RWghts[n + 1][0]:
#if there is more than one influence, use the one with the greater influence
#for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
- if RWghts[n][2] < RWghts[n+1][2]:
- TmpCol = VtxCol[RWghts[n+1][1]]
- Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0],TmpCol[1],TmpCol[2],0))
+ if RWghts[n][2] < RWghts[n + 1][2]:
+ TmpCol = VtxCol[RWghts[n + 1][1]]
+ Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0], TmpCol[1], TmpCol[2], 0))
"""
if (DEBUGLOG):
logf.close()
#==================================================================================================
#Building Mesh
#==================================================================================================
- print("vertex:",len(verts),"faces:",len(faces))
- print("vertex2:",len(verts2))
+ print("vertex:", len(verts), "faces:", len(faces))
+ print("vertex2:", len(verts2))
me_ob.vertices.add(len(verts2))
me_ob.tessfaces.add(len(faces))
me_ob.vertices.foreach_set("co", unpack_list(verts2))
- me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
-
+ me_ob.tessfaces.foreach_set("vertices_raw", unpack_list( faces))
+
for face in me_ob.tessfaces:
- face.use_smooth = facesmooth[face.index]
-
+ face.use_smooth = facesmooth[face.index]
+
"""
Material setup coding.
First the mesh has to be create first to get the uv texture setup working.
-Create material(s) list in the psk pack data from the list.(to do list)
-Append the material to the from create the mesh object.
-Create Texture(s)
- -fae loop for uv assign and assign material index
-
+ -face loop for uv assign and assign material index
"""
bpy.ops.object.mode_set(mode='OBJECT')
#===================================================================================================
@@ -591,9 +603,9 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
#print(dir(mtex))
#print(dir(matdata))
#for texno in range(len( bpy.data.textures)):
- #print((bpy.data.textures[texno].name))
+ #print((bpy.data.textures[texno].name))
#print(dir(bpy.data.textures[texno]))
- #matdata.active_texture = bpy.data.textures[matcount-1]
+ #matdata.active_texture = bpy.data.textures[matcount - 1]
#matdata.texture_coords = 'UV'
#matdata.active_texture = texturedata
materials.append(matdata)
@@ -611,13 +623,13 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
# texturename = "text1" # UNUSED
countm = 0
for countm in range(materialcount):
- psktexname="psk" + str(countm)
+ psktexname = "psk" + str(countm)
me_ob.uv_textures.new(name=psktexname)
countm += 1
print("INIT UV TEXTURE...")
_matcount = 0
#for mattexcount in materials:
- #print("MATERAIL ID:",_matcount)
+ #print("MATERAIL ID:", _matcount)
_textcount = 0
for uv in me_ob.tessface_uv_textures: # uv texture
print("UV TEXTURE ID:",_textcount)
@@ -627,25 +639,25 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
if faceuv[face.index][1] == _textcount: #if face index and texture index matches assign it
mfaceuv = faceuv[face.index] #face index
_uv1 = mfaceuv[0][0] #(0,0)
- uv.data[face.index].uv1 = mathutils.Vector((_uv1[0],_uv1[1])) #set them
+ uv.data[face.index].uv1 = mathutils.Vector((_uv1[0], _uv1[1])) #set them
_uv2 = mfaceuv[0][1] #(0,0)
- uv.data[face.index].uv2 = mathutils.Vector((_uv2[0],_uv2[1])) #set them
+ uv.data[face.index].uv2 = mathutils.Vector((_uv2[0], _uv2[1])) #set them
_uv3 = mfaceuv[0][2] #(0,0)
- uv.data[face.index].uv3 = mathutils.Vector((_uv3[0],_uv3[1])) #set them
+ uv.data[face.index].uv3 = mathutils.Vector((_uv3[0], _uv3[1])) #set them
else: #if not match zero them
- uv.data[face.index].uv1 = mathutils.Vector((0,0)) #zero them
- uv.data[face.index].uv2 = mathutils.Vector((0,0)) #zero them
- uv.data[face.index].uv3 = mathutils.Vector((0,0)) #zero them
+ uv.data[face.index].uv1 = mathutils.Vector((0, 0)) #zero them
+ uv.data[face.index].uv2 = mathutils.Vector((0, 0)) #zero them
+ uv.data[face.index].uv3 = mathutils.Vector((0, 0)) #zero them
_textcount += 1
#_matcount += 1
#print(matcount)
print("END UV TEXTURE...")
- print("UV TEXTURE LEN:",len(texture))
+ print("UV TEXTURE LEN:", len(texture))
#for tex in me_ob.uv_textures:
- #print("mesh tex:",dir(tex))
+ #print("mesh tex:", dir(tex))
#print((tex.name))
-
+
#for face in me_ob.faces:
#print(dir(face))
@@ -660,15 +672,14 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
#print(dir(ob_new.data.bones))
#create bone vertex group #deal with bone id for index number
for bone in ob_new.data.bones:
- #print("names:",bone.name,":",dir(bone))
- #print("names:",bone.name)
+ #print("names:", bone.name, ":", dir(bone))
+ #print("names:", bone.name)
group = obmesh.vertex_groups.new(bone.name)
for vgroup in obmesh.vertex_groups:
- #print(vgroup.name,":",vgroup.index)
+ #print(vgroup.name, ":", vgroup.index)
for vgp in RWghts:
#bone index
-
if vgp[1] == bni_dict[vgroup.name]:
#print(vgp)
#[vertex id],weight
@@ -678,7 +689,7 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
if len(materials) > 0:
obmesh.active_material = materials[0] #material setup tmp
print("---- adding mesh to the scene ----")
-
+
bpy.ops.object.mode_set(mode='OBJECT')
#bpy.ops.object.select_pattern(extend=True, pattern=obmesh.name, case_sensitive=True)
#bpy.ops.object.select_pattern(extend=True, pattern=ob_new.name, case_sensitive=True)
@@ -694,26 +705,26 @@ def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
obmesh.select = True
ob_new.select = True
bpy.ops.object.parent_set(type="ARMATURE")
-
+
print ("PSK2Blender completed")
#End of def pskimport#########################
-def getInputFilenamepsk(self,filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
+def getInputFilenamepsk(self, filename, importmesh, importbone, bDebugLogPSK, importmultiuvtextures):
checktype = filename.split('\\')[-1].split('.')[1]
print ("------------",filename)
if checktype.lower() != 'psk':
- print (" Selected file = ",filename)
+ print (" Selected file = ", filename)
raise (IOError, "The selected input file is not a *.psk file")
#self.report({'INFO'}, ("Selected file:"+ filename))
else:
- pskimport(filename,importmesh,importbone,bDebugLogPSK,importmultiuvtextures)
-
-def getInputFilenamepsa(self,filename,context):
+ pskimport(filename, importmesh, importbone, bDebugLogPSK, importmultiuvtextures)
+
+def getInputFilenamepsa(self, filename, context):
checktype = filename.split('\\')[-1].split('.')[1]
if checktype.lower() != 'psa':
- print (" Selected file = ",filename)
+ print (" Selected file = ", filename)
raise (IOError, "The selected input file is not a *.psa file")
- #self.report({'INFO'}, ("Selected file:"+ filename))
+ #self.report({'INFO'}, ("Selected file:" + filename))
else:
psaimport(filename,context)
@@ -751,7 +762,7 @@ class IMPORT_OT_psk(bpy.types.Operator):
)
bDebugLogPSK = BoolProperty(
name="Debug Log.txt",
- description="Log the output of raw format. It will save in " \
+ description="Log the output of raw format. It will save in "
"current file dir. Note this just for testing",
default=False,
)
@@ -765,13 +776,14 @@ class IMPORT_OT_psk(bpy.types.Operator):
def execute(self, context):
bpy.types.Scene.unrealbonesize = self.unrealbonesize
- getInputFilenamepsk(self,self.filepath,self.importmesh,self.importbone,self.bDebugLogPSK,self.importmultiuvtextures)
+ getInputFilenamepsk(self, self.filepath, self.importmesh, self.importbone, self.bDebugLogPSK,
+ self.importmultiuvtextures)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
- return {'RUNNING_MODAL'}
+ return {'RUNNING_MODAL'}
class psa_bone:
name=""
@@ -781,7 +793,7 @@ class psa_bone:
self.name=""
self.Transform=None
self.parent=None
-
+
def psaimport(filename,context):
print ("--------------------------------------------------")
print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
@@ -791,33 +803,33 @@ def psaimport(filename,context):
debug = True
if (debug):
logpath = filename.replace(".psa", ".txt")
- print("logpath:",logpath)
- logf = open(logpath,'w')
+ print("logpath:", logpath)
+ logf = open(logpath, 'w')
def printlog(strdata):
if (debug):
logf.write(strdata)
- def printlogplus(name,data):
+ def printlogplus(name, data):
if (debug):
- logf.write(str(name)+'\n')
- if isinstance(data,bytes):
+ logf.write(str(name) + '\n')
+ if isinstance(data, bytes):
logf.write(str(bytes.decode(data).strip(bytes.decode(b'\x00'))))
else:
logf.write(str(data))
logf.write('\n')
-
+
printlog('-----------Log File------------\n')
#General Header
- indata = unpack('20s3i',psafile.read(32))
- printlogplus('ChunkID',indata[0])
- printlogplus('TypeFlag',indata[1])
- printlogplus('DataSize',indata[2])
- printlogplus('DataCount',indata[3])
+ indata = unpack('20s3i', psafile.read(32))
+ printlogplus('ChunkID', indata[0])
+ printlogplus('TypeFlag', indata[1])
+ printlogplus('DataSize', indata[2])
+ printlogplus('DataCount', indata[3])
#Bones Header
- indata = unpack('20s3i',psafile.read(32))
- printlogplus('ChunkID',indata[0])
- printlogplus('TypeFlag',indata[1])
- printlogplus('DataSize',indata[2])
- printlogplus('DataCount',indata[3])
+ indata = unpack('20s3i', psafile.read(32))
+ printlogplus('ChunkID', indata[0])
+ printlogplus('TypeFlag', indata[1])
+ printlogplus('DataSize', indata[2])
+ printlogplus('DataCount', indata[3])
#Bones Data
BoneIndex2NamePairMap = {}
BoneNotFoundList = []
@@ -826,56 +838,56 @@ def psaimport(filename,context):
counter = 0
nobonematch = True
while counter < recCount:
- indata = unpack('64s3i11f',psafile.read(120))
- #printlogplus('bone',indata[0])
+ indata = unpack('64s3i11f', psafile.read(120))
+ #printlogplus('bone', indata[0])
bonename = str(bytes.decode(indata[0]).strip(bytes.decode(b'\x00')))
if bonename in bpy.data.armatures['armaturedata'].bones.keys():
BoneIndex2NamePairMap[counter] = bonename
- print('find bone',bonename)
+ print('find bone', bonename)
nobonematch = False
else:
- print('can not find the bone:',bonename)
+ print('can not find the bone:', bonename)
BoneNotFoundList.append(counter)
counter += 1
-
+
if nobonematch:
print('no bone was match so skip import!')
return
-
+
#Animations Header
- indata = unpack('20s3i',psafile.read(32))
- printlogplus('ChunkID',indata[0])
- printlogplus('TypeFlag',indata[1])
- printlogplus('DataSize',indata[2])
- printlogplus('DataCount',indata[3])
+ indata = unpack('20s3i', psafile.read(32))
+ printlogplus('ChunkID', indata[0])
+ printlogplus('TypeFlag', indata[1])
+ printlogplus('DataSize', indata[2])
+ printlogplus('DataCount', indata[3])
#Animations Data
recCount = indata[3]
counter = 0
Raw_Key_Nums = 0
Action_List = []
while counter < recCount:
- indata = unpack('64s64s4i3f3i',psafile.read(64+64+4*4+3*4+3*4))
- printlogplus('Name',indata[0])
- printlogplus('Group',indata[1])
- printlogplus('totalbones',indata[2])
- printlogplus('NumRawFrames',indata[-1])
+ indata = unpack('64s64s4i3f3i', psafile.read(64 + 64 + 4 * 4 + 3 * 4 + 3 * 4))
+ printlogplus('Name', indata[0])
+ printlogplus('Group', indata[1])
+ printlogplus('totalbones', indata[2])
+ printlogplus('NumRawFrames', indata[-1])
Name = str(bytes.decode(indata[0]).strip(bytes.decode(b'\x00')))
Group = str(bytes.decode(indata[1]).strip(bytes.decode(b'\x00')))
totalbones = indata[2]
NumRawFrames = indata[-1]
-
+
Raw_Key_Nums += indata[2] * indata[-1]
Action_List.append((Name,Group,totalbones,NumRawFrames))
-
+
counter += 1
-
+
#Raw keys Header
Raw_Key_List = []
- indata = unpack('20s3i',psafile.read(32))
- printlogplus('ChunkID',indata[0])
- printlogplus('TypeFlag',indata[1])
- printlogplus('DataSize',indata[2])
- printlogplus('DataCount',indata[3])
+ indata = unpack('20s3i', psafile.read(32))
+ printlogplus('ChunkID', indata[0])
+ printlogplus('TypeFlag', indata[1])
+ printlogplus('DataSize', indata[2])
+ printlogplus('DataCount', indata[3])
if(Raw_Key_Nums != indata[3]):
print('error! Raw_Key_Nums Inconsistent')
return
@@ -883,39 +895,39 @@ def psaimport(filename,context):
recCount = Raw_Key_Nums
counter = 0
while counter < recCount:
- indata = unpack('3f4f1f',psafile.read(3*4+4*4+4))
+ indata = unpack('3f4f1f', psafile.read(3 * 4 + 4 * 4 + 4))
pos = mathutils.Vector((indata[0], indata[1], indata[2]))
quat = mathutils.Quaternion((indata[6], indata[3], indata[4], indata[5]))
time = indata[7]
- Raw_Key_List.append((pos,quat,time))
+ Raw_Key_List.append((pos, quat, time))
counter += 1
#Scale keys Header,Scale keys Data,Curve keys Header,Curve keys Data
curFilePos = psafile.tell()
- psafile.seek(0,2)
+ psafile.seek(0, 2)
endFilePos = psafile.tell()
if curFilePos == endFilePos:
print('no Scale keys,Curve keys')
-
+
#build the animation line
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
-
+
NeededBoneMatrix = {}
ARMATURE_OBJ = 'ArmObject'
ARMATURE_DATA = 'armaturedata'
if bpy.context.scene.udk_importarmatureselect:
if len(bpy.context.scene.udkas_list) > 0:
print("CHECKING ARMATURE...")
- #for bone in bpy.data.objects[ARMATURE_OBJ].pose.bones:
+ #for bone in bpy.data.objects[ARMATURE_OBJ].pose.bones:
#for objd in bpy.data.objects:
- #print("NAME:",objd.name," TYPE:",objd.type)
+ #print("NAME:", objd.name, " TYPE:", objd.type)
#if objd.type == 'ARMARURE':
#print(dir(objd))
armature_list = bpy.context.scene.udkas_list #armature list array
armature_idx = bpy.context.scene.udkimportarmature_list_idx #armature index selected
ARMATURE_OBJ = bpy.data.objects[armature_list[armature_idx]].name #object armature
ARMATURE_DATA = bpy.data.objects[armature_list[armature_idx]].data.name #object data
-
+
for bone in bpy.data.armatures[ARMATURE_DATA].bones:
name = bone.name
ori_matrix = bone.matrix
@@ -928,7 +940,7 @@ def psaimport(filename,context):
bone_rest_matrix_inv.resize_4x4()
bone_rest_matrix.resize_4x4()
NeededBoneMatrix[name] = (bone_rest_matrix,bone_rest_matrix_inv,ori_matrix)
-
+
#build tmp pose bone tree
psa_bones = {}
for bone in bpy.data.objects[ARMATURE_OBJ].pose.bones:
@@ -940,29 +952,29 @@ def psaimport(filename,context):
else:
_psa_bone.parent = None
psa_bones[bone.name] = _psa_bone
-
+
raw_key_index = 0
for raw_action in Action_List:
- Name = raw_action[0]
- Group = raw_action[1]
- Totalbones = raw_action[2]
- NumRawFrames = raw_action[3]
+ Name = raw_action[0]
+ Group = raw_action[1]
+ Totalbones = raw_action[2]
+ NumRawFrames = raw_action[3]
context.scene.update()
object = bpy.data.objects['ArmObject']
object.animation_data_create()
- action = bpy.data.actions.new(name=Name)
+ action = bpy.data.actions.new(name=Name)
object.animation_data.action = action
for i in range(NumRawFrames):
- context.scene.frame_set(i+1)
+ context.scene.frame_set(i + 1)
pose_bones = object.pose.bones
for j in range(Totalbones):
if j not in BoneNotFoundList:
bName = BoneIndex2NamePairMap[j]
- pbone = psa_bones[bName]
+ pbone = psa_bones[bName]
pos = Raw_Key_List[raw_key_index][0]
quat = Raw_Key_List[raw_key_index][1]
-
+
mat = Matrix()
if pbone.parent != None:
quat = quat.conjugated()
@@ -978,7 +990,7 @@ def psaimport(filename,context):
raw_key_index += 1
#bpy.data.meshes[1]
- for bone in pose_bones:
+ for bone in pose_bones:
bone.matrix = psa_bones[bone.name].Transform
bone.keyframe_insert("rotation_quaternion")
bone.keyframe_insert("location")
@@ -986,16 +998,16 @@ def psaimport(filename,context):
def whirlSingleBone(pose_bone,quat):
bpy.context.scene.update()
#record child's matrix and origin rotate
- hymat = Quaternion((0.707,-0.707,0,0)).inverted().to_matrix().to_4x4()
+ hymat = Quaternion((0.707, -0.707, 0, 0)).inverted().to_matrix().to_4x4()
children_infos = {}
childrens = pose_bone.children
for child in childrens:
- armmat = bpy.data.armatures['armaturedata'].bones[child.name].matrix.copy().to_4x4()
+ armmat = bpy.data.armatures['armaturedata'].bones[child.name].matrix.copy().to_4x4()
cmat = child.matrix.copy() * armmat.inverted() * hymat.inverted()
pos = cmat.to_translation()
rotmat = cmat.to_3x3()
- children_infos[child] = (armmat,pos,rotmat)
-
+ children_infos[child] = (armmat, pos, rotmat)
+
#whirl this bone by quat
pose_bone.matrix *= quat.to_matrix().to_4x4()
pose_bone.keyframe_insert("location")
@@ -1003,7 +1015,7 @@ def psaimport(filename,context):
bpy.context.scene.update()
#set back children bon to original position
#reverse whirl child bone by quat.inverse()
-
+
for child in childrens:
armmat = children_infos[child][0]
pos = children_infos[child][1]
@@ -1015,17 +1027,17 @@ def psaimport(filename,context):
for bone in pose_bones:
if bone.parent != None:
- whirlSingleBone(bone,Quaternion((0.707,0,0,-0.707)))
+ whirlSingleBone(bone,Quaternion((0.707, 0, 0, -0.707)))
else:
- bone.rotation_quaternion *= Quaternion((0.707,-0.707,0,0))*Quaternion((0.707,0,0,-0.707))
+ bone.rotation_quaternion *= Quaternion((0.707, -0.707, 0, 0)) * Quaternion((0.707, 0, 0, -0.707))
bone.keyframe_insert("rotation_quaternion")
-
+
break
-
+
context.scene.frame_set(0)
if(debug):
logf.close()
-
+
class IMPORT_OT_psa(bpy.types.Operator):
'''Load a skeleton anim psa File'''
bl_idname = "import_scene.psa"
@@ -1048,7 +1060,7 @@ class IMPORT_OT_psa(bpy.types.Operator):
def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
- return {'RUNNING_MODAL'}
+ return {'RUNNING_MODAL'}
class IMPORT_OT_psa(bpy.types.Operator):
'''Load a skeleton anim psa File'''
@@ -1072,50 +1084,50 @@ class IMPORT_OT_psa(bpy.types.Operator):
def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
- return {'RUNNING_MODAL'}
+ return {'RUNNING_MODAL'}
bpy.types.Scene.udk_importpsk = StringProperty(
- name = "Import .psk",
- description = "Skeleton mesh file path for psk",
- default = "")
+ name = "Import .psk",
+ description = "Skeleton mesh file path for psk",
+ default = "")
bpy.types.Scene.udk_importpsa = StringProperty(
- name = "Import .psa",
- description = "Animation Data to Action Set(s) file path for psa",
- default = "")
+ name = "Import .psa",
+ description = "Animation Data to Action Set(s) file path for psa",
+ default = "")
bpy.types.Scene.udk_importarmatureselect = BoolProperty(
- name = "Armature Selected",
- description = "Select Armature to Import psa animation data.",
- default = False)
-
-class Panel_UDKImport( bpy.types.Panel ):
-
- bl_label = "UDK Import"
- bl_idname = "OBJECT_PT_udk_import"
- bl_space_type = "VIEW_3D"
- bl_region_type = "TOOLS"
-
- filepath = StringProperty(
+ name = "Armature Selected",
+ description = "Select Armature to Import psa animation data",
+ default = False)
+
+class Panel_UDKImport(bpy.types.Panel):
+ bl_label = "UDK Import"
+ bl_idname = "OBJECT_PT_udk_import"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+
+ filepath = StringProperty(
subtype='FILE_PATH',
)
-
- #@classmethod
- #def poll(cls, context):
- # return context.active_object
-
- def draw(self, context):
- layout = self.layout
- layout.operator(OBJECT_OT_PSKPath.bl_idname)
-
- layout.prop(context.scene, "udk_importarmatureselect")
- if bpy.context.scene.udk_importarmatureselect:
- layout.operator(OBJECT_OT_UDKImportArmature.bl_idname)
- layout.template_list(context.scene, "udkimportarmature_list", context.scene, "udkimportarmature_list_idx",prop_list="template_list_controls", rows=5)
- layout.operator(OBJECT_OT_PSAPath.bl_idname)
-
+
+ #@classmethod
+ #def poll(cls, context):
+ # return context.active_object
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator(OBJECT_OT_PSKPath.bl_idname)
+
+ layout.prop(context.scene, "udk_importarmatureselect")
+ if bpy.context.scene.udk_importarmatureselect:
+ layout.operator(OBJECT_OT_UDKImportArmature.bl_idname)
+ layout.template_list("UI_UL_list", "", context.scene, "udkimportarmature_list",
+ context.scene, "udkimportarmature_list_idx", rows=5)
+ layout.operator(OBJECT_OT_PSAPath.bl_idname)
+
class OBJECT_OT_PSKPath(bpy.types.Operator):
+ """Select .psk file path to import for skeleton mesh"""
bl_idname = "object.pskpath"
bl_label = "Import PSK Path"
- __doc__ = " Select .psk file path to import for skeleton mesh."
filepath = StringProperty(
subtype='FILE_PATH',
@@ -1152,107 +1164,110 @@ class OBJECT_OT_PSKPath(bpy.types.Operator):
min=0.001,
max=1000,
)
-
+
def execute(self, context):
#context.scene.importpskpath = self.properties.filepath
bpy.types.Scene.unrealbonesize = self.unrealbonesize
- getInputFilenamepsk(self,self.filepath,self.importmesh,self.importbone,self.bDebugLogPSK,self.importmultiuvtextures)
+ getInputFilenamepsk(self, self.filepath, self.importmesh, self.importbone, self.bDebugLogPSK,
+ self.importmultiuvtextures)
return {'FINISHED'}
-
+
def invoke(self, context, event):
#bpy.context.window_manager.fileselect_add(self)
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
-
+
class UDKImportArmaturePG(bpy.types.PropertyGroup):
- bool = BoolProperty(default=False)
- string = StringProperty()
- bexport = BoolProperty(default=False,name="Export", options={"HIDDEN"},description = "This will be ignore when exported")
- bselect = BoolProperty(default=False,name="Select", options={"HIDDEN"},description = "This will be ignore when exported")
- otype = StringProperty(name="Type",description = "This will be ignore when exported")
- template_list_controls = StringProperty(default="", options={"HIDDEN"})
+ #boolean = BoolProperty(default=False)
+ string = StringProperty()
+ bexport = BoolProperty(default=False, name="Export", options={"HIDDEN"},
+ description = "This will be ignore when exported")
+ bselect = BoolProperty(default=False, name="Select", options={"HIDDEN"},
+ description = "This will be ignore when exported")
+ otype = StringProperty(name="Type",description = "This will be ignore when exported")
bpy.utils.register_class(UDKImportArmaturePG)
bpy.types.Scene.udkimportarmature_list = CollectionProperty(type=UDKImportArmaturePG)
bpy.types.Scene.udkimportarmature_list_idx = IntProperty()
class OBJECT_OT_PSAPath(bpy.types.Operator):
- bl_idname = "object.psapath"
- bl_label = "Import PSA Path"
- __doc__ = " Select .psa file path to import for animation data."
+ """Select .psa file path to import for animation data"""
+ bl_idname = "object.psapath"
+ bl_label = "Import PSA Path"
- filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file", maxlen= 1024, default= "")
- filter_glob = StringProperty(
+ filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file",
+ maxlen=1024, default="")
+ filter_glob = StringProperty(
default="*.psa",
options={'HIDDEN'},
)
-
- def execute(self, context):
- #context.scene.importpsapath = self.properties.filepath
- getInputFilenamepsa(self,self.filepath,context)
- return {'FINISHED'}
-
- def invoke(self, context, event):
- bpy.context.window_manager.fileselect_add(self)
- return {'RUNNING_MODAL'}
-
+
+ def execute(self, context):
+ #context.scene.importpsapath = self.properties.filepath
+ getInputFilenamepsa(self,self.filepath,context)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ bpy.context.window_manager.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
class OBJECT_OT_UDKImportArmature(bpy.types.Operator):
- bl_idname = "object.udkimportarmature"
- bl_label = "Update Armature"
- __doc__ = "This will update the filter of the mesh and armature."
-
- def execute(self, context):
- my_objlist = bpy.context.scene.udkimportarmature_list
- objectl = []
- for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
- if objarm.type == 'ARMATURE':
- objectl.append(objarm)
- for _objd in objectl:#check if list has in udk list
- bfound_obj = False
- for _obj in my_objlist:
- if _obj.name == _objd.name and _obj.otype == _objd.type:
- _obj.bselect = _objd.select
- bfound_obj = True
- break
- if bfound_obj == False:
- #print("ADD ARMATURE...")
- my_item = my_objlist.add()
- my_item.name = _objd.name
- my_item.bselect = _objd.select
- my_item.otype = _objd.type
- removeobject = []
- for _udkobj in my_objlist:
- bfound_objv = False
- for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
- if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
- bfound_objv = True
- break
- if bfound_objv == False:
- removeobject.append(_udkobj)
- #print("remove check...")
- for _item in removeobject: #loop remove object from udk list object
- count = 0
- for _obj in my_objlist:
- if _obj.name == _item.name and _obj.otype == _item.otype:
- my_objlist.remove(count)
- break
- count += 1
- return{'FINISHED'}
-
+ """This will update the filter of the mesh and armature"""
+ bl_idname = "object.udkimportarmature"
+ bl_label = "Update Armature"
+
+ def execute(self, context):
+ my_objlist = bpy.context.scene.udkimportarmature_list
+ objectl = []
+ for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
+ if objarm.type == 'ARMATURE':
+ objectl.append(objarm)
+ for _objd in objectl:#check if list has in udk list
+ bfound_obj = False
+ for _obj in my_objlist:
+ if _obj.name == _objd.name and _obj.otype == _objd.type:
+ _obj.bselect = _objd.select
+ bfound_obj = True
+ break
+ if bfound_obj == False:
+ #print("ADD ARMATURE...")
+ my_item = my_objlist.add()
+ my_item.name = _objd.name
+ my_item.bselect = _objd.select
+ my_item.otype = _objd.type
+ removeobject = []
+ for _udkobj in my_objlist:
+ bfound_objv = False
+ for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
+ if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
+ bfound_objv = True
+ break
+ if bfound_objv == False:
+ removeobject.append(_udkobj)
+ #print("remove check...")
+ for _item in removeobject: #loop remove object from udk list object
+ count = 0
+ for _obj in my_objlist:
+ if _obj.name == _item.name and _obj.otype == _item.otype:
+ my_objlist.remove(count)
+ break
+ count += 1
+ return{'FINISHED'}
+
class OBJECT_OT_UDKImportA(bpy.types.Operator):
- bl_idname = "object.udkimporta"
- bl_label = "Update Armature"
- __doc__ = "This will update the filter of the mesh and armature."
-
- def execute(self, context):
- for objd in bpy.data.objects:
- print("NAME:",objd.name," TYPE:",objd.type)
- if objd.type == "ARMATURE":
- print(dir(objd))
- print((objd.data.name))
- return{'FINISHED'}
-
+ """This will update the filter of the mesh and armature"""
+ bl_idname = "object.udkimporta"
+ bl_label = "Update Armature"
+
+ def execute(self, context):
+ for objd in bpy.data.objects:
+ print("NAME:",objd.name," TYPE:",objd.type)
+ if objd.type == "ARMATURE":
+ print(dir(objd))
+ print((objd.data.name))
+ return{'FINISHED'}
+
def menu_func(self, context):
self.layout.operator(IMPORT_OT_psk.bl_idname, text="Skeleton Mesh (.psk)")
self.layout.operator(IMPORT_OT_psa.bl_idname, text="Skeleton Anim (.psa)")
@@ -1260,7 +1275,7 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func)
-
+
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func)
@@ -1270,4 +1285,4 @@ if __name__ == "__main__":
#note this only read the data and will not be place in the scene
#getInputFilename('C:\\blenderfiles\\BotA.psk')
-#getInputFilename('C:\\blenderfiles\\AA.PSK')
\ No newline at end of file
+#getInputFilename('C:\\blenderfiles\\AA.PSK')
diff --git a/release/scripts/addons/io_mesh_pdb/__init__.py b/release/scripts/addons/io_mesh_pdb/__init__.py
index 15d6642..92d937b 100644
--- a/release/scripts/addons/io_mesh_pdb/__init__.py
+++ b/release/scripts/addons/io_mesh_pdb/__init__.py
@@ -38,8 +38,8 @@ bl_info = {
"name": "Atomic Blender - PDB",
"description": "Loading and manipulating atoms from PDB files",
"author": "Clemens Barth",
- "version": (1,5),
- "blender": (2,6),
+ "version": (1, 5),
+ "blender": (2, 60, 0),
"location": "File -> Import -> PDB (.pdb)",
"warning": "",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/"
diff --git a/release/scripts/addons/io_mesh_ply/__init__.py b/release/scripts/addons/io_mesh_ply/__init__.py
index 623900c..6672dae 100644
--- a/release/scripts/addons/io_mesh_ply/__init__.py
+++ b/release/scripts/addons/io_mesh_ply/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Stanford PLY format",
"author": "Bruce Merry, Campbell Barton",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export",
"description": "Import-Export PLY mesh data withs UV's and vertex colors",
"warning": "",
diff --git a/release/scripts/addons/io_mesh_raw/__init__.py b/release/scripts/addons/io_mesh_raw/__init__.py
index 61c2152..3e8c712 100644
--- a/release/scripts/addons/io_mesh_raw/__init__.py
+++ b/release/scripts/addons/io_mesh_raw/__init__.py
@@ -23,7 +23,7 @@ bl_info = {
"name": "Raw mesh format (.raw)",
"author": "Anthony D,Agostino (Scorpius), Aurel Wildfellner",
"version": (0, 2),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export > Raw Faces (.raw) ",
"description": "Import-Export Raw Faces",
"warning": "",
diff --git a/release/scripts/addons/io_mesh_stl/__init__.py b/release/scripts/addons/io_mesh_stl/__init__.py
index 1088490..34c586a 100644
--- a/release/scripts/addons/io_mesh_stl/__init__.py
+++ b/release/scripts/addons/io_mesh_stl/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "STL format",
"author": "Guillaume Bouchard (Guillaum)",
"version": (1, 0),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export > Stl",
"description": "Import-Export STL files",
"warning": "",
diff --git a/release/scripts/addons/io_mesh_uv_layout/__init__.py b/release/scripts/addons/io_mesh_uv_layout/__init__.py
index ccf0ddd..dc6c05d 100644
--- a/release/scripts/addons/io_mesh_uv_layout/__init__.py
+++ b/release/scripts/addons/io_mesh_uv_layout/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "UV Layout",
"author": "Campbell Barton, Matt Ebb",
"version": (1, 1),
- "blender": (2, 6, 2),
+ "blender": (2, 62, 0),
"location": "Image-Window > UVs > Export UV Layout",
"description": "Export the UV layout as a 2D graphic",
"warning": "",
diff --git a/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py b/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py
index 423ad33..1168e33 100644
--- a/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py
+++ b/release/scripts/addons/io_mesh_uv_layout/export_uv_png.py
@@ -113,7 +113,7 @@ def write(fw, mesh_source, image_width, image_height, opacity, face_iter_func):
# scene render settings
scene.render.use_raytrace = False
- scene.render.alpha_mode = 'STRAIGHT'
+ scene.render.alpha_mode = 'TRANSPARENT'
scene.render.image_settings.color_mode = 'RGBA'
scene.render.resolution_x = image_width
diff --git a/release/scripts/addons/io_scene_3ds/__init__.py b/release/scripts/addons/io_scene_3ds/__init__.py
index bdebc12..e39622f 100644
--- a/release/scripts/addons/io_scene_3ds/__init__.py
+++ b/release/scripts/addons/io_scene_3ds/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Autodesk 3DS format",
"author": "Bob Holcomb, Campbell Barton",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export",
"description": "Import-Export 3DS, meshes, uvs, materials, textures, "
"cameras & lamps",
diff --git a/release/scripts/addons/io_scene_fbx/__init__.py b/release/scripts/addons/io_scene_fbx/__init__.py
index 3b64d05..19de480 100644
--- a/release/scripts/addons/io_scene_fbx/__init__.py
+++ b/release/scripts/addons/io_scene_fbx/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Autodesk FBX format",
"author": "Campbell Barton",
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "File > Import-Export",
"description": "Export FBX meshes, UV's, vertex colors, materials, "
"textures, cameras, lamps and actions",
diff --git a/release/scripts/addons/io_scene_map/__init__.py b/release/scripts/addons/io_scene_map/__init__.py
index c1b7777..a589e76 100644
--- a/release/scripts/addons/io_scene_map/__init__.py
+++ b/release/scripts/addons/io_scene_map/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Quake MAP format",
"author": "Campbell Barton",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Export",
"description": "Export MAP brushes, nurbs surfaces, "
"lamps and empties as map nodes",
diff --git a/release/scripts/addons/io_scene_obj/__init__.py b/release/scripts/addons/io_scene_obj/__init__.py
index db08318..501dc4b 100644
--- a/release/scripts/addons/io_scene_obj/__init__.py
+++ b/release/scripts/addons/io_scene_obj/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Wavefront OBJ format",
"author": "Campbell Barton",
- "blender": (2, 5, 8),
+ "blender": (2, 58, 0),
"location": "File > Import-Export",
"description": "Import-Export OBJ, Import OBJ mesh, UV's, "
"materials and textures",
diff --git a/release/scripts/addons/io_scene_x3d/__init__.py b/release/scripts/addons/io_scene_x3d/__init__.py
index 8f18841..1440684 100644
--- a/release/scripts/addons/io_scene_x3d/__init__.py
+++ b/release/scripts/addons/io_scene_x3d/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Web3D X3D/VRML2 format",
"author": "Campbell Barton, Bart",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export",
"description": "Import-Export X3D, Import VRML2",
"warning": "",
diff --git a/release/scripts/addons/io_sequencer_edl/__init__.py b/release/scripts/addons/io_sequencer_edl/__init__.py
new file mode 100644
index 0000000..09ee806
--- /dev/null
+++ b/release/scripts/addons/io_sequencer_edl/__init__.py
@@ -0,0 +1,333 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Import EDL",
+ "author": "Campbell Barton",
+ "version": (1, 0),
+ "blender": (2, 65, 0),
+ "location": "Sequencer -> Track View Properties",
+ "description": "Load a CMX formatted EDL into the sequencer",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:"
+ "2.6/Py/Scripts/Import-Export/EDL_Import",
+ "tracker_url": "",
+ "category": "Import"}
+
+import bpy
+
+
+# ImportHelper is a helper class, defines filename and
+# invoke() function which calls the file selector.
+from bpy_extras.io_utils import ImportHelper
+from bpy.props import (StringProperty,
+ IntProperty,
+ PointerProperty,
+ CollectionProperty,
+ )
+from bpy.types import Operator
+
+# ----------------------------------------------------------------------------
+# Main Operators
+
+
+class ReloadEDL(Operator):
+ bl_idname = "sequencer.import_edl_refresh"
+ bl_label = "Refresh Reels"
+
+ def execute(self, context):
+ import os
+ from . import parse_edl
+
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+
+ filepath = edl_import_info.filepath
+ dummy_fps = 25
+
+ if not os.path.exists(filepath):
+ self.report({'ERROR'}, "File Not Found %r" % filepath)
+ return {'CANCELLED'}
+
+ elist = parse_edl.EditList()
+ if not elist.parse(filepath, dummy_fps):
+ self.report({'ERROR'}, "Failed to parse EDL %r" % filepath)
+ return {'CANCELLED'}
+
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+ bl_reels = edl_import_info.reels
+
+ data_prev = {reel.name: (reel.filepath, reel.frame_offset)
+ for reel in edl_import_info.reels}
+
+ reels = elist.reels_as_dict()
+ reels = [k for k in reels.keys() if k not in parse_edl.BLACK_ID]
+
+ # re-create reels collection, keeping old values
+ bl_reels.clear()
+ for k in sorted(reels):
+ reel = bl_reels.add()
+ reel.name = k
+ filepath, frame_offset = data_prev.get(k, (None, None))
+ if filepath is not None:
+ reel.filepath = filepath
+ reel.frame_offset = frame_offset
+
+ return {'FINISHED'}
+
+
+class FindReelsEDL(Operator):
+ """Scan a path for missing reel files, """ \
+ """ Matching by reel name and existing filename when set"""
+ bl_idname = "sequencer.import_edl_findreel"
+ bl_label = "Find Missing Reel Files"
+ directory = StringProperty(
+ subtype='DIR_PATH',
+ )
+
+ @staticmethod
+ def missing_reels(context):
+ import os
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+ return [reel for reel in edl_import_info.reels
+ if not os.path.exists(reel.filepath)]
+
+ def execute(self, context):
+ import os
+
+ # walk over .avi, .mov, .wav etc.
+ def media_file_walker(path):
+ ext_check = bpy.path.extensions_movie | bpy.path.extensions_audio
+ for dirpath, dirnames, filenames in os.walk(path):
+ # skip '.svn'
+ if dirpath.startswith("."):
+ continue
+ for filename in filenames:
+ fileonly, ext = os.path.splitext(filename)
+ ext_lower = ext.lower()
+ if ext_lower in ext_check:
+ yield os.path.join(dirpath, filename), fileonly
+
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+
+ bl_reels = FindReelsEDL.missing_reels(context)
+ assert(len(bl_reels))
+
+ # Search is as follows
+ # Each reel has a triple:
+ # ([search_names, ...], [(priority, found_file), ...], bl_reel)
+ bl_reels_search = [(set(), [], reel) for reel in bl_reels]
+
+ # first get the search names...
+ for reel_names, reel_files_found, reel in bl_reels_search:
+ reel_names_list = []
+ reel_names_list.append(reel.name.lower())
+
+ # add non-extension version of the reel name
+ if "." in reel_names_list[-1]:
+ reel_names_list.append(os.path.splitext(reel_names_list[-1])[0])
+
+ # use the filepath if set
+ reel_filepath = reel.filepath
+ if reel_filepath:
+ reel_filepath = os.path.basename(reel_filepath)
+ reel_filepath = os.path.splitext(reel_filepath)[0]
+ reel_names_list.append(reel_filepath.lower())
+
+ # when '_' are found, replace with space
+ reel_names_list += [reel_filepath.replace("_", " ")
+ for reel_filepath in reel_names_list
+ if "_" in reel_filepath]
+ reel_names.update(reel_names_list)
+
+ # debug info
+ print("Searching or %d reels" % len(bl_reels_search))
+ for reel_names, reel_files_found, reel in bl_reels_search:
+ print("Reel: %r --> (%s)" % (reel.name, " ".join(sorted(reel_names))))
+ print()
+
+ for filename, fileonly in media_file_walker(self.directory):
+ for reel_names, reel_files_found, reel in bl_reels_search:
+ if fileonly.lower() in reel_names:
+ reel_files_found.append((0, filename))
+ else:
+ # check on partial match
+ for r in reel_names:
+ if fileonly.startswith(r):
+ reel_files_found.append((1, filename))
+ if fileonly.endswith(r):
+ reel_files_found.append((2, filename))
+
+ # apply back and report
+ tot_done = 0
+ tot_fail = 0
+ for reel_names, reel_files_found, reel in bl_reels_search:
+ if reel_files_found:
+ # make sure partial matches end last
+ reel_files_found.sort()
+ reel.filepath = reel_files_found[0][1]
+ tot_done += 1
+ else:
+ tot_fail += 1
+
+ self.report({'INFO'} if tot_fail == 0 else {'WARNING'},
+ "Found %d clips, missing %d" % (tot_done, tot_fail))
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ import os
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+
+ if not FindReelsEDL.missing_reels(context):
+ self.report({'INFO'},
+ "Nothing to do, all reels point to valid files")
+ return {'CANCELLED'}
+
+ # default to the EDL path
+ if not self.directory and edl_import_info.filepath:
+ self.directory = os.path.dirname(edl_import_info.filepath)
+
+ wm = context.window_manager
+ wm.fileselect_add(self)
+ return {"RUNNING_MODAL"}
+
+
+class ImportEDL(Operator):
+ """Import an EDL into the sequencer"""
+ bl_idname = "sequencer.import_edl"
+ bl_label = "Import Video Sequence (.edl)"
+
+ def execute(self, context):
+ import os
+ from . import import_edl
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+
+ filepath = edl_import_info.filepath
+ reel_filepaths = {reel.name: reel.filepath
+ for reel in edl_import_info.reels}
+ reel_offsets = {reel.name: reel.frame_offset
+ for reel in edl_import_info.reels}
+
+ if not os.path.exists(filepath):
+ self.report({'ERROR'}, "File Not Found %r" % filepath)
+ return {'CANCELLED'}
+
+ msg = import_edl.load_edl(
+ scene, filepath,
+ reel_filepaths, reel_offsets,
+ edl_import_info.frame_offset)
+
+ if msg:
+ self.report({'WARNING'}, msg)
+
+ return {'FINISHED'}
+
+
+# ----------------------------------------------------------------------------
+# Persistent Scene Data Types (store EDL import info)
+
+class EDLReelInfo(bpy.types.PropertyGroup):
+ name = StringProperty(
+ name="Name",
+ )
+ filepath = StringProperty(
+ name="Video File",
+ subtype='FILE_PATH',
+ )
+ frame_offset = IntProperty(
+ name="Frame Offset",
+ )
+
+
+class EDLImportInfo(bpy.types.PropertyGroup):
+ filepath = StringProperty(
+ subtype='FILE_PATH',
+ )
+ reels = bpy.props.CollectionProperty(
+ type=EDLReelInfo,
+ )
+ frame_offset = IntProperty(
+ name="Global Frame Offset",
+ )
+
+# ----------------------------------------------------------------------------
+# Panel to show EDL Import UI
+
+
+class SEQUENCER_PT_import_edl(bpy.types.Panel):
+ bl_label = "EDL Import"
+ bl_space_type = 'SEQUENCE_EDITOR'
+ bl_region_type = 'UI'
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ edl_import_info = scene.edl_import_info
+
+ layout.operator(ImportEDL.bl_idname)
+
+ col = layout.column(align=True)
+ col.prop(edl_import_info, "frame_offset")
+ col.prop(edl_import_info, "filepath", text="")
+ col.operator(ReloadEDL.bl_idname, icon='FILE_REFRESH')
+
+ box = layout.box()
+ reel = None
+ for reel in scene.edl_import_info.reels:
+ col = box.column(align=True)
+ col.label(text=reel.name)
+ col.prop(reel, "filepath", text="")
+ col.prop(reel, "frame_offset")
+
+ if reel is None:
+ box.label("Empty (No EDL Data)")
+
+ box.operator(FindReelsEDL.bl_idname, icon='EXTERNAL_DATA')
+
+
+def register():
+ bpy.utils.register_class(ReloadEDL)
+ bpy.utils.register_class(FindReelsEDL)
+ bpy.utils.register_class(ImportEDL)
+ bpy.utils.register_class(SEQUENCER_PT_import_edl)
+
+ # edl_import_info
+ bpy.utils.register_class(EDLReelInfo)
+ bpy.utils.register_class(EDLImportInfo)
+ bpy.types.Scene.edl_import_info = PointerProperty(type=EDLImportInfo)
+
+
+def unregister():
+ bpy.utils.unregister_class(ReloadEDL)
+ bpy.utils.unregister_class(FindReelsEDL)
+ bpy.utils.unregister_class(ImportEDL)
+ bpy.utils.unregister_class(SEQUENCER_PT_import_edl)
+
+ # edl_import_info
+ bpy.utils.unregister_class(EDLImportInfo)
+ bpy.utils.unregister_class(EDLReelInfo)
+ del bpy.types.Scene.edl_import_info
diff --git a/release/scripts/addons/io_sequencer_edl/import_edl.py b/release/scripts/addons/io_sequencer_edl/import_edl.py
new file mode 100644
index 0000000..ff95c7c
--- /dev/null
+++ b/release/scripts/addons/io_sequencer_edl/import_edl.py
@@ -0,0 +1,319 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from . import parse_edl
+
+def id_animdata_action_ensure(id_data):
+ id_data.animation_data_create()
+ animation_data = id_data.animation_data
+ if animation_data.action is None:
+ animation_data.action = bpy.data.actions.new(name="Scene Action")
+
+
+def scale_meta_speed(sequence_editor, strip_list, strip_movie, scale):
+ # Add an effect
+ dummy_frame = 0
+ strip_speed = sequence_editor.sequences.new_effect(
+ name="Speed",
+ type='SPEED',
+ seq1=strip_movie,
+ frame_start=dummy_frame,
+ channel=strip_movie.channel + 1)
+ strip_list.append(strip_speed)
+
+ # not working in 2.6x :|
+ strip_speed.use_frame_blend = True
+ #meta = sequence_editor.new([strip_movie, strip_speed], 199, strip_movie.channel)
+
+ # XXX-Meta Operator Mess
+ scene = sequence_editor.id_data
+ # we _know_ there are no others selected
+ for strip in strip_list:
+ strip.select = False
+ strip_movie.select = True
+ strip_speed.select = True
+ bpy.ops.sequencer.meta_make()
+ strip_meta = scene.sequence_editor.sequences[-1] # XXX, weak assumption
+ assert(strip_meta.type == 'META')
+ strip_list.append(strip_meta)
+ strip_movie.select = strip_speed.select = strip_meta.select = False
+ # XXX-Meta Operator Mess (END)
+
+ if scale >= 1.0:
+ strip_movie.frame_still_end = int(strip_movie.frame_duration * (scale - 1.0))
+ else:
+ strip_speed.multiply_speed = 1.0 / scale
+ strip_meta.frame_offset_end = strip_movie.frame_duration - int(strip_movie.frame_duration * scale)
+
+ strip_speed.update()
+ strip_meta.update()
+ return strip_meta
+
+
+def apply_dissolve_fcurve(strip_movie, blendin):
+ scene = strip_movie.id_data
+ id_animdata_action_ensure(scene)
+ action = scene.animation_data.action
+
+ data_path = strip_movie.path_from_id("blend_alpha")
+ blend_alpha_fcurve = action.fcurves.new(data_path, index=0)
+ blend_alpha_fcurve.keyframe_points.insert(strip_movie.frame_final_start, 0.0)
+ blend_alpha_fcurve.keyframe_points.insert(strip_movie.frame_final_end, 1.0)
+
+ blend_alpha_fcurve.keyframe_points[0].interpolation = 'LINEAR'
+ blend_alpha_fcurve.keyframe_points[1].interpolation = 'LINEAR'
+
+ if strip_movie.type != 'SOUND':
+ strip_movie.blend_type = 'ALPHA_OVER'
+
+
+def replace_ext(path, ext):
+ return path[:path.rfind(".") + 1] + ext
+
+
+def load_edl(scene, filename, reel_files, reel_offsets, global_offset):
+ """
+ reel_files - key:reel <--> reel:filename
+ """
+
+ strip_list = []
+
+ import os
+ # For test file
+ # frame_offset = -769
+
+ fps = scene.render.fps
+ dummy_frame = 1
+
+ elist = parse_edl.EditList()
+ if not elist.parse(filename, fps):
+ return "Unable to parse %r" % filename
+
+ scene.sequence_editor_create()
+ sequence_editor = scene.sequence_editor
+
+ for strip in sequence_editor.sequences_all:
+ strip.select = False
+
+ # elist.clean()
+
+ track = 0
+
+ edits = elist.edits[:]
+ # edits.sort(key = lambda edit: int(edit.recIn))
+
+ prev_edit = None
+ for edit in edits:
+ print(edit)
+ if edit.reel.lower() in parse_edl.BLACK_ID:
+ frame_offset = 0
+ else:
+ frame_offset = reel_offsets[edit.reel]
+
+ src_start = int(edit.srcIn) + frame_offset
+ src_end = int(edit.srcOut) + frame_offset
+ src_length = src_end - src_start
+
+ rec_start = int(edit.recIn) + 1
+ rec_end = int(edit.recOut) + 1
+ rec_length = rec_end - rec_start
+
+ # apply global offset
+ rec_start += global_offset
+ rec_end += global_offset
+
+ # print src_length, rec_length, src_start
+
+ if edit.m2 is not None:
+ scale = fps / edit.m2.fps
+ else:
+ scale = 1.0
+
+ unedited_start = rec_start - src_start
+ offset_start = src_start - int(src_start * scale) # works for scaling up AND down
+
+ if edit.transition_type == parse_edl.TRANSITION_CUT and (not elist.overlap_test(edit)):
+ track = 1
+
+ strip = None
+ final_strips = []
+ if edit.reel.lower() in parse_edl.BLACK_ID:
+ strip = sequence_editor.sequences.new_effect(
+ name="Color",
+ type='COLOR',
+ frame_start=rec_start,
+ frame_end=rec_start + max(1, rec_length),
+ channel=track + 1)
+ strip_list.append(strip)
+ final_strips.append(strip)
+ strip.color = 0.0, 0.0, 0.0
+
+ else:
+ path_full = reel_files[edit.reel]
+ path_dironly, path_fileonly = os.path.split(path_full)
+
+ if edit.edit_type & parse_edl.EDIT_VIDEO: # and edit.transition_type == parse_edl.TRANSITION_CUT:
+
+ #try:
+ strip = sequence_editor.sequences.new_movie(
+ name=edit.reel,
+ filepath=path_full,
+ channel=track + 1,
+ frame_start=unedited_start + offset_start)
+ strip_list.append(strip)
+ #except:
+ # return "Invalid input for movie"
+
+ # Apply scaled rec in bounds
+ if scale != 1.0:
+ meta = scale_meta_speed(sequence_editor, strip_list, strip, scale)
+ final_strip = meta
+ else:
+ final_strip = strip
+
+ final_strip.update()
+ final_strip.frame_offset_start = rec_start - final_strip.frame_final_start
+ final_strip.frame_offset_end = rec_end - final_strip.frame_final_end
+ final_strip.update()
+ final_strip.frame_offset_end += (final_strip.frame_final_end - rec_end)
+ final_strip.update()
+
+ if edit.transition_duration:
+ if not prev_edit:
+ print("Error no previous strip")
+ else:
+ new_end = rec_start + int(edit.transition_duration)
+ for other in prev_edit.custom_data:
+ if other.type != 'SOUND':
+ other.frame_offset_end += (other.frame_final_end - new_end)
+ other.update()
+
+ # Apply disolve
+ if edit.transition_type == parse_edl.TRANSITION_DISSOLVE:
+ apply_dissolve_fcurve(final_strip, edit.transition_duration)
+
+ if edit.transition_type == parse_edl.TRANSITION_WIPE:
+ other_track = track + 2
+ for other in prev_edit.custom_data:
+ if other.type != 'SOUND':
+ strip_wipe = sequence_editor.sequences.new_effect(
+ name="Wipe",
+ type='WIPE',
+ seq1=final_strip,
+ frame_start=dummy_frame,
+ channel=other_track)
+ strip_list.append(strip_wipe)
+
+ from math import radians
+ if edit.wipe_type == parse_edl.WIPE_0:
+ strip_wipe.angle = radians(+90)
+ else:
+ strip_wipe.angle = radians(-90)
+
+ other_track += 1
+
+ # strip.frame_offset_end = strip.frame_duration - int(edit.srcOut)
+ # end_offset = (unedited_start + strip.frame_duration) - end
+ # print start, end, end_offset
+ # strip.frame_offset_end = end_offset
+ #
+ # break
+ # print(strip)
+
+ final_strips.append(final_strip)
+
+ if edit.edit_type & (parse_edl.EDIT_AUDIO | parse_edl.EDIT_AUDIO_STEREO | parse_edl.EDIT_VIDEO_AUDIO):
+
+ if scale == 1.0: # TODO - scaled audio
+
+ try:
+ strip = sequence_editor.sequences.new_sound(
+ name=edit.reel,
+ filepath=path_full,
+ channel=track + 6,
+ frame_start=unedited_start + offset_start)
+ strip_list.append(strip)
+ except:
+
+ # See if there is a wave file there
+ path_full_wav = replace_ext(path_full, "wav")
+ path_fileonly_wav = replace_ext(path_fileonly, "wav")
+
+ #try:
+ strip = sequence_editor.sequences.new_sound(
+ name=edit.reel,
+ filepath=path_full_wav,
+ channel=track + 6,
+ frame_start=unedited_start + offset_start)
+ strip_list.append(strip)
+ #except:
+ # return "Invalid input for audio"
+
+ final_strip = strip
+
+ # Copied from above
+ final_strip.update()
+ final_strip.frame_offset_start = rec_start - final_strip.frame_final_start
+ final_strip.frame_offset_end = rec_end - final_strip.frame_final_end
+ final_strip.update()
+ final_strip.frame_offset_end += (final_strip.frame_final_end - rec_end)
+ final_strip.update()
+
+ if edit.transition_type == parse_edl.TRANSITION_DISSOLVE:
+ apply_dissolve_fcurve(final_strip, edit.transition_duration)
+
+ final_strips.append(final_strip)
+
+ if final_strips:
+ for strip in final_strips:
+ # strip.frame_duration = length
+ strip.name = edit.as_name()
+ edit.custom_data[:] = final_strips
+ # track = not track
+ prev_edit = edit
+ track += 1
+
+ #break
+
+ for strip in strip_list:
+ strip.update(True)
+ strip.select = True
+
+ return ""
+
+
+def _test():
+ elist = parse_edl.EditList()
+ _filename = "/fe/edl/cinesoft/rush/blender_edl.edl"
+ _fps = 25
+ if not elist.parse(_filename, _fps):
+ assert(0)
+ reels = elist.reels_as_dict()
+
+ print(list(reels.keys()))
+
+ # import pdb; pdb.set_trace()
+ msg = load_edl(bpy.context.scene,
+ _filename,
+ {'tapec': "/fe/edl/cinesoft/rush/rushes3.avi"},
+ {'tapec': 0}) # /tmp/test.edl
+ print(msg)
+# _test()
diff --git a/release/scripts/addons/io_sequencer_edl/parse_edl.py b/release/scripts/addons/io_sequencer_edl/parse_edl.py
new file mode 100644
index 0000000..683e67b
--- /dev/null
+++ b/release/scripts/addons/io_sequencer_edl/parse_edl.py
@@ -0,0 +1,586 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+This is a pure python module (no blender deps),
+that parses EDL files and could be used outside of blender.
+"""
+
+class TimeCode:
+ """
+ Simple timecode class
+ also supports conversion from other time strings used by EDL
+ """
+ __slots__ = (
+ "fps",
+ "hours",
+ "minutes",
+ "seconds",
+ "frame",
+ )
+
+ def __init__(self, data, fps):
+ self.fps = fps
+ if type(data) == str:
+ self.from_string(data)
+ frame = self.as_frame()
+ self.from_frame(frame)
+ else:
+ self.from_frame(data)
+
+ def from_string(self, text):
+ # hh:mm:ss:ff
+ # No dropframe support yet
+
+ if text.lower().endswith("mps"): # 5.2mps
+ return self.from_frame(int(float(text[:-3]) * self.fps))
+ elif text.lower().endswith("s"): # 5.2s
+ return self.from_frame(int(float(text[:-1]) * self.fps))
+ elif text.isdigit(): # 1234
+ return self.from_frame(int(text))
+ elif ":" in text: # hh:mm:ss:ff
+ text = text.replace(";", ":").replace(",", ":").replace(".", ":")
+ text = text.split(":")
+
+ self.hours = int(text[0])
+ self.minutes = int(text[1])
+ self.seconds = int(text[2])
+ self.frame = int(text[3])
+ return self
+ else:
+ print("ERROR: could not convert this into timecode %r" % text)
+ return self
+
+ def from_frame(self, frame):
+
+ if frame < 0:
+ frame = -frame
+ neg = True
+ else:
+ neg = False
+
+ fpm = 60 * self.fps
+ fph = 60 * fpm
+
+ if frame < fph:
+ self.hours = 0
+ else:
+ self.hours = int(frame / fph)
+ frame = frame % fph
+
+ if frame < fpm:
+ self.minutes = 0
+ else:
+ self.minutes = int(frame / fpm)
+ frame = frame % fpm
+
+ if frame < self.fps:
+ self.seconds = 0
+ else:
+ self.seconds = int(frame / self.fps)
+ frame = frame % self.fps
+
+ self.frame = frame
+
+ if neg:
+ self.frame = -self.frame
+ self.seconds = -self.seconds
+ self.minutes = -self.minutes
+ self.hours = -self.hours
+
+ return self
+
+ def as_frame(self):
+ abs_frame = self.frame
+ abs_frame += self.seconds * self.fps
+ abs_frame += self.minutes * 60 * self.fps
+ abs_frame += self.hours * 60 * 60 * self.fps
+
+ return abs_frame
+
+ def as_string(self):
+ self.from_frame(int(self))
+ return "%.2d:%.2d:%.2d:%.2d" % (self.hours, self.minutes, self.seconds, self.frame)
+
+ def __repr__(self):
+ return self.as_string()
+
+ # Numeric stuff, may as well have this
+ def __neg__(self):
+ return TimeCode(-int(self), self.fps)
+
+ def __int__(self):
+ return self.as_frame()
+
+ def __sub__(self, other):
+ return TimeCode(int(self) - int(other), self.fps)
+
+ def __add__(self, other):
+ return TimeCode(int(self) + int(other), self.fps)
+
+ def __mul__(self, other):
+ return TimeCode(int(self) * int(other), self.fps)
+
+ def __div__(self, other):
+ return TimeCode(int(self) // int(other), self.fps)
+
+ def __abs__(self):
+ return TimeCode(abs(int(self)), self.fps)
+
+ def __iadd__(self, other):
+ return self.from_frame(int(self) + int(other))
+
+ def __imul__(self, other):
+ return self.from_frame(int(self) * int(other))
+
+ def __idiv__(self, other):
+ return self.from_frame(int(self) // int(other))
+# end timecode
+
+
+"""Comments
+Comments can appear at the beginning of the EDL file (header) or between the edit lines in the EDL. The first block of comments in the file is defined to be the header comments and they are associated with the EDL as a whole. Subsequent comments in the EDL file are associated with the first edit line that appears after them.
+Edit Entries
+<filename|tag> <EditMode> <TransitionType>[num] [duration] [srcIn] [srcOut] [recIn] [recOut]
+
+ * <filename|tag>: Filename or tag value. Filename can be for an MPEG file, Image file, or Image file template. Image file templates use the same pattern matching as for command line glob, and can be used to specify images to encode into MPEG. i.e. /usr/data/images/image*.jpg
+ * <EditMode>: 'V' | 'A' | 'VA' | 'B' | 'v' | 'a' | 'va' | 'b' which equals Video, Audio, Video_Audio edits (note B or b can be used in place of VA or va).
+ * <TransitonType>: 'C' | 'D' | 'E' | 'FI' | 'FO' | 'W' | 'c' | 'd' | 'e' | 'fi' | 'fo' | 'w'. which equals Cut, Dissolve, Effect, FadeIn, FadeOut, Wipe.
+ * [num]: if TransitionType = Wipe, then a wipe number must be given. At the moment only wipe 'W0' and 'W1' are supported.
+ * [duration]: if the TransitionType is not equal to Cut, then an effect duration must be given. Duration is in frames.
+ * [srcIn]: Src in. If no srcIn is given, then it defaults to the first frame of the video or the first frame in the image pattern. If srcIn isn't specified, then srcOut, recIn, recOut can't be specified.
+ * [srcOut]: Src out. If no srcOut is given, then it defaults to the last frame of the video - or last image in the image pattern. if srcOut isn't given, then recIn and recOut can't be specified.
+ * [recIn]: Rec in. If no recIn is given, then it is calculated based on its position in the EDL and the length of its input.
+ [recOut]: Rec out. If no recOut is given, then it is calculated based on its position in the EDL and the length of its input. first frame of the video.
+
+For srcIn, srcOut, recIn, recOut, the values can be specified as either timecode, frame number, seconds, or mps seconds. i.e.
+[tcode | fnum | sec | mps], where:
+
+ * tcode : SMPTE timecode in hh:mm:ss:ff
+ * fnum : frame number (the first decodable frame in the video is taken to be frame 0).
+ * sec : seconds with 's' suffix (e.g. 5.2s)
+ * mps : seconds with 'mps' suffix (e.g. 5.2mps). This corresponds to the 'seconds' value displayed by Windows MediaPlayer.
+
+More notes,
+Key
+
+"""
+
+enum = 0
+TRANSITION_UNKNOWN = enum
+TRANSITION_CUT = enum
+enum += 1
+TRANSITION_DISSOLVE = enum
+enum += 1
+TRANSITION_EFFECT = enum
+enum += 1
+TRANSITION_FADEIN = enum
+enum += 1
+TRANSITION_FADEOUT = enum
+enum += 1
+TRANSITION_WIPE = enum
+enum += 1
+TRANSITION_KEY = enum
+enum += 1
+
+TRANSITION_DICT = {
+ "c": TRANSITION_CUT,
+ "d": TRANSITION_DISSOLVE,
+ "e": TRANSITION_EFFECT,
+ "fi": TRANSITION_FADEIN,
+ "fo": TRANSITION_FADEOUT,
+ "w": TRANSITION_WIPE,
+ "k": TRANSITION_KEY,
+ }
+
+enum = 0
+EDIT_UNKNOWN = 1 << enum
+enum += 1
+EDIT_VIDEO = 1 << enum
+enum += 1
+EDIT_AUDIO = 1 << enum
+enum += 1
+EDIT_AUDIO_STEREO = 1 << enum
+enum += 1
+EDIT_VIDEO_AUDIO = 1 << enum
+enum += 1
+
+EDIT_DICT = {
+ "none": 0, # TODO, investigate this more.
+ "v": EDIT_VIDEO,
+ "a": EDIT_AUDIO,
+ "aa": EDIT_AUDIO_STEREO,
+ "va": EDIT_VIDEO_AUDIO,
+ "b": EDIT_VIDEO_AUDIO,
+ }
+
+
+enum = 0
+WIPE_UNKNOWN = enum
+WIPE_0 = enum
+enum += 1
+WIPE_1 = enum
+enum += 1
+
+enum = 0
+KEY_UNKNOWN = enum
+KEY_BG = enum # K B
+enum += 1
+KEY_IN = enum # This is assumed if no second type is set
+enum += 1
+KEY_OUT = enum # K O
+enum += 1
+
+BLACK_ID = {
+ "bw",
+ "bl",
+ "blk",
+ "black",
+ }
+
+
+"""
+Most sytems:
+Non-dropframe: 1:00:00:00 - colon in last position
+Dropframe: 1:00:00;00 - semicolon in last position
+PAL/SECAM: 1:00:00:00 - colon in last position
+
+SONY:
+Non-dropframe: 1:00:00.00 - period in last position
+Dropframe: 1:00:00,00 - comma in last position
+PAL/SECAM: 1:00:00.00 - period in last position
+"""
+
+"""
+t = abs(timecode('-124:-12:-43:-22', 25))
+t /= 2
+print t
+"""
+
+class EditDecision:
+ __slots__ = (
+ "number",
+ "reel",
+ "transition_duration",
+ "edit_type",
+ "transition_type",
+ "wipe_type",
+ "key_type",
+ "key_fade",
+ "srcIn",
+ "srcOut",
+ "recIn",
+ "recOut",
+ "m2",
+ "filename",
+ "custom_data",
+ )
+
+ @staticmethod
+ def edit_flags_to_text(flag):
+ return "/".join([item for item, val in EDIT_DICT.items() if val & flag])
+
+ @staticmethod
+ def strip_digits(text):
+ return "".join(filter(lambda x: not x.isdigit(), text))
+
+ def __init__(self, text=None, fps=25):
+ # print text
+ self.number = -1
+ self.reel = "" # Uniqie name for this 'file' but not filename, when BL signifies black
+ self.transition_duration = 0
+ self.edit_type = EDIT_UNKNOWN
+ self.transition_type = TRANSITION_UNKNOWN
+ self.wipe_type = WIPE_UNKNOWN
+ self.key_type = KEY_UNKNOWN
+ self.key_fade = -1 # true/false
+ self.srcIn = None # Where on the original field recording the event begins
+ self.srcOut = None # Where on the original field recording the event ends
+ self.recIn = None # Beginning of the original event in the edited program
+ self.recOut = None # End of the original event in the edited program
+ self.m2 = None # fps set by the m2 command
+ self.filename = ""
+
+ self.custom_data = [] # use for storing any data you want (blender strip for eg)
+
+ if text is not None:
+ self.read(text, fps)
+
+ def __repr__(self):
+ txt = "num: %d, " % self.number
+ txt += "reel: %s, " % self.reel
+ txt += "edit_type: "
+ txt += EditDecision.edit_flags_to_text(self.edit_type) + ", "
+
+ txt += "trans_type: "
+ for item, val in TRANSITION_DICT.items():
+ if val == self.transition_type:
+ txt += item + ", "
+ break
+
+ txt += "m2: "
+ if self.m2:
+ txt += "%g" % float(self.m2.fps)
+ txt += "\n\t"
+ txt += self.m2.data
+ else:
+ txt += "nil"
+
+ txt += ", "
+ txt += "recIn: " + str(self.recIn) + ", "
+ txt += "recOut: " + str(self.recOut) + ", "
+ txt += "srcIn: " + str(self.srcIn) + ", "
+ txt += "srcOut: " + str(self.srcOut) + ", "
+
+ return txt
+
+ def read(self, line, fps):
+ line = line.split()
+ index = 0
+ self.number = int(line[index])
+ index += 1
+ self.reel = line[index].lower()
+ index += 1
+
+ # AA/V can be an edit type
+ self.edit_type = 0
+ for edit_type in line[index].lower().split("/"):
+ # stripping digits is done because we don't do 'a1, a2...'
+ self.edit_type |= EDIT_DICT[EditDecision.strip_digits(edit_type)]
+ index += 1
+
+ tx_name = "".join([c for c in line[index].lower() if not c.isdigit()])
+ self.transition_type = TRANSITION_DICT[tx_name] # advance the index later
+
+ if self.transition_type == TRANSITION_WIPE:
+ tx_num = "".join([c for c in line[index].lower() if c.isdigit()])
+ if tx_num:
+ tx_num = int(tx_num)
+ else:
+ tx_num = 0
+
+ self.wipe_type = tx_num
+
+ elif self.transition_type == TRANSITION_KEY: # UNTESTED
+
+ val = line[index + 1].lower()
+
+ if val == "b":
+ self.key_type = KEY_BG
+ index += 1
+ elif val == "o":
+ self.key_type = KEY_OUT
+ index += 1
+ else:
+ self.key_type = KEY_IN # if no args given
+
+ # there may be an (F) after, eg 'K B (F)'
+ # in the docs this should only be after K B but who knows, it may be after K O also?
+ val = line[index + 1].lower()
+ if val == "(f)":
+ index += 1
+ self.key_fade = True
+ else:
+ self.key_fade = False
+
+ index += 1
+
+ if self.transition_type in {TRANSITION_DISSOLVE, TRANSITION_EFFECT, TRANSITION_FADEIN, TRANSITION_FADEOUT, TRANSITION_WIPE}:
+ self.transition_duration = TimeCode(line[index], fps)
+ index += 1
+
+ if index < len(line):
+ self.srcIn = TimeCode(line[index], fps)
+ index += 1
+ if index < len(line):
+ self.srcOut = TimeCode(line[index], fps)
+ index += 1
+
+ if index < len(line):
+ self.recIn = TimeCode(line[index], fps)
+ index += 1
+ if index < len(line):
+ self.recOut = TimeCode(line[index], fps)
+ index += 1
+
+ def renumber(self):
+ self.edits.sort(key=lambda e: int(e.recIn))
+ for i, edit in enumerate(self.edits):
+ edit.number = i
+
+ def clean(self):
+ """
+ Clean up double ups
+ """
+ self.renumber()
+
+ # TODO
+ def as_name(self):
+ cut_type = "nil"
+ for k, v in TRANSITION_DICT.items():
+ if v == self.transition_type:
+ cut_type = k
+ break
+
+ return "%d_%s_%s" % (self.number, self.reel, cut_type)
+
+
+class M2:
+ __slots__ = (
+ "reel",
+ "fps",
+ "time",
+ "data",
+ "index",
+ "tot",
+ )
+
+ def __init__(self):
+ self.reel = None
+ self.fps = None
+ self.time = None
+ self.data = None
+
+ self.index = -1
+ self.tot = -1
+
+ def read(self, line, fps):
+
+ # M2 TAPEC 050.5 00:08:11:08
+ words = line.split()
+
+ self.reel = words[1].lower()
+ self.fps = float(words[2])
+ self.time = TimeCode(words[3], fps)
+
+ self.data = line
+
+
+class EditList:
+ __slots__ = (
+ "edits",
+ "title",
+ )
+
+ def __init__(self):
+ self.edits = []
+ self.title = ""
+
+ def parse(self, filename, fps):
+ try:
+ file = open(filename, "r", encoding="utf-8")
+ except:
+ return False
+
+ self.edits = []
+ edits_m2 = [] # edits with m2's
+
+ has_m2 = False
+
+ for line in file:
+ line = " ".join(line.split())
+
+ if not line or line.startswith(("*", "#")):
+ continue
+ elif line.startswith("TITLE:"):
+ self.title = " ".join(line.split()[1:])
+ elif line.split()[0].lower() == "m2":
+ has_m2 = True
+ m2 = M2()
+ m2.read(line, fps)
+ edits_m2.append(m2)
+ elif not line.split()[0].isdigit():
+ print("Ignoring:", line)
+ else:
+ self.edits.append(EditDecision(line, fps))
+ edits_m2.append(self.edits[-1])
+
+ if has_m2:
+ # Group indexes
+ i = 0
+ for item in edits_m2:
+ if isinstance(item, M2):
+ item.index = i
+ i += 1
+ else:
+ # not an m2
+ i = 0
+
+ # Set total group indexes
+ for item in reversed(edits_m2):
+ if isinstance(item, M2):
+ if tot_m2 == -1:
+ tot_m2 = item.index + 1
+
+ item.tot = tot_m2
+ else:
+ # not an m2
+ tot_m2 = -1
+
+ for i, item in enumerate(edits_m2):
+ if isinstance(item, M2):
+ # make a list of all items that match the m2's reel name
+ edits_m2_tmp = [item_tmp for item_tmp in edits_m2 if (isinstance(item, M2) or item_tmp.reel == item.reel)]
+
+ # get the new index
+ i_tmp = edits_m2_tmp.index(item)
+
+ # Seek back to get the edit.
+ edit = edits_m2[i_tmp - item.tot]
+
+ # Note, docs say time should also match with edit start time
+ # but from final cut pro, this seems not to be the case
+ if not isinstance(edit, EditDecision):
+ print("ERROR!", "M2 incorrect")
+ else:
+ edit.m2 = item
+
+ file.close()
+ return True
+
+ def overlap_test(self, edit_test):
+ recIn = int(edit_test.recIn)
+ recOut = int(edit_test.recOut)
+
+ for edit in self.edits:
+ if edit is edit_test:
+ break
+
+ recIn_other = int(edit.recIn)
+ recOut_other = int(edit.recOut)
+
+ if recIn_other < recIn < recOut_other:
+ return True
+ if recIn_other < recOut < recOut_other:
+ return True
+
+ if recIn < recIn_other < recOut:
+ return True
+ if recIn < recOut_other < recOut:
+ return True
+
+ return False
+
+ def reels_as_dict(self):
+ reels = {}
+ for edit in self.edits:
+ reels.setdefault(edit.reel, []).append(edit)
+
+ return reels
diff --git a/release/scripts/addons/io_shape_mdd/__init__.py b/release/scripts/addons/io_shape_mdd/__init__.py
index 8a6450b..d1b8b84 100644
--- a/release/scripts/addons/io_shape_mdd/__init__.py
+++ b/release/scripts/addons/io_shape_mdd/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "NewTek MDD format",
"author": "Bill L.Nieuwendorp",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "File > Import-Export",
"description": "Import-Export MDD as mesh shape keys",
"warning": "",
diff --git a/release/scripts/addons/light_field_tools/__init__.py b/release/scripts/addons/light_field_tools/__init__.py
index cabdd35..08ff8c3 100644
--- a/release/scripts/addons/light_field_tools/__init__.py
+++ b/release/scripts/addons/light_field_tools/__init__.py
@@ -18,16 +18,16 @@
bl_info = {
- 'name': 'Light Field Tools',
- 'author': 'Aurel Wildfellner',
- 'description': 'Tools to create a light field camera and projector',
- 'version': (0, 3, 0),
- 'blender': (2, 6, 4),
- 'location': 'View3D > Tool Shelf > Light Field Tools',
- 'url': 'http://www.jku.at/cg/',
+ "name": "Light Field Tools",
+ "author": "Aurel Wildfellner",
+ "description": "Tools to create a light field camera and projector",
+ "version": (0, 3, 0),
+ "blender": (2, 64, 0),
+ "location": "View3D > Tool Shelf > Light Field Tools",
+ "url": "http://www.jku.at/cg/",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Render/Light_Field_Tools",
"tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25719",
- 'category': 'Render'
+ "category": "Render"
}
diff --git a/release/scripts/addons/mesh_bsurfaces.py b/release/scripts/addons/mesh_bsurfaces.py
index bd43513..7aa43d7 100644
--- a/release/scripts/addons/mesh_bsurfaces.py
+++ b/release/scripts/addons/mesh_bsurfaces.py
@@ -21,7 +21,7 @@ bl_info = {
"name": "Bsurfaces GPL Edition",
"author": "Eclectiel",
"version": (1,5),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"api": 45996,
"location": "View3D > EditMode > ToolShelf",
"description": "Modeling and retopology tool.",
@@ -3260,8 +3260,12 @@ class GPENCIL_OT_SURFSK_edit_strokes(bpy.types.Operator):
elif self.strokes_type == "GP_STROKES" or self.strokes_type == "SINGLE_GP_STROKE_NO_SELECTION":
#### Convert grease pencil strokes to curve.
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
- bpy.ops.gpencil.convert('INVOKE_REGION_WIN', type='CURVE')
- ob_gp_strokes = bpy.context.object
+ bpy.ops.gpencil.convert('INVOKE_REGION_WIN', type='CURVE', use_link_strokes=False)
+ for ob in bpy.context.selected_objects:
+ if ob != bpy.context.scene.objects.active and ob.name.startswith("GP_Layer"):
+ ob_gp_strokes = ob
+
+ #ob_gp_strokes = bpy.context.object
#### Delete grease pencil strokes.
bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
@@ -3319,9 +3323,12 @@ class CURVE_OT_SURFSK_reorder_splines(bpy.types.Operator):
objects_to_delete = []
#### Convert grease pencil strokes to curve.
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
- bpy.ops.gpencil.convert('INVOKE_REGION_WIN', type='CURVE')
+ bpy.ops.gpencil.convert('INVOKE_REGION_WIN', type='CURVE', use_link_strokes=False)
+ for ob in bpy.context.selected_objects:
+ if ob != bpy.context.scene.objects.active and ob.name.startswith("GP_Layer"):
+ GP_strokes_curve = ob
- GP_strokes_curve = bpy.context.object
+ #GP_strokes_curve = bpy.context.object
objects_to_delete.append(GP_strokes_curve)
bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
diff --git a/release/scripts/addons/mesh_inset/__init__.py b/release/scripts/addons/mesh_inset/__init__.py
index d494fd1..8d4054d 100644
--- a/release/scripts/addons/mesh_inset/__init__.py
+++ b/release/scripts/addons/mesh_inset/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Inset Polygon",
"author": "Howard Trickey",
"version": (0, 4),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "View3D > Tools",
"description": "Make an inset polygon inside selection.",
"warning": "",
diff --git a/release/scripts/addons/mesh_looptools.py b/release/scripts/addons/mesh_looptools.py
index 81f972c..20c9b67 100644
--- a/release/scripts/addons/mesh_looptools.py
+++ b/release/scripts/addons/mesh_looptools.py
@@ -17,18 +17,18 @@
# ##### END GPL LICENSE BLOCK #####
bl_info = {
- 'name': "LoopTools",
- 'author': "Bart Crouch",
- 'version': (4, 2, 0),
- 'blender': (2, 6, 3),
- 'location': "View3D > Toolbar and View3D > Specials (W-key)",
- 'warning': "",
- 'description': "Mesh modelling toolkit. Several tools to aid modelling",
- 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
- "Scripts/Modeling/LoopTools",
- 'tracker_url': "http://projects.blender.org/tracker/index.php?"\
- "func=detail&aid=26189",
- 'category': 'Mesh'}
+ "name": "LoopTools",
+ "author": "Bart Crouch",
+ "version": (4, 2, 0),
+ "blender": (2, 63, 0),
+ "location": "View3D > Toolbar and View3D > Specials (W-key)",
+ "warning": "",
+ "description": "Mesh modelling toolkit. Several tools to aid modelling",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Modeling/LoopTools",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=26189",
+ "category": "Mesh"}
import bmesh
@@ -751,7 +751,14 @@ def settings_write(self):
# clean up and set settings back to original state
def terminate(global_undo):
- bpy.context.user_preferences.edit.use_global_undo = global_undo
+ context = bpy.context
+
+ # update editmesh cached data
+ obj = context.active_object
+ if obj.mode == 'EDIT':
+ bmesh.update_edit_mesh(obj.data, tessface=True, destructive=True)
+
+ context.user_preferences.edit.use_global_undo = global_undo
##########################################
@@ -2997,6 +3004,7 @@ class Bridge(bpy.types.Operator):
if self.remove_faces and old_selected_faces:
bridge_remove_internal_faces(bm, old_selected_faces)
# make sure normals are facing outside
+ bmesh.update_edit_mesh(object.data, tessface=False, destructive=True)
bpy.ops.mesh.normals_make_consistent()
# cleaning up
diff --git a/release/scripts/addons/mesh_relax.py b/release/scripts/addons/mesh_relax.py
index d168d05..579cce2 100644
--- a/release/scripts/addons/mesh_relax.py
+++ b/release/scripts/addons/mesh_relax.py
@@ -25,7 +25,7 @@ bl_info = {
"name": "Relax",
"author": "Fabian Fricke",
"version": (1,1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Specials > Relax ",
"description": "Relax the selected verts while retaining the shape",
"warning": "",
diff --git a/release/scripts/addons/mocap/__init__.py b/release/scripts/addons/mocap/__init__.py
index ac1e350..1681e0a 100644
--- a/release/scripts/addons/mocap/__init__.py
+++ b/release/scripts/addons/mocap/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Motion Capture Tools",
"author": "Benjy Cook",
- "blender": (2, 6, 2),
+ "blender": (2, 62, 0),
"location": "Object UI -> Mocap tools",
"description": "Various tools for working with motion capture animation",
"warning": "",
diff --git a/release/scripts/addons/modules/extensions_framework/__init__.py b/release/scripts/addons/modules/extensions_framework/__init__.py
index af909b4..5a53a63 100644
--- a/release/scripts/addons/modules/extensions_framework/__init__.py
+++ b/release/scripts/addons/modules/extensions_framework/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf8 -*-
+# -*- coding: utf-8 -*-
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/release/scripts/addons/modules/extensions_framework/ui.py b/release/scripts/addons/modules/extensions_framework/ui.py
index 9443091..2533a66 100644
--- a/release/scripts/addons/modules/extensions_framework/ui.py
+++ b/release/scripts/addons/modules/extensions_framework/ui.py
@@ -1,4 +1,4 @@
-# -*- coding: utf8 -*-
+# -*- coding: utf-8 -*-
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -295,7 +295,7 @@ class property_group_renderer(bpy.types.Panel):
)
elif current_property['type'] in ['template_list']:
- layout.template_list(
+ layout.template_list("UI_UL_list", "",
current_property['src'](supercontext, context),
current_property['src_attr'],
current_property['trg'](supercontext, context),
diff --git a/release/scripts/addons/modules/extensions_framework/util.py b/release/scripts/addons/modules/extensions_framework/util.py
index dd71e55..2ad450b 100644
--- a/release/scripts/addons/modules/extensions_framework/util.py
+++ b/release/scripts/addons/modules/extensions_framework/util.py
@@ -1,4 +1,4 @@
-# -*- coding: utf8 -*-
+# -*- coding: utf-8 -*-
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/release/scripts/addons/modules/extensions_framework/validate.py b/release/scripts/addons/modules/extensions_framework/validate.py
index 5b20552..85851b8 100644
--- a/release/scripts/addons/modules/extensions_framework/validate.py
+++ b/release/scripts/addons/modules/extensions_framework/validate.py
@@ -1,4 +1,4 @@
-# -*- coding: utf8 -*-
+# -*- coding: utf-8 -*-
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/release/scripts/addons/modules/rna_wiki_reference.py b/release/scripts/addons/modules/rna_wiki_reference.py
index 1be0841..ad3ad58 100644
--- a/release/scripts/addons/modules/rna_wiki_reference.py
+++ b/release/scripts/addons/modules/rna_wiki_reference.py
@@ -169,6 +169,7 @@ url_manual_mapping = (
("bpy.types.ImageFormatSettings.*", "Render/Output#File_Type"),
("bpy.types.RenderSettings.filepath", "Render/Output#File_Locations"),
+ ("bpy.types.RenderSettings.display_mode", "Render/Display#Displaying_Renders"),
("bpy.types.RenderSettings.*", "Render"), # catchall, TODO - refine
# *** ID Subclasses ***
@@ -185,7 +186,18 @@ url_manual_mapping = (
#("bpy.types.Mask.*", ""), # TODO - manual has no place for this! XXX
# *** Materials (blender internal) ***
("bpy.types.Material.diffuse*", "Materials/Properties/Diffuse_Shaders"),
+ ("bpy.types.Material.specular*", "Materials/Properties/Specular_Shaders"),
+ ("bpy.types.Material.ambient*", "Materials/Properties/Ambient_Light_Effect"),
+ ("bpy.types.Material.preview_render_type", "Materials/Preview"),
("bpy.types.Material.*", "Materials"), # catchall, until the section is filled in
+
+ ("bpy.types.MaterialSlot.link", "Materials/Options#Material_naming_and_linking"),
+ ("bpy.types.MaterialVolume.*", "Materials/Properties/Volume"),
+ ("bpy.types.MaterialHalo.*", "Materials/Halos"),
+ ("bpy.types.MaterialStrand.*", "Materials/Properties/Strands"),
+ ("bpy.types.MaterialSubsurfaceScattering.*", "Materials/Properties/Subsurface_Scattering"),
+ ("bpy.types.MaterialRaytraceMirror.*", "Materials/Properties/Raytraced_Reflections"),
+ ("bpy.types.MaterialRaytraceTransparency.*", "Materials/Properties/Raytraced_Transparency#Raytraced_Transparency"),
# ... todo, many more options
("bpy.types.MovieClip.*", "Motion_Tracking#Movie_Clip_Editor"),
#("bpy.types.NodeTree.*", ""), # dont document
@@ -270,6 +282,7 @@ url_manual_mapping = (
("bpy.ops.logic.*", "Game_Engine/Logic"),
("bpy.ops.marker.*", "Animation/Markers"),
# ("bpy.ops.mask.*", ""), # TODO
+ ("bpy.ops.material.new", "Materials/Assigning_a_material#Creating_a_new_Material"),
("bpy.ops.material.*", "Materials"),
("bpy.ops.mball.*", "Modeling/Metas"),
("bpy.ops.mesh.*", "Modeling/Meshes"),
diff --git a/release/scripts/addons/netrender/__init__.py b/release/scripts/addons/netrender/__init__.py
index a954ec0..2737ee5 100644
--- a/release/scripts/addons/netrender/__init__.py
+++ b/release/scripts/addons/netrender/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Network Renderer",
"author": "Martin Poirier",
"version": (1, 8),
- "blender": (2, 6, 0),
+ "blender": (2, 60, 0),
"location": "Render > Engine > Network Render",
"description": "Distributed rendering for Blender",
"warning": "Stable but still work in progress",
@@ -72,11 +72,6 @@ def register():
import bpy
bpy.utils.register_module(__name__)
- scene = bpy.context.scene
- if scene:
- ui.init_data(scene.network_render)
-
-
def unregister():
import bpy
bpy.utils.unregister_module(__name__)
diff --git a/release/scripts/addons/netrender/ui.py b/release/scripts/addons/netrender/ui.py
index 319c106..9d032cf 100644
--- a/release/scripts/addons/netrender/ui.py
+++ b/release/scripts/addons/netrender/ui.py
@@ -276,7 +276,7 @@ class RENDER_PT_network_slaves(NeedValidAddress, NetRenderButtonsPanel, bpy.type
netsettings = context.scene.network_render
row = layout.row()
- row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
+ row.template_list("UI_UL_list", "", netsettings, "slaves", netsettings, "active_slave_index", rows=2)
sub = row.column(align=True)
sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
@@ -307,7 +307,8 @@ class RENDER_PT_network_slaves_blacklist(NeedValidAddress, NetRenderButtonsPanel
netsettings = context.scene.network_render
row = layout.row()
- row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
+ row.template_list("UI_UL_list", "", netsettings, "slaves_blacklist",
+ netsettings, "active_blacklisted_slave_index", rows=2)
sub = row.column(align=True)
sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
@@ -337,7 +338,7 @@ class RENDER_PT_network_jobs(NeedValidAddress, NetRenderButtonsPanel, bpy.types.
netsettings = context.scene.network_render
row = layout.row()
- row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
+ row.template_list("UI_UL_list", "", netsettings, "jobs", netsettings, "active_job_index", rows=2)
sub = row.column(align=True)
sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
diff --git a/release/scripts/addons/object_add_chain.py b/release/scripts/addons/object_add_chain.py
index f1f8917..9c06795 100644
--- a/release/scripts/addons/object_add_chain.py
+++ b/release/scripts/addons/object_add_chain.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Add Chain",
"author": "Brian Hinton (Nichod)",
"version": (0,1),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "View3D > Add > Mesh",
"description": "Adds Chain with curve guide for easy creation",
"warning": "",
diff --git a/release/scripts/addons/object_animrenderbake.py b/release/scripts/addons/object_animrenderbake.py
index b79a0e5..e8dc0c1 100644
--- a/release/scripts/addons/object_animrenderbake.py
+++ b/release/scripts/addons/object_animrenderbake.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Animated Render Baker",
"author": "Janne Karhu (jahka)",
"version": (1, 0),
- "blender": (2, 5, 8),
+ "blender": (2, 58, 0),
"location": "Properties > Render > Bake Panel",
"description": "Renderbakes a series of frames",
"category": "Object",
diff --git a/release/scripts/addons/object_cloud_gen.py b/release/scripts/addons/object_cloud_gen.py
index c71764e..795d7b3 100644
--- a/release/scripts/addons/object_cloud_gen.py
+++ b/release/scripts/addons/object_cloud_gen.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Cloud Generator",
"author": "Nick Keeline(nrk)",
"version": (1, 0),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "View3D > Tool Shelf > Cloud Generator Panel",
"description": "Creates Volumetric Clouds",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
diff --git a/release/scripts/addons/object_fracture/__init__.py b/release/scripts/addons/object_fracture/__init__.py
index 1e5bae5..84da8b7 100644
--- a/release/scripts/addons/object_fracture/__init__.py
+++ b/release/scripts/addons/object_fracture/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Fracture Tools",
"author": "pildanovak",
"version": (2, 0),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "Search > Fracture Object & Add -> Fracture Helper Objects",
"description": "Fractured Object, Bomb, Projectile, Recorder",
"warning": "",
diff --git a/release/scripts/addons/object_fracture_cell/__init__.py b/release/scripts/addons/object_fracture_cell/__init__.py
index ee33648..4cb0497 100644
--- a/release/scripts/addons/object_fracture_cell/__init__.py
+++ b/release/scripts/addons/object_fracture_cell/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Cell Fracture",
"author": "ideasman42, phymec, Sergey Sharybin",
"version": (0, 1),
- "blender": (2, 6, 4),
+ "blender": (2, 64, 0),
"location": "Search > Fracture Object & Add -> Fracture Helper Objects",
"description": "Fractured Object, Bomb, Projectile, Recorder",
"warning": "",
diff --git a/release/scripts/addons/object_grease_scatter.py b/release/scripts/addons/object_grease_scatter.py
index f6b7258..8e9d655 100644
--- a/release/scripts/addons/object_grease_scatter.py
+++ b/release/scripts/addons/object_grease_scatter.py
@@ -24,7 +24,7 @@ bl_info = {
"name": "Grease Scatter Objects",
"author": "Campbell Barton",
"version": (0, 1),
- "blender": (2, 5, 8),
+ "blender": (2, 58, 0),
"location": "3D View, Add Mesh",
"description": "Scatter a group of objects onto the active mesh using "
"the grease pencil lines",
diff --git a/release/scripts/addons/paint_palette.py b/release/scripts/addons/paint_palette.py
index 8a3f4df..92de64b 100644
--- a/release/scripts/addons/paint_palette.py
+++ b/release/scripts/addons/paint_palette.py
@@ -23,8 +23,8 @@
bl_info = {
"name": "Paint Palettes",
"author": "Dany Lebel (Axon D)",
- "version": (0,9,1),
- "blender": (2, 63, 12),
+ "version": (0, 9, 1),
+ "blender": (2, 63, 0),
"location": "Image Editor and 3D View > Any Paint mode > Color Palette or Weight Palette panel",
"description": "Palettes for color and weight paint modes",
"warning": "",
diff --git a/release/scripts/addons/render_copy_settings/__init__.py b/release/scripts/addons/render_copy_settings/__init__.py
index a6d1fca..6d5e946 100644
--- a/release/scripts/addons/render_copy_settings/__init__.py
+++ b/release/scripts/addons/render_copy_settings/__init__.py
@@ -21,15 +21,12 @@
bl_info = {
"name": "Copy Settings",
"author": "Bastien Montagne",
- "version": (0, 1, 4),
- "blender": (2, 6, 1),
+ "version": (0, 1, 5),
+ "blender": (2, 65, 0),
"location": "Render buttons (Properties window)",
- "description": "Allows to copy a selection of render settings from "
- "current scene to others.",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Render/Copy Settings",
- "tracker_url": "http://projects.blender.org/tracker/index.php?"
- "func=detail&aid=25832",
+ "description": "Allows to copy a selection of render settings from current scene to others.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Render/Copy Settings",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25832",
"category": "Render"}
@@ -50,53 +47,38 @@ from bpy.props import (StringProperty,
PointerProperty)
-###############################################################################
-# Global properties for the script, for UI (as there’s no way to let them in
-# the operator…).
-###############################################################################
+########################################################################################################################
+# Global properties for the script, for UI (as there’s no way to let them in the operator…).
+########################################################################################################################
class RenderCopySettingsScene(bpy.types.PropertyGroup):
allowed = BoolProperty(default=True)
- # A string of identifiers (colon delimited) which property’s controls
- # should be displayed in a template_list.
- template_list_controls = StringProperty(default="allowed",
- options={'HIDDEN'})
-
class RenderCopySettingsSetting(bpy.types.PropertyGroup):
strid = StringProperty(default="")
copy = BoolProperty(default=False)
- # A string of identifiers (colon delimited) which property’s controls
- # should be displayed in a template_list.
- template_list_controls = StringProperty(default="copy",
- options={'HIDDEN'})
-
class RenderCopySettings(bpy.types.PropertyGroup):
# XXX: The consistency of this collection is delegated to the UI code.
# It should only contain one element for each render setting.
affected_settings = CollectionProperty(type=RenderCopySettingsSetting,
name="Affected Settings",
- description="The list of all "
- "available render "
- "settings")
+ description="The list of all available render settings")
# XXX Unused, but needed for template_list…
- aff_sett_idx = IntProperty()
+ affected_settings_idx = IntProperty()
# XXX: The consistency of this collection is delegated to the UI code.
# It should only contain one element for each scene.
allowed_scenes = CollectionProperty(type=RenderCopySettingsScene,
name="Allowed Scenes",
- description="The list all scenes "
- "in the file")
+ description="The list all scenes in the file")
# XXX Unused, but needed for template_list…
- allw_scenes_idx = IntProperty()
+ allowed_scenes_idx = IntProperty()
filter_scene = StringProperty(name="Filter Scene",
- description="Regex to only affect scenes "
- "which name matches it",
+ description="Regex to only affect scenes which name matches it",
default="")
@@ -105,8 +87,7 @@ def register():
bpy.utils.register_class(RenderCopySettingsScene)
bpy.utils.register_class(RenderCopySettingsSetting)
bpy.utils.register_class(RenderCopySettings)
- bpy.types.Scene.render_copy_settings = \
- PointerProperty(type=RenderCopySettings)
+ bpy.types.Scene.render_copy_settings = PointerProperty(type=RenderCopySettings)
bpy.utils.register_module(__name__)
diff --git a/release/scripts/addons/render_copy_settings/operator.py b/release/scripts/addons/render_copy_settings/operator.py
index 31d36ec..f231ac9 100644
--- a/release/scripts/addons/render_copy_settings/operator.py
+++ b/release/scripts/addons/render_copy_settings/operator.py
@@ -21,14 +21,12 @@
import bpy
from . import presets
-# These operators are only defined because it seems impossible to directly
-# edit properties from UI code…
+# These operators are only defined because it seems impossible to directly edit properties from UI code…
# A sorting func for collections (working in-place).
# XXX Not optimized at all…
-# XXX If some items in the collection do not have the sortkey property,
-# they are just ignored…
+# XXX If some items in the collection do not have the sortkey property, they are just ignored…
def collection_property_sort(collection, sortkey, start_idx=0):
while start_idx + 1 < len(collection):
while not hasattr(collection[start_idx], sortkey):
@@ -49,8 +47,7 @@ def collection_property_sort(collection, sortkey, start_idx=0):
class RenderCopySettingsPrepare(bpy.types.Operator):
- """Prepare internal data for render_copy_settings (gathering all """ \
- """existingrender settings, and scenes)"""
+ """Prepare internal data for render_copy_settings (gathering all existingrender settings, and scenes)"""
bl_idname = "scene.render_copy_settings_prepare"
bl_label = "Render: Copy Settings Prepare"
bl_option = {'REGISTER'}
@@ -62,8 +59,7 @@ class RenderCopySettingsPrepare(bpy.types.Operator):
def execute(self, context):
cp_sett = context.scene.render_copy_settings
- # Get all available render settings, and update accordingly
- # affected_settings…
+ # Get all available render settings, and update accordingly affected_settings…
props = {}
for prop in context.scene.render.bl_rna.properties:
if prop.identifier in {'rna_type'}:
@@ -92,13 +88,11 @@ class RenderCopySettingsPrepare(bpy.types.Operator):
try:
regex = re.compile(cp_sett.filter_scene)
except Exception as e:
- self.report({'ERROR_INVALID_INPUT'}, "The filter-scene "
- "regex did not compile:\n (%s)." % str(e))
+ self.report({'ERROR_INVALID_INPUT'}, "The filter-scene regex did not compile:\n (%s)." % str(e))
return {'CANCELLED'}
except:
regex = None
- self.report({'WARNING'}, "Unable to import the re module. "
- "Regex scene filtering will be disabled!")
+ self.report({'WARNING'}, "Unable to import the re module, regex scene filtering will be disabled!")
scenes = set()
for scene in bpy.data.scenes:
if scene == bpy.context.scene: # Exclude current scene!
@@ -190,12 +184,9 @@ class RenderCopySettings(bpy.types.Operator):
def execute(self, context):
regex = None
cp_sett = context.scene.render_copy_settings
- affected_settings = {sett.strid for sett in cp_sett.affected_settings
- if sett.copy}
- allowed_scenes = {sce.name for sce in cp_sett.allowed_scenes
- if sce.allowed}
- do_copy(context, affected_settings=affected_settings,
- allowed_scenes=allowed_scenes)
+ affected_settings = {sett.strid for sett in cp_sett.affected_settings if sett.copy}
+ allowed_scenes = {sce.name for sce in cp_sett.allowed_scenes if sce.allowed}
+ do_copy(context, affected_settings=affected_settings, allowed_scenes=allowed_scenes)
return {'FINISHED'}
diff --git a/release/scripts/addons/render_copy_settings/panel.py b/release/scripts/addons/render_copy_settings/panel.py
index 3c97017..d91e8b0 100644
--- a/release/scripts/addons/render_copy_settings/panel.py
+++ b/release/scripts/addons/render_copy_settings/panel.py
@@ -22,6 +22,24 @@ import bpy
from . import presets
+class RENDER_UL_copy_settings(bpy.types.UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ #assert(isinstance(item, (bpy.types.RenderCopySettingsScene, bpy.types.RenderCopySettingsSetting)))
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ if isinstance(item, bpy.types.RenderCopySettingsSetting):
+ layout.label(item.name, icon_value=icon)
+ layout.prop(item, "copy", text="")
+ else: #elif isinstance(item, bpy.types.RenderCopySettingsScene):
+ layout.prop(item, "allowed", text=item.name, toggle=True)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ if isinstance(item, bpy.types.RenderCopySettingsSetting):
+ layout.label(item.name, icon_value=icon)
+ layout.prop(item, "copy", text="")
+ else: #elif isinstance(item, bpy.types.RenderCopySettingsScene):
+ layout.prop(item, "allowed", text=item.name, toggle=True)
+
+
class RENDER_PT_copy_settings(bpy.types.Panel):
bl_label = "Copy Settings"
bl_space_type = "PROPERTIES"
@@ -34,8 +52,7 @@ class RENDER_PT_copy_settings(bpy.types.Panel):
layout = self.layout
cp_sett = context.scene.render_copy_settings
- layout.operator("scene.render_copy_settings",
- text="Copy Render Settings")
+ layout.operator("scene.render_copy_settings", text="Copy Render Settings")
# This will update affected_settings/allowed_scenes (as this seems
# to be impossible to do it from here…).
@@ -43,28 +60,24 @@ class RENDER_PT_copy_settings(bpy.types.Panel):
bpy.ops.scene.render_copy_settings_prepare()
split = layout.split(0.75)
- split.template_list(cp_sett, "affected_settings", cp_sett,
- "aff_sett_idx",
- prop_list="template_list_controls", rows=6)
+ split.template_list("RENDER_UL_copy_settings", "settings", cp_sett, "affected_settings",
+ cp_sett, "affected_settings_idx", rows=6)
col = split.column()
- all_set = {sett.strid for sett in cp_sett.affected_settings
- if sett.copy}
+ all_set = {sett.strid for sett in cp_sett.affected_settings if sett.copy}
for p in presets.presets:
label = ""
if p.elements & all_set == p.elements:
label = "Clear {}".format(p.ui_name)
else:
label = "Set {}".format(p.ui_name)
- col.operator("scene.render_copy_settings_preset",
- text=label).presets = {p.rna_enum[0]}
+ col.operator("scene.render_copy_settings_preset", text=label).presets = {p.rna_enum[0]}
layout.prop(cp_sett, "filter_scene")
if len(cp_sett.allowed_scenes):
layout.label("Affected Scenes:")
- # XXX Unfortunately, there can only be one template_list per panel…
- col = layout.column_flow(columns=0)
- for i, prop in enumerate(cp_sett.allowed_scenes):
- col.prop(prop, "allowed", toggle=True, text=prop.name)
+ layout.template_list("RENDER_UL_copy_settings", "scenes", cp_sett, "allowed_scenes",
+# cp_sett, "allowed_scenes_idx", rows=6, type='GRID')
+ cp_sett, "allowed_scenes_idx", rows=6) # XXX Grid is not nice currently...
else:
layout.label(text="No Affectable Scenes!", icon="ERROR")
diff --git a/release/scripts/addons/render_copy_settings/presets.py b/release/scripts/addons/render_copy_settings/presets.py
index d1037d3..8bc43af 100644
--- a/release/scripts/addons/render_copy_settings/presets.py
+++ b/release/scripts/addons/render_copy_settings/presets.py
@@ -27,20 +27,16 @@ class CopyPreset(object):
presets = (CopyPreset("Resolution",
- ("resolution", "Render Resolution",
- "Render resolution and aspect ratio settings"),
- {"resolution_x", "resolution_y",
- "pixel_aspect_x", "pixel_aspect_y"}),
+ ("resolution", "Render Resolution", "Render resolution and aspect ratio settings"),
+ {"resolution_x", "resolution_y", "pixel_aspect_x", "pixel_aspect_y"}),
CopyPreset("Scale",
("scale", "Render Scale", "The “Render Scale” setting"),
{"resolution_percentage"}),
CopyPreset("OSA",
- ("osa", "Render OSA",
- "The OSA toggle and sample settings"),
+ ("osa", "Render OSA", "The OSA toggle and sample settings"),
{"use_antialiasing", "antialiasing_samples"}),
CopyPreset("Threads",
- ("threads", "Render Threads",
- "The thread mode and number settings"),
+ ("threads", "Render Threads", "The thread mode and number settings"),
{"threads_mode", "threads"}),
CopyPreset("Fields",
("fields", "Render Fields", "The Fields settings"),
diff --git a/release/scripts/addons/render_povray/__init__.py b/release/scripts/addons/render_povray/__init__.py
index 1b7299e..573f24f 100644
--- a/release/scripts/addons/render_povray/__init__.py
+++ b/release/scripts/addons/render_povray/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "POV-Ray 3.7",
"author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud, Constantin Rahn, Bastien Montagne",
"version": (0, 0, 9),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "Render > Engine > POV-Ray 3.7",
"description": "Basic POV-Ray 3.7 integration for blender",
"warning": "both POV-Ray 3.7 and this script are beta",
diff --git a/release/scripts/addons/render_povray/render.py b/release/scripts/addons/render_povray/render.py
index a92aafb..ddcd354 100644
--- a/release/scripts/addons/render_povray/render.py
+++ b/release/scripts/addons/render_povray/render.py
@@ -1697,15 +1697,16 @@ def write_pov(filename, scene=None, info_callback=None):
if not world.use_sky_blend:
# Non fully transparent background could premultiply alpha and avoid anti-aliasing
# display issue:
- if render.alpha_mode == 'PREMUL':
+ if render.alpha_mode == 'TRANSPARENT':
tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n" % \
(world.horizon_color[:]))
#Currently using no alpha with Sky option:
elif render.alpha_mode == 'SKY':
tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0>}\n" % (world.horizon_color[:]))
#StraightAlpha:
- else:
- tabWrite("background {rgbt<%.3g, %.3g, %.3g, 1>}\n" % (world.horizon_color[:]))
+ # XXX Does not exists anymore
+ #else:
+ #tabWrite("background {rgbt<%.3g, %.3g, %.3g, 1>}\n" % (world.horizon_color[:]))
worldTexCount = 0
#For Background image textures
@@ -1776,10 +1777,11 @@ def write_pov(filename, scene=None, info_callback=None):
# for skysphere..5.5
tabWrite("gradient y\n")
tabWrite("color_map {\n")
- if render.alpha_mode == 'STRAIGHT':
- tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.horizon_color[:]))
- tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.zenith_color[:]))
- elif render.alpha_mode == 'PREMUL':
+ # XXX Does not exists anymore
+ #if render.alpha_mode == 'STRAIGHT':
+ #tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.horizon_color[:]))
+ #tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.zenith_color[:]))
+ if render.alpha_mode == 'TRANSPARENT':
tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.horizon_color[:]))
# aa premult not solved with transmit 1
tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.zenith_color[:]))
diff --git a/release/scripts/addons/render_renderfarmfi/__init__.py b/release/scripts/addons/render_renderfarmfi/__init__.py
index 5dfdb4e..eec9ff6 100644
--- a/release/scripts/addons/render_renderfarmfi/__init__.py
+++ b/release/scripts/addons/render_renderfarmfi/__init__.py
@@ -20,7 +20,7 @@ bl_info = {
"name": "Renderfarm.fi",
"author": "Nathan Letwory <nathan at letworyinteractive.com>, Jesse Kaukonen <jesse.kaukonen at gmail.com>",
"version": (22,),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "Render > Engine > Renderfarm.fi",
"description": "Send .blend as session to http://www.renderfarm.fi to render",
"warning": "",
diff --git a/release/scripts/addons/render_renderfarmfi/panels.py b/release/scripts/addons/render_renderfarmfi/panels.py
index 9291810..b202a58 100644
--- a/release/scripts/addons/render_renderfarmfi/panels.py
+++ b/release/scripts/addons/render_renderfarmfi/panels.py
@@ -101,7 +101,7 @@ class SESSIONS_PT_RenderfarmFi(RenderButtonsPanel, bpy.types.Panel):
if (bpy.passwordCorrect == True and bpy.loginInserted == True):
layout = self.layout
- layout.template_list(ore, 'all_sessions', ore, 'selected_session', rows=5)
+ layout.template_list("UI_UL_list", "", ore, 'all_sessions', ore, 'selected_session', rows=5)
layout.operator('ore.cancel_session')
if (bpy.cancelError == True):
layout.label("This session cannot be cancelled")
diff --git a/release/scripts/addons/rigify/__init__.py b/release/scripts/addons/rigify/__init__.py
index bcee813..ca99e31 100644
--- a/release/scripts/addons/rigify/__init__.py
+++ b/release/scripts/addons/rigify/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Rigify",
"author": "Nathan Vegdahl",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Add > Armature",
"description": "Adds various Rig Templates",
"location": "Armature properties",
diff --git a/release/scripts/addons/rigify/ui.py b/release/scripts/addons/rigify/ui.py
index 6b356a7..156ab0b 100644
--- a/release/scripts/addons/rigify/ui.py
+++ b/release/scripts/addons/rigify/ui.py
@@ -77,7 +77,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel):
# Rig type list
row = layout.row()
- row.template_list(id_store, "rigify_types", id_store, 'rigify_active_type')
+ row.template_list("UI_UL_list", "", id_store, "rigify_types", id_store, 'rigify_active_type')
op = layout.operator("armature.metarig_sample_add", text="Add sample")
op.metarig_type = id_store.rigify_types[id_store.rigify_active_type].name
diff --git a/release/scripts/addons/space_view3d_3d_navigation.py b/release/scripts/addons/space_view3d_3d_navigation.py
index 3e79835..f12914a 100644
--- a/release/scripts/addons/space_view3d_3d_navigation.py
+++ b/release/scripts/addons/space_view3d_3d_navigation.py
@@ -25,7 +25,7 @@ bl_info = {
"name": "3D Navigation",
"author": "Demohero, uriel",
"version": (1, 2),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Tool Shelf > 3D Nav",
"description": "Navigate the Camera & 3D View from the Toolshelf",
"warning": "",
diff --git a/release/scripts/addons/space_view3d_copy_attributes.py b/release/scripts/addons/space_view3d_copy_attributes.py
index ecc12b9..49bc1b2 100644
--- a/release/scripts/addons/space_view3d_copy_attributes.py
+++ b/release/scripts/addons/space_view3d_copy_attributes.py
@@ -19,17 +19,17 @@
# <pep8 compliant>
bl_info = {
- 'name': 'Copy Attributes Menu',
- 'author': 'Bassam Kurdali, Fabian Fricke, Adam Wiseman',
- 'version': (0, 4, 7),
- 'blender': (2, 6, 3),
- 'location': 'View3D > Ctrl-C',
- 'description': 'Copy Attributes Menu from Blender 2.4',
- 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/'
- 'Scripts/3D_interaction/Copy_Attributes_Menu',
- 'tracker_url': 'https://projects.blender.org/tracker/index.php?'
- 'func=detail&aid=22588',
- 'category': '3D View'}
+ "name": "Copy Attributes Menu",
+ "author": "Bassam Kurdali, Fabian Fricke, Adam Wiseman",
+ "version": (0, 4, 7),
+ "blender": (2, 63, 0),
+ "location": "View3D > Ctrl-C",
+ "description": "Copy Attributes Menu from Blender 2.4",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/3D_interaction/Copy_Attributes_Menu",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=22588",
+ "category": "3D View"}
import bpy
from mathutils import Matrix
diff --git a/release/scripts/addons/space_view3d_materials_utils.py b/release/scripts/addons/space_view3d_materials_utils.py
index 609d834..72a5da9 100644
--- a/release/scripts/addons/space_view3d_materials_utils.py
+++ b/release/scripts/addons/space_view3d_materials_utils.py
@@ -26,7 +26,7 @@ bl_info = {
"name": "Material Utils",
"author": "michaelw",
"version": (1, 4),
- "blender": (2, 6, 2),
+ "blender": (2, 62, 0),
"location": "View3D > Q key",
"description": "Menu of material tools (assign, select..) in the 3D View",
"warning": "Buggy, Broken in Cycles mode",
@@ -34,7 +34,7 @@ bl_info = {
"Scripts/3D interaction/Materials Utils",
"tracker_url": "https://projects.blender.org/tracker/index.php?"
"func=detail&aid=22140",
- "category": "3D View"}
+ "category": "Material"}
"""
This script has several functions and operators... grouped for convenience
diff --git a/release/scripts/addons/space_view3d_math_vis/__init__.py b/release/scripts/addons/space_view3d_math_vis/__init__.py
index 739c047..5682895 100644
--- a/release/scripts/addons/space_view3d_math_vis/__init__.py
+++ b/release/scripts/addons/space_view3d_math_vis/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Math Vis (Console)",
"author": "Campbell Barton",
"version": (0, 1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "View3D > Tool Shelf or Console",
"description": "Display console defined mathutils variables in the 3D view",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
@@ -42,62 +42,18 @@ else:
import bpy
-class VIEW3D_PT_math_vis(bpy.types.Panel):
- bl_space_type = "VIEW_3D"
- bl_region_type = "TOOLS"
- bl_label = "Math View"
-
- def draw(self, context):
- callbacks = draw.callbacks
- ok = False
- for region in context.area.regions:
- if callbacks.get(hash(region)):
- ok = True
- break
-
- self.layout.operator("view3d.math_vis_toggle", emboss=False, icon='CHECKBOX_HLT' if ok else 'CHECKBOX_DEHLT')
-
-
-class SetupMathView(bpy.types.Operator):
- """Visualize mathutils type python variables from the """ \
- """interactive console, see addon docs"""
- bl_idname = "view3d.math_vis_toggle"
- bl_label = "Use Math Vis"
-
- def execute(self, context):
- callbacks = draw.callbacks
- region = context.region
- region_id = hash(region)
- cb_data = callbacks.get(region_id)
- if cb_data is None:
- handle_pixel = region.callback_add(draw.draw_callback_px, (self, context), 'POST_PIXEL')
- handle_view = region.callback_add(draw.draw_callback_view, (self, context), 'POST_VIEW')
- callbacks[region_id] = region, handle_pixel, handle_view
- else:
- region.callback_remove(cb_data[1])
- region.callback_remove(cb_data[2])
- del callbacks[region_id]
-
- context.area.tag_redraw()
- return {'FINISHED'}
-
-
def console_hook():
- for region, handle_pixel, handle_view in draw.callbacks.values():
- region.tag_redraw()
-
+ draw.tag_redraw_all_view3d()
def register():
- bpy.utils.register_module(__name__)
+ draw.callback_enable()
import console_python
console_python.execute.hooks.append((console_hook, ()))
def unregister():
- bpy.utils.unregister_module(__name__)
+ draw.callback_disable()
import console_python
console_python.execute.hooks.remove((console_hook, ()))
-
- draw.callbacks_clear()
diff --git a/release/scripts/addons/space_view3d_math_vis/draw.py b/release/scripts/addons/space_view3d_math_vis/draw.py
index 509881e..40c44f3 100644
--- a/release/scripts/addons/space_view3d_math_vis/draw.py
+++ b/release/scripts/addons/space_view3d_math_vis/draw.py
@@ -1,4 +1,4 @@
-#====================== BEGIN GPL LICENSE BLOCK ======================
+# ##### 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
@@ -14,25 +14,57 @@
# 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 LICENSE BLOCK ========================
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
import bpy
import blf
from . import utils
from mathutils import Vector, Matrix
+SpaceView3D = bpy.types.SpaceView3D
+callback_handle = []
+
-callbacks = {}
+def tag_redraw_all_view3d():
+ context = bpy.context
+ # Py cant access notifers
+ for window in context.window_manager.windows:
+ for area in window.screen.areas:
+ if area.type == 'VIEW_3D':
+ for region in area.regions:
+ if region.type == 'WINDOW':
+ region.tag_redraw()
-def callbacks_clear():
- for region, handle_pixel, handle_view in callbacks.values():
- region.callback_remove(handle_pixel)
- region.callback_remove(handle_view)
- callbacks.clear()
+def callback_enable():
+ if callback_handle:
+ return
+
+ handle_pixel = SpaceView3D.draw_handler_add(draw_callback_px, (), 'WINDOW', 'POST_PIXEL')
+ handle_view = SpaceView3D.draw_handler_add(draw_callback_view, (), 'WINDOW', 'POST_VIEW')
+ callback_handle[:] = handle_pixel, handle_view
+
+ tag_redraw_all_view3d()
+
+
+def callback_disable():
+ if not callback_handle:
+ return
+
+ handle_pixel, handle_view = callback_handle
+ SpaceView3D.draw_handler_remove(handle_pixel, 'WINDOW')
+ SpaceView3D.draw_handler_remove(handle_view, 'WINDOW')
+ callback_handle[:] = []
+
+ tag_redraw_all_view3d()
+
+
+def draw_callback_px():
+ context = bpy.context
-def draw_callback_px(self, context):
from bgl import glColor3f
font_id = 0 # XXX, need to find out how best to get this.
blf.size(font_id, 12, 72)
@@ -41,10 +73,12 @@ def draw_callback_px(self, context):
if not data_matrix and not data_quat and not data_euler and not data_vector and not data_vector_array:
+ '''
# draw some text
glColor3f(1.0, 0.0, 0.0)
blf.position(font_id, 180, 10, 0)
blf.draw(font_id, "Python Console has no mathutils definitions")
+ '''
return
glColor3f(1.0, 1.0, 1.0)
@@ -93,7 +127,9 @@ def draw_callback_px(self, context):
draw_text(key, loc)
-def draw_callback_view(self, context):
+def draw_callback_view():
+ context = bpy.context
+
from bgl import glEnable, glDisable, glColor3f, glVertex3f, glPointSize, glLineWidth, glBegin, glEnd, glLineStipple, GL_POINTS, GL_LINE_STRIP, GL_LINES, GL_LINE_STIPPLE
data_matrix, data_quat, data_euler, data_vector, data_vector_array = utils.console_math_data()
diff --git a/release/scripts/addons/space_view3d_math_vis/utils.py b/release/scripts/addons/space_view3d_math_vis/utils.py
index a89a9ff..318beff 100644
--- a/release/scripts/addons/space_view3d_math_vis/utils.py
+++ b/release/scripts/addons/space_view3d_math_vis/utils.py
@@ -1,4 +1,4 @@
-#====================== BEGIN GPL LICENSE BLOCK ======================
+# ##### 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
@@ -14,7 +14,9 @@
# 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 LICENSE BLOCK ========================
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
def console_namespace():
import console_python
@@ -25,6 +27,7 @@ def console_namespace():
return console.locals
return {}
+
def console_math_data():
from mathutils import Matrix, Vector, Quaternion, Euler
@@ -66,4 +69,3 @@ def console_math_data():
data_vector_array[key] = var
return data_matrix, data_quat, data_euler, data_vector, data_vector_array
-
diff --git a/release/scripts/addons/space_view3d_panel_measure.py b/release/scripts/addons/space_view3d_panel_measure.py
index 2d86130..6897871 100644
--- a/release/scripts/addons/space_view3d_panel_measure.py
+++ b/release/scripts/addons/space_view3d_panel_measure.py
@@ -27,8 +27,8 @@ bl_info = {
"author": "Buerbaum Martin (Pontiac), TNae (Normal patch)," \
" Benjamin Lauritzen (Loonsbury; Volume code)," \
" Alessandro Sala (patch: Units in 3D View)",
- "version": (0, 8, 9),
- "blender": (2, 6, 0),
+ "version": (0, 9, 0),
+ "blender": (2, 60, 0),
"location": "View3D > Properties > Measure Panel",
"description": "Measure distances between objects",
"warning": "Script needs repairs",
@@ -82,7 +82,7 @@ from bpy_extras.mesh_utils import ngon_tessellate
# Precicion for display of float values.
-PRECISION = 4
+PRECISION = 5
# Name of the custom properties as stored in the scene.
COLOR_LOCAL = (1.0, 0.5, 0.0, 0.8)
@@ -102,6 +102,7 @@ LINE_WIDTH_DIST = 2
# and formatting options.
# Returned data is meant to be passed to formatDistance().
# Original by Alessandro Sala (Feb, 12th 2012)
+# Update by Alessandro Sala (Dec, 18th 2012)
def getUnitsInfo():
scale = bpy.context.scene.unit_settings.scale_length
unit_system = bpy.context.scene.unit_settings.system
@@ -110,9 +111,9 @@ def getUnitsInfo():
scale_steps = ((1000, 'km'), (1, 'm'), (1 / 100, 'cm'),
(1 / 1000, 'mm'), (1 / 1000000, '\u00b5m'))
elif unit_system == 'IMPERIAL':
- scale_steps = ((1760, 'mi'), (1, 'yd'), (1 / 3, '\''),
- (1 / 36, '"'), (1 / 36000, 'thou'))
- scale *= 1.0936133
+ scale_steps = ((5280, 'mi'), (1, '\''),
+ (1 / 12, '"'), (1 / 12000, 'thou'))
+ scale /= 0.3048 # BU to feet
else:
scale_steps = ((1, ' BU'),)
separate_units = False
@@ -123,13 +124,13 @@ def getUnitsInfo():
# Converts a distance from BU into the measuring system
# described by units_info.
# Original by Alessandro Sala (Feb, 12th 2012)
+# Update by Alessandro Sala (Dec, 18th 2012)
def convertDistance(val, units_info):
scale, scale_steps, separate_units = units_info
sval = val * scale
- rsval = round(sval, PRECISION)
idx = 0
while idx < len(scale_steps) - 1:
- if rsval >= scale_steps[idx][0]:
+ if sval >= scale_steps[idx][0]:
break
idx += 1
factor, suffix = scale_steps[idx]
@@ -138,14 +139,14 @@ def convertDistance(val, units_info):
dval = str(round(sval, PRECISION)) + suffix
else:
ival = int(sval)
- dval = str(ival) + suffix
+ dval = str(round(ival, PRECISION)) + suffix
fval = sval - ival
idx += 1
while idx < len(scale_steps):
fval *= scale_steps[idx - 1][0] / scale_steps[idx][0]
if fval >= 1:
dval += ' ' \
- + str(round(fval, 1)) \
+ + ("%.1f" % fval) \
+ scale_steps[idx][1]
break
idx += 1
@@ -912,7 +913,6 @@ class VIEW3D_OT_display_measurements(bpy.types.Operator):
def modal(self, context, event):
context.area.tag_redraw()
-
return {'FINISHED'}
def execute(self, context):
@@ -920,17 +920,18 @@ class VIEW3D_OT_display_measurements(bpy.types.Operator):
mgr_ops = context.window_manager.operators.values()
if not self.bl_idname in [op.bl_idname for op in mgr_ops]:
# Add the region OpenGL drawing callback
- for WINregion in context.area.regions:
- if WINregion.type == 'WINDOW':
- self._handle = WINregion.callback_add(
- draw_measurements_callback,
- (self, context),
- 'POST_PIXEL')
- print("Measure panel display callback added")
+ # XXX, this is never removed!, it should be! (at least when disabling the addon)
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(
+ draw_measurements_callback,
+ (self, context),
+ 'WINDOW', 'POST_PIXEL')
+
+ print("Measure panel display callback added")
- context.window_manager.modal_handler_add(self)
- return {'RUNNING_MODAL'}
+ # XXX, never removed!
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
return {'CANCELLED'}
diff --git a/release/scripts/addons/space_view3d_screencast_keys.py b/release/scripts/addons/space_view3d_screencast_keys.py
index 09989e7..9296e35 100644
--- a/release/scripts/addons/space_view3d_screencast_keys.py
+++ b/release/scripts/addons/space_view3d_screencast_keys.py
@@ -19,19 +19,19 @@
# <pep8 compliant>
bl_info = {
- 'name': "Screencast Keys",
- 'author': 'Paulo Gomes, Bart Crouch, John E. Herrenyo, Gaia Clary, Pablo Vazquez',
- 'version': (1, 7),
- 'blender': (2, 6, 4),
- 'location': '3D View > Properties Panel > Screencast Keys',
- 'warning': '',
- 'description': 'Display keys pressed in the 3D View, '\
- 'useful for screencasts.',
- 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/'
- 'Py/Scripts/3D_interaction/Screencast_Key_Status_Tool',
- 'tracker_url': 'http://projects.blender.org/tracker/index.php?'
- 'func=detail&aid=21612',
- 'category': '3D View'}
+ "name": "Screencast Keys",
+ "author": "Paulo Gomes, Bart Crouch, John E. Herrenyo, Gaia Clary, Pablo Vazquez",
+ "version": (1, 7),
+ "blender": (2, 64, 0),
+ "location": "3D View > Properties Panel > Screencast Keys",
+ "warning": "",
+ "description": "Display keys pressed in the 3D View, "
+ "useful for screencasts.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/"
+ "Py/Scripts/3D_interaction/Screencast_Key_Status_Tool",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=21612",
+ "category": "3D View"}
import bgl
import blf
@@ -581,7 +581,7 @@ class ScreencastKeysStatus(bpy.types.Operator):
if not context.window_manager.screencast_keys_keys:
# stop script
context.window_manager.event_timer_remove(self._timer)
- context.region.callback_remove(self._handle)
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'CANCELLED'}
return {'PASS_THROUGH'}
@@ -589,7 +589,7 @@ class ScreencastKeysStatus(bpy.types.Operator):
def cancel(self, context):
if context.window_manager.screencast_keys_keys:
context.window_manager.event_timer_remove(self._timer)
- context.region.callback_remove(self._handle)
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
context.window_manager.screencast_keys_keys = False
return {'CANCELLED'}
@@ -603,8 +603,8 @@ class ScreencastKeysStatus(bpy.types.Operator):
self.mouse = []
self.mouse_time = []
ScreencastKeysStatus.overall_time = []
- self._handle = context.region.callback_add(draw_callback_px,
- (self, context), 'POST_PIXEL')
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px,
+ (self, context), 'WINDOW', 'POST_PIXEL')
self._timer = context.window_manager.event_timer_add(0.075,
context.window)
ScreencastKeysStatus.overall_time.insert(0, time.time())
diff --git a/release/scripts/addons/space_view3d_spacebar_menu.py b/release/scripts/addons/space_view3d_spacebar_menu.py
index 17775a0..5732555 100644
--- a/release/scripts/addons/space_view3d_spacebar_menu.py
+++ b/release/scripts/addons/space_view3d_spacebar_menu.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Dynamic Spacebar Menu",
"author": "JayDez, sim88, meta-androcto, sam",
"version": (1, 7, 3),
- "blender": (2, 6, 0),
+ "blender": (2, 60, 0),
"location": "View3D > Spacebar Key",
"description": "Context Sensitive Spacebar Menu",
"warning": "",
diff --git a/release/scripts/addons/system_blend_info.py b/release/scripts/addons/system_blend_info.py
index b4ad18f..8e7ecc3 100644
--- a/release/scripts/addons/system_blend_info.py
+++ b/release/scripts/addons/system_blend_info.py
@@ -24,7 +24,7 @@ bl_info = {
"name": "Scene Information",
"author": "uselessdreamer",
"version": (0,3),
- "blender": (2, 5, 9),
+ "blender": (2, 59, 0),
"location": "Properties > Scene > Blend Info Panel",
"description": "Show information about the .blend",
"warning": "",
diff --git a/release/scripts/addons/system_demo_mode/__init__.py b/release/scripts/addons/system_demo_mode/__init__.py
index 39f7211..e4ae9e7 100644
--- a/release/scripts/addons/system_demo_mode/__init__.py
+++ b/release/scripts/addons/system_demo_mode/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Demo Mode",
"author": "Campbell Barton",
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "Demo Menu",
"description": "Demo mode lets you select multiple blend files and loop over them.",
"warning": "",
diff --git a/release/scripts/addons/system_property_chart.py b/release/scripts/addons/system_property_chart.py
index 5ed96aa..082a830 100644
--- a/release/scripts/addons/system_property_chart.py
+++ b/release/scripts/addons/system_property_chart.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Object Property Chart",
"author": "Campbell Barton (ideasman42)",
"version": (0, 1),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "Tool Shelf",
"description": "Edit arbitrary selected properties for objects of the same type",
"warning": "",
diff --git a/release/scripts/addons/texture_paint_layer_manager.py b/release/scripts/addons/texture_paint_layer_manager.py
index b572a44..192f9e6 100644
--- a/release/scripts/addons/texture_paint_layer_manager.py
+++ b/release/scripts/addons/texture_paint_layer_manager.py
@@ -2,7 +2,7 @@ bl_info = {
"name": "Texture Paint Layer Manager",
"author": "Michael Wiliamson",
"version": (1, 0),
- "blender": (2, 5, 7),
+ "blender": (2, 57, 0),
"location": "Texture Paint > Properties > Texture Paint Layers Panels",
"description": "Adds a layer manager for image based texture slots in paint and quick add layer tools",
"warning": "",
@@ -154,12 +154,10 @@ class OBJECT_PT_Texture_paint_layers(bpy.types.Panel):
row = layout.row()
row.label(' Add a Material first!', icon = 'ERROR')
else:
- row = layout.row()
- row.template_list(ob, "material_slots", ob,
- "active_material_index", rows=2 )
-
-
-
+ row = layout.row()
+ row.template_list("UI_UL_list", "", ob, "material_slots", ob,
+ "active_material_index", rows=2 )
+
#list Paintable textures
#TODO add filter for channel type
i = -1
@@ -570,7 +568,6 @@ def save_painted(ts):
else:
i.filepath = fp
i.name = name
- i.use_premultiply = True
except:
print("something wrong with", fp)
#THAT'S THE GENERATED FILES saved, pathed and reloaded
diff --git a/release/scripts/addons/ui_translate/__init__.py b/release/scripts/addons/ui_translate/__init__.py
index 26e800c..f74b177 100644
--- a/release/scripts/addons/ui_translate/__init__.py
+++ b/release/scripts/addons/ui_translate/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Translate UI Messages",
"author": "Bastien Montagne",
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "Any UI control",
"description": "Allow to translate UI directly from Blender",
"warning": "",
diff --git a/release/scripts/addons/uv_bake_texture_to_vcols.py b/release/scripts/addons/uv_bake_texture_to_vcols.py
index 802a303..8a9a5ae 100644
--- a/release/scripts/addons/uv_bake_texture_to_vcols.py
+++ b/release/scripts/addons/uv_bake_texture_to_vcols.py
@@ -34,7 +34,7 @@ bl_info = {
"description": "Bakes the colors of the active UV Texture to a Vertex Color layer. ",
"author": "Patrick Boelens, CoDEmanX",
"version": (0, 6),
- "blender": (2, 6, 3),
+ "blender": (2, 63, 0),
"location": "3D View > Vertex Paint > Toolshelf > Bake",
"warning": "Requires image texture, generated textures aren't supported.",
"wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/"
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/Blocks.py b/release/scripts/addons_contrib/add_mesh_building_objects/Blocks.py
new file mode 100644
index 0000000..36ef5c0
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/Blocks.py
@@ -0,0 +1,1683 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you may 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
+#
+# or go online at: http://www.gnu.org/licenses/ to view license options.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+
+##
+#
+# Module notes:
+#
+# Grout needs to be implemented.
+# consider removing wedge crit for small "c" and "cl" values
+# wrap around for openings on radial stonework?
+# auto-clip wall edge to SMALL for radial and domes.
+# unregister doesn't release all references.
+# repeat for opening doesn't distribute evenly when radialized - see wrap around
+# note above.
+# if opening width == indent*2 the edge blocks fail (row of blocks cross opening).
+# if openings overlap fills inverse with blocks - see h/v slots.
+# Negative grout width creates a pair of phantom blocks, seperated by grout
+# width, inside the edges.
+# if block width variance is 0, and edging is on, right edge blocks create a "vertical seam".
+#
+##
+
+# <pep8-80 compliant>
+
+import bpy, time, math
+from random import random
+from math import fmod, sqrt, sin, cos, atan
+
+#A few constants
+SMALL = 0.000000000001
+NOTZERO = 0.01 # for values that must be != 0; see UI options/variables -
+# sort of a bug to be fixed.
+PI = math.pi
+
+#global variables
+
+#General masonry Settings
+settings = {'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1,
+ 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0,
+ 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln':0,
+ 'wm': 0.8, 'hm': 0.3, 'dm':0.1,
+ 'woff':0.0, 'woffv':0.0, 'eoff':0.3, 'eoffv':0.0, 'rwhl':1,
+ 'hb':0, 'ht':0, 'ge':0, 'physics':0}
+# 'w':width 'wv':widthVariation
+# 'h':height 'hv':heightVariation
+# 'd':depth 'dv':depthVariation
+# 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation
+# 'b':bevel 'bv':bevelVariation
+# 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction
+# 't':taper
+# 'sdv':subdivision(distance or angle)
+# 'hwt':row height effect on block widths in the row (0=no effect,
+# 1=1:1 relationship, negative values allowed, 0.5 works well)
+# 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows)
+# (currently un-used)
+# 'wm':width minimum 'hm':height minimum 'dm':depth minimum
+# 'woff':row start offset(fraction of width)
+# 'woffv':width offset variation(fraction of width)
+# 'eoff':edge offset 'eoffv':edge offset variation
+# 'rwhl':row height lock(1 is all blocks in row have same height)
+# 'hb':bottom row height 'ht': top row height 'ge': grout the edges
+# 'physics': set up for physics
+
+# dims = area of wall (face)
+dims = {'s':0, 'e':PI*3/2, 'b':0.1, 't':12.3} # radial
+# 's':start x or theta 'e':end x or theta 'b':bottom z or r 't':top z or r
+# 'w' = e-s and h = t-b; calculated to optimize for various operations/usages
+#dims = {'s':-12, 'e':15, 'w':27, 'b':-15., 't':15., 'h':30}
+#dims = {'s':-bayDim/2, 'e':bayDim/2, 'b':-5., 't':10.} # bay settings?
+
+radialized = 0 # Radiating from one point - round/disc; instead of square
+slope = 0 # Warp/slope; curved over like a vaulted tunnel
+# 'bigblock': merge adjacent blocks into single large blocks
+bigBlock = 0 # Merge blocks
+
+# Gaps in blocks for various apertures.
+#openingSpecs = []
+openingSpecs = [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0,
+ 'v':0, 'vl':0, 't':0, 'tl':0}]
+# 'w': opening width, 'h': opening height,
+# 'x': horizontal position, 'z': vertical position,
+# 'rp': make multiple openings, with a spacing of x,
+# 'b': bevel the opening, inside only, like an arrow slit.
+# 'v': height of the top arch, 'vl':height of the bottom arch,
+# 't': thickness of the top arch, 'tl': thickness of the bottom arch
+
+# Add blocks to make platforms.
+shelfExt = 0
+#shelfSpecs = []
+shelfSpecs = {'w':0.5, 'h':0.5, 'd': 0.3, 'x':0.8, 'z':2.7}
+# 'w': block width, 'h': block height, 'd': block depth (shelf size; offset from wall)
+# 'x': horizontal start position, 'z': vertical start position
+
+# Add blocks to make steps.
+stepMod = 0
+stepSpecs = {'x':0.0, 'z':-10, 'w':10.0, 'h':10.0,
+ 'v':0.7, 't':1.0, 'd':1.0 }
+# 'x': horizontal start position, 'z': vertical start position,
+# 'w': step area width, 'h': step area height,
+# 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall)
+
+
+ #easier way to get to the random function
+def rnd(): return random()
+
+ #random number from -0.5 to 0.5
+def rndc(): return (random() - 0.5)
+
+ #random number from -1.0 to 1.0
+def rndd(): return (random() - 0.5)*2.0
+
+
+#Opening Test suite
+#opening test function
+
+def test(TestN = 13):
+ dims = {'s':-29., 'e':29., 'b':-6., 't':TestN*7.5}
+ openingSpecs = []
+ for i in range(TestN):
+ x = (random() - 0.5) * 6
+ z = i*7.5
+ v = .2 + i*(3./TestN)
+ vl = 3.2 - i*(3./TestN)
+ t = 0.3 + random()
+ tl = 0.3 + random()
+ rn = random()*2
+ openingSpecs += [{'w':3.1 + rn, 'h':0.3 + rn, 'x':float(x),
+ 'z':float(z), 'rp':0, 'b':0.,
+ 'v':float(v), 'vl':float(vl),
+ 't':float(t), 'tl':float(tl)}]
+ return dims, openingSpecs
+
+#dims, openingSpecs = test(15)
+
+
+#For filling a linear space with divisions
+def fill(left, right, avedst, mindst=0.0, dev=0.0, pad=(0.0,0.0), num=0,
+ center=0):
+ __doc__ = """\
+ Fills a linear range with points and returns an ordered list of those points
+ including the end points.
+
+ left: the lower boundary
+ right: the upper boundary
+ avedst: the average distance between points
+ mindst: the minimum distance between points
+ dev: the maximum random deviation from avedst
+ pad: tends to move the points near the bounds right (positive) or
+ left (negative).
+ element 0 pads the lower bounds, element 1 pads the upper bounds
+ num: substitutes a numerical limit for the right limit. fill will then make
+ a num+1 element list
+ center: flag to center the elements in the range, 0 == disabled
+ """
+
+ poslist = [left]
+ curpos = left+pad[0]
+
+ # Set offset by average spacing, then add blocks (fall through);
+ # if not at right edge.
+ if center:
+ curpos += ((right-left-mindst*2)%avedst)/2+mindst
+ if curpos-poslist[-1]<mindst: curpos = poslist[-1]+mindst+rnd()*dev/2
+
+ # clip to right edge.
+ if (right-curpos<mindst) or (right-curpos< mindst-pad[1]):
+ poslist.append(right)
+ return poslist
+
+ else: poslist.append(curpos)
+
+ #unused... for now.
+ if num:
+ idx = len(poslist)
+
+ while idx<num+1:
+ curpos += avedst+rndd()*dev
+ if curpos-poslist[-1]<mindst:
+ curpos = poslist[-1]+mindst+rnd()*dev/2
+ poslist.append(curpos)
+ idx += 1
+
+ return poslist
+
+ # make block edges
+ else:
+ while True: # loop for blocks
+ curpos += avedst+rndd()*dev
+ if curpos-poslist[-1]<mindst:
+ curpos = poslist[-1]+mindst+rnd()*dev/2
+ # close off edges at limit
+ if (right-curpos<mindst) or (right-curpos< mindst-pad[1]):
+ poslist.append(right)
+ return poslist
+
+ else: poslist.append(curpos)
+
+
+#For generating block geometry
+def MakeABlock(bounds, segsize, vll=0, Offsets=None, FaceExclude=[],
+ bevel=0, xBevScl=1):
+ __doc__ = """\
+ MakeABlock returns lists of points and faces to be made into a square
+ cornered block, subdivided along the length, with optional bevels.
+ bounds: a list of boundary positions:
+ 0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front
+ segsize: the maximum size before lengthwise subdivision occurs
+ vll: the number of vertexes already in the mesh. len(mesh.verts) should
+ give this number.
+ Offsets: list of coordinate delta values.
+ Offsets are lists, [x,y,z] in
+ [
+ 0:left_bottom_back,
+ 1:left_bottom_front,
+ 2:left_top_back,
+ 3:left_top_front,
+ 4:right_bottom_back,
+ 5:right_bottom_front,
+ 6:right_top_back,
+ 7:right_top_front,
+ ]
+ FaceExclude: list of faces to exclude from the faces list. see bounds above for indices
+ xBevScl: how much to divide the end (+- x axis) bevel dimensions. Set to current average radius to compensate for angular distortion on curved blocks
+ """
+
+ slices = fill(bounds[0], bounds[1], segsize, segsize, center=1)
+ points = []
+ faces = []
+
+ if Offsets == None:
+ points.append([slices[0],bounds[4],bounds[2]])
+ points.append([slices[0],bounds[5],bounds[2]])
+ points.append([slices[0],bounds[5],bounds[3]])
+ points.append([slices[0],bounds[4],bounds[3]])
+
+ for x in slices[1:-1]:
+ points.append([x,bounds[4],bounds[2]])
+ points.append([x,bounds[5],bounds[2]])
+ points.append([x,bounds[5],bounds[3]])
+ points.append([x,bounds[4],bounds[3]])
+
+ points.append([slices[-1],bounds[4],bounds[2]])
+ points.append([slices[-1],bounds[5],bounds[2]])
+ points.append([slices[-1],bounds[5],bounds[3]])
+ points.append([slices[-1],bounds[4],bounds[3]])
+
+ else:
+ points.append([slices[0]+Offsets[0][0],bounds[4]+Offsets[0][1],bounds[2]+Offsets[0][2]])
+ points.append([slices[0]+Offsets[1][0],bounds[5]+Offsets[1][1],bounds[2]+Offsets[1][2]])
+ points.append([slices[0]+Offsets[3][0],bounds[5]+Offsets[3][1],bounds[3]+Offsets[3][2]])
+ points.append([slices[0]+Offsets[2][0],bounds[4]+Offsets[2][1],bounds[3]+Offsets[2][2]])
+
+ for x in slices[1:-1]:
+ xwt = (x-bounds[0])/(bounds[1]-bounds[0])
+ points.append([x+Offsets[0][0]*(1-xwt)+Offsets[4][0]*xwt,bounds[4]+Offsets[0][1]*(1-xwt)+Offsets[4][1]*xwt,bounds[2]+Offsets[0][2]*(1-xwt)+Offsets[4][2]*xwt])
+ points.append([x+Offsets[1][0]*(1-xwt)+Offsets[5][0]*xwt,bounds[5]+Offsets[1][1]*(1-xwt)+Offsets[5][1]*xwt,bounds[2]+Offsets[1][2]*(1-xwt)+Offsets[5][2]*xwt])
+ points.append([x+Offsets[3][0]*(1-xwt)+Offsets[7][0]*xwt,bounds[5]+Offsets[3][1]*(1-xwt)+Offsets[7][1]*xwt,bounds[3]+Offsets[3][2]*(1-xwt)+Offsets[7][2]*xwt])
+ points.append([x+Offsets[2][0]*(1-xwt)+Offsets[6][0]*xwt,bounds[4]+Offsets[2][1]*(1-xwt)+Offsets[6][1]*xwt,bounds[3]+Offsets[2][2]*(1-xwt)+Offsets[6][2]*xwt])
+
+ points.append([slices[-1]+Offsets[4][0],bounds[4]+Offsets[4][1],bounds[2]+Offsets[4][2]])
+ points.append([slices[-1]+Offsets[5][0],bounds[5]+Offsets[5][1],bounds[2]+Offsets[5][2]])
+ points.append([slices[-1]+Offsets[7][0],bounds[5]+Offsets[7][1],bounds[3]+Offsets[7][2]])
+ points.append([slices[-1]+Offsets[6][0],bounds[4]+Offsets[6][1],bounds[3]+Offsets[6][2]])
+
+ faces.append([vll,vll+3,vll+2,vll+1])
+
+ for x in range(len(slices)-1):
+ faces.append([vll,vll+1,vll+5,vll+4])
+ vll+=1
+ faces.append([vll,vll+1,vll+5,vll+4])
+ vll+=1
+ faces.append([vll,vll+1,vll+5,vll+4])
+ vll+=1
+ faces.append([vll,vll-3,vll+1,vll+4])
+ vll+=1
+
+ faces.append([vll,vll+1,vll+2,vll+3])
+
+ return points, faces
+#
+#
+#
+
+#For generating Keystone Geometry
+def MakeAKeystone(xpos, width, zpos, ztop, zbtm, thick, bevel, vll=0, FaceExclude=[], xBevScl=1):
+ __doc__ = """\
+ MakeAKeystone returns lists of points and faces to be made into a square cornered keystone, with optional bevels.
+ xpos: x position of the centerline
+ width: x width of the keystone at the widest point (discounting bevels)
+ zpos: z position of the widest point
+ ztop: distance from zpos to the top
+ zbtm: distance from zpos to the bottom
+ thick: thickness
+ bevel: the amount to raise the back vertex to account for arch beveling
+ vll: the number of vertexes already in the mesh. len(mesh.verts) should give this number
+ faceExclude: list of faces to exclude from the faces list. 0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front
+ xBevScl: how much to divide the end (+- x axis) bevel dimensions. Set to current average radius to compensate for angular distortion on curved blocks
+ """
+
+ points = []
+ faces = []
+ faceinclude = [1 for x in range(6)]
+ for x in FaceExclude: faceinclude[x]=0
+ Top = zpos + ztop
+ Btm = zpos - zbtm
+ Wid = width/2.
+ Thk = thick/2.
+
+ # The front top point
+ points.append([xpos, Thk, Top])
+ # The front left point
+ points.append([xpos-Wid, Thk, zpos])
+ # The front bottom point
+ points.append([xpos, Thk, Btm])
+ # The front right point
+ points.append([xpos+Wid, Thk, zpos])
+
+ MirrorPoints = []
+ for i in points:
+ MirrorPoints.append([i[0],-i[1],i[2]])
+ points += MirrorPoints
+ points[6][2] += bevel
+
+ faces.append([3,2,1,0])
+ faces.append([4,5,6,7])
+ faces.append([4,7,3,0])
+ faces.append([5,4,0,1])
+ faces.append([6,5,1,2])
+ faces.append([7,6,2,3])
+ # Offset the vertex numbers by the number of verticies already in the list
+ for i in range(len(faces)):
+ for j in range(len(faces[i])): faces[i][j] += vll
+
+ return points, faces
+
+
+#for finding line/circle intercepts
+def circ(offs=0.,r=1.):
+ __doc__ = """\
+ offs is the distance perpendicular to the line to the center of the circle
+ r is the radius of the circle
+ circ returns the distance paralell to the line to the center of the circle at the intercept.
+ """
+ offs = abs(offs)
+ if offs > r: return None
+ elif offs == r: return 0.
+ else: return sqrt(r**2 - offs**2)
+
+
+#class openings in the wall
+class opening:
+ __doc__ = """\
+ This is the class for holding the data for the openings in the wall.
+ It has methods for returning the edges of the opening for any given position value,
+ as well as bevel settings and top and bottom positions.
+ It stores the 'style' of the opening, and all other pertinent information.
+ """
+ # x = 0. # x position of the opening
+ # z = 0. # x position of the opening
+ # w = 0. # width of the opening
+ # h = 0. # height of the opening
+ r = 0 # top radius of the arch (derived from 'v')
+ rl = 0 # lower radius of the arch (derived from 'vl')
+ rt = 0 # top arch thickness
+ rtl = 0# lower arch thickness
+ ts = 0 # Opening side thickness, if greater than average width, replaces it.
+ c = 0 # top arch corner position (for low arches), distance from the top of the straight sides
+ cl = 0 # lower arch corner position (for low arches), distance from the top of the straight sides
+ # form = 0 # arch type (unused for now)
+ # b = 0. # back face bevel distance, like an arrow slit
+ v = 0. # top arch height
+ vl = 0.# lower arch height
+ # variable "s" is used for "side" in the "edge" function.
+ # it is a signed int, multiplied by the width to get + or - of the center
+
+ def btm(self):
+ if self.vl <= self.w/2 : return self.z-self.h/2-self.vl-self.rtl
+ else: return self.z - sqrt((self.rl+self.rtl)**2 - (self.rl - self.w/2 )**2) - self.h/2
+
+
+ def top(self):
+ if self.v <= self.w/2 : return self.z+self.h/2+self.v+self.rt
+ else: return sqrt((self.r+self.rt)**2 - (self.r - self.w/2 )**2) + self.z + self.h/2
+
+
+ #crits returns the critical split points, or discontinuities, used for making rows
+ def crits(self):
+ critlist = []
+ if self.vl>0: # for lower arch
+ # add the top point if it is pointed
+ #if self.vl >= self.w/2.: critlist.append(self.btm())
+ if self.vl < self.w/2.:#else: for low arches, with wedge blocks under them
+ #critlist.append(self.btm())
+ critlist.append(self.z-self.h/2 - self.cl)
+
+ if self.h>0: # if it has a height, append points at the top and bottom of the main square section
+ critlist += [self.z-self.h/2,self.z+self.h/2]
+ else: # otherwise, append just one in the center
+ critlist.append(self.z)
+
+ if self.v>0: # for the upper arch
+ if self.v < self.w/2.: # add the splits for the upper wedge blocks, if needed
+ critlist.append(self.z+self.h/2 + self.c)
+ #critlist.append(self.top())
+ #otherwise just add the top point, if it is pointed
+ #else: critlist.append(self.top())
+
+ return critlist
+
+
+ # get the side position of the opening.
+ # ht is the z position; s is the side: 1 for right, -1 for left
+ # if the height passed is above or below the opening, return None
+ #
+ def edgeS(self, ht, s):
+ # set the row radius: 1 for standard wall (flat)
+ if radialized:
+ if slope: r1 = abs(dims['t']*sin(ht*PI/(dims['t']*2)))
+ else: r1 = abs(ht)
+ else: r1 = 1
+
+ #Go through all the options, and return the correct value
+ if ht < self.btm(): #too low
+ return None
+ elif ht > self.top(): #too high
+ return None
+
+ # Check for circ returning None - prevent TypeError (script failure) with float.
+
+ # in this range, pass the lower arch info
+ elif ht <= self.z-self.h/2-self.cl:
+ if self.vl > self.w/2:
+ circVal = circ(ht-self.z+self.h/2,self.rl+self.rtl)
+ if circVal == None:
+ return None
+ else: return self.x + s*(self.w/2.-self.rl+circVal)/r1
+ else:
+ circVal = circ(ht-self.z+self.h/2+self.vl-self.rl,self.rl+self.rtl)
+ if circVal == None:
+ return None
+ else: return self.x + s*circVal/r1
+
+ #in this range, pass the top arch info
+ elif ht >= self.z+self.h/2+self.c:
+ if self.v > self.w/2:
+ circVal = circ(ht-self.z-self.h/2,self.r+self.rt)
+ if circVal == None:
+ return None
+ else: return self.x + s*(self.w/2.-self.r+circVal)/r1
+ else:
+ circVal = circ(ht-(self.z+self.h/2+self.v-self.r),self.r+self.rt)
+ if circVal == None:
+ return None
+ else: return self.x + s*circVal/r1
+
+ #in this range pass the lower corner edge info
+ elif ht <= self.z-self.h/2:
+ d = sqrt(self.rtl**2 - self.cl**2)
+ if self.cl > self.rtl/sqrt(2.): return self.x + s*(self.w/2 + (self.z - self.h/2 - ht)*d/self.cl)/r1
+ else: return self.x + s*( self.w/2 + d )/r1
+
+ #in this range pass the upper corner edge info
+ elif ht >= self.z+self.h/2:
+ d = sqrt(self.rt**2 - self.c**2)
+ if self.c > self.rt/sqrt(2.): return self.x + s*(self.w/2 + (ht - self.z - self.h/2 )*d/self.c)/r1
+ else: return self.x + s*( self.w/2 + d )/r1
+
+ #in this range, pass the middle info (straight sides)
+ else: return self.x + s*self.w/2/r1
+
+
+ # get the top or bottom of the opening
+ # ht is the x position; s is the side: 1 for top, -1 for bottom
+ #
+ def edgeV(self, ht, s):
+ dist = abs(self.x-ht)
+ def radialAdjust(dist, sideVal):
+ """take the distance and adjust for radial geometry, return dist.
+ """
+ if radialized:
+ if slope:
+ dist = dist * abs(dims['t']*sin(sideVal*PI/(dims['t']*2)))
+ else:
+ dist = dist * sideVal
+ return dist
+
+ if s > 0 :#and (dist <= self.edgeS(self.z+self.h/2+self.c,1)-self.x): #check top down
+ #hack for radialized masonry, import approx Z instead of self.top()
+ dist = radialAdjust(dist, self.top())
+
+ #no arch on top, flat
+ if not self.r: return self.z+self.h/2
+
+ #pointed arch on top
+ elif self.v > self.w/2:
+ circVal = circ(dist-self.w/2+self.r,self.r+self.rt)
+ if circVal == None:
+ return None
+ else: return self.z+self.h/2+circVal
+
+ #domed arch on top
+ else:
+ circVal = circ(dist,self.r+self.rt)
+ if circVal == None:
+ return None
+ else: return self.z+self.h/2+self.v-self.r+circVal
+
+ else:#and (dist <= self.edgeS(self.z-self.h/2-self.cl,1)-self.x): #check bottom up
+ #hack for radialized masonry, import approx Z instead of self.top()
+ dist = radialAdjust(dist, self.btm())
+
+ #no arch on bottom
+ if not self.rl: return self.z-self.h/2
+
+ #pointed arch on bottom
+ elif self.vl > self.w/2:
+ circVal = circ(dist-self.w/2+self.rl,self.rl+self.rtl)
+ if circVal == None:
+ return None
+ else: return self.z-self.h/2-circVal
+
+ #old conditional? if (dist-self.w/2+self.rl)<=(self.rl+self.rtl):
+ #domed arch on bottom
+ else:
+ circVal = circ(dist,self.rl+self.rtl) # dist-self.w/2+self.rl
+ if circVal == None:
+ return None
+ else: return self.z-self.h/2-self.vl+self.rl-circVal
+
+ # and this never happens - but, leave it as failsafe :)
+ print("got all the way out of the edgeV! Not good!")
+ print("opening x = ", self.x, ", opening z = ", self.z)
+ return 0.0
+ #
+ def edgeBev(self, ht):
+ if ht > (self.z + self.h/2): return 0.0
+ if ht < (self.z - self.h/2): return 0.0
+ if radialized:
+ if slope: r1 = abs(dims['t']*sin(ht*PI/(dims['t']*2)))
+ else: r1 = abs(ht)
+ else: r1 = 1
+ bevel = self.b / r1
+ return bevel
+#
+##
+#
+
+ def __init__(self, xpos, zpos, width, height, archHeight=0, archThk=0,
+ archHeightLower=0, archThkLower=0, bevel=0, edgeThk=0):
+ self.x = float(xpos)
+ self.z = float(zpos)
+ self.w = float(width)
+ self.h = float(height)
+ self.rt = archThk
+ self.rtl = archThkLower
+ self.v = archHeight
+ self.vl = archHeightLower
+ if self.w <= 0: self.w = SMALL
+
+ #find the upper arch radius
+ if archHeight >= width/2:
+ # just one arch, low long
+ self.r = (self.v**2)/self.w + self.w/4
+ elif archHeight <= 0:
+ # No arches
+ self.r = 0
+ self.v = 0
+ else:
+ # Two arches
+ self.r = (self.w**2)/(8*self.v) + self.v/2.
+ self.c = self.rt*cos(atan(self.w/(2*(self.r-self.v))))
+
+ #find the lower arch radius
+ if archHeightLower >= width/2:
+ self.rl = (self.vl**2)/self.w + self.w/4
+ elif archHeightLower <= 0:
+ self.rl = 0
+ self.vl = 0
+ else:
+ self.rl = (self.w**2)/(8*self.vl) + self.vl/2.
+ self.cl = self.rtl*cos(atan(self.w/(2*(self.rl-self.vl))))
+
+ #self.form = something?
+ self.b = float(bevel)
+ self.ts = edgeThk
+#
+#
+
+#class for the whole wall boundaries; a sub-class of "opening"
+class OpeningInv(opening):
+ #this is supposed to switch the sides of the opening
+ #so the wall will properly enclose the whole wall.
+ #We'll see if it works.
+
+ def edgeS(self, ht, s):
+ return opening.edgeS(self, ht, -s)
+
+ def edgeV(self, ht, s):
+ return opening.edgeV(self, ht, -s)
+
+#class rows in the wall
+class rowOb:
+ __doc__ = """\
+ This is the class for holding the data for individual rows of blocks.
+ each row is required to have some edge blocks, and can also have
+ intermediate sections of "normal" blocks.
+ """
+
+ #z = 0.
+ #h = 0.
+ radius = 1
+ EdgeOffset = 0.
+# BlocksEdge = []
+# RowSegments = []
+# BlocksNorm = []
+
+ def FillBlocks(self):
+ # Set the radius variable, in the case of radial geometry
+ if radialized:
+ if slope: self.radius = dims['t']*(sin(self.z*PI/(dims['t']*2)))
+ else: self.radius = self.z
+
+ #initialize internal variables from global settings
+
+ SetH = settings['h']
+ SetHwt = settings['hwt']
+ SetWid = settings['w']
+ SetWidMin = settings['wm']
+ SetWidVar = settings['wv']
+ SetGrt = settings['g']
+ SetGrtVar = settings['gv']
+ SetRowHeightLink = settings['rwhl']
+ SetDepth = settings['d']
+ SetDepthVar = settings['dv']
+
+ #height weight, used for making shorter rows have narrower blocks, and vice-versa
+ hwt = ((self.h/SetH-1)*SetHwt+1)
+
+ # set variables for persistent values: loop optimization, readability, single ref for changes.
+
+ avgDist = hwt*SetWid/self.radius
+ minDist = SetWidMin/self.radius
+ deviation = hwt*SetWidVar/self.radius
+ grtOffset = SetGrt/(2*self.radius)
+
+ # init loop variables that may change...
+
+ grt = (SetGrt + rndc()*SetGrtVar)/(self.radius)
+ ThisBlockHeight = self.h+rndc()*(1-SetRowHeightLink)*SetGrtVar
+ ThisBlockDepth = rndd()*SetDepthVar+SetDepth
+
+ for segment in self.RowSegments:
+ divs = fill(segment[0]+grtOffset, segment[1]-grtOffset, avgDist, minDist, deviation)
+
+ #loop through the divisions, adding blocks for each one
+ for i in range(len(divs)-1):
+ ThisBlockx = (divs[i]+divs[i+1])/2
+ ThisBlockw = divs[i+1]-divs[i]-grt
+
+ self.BlocksNorm.append([ThisBlockx, self.z, ThisBlockw, ThisBlockHeight, ThisBlockDepth, None])
+
+ if SetDepthVar: # vary depth
+ ThisBlockDepth = rndd()*SetDepthVar+SetDepth
+
+ if SetGrtVar: # vary grout
+ grt = (SetGrt + rndc()*SetGrtVar)/(self.radius)
+ ThisBlockHeight = self.h+rndc()*(1-SetRowHeightLink)*SetGrtVar
+
+
+ def __init__(self,centerheight,rowheight,edgeoffset = 0.):
+ self.z = float(centerheight)
+ self.h = float(rowheight)
+ self.EdgeOffset = float(edgeoffset)
+
+#THIS INITILIZATION IS IMPORTANT! OTHERWISE ALL OBJECTS WILL HAVE THE SAME LISTS!
+ self.BlocksEdge = []
+ self.RowSegments = []
+ self.BlocksNorm = []
+
+#
+def arch(ra,rt,x,z, archStart, archEnd, bevel, bevAngle, vll):
+ __doc__ = """\
+ Makes a list of faces and vertexes for arches.
+ ra: the radius of the arch, to the center of the bricks
+ rt: the thickness of the arch
+ x: x center location of the circular arc, as if the arch opening were centered on x = 0
+ z: z center location of the arch
+ anglebeg: start angle of the arch, in radians, from vertical?
+ angleend: end angle of the arch, in radians, from vertical?
+ bevel: how much to bevel the inside of the arch.
+ vll: how long is the vertex list already?
+ """
+ avlist = []
+ aflist = []
+
+ #initialize internal variables for global settings
+#overkill?
+ SetH = settings['h']
+ SetHwt = settings['hwt']
+ SetWid = settings['w']
+ SetWidMin = settings['wm']
+ SetWidVar = settings['wv']
+ SetGrt = settings['g']
+ SetGrtVar = settings['gv']
+ SetRowHeightLink = settings['rwhl']
+ SetDepth = settings['d']
+ SetDepthVar = settings['dv']
+
+ # Init loop variables
+
+ def bevelEdgeOffset(offsets, bevel, side):
+ """
+ Take the block offsets and modify it for the correct bevel.
+
+ offsets = the offset list. See MakeABlock
+ bevel = how much to offset the edge
+ side = -1 for left (right side), 1 for right (left side)
+ """
+ left = (0,2,3)
+ right = (4,6,7)
+ if side == 1: pointsToAffect = right
+ else: pointsToAffect = left
+ for num in pointsToAffect:
+ offsets[num] = offsets[num][:]
+ offsets[num][0] += -bevel * side
+
+ ArchInner = ra-rt/2
+ ArchOuter = ra+rt/2-SetGrt + rndc()*SetGrtVar
+
+ DepthBack = -SetDepth/2-rndc()*SetDepthVar
+ DepthFront = SetDepth/2+rndc()*SetDepthVar
+
+ if radialized: subdivision = settings['sdv']
+ else: subdivision = 0.12
+
+ grt = (SetGrt + rndc()*SetGrtVar)/(2*ra) # init grout offset for loop
+ # set up the offsets, it will be the same for every block
+ offsets = ([[0]*2 + [bevel]] + [[0]*3]*3)*2
+
+ #make the divisions in the "length" of the arch
+ divs = fill(archStart, archEnd, settings['w']/ra, settings['wm']/ra, settings['wv']/ra)
+
+ for i in range(len(divs)-1):
+ if i == 0:
+ ThisOffset = offsets[:]
+ bevelEdgeOffset(ThisOffset, bevAngle, -1)
+ elif i == len(divs)-2:
+ ThisOffset = offsets[:]
+ bevelEdgeOffset(ThisOffset, bevAngle, 1)
+ else:
+ ThisOffset = offsets
+
+ geom = MakeABlock([divs[i]+grt, divs[i+1]-grt, ArchInner, ArchOuter, DepthBack, DepthFront],
+ subdivision, len(avlist) + vll, ThisOffset, [], None, ra)
+
+ avlist += geom[0]
+ aflist += geom[1]
+
+ if SetDepthVar: # vary depth
+ DepthBack = -SetDepth/2-rndc()*SetDepthVar
+ DepthFront = SetDepth/2+rndc()*SetDepthVar
+
+ if SetGrtVar: # vary grout
+ grt = (settings['g'] + rndc()*SetGrtVar)/(2*ra)
+ ArchOuter = ra+rt/2-SetGrt + rndc()*SetGrtVar
+
+ for i,vert in enumerate(avlist):
+ v0 = vert[2]*sin(vert[0]) + x
+ v1 = vert[1]
+ v2 = vert[2]*cos(vert[0]) + z
+
+ if radialized==1:
+ if slope==1: r1 = dims['t']*(sin(v2*PI/(dims['t']*2)))
+ else: r1 = v2
+ v0 = v0/r1
+
+ avlist[i] = [v0,v1,v2]
+
+ return (avlist,aflist)
+
+#
+def sketch():
+ __doc__ = """\
+ The 'sketch' function creates a list of openings from the general specifications passed to it.
+ It takes curved and domed walls into account, placing the openings at the appropriate angular locations
+ """
+ boundlist = []
+ for x in openingSpecs:
+ if x['rp']:
+ if radialized: r1 = x['z']
+ else: r1 = 1
+
+ if x['x'] > (x['w'] + settings['wm']):spacing = x['x']/r1
+ else: spacing = (x['w'] + settings['wm'])/r1
+
+ minspacing = (x['w'] + settings['wm'])/r1
+
+ divs = fill(dims['s'],dims['e'],spacing,minspacing,center=1)
+
+ for posidx in range(len(divs)-2):
+ boundlist.append(opening(divs[posidx+1],x['z'],x['w'],x['h'],x['v'],x['t'],x['vl'],x['tl'],x['b']))
+
+ else: boundlist.append(opening(x['x'],x['z'],x['w'],x['h'],x['v'],x['t'],x['vl'],x['tl'],x['b']))
+ #check for overlaping edges?
+
+ return boundlist
+
+
+def wedgeBlocks(row, opening, leftPos, rightPos, edgeBinary, r1):
+ __doc__ = """\
+ Makes wedge blocks for the left and right sides, depending
+ example:
+ wedgeBlocks(row, LeftWedgeEdge, LNerEdge, LEB, r1)
+ wedgeBlocks(row, RNerEdge, RightWedgeEdge, REB, r1)
+ """
+ wedgeEdges = fill(leftPos, rightPos, settings['w']/r1, settings['wm']/r1,
+ settings['wv']/r1)
+
+ for i in range(len(wedgeEdges)-1):
+ x = (wedgeEdges[i+1] + wedgeEdges[i])/2
+ grt = (settings['g'] + rndd()*settings['gv'])/r1
+ w = wedgeEdges[i+1] - wedgeEdges[i] - grt
+
+ ThisBlockDepth = rndd()*settings['dv']+settings['d']
+
+#edgeV may return "None" - causing TypeError for math op.
+#use 0 until wedgeBlocks operation worked out
+ edgeVal = opening.edgeV(x-w/2,edgeBinary)
+ if edgeVal == None: edgeVal = 0.0
+
+ LeftVertOffset = -( row.z - (row.h/2)*edgeBinary - edgeVal )
+
+#edgeV may return "None" - causing TypeError for math op.
+#use 0 until wedgeBlocks operation worked out
+ edgeVal = opening.edgeV(x+w/2,edgeBinary)
+ if edgeVal == None: edgeVal = 0.0
+
+ RightVertOffset = -( row.z - (row.h/2)*edgeBinary - edgeVal )
+
+ #Wedges are on top = off, blank, off, blank
+ #Wedges are on btm = blank, off, blank, off
+ ThisBlockOffsets = [[0,0,LeftVertOffset]]*2 + [[0]*3]*2 + [[0,0,RightVertOffset]]*2
+
+ # Instert or append "blank" for top or bottom wedges.
+ if edgeBinary == 1: ThisBlockOffsets = ThisBlockOffsets + [[0]*3]*2
+ else: ThisBlockOffsets = [[0]*3]*2 + ThisBlockOffsets
+
+ row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,ThisBlockOffsets])
+
+ return None
+
+def bevelBlockOffsets(offsets, bevel, side):
+ """
+ Take the block offsets and modify it for the correct bevel.
+
+ offsets = the offset list. See MakeABlock
+ bevel = how much to offset the edge
+ side = -1 for left (right side), 1 for right (left side)
+ """
+# left = (4,6)
+# right = (0,2)
+ if side == 1: pointsToAffect = (0,2) # right
+ else: pointsToAffect = (4,6) # left
+ for num in pointsToAffect:
+ offsets[num] = offsets[num][:]
+ offsets[num][0] += bevel * side
+
+def rowProcessing(row, Thesketch, WallBoundaries):
+ __doc__ = """\
+ Take row and opening data and process a single row, adding edge and fill blocks to the row data.
+ """
+ #set end blocks
+ #check for openings, record top and bottom of row for right and left of each
+ #if both top and bottom intersect create blocks on each edge, appropriate to the size of the overlap
+ #if only one side intersects, run fill to get edge positions, but this should never happen
+ #
+
+ if radialized:#this checks for radial stonework, and sets the row radius if required
+ if slope: r1 = abs(dims['t']*sin(row.z*PI/(dims['t']*2)))
+ else: r1 = abs(row.z)
+ else: r1 = 1
+
+ # set the edge grout thickness, especially with radial stonework in mind
+ edgrt = settings['ge']*(settings['g']/2 + rndc()*settings['gv'])/(2*r1)
+
+ # Sets up a list of intersections of top of row with openings,
+ #from left to right [left edge of opening, right edge of opening, etc...]
+ #initially just the left and right edge of the wall
+ edgetop = [[dims['s']+row.EdgeOffset/r1+edgrt,WallBoundaries], [dims['e']+row.EdgeOffset/r1-edgrt,WallBoundaries]]
+ # Same as edgetop, but for the bottms of the rows
+ edgebtm = [[dims['s']+row.EdgeOffset/r1+edgrt,WallBoundaries], [dims['e']+row.EdgeOffset/r1-edgrt,WallBoundaries]]
+
+ # set up some useful values for the top and bottom of the rows.
+ rowTop = row.z+row.h/2
+ rowBtm = row.z-row.h/2
+
+ for hole in Thesketch:
+ #check the top and bottom of the row, looking at the opening from the right
+ e = [hole.edgeS(rowTop, -1), hole.edgeS(rowBtm, -1)]
+
+ # If either one hit the opening, make split points for the left side of the opening.
+ if e[0] or e[1]:
+ e += [hole.edgeS(rowTop, 1), hole.edgeS(rowBtm, 1)]
+
+ # If one of them missed for some reason, set that value to
+ # the middle of the opening.
+ for i,pos in enumerate(e):
+ if pos == None: e[i] = hole.x
+
+ # add the intersects to the list of edge points
+ edgetop.append([e[0],hole])
+ edgetop.append([e[2],hole])
+ edgebtm.append([e[1],hole])
+ edgebtm.append([e[3],hole])
+
+ # We want to make the walls in order, so sort the intersects.
+ # This is where you would want to remove edge points that are out of order
+ # so that you don't get the "oddity where overlapping openings create blocks inversely" problem
+ edgetop.sort()
+ edgebtm.sort()
+
+ #these two loops trim the edges to the limits of the wall. This way openings extending outside the wall don't enlarge the wall.
+ while True:
+ try:
+ if (edgetop[-1][0] > dims['e']+row.EdgeOffset/r1) or (edgebtm[-1][0] > dims['e']+row.EdgeOffset/r1):
+ edgetop[-2:] = []
+ edgebtm[-2:] = []
+ else: break
+ except IndexError: break
+ #still trimming the edges...
+ while True:
+ try:
+ if (edgetop[0][0] < dims['s']+row.EdgeOffset/r1) or (edgebtm[0][0] < dims['s']+row.EdgeOffset/r1):
+ edgetop[:2] = []
+ edgebtm[:2] = []
+ else: break
+ except IndexError: break
+
+ #make those edge blocks and rows! Wooo!
+ #This loop goes through each section, (a pair of points in edgetop)
+ #and places the edge blocks and inbetween normal block zones into the row object
+ for OpnSplitNo in range(int(len(edgetop)/2)):
+ #left edge is edge<x>[2*OpnSplitNo], right edge edgex[2*OpnSplitNo+1]
+ leftEdgeIndex = 2*OpnSplitNo
+ rightEdgeIndex = 2*OpnSplitNo + 1
+ # get the openings, to save time and confusion
+ leftOpening = edgetop[leftEdgeIndex][1]
+ rightOpening = edgetop[rightEdgeIndex][1]
+ #find the difference between the edge top and bottom on both sides
+ LTop = edgetop[leftEdgeIndex][0]
+ LBtm = edgebtm[leftEdgeIndex][0]
+ RTop = edgetop[rightEdgeIndex][0]
+ RBtm = edgebtm[rightEdgeIndex][0]
+ LDiff = LBtm-LTop
+ RDiff = RTop-RBtm
+
+ #which is furthur out on each side, top or bottom?
+ if LDiff > 0:
+ LFarEdge = LTop #The furthest edge left
+ LNerEdge = LBtm #the nearer edge left
+ LEB = 1 #Left Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom
+ else:
+ LFarEdge = LBtm
+ LNerEdge = LTop
+ LEB = -1
+
+ if RDiff > 0:
+ RFarEdge = RTop #The furthest edge right
+ RNerEdge = RBtm #the nearer edge right
+ REB = 1 #Right Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom
+
+ else:
+ RFarEdge = RBtm #The furthest edge right
+ RNerEdge = RTop
+ REB = -1 #Right Edge Boolean, set to 1 if furthest edge is top, -1 if it is bottom
+
+ #The space between the closest edges of the openings in this section of the row
+ InnerDiff = RNerEdge - LNerEdge
+ #The mid point between the nearest edges
+ InnerMid = (RNerEdge + LNerEdge)/2
+
+ #maximum distance to span with one block
+ MaxWid = (settings['w']+settings['wv'])/r1
+ AveWid = settings['w']
+ MinWid = settings['wm']
+
+ #check the left and right sides for wedge blocks
+ #Check and run the left edge first
+ #find the edge of the correct side, offset for minimum block height. The LEB decides top or bottom
+ ZPositionCheck = row.z + (row.h/2-settings['hm'])*LEB
+#edgeS may return "None"
+ LeftWedgeEdge = leftOpening.edgeS(ZPositionCheck,1)
+
+ if (abs(LDiff) > AveWid) or (not LeftWedgeEdge):
+ #make wedge blocks
+ if not LeftWedgeEdge: LeftWedgeEdge = leftOpening.x
+ wedgeBlocks(row, leftOpening, LeftWedgeEdge, LNerEdge, LEB, r1)
+ #set the near and far edge settings to vertical, so the other edge blocks don't interfere
+ LFarEdge , LTop , LBtm = LNerEdge, LNerEdge, LNerEdge
+ LDiff = 0
+
+ #Now do the wedge blocks for the right, same drill... repeated code?
+ #find the edge of the correct side, offset for minimum block height. The REB decides top or bottom
+ ZPositionCheck = row.z + (row.h/2-settings['hm'])*REB
+#edgeS may return "None"
+ RightWedgeEdge = rightOpening.edgeS(ZPositionCheck,-1)
+ if (abs(RDiff) > AveWid) or (not RightWedgeEdge):
+ #make wedge blocks
+ if not RightWedgeEdge: RightWedgeEdge = rightOpening.x
+ wedgeBlocks(row, rightOpening, RNerEdge, RightWedgeEdge, REB, r1)
+ #set the near and far edge settings to vertical, so the other edge blocks don't interfere
+ RFarEdge , RTop , RBtm = RNerEdge, RNerEdge, RNerEdge
+ RDiff = 0
+
+ #Check to see if the edges are close enough toegther to warrant a single block filling it
+ if (InnerDiff < MaxWid):
+ #if this is true, then this row is just one block!
+ x = (LNerEdge + RNerEdge)/2.
+ w = InnerDiff
+ ThisBlockDepth = rndd()*settings['dv']+settings['d']
+ BtmOff = LBtm - LNerEdge
+ TopOff = LTop - LNerEdge
+ ThisBlockOffsets = [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2
+ BtmOff = RBtm - RNerEdge
+ TopOff = RTop - RNerEdge
+ ThisBlockOffsets += [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2
+ bevel = leftOpening.edgeBev(rowTop)
+ bevelBlockOffsets(ThisBlockOffsets, bevel, 1)
+ bevel = rightOpening.edgeBev(rowTop)
+ bevelBlockOffsets(ThisBlockOffsets, bevel, -1)
+ row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,ThisBlockOffsets])
+ continue
+
+ # it's not one block, must be two or more
+ # set up the offsets for the left
+ BtmOff = LBtm - LNerEdge
+ TopOff = LTop - LNerEdge
+ leftOffsets = [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2 + [[0]*3]*4
+ bevelL = leftOpening.edgeBev(rowTop)
+ bevelBlockOffsets(leftOffsets, bevelL, 1)
+ # and now for the right
+ BtmOff = RBtm - RNerEdge
+ TopOff = RTop - RNerEdge
+ rightOffsets = [[0]*3]*4 + [[BtmOff,0,0]]*2 + [[TopOff,0,0]]*2
+ bevelR = rightOpening.edgeBev(rowTop)
+ bevelBlockOffsets(rightOffsets, bevelR, -1)
+ # check to see if it is only two blocks
+ if (InnerDiff < MaxWid*2):
+ #this row is just two blocks! Left block, then right block
+ #div is the x position of the dividing point between the two bricks
+ div = InnerMid + (rndd()*settings['wv'])/r1
+ #set the grout distance, since we need grout seperation between the blocks
+ grt = (settings['g'] + rndc()*settings['gv'])/r1
+ #set the x position and width for the left block
+ x = (div + LNerEdge)/2 - grt/4
+ w = (div - LNerEdge) - grt/2
+ ThisBlockDepth = rndd()*settings['dv']+settings['d']
+ #For reference: EdgeBlocks = [[x,z,w,h,d,[corner offset matrix]],[etc.]]
+ row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,leftOffsets])
+ #Initialize for the block on the right side
+ x = (div + RNerEdge)/2 + grt/4
+ w = (RNerEdge - div) - grt/2
+ ThisBlockDepth = rndd()*settings['dv']+settings['d']
+ row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,rightOffsets])
+ continue
+
+ #program should only get here if there are more than two blocks in the row, and no wedge blocks
+
+ #make Left edge block
+ #set the grout
+ grt = (settings['g'] + rndc()*settings['gv'])/r1
+ #set the x position and width for the left block
+ widOptions = [settings['w'], bevelL + settings['wm'], leftOpening.ts]
+ baseWid = max(widOptions)
+ w = (rndd()*settings['wv']+baseWid+row.EdgeOffset)
+ widOptions[0] = settings['wm']
+ widOptions[2] = w
+ w = max(widOptions) / r1 - grt
+ x = w/2 + LNerEdge + grt/2
+ BlockRowL = x + w/2
+ ThisBlockDepth = rndd()*settings['dv']+settings['d']
+ row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,leftOffsets])
+
+ #make Right edge block
+ #set the grout
+ grt = (settings['g'] + rndc()*settings['gv'])/r1
+ #set the x position and width for the left block
+ widOptions = [settings['w'], bevelR + settings['wm'], rightOpening.ts]
+ baseWid = max(widOptions)
+ w = (rndd()*settings['wv']+baseWid+row.EdgeOffset)
+ widOptions[0] = settings['wm']
+ widOptions[2] = w
+ w = max(widOptions) / r1 - grt
+ x = RNerEdge - w/2 - grt/2
+ BlockRowR = x - w/2
+ ThisBlockDepth = rndd()*settings['dv']+settings['d']
+ row.BlocksEdge.append([x,row.z,w,row.h,ThisBlockDepth,rightOffsets])
+
+ row.RowSegments.append([BlockRowL,BlockRowR])
+ return None
+
+
+def plan(Thesketch, oldrows = 0):
+ __doc__ = """\
+ The 'plan' function takes the data generated by the sketch function and the global settings
+ and creates a list of blocks.
+ It passes out a list of row heights, edge positions, edge blocks, and rows of blocks.
+ """
+ # if we were passed a list of rows already, use those; else make a list.
+ if oldrows: rows = oldrows
+ else:
+ #rows holds the important information common to all rows
+ #rows = [list of row objects]
+ rows = []
+
+ #splits are places where we NEED a row division, to accomidate openings
+ #add a split for the bottom row
+ splits = [dims['b']+settings['hb']]
+
+ #add a split for each critical point on each opening
+ for hole in Thesketch: splits += hole.crits()
+
+ #and, a split for the top row
+ splits.append(dims['t']-settings['ht'])
+ splits.sort()
+
+ #divs are the normal old row divisions, add them between the top and bottom split
+ divs = fill(splits[0],splits[-1],settings['h'],settings['hm']+settings['g'],settings['hv'])[1:-1]
+
+ #remove the divisions that are too close to the splits, so we don't get tiny thin rows
+ for i in range(len(divs)-1,-1,-1):
+ for j in range(len(splits)):
+ diff = abs(divs[i] - splits[j])
+ #(settings['hm']+settings['g']) is the old minimum value
+ if diff < (settings['h']-settings['hv']+settings['g']):
+ del(divs[i])
+ break
+
+ #now merge the divs and splits lists
+ divs += splits
+
+ #add bottom and/or top points, if bottom and/or top row heights are more than zero
+ if settings['hb']>0: divs.insert(0,dims['b'])
+ if settings['ht']>0: divs.append(dims['t'])
+
+ divs.sort()
+
+ #trim the rows to the bottom and top of the wall
+ if divs[0] < dims['b']: divs[:1] = []
+ if divs[-1] > dims['t']: divs[-1:] = []
+
+ #now, make the data for each row
+ #rows = [[center height,row height,edge offset],[etc.]]
+
+ divCount = len(divs)-1 # number of divs to check
+ divCheck = 0 # current div entry
+
+ while divCheck < divCount:
+ RowZ = (divs[divCheck]+divs[divCheck+1])/2
+ RowHeight = divs[divCheck+1]-divs[divCheck]-settings['g']+rndc()*settings['rwhl']*settings['gv']
+ EdgeOffset = settings['eoff']*(fmod(divCheck,2)-0.5)+settings['eoffv']*rndd()
+
+ # if row height is too shallow: delete next div entry, decrement total, and recheck current entry.
+ if RowHeight < settings['hm']:
+ del(divs[divCheck+1])
+ divCount -= 1 # Adjust count for removed div entry.
+ continue
+
+ rows.append(rowOb(RowZ, RowHeight, EdgeOffset))
+
+ divCheck += 1 # on to next div entry
+
+ #set up a special opening object to handle the edges of the wall
+ x = (dims['s'] + dims['e'])/2
+ z = (dims['t'] + dims['b'])/2
+ w = (dims['e'] - dims['s'])
+ h = (dims['t'] - dims['b'])
+ WallBoundaries = OpeningInv(x,z,w,h)
+
+ #Go over each row in the list, set up edge blocks and block sections
+ for rownum in range(len(rows)):
+ rowProcessing(rows[rownum], Thesketch, WallBoundaries)
+
+ #now return the things everyone needs
+ #return [rows,edgeBlocks,blockRows,Asketch]
+ return [rows,Thesketch]
+
+
+def archGeneration(hole, vlist, flist, sideSign):
+ __doc__ = """\
+ Makes arches for the top and bottom, depending on sideSign
+ example, Lower arch:
+ archGeneration(hole, vlist, flist, -1)
+ example, Upper arch:
+ archGeneration(hole, vlist, flist, 1)
+ hole is the opening object that the arch is for
+ add the verticies to vlist
+ add the faces to flist
+ sideSign is + or - 1, for the top or bottom arch. Other values may cause errors.
+ """
+
+ # working arrays for vectors and faces
+ avlist = []
+ aflist = []
+
+ # Top (1) or bottom (-1)
+ if sideSign == -1:
+ r = hole.rl #radius of the arch
+ rt = hole.rtl #thickness of the arch (stone height)
+ v = hole.vl #height of the arch
+ c = hole.cl
+ else:
+ r = hole.r #radius of the arch
+ rt = hole.rt #thickness of the arch (stone height)
+ v = hole.v #height of the arch
+ c = hole.c
+
+ ra = r + rt/2 #average radius of the arch
+ x = hole.x
+ w = hole.w
+ h = hole.h
+ z = hole.z
+ bev = hole.b
+ sideSignInv = -sideSign
+
+ if v > w/2: #two arcs, to make a pointed arch
+ # positioning
+ zpos = z + (h/2)*sideSign
+ xoffset = r - w/2
+ #left side top, right side bottom
+ #angles reference straight up, and are in radians
+ bevRad = r + bev
+ bevHt = sqrt(bevRad**2 - (bevRad - (w/2 + bev))**2)
+ midHalfAngle = atan(v/(r-w/2))
+ midHalfAngleBevel = atan(bevHt/(r-w/2))
+ bevelAngle = midHalfAngle - midHalfAngleBevel
+ anglebeg = (PI/2)*(sideSignInv)
+ angleend = (PI/2)*(sideSignInv) + midHalfAngle
+
+ avlist,aflist = arch(ra,rt,(xoffset)*(sideSign),zpos,anglebeg,angleend,bev,bevelAngle,len(vlist))
+
+ for i,vert in enumerate(avlist): avlist[i] = [vert[0]+hole.x,vert[1],vert[2]]
+ vlist += avlist
+ flist += aflist
+
+ #right side top, left side bottom
+
+ #angles reference straight up, and are in radians
+ anglebeg = (PI/2)*(sideSign) - midHalfAngle
+ angleend = (PI/2)*(sideSign)
+
+ avlist,aflist = arch(ra,rt,(xoffset)*(sideSignInv),zpos,anglebeg,angleend,bev,bevelAngle,len(vlist))
+
+ for i,vert in enumerate(avlist): avlist[i] = [vert[0]+hole.x,vert[1],vert[2]]
+
+ vlist += avlist
+ flist += aflist
+
+ #keystone
+ Dpth = settings['d']+rndc()*settings['dv']
+ Grout = settings['g'] + rndc()*settings['gv']
+ angleBevel = (PI/2)*(sideSign) - midHalfAngle
+ Wdth = (rt - Grout - bev) * 2 * sin(angleBevel) * sideSign #note, sin may be negative
+ MidZ = ((sideSign)*(bevHt + h/2.0) + z) + (rt - Grout - bev) * cos(angleBevel) #note, cos may come out negative too
+ nearCorner = sideSign*(MidZ - z) - v - h/2
+
+ if sideSign == 1:
+ TopHt = hole.top() - MidZ - Grout
+ BtmHt = nearCorner
+ else:
+ BtmHt = - (hole.btm() - MidZ) - Grout
+ TopHt = nearCorner
+
+ # set the amout to bevel the keystone
+ keystoneBevel = (bevHt - v)*sideSign
+ if Wdth >= settings['hm']:
+ avlist,aflist = MakeAKeystone(x, Wdth, MidZ, TopHt, BtmHt, Dpth, keystoneBevel, len(vlist))
+
+ if radialized:
+ for i,vert in enumerate(avlist):
+ if slope: r1 = dims['t']*sin(vert[2]*PI/(dims['t']*2))
+ else: r1 = vert[2]
+ avlist[i] = [((vert[0]-hole.x)/r1)+hole.x,vert[1],vert[2]]
+
+ vlist += avlist
+ flist += aflist
+# remove "debug note" once bevel is finalized.
+ else: print("keystone was too narrow - " + str(Wdth))
+
+ else: # only one arc - curve not peak.
+#bottom (sideSign -1) arch has poorly sized blocks...
+
+ zpos = z + (sideSign * (h/2 + v - r)) # single arc positioning
+
+ #angles reference straight up, and are in radians
+ if sideSign == -1: angleOffset = PI
+ else: angleOffset = 0.0
+
+ if v < w/2:
+ halfangle = atan(w/(2*(r-v)))
+
+ anglebeg = angleOffset - halfangle
+ angleend = angleOffset + halfangle
+ else:
+ anglebeg = angleOffset - PI/2
+ angleend = angleOffset + PI/2
+
+ avlist,aflist = arch(ra,rt,0,zpos,anglebeg,angleend,bev,0.0,len(vlist))
+
+ for i,vert in enumerate(avlist): avlist[i] = [vert[0]+x,vert[1],vert[2]]
+
+ vlist += avlist
+ flist += aflist
+
+ #Make the Side Stones
+ grt = (settings['g'] + rndc()*settings['gv'])
+ width = sqrt(rt**2 - c**2) - grt
+
+ if c > settings['hm'] + grt and c < width + grt:
+ if radialized: subdivision = settings['sdv'] * (zpos + (h/2)*sideSign)
+ else: subdivision = settings['sdv']
+
+ #set the height of the block, it should be as high as the max corner position, minus grout
+ height = c - grt*(0.5 + c/(width + grt))
+
+ #the vertical offset for the short side of the block
+ voff = sideSign * (settings['hm'] - height)
+ xstart = w/2
+ zstart = z + sideSign * (h/2 + grt/2)
+ woffset = width*(settings['hm'] + grt/2)/(c - grt/2)
+ depth = rndd()*settings['dv']+settings['d']
+
+ if sideSign == 1:
+ offsets = [[0]*3]*6 + [[0]*2 + [voff]]*2
+ topSide = zstart+height
+ btmSide = zstart
+ else:
+ offsets = [[0]*3]*4 + [[0]*2 + [voff]]*2 + [[0]*3]*2
+ topSide = zstart
+ btmSide = zstart-height
+ # Do some stuff to incorporate bev here
+ bevelBlockOffsets(offsets, bev, -1)
+
+ avlist,aflist = MakeABlock([x-xstart-width, x-xstart- woffset, btmSide, topSide, -depth/2, depth/2], subdivision, len(vlist), Offsets=offsets, xBevScl=1)
+
+# top didn't use radialized in prev version; just noting for clarity - may need to revise for "sideSign == 1"
+ if radialized:
+ for i,vert in enumerate(avlist): avlist[i] = [((vert[0]-x)/vert[2])+x,vert[1],vert[2]]
+
+ vlist += avlist
+ flist += aflist
+
+# keep sizing same - neat arches = master masons :)
+# grt = (settings['g'] + rndc()*settings['gv'])
+# height = c - grt*(0.5 + c/(width + grt))
+# if grout varies may as well change width too... width = sqrt(rt**2 - c**2) - grt
+# voff = sideSign * (settings['hm'] - height)
+# woffset = width*(settings['hm'] + grt/2)/(c - grt/2)
+
+ if sideSign == 1:
+ offsets = [[0]*3]*2 + [[0]*2 + [voff]]*2 + [[0]*3]*4
+ topSide = zstart+height
+ btmSide = zstart
+ else:
+ offsets = [[0]*2 + [voff]]*2 + [[0]*3]*6
+ topSide = zstart
+ btmSide = zstart-height
+ # Do some stuff to incorporate bev here
+ bevelBlockOffsets(offsets, bev, 1)
+
+ avlist,aflist = MakeABlock([x+xstart+woffset, x+xstart+width, btmSide, topSide, -depth/2, depth/2], subdivision, len(vlist), Offsets=offsets, xBevScl=1)
+
+# top didn't use radialized in prev version; just noting for clarity - may need to revise for "sideSign == 1"
+ if radialized:
+ for i,vert in enumerate(avlist): avlist[i] = [((vert[0]-x)/vert[2])+x,vert[1],vert[2]]
+
+ vlist += avlist
+ flist += aflist
+ return None
+
+
+def build(Aplan):
+ __doc__ = """\
+ Build creates the geometry for the wall, based on the
+ "Aplan" object from the "plan" function. If physics is
+ enabled, then it make a number of individual blocks with
+ physics interaction enabled. Otherwise it creates
+ geometry for the blocks, arches, etc. of the wall.
+ """
+
+ vlist = []
+ flist = []
+ rows = Aplan[0]
+
+#dead code...
+ #Physics setup is horribly broken. Revisit when new API is in place.
+ '''if False: #settings['physics']:
+ geom = MakeABlock([-0.5,0.5,-0.5,0.5,-0.5,0.5], 3, 0, None,[], 3*settings['b']/(settings['w'] + settings['h'] + settings['d']))
+ blockmesh = Blender.Mesh.New('block')
+ vlist += geom[0]
+ flist += geom[1]
+ blockmesh.verts.extend(vlist)
+ blockmesh.faces.extend(flist)
+
+ for block in Aplan[1]:
+ x,z,w,h,d = block[:5]
+ block = scn.objects.new(blockmesh, 'block')
+ block.loc = [x, 0, z]
+ block.size = [w,d,h]
+ block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY']
+ block.rbShapeBoundType = Blender.Object.RBShapes['BOX']
+
+
+ for row in Aplan[2]:#row=[xstart,xend,z,h]
+ #currently, radial geometry is disabled for physics blocks setup
+ if radialized:
+ if slope: r1 = dims['t']*sin(row[2]*PI/(dims['t']*2))
+ else: r1 = row[2]
+
+ else: r1 = 1
+
+ divs = fill(row[0], row[1], settings['w'], settings['wm'], settings['wv'])
+ for i in range(len(divs)-1):
+ block = scn.objects.new(blockmesh, 'block')
+ block.loc = [(divs[i]+divs[i+1])/2, 0, row[2]]
+ block.size = [(divs[i + 1] - divs[i]) - settings['g'], (settings['d'] + rndd()*settings['dv'])*(1-settings['t']*((row[3]-dims['b'])/(dims['t'] - dims['b']))), row[3]]
+ block.rbFlags = Blender.Object.RBFlags['BOUNDS'] | Blender.Object.RBFlags['ACTOR'] | Blender.Object.RBFlags['DYNAMIC'] | Blender.Object.RBFlags['RIGIDBODY']
+ block.rbShapeBoundType = Blender.Object.RBShapes['BOX']
+
+ return None'''
+#end dead code...
+
+ # all the edge blocks, redacted
+ #AllBlocks = [[x,z,w,h,d,[corner offset matrix]],[etc.]]
+
+ #loop through each row, adding the normal old blocks
+ for rowidx in range(len(rows)):#row = row object
+ rows[rowidx].FillBlocks()
+
+ AllBlocks = []
+
+ # If the wall is set to merge blocks, check all the blocks to see if you can merge any
+#seems to only merge vertical, should do horizontal too
+ if bigBlock:
+ for rowidx in range(len(rows)-1):
+ if radialized:
+ if slope: r1 = dims['t']*sin(abs(rows[rowidx].z)*PI/(dims['t']*2))
+ else: r1 = abs(rows[rowidx].z)
+ else: r1 = 1
+
+ Tollerance = settings['g']/r1
+ idxThis = len(rows[rowidx].BlocksNorm[:]) - 1
+ idxThat = len(rows[rowidx+1].BlocksNorm[:]) - 1
+
+ while True:
+ # end loop when either array idx wraps
+ if idxThis < 0 or idxThat < 0: break
+
+ blockThis = rows[rowidx].BlocksNorm[idxThis]
+ blockThat = rows[rowidx+1].BlocksNorm[idxThat]
+
+#seems to only merge vertical, should do horizontal too...
+ cx, cz, cw, ch, cd = blockThis[:5]
+ ox, oz, ow, oh, od = blockThat[:5]
+
+ if (abs(cw - ow) < Tollerance) and (abs(cx - ox) < Tollerance) :
+ if cw > ow: BlockW = ow
+ else: BlockW = cw
+
+ AllBlocks.append([(cx+ox)/2,(cz+oz+(oh-ch)/2)/2,BlockW,abs(cz-oz)+(ch+oh)/2,(cd+od)/2,None])
+
+ rows[rowidx].BlocksNorm.pop(idxThis)
+ rows[rowidx+1].BlocksNorm.pop(idxThat)
+ idxThis -= 1
+ idxThat -= 1
+
+ elif cx > ox: idxThis -= 1
+ else: idxThat -= 1
+
+ #
+ #
+ # Add blocks to create a "shelf/platform".
+ # Does not account for openings (crosses gaps - which is a good thing)
+ if shelfExt:
+ SetGrtOff = settings['g']/2 # half grout for block size modifier
+
+ # Use wall block settings for shelf
+ SetBW = settings['w']
+ SetBWVar = settings['wv']
+ SetBWMin = settings['wm']
+ SetBH = settings['h']
+
+ # Shelf area settings
+ ShelfLft = shelfSpecs['x']
+ ShelfBtm = shelfSpecs['z']
+ ShelfEnd = ShelfLft + shelfSpecs['w']
+ ShelfTop = ShelfBtm + shelfSpecs['h']
+ ShelfThk = shelfSpecs['d'] * 2 # use double-depth due to offsets to position at cursor.
+
+ # Use "corners" to adjust position so not centered on depth.
+ # Facing shelf, at cursor (middle of wall blocks) - this way no gaps between platform and wall face due to wall block depth.
+ wallDepth = settings['d']/2 # offset by wall depth so step depth matches UI setting :)
+ if shelfBack: # place blocks on backside of wall
+ ShelfOffsets = [[0,ShelfThk/2,0],[0,wallDepth,0],[0,ShelfThk/2,0],[0,wallDepth,0],[0,ShelfThk/2,0],[0,wallDepth,0],[0,ShelfThk/2,0],[0,wallDepth,0]]
+ else:
+ ShelfOffsets = [[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0],[0,-wallDepth,0],[0,-ShelfThk/2,0]]
+
+ # Add blocks for each "shelf row" in area
+ while ShelfBtm < ShelfTop:
+
+ # Make blocks for each row - based on rowOb::fillblocks
+ # Does not vary grout.
+ divs = fill(ShelfLft, ShelfEnd, SetBW, SetBWMin, SetBWVar)
+
+ #loop through the row divisions, adding blocks for each one
+ for i in range(len(divs)-1):
+ ThisBlockx = (divs[i]+divs[i+1])/2
+ ThisBlockw = divs[i+1]-divs[i]-SetGrtOff
+
+ AllBlocks.append([ThisBlockx, ShelfBtm, ThisBlockw, SetBH, ShelfThk, ShelfOffsets])
+
+ ShelfBtm += SetBH + SetGrtOff # moving up to next row...
+ #
+ #
+ # Add blocks to create "steps".
+ # Does not account for openings (crosses gaps - which is a good thing)
+ if stepMod:
+ SetGrtOff = settings['g']/2 # half grout for block size modifier
+
+ # Vary block width by wall block variations.
+ SetWidVar = settings['wv']
+ SetWidMin = settings['wm']
+
+ StepXMod = stepSpecs['t'] # width of step/tread, also sets basic block size.
+ StepZMod = stepSpecs['v']
+
+ StepLft = stepSpecs['x']
+ StepRt = stepSpecs['x'] + stepSpecs['w']
+ StepBtm = stepSpecs['z'] + StepZMod/2 # Start offset for centered blocks
+ StepWide = stepSpecs['w']
+ StepTop = StepBtm + stepSpecs['h']
+ StepThk = stepSpecs['d'] * 2 # use double-depth due to offsets to position at cursor.
+
+ # Use "corners" to adjust steps so not centered on depth.
+ # Facing steps, at cursor (middle of wall blocks) - this way no gaps between steps and wall face due to wall block depth.
+ # Also, will work fine as stand-alone if not used with wall (try block depth 0 and see what happens).
+ wallDepth = settings['d']/2 # offset by wall depth so step depth matches UI setting :)
+ if stepBack: # place blocks on backside of wall
+ StepOffsets = [[0,StepThk/2,0],[0,wallDepth,0],[0,StepThk/2,0],[0,wallDepth,0],[0,StepThk/2,0],[0,wallDepth,0],[0,StepThk/2,0],[0,wallDepth,0]]
+ else:
+ StepOffsets = [[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0],[0,-wallDepth,0],[0,-StepThk/2,0]]
+
+ # Add steps for each "step row" in area (neg width is interesting but prevented)
+ while StepBtm < StepTop and StepWide > 0:
+
+ # Make blocks for each step row - based on rowOb::fillblocks
+ # Does not vary grout.
+
+ if stepOnly: # "cantilevered steps"
+ if stepLeft:
+ stepStart = StepRt - StepXMod
+ else:
+ stepStart = StepLft
+
+ AllBlocks.append([stepStart, StepBtm, StepXMod, StepZMod, StepThk, StepOffsets])
+ else:
+ divs = fill(StepLft, StepRt, StepXMod, SetWidMin, SetWidVar)
+
+ #loop through the row divisions, adding blocks for each one
+ for i in range(len(divs)-1):
+ ThisBlockx = (divs[i]+divs[i+1])/2
+ ThisBlockw = divs[i+1]-divs[i]-SetGrtOff
+
+ AllBlocks.append([ThisBlockx, StepBtm, ThisBlockw, StepZMod, StepThk, StepOffsets])
+
+ StepBtm += StepZMod + SetGrtOff # moving up to next row...
+ StepWide -= StepXMod # reduce step width
+
+ # adjust side limit depending on direction of steps
+ if stepLeft:
+ StepRt -= StepXMod # move in from right
+ else:
+ StepLft += StepXMod # move in from left
+
+
+ #Copy all the blocks out of the rows
+ for row in rows:
+ AllBlocks += row.BlocksEdge
+ AllBlocks += row.BlocksNorm
+
+ #This loop makes individual blocks for each block specified in the plan
+ for block in AllBlocks:
+ x,z,w,h,d,corners = block
+ if radialized:
+ if slope: r1 = dims['t']*sin(z*PI/(dims['t']*2))
+ else: r1 = z
+ else: r1 = 1
+
+ geom = MakeABlock([x-w/2, x+w/2, z-h/2, z+h/2, -d/2, d/2], settings['sdv'], len(vlist), corners, None, settings['b']+rndd()*settings['bv'], r1)
+ vlist += geom[0]
+ flist += geom[1]
+
+
+ # This loop makes Arches for every opening specified in the plan.
+ for hole in Aplan[1]:
+ # lower arch stones
+ if hole.vl > 0 and hole.rtl > (settings['g'] + settings['hm']):#make lower arch blocks
+ archGeneration(hole, vlist, flist, -1)
+
+ #top arch stones
+ if hole.v > 0 and hole.rt > (settings['g'] + settings['hm']):#make upper arch blocks
+ archGeneration(hole, vlist, flist, 1)
+ #
+
+ #Warp all the points for domed stonework
+ if slope:
+ for i,vert in enumerate(vlist):
+ vlist[i] = [vert[0],(dims['t']+vert[1])*cos(vert[2]*PI/(2*dims['t'])),(dims['t']+vert[1])*sin(vert[2]*PI/(2*dims['t']))]
+
+ #Warp all the points for radial stonework
+ if radialized:
+ for i,vert in enumerate(vlist):
+ vlist[i] = [vert[2]*cos(vert[0]),vert[2]*sin(vert[0]),vert[1]]
+
+ return vlist, flist
+
+
+#The main function
+def createWall(radial, curve, openings, mergeBlox, shelf, shelfSide,
+ steps, stepDir, stepBare, stepSide):
+ __doc__ = """\
+ Call all the funcitons you need to make a wall, return the verts and faces.
+ """
+ global radialized
+ global slope
+ global openingSpecs
+ global bigBlock
+ global shelfExt
+ global stepMod
+ global stepLeft
+ global shelfBack
+ global stepOnly
+ global stepBack
+
+ # set all the working variables from passed parameters
+
+ radialized = radial
+ slope = curve
+ openingSpecs = openings
+ bigBlock = mergeBlox
+ shelfExt = shelf
+ stepMod = steps
+ stepLeft = stepDir
+ shelfBack = shelfSide
+ stepOnly = stepBare
+ stepBack = stepSide
+
+ asketch = sketch()
+ aplan = plan(asketch, 0)
+
+ return build(aplan)
+
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/Wallfactory.py b/release/scripts/addons_contrib/add_mesh_building_objects/Wallfactory.py
new file mode 100644
index 0000000..8c7fb93
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/Wallfactory.py
@@ -0,0 +1,647 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you may 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
+#
+# or go online at: http://www.gnu.org/licenses/ to view license options.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+#
+# This module contains the UI definition, display, and processing (create mesh)
+# functions.
+#
+# The routines to generate the vertices for the wall are found in the "Blocks" module.
+#
+
+
+import bpy
+import mathutils
+from bpy.props import *
+from add_mesh_building_objects.Blocks import *
+#from add_mesh_walls.preset_utils import *
+
+
+#
+class add_mesh_wallb(bpy.types.Operator):
+ """Add a wall mesh"""
+ bl_idname = "mesh.wall_add"
+ bl_label = "Add A Masonry Wall"
+ bl_options = {'REGISTER', 'UNDO'} # removes object, does not reset to "last" modification.
+ bl_description = "adds a block wall"
+
+ # UI items - API for properties - User accessable variables...
+# not all options are via UI, and some operations just don't work yet.
+
+ # only create object when True
+ # False allows modifying several parameters without creating object
+ ConstructTog = BoolProperty(name="Construct",
+ description="Generate the object",
+ default = True)
+
+# need to modify so radial makes a tower (normal); want "flat" setting to make disk (alternate)
+ # make the wall circular - if not sloped it's a flat disc
+ RadialTog = BoolProperty(name="Radial",
+ description="Make masonry radial",
+ default = False)
+
+ # curve the wall - if radial creates dome.
+ SlopeTog = BoolProperty(name="Curved",
+ description="Make masonry sloped, or curved",
+ default = False)
+
+#need to review defaults and limits for all of these UI objects.
+
+ # wall area/size
+ WallStart = FloatProperty(name="Start",
+ description="Left side, or start angle",
+ default=-10.0, min=-100, max=100.0)
+ WallEnd = FloatProperty(name="End",
+ description="Right side, or end angle",
+ default=10.0, min=0.0, max=100.0)
+ WallBottom = FloatProperty(name="Bottom",
+ description="Lower height or radius",
+ default=0.0, min=-100, max=100)
+ WallTop = FloatProperty(name="Top",
+ description="Upper height or radius",
+ default=15.0, min=0.0, max=100.0)
+ EdgeOffset = FloatProperty(name="Edging",
+ description="Block staggering on wall sides",
+ default=0.6, min=0.0, max=100.0)
+
+ # block sizing
+ Width = FloatProperty(name="Width",
+ description="Average width of each block",
+ default=1.5, min=0.01, max=100.0)
+ WidthVariance = FloatProperty(name="Variance",
+ description="Random variance of block width",
+ default=0.5, min=0.0, max=100.0)
+ WidthMinimum = FloatProperty(name="Minimum",
+ description="Absolute minimum block width",
+ default=0.5, min=0.01, max=100.0)
+ Height = FloatProperty(name="Height",
+ description="Average Height of each block",
+ default=0.7, min=0.01, max=100.0)
+ HeightVariance = FloatProperty(name="Variance",
+ description="Random variance of block Height",
+ default=0.3, min=0.0, max=100.0)
+ HeightMinimum = FloatProperty(name="Minimum",
+ description="Absolute minimum block Height",
+ default=0.25, min=0.01, max=100.0)
+ Depth = FloatProperty(name="Depth",
+ description="Average Depth of each block",
+ default=2.0, min=0.01, max=100.0)
+ DepthVariance = FloatProperty(name="Variance",
+ description="Random variance of block Depth",
+ default=0.1, min=0.0, max=100.0)
+ DepthMinimum = FloatProperty(name="Minimum",
+ description="Absolute minimum block Depth",
+ default=1.0, min=0.01, max=100.0)
+ MergeBlock = BoolProperty(name="Merge Blocks",
+ description="Make big blocks (merge closely adjoining blocks)",
+ default = False)
+
+ # edging for blocks
+ Grout = FloatProperty(name="Thickness",
+ description="Distance between blocks",
+ default=0.1, min=-10.0, max=10.0)
+ GroutVariance = FloatProperty(name="Variance",
+ description="Random variance of block Grout",
+ default=0.03, min=0.0, max=100.0)
+ GroutDepth = FloatProperty(name="Depth",
+ description="Grout Depth from the face of the blocks",
+ default=0.1, min=0.0001, max=10.0)
+ GroutDepthVariance = FloatProperty(name="Variance",
+ description="Random variance of block Grout Depth",
+ default=0.03, min=0.0, max=100.0)
+ GroutEdge = BoolProperty(name="Edging",
+ description="Grout perimiter",
+ default = False)
+
+ #properties for openings
+ Opening1Tog = BoolProperty(name="Opening(s)",description="Make windows or doors", default = True)
+ Opening1Width = FloatProperty(name="Width",
+ description="The Width of opening 1",
+ default=2.5, min=0.01, max=100.0)
+ Opening1Height = FloatProperty(name="Height",
+ description="The Height of opening 1",
+ default=3.5, min=0.01, max=100.0)
+ Opening1X = FloatProperty(name="Indent",
+ description="The x position or spacing of opening 1",
+ default=5.0, min=-100, max=100.0)
+ Opening1Z = FloatProperty(name="Bottom",
+ description="The z position of opening 1",
+ default=5.0, min=-100, max=100.0)
+ Opening1Repeat = BoolProperty(name="Repeat",
+ description="make multiple openings, with spacing X1",
+ default=False)
+ Opening1TopArchTog = BoolProperty(name="Top Arch",
+ description="Add an arch to the top of opening 1",
+ default=True)
+ Opening1TopArch = FloatProperty(name="Curve",
+ description="Height of the arch on the top of the opening",
+ default=2.5, min=0.001, max=100.0)
+ Opening1TopArchThickness = FloatProperty(name="Thickness",
+ description="Thickness of the arch on the top of the opening",
+ default=0.75, min=0.001, max=100.0)
+ Opening1BtmArchTog = BoolProperty(name="Bottom Arch",
+ description="Add an arch to the bottom of opening 1",
+ default=False)
+ Opening1BtmArch = FloatProperty(name="Curve",
+ description="Height of the arch on the bottom of the opening",
+ default=1.0, min=0.01, max=100.0)
+ Opening1BtmArchThickness = FloatProperty(name="Thickness",
+ description="Thickness of the arch on the bottom of the opening",
+ default=0.5, min=0.01, max=100.0)
+ Opening1Bevel = FloatProperty(name="Bevel",
+ description="Angle block face",
+ default=0.25, min=-10.0, max=10.0)
+
+
+ # openings on top of wall.
+ CrenelTog = BoolProperty(name="Crenels",
+ description="Make openings along top of wall",
+ default = False)
+ CrenelXP = FloatProperty(name="Width %",
+ description="Gap width in wall based % of wall width",
+ default=0.25, min=0.10, max=1.0)
+ CrenelZP = FloatProperty(name="Height %",
+ description="Crenel Height as % of wall height",
+ default=0.10, min=0.10, max=1.0)
+
+
+ # narrow openings in wall.
+#need to prevent overlap with arch openings - though inversion is an interesting effect.
+ SlotTog = BoolProperty(name="Slots",
+ description="Make narrow openings in wall",
+ default = False)
+ SlotRpt = BoolProperty(name="Repeat",
+ description="Repeat slots along wall",
+ default = False)
+ SlotWdg = BoolProperty(name="Wedged (n/a)",
+ description="Bevel edges of slots",
+ default = False)
+ SlotX = FloatProperty(name="Indent",
+ description="The x position or spacing of slots",
+ default=0.0, min=-100, max=100.0)
+ SlotGap = FloatProperty(name="Opening",
+ description="The opening size of slots",
+ default=0.5, min=0.10, max=100.0)
+ SlotV = BoolProperty(name="Vertical",
+ description="Vertical slots",
+ default = True)
+ SlotVH = FloatProperty(name="Height",
+ description="Height of vertical slot",
+ default=3.5, min=0.10, max=100.0)
+ SlotVBtm = FloatProperty(name="Bottom",
+ description="Z position for slot",
+ default=5.00, min=-100.0, max=100.0)
+ SlotH = BoolProperty(name="Horizontal",
+ description="Horizontal slots",
+ default = False)
+ SlotHW = FloatProperty(name="Width",
+ description="Width of horizontal slot",
+ default=2.5, min=0.10, max=100.0)
+#this should offset from VBtm... maybe make a % like crenels?
+ SlotHBtm = FloatProperty(name="Bottom",
+ description="Z position for horizontal slot",
+ default=5.50, min=-100.0, max=100.0)
+
+
+ #properties for shelf (extend blocks in area)
+ ShelfTog = BoolProperty(name="Shelf",description="Add blocks in area by depth to make shelf/platform", default = False)
+ ShelfX = FloatProperty(name="Left",
+ description="The x position of Shelf",
+ default=-5.00, min=-100, max=100.0)
+ ShelfZ = FloatProperty(name="Bottom",
+ description="The z position of Shelf",
+ default=10.0, min=-100, max=100.0)
+ ShelfH = FloatProperty(name="Height",
+ description="The Height of Shelf area",
+ default=1.0, min=0.01, max=100.0)
+ ShelfW = FloatProperty(name="Width",
+ description="The Width of shelf area",
+ default=5.0, min=0.01, max=100.0)
+ ShelfD = FloatProperty(name="Depth",
+ description="Depth of each block for shelf (from cursor + 1/2 wall depth)",
+ default=2.0, min=0.01, max=100.0)
+ ShelfBack = BoolProperty(name="Backside",description="Shelf on backside of wall", default = False)
+
+
+ #properties for steps (extend blocks in area, progressive width)
+ StepTog = BoolProperty(name="Steps",description="Add blocks in area by depth with progressive width to make steps", default = False)
+ StepX = FloatProperty(name="Left",
+ description="The x position of steps",
+ default=-9.00, min=-100, max=100.0)
+ StepZ = FloatProperty(name="Bottom",
+ description="The z position of steps",
+ default=0.0, min=-100, max=100.0)
+ StepH = FloatProperty(name="Height",
+ description="The Height of step area",
+ default=10.0, min=0.01, max=100.0)
+ StepW = FloatProperty(name="Width",
+ description="The Width of step area",
+ default=8.0, min=0.01, max=100.0)
+ StepD = FloatProperty(name="Depth",
+ description="Depth of each block for steps (from cursor + 1/2 wall depth)",
+ default=1.0, min=0.01, max=100.0)
+ StepV = FloatProperty(name="Riser",
+ description="Height of each step",
+ default=0.70, min=0.01, max=100.0)
+ StepT = FloatProperty(name="Tread",
+ description="Width of each step",
+ default=1.0, min=0.01, max=100.0)
+ StepLeft = BoolProperty(name="High Left",description="Height left; else Height right", default = False)
+ StepOnly = BoolProperty(name="No Blocks",description="Steps only, no supporting blocks", default = False)
+ StepBack = BoolProperty(name="Backside",description="Steps on backside of wall", default = False)
+
+##
+##
+#####
+# Show the UI - expose the properties.
+#####
+##
+##
+ # Display the toolbox options
+
+ def draw(self, context):
+
+ layout = self.layout
+
+ box = layout.box()
+ box.prop(self, 'ConstructTog')
+
+# Wall area (size/position)
+ box = layout.box()
+ box.label(text='Wall Size (area)')
+ box.prop(self, 'WallStart')
+ box.prop(self, 'WallEnd')
+ box.prop(self, 'WallBottom')
+ box.prop(self, 'WallTop')
+ box.prop(self, 'EdgeOffset')
+
+# Wall block sizing
+ box = layout.box()
+ box.label(text='Block Sizing')
+ box.prop(self, 'MergeBlock')
+#add checkbox for "fixed" sizing (ignore variance) a.k.a. bricks.
+ box.prop(self, 'Width')
+ box.prop(self, 'WidthVariance')
+ box.prop(self, 'WidthMinimum')
+ box.prop(self, 'Height')
+ box.prop(self, 'HeightVariance')
+ box.prop(self, 'HeightMinimum')
+ box.prop(self, 'Depth')
+ box.prop(self, 'DepthVariance')
+ box.prop(self, 'DepthMinimum')
+
+# grout settings
+ box = layout.box()
+ bl_label = "Grout"
+ box.label(text='Grout')
+ box.prop(self, 'Grout')
+ box.prop(self, 'GroutVariance')
+ box.prop(self, 'GroutDepth')
+ box.prop(self, 'GroutDepthVariance')
+# box.prop(self, 'GroutEdge')
+
+# Wall shape modifiers
+ box = layout.box()
+ box.label(text='Wall Shape')
+ box.prop(self, 'RadialTog')
+ box.prop(self, 'SlopeTog')
+
+# Openings (doors, windows; arched)
+ box = layout.box()
+ box.prop(self, 'Opening1Tog')
+ if self.properties.Opening1Tog:
+ box.prop(self, 'Opening1Width')
+ box.prop(self, 'Opening1Height')
+ box.prop(self, 'Opening1X')
+ box.prop(self, 'Opening1Z')
+ box.prop(self, 'Opening1Bevel')
+ box.prop(self, 'Opening1Repeat')
+ box.prop(self, 'Opening1TopArchTog')
+ box.prop(self, 'Opening1TopArch')
+ box.prop(self, 'Opening1TopArchThickness')
+ box.prop(self, 'Opening1BtmArchTog')
+ box.prop(self, 'Opening1BtmArch')
+ box.prop(self, 'Opening1BtmArchThickness')
+
+# Slots (narrow openings)
+ box = layout.box()
+ box.prop(self, 'SlotTog')
+ if self.properties.SlotTog:
+# box.prop(self, 'SlotWdg')
+ box.prop(self, 'SlotX')
+ box.prop(self, 'SlotGap')
+ box.prop(self, 'SlotRpt')
+ box.prop(self, 'SlotV')
+ box.prop(self, 'SlotVH')
+ box.prop(self, 'SlotVBtm')
+ box.prop(self, 'SlotH')
+ box.prop(self, 'SlotHW')
+ box.prop(self, 'SlotHBtm')
+
+# Crenels, gaps in top of wall
+ box = layout.box()
+ box.prop(self, 'CrenelTog')
+ if self.properties.CrenelTog:
+ box.prop(self, 'CrenelXP')
+ box.prop(self, 'CrenelZP')
+
+# Shelfing (protrusions)
+ box = layout.box()
+ box.prop(self, 'ShelfTog')
+ if self.properties.ShelfTog:
+ box.prop(self, 'ShelfX')
+ box.prop(self, 'ShelfZ')
+ box.prop(self, 'ShelfH')
+ box.prop(self, 'ShelfW')
+ box.prop(self, 'ShelfD')
+ box.prop(self, 'ShelfBack')
+
+# Steps
+ box = layout.box()
+ box.prop(self, 'StepTog')
+ if self.properties.StepTog:
+ box.prop(self, 'StepX')
+ box.prop(self, 'StepZ')
+ box.prop(self, 'StepH')
+ box.prop(self, 'StepW')
+ box.prop(self, 'StepD')
+ box.prop(self, 'StepV')
+ box.prop(self, 'StepT')
+ box.prop(self, 'StepLeft')
+ box.prop(self, 'StepOnly')
+ box.prop(self, 'StepBack')
+
+##
+#####
+# Respond to UI - get the properties set by user.
+#####
+##
+ # Check and process UI settings to generate masonry
+
+ def execute(self, context):
+
+ global radialized
+ global slope
+ global openingSpecs
+ global bigBlock
+ global shelfExt
+ global stepMod
+ global stepLeft
+ global shelfBack
+ global stepOnly
+ global stepBack
+
+ # Create the wall when enabled (skip regen iterations when off)
+ if not self.properties.ConstructTog: return {'FINISHED'}
+
+ #enter the settings for the wall dimensions (area)
+# start can't be zero - min/max don't matter [if max less than end] but zero don't workie.
+# start can't exceed end.
+ if not self.properties.WallStart or self.properties.WallStart >= self.properties.WallEnd:
+ self.properties.WallStart = NOTZERO # Reset UI if input out of bounds...
+
+ dims['s'] = self.properties.WallStart
+ dims['e'] = self.properties.WallEnd
+ dims['b'] = self.properties.WallBottom
+ dims['t'] = self.properties.WallTop
+
+ settings['eoff'] = self.properties.EdgeOffset
+
+ #retrieve the settings for the wall block properties
+ settings['w'] = self.properties.Width
+ settings['wv'] = self.properties.WidthVariance
+ settings['wm'] = self.properties.WidthMinimum
+ if not radialized: settings['sdv'] = settings['w']
+ else: settings['sdv'] = 0.12
+
+ settings['h'] = self.properties.Height
+ settings['hv'] = self.properties.HeightVariance
+ settings['hm'] = self.properties.HeightMinimum
+
+ settings['d'] = self.properties.Depth
+ settings['dv'] = self.properties.DepthVariance
+ settings['dm'] = self.properties.DepthMinimum
+
+ if self.properties.MergeBlock:
+ bigBlock = 1
+ else: bigBlock = 0
+
+ settings['g'] = self.properties.Grout
+ settings['gv'] = self.properties.GroutVariance
+ settings['gd'] = self.properties.GroutDepth
+ settings['gdv'] = self.properties.GroutDepthVariance
+
+ if self.properties.GroutEdge: settings['ge'] = 1
+ else: settings['ge'] = 0
+
+ # set wall shape modifiers
+ if self.properties.RadialTog:
+ radialized = 1
+#eliminate to allow user control for start/completion?
+ dims['s'] = 0.0 # complete radial
+ if dims['e'] > PI*2: dims['e'] = PI*2 # max end for circle
+ if dims['b'] < settings['g']: dims['b'] = settings['g'] # min bottom for grout extension
+ else: radialized = 0
+
+ if self.properties.SlopeTog: slope = 1
+ else: slope = 0
+
+
+ shelfExt = 0
+ shelfBack = 0
+
+ # Add shelf if enabled
+ if self.properties.ShelfTog:
+ shelfExt = 1
+ shelfSpecs['h'] = self.properties.ShelfH
+ shelfSpecs['w'] = self.properties.ShelfW
+ shelfSpecs['d'] = self.properties.ShelfD
+ shelfSpecs['x'] = self.properties.ShelfX
+ shelfSpecs['z'] = self.properties.ShelfZ
+
+ if self.properties.ShelfBack:
+ shelfBack = 1
+
+
+ stepMod = 0
+ stepLeft = 0
+ stepOnly = 0
+ stepBack = 0
+
+ # Make steps if enabled
+ if self.properties.StepTog:
+ stepMod = 1
+ stepSpecs['x'] = self.properties.StepX
+ stepSpecs['z'] = self.properties.StepZ
+ stepSpecs['h'] = self.properties.StepH
+ stepSpecs['w'] = self.properties.StepW
+ stepSpecs['d'] = self.properties.StepD
+ stepSpecs['v'] = self.properties.StepV
+ stepSpecs['t'] = self.properties.StepT
+
+ if self.properties.StepLeft:
+ stepLeft = 1
+
+ if self.properties.StepOnly:
+ stepOnly = 1
+
+ if self.properties.StepBack:
+ stepBack = 1
+
+
+ #enter the settings for the openings
+#when openings overlap they create inverse stonework - interesting but not the desired effect :)
+#if opening width == indent*2 the edge blocks fail (row of blocks cross opening) - bug.
+ openingSpecs = []
+ openingIdx = 0 # track opening array references for multiple uses
+
+ # general openings with arch options - can be windows or doors.
+ if self.properties.Opening1Tog:
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ openingSpecs[openingIdx]['w'] = self.properties.Opening1Width
+ openingSpecs[openingIdx]['h'] = self.properties.Opening1Height
+ openingSpecs[openingIdx]['x'] = self.properties.Opening1X
+ openingSpecs[openingIdx]['z'] = self.properties.Opening1Z
+ openingSpecs[openingIdx]['rp'] = self.properties.Opening1Repeat
+
+ if self.properties.Opening1TopArchTog:
+ openingSpecs[openingIdx]['v'] = self.properties.Opening1TopArch
+ openingSpecs[openingIdx]['t'] = self.properties.Opening1TopArchThickness
+
+ if self.properties.Opening1BtmArchTog:
+ openingSpecs[openingIdx]['vl'] = self.properties.Opening1BtmArch
+ openingSpecs[openingIdx]['tl'] = self.properties.Opening1BtmArchThickness
+
+ openingSpecs[openingIdx]['b'] = self.properties.Opening1Bevel
+
+ openingIdx += 1 # count window/door/arch openings
+
+ # Slots (narrow openings)
+ if self.properties.SlotTog:
+
+ if self.properties.SlotV: # vertical slots
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':0, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ openingSpecs[openingIdx]['w'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['h'] = self.properties.SlotVH
+ openingSpecs[openingIdx]['x'] = self.properties.SlotX
+ openingSpecs[openingIdx]['z'] = self.properties.SlotVBtm
+ openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt
+
+ # make them pointy...
+ openingSpecs[openingIdx]['v'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['t'] = self.properties.SlotGap/2
+ openingSpecs[openingIdx]['vl'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['tl'] = self.properties.SlotGap/2
+
+ openingIdx += 1 # count vertical slot openings
+
+# need to handle overlap of H and V slots...
+
+ if self.properties.SlotH: # Horizontal slots
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':0, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ openingSpecs[openingIdx]['w'] = self.properties.SlotHW
+ openingSpecs[openingIdx]['h'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['x'] = self.properties.SlotX
+ openingSpecs[openingIdx]['z'] = self.properties.SlotHBtm
+#horizontal repeat isn't same spacing as vertical...
+ openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt
+
+ # make them pointy...
+# want arc to go sideways... maybe wedge will be sufficient and can skip horiz arcs.
+# openingSpecs[openingIdx]['v'] = self.properties.SlotGap
+# openingSpecs[openingIdx]['t'] = self.properties.SlotGap/2
+# openingSpecs[openingIdx]['vl'] = self.properties.SlotGap
+# openingSpecs[openingIdx]['tl'] = self.properties.SlotGap/2
+
+ openingIdx += 1 # count horizontal slot openings
+
+
+ # Crenellations (top row openings)
+ if self.properties.CrenelTog:
+
+# add bottom arch option?
+# perhaps a repeat toggle...
+# if crenel opening overlaps with arch opening it fills with blocks...
+
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ wallW = self.properties.WallEnd - self.properties.WallStart
+ crenelW = wallW*self.properties.CrenelXP # Width % opening.
+
+ wallH = self.properties.WallTop - self.properties.WallBottom
+ crenelH = wallH*self.properties.CrenelZP # % proportional height.
+
+ openingSpecs[openingIdx]['w'] = crenelW
+ openingSpecs[openingIdx]['h'] = crenelH
+
+ # calculate the spacing between openings.
+ # this isn't the absolute start (left), it's opening center offset relative to cursor (space between openings)...
+ openingSpecs[openingIdx]['x'] = crenelW*2-1 # assume standard spacing
+
+ if not radialized: # normal wall?
+ # set indent 0 (center) if opening is 50% or more of wall width, no repeat.
+ if crenelW*2 >= wallW:
+ openingSpecs[openingIdx]['x'] = 0
+ openingSpecs[openingIdx]['rp'] = 0
+
+ openingSpecs[openingIdx]['z'] = self.properties.WallTop - (crenelH/2) # set bottom of opening (center of hole)
+
+ openingIdx += 1 # count crenel openings
+
+ #
+ # Process the user settings to generate a wall
+ #
+ # generate the list of vertices for the wall...
+ verts_array, faces_array = createWall(radialized, slope, openingSpecs, bigBlock,
+ shelfExt, shelfBack, stepMod, stepLeft, stepOnly, stepBack)
+
+ # Create new mesh
+ mesh = bpy.data.meshes.new("Wall")
+
+ # Make a mesh from a list of verts/edges/faces.
+ mesh.from_pydata(verts_array, [], faces_array)
+
+ scene = context.scene
+
+ # Deselect all objects.
+ bpy.ops.object.select_all(action='DESELECT')
+
+ mesh.update()
+
+ ob_new = bpy.data.objects.new("Wall", mesh)
+ scene.objects.link(ob_new)
+# leave this out to prevent 'Tab key" going into edit mode :):):)
+# Use rmb click to select and still modify.
+ scene.objects.active = ob_new
+ ob_new.select = True
+
+ ob_new.location = tuple(context.scene.cursor_location)
+ ob_new.rotation_quaternion = [1.0,0.0,0.0,0.0]
+
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/__init__.py b/release/scripts/addons_contrib/add_mesh_building_objects/__init__.py
new file mode 100644
index 0000000..19623aa
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/__init__.py
@@ -0,0 +1,99 @@
+# ##### 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 LICENSE BLOCK #####
+# Contributed to by
+# SAYproductions, meta-androcto, jambay, brikbot#
+
+bl_info = {
+ "name": "Building Objects",
+ "author": "Multiple Authors",
+ "version": (0, 2),
+ "blender": (2, 64, 0),
+ "location": "View3D > Add > Mesh > Cad Objects",
+ "description": "Add building object types",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=32711",
+ "category": "Add Mesh"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(add_mesh_balcony)
+ imp.reload(add_mesh_sove)
+ imp.reload(add_mesh_window)
+ imp.reload(add_mesh_beam_builder)
+ imp.reload(Wallfactory)
+ imp.reload(stairbuilder)
+
+else:
+ from . import add_mesh_balcony
+ from . import add_mesh_sove
+ from . import add_mesh_window
+ from . import add_mesh_beam_builder
+ from . import Wallfactory
+ from . import stairbuilder
+
+import bpy
+
+
+class INFO_MT_mesh_objects_add(bpy.types.Menu):
+ # Define the "mesh objects" menu
+ bl_idname = "INFO_MT_cad_objects_add"
+ bl_label = "Building Objects"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.menu("INFO_MT_mesh_beambuilder_add",
+ text="Beam Builder")
+ layout.operator("mesh.add_say3d_balcony",
+ text="Balcony")
+ layout.operator("mesh.add_say3d_sove",
+ text="Sove")
+ layout.operator("mesh.add_say3d_pencere2",
+ text="Window")
+ layout.operator("mesh.wall_add",
+ text="Wall Factory")
+ layout.operator("mesh.stairs",
+ text="Stair Builder")
+
+
+# Register all operators and panels
+
+# Define "Extras" menu
+def menu_func(self, context):
+ self.layout.menu("INFO_MT_cad_objects_add", icon="PLUGIN")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ # Add "Extras" menu to the "Add Mesh" menu
+ bpy.types.INFO_MT_mesh_add.append(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ # Remove "Extras" menu from the "Add Mesh" menu.
+ bpy.types.INFO_MT_mesh_add.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_balcony.py b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_balcony.py
new file mode 100644
index 0000000..4648849
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_balcony.py
@@ -0,0 +1,492 @@
+'''
+bl_info = {
+ "name": "Balcony",
+ "author": "SayPRODUCTIONS",
+ "version": (1, 0),
+ "blender": (2, 59, 0),
+ "api": 33333,
+ "location": "View3D > Add > Mesh > Say3D",
+ "description": "Balcony olusturma",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Mesh"}
+'''
+import bpy, bmesh
+from bpy.props import *
+from bpy_extras.object_utils import object_data_add
+from mathutils import Vector
+import operator
+import os
+from math import pi, sin, cos, sqrt, atan
+def MAT(AD,R,G,B):
+ if AD not in bpy.data.materials:
+ mtl=bpy.data.materials.new(AD)
+ mtl.diffuse_color = ([R,G,B])
+ mtl.diffuse_shader = 'LAMBERT'
+ mtl.diffuse_intensity = 1.0
+ else:
+ mtl=bpy.data.materials[AD]
+ return mtl
+def Prs(s,v):
+ if v=='1':
+ s.lst=3
+ s.ls0='1';s.by0= 80;s.bk0=20;s.bf0=4;s.fh0=3;s.fd0=2;s.f00=16;s.f01=12;s.f02=12;s.f03=12
+ s.ls1='3';s.my1= 4;s.mg1= 4
+ s.ls2='4';s.kt2="2";s.ky2= 5;s.kk2=5
+ if v=='2':
+ s.lst=5
+ s.ls0='1';s.by0= 15;s.bk0=20;s.bf0=0
+ s.ls1='2';s.py1= 60;s.pd1=10
+ s.ls2='1';s.by2= 15;s.bk2=20;s.bf2=0
+ s.ls3='3';s.my3= 4;s.mg3= 4
+ s.ls4='4';s.kt4="2";s.ky4= 5;s.kk4=5
+ if v=='3':
+ s.lst=3
+ s.ls0='1';s.by0= 40;s.bk0=10;s.bf0=0
+ s.ls1='5';s.cy1= 56
+ s.ls2='4';s.kt2="1";s.ky2= 0;s.kk2=4
+ if v=='4':
+ s.lst=2
+ s.ls0='1';s.by0= 30;s.bk0=20;s.bf0=0
+ s.ls1='3';s.my1= 4;s.mg1= 4
+ if v=='5':
+ s.lst=2
+ s.ls0='1';s.by0= 27;s.bk0=20;s.bf0=2;s.fh0=3;s.fd0=2;s.f00=7;s.f01=7
+ s.ls1='3';s.my1= 4;s.mg1= 4
+ if v=='6':
+ s.lst=6
+ s.ls0='1';s.by0= 50;s.bk0=20;s.bf0=2;s.fh0=3;s.fd0=2;s.f00=12;s.f01=20
+ s.ls1='3';s.my1= 4;s.mg1= 4
+ s.ls2='4';s.kt2="2";s.ky2= 5;s.kk2=4
+ s.ls3='4';s.kt3="2";s.ky3= 5;s.kk3=4
+ s.ls4='4';s.kt4="2";s.ky4= 5;s.kk4=4
+ s.ls5='4';s.kt5="2";s.ky5= 5;s.kk5=5
+def EXT(PR,vr,fc,lz,mz,rz):
+ n=len(vr)
+ m=len(PR)
+ if lz==0:
+ for P in PR:vr.append([-mz,P[0],P[1]])
+ else:
+ for P in PR:vr.append([ P[0]-mz, lz,P[1]])
+ for P in PR:vr.append([ P[0]-mz,P[0],P[1]])
+ if rz==0:
+ for P in PR:vr.append([ mz,P[0],P[1]])
+ else:
+ for P in PR:vr.append([-P[0]+mz,P[0],P[1]])
+ for P in PR:vr.append([-P[0]+mz, rz,P[1]])
+ if lz==0 and rz==0:l=1
+ elif lz==0 and rz> 0:l=2
+ elif lz> 0 and rz==0:l=2
+ elif lz> 0 and rz> 0:l=3
+ for j in range(0,l):
+ for i in range(0,m):
+ a=j*m
+ if i==m-1:fc.append([a+i+n,a+0+n+0,a+0+n+0+m,a+i+n+m])
+ else: fc.append([a+i+n,a+i+n+1,a+i+n+1+m,a+i+n+m])
+def add_object(s,context):
+ fc=[];vr=[];SM=[]
+ Bal=[];Par=[];Mer=[];Krm=[];Glass=[];Dos=[]
+ blok=[]# [ Tip ][ Balcony [ Joint_Gap ] [ Bulwark ] [ Marble ] [ Chrome ] [ Glass ]
+ blok.append([s.ls0,[s.by0,s.bk0,s.bf0,s.fh0,s.fd0,[s.f00,s.f01,s.f02,s.f03,s.f04,s.f05,s.f06,s.f07]],[s.py0,s.pd0],[s.my0,s.mg0],[s.kt0,s.ky0,s.kk0],[s.cy0]])
+ blok.append([s.ls1,[s.by1,s.bk1,s.bf1,s.fh1,s.fd1,[s.f10,s.f11,s.f12,s.f13,s.f14,s.f15,s.f16,s.f17]],[s.py1,s.pd1],[s.my1,s.mg1],[s.kt1,s.ky1,s.kk1],[s.cy1]])
+ blok.append([s.ls2,[s.by2,s.bk2,s.bf2,s.fh2,s.fd2,[s.f20,s.f21,s.f22,s.f23,s.f24,s.f25,s.f26,s.f27]],[s.py2,s.pd2],[s.my2,s.mg2],[s.kt2,s.ky2,s.kk2],[s.cy2]])
+ blok.append([s.ls3,[s.by3,s.bk3,s.bf3,s.fh3,s.fd3,[s.f30,s.f31,s.f32,s.f33,s.f34,s.f35,s.f36,s.f37]],[s.py3,s.pd3],[s.my3,s.mg3],[s.kt3,s.ky3,s.kk3],[s.cy3]])
+ blok.append([s.ls4,[s.by4,s.bk4,s.bf4,s.fh4,s.fd4,[s.f40,s.f41,s.f42,s.f43,s.f44,s.f45,s.f46,s.f47]],[s.py4,s.pd4],[s.my4,s.mg4],[s.kt4,s.ky4,s.kk4],[s.cy4]])
+ blok.append([s.ls5,[s.by5,s.bk5,s.bf5,s.fh5,s.fd5,[s.f50,s.f51,s.f52,s.f53,s.f54,s.f55,s.f56,s.f57]],[s.py5,s.pd5],[s.my5,s.mg5],[s.kt5,s.ky5,s.kk5],[s.cy5]])
+ blok.append([s.ls6,[s.by6,s.bk6,s.bf6,s.fh6,s.fd6,[s.f60,s.f61,s.f62,s.f63,s.f64,s.f65,s.f66,s.f67]],[s.py6,s.pd6],[s.my6,s.mg6],[s.kt6,s.ky6,s.kk6],[s.cy6]])
+ blok.append([s.ls7,[s.by7,s.bk7,s.bf7,s.fh7,s.fd7,[s.f70,s.f71,s.f72,s.f73,s.f74,s.f75,s.f76,s.f77]],[s.py7,s.pd7],[s.my7,s.mg7],[s.kt7,s.ky7,s.kk7],[s.cy7]])
+
+ h=-s.dds/100;dh=h+s.dhg/100;du=s.duz/100;
+ lz=s.luz/100;mz=s.muz/200;rz=s.ruz/100
+ dg=-((blok[0][1][1]-s.ddg)/100)
+ if h<0:#Pavement
+ if lz==0 and rz==0:
+ vr=[[-mz,du,h],[ mz,du, h],[-mz,dg, h],[ mz,dg, h],[-mz,dg, 0],
+ [ mz,dg,0],[-mz, 0,dh],[ mz, 0,dh],[-mz,du,dh],[ mz,du,dh]]
+ fc=[[0,1,3,2],[2,3,5,4],[6,7,9,8]];Dos=[0,1,2]
+ if lz==0 and rz >0:
+ vr=[[-mz, du,h],[ mz-dg,du, h],[-mz, dg, h],[ mz-dg,dg, h],[-mz, dg, 0],
+ [ mz-dg,dg,0],[-mz, 0, dh],[ mz-dg, 0,dh],[-mz, du,dh],[ mz-dg,du,dh],[ mz-dg,du,0]]
+ fc=[[0,1,3,2],[2,3,5,4],[6,7,9,8],[3,1,10,5]];Dos=[0,1,2,3]
+ if lz >0 and rz==0:
+ vr=[[-mz+dg,du,h],[ mz, du, h],[-mz+dg,dg, h],[ mz, dg, h],[-mz+dg,dg, 0],
+ [ mz, dg,0],[-mz+dg, 0,dh],[ mz, 0,dh],[-mz+dg,du,dh],[ mz, du,dh],[-mz+dg,du,0]]
+ fc=[[0,1,3,2],[2,3,5,4],[6,7,9,8],[0,2,4,10]];Dos=[0,1,2,3]
+ if lz >0 and rz >0:
+ vr=[[-mz+dg,dg,0],[mz-dg,dg,0],[-mz+dg,dg, h],[mz-dg,dg, h],[-mz+dg,du, h],[mz-dg,du, h],
+ [-mz+dg,du,0],[mz-dg,du,0],[-mz, 0,dh],[mz, 0,dh],[-mz, du,dh],[mz, du,dh]]
+ fc=[[1,0,2,3],[3,2,4,5],[6,4,2,0],[3,5,7,1],[8,9,11,10]];Dos=[0,1,2,3,4]
+ else:
+ vr=[[-mz, 0, h],[mz, 0, h],[-mz,du, h],[mz,du, h],
+ [-mz,du,dh],[mz,du,dh],[-mz, 0,dh],[mz, 0,dh]]
+ fc=[[1,0,2,3],[5,4,6,7]];Dos=[0,1]
+ z=0
+ for i in range(s.lst):
+ if blok[i][0]=='1':#Balcony
+ k1=blok[i][1][1]/100;h =blok[i][1][0]/100
+ fh=blok[i][1][3]/100;fd=blok[i][1][4]/100
+ PR=[[-k1,z],[0,z],[0,z+h],[-k1,z+h]]
+ z+=h;fz=z
+ for f in range(blok[i][1][2]):
+ fz-=blok[i][1][5][f]/100
+ PR.append([-k1, fz ]);PR.append([-k1+fd,fz ])
+ PR.append([-k1+fd,fz-fh]);PR.append([-k1, fz-fh])
+ fz-=fh
+ BB=len(fc)
+ EXT(PR,vr,fc,lz,mz,rz)
+ BE=len(fc)
+ for F in range(BB,BE):Bal.append(F)
+ if blok[i][0]=='2':#Bulwark
+ k1=blok[i][2][1]/100;h=blok[i][2][0]/100
+ PR=[[-k1,z],[0,z],[0,z+h],[-k1,z+h]]
+ z+=h
+ BB=len(fc)
+ EXT(PR,vr,fc,lz,mz,rz)
+ BE=len(fc)
+ for F in range(BB,BE):Par.append(F)
+ if blok[i][0]=='3':#Marble
+ k1=blok[0][1][1]/100;k2=blok[i][3][1]/100;h=blok[i][3][0]/100
+ PR=[[-k1-k2,z],[k2,z],[k2,z+h],[-k1-k2,z+h]]
+ z+=h
+ BB=len(fc)
+ EXT(PR,vr,fc,lz,mz,rz)
+ BE=len(fc)
+ for F in range(BB,BE):Mer.append(F)
+ if blok[i][0]=='4':#Chrome
+ k1=blok[0][1][1]/200;k2=blok[i][4][2]/200;h=blok[i][4][1]/100
+ if blok[i][4][0]=="1":#Duz
+ z+=h
+ PR=[[-k1-k2,z],[-k1+k2,z],[-k1+k2,z+k2*2],[-k1-k2,z+k2*2]]
+ z+=k2*2
+ else:#Round
+ PR=[];z+=h+k2
+ for a in range(24):
+ x=-k1+cos(a*pi/12)*k2;y=z+sin(a*pi/12)*k2
+ PR.append([x,y])
+ z+=k2
+ BB=len(fc)
+ EXT(PR,vr,fc,lz,mz,rz)
+ BE=len(fc)
+ for F in range(BB,BE):Krm.append(F)
+ if blok[i][4][0]=="2":
+ for F in range(BB,BE):SM.append(F)
+ if blok[i][0]=='5':#Glass
+ k1=blok[0][1][1]/200;h=blok[i][5][0]/100
+ PR=[[-k1-0.001,z],[-k1+0.001,z],[-k1+0.001,z+h],[-k1-0.001,z+h]]
+ z+=h;BB=len(fc);n=len(vr)
+ fc.append([n+1,n,n+3,n+2])
+ EXT(PR,vr,fc,lz,mz,rz)
+ n=len(vr)
+ fc.append([n-2,n-1,n-4,n-3])
+ BE=len(fc)
+ for F in range(BB,BE):Glass.append(F)
+#OBJE -----------------------------------------------------------
+ mesh = bpy.data.meshes.new(name='Balcony')
+ mesh.from_pydata(vr,[],fc)
+ for i in SM:
+ mesh.polygons[i].use_smooth = 1
+ mesh.materials.append(MAT('Balcony', 0.66,0.64,0.72))
+ mesh.materials.append(MAT('Bulwark',0.46,0.44,0.52))
+ mesh.materials.append(MAT('Marble', 0.90,0.85,0.80))
+ mesh.materials.append(MAT('Chrome', 0.50,0.55,0.60))
+ mesh.materials.append(MAT('Glass', 0.50,0.80,1.00))
+ mesh.materials.append(MAT('Pavement', 1.00,1.00,1.00))
+
+ for i in Bal:mesh.polygons[i].material_index = 0
+ for i in Par:mesh.polygons[i].material_index = 1
+ for i in Mer:mesh.polygons[i].material_index = 2
+ for i in Krm:mesh.polygons[i].material_index = 3
+ for i in Glass:mesh.polygons[i].material_index = 4
+ for i in Dos:mesh.polygons[i].material_index = 5
+
+ mesh.update(calc_edges=True)
+ object_data_add(context, mesh, operator=None)
+ if bpy.context.mode != 'EDIT_MESH':
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+#----------------------------------------------------------------
+class OBJECT_OT_add_balcony(bpy.types.Operator):
+ bl_idname = "mesh.add_say3d_balcony"
+ bl_label = "Balcony"
+ bl_description = "Balcony Olustur"
+ bl_options = {'REGISTER', 'UNDO'}
+ prs = EnumProperty(items = (("1","Joint_Gap", ""),
+ ("2","Bulwark", ""),
+ ("3","Glass", ""),
+ ("4","Marquise", ""),
+ ("5","Eaves", ""),
+ ("6","Railing","")))
+ son=prs
+ lst=IntProperty( min=1,max= 8,default= 3)
+ luz=IntProperty(name='<',min=0,max=1000,default=100)
+ muz=IntProperty( min=0,max=1000,default=200)
+ ruz=IntProperty(name='>',min=0,max=1000,default=100)
+
+ duz=IntProperty(min= 1,max=500,default=100,description="Pavement Width")
+ dhg=IntProperty(min= 1,max= 50,default= 17,description="Pavement Height")
+ dds=IntProperty(min=-50,max= 50,default= 10,description="Pavement Height")
+ ddg=IntProperty(min= 0,max= 50,default= 10,description="Pavement Width")
+ #Tip
+ ls0=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="1")
+ #Balcony
+ by0=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk0=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf0=IntProperty(name='Joint_Gap', min=0,max= 8,default= 4,description='Joint_Gap' )
+ fh0=IntProperty(min=1,max= 10,default= 3);fd0=IntProperty(min=1,max= 10,default= 2)
+ f00=IntProperty(min=1,max=200,default=16);f01=IntProperty(min=1,max=200,default=12)
+ f02=IntProperty(min=1,max=200,default=12);f03=IntProperty(min=1,max=200,default=12)
+ f04=IntProperty(min=1,max=200,default= 3);f05=IntProperty(min=1,max=200,default= 3)
+ f06=IntProperty(min=1,max=200,default= 3);f07=IntProperty(min=1,max=200,default= 3)
+ #Bulwark
+ py0=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd0=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my0=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg0=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt0=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky0=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk0=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy0=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls1=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="3")
+ #Balcony
+ by1=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk1=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf1=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh1=IntProperty(min=1,max= 10,default=3);fd1=IntProperty(min=1,max= 10,default=2)
+ f10=IntProperty(min=1,max=200,default=3);f11=IntProperty(min=1,max=200,default=3)
+ f12=IntProperty(min=1,max=200,default=3);f13=IntProperty(min=1,max=200,default=3)
+ f14=IntProperty(min=1,max=200,default=3);f15=IntProperty(min=1,max=200,default=3)
+ f16=IntProperty(min=1,max=200,default=3);f17=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py1=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd1=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my1=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg1=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt1=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky1=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk1=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy1=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls2=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="4")
+ #Balcony
+ by2=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk2=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf2=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh2=IntProperty(min=1,max= 10,default=3);fd2=IntProperty(min=1,max= 10,default=2)
+ f20=IntProperty(min=1,max=200,default=3);f21=IntProperty(min=1,max=200,default=3)
+ f22=IntProperty(min=1,max=200,default=3);f23=IntProperty(min=1,max=200,default=3)
+ f24=IntProperty(min=1,max=200,default=3);f25=IntProperty(min=1,max=200,default=3)
+ f26=IntProperty(min=1,max=200,default=3);f27=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py2=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd2=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my2=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg2=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt2=EnumProperty(items=(("1","Square",""),("2","Round","")),default="2")
+ ky2=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk2=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy2=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls3=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="4")
+ #Balcony
+ by3=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk3=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf3=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh3=IntProperty(min=1,max= 10,default=3);fd3=IntProperty(min=1,max= 10,default=2)
+ f30=IntProperty(min=1,max=200,default=3);f31=IntProperty(min=1,max=200,default=3)
+ f32=IntProperty(min=1,max=200,default=3);f33=IntProperty(min=1,max=200,default=3)
+ f34=IntProperty(min=1,max=200,default=3);f35=IntProperty(min=1,max=200,default=3)
+ f36=IntProperty(min=1,max=200,default=3);f37=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py3=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd3=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my3=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg3=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt3=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky3=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk3=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy3=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls4=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="4")
+ #Balcony
+ by4=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk4=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf4=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh4=IntProperty(min=1,max= 10,default=3);fd4=IntProperty(min=1,max= 10,default=2)
+ f40=IntProperty(min=1,max=200,default=3);f41=IntProperty(min=1,max=200,default=3)
+ f42=IntProperty(min=1,max=200,default=3);f43=IntProperty(min=1,max=200,default=3)
+ f44=IntProperty(min=1,max=200,default=3);f45=IntProperty(min=1,max=200,default=3)
+ f46=IntProperty(min=1,max=200,default=3);f47=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py4=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd4=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my4=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg4=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt4=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky4=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk4=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy4=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls5=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="4")
+ #Balcony
+ by5=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk5=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf5=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh5=IntProperty(min=1,max= 10,default=3);fd5=IntProperty(min=1,max= 10,default=2)
+ f50=IntProperty(min=1,max=200,default=3);f51=IntProperty(min=1,max=200,default=3)
+ f52=IntProperty(min=1,max=200,default=3);f53=IntProperty(min=1,max=200,default=3)
+ f54=IntProperty(min=1,max=200,default=3);f55=IntProperty(min=1,max=200,default=3)
+ f56=IntProperty(min=1,max=200,default=3);f57=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py5=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd5=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my5=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg5=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt5=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky5=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk5=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy5=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls6=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="4")
+ #Balcony
+ by6=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk6=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf6=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh6=IntProperty(min=1,max= 10,default=3);fd6=IntProperty(min=1,max= 10,default=2)
+ f60=IntProperty(min=1,max=200,default=3);f61=IntProperty(min=1,max=200,default=3)
+ f62=IntProperty(min=1,max=200,default=3);f63=IntProperty(min=1,max=200,default=3)
+ f64=IntProperty(min=1,max=200,default=3);f65=IntProperty(min=1,max=200,default=3)
+ f66=IntProperty(min=1,max=200,default=3);f67=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py6=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd6=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my6=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg6=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt6=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky6=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk6=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy6=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ #Tip
+ ls7=EnumProperty(items=(("1","Balcony",""),("2","Bulwark",""),("3","Marble",""),("4","Chrome",""),("5","Glass","")),default="4")
+ #Balcony
+ by7=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ bk7=IntProperty(name='Thickness', min=1,max= 50,default=20,description='Thickness' )
+ bf7=IntProperty(name='Joint_Gap', min=0,max= 8,default= 0,description='Joint_Gap' )
+ fh7=IntProperty(min=1,max= 10,default=3);fd7=IntProperty(min=1,max= 10,default=2)
+ f70=IntProperty(min=1,max=200,default=3);f71=IntProperty(min=1,max=200,default=3)
+ f72=IntProperty(min=1,max=200,default=3);f73=IntProperty(min=1,max=200,default=3)
+ f74=IntProperty(min=1,max=200,default=3);f75=IntProperty(min=1,max=200,default=3)
+ f76=IntProperty(min=1,max=200,default=3);f77=IntProperty(min=1,max=200,default=3)
+ #Bulwark
+ py7=IntProperty(name='Elevation',min=1,max=200,default=80,description='Elevation')
+ pd7=IntProperty(name='Thickness', min=1,max= 50,default=10,description='Thickness' )
+ #Marble
+ my7=IntProperty(name='Elevation',min=1,max=50,default=4,description='Elevation')
+ mg7=IntProperty(name='maxWidth', min=0,max=20,default=4,description='maxWidth' )
+ #Chrome
+ kt7=EnumProperty(items=(("1","Square",""),("2","Round","")))
+ ky7=IntProperty(min=0,max=50,default=5,description='CutOut' )
+ kk7=IntProperty(min=1,max=20,default=5,description='Thickness')
+ #Glass
+ cy7=IntProperty(name='Elevation',min=1,max=100,default=20,description='Elevation')
+ #--------------------------------------------------------------
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self,'prs', text="Wall Style")
+ layout.prop(self,'lst', text="Add Level")
+ row=layout.row()
+ row.label(text="Wall Length & Width")
+ row=layout.row()
+ row.prop(self,'luz')
+ row.prop(self,'muz')
+ row.prop(self,'ruz')
+
+ layout.label('Pavement XYZ')
+ row=layout.row();row.prop(self,'duz');row.prop(self,'dhg')
+ row=layout.row();row.prop(self,'dds');row.prop(self,'ddg')
+
+ ls=[];lf=[]
+ ls.append(self.ls0);lf.append(self.bf0)
+ ls.append(self.ls1);lf.append(self.bf1)
+ ls.append(self.ls2);lf.append(self.bf2)
+ ls.append(self.ls3);lf.append(self.bf3)
+ ls.append(self.ls4);lf.append(self.bf4)
+ ls.append(self.ls5);lf.append(self.bf5)
+ ls.append(self.ls6);lf.append(self.bf6)
+ ls.append(self.ls7);lf.append(self.bf7)
+ for i in range(self.lst-1,-1,-1):
+ box=layout.box()
+ box.prop(self,'ls'+str(i))
+ if ls[i]=='1':#Balcony
+ box.prop(self,'by'+str(i))
+ box.prop(self,'bk'+str(i))
+ box.prop(self,'bf'+str(i))
+ if lf[i]>0:
+ row=box.row()
+ row.prop(self,'fh'+str(i))
+ row.prop(self,'fd'+str(i))
+ for f in range(lf[i]):
+ box.prop(self,'f'+str(i)+str(f))
+ if ls[i]=='2':#Bulwark
+ box.prop(self,'py'+str(i))
+ box.prop(self,'pd'+str(i))
+ if ls[i]=='3':#Marble
+ row=box.row()
+ row.prop(self,'my'+str(i))
+ row.prop(self,'mg'+str(i))
+ if ls[i]=='4':#Chrome
+ row=box.row()
+ row.prop(self,'kt'+str(i))
+ row.prop(self,'ky'+str(i))
+ row.prop(self,'kk'+str(i))
+ if ls[i]=='5':#Glass
+ box.prop(self,'cy'+str(i))
+ def execute(self, context):
+ if self.son!=self.prs:
+ Prs(self,self.prs)
+ self.son=self.prs
+ add_object(self,context)
+ return {'FINISHED'}
+# Registration
+def add_object_button(self, context):
+ self.layout.operator(
+ OBJECT_OT_add_balcony.bl_idname,
+ text="Balcony",
+ icon="SNAP_FACE")
+def register():
+ bpy.utils.register_class(OBJECT_OT_add_balcony)
+ bpy.types.INFO_MT_mesh_add.append(add_object_button)
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_add_balcony)
+ bpy.types.INFO_MT_mesh_add.remove(add_object_button)
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_beam_builder.py b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_beam_builder.py
new file mode 100644
index 0000000..446009e
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_beam_builder.py
@@ -0,0 +1,1477 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Beam Builder",
+ "description": "Creates various types of beams.",
+ "author": "revolt_randy",
+ "version": (0, 1, 3),
+ "blender": (2, 60, 0),
+ "location": "View3D > Add > Mesh",
+ "warning": "Currently under development.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Add_Mesh/BeamBuilder",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=26911",
+ "category": "Add Mesh"}
+
+#
+# Creates a rectangluar, 'C', 'L', 'T', or 'I' - type beam.
+#
+
+# Version History
+#
+# v0.1 - Script only generates a multi-sided mesh object,
+# initial release for testing. 3/12/11
+#
+# v0.1.1 - Added 'C'-type beam, updated to work with
+# api r35499. 3/13/11
+#
+# v0.1.2 - Totally changed the way beams are created, size
+# is now calculated based off width, length, & height
+# (x,y,z). Added ability to taper beams as well.
+# Add 'L' - type beam
+# Add 'T' - type beam
+# Add 'I' - type beam
+#
+# v0.1.3 - Updated to work with api r41226, including using object_utils.py -
+# part of blender's bpy_extras scripts. This is what handles
+# the 'align to view', 'location', & 'rotation' options in the
+# toolshelf when creating mesh. Added wiki & tracker url. Fixed
+# a few bugs & fixed some debug prints that were still printing
+# to console.
+#
+
+import bpy
+
+from bpy_extras import object_utils
+
+
+def create_mesh (self, context, name, verts, faces, debug):
+ # Creates mesh and object
+ # name - name of object to create
+ # verts - a list of vertex tuples
+ # faces - a list of face tuples
+ # debug - debug flag - if true prints data to console
+
+ # Actually create mesh and object
+ mesh = bpy.data.meshes.new(name)
+
+ # add verts & faces to object
+ mesh.from_pydata(verts, [], faces)
+ mesh.update(calc_edges=True)
+
+ if debug:
+ print("create_mesh function called and finished")
+
+ return object_utils.object_data_add(context, mesh, operator=self)
+
+
+def recalc_normals(debug):
+ # Recalculate normals
+ # parts of this script creates faces that are backwards or
+ # have thier normals facing the wrong way, so recalculate them
+ # debug - debug flag - if true prints data to console
+
+
+ if bpy.context.mode != 'EDIT_MESH':
+ bpy.ops.object.editmode_toggle()
+ # Recalcuate normals
+ bpy.ops.mesh.normals_make_consistent()
+ bpy.ops.object.editmode_toggle()
+ if debug:
+ print("\nObjectMode")
+ else:
+ bpy.ops.mesh.normals_make_consistent()
+ if debug:
+ print("\nEditMode")
+
+ return
+
+
+def create_end_faces(verts_list, thick, debug):
+ # Create End Faces
+ # verts_list - list of vertices
+ # thick - if true object is hollow, so construct loop of end faces
+ # instead of a solid end face
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # faces - a list of tuples defining the end faces
+
+ faces = []
+
+ num_of_verts = len(verts_list)
+ faces_temp = []
+
+ sides = 4 # sides - number of sides to mesh *added because of code re-write
+
+ if thick:
+ # has thickness, so build end faces
+ num_of_verts = int(num_of_verts / 2)
+
+ # Create a list of the front faces
+ for index in range(num_of_verts):
+ if index == (num_of_verts - 1):
+ faces_temp.append(verts_list[index])
+ faces_temp.append(verts_list[index-index])
+ faces_temp.append(verts_list[index+1])
+ faces_temp.append(verts_list[index*2+1])
+ else:
+ faces_temp.append(verts_list[index])
+ faces_temp.append(verts_list[index+1])
+ faces_temp.append(verts_list[index+num_of_verts+1])
+ faces_temp.append(verts_list[index+num_of_verts])
+
+ faces.append(tuple(faces_temp))
+ faces_temp = []
+ else:
+ #this code may not be needed, depends upon rewrite...
+ if sides > 4:
+ # more than 4 sides, so replace last list item (center vert) with first list item
+ # for looping and building faces
+ center_vert = verts_list[num_of_verts - 1]
+ verts_list[num_of_verts - 1] = verts_list[0]
+
+ for index in range(int(num_of_verts - 1)):
+ faces_temp.append(verts_list[index])
+ faces_temp.append(verts_list[index + 1])
+ faces_temp.append(center_vert)
+ faces.append(tuple(faces_temp))
+ faces_temp = []
+
+ else:
+ # create 1 end face
+ for index in range(num_of_verts):
+ faces_temp.append(verts_list[index])
+ faces.append(tuple(faces_temp))
+
+ # print debug info to console
+ if debug:
+ print("\ncreate_end_faces Function Starts")
+ print("\n End Face Verts list :", verts_list)
+ print("\n End Faces: ", faces)
+ print("\ncreate_end_faces Function Ends\n\n")
+
+ return faces
+
+
+def create_side_faces(front_verts, back_verts, debug):
+ # Create side faces - simple bridging of front_verts & back_verts vertices,
+ # both front_verts & back_verts must be ordered in same direction
+ # with respect to y-axis
+ # front_verts - a list of front face vertices
+ # back_verts - a list of back face vertices
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # new_faces - a list of tuples defining the faces bridged between front_verts & back_verts
+
+ # Number of faces to create
+ num_of_faces = (len(front_verts))
+ new_faces = []
+
+ # add first value to end of lists for looping
+ front_verts.append(front_verts[0])
+ back_verts.append(back_verts[0])
+
+ # Build the new_faces list with tuples defining each face
+ for index in range(num_of_faces):
+ facestemp = (front_verts[index], front_verts[index+1], back_verts[index+1], back_verts[index])
+ new_faces.append(facestemp)
+
+ # print debug info to console
+ if debug:
+ print("\ncreate_side_faces Function Starts")
+ print("\n Number of faces to create: ", num_of_faces)
+ print("\n New faces :", new_faces)
+ print("\ncreate_side_faces Function Ends\n\n")
+
+ return new_faces
+
+
+def calc_end_verts(size, y_off, thick, debug):
+ # Calculates vertex location for end of mesh
+
+ # size - tuple of x,y,z dimensions of mesh to create
+ # y_off - y offset, lets function know where to create verts on y-axis
+ # thick - thickness, if not zero this is the thickness of a hollow mesh
+ # with the inner faces inset from size dimensions
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # verts - a list of tuples of the x,y,z location of each vertex
+
+ verts = []
+
+ if debug:
+ print ("\ncalc_end_verts Function Starts\n")
+ print("\nsize = ",size)
+ print("y_off = ",y_off)
+
+ # Create vertices by calculation
+ x_pos = 0 + size[0]/2
+ z_pos = 0 + size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ x_pos = 0 - size[0]/2
+ z_pos = 0 + size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ x_pos = 0 - size[0]/2
+ z_pos = 0 - size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ x_pos = 0 + size[0]/2
+ z_pos = 0 - size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ if thick:
+ # has thickness, so calculate inside vertices
+ #### not too sure about this, but it does work the way the
+ #### solidify modifier works, so leaving as is for now
+ x_pos = size[0] - (thick * 2)
+ z_pos = size[2] - (thick * 2)
+ size = (x_pos, y_off, z_pos)
+
+ # Create vertices by calculation
+ x_pos = 0 + size[0]/2
+ z_pos = 0 + size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ x_pos = 0 - size[0]/2
+ z_pos = 0 + size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ x_pos = 0 - size[0]/2
+ z_pos = 0 - size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ x_pos = 0 + size[0]/2
+ z_pos = 0 - size[2]/2
+ verts.append((x_pos, y_off, z_pos))
+
+ if debug:
+ print ("verts :", verts)
+ print ("\ncalc_end_verts Function Ends.\n\n")
+
+ return verts
+
+
+def adjust_c_beam_verts(verts, taper, debug):
+ # Adjusts verts produced to correct c beam shape
+ # verts - a list of tuples of vertex locations for one end of beam
+ # taper - % to taper outside verts by
+ # debug - if true values are printed to console for debugging
+
+ # returns:
+ # verts - the corrected list of tuples of the adjustec vertex locations
+
+ # This function corrects vertex locations to properly shape the
+ # beam, because creating a c beam uses the same code as the
+ # create_rectangular_beam function does. Therefore the 5th & 6th
+ # vertice's z location needs to be changed to match the 1st & 2nd
+ # vertice's z location.
+
+ vert_orig = verts[0]
+
+ # get 3rd value, the z location
+ vert_z = vert_orig[2]
+ # get 1st value, the x location, for vert taper calcs
+ vert_x = vert_orig[0]
+
+ # vert_z has the z value to be used in the 5th & 6th verts
+ # get value of 5th vert
+ vert_temp = verts[4]
+
+
+
+ # calculate the amount of taper, updating vert_x
+ # with the new value calculated.
+ vert_x = calc_taper(vert_orig[0], vert_temp[0], taper)
+
+ vert_new = (vert_x,vert_temp[1],vert_z)
+
+ if debug:
+ print ("\nadjust_c_beam_verts function starting")
+ print ("vert_orig = ",vert_orig[0])
+ print ("vert_x = ",vert_x)
+ print("vert_temp =",vert_temp)
+ print("vert_new =",vert_new)
+
+ # update 5th vert with new value
+ verts[4] = vert_new
+
+ vert_orig = verts[1]
+
+ # get 3rd value, the z location
+ vert_z = vert_orig[2]
+ # get 1st value, the x location, for vert taper calcs
+ vert_x = vert_orig[0]
+ # vert_z has the z value to be used in the 5th & 6th verts
+ # get value of 5th vert
+ vert_temp = verts[5]
+
+
+
+ # calculate the amount of taper, updating vert_x
+ # with the new value calculated.
+ vert_x = calc_taper(vert_orig[0], vert_temp[0], taper)
+
+ vert_new = (vert_x,vert_temp[1],vert_z)
+
+ if debug:
+ print ("vert_orig = ",vert_orig[0])
+ print ("vert_x = ",vert_x)
+ print("vert_temp =",vert_temp)
+ print("vert_new =",vert_new)
+
+ # update 6th vert with new value
+ verts[5] = vert_new
+
+ if debug:
+ print("\n adjust_c_beam_verts function ending")
+ print("verts =", verts)
+
+ return verts
+
+
+def calc_taper(outer_vert, inner_vert, taper):
+ # Calculate tapered edges of beam - inner vert is moved towards
+ # outer vert based upon percentage value in taper
+ # outer_vert - the outside vertex
+ # inner_vert - the inside vertex to be moved
+ # taper - percentage to move vert
+
+ # returns:
+ # adjusted_vert - the calculated vertex
+
+ #print("outer_vert =",outer_vert,"inner_vert",inner_vert)
+
+ # taper values range from 0 to 100 for UI, but for calculations
+ # this value needs to be flipped, ranging from 100 to 0
+ taper = 100 - taper
+
+ # calcuate taper & adjust vertex
+ vert_delta = inner_vert - outer_vert
+ adjusted_vert = outer_vert + ((vert_delta/100) * taper)
+
+ #print("adjusted_vert =", adjusted_vert)
+ return adjusted_vert
+
+
+def create_rectangular_beam(size, thick, debug):
+ # Creates a rectangular beam mesh object
+ # size - tuple of x,y,z dimensions of box
+ # thick - thickness, if not zero this is the thickness of a hollow
+ # box with inner faces inset from size dimensions
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # verts_final - a list of tuples of the x, y, z, location of each vertice
+ # faces_final - a list of tuples of the vertices that make up each face
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp=[]
+ verts_back_temp=[]
+
+ #calculate y offset from center for front vertices
+ y_off = size[1]/2
+
+
+ # Create front vertices by calculation
+ verts_front_temp = calc_end_verts(size, y_off, thick, debug)
+
+ # re-calculate y offset from center for back vertices
+ y_off = 0 - y_off
+
+ # Create back vertices by calculation
+ verts_back_temp = calc_end_verts(size, y_off, thick, debug)
+
+ # Combine all vertices into a final list of tuples
+ verts_final = verts_front_temp + verts_back_temp
+
+ # Print debug info to console
+ if debug:
+ print("\ncreate_multi_side_box Function Start")
+ print("\n Front vertices :", verts_front_temp)
+ print("\n Back vertices:", verts_back_temp)
+ print("\n All vertices:", verts_final)
+
+ # Create front face
+ faces_front_temp = []
+ verts_front_list = []
+ numofverts = len(verts_front_temp)
+
+ # Build vertex list
+ for index in range(numofverts):
+ verts_front_list.append(index)
+
+ faces_front_temp = create_end_faces(verts_front_list, thick, debug)
+
+ # Create back face
+ faces_back_temp = []
+ verts_back_list = []
+ numofverts = len(verts_back_temp)
+
+ # Build vertex list
+ for index in range(numofverts):
+ verts_back_list.append(index + len(verts_back_temp))
+
+ faces_back_temp = create_end_faces(verts_back_list, thick, debug)
+
+ # Create side faces
+ faces_side_temp = []
+
+ # better code needed here???
+ if thick:
+ # Object has thickness, create list of outside vertices
+ numofverts = len(verts_front_list)
+ verts_front_temp = verts_front_list[0:int(numofverts/2)]
+ verts_back_temp = verts_back_list[0:int(numofverts/2)]
+
+ faces_side_temp = create_side_faces(verts_front_temp, verts_back_temp, debug)
+
+ # Create list of inside vertices
+ verts_front_temp = verts_front_list[int(numofverts/2):numofverts]
+ verts_back_temp = verts_back_list[int(numofverts/2):numofverts]
+
+ faces_side_temp += create_side_faces(verts_front_temp, verts_back_temp, debug)
+ else:
+ # Create list of only outside faces
+ faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
+
+ # Combine all faces
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ # print debug info to console
+ if debug:
+ print("\ncreate_multi_side_box Function")
+ print("\nAll faces :",faces_final)
+ print("\ncreate_multi_side_box Function Ends\n\n")
+
+ return verts_final, faces_final
+
+
+def create_C_beam(size, thick, taper, debug):
+ # Creates a C or U shaped mesh beam object
+ # size - tuple of x,y,z dimensions of beam
+ # thick - thickness, the amount the inner faces will be
+ # inset from size dimensions
+ # taper - % to taper outside edges by
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # verts_final - a list of tuples of the x, y, z, location of each vertice
+ # faces_final - a list of tuples of the vertices that make up each face
+
+ # print debug info to console
+ if debug:
+ print ("\ncreate_C_beam - function called")
+
+ # Get y offset of vertices from center
+ y_off = size[1] / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp=[]
+ verts_back_temp=[]
+
+ # Create front vertices by calculation
+ verts_front_temp = calc_end_verts(size, y_off, thick, debug)
+ # Additional adjustment to the verts needed - 5th & 6th verts
+ # needed because the calc_end_verts creates a rectangluar beam
+ # the insides are inset, for a U channel we need the inside
+ # verts on the open end to match the z-loc of the outside verts
+ verts_front_temp = adjust_c_beam_verts(verts_front_temp, taper, debug)
+
+ # recalculate y_off for other end vertices
+ y_off = 0 - y_off
+
+ # Create back vertices by calculation
+ verts_back_temp = calc_end_verts(size, y_off, thick, debug)
+ # Additional adjustment to the verts needed - the z location
+ verts_back_temp = adjust_c_beam_verts(verts_back_temp, taper, debug)
+
+ # Combine all vertices into a final list of tuples
+ verts_final = verts_front_temp + verts_back_temp
+
+ # Print debug info to console
+ if debug:
+ print("\ncreate_C_beam function start")
+ print("\n Front vertices :", verts_front_temp)
+ print("\n Back vertices:", verts_back_temp)
+ print("\n All vertices:", verts_final)
+
+ # Create front face
+ faces_front_temp = []
+ verts_front_list = []
+ numofverts = len(verts_front_temp)
+
+ # Build vertex list
+ for index in range(numofverts):
+ verts_front_list.append(index)
+ # problem area
+ faces_front_temp = create_end_faces(verts_front_list, thick, debug)
+ # Remove 1st face - only 3 end faces needed
+ faces_front_temp = faces_front_temp[1:4]
+
+ # Create back face
+ faces_back_temp = []
+ verts_back_list = []
+ numofverts = len(verts_back_temp)
+
+ # Build vertex list
+ for index in range(numofverts):
+ verts_back_list.append(index + len(verts_back_temp))
+
+ faces_back_temp = create_end_faces(verts_back_list, thick, debug)
+ # Remove 1st face - only 3 end faces needed
+ faces_back_temp = faces_back_temp[1:4]
+
+ # Create list of outside vertices for the 3 outside faces
+ numofverts = (len(verts_front_list))
+ verts_front_temp = verts_front_list[0:int(numofverts/2)]
+ verts_back_temp = verts_back_list[0:int(numofverts/2)]
+
+ faces_side_temp = create_side_faces(verts_front_temp, verts_back_temp, debug)
+ # create_side_faces creates 4 outside faces, we only want 3
+ # so remove the 1st face
+ faces_side_temp = faces_side_temp[1:]
+
+ # Create list of inside vertices for the 3 inside faces
+ verts_front_temp = verts_front_list[int(numofverts/2):numofverts]
+ verts_back_temp = verts_back_list[int(numofverts/2):numofverts]
+
+ faces_side_temp += create_side_faces(verts_front_temp, verts_back_temp, debug)
+ # create_side_faces creates 4 outside faces, we only want 3
+ # so remove the 1st face
+ faces_side_temp = faces_side_temp[0:3] + faces_side_temp[4:]
+
+ # fill in top two faces
+ faces_side_temp.append((0, 4, 12, 8))
+ faces_side_temp.append((5, 1, 9, 13))
+
+ # Combine all faces
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ # Print debug info to console
+ if debug:
+ print("\ncreate_C_beam function")
+ print("\nAll faces =", faces_final)
+ print("\ncreate_C_beam function ending")
+
+ return verts_final, faces_final
+
+
+def create_L_beam(size, thick, taper, debug):
+ # Creates a L shaped mesh beam object
+ # size - tuple of x,y,z dimensions of beam
+ # thick - thickness, the amount the inner faces will be
+ # inset from size dimensions
+ # taper - % to taper outside edges by
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # verts_final - a list of tuples of the x, y, z, location of each vertice
+ # faces_final - a list of tuples of the vertices that make up each face
+
+ if debug:
+ print("\ncreate_L_beam function starting")
+
+ # Get offset of vertices from center
+ x_off = size[0] / 2
+ y_off = size[1] / 2
+ z_off = size[2] / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp=[]
+ verts_back_temp=[]
+
+ # Create front vertices by calculation
+ verts_front_temp = [(0 - x_off, 0 - y_off, z_off), \
+ (0 - (x_off - thick), 0 - y_off, z_off), \
+ (0 - (x_off - thick), 0 - y_off, 0 - (z_off - thick)), \
+ (x_off, 0 - y_off, 0 - (z_off - thick)), \
+ (x_off, 0 - y_off, 0 - z_off), \
+ (0 - x_off, 0 - y_off, 0 - z_off)]
+
+ # Adjust taper
+ vert_outside = verts_front_temp[0]
+ vert_inside = verts_front_temp[1]
+ verts_front_temp[1] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1],vert_inside[2]]
+
+ vert_outside = verts_front_temp[4]
+ vert_inside = verts_front_temp[3]
+ verts_front_temp[3] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ # Create back vertices by calculation
+ verts_back_temp = [(0 - x_off, y_off, z_off), \
+ (0 - (x_off - thick), y_off, z_off), \
+ (0 - (x_off - thick), y_off, 0 - (z_off - thick)), \
+ (x_off, y_off, 0 - (z_off - thick)), \
+ (x_off, y_off, 0 - z_off), \
+ (0 - x_off, y_off, 0 - z_off)]
+
+ # Adjust taper
+ vert_outside = verts_back_temp[0]
+ vert_inside = verts_back_temp[1]
+ verts_back_temp[1] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1],vert_inside[2]]
+
+ vert_outside = verts_back_temp[4]
+ vert_inside = verts_back_temp[3]
+ verts_back_temp[3] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ verts_final = verts_front_temp + verts_back_temp
+
+ if debug:
+ print("\n verts_front_temp =", verts_front_temp)
+ print("\n verts_back_temp =", verts_back_temp)
+ print("\n verts_final =", verts_final)
+
+ # define end faces, only 4 so just coded
+ faces_front_temp = []
+ faces_back_temp = []
+ faces_side_temp = []
+
+ faces_front_temp = [(0, 1, 2, 5), (2, 3, 4, 5)]
+ faces_back_temp = [(6, 7, 8, 11), (8, 9, 10, 11)]
+
+ verts_front_list = []
+ verts_back_list = []
+ num_of_verts = len(verts_front_temp)
+
+ # build lists of back and front verts for create_side_faces function
+ for index in range(num_of_verts):
+ verts_front_list.append(index)
+ for index in range(num_of_verts):
+ verts_back_list.append(index + 6)
+
+ faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
+
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ if debug:
+ print("\n faces_front_temp =", faces_front_temp)
+ print("\n faces_back_temp =", faces_back_temp)
+ print("\n faces_side_temp =", faces_side_temp)
+ print("\n faces_final =", faces_final)
+ print("\ncreate_L_beam function ending")
+
+ return verts_final, faces_final
+
+
+
+def create_T_beam(size, thick, taper, debug):
+ # Creates a T shaped mesh beam object
+ # size - tuple of x,y,z dimensions of beam
+ # thick - thickness, the amount the inner faces will be
+ # inset from size dimensions
+ # taper - % to taper outside edges by
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # verts_final - a list of tuples of the x, y, z, location of each vertice
+ # faces_final - a list of tuples of the vertices that make up each face
+ debug = 0
+
+ if debug:
+ print("\ncreate_T_beam function starting")
+
+ # Get offset of vertices from center
+ x_off = size[0] / 2
+ y_off = size[1] / 2
+ z_off = size[2] / 2
+ thick_off = thick / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp=[]
+ verts_back_temp=[]
+
+ # Create front vertices by calculation
+ verts_front_temp = [(0 - x_off, 0 - y_off, z_off), \
+ (0 - thick_off, 0 - y_off, z_off), \
+ (thick_off, 0 - y_off, z_off), \
+ (x_off, 0 - y_off, z_off), \
+ (x_off, 0 - y_off, z_off - thick), \
+ (thick_off, 0 - y_off, z_off - thick), \
+ (thick_off, 0 - y_off, 0 - z_off), \
+ (0 - thick_off, 0 - y_off, 0 - z_off), \
+ (0 - thick_off, 0 - y_off, z_off - thick), \
+ (0 - x_off, 0 - y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_front_temp[0]
+ vert_inside = verts_front_temp[9]
+ verts_front_temp[9] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_front_temp[3]
+ vert_inside = verts_front_temp[4]
+ verts_front_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ # Adjust taper of bottom of beam, so 0 the center
+ # now becomes vert_outside, and vert_inside is calculated
+ # 1/2 way towards center
+ vert_outside = (0, 0 - y_off, 0 - z_off)
+ vert_inside = verts_front_temp[6]
+ verts_front_temp[6] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]
+
+ vert_outside = (0, 0 - y_off, 0 - z_off)
+ vert_inside = verts_front_temp[7]
+ verts_front_temp[7] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]
+
+ # Create fack vertices by calculation
+ verts_back_temp = [(0 - x_off, y_off, z_off), \
+ (0 - thick_off, y_off, z_off), \
+ (thick_off, y_off, z_off), \
+ (x_off, y_off, z_off), \
+ (x_off, y_off, z_off - thick), \
+ (thick_off, y_off, z_off - thick), \
+ (thick_off, y_off, 0 - z_off), \
+ (0 - thick_off, y_off, 0 - z_off), \
+ (0 - thick_off, y_off, z_off - thick), \
+ (0 - x_off, y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_back_temp[0]
+ vert_inside = verts_back_temp[9]
+ verts_back_temp[9] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_back_temp[3]
+ vert_inside = verts_back_temp[4]
+ verts_back_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ # Adjust taper of bottom of beam, so 0 the center
+ # now becomes vert_outside, and vert_inside is calculated
+ # 1/2 way towards center
+ vert_outside = (0, 0 - y_off, 0 - z_off)
+ vert_inside = verts_back_temp[6]
+ verts_back_temp[6] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]
+
+ vert_outside = (0, 0 - y_off, 0 - z_off)
+ vert_inside = verts_back_temp[7]
+ verts_back_temp[7] = [(calc_taper(vert_outside[0], vert_inside[0], taper)), vert_inside[1], vert_inside[2]]
+
+ verts_final = verts_front_temp + verts_back_temp
+
+
+ # define end faces, only 8 so just coded
+ faces_front_temp = []
+ faces_back_temp = []
+ faces_side_temp = []
+
+ faces_front_temp = [(0, 1, 8, 9), (1, 2, 5, 8), \
+ (2, 3, 4, 5), (5, 6, 7, 8)]
+
+ faces_back_temp = [(10, 11, 18, 19), (11, 12, 15, 18), \
+ (12, 13, 14, 15), (15, 16, 17, 18)]
+
+ verts_front_list = []
+ verts_back_list = []
+ num_of_verts = len(verts_front_temp)
+
+ # build lists of back and front verts for create_side_faces function
+ for index in range(num_of_verts):
+ verts_front_list.append(index)
+ for index in range(num_of_verts):
+ verts_back_list.append(index + 10)
+
+ faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
+
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ if debug:
+ print("\ncreate_T_beam function ending")
+
+ return verts_final, faces_final
+
+
+def create_I_beam(size, thick, taper, debug):
+ # Creates a T shaped mesh beam object
+ # size - tuple of x,y,z dimensions of beam
+ # thick - thickness, the amount the inner faces will be
+ # inset from size dimensions
+ # taper - % to taper outside edges by
+ # debug - if true prints values from this function to console
+
+ # returns:
+ # verts_final - a list of tuples of the x, y, z, location of each vertice
+ # faces_final - a list of tuples of the vertices that make up each face
+ debug = 0
+
+ if debug:
+ print("\ncreate_I_beam function starting")
+
+ # Get offset of vertices from center
+ x_off = size[0] / 2
+ y_off = size[1] / 2
+ z_off = size[2] / 2
+ thick_off = thick / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp=[]
+ verts_back_temp=[]
+
+ # Create front vertices by calculation
+ verts_front_temp = [(0 - x_off, 0 - y_off, z_off), \
+ (0 - thick_off, 0 - y_off, z_off), \
+ (thick_off, 0 - y_off, z_off), \
+ (x_off, 0 - y_off, z_off), \
+ (x_off, 0 - y_off, z_off - thick), \
+ (thick_off, 0 - y_off, z_off - thick), \
+ (thick_off, 0 - y_off, 0 - z_off + thick), \
+ (x_off, 0 - y_off, 0 - z_off + thick), \
+ (x_off, 0 - y_off, 0 - z_off), \
+ (thick_off, 0 - y_off, 0 - z_off), \
+ (0 - thick_off, 0 - y_off, 0 - z_off), \
+ (0 - x_off, 0 - y_off, 0 - z_off), \
+ (0 - x_off, 0 - y_off, 0 -z_off + thick), \
+ (0 - thick_off, 0 - y_off, 0 - z_off + thick), \
+ (0 - thick_off, 0 - y_off, z_off - thick), \
+ (0 - x_off, 0 - y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_front_temp[0]
+ vert_inside = verts_front_temp[15]
+ verts_front_temp[15] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_front_temp[3]
+ vert_inside = verts_front_temp[4]
+ verts_front_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_front_temp[8]
+ vert_inside = verts_front_temp[7]
+ verts_front_temp[7] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_front_temp[11]
+ vert_inside = verts_front_temp[12]
+ verts_front_temp[12] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ # Create back vertices by calculation
+ verts_back_temp = [(0 - x_off, y_off, z_off), \
+ (0 - thick_off, y_off, z_off), \
+ (thick_off, y_off, z_off), \
+ (x_off, y_off, z_off), \
+ (x_off, y_off, z_off - thick), \
+ (thick_off, y_off, z_off - thick), \
+ (thick_off, y_off, 0 - z_off + thick), \
+ (x_off, y_off, 0 - z_off + thick), \
+ (x_off, y_off, 0 - z_off), \
+ (thick_off, y_off, 0 - z_off), \
+ (0 - thick_off, y_off, 0 - z_off), \
+ (0 - x_off, y_off, 0 - z_off), \
+ (0 - x_off, y_off, 0 -z_off + thick), \
+ (0 - thick_off, y_off, 0 - z_off + thick), \
+ (0 - thick_off, y_off, z_off - thick), \
+ (0 - x_off, y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_back_temp[0]
+ vert_inside = verts_back_temp[15]
+ verts_back_temp[15] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_back_temp[3]
+ vert_inside = verts_back_temp[4]
+ verts_back_temp[4] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_back_temp[8]
+ vert_inside = verts_back_temp[7]
+ verts_back_temp[7] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ vert_outside = verts_back_temp[11]
+ vert_inside = verts_back_temp[12]
+ verts_back_temp[12] = [vert_inside[0], vert_inside[1], (calc_taper(vert_outside[2], vert_inside[2], taper))]
+
+ verts_final = verts_front_temp + verts_back_temp
+
+
+# define end faces, only 7 per end, so just coded
+ faces_front_temp = []
+ faces_back_temp = []
+ faces_side_temp = []
+
+ faces_front_temp = [(0, 1, 14, 15), (1, 2, 5, 14), \
+ (2, 3, 4, 5), (6, 7, 8, 9), \
+ (6, 9, 10, 13), (12, 13, 10, 11), \
+ (5, 6, 13, 14)]
+
+ faces_back_temp = [(16, 17, 30, 31), (17, 18, 21, 30), \
+ (18, 19, 20, 21), (22, 23, 24, 25), \
+ (22, 25, 26, 29), (28, 29, 26, 27), \
+ (21, 22, 29, 30)]
+
+ verts_front_list = []
+ verts_back_list = []
+ num_of_verts = len(verts_front_temp)
+
+ # build lists of back and front verts for create_side_faces function
+ for index in range(num_of_verts):
+ verts_front_list.append(index)
+ for index in range(num_of_verts):
+ verts_back_list.append(index + 16)
+
+ faces_side_temp = create_side_faces(verts_front_list, verts_back_list, debug)
+
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ if debug:
+ print("\ncreate_I_beam function ending")
+
+ return verts_final, faces_final
+
+
+
+# Define "Add_Rectangular_Beam" operator
+########### Needs Work ###############
+class Add_Rectangular_Beam(bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_rectangle_add"
+ bl_label = "Add Rectangluar Beam"
+ bl_description = "Create a Rectangular Beam mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
+ description = "Height (along the z-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 1)
+
+ mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
+ description = "Width (along the x-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = .5)
+
+ mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
+ description = "Length (along y-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 2)
+
+ thick_bool = bpy.props.BoolProperty(name = "Hollow",
+ description = "Create a hollow mesh with a defined thickness",
+ default = True)
+
+ thick = bpy.props.FloatProperty(name = "Thickness",
+ description = "Thickness of hollow mesh",
+ min = 0.01,
+ max = 1,
+ default = 0.1)
+
+ # generic transform props
+ # required by object_utils.py - part of blender's
+ # code and is what handles alignment amongst other
+ # things.
+ view_align = bpy.props.BoolProperty(
+ name="Align to View",
+ default=False
+ )
+ location = bpy.props.FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = bpy.props.FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
+
+ # Define tool parameter layout
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, 'mesh_z_size')
+ layout.prop(self, 'mesh_x_size')
+ layout.prop(self, 'mesh_y_size')
+ layout.prop(self, 'thick_bool')
+ if self.thick_bool:
+ layout.prop(self, 'thick')
+ layout.prop(self, 'view_align')
+ col = layout.column()
+ col.prop(self, 'location')
+ col.prop(self, 'rotation')
+
+ def execute(self, context):
+ # debug flag - True prints debug info to console
+ debug = 0
+
+ size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
+ if self.thick_bool is True:
+ thick = self.thick
+ else:
+ thick = 0
+
+ verts, faces = create_rectangular_beam(size, thick, debug)
+
+ if debug:
+ print("\nCreated Verts:", verts)
+ print("\nCreated Faces:", faces)
+
+ create_mesh(self, context, "Rectangular Beam", verts, faces, debug)
+
+ recalc_normals(debug)
+
+ return {'FINISHED'}
+
+'''
+ def invoke(self, context, event):
+ #self.align_matrix = align_matrix(context)
+ self.execute(context)
+ return {'FINISHED'}
+'''
+
+
+# Define "Add_C_Beam" operator
+class Add_C_Beam(bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_c_beam_add"
+ bl_label = "Add C or U Channel"
+ bl_description = "Create a C or U channel mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+
+ mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
+ description = "Height (along the z-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 1)
+
+ mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
+ description = "Width (along the x-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = .5)
+
+ mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
+ description = "Length (along y-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 2)
+
+ thick = bpy.props.FloatProperty(name = "Thickness",
+ description = "Thickness of mesh",
+ min = 0.01,
+ max = 1,
+ default = 0.1)
+
+ taper = bpy.props.IntProperty(name = "Taper",
+ description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
+ min = 0,
+ max = 100,
+ default = 0)
+
+ type = bpy.props.BoolProperty(name = "U-shaped",
+ description = "Create the beam in a U orientation rather than the defualt C orientation",
+ default = True)
+
+ # generic transform props
+ # required by object_utils.py - part of blender's
+ # code and is what handles alignment amongst other
+ # things.
+ view_align = bpy.props.BoolProperty(
+ name="Align to View",
+ default=False
+ )
+ location = bpy.props.FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = bpy.props.FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
+
+ # Define tool parameter layout
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, 'mesh_z_size')
+ layout.prop(self, 'mesh_x_size')
+ layout.prop(self, 'mesh_y_size')
+ layout.prop(self, 'thick')
+ layout.prop(self, 'taper')
+ layout.prop(self, 'type')
+ layout.prop(self, 'view_align')
+ col = layout.column()
+ col.prop(self, 'location')
+ col.prop(self, 'rotation')
+
+
+ def execute(self, context):
+ # debug flag - True prints debug info to console
+ debug = 0
+
+ # if type == true beam is U chanel, otherwise it's a C
+ if self.type:
+ size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
+ mesh_name = "U Beam"
+ else:
+ size = (self.mesh_z_size, self.mesh_y_size, self.mesh_x_size)
+ mesh_name = "C Beam"
+
+ verts, faces = create_C_beam(size, self.thick, self.taper, debug)
+
+ if debug:
+ print("\nCreated Verts:", verts)
+ print("\nCreated Faces:", faces)
+
+ create_mesh(self, context, mesh_name, verts, faces, debug)
+
+ recalc_normals(debug)
+
+ if not self.type:
+ # C-type beam is actually created as a u-type beam
+ # so rotate 90 degrees on y-axis to make a c-type
+ # and apply rotation to reset those values
+ # if self.type is true, do nothing as beam is alreay u-type.
+ # rotation value is in radians
+ bpy.ops.transform.rotate(value=[1.570796], constraint_axis=[False, True, False])
+ bpy.ops.object.transform_apply(location=False, rotation =True, scale=False)
+
+ return {'FINISHED'}
+
+'''
+ def invoke(self, context, event):
+ #self.align_matrix = align_matrix(context)
+ self.execute(context)
+ return {'FINISHED'}
+'''
+
+
+# Define "Add_L_Beam" operator
+class Add_L_Beam(bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_l_beam_add"
+ bl_label = "Add L Beam"
+ bl_description = "Create a L shaped mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
+ description = "Height (along the z-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 1)
+
+ mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
+ description = "Width (along the x-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = .5)
+
+ mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
+ description = "Length (along y-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 2)
+
+ thick = bpy.props.FloatProperty(name = "Thickness",
+ description = "Thickness of mesh",
+ min = 0.01,
+ max = 1,
+ default = 0.1)
+
+ taper = bpy.props.IntProperty(name = "Taper",
+ description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
+ min = 0,
+ max = 100,
+ default = 0)
+
+ # generic transform props
+ # required by object_utils.py - part of blender's
+ # code and is what handles alignment amongst other
+ # things.
+ view_align = bpy.props.BoolProperty(
+ name="Align to View",
+ default=False
+ )
+ location = bpy.props.FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = bpy.props.FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
+
+ # Define tool parameter layout
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, 'mesh_z_size')
+ layout.prop(self, 'mesh_x_size')
+ layout.prop(self, 'mesh_y_size')
+ layout.prop(self, 'thick')
+ layout.prop(self, 'taper')
+ layout.prop(self, 'view_align')
+ col = layout.column()
+ col.prop(self, 'location')
+ col.prop(self, 'rotation')
+
+
+ def execute(self, context):
+ # debug flag - True prints debug info to console
+ debug = 0
+
+ size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
+
+ verts, faces = create_L_beam(size, self.thick, self.taper, debug)
+
+ if debug:
+ print("\nCreated Verts:", verts)
+ print("\nCreated Faces:", faces)
+
+ create_mesh(self, context, "L Beam", verts, faces, debug)
+
+ recalc_normals(debug)
+
+ return {'FINISHED'}
+
+'''
+ def invoke(self, context, event):
+ self.align_matrix = align_matrix(context)
+ self.execute(context)
+ return {'FINISHED'}
+'''
+
+
+# Define "Add_T_Beam" operator
+class Add_T_Beam(bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_t_beam_add"
+ bl_label = "Add T Beam"
+ bl_description = "Create a T shaped mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
+ description = "Height (along the z-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 1)
+
+ mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
+ description = "Width (along the x-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = .5)
+
+ mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
+ description = "Length (along y-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 2)
+
+ thick = bpy.props.FloatProperty(name = "Thickness",
+ description = "Thickness of mesh",
+ min = 0.01,
+ max = 1,
+ default = 0.1)
+
+ taper = bpy.props.IntProperty(name = "Taper",
+ description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
+ min = 0,
+ max = 100,
+ default = 0)
+
+ # generic transform props
+ # required by object_utils.py - part of blender's
+ # code and is what handles alignment amongst other
+ # things.
+ view_align = bpy.props.BoolProperty(
+ name="Align to View",
+ default=False
+ )
+ location = bpy.props.FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = bpy.props.FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
+
+ # Define tool parameter layout
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, 'mesh_z_size')
+ layout.prop(self, 'mesh_x_size')
+ layout.prop(self, 'mesh_y_size')
+ layout.prop(self, 'thick')
+ layout.prop(self, 'taper')
+ layout.prop(self, 'view_align')
+ col = layout.column()
+ col.prop(self, 'location')
+ col.prop(self, 'rotation')
+
+
+ def execute(self, context):
+ # debug flag - True prints debug info to console
+ debug = 0
+
+ size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
+
+ verts, faces = create_T_beam(size, self.thick, self.taper, debug)
+
+ if debug:
+ print("\nCreated Verts:", verts)
+ print("\nCreated Faces:", faces)
+
+ create_mesh(self, context, "T Beam", verts, faces, debug)
+
+ recalc_normals(debug)
+
+ return {'FINISHED'}
+
+'''
+ def invoke(self, context, event):
+ self.align_matrix = align_matrix(context)
+ self.execute(context)
+ return {'FINISHED'}
+'''
+
+
+# Define "Add_I_Beam" operator
+class Add_I_Beam(bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_i_beam_add"
+ bl_label = "Add I Beam"
+ bl_description = "Create a I shaped mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ mesh_z_size = bpy.props.FloatProperty(name = "Height(z)",
+ description = "Height (along the z-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 1)
+
+ mesh_x_size = bpy.props.FloatProperty(name = "Width(x)",
+ description = "Width (along the x-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = .5)
+
+ mesh_y_size = bpy.props.FloatProperty(name = "Length(y)",
+ description = "Length (along y-axis) of mesh",
+ min = 0.01,
+ max = 100,
+ default = 2)
+
+ thick = bpy.props.FloatProperty(name = "Thickness",
+ description = "Thickness of mesh",
+ min = 0.01,
+ max = 1,
+ default = 0.1)
+
+ taper = bpy.props.IntProperty(name = "Taper",
+ description = "Percentage to taper outside edges, 0 = no taper, 100 = full taper",
+ min = 0,
+ max = 100,
+ default = 0)
+
+ # generic transform props
+ # required by object_utils.py - part of blender's
+ # code and is what handles alignment amongst other
+ # things.
+ view_align = bpy.props.BoolProperty(
+ name="Align to View",
+ default=False
+ )
+ location = bpy.props.FloatVectorProperty(
+ name="Location",
+ subtype='TRANSLATION',
+ )
+ rotation = bpy.props.FloatVectorProperty(
+ name="Rotation",
+ subtype='EULER',
+ )
+
+ # Define tool parameter layout
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, 'mesh_z_size')
+ layout.prop(self, 'mesh_x_size')
+ layout.prop(self, 'mesh_y_size')
+ layout.prop(self, 'thick')
+ layout.prop(self, 'taper')
+ layout.prop(self, 'view_align')
+ col = layout.column()
+ col.prop(self, 'location')
+ col.prop(self, 'rotation')
+
+
+ def execute(self, context):
+ # debug flag - True prints debug info to console
+ debug = 0
+
+ size = (self.mesh_x_size, self.mesh_y_size, self.mesh_z_size)
+
+ verts, faces = create_I_beam(size, self.thick, self.taper, debug)
+
+ if debug:
+ print("\nCreated Verts:", verts)
+ print("\nCreated Faces:", faces)
+
+ create_mesh(self, context, "I Beam", verts, faces, debug)
+
+ recalc_normals(debug)
+
+ return {'FINISHED'}
+
+
+'''
+ def invoke(self, context, event):
+ self.align_matrix = align_matrix(context)
+ self.execute(context)
+ return {'FINISHED'}
+'''
+
+
+# Register all operators and define menus
+
+class INFO_MT_mesh_beambuilder_add(bpy.types.Menu):
+ # Define the "Beam Builder" menu
+ bl_idname = "INFO_MT_mesh_beambuilder_add"
+ bl_label = "Beam Builder"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("mesh.primitive_rectangle_add", text = "Rectangluar Beam")
+ layout.operator("mesh.primitive_c_beam_add", text = "C or U Channel")
+ layout.operator("mesh.primitive_l_beam_add", text = "L Shaped Beam")
+ layout.operator("mesh.primitive_t_beam_add", text = "T Shaped Beam")
+ layout.operator("mesh.primitive_i_beam_add", text = "I Shaped Beam")
+
+
+
+# Define menu
+def menu_func(self, context):
+ self.layout.menu("INFO_MT_mesh_beambuilder_add", icon='PLUGIN')
+
+
+# Add
+def register():
+ bpy.utils.register_module(__name__)
+
+ # Add BeamBuilder menu to the 'Add Mesh' menu
+ bpy.types.INFO_MT_mesh_add.append(menu_func)
+
+
+# Remove
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ # Remove BeamBuilder menu from 'Add Mesh' menu
+ bpy.types.INFO_MT_mesh_add.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_sove.py b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_sove.py
new file mode 100644
index 0000000..b922239
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_sove.py
@@ -0,0 +1,222 @@
+'''bl_info = {
+ "name": "Sove",
+ "author": "SayPRODUCTIONS",
+ "version": (1, 0),
+ "blender": (2, 59, 0),
+ "api": 33333,
+ "location": "View3D > Add > Mesh > Say3D",
+ "description": "Sove Framema",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Mesh"}
+ '''
+import bpy
+from bpy.props import *
+from bpy_extras.object_utils import object_data_add
+from mathutils import Vector
+import operator
+from math import pi, sin, cos, sqrt, atan
+
+def MSVE():
+ if 'Sove' not in bpy.data.materials:
+ mtl=bpy.data.materials.new('Sove')
+ mtl.diffuse_color = (0.44,0.52,0.64)
+ mtl.diffuse_shader = 'LAMBERT'
+ mtl.diffuse_intensity = 1.0
+ else:
+ mtl=bpy.data.materials['Sove']
+ return mtl
+def Prs(self,v1,v2,v3,v4,v5,v6,v7,v8,v9,fg,fh,fd,
+ f0,f1,f2,f3,f4,f5,f6,f7,f8,f9):
+ self.gen=v1;self.knr=v2;self.yuk=v3
+ self.alt=v4;self.ust=v5;self.sdr=v6
+ self.pdr=v7;self.dh =v8;self.dr =v9
+ self.fg =fg;self.fh =fh;self.fd =fd
+ self.f0 =f0;self.f1 =f1;self.f2 =f2;self.f3=f3;self.f4=f4
+ self.f5 =f5;self.f6 =f6;self.f7 =f7;self.f8=f8;self.f9=f9
+def add_object(self, context):
+ fc=[];vr=[]
+ mx =self.gen/200;my =self.yuk/100;k1=self.knr/100;dh=self.dh/100;fd=self.fd/100;fh=self.fh/100
+ alt=self.alt/100;ust=my-self.ust/100;drn=-self.sdr/100;pdr=self.pdr/100
+ vr.append([-mx-k1, 0, 0]);vr.append([ mx+k1, 0, 0]);vr.append([ mx+k1, 0, my]);vr.append([-mx-k1, 0, my])
+ vr.append([-mx, pdr,alt]);vr.append([ mx, pdr,alt]);vr.append([ mx, pdr,ust]);vr.append([-mx, pdr,ust])
+ vr.append([-mx-k1,drn, 0]);vr.append([ mx+k1,drn, 0]);vr.append([ mx+k1,drn, my]);vr.append([-mx-k1,drn, my])
+ vr.append([-mx, drn,alt]);vr.append([ mx, drn,alt]);vr.append([ mx, drn,ust]);vr.append([-mx, drn,ust])
+ fc.append([ 8, 0, 1, 9]);fc.append([ 8, 9,13,12])
+ fc.append([12,13, 5, 4]);fc.append([11,10, 2, 3])
+ if self.fg==0:
+ fc.append([ 0, 8,11, 3]);fc.append([ 8,12,15,11]);fc.append([12, 4, 7,15])
+ fc.append([ 5,13,14, 6]);fc.append([13, 9,10,14]);fc.append([ 9, 1, 2,10])
+ else:
+ fc.append([11, 3,16,17]);fc.append([15,11,17,18]);fc.append([ 7,15,18,24])
+ fc.append([25,19,14, 6]);fc.append([19,20,10,14]);fc.append([20,21, 2,10])
+ ou=self.fg*12
+ fc.append([4,7,12+ou,24+ou]);fc.append([6,5,25+ou,13+ou])
+ z=my
+ for i in range(self.fg):
+ if i==0:z-=self.f0/100
+ if i==1:z-=self.f1/100
+ if i==2:z-=self.f2/100
+ if i==3:z-=self.f3/100
+ if i==4:z-=self.f4/100
+ if i==5:z-=self.f5/100
+ if i==6:z-=self.f6/100
+ if i==7:z-=self.f7/100
+ if i==8:z-=self.f8/100
+ if i==9:z-=self.f9/100
+ vr.append([ -mx-k1, 0,z]);vr.append([ -mx-k1, drn,z]);vr.append([ -mx, drn,z])
+ vr.append([ mx, drn,z]);vr.append([ mx+k1, drn,z]);vr.append([ mx+k1, 0,z])
+ vr.append([-mx-k1+fd, 0,z]);vr.append([-mx-k1+fd,drn+fd,z]);vr.append([ -mx,drn+fd,z])
+ vr.append([ mx,drn+fd,z]);vr.append([ mx+k1-fd,drn+fd,z]);vr.append([mx+k1-fd, 0,z])
+ z-=fh
+ vr.append([ -mx-k1, 0,z]);vr.append([ -mx-k1, drn,z]);vr.append([ -mx, drn,z])
+ vr.append([ mx, drn,z]);vr.append([ mx+k1, drn,z]);vr.append([ mx+k1, 0,z])
+ vr.append([-mx-k1+fd, 0,z]);vr.append([-mx-k1+fd,drn+fd,z]);vr.append([ -mx,drn+fd,z])
+ vr.append([ mx,drn+fd,z]);vr.append([ mx+k1-fd,drn+fd,z]);vr.append([mx+k1-fd, 0,z])
+ n=len(vr)
+ fc.append([n- 1,n- 2,n- 8,n- 7]);fc.append([n- 3,n- 9,n- 8,n- 2]);fc.append([n- 2,n- 1,n-13,n-14])
+ fc.append([n- 3,n- 2,n-14,n-15]);fc.append([n-15,n-14,n-20,n-21]);fc.append([n-14,n-13,n-19,n-20])
+ fc.append([n- 4,n- 5,n-11,n-10]);fc.append([n- 5,n- 6,n-12,n-11]);fc.append([n- 5,n- 4,n-16,n-17])
+ fc.append([n- 6,n- 5,n-17,n-18]);fc.append([n-24,n-18,n-17,n-23]);fc.append([n-23,n-17,n-16,n-22])
+ if self.fg>1:
+ if self.fg%2==0:
+ if i < self.fg/2:fc.append([7,n-16,n-4]);fc.append([6,n-3,n-15])
+ if i+1<self.fg/2:fc.append([7,n- 4,n+8]);fc.append([6,n+9,n- 3])
+ if i+1>self.fg/2:fc.append([4,n-16,n-4]);fc.append([5,n-3,n-15])
+ if i+1>self.fg/2 and i+1<self.fg:fc.append([4,n-4,n+8]);fc.append([5,n+9,n-3])
+ else:
+ if i<self.fg//2:
+ fc.append([7,n-16,n-4]);fc.append([6,n-3,n-15])
+ fc.append([7,n- 4,n+8]);fc.append([6,n+9,n- 3])
+ if i > self.fg//2:fc.append([4,n-16,n-4]);fc.append([5,n-3,n-15])
+ if i+1>self.fg//2 and i+1<self.fg:fc.append([4,n- 4,n+8]);fc.append([5,n+9,n-3])
+ if i<self.fg-1 and self.fg>1:
+ fc.append([n- 7,n- 8,n+4,n+5]);fc.append([n- 8,n- 9,n+3,n+4]);fc.append([n-9,n- 3,n+9,n+3])
+ fc.append([n-10,n-11,n+1,n+2]);fc.append([n-11,n-12, n ,n+1]);fc.append([n-4,n-10,n+2,n+8])
+ if i==self.fg-1:
+ fc.append([0, 8,n-11,n-12]);fc.append([ 8,12,n-10,n-11]);fc.append([12,4,n-4,n-10])
+ fc.append([5,13,n- 9,n- 3]);fc.append([13, 9,n- 8,n- 9]);fc.append([ 9,1,n-7,n- 8])
+ SM=[]
+ #Duz----------------
+ if self.dr==False:
+ fc.append([14,10,11,15]);fc.append([6,14,15,7])
+ #Yuvarlak-----------
+ else:
+ if dh>mx:dh=mx;self.dh=mx*100
+ vr[ 6][2]-=dh;vr[ 7][2]-=dh
+ vr[14][2]-=dh;vr[15][2]-=dh
+ O=mx/dh
+ H1=sqrt(mx**2+dh**2)/2
+ H2=H1*O
+ R=sqrt(H1**2+H2**2)
+ M=ust-R
+ A=pi-atan(O)*2
+ for a in range(1,24):
+ p=(a*A/12)+(pi*1.5)-A
+ vr.append([cos(p)*R,pdr,M-sin(p)*R])
+ vr.append([cos(p)*R,drn,M-sin(p)*R])
+ n=len(vr)
+ if a==1:
+ fc.append([n-1,15,7,n-2])
+ SM.append(len(fc))
+ fc.append([15,n-1,11])
+ elif a<23:
+ fc.append([n-1,n-3,n-4,n-2])
+ SM.append(len(fc))
+ if a<13: fc.append([n-3,n-1,11])
+ elif a==13:fc.append([n-3,n-1,10,11])
+ else: fc.append([n-3,n-1,10])
+ elif a==23:
+ fc.append([n-1,n-3,n-4,n-2])
+ SM.append(len(fc))
+ fc.append([n-3,n-1,10])
+ fc.append([14,n-1,n-2,6])
+ SM.append(len(fc))
+ fc.append([n-1,14,10])
+#OBJE -----------------------------------------------------------
+ mesh = bpy.data.meshes.new(name='Sove')
+ bpy.data.objects.new('Sove', mesh)
+ mesh.from_pydata(vr,[],fc)
+ # for i in SM:
+ # mesh.faces[i-1].shade_smooth()
+ mesh.materials.append(MSVE())
+ mesh.update(calc_edges=True)
+ object_data_add(context, mesh, operator=None)
+ if bpy.context.mode != 'EDIT_MESH':
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+#----------------------------------------------------------------
+class OBJECT_OT_add_object(bpy.types.Operator):
+ bl_idname = "mesh.add_say3d_sove"
+ bl_label = "Sove"
+ bl_description = "Sove Frame"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ prs = EnumProperty(items = (("1","PENCERE 200",""),
+ ("2","PENCERE 180",""),
+ ("3","PENCERE 160","")),
+ name="",description="")
+ son=prs
+ gen=IntProperty(name='Width', min=1,max= 400,default=200,description='Width')
+ knr=IntProperty(name='Thickness', min=1,max= 100,default= 15,description='Thickness')
+ yuk=IntProperty(name='Elevation',min=1,max=3000,default=590,description='Elevation')
+ alt=IntProperty(name='Old Spacing', min=1,max= 300,default= 44,description='Old Spacing')
+ ust=IntProperty(name='Top margin', min=1,max= 300,default= 33,description='Top margin')
+ sdr=IntProperty(name='Jamb', min=1,max= 100,default= 15,description='jamb Depth')
+ pdr=IntProperty(name='Wall Thickness', min=0,max= 100,default= 20,description='Wall Thickness')
+ dh =IntProperty(name='', min=1,max= 200,default= 30,description='Height')
+ dr=BoolProperty(name='Rounded', default=True, description='Rounded')
+
+ fg =IntProperty(name='Gap',min=0,max=10,default=1,description='Gap')
+ fh =IntProperty(name='', min=1,max=10,default=3,description='Height')
+ fd =IntProperty(name='', min=1,max=10,default=2,description='Depth')
+
+ f0 =IntProperty(name='Interval',min=1,max=3000,default=90,description='Interval')
+ f1 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f2 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f3 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f4 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f5 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f6 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f7 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f8 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ f9 =IntProperty(name='Interval',min=1,max=3000,default=30,description='Interval')
+ #--------------------------------------------------------------
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self,'prs')
+ box=layout.box()
+ box.prop(self,'gen');box.prop(self,'yuk')
+ box.prop(self,'knr')
+ row=box.row();row.prop(self,'alt');row.prop(self,'ust')
+ row=box.row();row.prop(self,'sdr');row.prop(self,'pdr')
+ row=box.row();row.prop(self, 'dr');row.prop(self, 'dh')
+ box=layout.box()
+ box.prop(self,'fg')
+ row=box.row();row.prop(self, 'fh');row.prop(self, 'fd')
+ for i in range(self.fg):
+ box.prop(self,'f'+str(i))
+
+ def execute(self, context):
+ if self.son!=self.prs:
+ if self.prs=='1':Prs(self,200,15,590,44,33,15,20,30,True,1,2,3,90,30,30,30,30,30,30,30,30,30)
+ if self.prs=='2':Prs(self,180,15,590,44,33,15,20,30,True,1,2,3,90,30,30,30,30,30,30,30,30,30)
+ if self.prs=='3':Prs(self,160,15,590,44,33,15,20,30,True,1,2,3,90,30,30,30,30,30,30,30,30,30)
+ self.son=self.prs
+ add_object(self, context)
+ return {'FINISHED'}
+# Reg--------------------------------
+def add_object_button(self, context):
+ self.layout.operator(
+ OBJECT_OT_add_object.bl_idname,
+ text="Sove",
+ icon="MOD_MESHDEFORM")
+def register():
+ bpy.utils.register_class(OBJECT_OT_add_object)
+ bpy.types.INFO_MT_mesh_add.append(add_object_button)
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_add_object)
+ bpy.types.INFO_MT_mesh_add.remove(add_object_button)
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_window.py b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_window.py
new file mode 100644
index 0000000..459a612
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/add_mesh_window.py
@@ -0,0 +1,764 @@
+bl_info = {
+ "name": "Window Generator 2",
+ "author": "SayPRODUCTIONS",
+ "version": (2, 0),
+ "blender": (2, 63, 0),
+ "api": 33333,
+ "location": "View3D > Add > Mesh > Say3D",
+ "description": "Window Generator 2",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Mesh"}
+import bpy
+from bpy.props import *
+from math import pi, sin, cos, sqrt
+def MAT(AD,R,G,B):
+ if AD not in bpy.data.materials:
+ mtl=bpy.data.materials.new(AD)
+ mtl.diffuse_color = ([R,G,B])
+ mtl.diffuse_shader = 'LAMBERT'
+ mtl.diffuse_intensity = 1.0
+ else:
+ mtl=bpy.data.materials[AD]
+ return mtl
+def Fitil(vr,fc,X,Z,x,y,z,zz,xx):
+ k3=z*2
+ vr.extend([[X[x ]+xx,-z+zz,Z[y ]+xx],[X[x ]+xx+k3,-z+zz,Z[y ]+xx+k3],[X[x ]+xx+k3,z+zz,Z[y ]+xx+k3],[X[x ]+xx,z+zz,Z[y ]+xx]])
+ vr.extend([[X[x ]+xx,-z+zz,Z[y+1]-xx],[X[x ]+xx+k3,-z+zz,Z[y+1]-xx-k3],[X[x ]+xx+k3,z+zz,Z[y+1]-xx-k3],[X[x ]+xx,z+zz,Z[y+1]-xx]])
+ vr.extend([[X[x+1]-xx,-z+zz,Z[y+1]-xx],[X[x+1]-xx-k3,-z+zz,Z[y+1]-xx-k3],[X[x+1]-xx-k3,z+zz,Z[y+1]-xx-k3],[X[x+1]-xx,z+zz,Z[y+1]-xx]])
+ vr.extend([[X[x+1]-xx,-z+zz,Z[y ]+xx],[X[x+1]-xx-k3,-z+zz,Z[y ]+xx+k3],[X[x+1]-xx-k3,z+zz,Z[y ]+xx+k3],[X[x+1]-xx,z+zz,Z[y ]+xx]])
+ n=len(vr)
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2]])
+ fc.extend([[n- 4,n- 3,n-15,n-16],[n- 3,n- 2,n-14,n-15],[n- 2,n- 1,n-13,n-14]])
+ z=0.005
+ vr.extend([[X[x]+xx+k3,-z+zz,Z[y]+xx+k3],[X[x]+xx+k3,-z+zz,Z[y+1]-xx-k3],[X[x+1]-xx-k3,-z+zz,Z[y+1]-xx-k3],[X[x+1]-xx-k3,-z+zz,Z[y]+xx+k3]])
+ vr.extend([[X[x]+xx+k3, z+zz,Z[y]+xx+k3],[X[x]+xx+k3, z+zz,Z[y+1]-xx-k3],[X[x+1]-xx-k3, z+zz,Z[y+1]-xx-k3],[X[x+1]-xx-k3, z+zz,Z[y]+xx+k3]])
+ fc.extend([[n+1,n+0,n+3,n+2],[n+4,n+5,n+6,n+7]])
+def Kapak(vr,fc,X,Z,x,y,z,zz):
+ k2=z*2
+ vr.extend([[X[x ],-z+zz,Z[y ]],[X[x ]+k2,-z+zz,Z[y ]+k2],[X[x ]+k2,z+zz,Z[y ]+k2],[X[x ],z+zz,Z[y ]]])
+ vr.extend([[X[x ],-z+zz,Z[y+1]],[X[x ]+k2,-z+zz,Z[y+1]-k2],[X[x ]+k2,z+zz,Z[y+1]-k2],[X[x ],z+zz,Z[y+1]]])
+ vr.extend([[X[x+1],-z+zz,Z[y+1]],[X[x+1]-k2,-z+zz,Z[y+1]-k2],[X[x+1]-k2,z+zz,Z[y+1]-k2],[X[x+1],z+zz,Z[y+1]]])
+ vr.extend([[X[x+1],-z+zz,Z[y ]],[X[x+1]-k2,-z+zz,Z[y ]+k2],[X[x+1]-k2,z+zz,Z[y ]+k2],[X[x+1],z+zz,Z[y ]]])
+ n=len(vr)
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10],[n-13,n-16,n-12,n- 9]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6],[n- 9,n-12,n- 8,n- 5]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2],[n- 5,n- 8,n- 4,n- 1]])
+ fc.extend([[n- 4,n- 3,n-15,n-16],[n- 3,n- 2,n-14,n-15],[n- 2,n- 1,n-13,n-14],[n- 1,n- 4,n-16,n-13]])
+def Prs(s):
+ if s.prs=='1':
+ s.gen=3;s.yuk=1;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=190;s.mr=True
+ s.gnx0= 60;s.gnx1= 110;s.gnx2= 60
+ s.k00 =True;s.k01 =False;s.k02 =True
+ if s.prs=='2':
+ s.gen=3;s.yuk=1;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=190;s.mr=True
+ s.gnx0= 60;s.gnx1= 60;s.gnx2= 60
+ s.k00 =True;s.k01 =False;s.k02 =True
+ if s.prs=='3':
+ s.gen=3;s.yuk=1;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=190;s.mr=True
+ s.gnx0= 55;s.gnx1= 50;s.gnx2= 55
+ s.k00 =True;s.k01 =False;s.k02 =True
+ if s.prs=='4':
+ s.gen=3;s.yuk=1;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=150;s.mr=True
+ s.gnx0= 55;s.gnx1= 50;s.gnx2= 55
+ s.k00 =True;s.k01 =False;s.k02 =True
+ if s.prs=='5':
+ s.gen=3;s.yuk=1;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=150;s.mr=True
+ s.gnx0= 50;s.gnx1= 40;s.gnx2= 50
+ s.k00 =True;s.k01 =False;s.k02 =True
+ if s.prs=='6':
+ s.gen=1;s.yuk=1;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=40;s.mr=True
+ s.gnx0=40
+ s.k00 =False
+ if s.prs=='7':
+ s.gen=1;s.yuk=2;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=195;s.gny1=40
+ s.gnx0=70
+ s.k00 =True;s.k10 =False
+ s.mr=False
+ if s.prs=='8':
+ s.gen=1;s.yuk=2;s.kl1=5;s.kl2=5;s.fk=2
+ s.gny0=180;s.gny1=35
+ s.gnx0=70
+ s.k00 =True;s.k10 =False
+ s.mr=False
+def add_object(self, context):
+ fc=[];vr=[];kx=[]
+ mx=self.gen;my=self.yuk;k1=self.kl1/100;y=my*4+4;k2=self.kl2/100;k3=self.fk/200;fr=(k1+k2)*0.5-0.01
+ RES=self.RES
+
+ u=self.kl1/100;X=[0,round(u,2)]
+ if mx> 0:u+=self.gnx0 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 1:u+=self.gnx1 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 2:u+=self.gnx2 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 3:u+=self.gnx3 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 4:u+=self.gnx4 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 5:u+=self.gnx5 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 6:u+=self.gnx6 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ if mx> 7:u+=self.gnx7 /100;X.append(round(u,2));u+=k2;X.append(round(u,2))
+ X[-1]=X[-2]+k1
+
+ u=self.kl1/100;Z=[0,round(u,2)]
+ if my> 0:u+=self.gny0 /100;Z.append(round(u,2));u+=k2;Z.append(round(u,2))
+ if my> 1:u+=self.gny1 /100;Z.append(round(u,2));u+=k2;Z.append(round(u,2))
+ if my> 2:u+=self.gny2 /100;Z.append(round(u,2));u+=k2;Z.append(round(u,2))
+ if my> 3:u+=self.gny3 /100;Z.append(round(u,2));u+=k2;Z.append(round(u,2))
+ if my> 4:u+=self.gny4 /100;Z.append(round(u,2));u+=k2;Z.append(round(u,2))
+ Z[-1]=Z[-2]+k1
+
+ u = X[-1]/2
+ for i in range(0,len(X)):X[i]-=u
+ kx=[[self.k00,self.k10,self.k20,self.k30,self.k40],
+ [self.k01,self.k11,self.k21,self.k31,self.k41],
+ [self.k02,self.k12,self.k22,self.k32,self.k42],
+ [self.k03,self.k13,self.k23,self.k33,self.k43],
+ [self.k04,self.k14,self.k24,self.k34,self.k44],
+ [self.k05,self.k15,self.k25,self.k35,self.k45],
+ [self.k06,self.k16,self.k26,self.k36,self.k46],
+ [self.k07,self.k17,self.k27,self.k37,self.k47]]
+ cam=[];mer=[];ftl=[];SM=[]
+#VERTICES ------------------------
+ vr.extend([[X[0],-k1/2,Z[0]],[X[0],k1/2,Z[0]]])
+ for x in range(1,len(X)-1):vr.extend([[X[x],-k1/2,Z[1]],[X[x], k1/2,Z[1]]])
+ vr.extend([[X[-1],-k1/2,Z[0]],[X[-1], k1/2,Z[0]]])
+ for z in range(2,len(Z)-2,2):
+ for x in range(0,len(X)):vr.extend([[X[x],-k1/2,Z[z]],[X[x], k1/2,Z[z]]])
+ for x in range(0,len(X)):vr.extend([[X[x],-k1/2,Z[z+1]],[X[x], k1/2,Z[z+1]]])
+ z=len(Z)-2
+ vr.extend([[X[0],-k1/2,Z[z+1]],[X[0], k1/2,Z[z+1]]])
+ ALT=[];UST=[len(vr)-2,len(vr)-1]
+ for x in range(1,len(X)-1):
+ vr.extend([[X[x],-k1/2,Z[z]],[X[x], k1/2,Z[z]]])
+ ALT.extend([len(vr)-2,len(vr)-1])
+ vr.extend([[X[-1],-k1/2,Z[z+1]],[X[-1],k1/2,Z[z+1]]])
+ SON=[len(vr)-2,len(vr)-1]
+#FACES ---------------------------
+ fc.append([0,1,3+mx*4,2+mx*4])
+ FB=[0];FR=[1]
+ for i in range(0,mx*4,4):
+ fc.append([i+3,i+2,i+4,i+5])
+ FB.extend([i+2,i+4])
+ FR.extend([i+3,i+5])
+ FR.append(3+mx*4);FB.append(2+mx*4)
+ FB.reverse()
+ fc.extend([FB,FR])
+ #Yatay
+ Y=(mx*4+4);V=mx*4+2
+ for z in range(0,(my-1)*Y*2,Y*2):
+ fc.extend([[z+Y+1,z+Y,z+Y+4+mx*4,z+Y+5+mx*4],[z+Y+V,z+Y+V+1,z+Y+V+5+mx*4,z+Y+V+4+mx*4]])
+ for i in range(0,mx*4+2,2):fc.extend([[z+i+Y+0,z+i+Y+2,z+i+Y+V+4,z+i+Y+V+2],[z+i+Y +3,z+i+Y +1,z+i+Y+V+3,z+i+Y+V+5]])
+ for i in range(0,mx*4-3,4):fc.extend([[z+i+Y+2,z+i+Y+3,z+i+Y +5,z+i+Y +4],[z+i+Y+V+5,z+i+Y+V+4,z+i+Y+V+6,z+i+Y+V+7]])
+ #Dikey
+ for Y in range(0,my):
+ z=Y*(mx*4+4)*2
+ for i in range(0,mx*4+2,4):fc.extend([[z+i+1,z+i+0,z+i+V+2,z+i+V+3],[z+i+3,z+i+1,z+i+V+3,z+i+V+5],[z+i+2,z+i+3,z+i+V+5,z+i+V+4],[z+i+0,z+i+2,z+i+V+4,z+i+V+2]])
+ #Fitil-------------------
+ if self.UST=='1':y1=my
+ else: y1=my-1
+ for y in range(0,y1):
+ for x in range(0,mx):
+ if kx[x][y]==True:
+ Kapak(vr,fc,X,Z,x*2+1,y*2+1,k2/2,(k1+k2)*0.5-0.01)
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,(k1+k2)*0.5-0.01,k2)
+ else:
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,0,0)
+ m=len(fc);cam.extend([m-1,m-2])
+ ftl.extend([m-3,m-4,m-5,m-6,m-7,m-8,m-9,m-10,m-11,m-12,m-13,m-14])
+ #-----------------------------------------------------
+ if self.UST=='1':#Duz
+ fc.append([UST[1],UST[0],SON[0],SON[1]])
+ for i in range(0,mx*4,4):
+ fc.append([ALT[i],ALT[i+1],ALT[i+3],ALT[i+2]])
+ ON=[UST[0]]
+ AR=[UST[1]]
+ for i in range(0,len(ALT)-1,2):
+ ON.append(ALT[i ])
+ AR.append(ALT[i+1])
+ ON.append(SON[0])
+ fc.append(ON)
+ AR.append(SON[1])
+ AR.reverse();fc.append(AR)
+ elif self.UST=='2':#Yay
+ if self.DT2=='1':
+ H=self.VL1/100
+ if H<0.01:H= 0.01;self.VL1=1
+ elif H >= u:H=u-0.01;self.VL1=H*100
+ h=sqrt(u**2+H**2)/2
+ e=h*(u/H)
+ C=sqrt(h**2+e**2)
+ T1=Z[-1]-H
+ elif self.DT2=='2':
+ C=self.VL2/100
+ if C<u+0.01:
+ C=u+0.01
+ self.VL2=C*100
+ T1=sqrt(C**2-u**2)+Z[-1]-C
+ R=C-k1;F=R-k3*2
+ K=R-k2;E=K-k3*2
+ z=Z[-1]-C
+
+ vr[UST[0]][2]=T1;vr[UST[1]][2]=T1
+ vr[SON[0]][2]=T1;vr[SON[1]][2]=T1
+ for i in ALT:vr[i][2]=sqrt(R**2-vr[i][0]**2)+z
+
+ ON=[SON[0]];U1=[]
+ for i in range(0,RES):
+ A=i*pi/RES;x=cos(A)*C
+ if x>-u and x<u:
+ vr.append([x,-k1/2,sin(A)*C+z]);ON.append(len(vr)-1)
+ U1.extend(ON);U1.append(UST[0])
+ ON.extend([UST[0],ALT[0]])
+ AR=[];D1=[];D2=[]
+ for i in range(0,len(ALT)-2,4):
+ x1=vr[ALT[i+0]][0]; x2=vr[ALT[i+2]][0]
+ ON.append(ALT[i+0]);AR.append(ALT[i+1])
+ T1=[ALT[i+0]]; T2=[ALT[i+1]]
+ for j in range(0,RES):
+ A=j*pi/RES;x=-cos(A)*R
+ if x1<x and x<x2:
+ vr.extend([[x,-k1/2,sin(A)*R+z],[x,k1/2,sin(A)*R+z]])
+ ON.append(len(vr)-2);AR.append(len(vr)-1)
+ T1.append(len(vr)-2);T2.append(len(vr)-1)
+ ON.append(ALT[i+2]);AR.append(ALT[i+3])
+ T1.append(ALT[i+2]);T2.append(ALT[i+3])
+ D1.append(T1); D2.append(T2)
+ AR.append(SON[1])
+ U2=[SON[1]]
+ for i in range(0,RES):
+ A=i*pi/RES;x=cos(A)*C
+ if x>-u and x<u:
+ vr.append([x,k1/2,sin(A)*C+z])
+ AR.append(len(vr)-1);U2.append(len(vr)-1)
+ AR.append(UST[1])
+ U2.append(UST[1])
+ AR.reverse()
+ fc.extend([ON,AR])
+ for i in range(0,len(U1)-1):fc.append([U1[i+1],U1[i],U2[i],U2[i+1]]);SM.append(len(fc)-1)
+ for A in range(0,mx):
+ for i in range(0,len(D1[A])-1):
+ fc.append([D1[A][i+1],D1[A][i],D2[A][i],D2[A][i+1]]);SM.append(len(fc)-1)
+ y=my-1
+ for x in range(0,mx):
+ if kx[x][y]==True:
+ fr=(k1+k2)*0.5-0.01;ek=k2
+ R=C-k1;K=R-k2
+
+ x1=X[x*2+1];x2=X[x*2+2]
+ vr.extend([[x2,fr-k2/2,z+1 ],[x2-k2,fr-k2/2,z+1 ],[x2-k2,fr+k2/2,z+1 ],[x2,fr+k2/2,z+1 ]])
+ vr.extend([[x2,fr-k2/2,Z[-3]],[x2-k2,fr-k2/2,Z[-3]+k2],[x2-k2,fr+k2/2,Z[-3]+k2],[x2,fr+k2/2,Z[-3]]])
+ vr.extend([[x1,fr-k2/2,Z[-3]],[x1+k2,fr-k2/2,Z[-3]+k2],[x1+k2,fr+k2/2,Z[-3]+k2],[x1,fr+k2/2,Z[-3]]])
+ vr.extend([[x1,fr-k2/2,z+1 ],[x1+k2,fr-k2/2,z+1 ],[x1+k2,fr+k2/2,z+1 ],[x1,fr+k2/2,z+1 ]])
+
+ n=len(vr)
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10],[n-13,n-16,n-12,n- 9]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6],[n- 9,n-12,n- 8,n- 5]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2],[n- 5,n- 8,n- 4,n- 1]])
+ ALT=[n-16,n-15,n-14,n-13,n-4,n-3,n-2,n-1]
+ vr[ALT[0]][2]=sqrt(R**2-vr[ALT[0]][0]**2)+z;vr[ALT[1]][2]=sqrt(K**2-vr[ALT[1]][0]**2)+z
+ vr[ALT[2]][2]=sqrt(K**2-vr[ALT[2]][0]**2)+z;vr[ALT[3]][2]=sqrt(R**2-vr[ALT[3]][0]**2)+z
+ vr[ALT[4]][2]=sqrt(R**2-vr[ALT[4]][0]**2)+z;vr[ALT[5]][2]=sqrt(K**2-vr[ALT[5]][0]**2)+z
+ vr[ALT[6]][2]=sqrt(K**2-vr[ALT[6]][0]**2)+z;vr[ALT[7]][2]=sqrt(R**2-vr[ALT[7]][0]**2)+z
+
+ D1=[];D2=[];T1=[];T2=[]
+ for i in range(0,RES):
+ A =i*pi/RES;y1=cos(A)*R;y2=-cos(A)*K
+ if x1 <y1 and y1<x2: vr.extend([[y1,fr-k2/2,sin(A)*R+z],[y1,fr+k2/2,sin(A)*R+z]]);T1.append(len(vr)-2);T2.append(len(vr)-1)
+ if x1+k2<y2 and y2<x2-k2:vr.extend([[y2,fr-k2/2,sin(A)*K+z],[y2,fr+k2/2,sin(A)*K+z]]);D1.append(len(vr)-2);D2.append(len(vr)-1)
+ ON=[ALT[1],ALT[0]];ON.extend(T1);ON.extend([ALT[4],ALT[5]]);ON.extend(D1)
+ AR=[ALT[2],ALT[3]];AR.extend(T2);AR.extend([ALT[7],ALT[6]]);AR.extend(D2);AR.reverse()
+
+ if D1==[] and T1==[]:fc.extend([ON,AR,[ALT[5],ALT[6],ALT[2],ALT[1]],[ALT[7],ALT[4],ALT[0],ALT[3]]]); m=len(fc);SM.extend([m-1,m-2])
+ elif D1==[] and T1!=[]:fc.extend([ON,AR,[ALT[5],ALT[6],ALT[2],ALT[1]],[ALT[7],ALT[4],T1[-1],T2[-1]],[ALT[0],ALT[3],T2[0],T1[0]]]); m=len(fc);SM.extend([m-1,m-2,m-3])
+ elif D1!=[] and T1==[]:fc.extend([ON,AR,[ALT[5],ALT[6],D2[0],D1[0]],[ALT[2],ALT[1],D1[-1],D2[-1]],[ALT[7],ALT[4],ALT[0],ALT[3]]]); m=len(fc);SM.extend([m-1,m-2,m-3])
+ else: fc.extend([ON,AR,[ALT[5],ALT[6],D2[0],D1[0]],[ALT[2],ALT[1],D1[-1],D2[-1]],[ALT[7],ALT[4],T1[-1],T2[-1]],[ALT[0],ALT[3],T2[0],T1[0]]]);m=len(fc);SM.extend([m-1,m-2,m-3,m-4])
+
+ for i in range(0,len(D1)-1):fc.append([D1[i+1],D1[i],D2[i],D2[i+1]]);SM.append(len(fc)-1)
+ for i in range(0,len(T1)-1):fc.append([T1[i+1],T1[i],T2[i],T2[i+1]]);SM.append(len(fc)-1)
+ R=C-k1-k2;K=R-k3*2
+ else:
+ fr=0;ek=0
+ R=C-k1;K=R-k3*2
+ #Fitil
+ x1=X[x*2+1]+ek;x2=X[x*2+2]-ek
+ vr.extend([[x2,fr-k3,z+1 ],[x2-k3*2,fr-k3,z+1 ],[x2-k3*2,fr+k3,z+1 ],[x2,fr+k3,z+1 ]])
+ vr.extend([[x2,fr-k3,Z[-3]+ek],[x2-k3*2,fr-k3,Z[-3]+ek+k3*2],[x2-k3*2,fr+k3,Z[-3]+ek+k3*2],[x2,fr+k3,Z[-3]+ek]])
+ vr.extend([[x1,fr-k3,Z[-3]+ek],[x1+k3*2,fr-k3,Z[-3]+ek+k3*2],[x1+k3*2,fr+k3,Z[-3]+ek+k3*2],[x1,fr+k3,Z[-3]+ek]])
+ vr.extend([[x1,fr-k3,z+1 ],[x1+k3*2,fr-k3,z+1 ],[x1+k3*2,fr+k3,z+1 ],[x1,fr+k3,z+1 ]])
+ n=len(vr)
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2]])
+ m=len(fc);ftl.extend([m-1,m-2,m-3,m-4,m-5,m-6,m-7,m-8,m-9])
+ ALT=[n-16,n-15,n-14,n-13,n-4,n-3,n-2,n-1]
+ vr[ALT[0]][2]=sqrt(R**2-vr[ALT[0]][0]**2)+z;vr[ALT[1]][2]=sqrt(K**2-vr[ALT[1]][0]**2)+z
+ vr[ALT[2]][2]=sqrt(K**2-vr[ALT[2]][0]**2)+z;vr[ALT[3]][2]=sqrt(R**2-vr[ALT[3]][0]**2)+z
+ vr[ALT[4]][2]=sqrt(R**2-vr[ALT[4]][0]**2)+z;vr[ALT[5]][2]=sqrt(K**2-vr[ALT[5]][0]**2)+z
+ vr[ALT[6]][2]=sqrt(K**2-vr[ALT[6]][0]**2)+z;vr[ALT[7]][2]=sqrt(R**2-vr[ALT[7]][0]**2)+z
+ D1=[];D2=[];T1=[];T2=[]
+ for i in range(0,RES):
+ A =i*pi/RES;y1=cos(A)*R;y2=-cos(A)*K
+ if x1 <y1 and y1<x2: vr.extend([[y1,fr-k3,sin(A)*R+z],[y1,fr+k3,sin(A)*R+z]]);T1.append(len(vr)-2);T2.append(len(vr)-1);ftl.extend([len(fc)-1,len(fc)-2])
+ if x1+k3*2<y2 and y2<x2-k3*2:vr.extend([[y2,fr-k3,sin(A)*K+z],[y2,fr+k3,sin(A)*K+z]]);D1.append(len(vr)-2);D2.append(len(vr)-1);ftl.extend([len(fc)-1,len(fc)-2])
+ ON=[ALT[1],ALT[0]];ON.extend(T1);ON.extend([ALT[4],ALT[5]]);ON.extend(D1)
+ AR=[ALT[2],ALT[3]];AR.extend(T2);AR.extend([ALT[7],ALT[6]]);AR.extend(D2);AR.reverse()
+
+ if D1==[]:fc.extend([ON,AR,[ALT[5],ALT[6],ALT[2],ALT[1]]]); m=len(fc);ftl.extend([m-1,m-2,m-3 ]);SM.extend([m-1 ])
+ else: fc.extend([ON,AR,[ALT[5],ALT[6],D2[0],D1[0]],[ALT[2],ALT[1],D1[-1],D2[-1]]]);m=len(fc);ftl.extend([m-1,m-2,m-3,m-4]);SM.extend([m-1,m-2])
+
+ for i in range(0,len(D1)-1):fc.append([D1[i+1],D1[i],D2[i],D2[i+1]]);ftl.append(len(fc)-1);SM.append(len(fc)-1)
+ #Cam
+ x1=X[x*2+1]+ek+k3*2;x2=X[x*2+2]-ek-k3*2
+ ON=[];AR=[]
+ for i in range(0,RES):
+ A= i*pi/RES;y1=-cos(A)*K
+ if x1<y1 and y1<x2:
+ vr.extend([[y1,fr-0.005,sin(A)*K+z],[y1,fr+0.005,sin(A)*K+z]])
+ n=len(vr);ON.append(n-1);AR.append(n-2)
+ vr.extend([[x1,fr-0.005,sqrt(K**2-x1**2)+z],[x1,fr+0.005,sqrt(K**2-x1**2)+z]])
+ vr.extend([[x1,fr-0.005,Z[-3]+ek+k3*2 ],[x1,fr+0.005,Z[-3]+ek+k3*2 ]])
+ vr.extend([[x2,fr-0.005,Z[-3]+ek+k3*2 ],[x2,fr+0.005,Z[-3]+ek+k3*2 ]])
+ vr.extend([[x2,fr-0.005,sqrt(K**2-x2**2)+z],[x2,fr+0.005,sqrt(K**2-x2**2)+z]])
+ n=len(vr);ON.extend([n-1,n-3,n-5,n-7]);AR.extend([n-2,n-4,n-6,n-8])
+ fc.append(ON);AR.reverse();fc.append(AR)
+ m=len(fc);cam.extend([m-1,m-2])
+
+ elif self.UST=='3':#Egri
+ if self.DT3=='1':H=(self.VL1/200)/u
+ elif self.DT3=='2':H=self.VL3/100
+ elif self.DT3=='3':H=sin(self.VL4*pi/180)/cos(self.VL4*pi/180)
+ z=sqrt(k1**2+(k1*H)**2)
+ k=sqrt(k2**2+(k2*H)**2)
+ f=sqrt(k3**2+(k3*H)**2)*2
+ vr[UST[0]][2]=Z[-1]+vr[UST[0]][0]*H
+ vr[UST[1]][2]=Z[-1]+vr[UST[1]][0]*H
+ for i in ALT:
+ vr[i][2] =Z[-1]+vr[i][0]*H-z
+ vr[SON[0]][2]=Z[-1]+vr[SON[0]][0]*H
+ vr[SON[1]][2]=Z[-1]+vr[SON[1]][0]*H
+ fc.append([UST[1],UST[0], SON[0],SON[1] ])
+ for i in range(0,mx*4,4):
+ fc.append([ALT[i],ALT[i+1],ALT[i+3],ALT[i+2]])
+ ON=[UST[0]]
+ AR=[UST[1]]
+ for i in range(0,len(ALT)-1,2):
+ ON.append(ALT[i ])
+ AR.append(ALT[i+1])
+ ON.append(SON[0])
+ fc.append(ON)
+ AR.append(SON[1])
+ AR.reverse();fc.append(AR)
+ y=my-1
+ for x in range(0,mx):
+ if kx[x][y]==True:
+ Kapak(vr,fc,X,Z,x*2+1,y*2+1,k2/2,(k1+k2)*0.5-0.01)
+ n=len(vr)
+ vr[n- 5][2]=Z[-1]+vr[n- 5][0]*H-z
+ vr[n- 6][2]=Z[-1]+vr[n- 6][0]*H-z-k
+ vr[n- 7][2]=Z[-1]+vr[n- 7][0]*H-z-k
+ vr[n- 8][2]=Z[-1]+vr[n- 8][0]*H-z
+ vr[n- 9][2]=Z[-1]+vr[n- 9][0]*H-z
+ vr[n-10][2]=Z[-1]+vr[n-10][0]*H-z-k
+ vr[n-11][2]=Z[-1]+vr[n-11][0]*H-z-k
+ vr[n-12][2]=Z[-1]+vr[n-12][0]*H-z
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,(k1+k2)*0.5-0.01,k2)
+ n=len(vr)
+ vr[n- 2][2]=Z[-1]+vr[n- 2][0]*H-z-k-f
+ vr[n- 3][2]=Z[-1]+vr[n- 3][0]*H-z-k-f
+ vr[n- 6][2]=Z[-1]+vr[n- 6][0]*H-z-k-f
+ vr[n- 7][2]=Z[-1]+vr[n- 7][0]*H-z-k-f
+ vr[n-13][2]=Z[-1]+vr[n-13][0]*H-z-k
+ vr[n-14][2]=Z[-1]+vr[n-14][0]*H-z-k-f
+ vr[n-15][2]=Z[-1]+vr[n-15][0]*H-z-k-f
+ vr[n-16][2]=Z[-1]+vr[n-16][0]*H-z-k
+ vr[n-17][2]=Z[-1]+vr[n-17][0]*H-z-k
+ vr[n-18][2]=Z[-1]+vr[n-18][0]*H-z-k-f
+ vr[n-19][2]=Z[-1]+vr[n-19][0]*H-z-k-f
+ vr[n-20][2]=Z[-1]+vr[n-20][0]*H-z-k
+ else:
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,0,0)
+ n=len(vr)
+ vr[n-2][2]=Z[-1]+vr[n-2][0]*H-z-f
+ vr[n-3][2]=Z[-1]+vr[n-3][0]*H-z-f
+ vr[n-6][2]=Z[-1]+vr[n-6][0]*H-z-f
+ vr[n-7][2]=Z[-1]+vr[n-7][0]*H-z-f
+ vr[n-13][2]=Z[-1]+vr[n-13][0]*H-z
+ vr[n-14][2]=Z[-1]+vr[n-14][0]*H-z-f
+ vr[n-15][2]=Z[-1]+vr[n-15][0]*H-z-f
+ vr[n-16][2]=Z[-1]+vr[n-16][0]*H-z
+ vr[n-17][2]=Z[-1]+vr[n-17][0]*H-z
+ vr[n-18][2]=Z[-1]+vr[n-18][0]*H-z-f
+ vr[n-19][2]=Z[-1]+vr[n-19][0]*H-z-f
+ vr[n-20][2]=Z[-1]+vr[n-20][0]*H-z
+ m=len(fc);cam.extend([m-1,m-2])
+ ftl.extend([m-3,m-4,m-5,m-6,m-7,m-8,m-9,m-10,m-11,m-12,m-13,m-14])
+ elif self.UST=='4':#Ucgen
+ if self.DT3=='1':H=(self.VL1/100)/u
+ elif self.DT3=='2':H=self.VL3/100
+ elif self.DT3=='3':H=sin(self.VL4*pi/180)/cos(self.VL4*pi/180)
+ z=sqrt(k1**2+(k1*H)**2)
+ k=sqrt(k2**2+(k2*H)**2)
+ f=sqrt(k3**2+(k3*H)**2)*2
+ vr[UST[0]][2]=Z[-1]+vr[UST[0]][0]*H
+ vr[UST[1]][2]=Z[-1]+vr[UST[1]][0]*H
+ for i in ALT:
+ vr[i][2] =Z[-1]-abs(vr[i][0])*H-z
+ vr[SON[0]][2]=Z[-1]-vr[SON[0]][0]*H
+ vr[SON[1]][2]=Z[-1]-vr[SON[1]][0]*H
+ vr.extend([[0,-k1/2,Z[-1]],[0, k1/2,Z[-1]]])
+
+ x = 0
+ for j in range(2,len(ALT)-2,4):
+ if vr[ALT[j]][0]<0 and 0<vr[ALT[j+2]][0]:x=1
+
+ n=len(vr)
+ fc.extend([[UST[1],UST[0],n-2,n-1],[n-1,n-2,SON[0],SON[1]]])
+ ON=[SON[0],n-2,UST[0]];AR=[SON[1],n-1,UST[1]]
+
+ if x==0:vr.extend([[0,-k1/2,Z[-1]-z],[0,k1/2,Z[-1]-z]])
+ for j in range(0,len(ALT)-2,4):
+ if vr[ALT[j]][0]<0 and vr[ALT[j+2]][0]<0:
+ fc.append([ALT[j],ALT[j+1],ALT[j+3],ALT[j+2]])
+ ON.extend([ALT[j ],ALT[j+2]])
+ AR.extend([ALT[j+1],ALT[j+3]])
+ elif vr[ALT[j]][0]>0 and vr[ALT[j+2]][0]>0:
+ fc.append([ALT[j],ALT[j+1],ALT[j+3],ALT[j+2]])
+ ON.extend([ALT[j ],ALT[j+2]])
+ AR.extend([ALT[j+1],ALT[j+3]])
+ else:
+ n=len(vr)
+ fc.extend([[ALT[j],ALT[j+1],n-1,n-2],[n-2,n-1,ALT[j+3],ALT[j+2]]])
+ ON.extend([ALT[j+0],n-2,ALT[j+2]])
+ AR.extend([ALT[j+1],n-1,ALT[j+3]])
+ fc.append(ON);AR.reverse();fc.append(AR)
+ y=my-1
+ for x in range(0,mx):
+ if vr[ALT[x*4]][0]<0 and vr[ALT[x*4+2]][0]<0:
+ if kx[x][y]==True:
+ Kapak(vr,fc,X,Z,x*2+1,y*2+1,k2/2,(k1+k2)*0.5-0.01)
+ n=len(vr)
+ vr[n- 5][2]=Z[-1]+vr[n- 5][0]*H-z
+ vr[n- 6][2]=Z[-1]+vr[n- 6][0]*H-z-k
+ vr[n- 7][2]=Z[-1]+vr[n- 7][0]*H-z-k
+ vr[n- 8][2]=Z[-1]+vr[n- 8][0]*H-z
+ vr[n- 9][2]=Z[-1]+vr[n- 9][0]*H-z
+ vr[n-10][2]=Z[-1]+vr[n-10][0]*H-z-k
+ vr[n-11][2]=Z[-1]+vr[n-11][0]*H-z-k
+ vr[n-12][2]=Z[-1]+vr[n-12][0]*H-z
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,(k1+k2)*0.5-0.01,k2)
+ n=len(vr)
+ vr[n- 2][2]=Z[-1]+vr[n- 2][0]*H-z-k-f
+ vr[n- 3][2]=Z[-1]+vr[n- 3][0]*H-z-k-f
+ vr[n- 6][2]=Z[-1]+vr[n- 6][0]*H-z-k-f
+ vr[n- 7][2]=Z[-1]+vr[n- 7][0]*H-z-k-f
+ vr[n-13][2]=Z[-1]+vr[n-13][0]*H-z-k
+ vr[n-14][2]=Z[-1]+vr[n-14][0]*H-z-k-f
+ vr[n-15][2]=Z[-1]+vr[n-15][0]*H-z-k-f
+ vr[n-16][2]=Z[-1]+vr[n-16][0]*H-z-k
+ vr[n-17][2]=Z[-1]+vr[n-17][0]*H-z-k
+ vr[n-18][2]=Z[-1]+vr[n-18][0]*H-z-k-f
+ vr[n-19][2]=Z[-1]+vr[n-19][0]*H-z-k-f
+ vr[n-20][2]=Z[-1]+vr[n-20][0]*H-z-k
+ else:
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,0,0)
+ n=len(vr)
+ vr[n-2][2]=Z[-1]+vr[n-2][0]*H-z-f
+ vr[n-3][2]=Z[-1]+vr[n-3][0]*H-z-f
+ vr[n-6][2]=Z[-1]+vr[n-6][0]*H-z-f
+ vr[n-7][2]=Z[-1]+vr[n-7][0]*H-z-f
+ vr[n-13][2]=Z[-1]+vr[n-13][0]*H-z
+ vr[n-14][2]=Z[-1]+vr[n-14][0]*H-z-f
+ vr[n-15][2]=Z[-1]+vr[n-15][0]*H-z-f
+ vr[n-16][2]=Z[-1]+vr[n-16][0]*H-z
+ vr[n-17][2]=Z[-1]+vr[n-17][0]*H-z
+ vr[n-18][2]=Z[-1]+vr[n-18][0]*H-z-f
+ vr[n-19][2]=Z[-1]+vr[n-19][0]*H-z-f
+ vr[n-20][2]=Z[-1]+vr[n-20][0]*H-z
+ m=len(fc);cam.extend([m-1,m-2])
+ ftl.extend([m-3,m-4,m-5,m-6,m-7,m-8,m-9,m-10,m-11,m-12,m-13,m-14])
+ elif vr[ALT[x*4]][0]>0 and vr[ALT[x*4+2]][0]>0:
+ if kx[x][y]==True:
+ Kapak(vr,fc,X,Z,x*2+1,y*2+1,k2/2,(k1+k2)*0.5-0.01)
+ n=len(vr)
+ vr[n- 5][2]=Z[-1]-vr[n- 5][0]*H-z
+ vr[n- 6][2]=Z[-1]-vr[n- 6][0]*H-z-k
+ vr[n- 7][2]=Z[-1]-vr[n- 7][0]*H-z-k
+ vr[n- 8][2]=Z[-1]-vr[n- 8][0]*H-z
+ vr[n- 9][2]=Z[-1]-vr[n- 9][0]*H-z
+ vr[n-10][2]=Z[-1]-vr[n-10][0]*H-z-k
+ vr[n-11][2]=Z[-1]-vr[n-11][0]*H-z-k
+ vr[n-12][2]=Z[-1]-vr[n-12][0]*H-z
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,(k1+k2)*0.5-0.01,k2)
+ n=len(vr)
+ vr[n- 2][2]=Z[-1]-vr[n- 2][0]*H-z-k-f
+ vr[n- 3][2]=Z[-1]-vr[n- 3][0]*H-z-k-f
+ vr[n- 6][2]=Z[-1]-vr[n- 6][0]*H-z-k-f
+ vr[n- 7][2]=Z[-1]-vr[n- 7][0]*H-z-k-f
+ vr[n-13][2]=Z[-1]-vr[n-13][0]*H-z-k
+ vr[n-14][2]=Z[-1]-vr[n-14][0]*H-z-k-f
+ vr[n-15][2]=Z[-1]-vr[n-15][0]*H-z-k-f
+ vr[n-16][2]=Z[-1]-vr[n-16][0]*H-z-k
+ vr[n-17][2]=Z[-1]-vr[n-17][0]*H-z-k
+ vr[n-18][2]=Z[-1]-vr[n-18][0]*H-z-k-f
+ vr[n-19][2]=Z[-1]-vr[n-19][0]*H-z-k-f
+ vr[n-20][2]=Z[-1]-vr[n-20][0]*H-z-k
+ else:
+ Fitil(vr,fc,X,Z,x*2+1,y*2+1,k3,0,0)
+ n=len(vr)
+ vr[n-2][2]=Z[-1]-vr[n-2][0]*H-z-f
+ vr[n-3][2]=Z[-1]-vr[n-3][0]*H-z-f
+ vr[n-6][2]=Z[-1]-vr[n-6][0]*H-z-f
+ vr[n-7][2]=Z[-1]-vr[n-7][0]*H-z-f
+ vr[n-13][2]=Z[-1]-vr[n-13][0]*H-z
+ vr[n-14][2]=Z[-1]-vr[n-14][0]*H-z-f
+ vr[n-15][2]=Z[-1]-vr[n-15][0]*H-z-f
+ vr[n-16][2]=Z[-1]-vr[n-16][0]*H-z
+ vr[n-17][2]=Z[-1]-vr[n-17][0]*H-z
+ vr[n-18][2]=Z[-1]-vr[n-18][0]*H-z-f
+ vr[n-19][2]=Z[-1]-vr[n-19][0]*H-z-f
+ vr[n-20][2]=Z[-1]-vr[n-20][0]*H-z
+ m=len(fc);cam.extend([m-1,m-2])
+ ftl.extend([m-3,m-4,m-5,m-6,m-7,m-8,m-9,m-10,m-11,m-12,m-13,m-14])
+ else:
+ k4=k3*2
+ if kx[x][y]==True:
+ zz=(k1+k2)*0.5-0.01
+ xx=X[x*2+1]
+ vr.extend([[xx,-k2/2+zz,Z[-3] ],[xx+k2,-k2/2+zz,Z[-3] +k2 ],[xx+k2,k2/2+zz,Z[-3] +k2 ],[xx,k2/2+zz,Z[-3] ]])
+ vr.extend([[xx,-k2/2+zz,Z[-1]+xx*H-z],[xx+k2,-k2/2+zz,Z[-1]+(xx+k2)*H-z-k],[xx+k2,k2/2+zz,Z[-1]+(xx+k2)*H-z-k],[xx,k2/2+zz,Z[-1]+xx*H-z]])
+ vr.extend([[ 0,-k2/2+zz,Z[-1] -z],[ 0,-k2/2+zz,Z[-1] -z-k],[ 0,k2/2+zz,Z[-1] -z-k],[ 0,k2/2+zz,Z[-1] -z]])
+ xx=X[x*2+2]
+ vr.extend([[xx,-k2/2+zz,Z[-1]-xx*H-z],[xx-k2,-k2/2+zz,Z[-1]-(xx-k2)*H-z-k],[xx-k2,k2/2+zz,Z[-1]-(xx-k2)*H-z-k],[xx,k2/2+zz,Z[-1]-xx*H-z]])
+ vr.extend([[xx,-k2/2+zz,Z[-3] ],[xx-k2,-k2/2+zz,Z[-3] +k2 ],[xx-k2,k2/2+zz,Z[-3] +k2 ],[xx,k2/2+zz,Z[-3] ]])
+ n=len(vr)
+ fc.extend([[n-20,n-19,n-15,n-16],[n-19,n-18,n-14,n-15],[n-18,n-17,n-13,n-14],[n-17,n-20,n-16,n-13]])
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10],[n-13,n-16,n-12,n- 9]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6],[n- 9,n-12,n- 8,n- 5]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2],[n- 5,n- 8,n- 4,n- 1]])
+ fc.extend([[n- 4,n- 3,n-19,n-20],[n- 3,n- 2,n-18,n-19],[n- 2,n- 1,n-17,n-18],[n- 1,n- 4,n-20,n-17]])
+ xx=X[x*2+1]
+ vr.extend([[xx +k2,-k3+zz,Z[-3] +k2 ],[xx+k4+k2,-k3+zz,Z[-3] +k2+k4 ],[xx+k4+k2, k3+zz,Z[-3] +k2+k4 ],[xx +k2, k3+zz,Z[-3] +k2 ]])
+ vr.extend([[xx +k2,-k3+zz,Z[-1]+(xx+k2 )*H-z-k ],[xx+k4+k2,-k3+zz,Z[-1]+(xx+k2+k4)*H-z-k-f],[xx+k4+k2, k3+zz,Z[-1]+(xx+k2+k4)*H-z-k-f],[xx +k2, k3+zz,Z[-1]+(xx+k2 )*H-z-k ]])
+ vr.extend([[ 0,-k3+zz,Z[-1]-k -z],[ 0,-k3+zz,Z[-1]-k -z-f],[ 0,k3+zz,Z[-1]-k -z-f],[ 0,k3+zz,Z[-1]-k -z]])
+ xx=X[x*2+2]
+ vr.extend([[xx -k2,-k3+zz,Z[-1]-(xx-k2 )*H-z-k ],[xx-k4-k2,-k3+zz,Z[-1]-(xx-k2-k4)*H-z-k-f],[xx-k4-k2, k3+zz,Z[-1]-(xx-k2-k4)*H-z-k-f],[xx -k2, k3+zz,Z[-1]-(xx-k2 )*H-z-k ]])
+ vr.extend([[xx -k2,-k3+zz,Z[-3] +k2 ],[xx-k4-k2,-k3+zz,Z[-3] +k2+k4 ],[xx-k4-k2, k3+zz,Z[-3] +k2+k4 ],[xx -k2, k3+zz,Z[-3] +k2 ]])
+ n=len(vr)
+ fc.extend([[n-20,n-19,n-15,n-16],[n-19,n-18,n-14,n-15],[n-18,n-17,n-13,n-14]])
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2]])
+ fc.extend([[n- 4,n- 3,n-19,n-20],[n- 3,n- 2,n-18,n-19],[n- 2,n- 1,n-17,n-18]])
+ xx=X[x*2+1]
+ vr.extend([[xx+k4+k2,-k3+zz,Z[-3] +k2+k4 ],[xx+k4+k2, k3+zz,Z[-3] +k2+k4 ]])
+ vr.extend([[xx+k4+k2,-k3+zz,Z[-1]+(xx+k2+k4)*H-z-k-f],[xx+k4+k2, k3+zz,Z[-1]+(xx+k2+k4)*H-z-k-f]])
+ vr.extend([[ 0,-k3+zz,Z[-1]-k -z-f],[ 0,k3+zz,Z[-1]-k -z-f]])
+ xx=X[x*2+2]
+ vr.extend([[xx-k4-k2,-k3+zz,Z[-1]-(xx-k2-k4)*H-z-k-f],[xx-k4-k2, k3+zz,Z[-1]-(xx-k2-k4)*H-z-k-f]])
+ vr.extend([[xx-k4-k2,-k3+zz,Z[-3] +k2+k4 ],[xx-k4-k2, k3+zz,Z[-3] +k2+k4 ]])
+ fc.extend([[n+8,n+6,n+4,n+2,n+0],[n+1,n+3,n+5,n+7,n+9]])
+ else:
+ xx=X[x*2+1]
+ vr.extend([[xx,-k3,Z[-3] ],[xx+k4,-k3,Z[-3] +k4 ],[xx+k4,k3,Z[-3] +k4 ],[xx,k3,Z[-3] ]])
+ vr.extend([[xx,-k3,Z[-1]+xx*H-z],[xx+k4,-k3,Z[-1]+(xx+k4)*H-z-f],[xx+k4,k3,Z[-1]+(xx+k4)*H-z-f],[xx,k3,Z[-1]+xx*H-z]])
+ vr.extend([[ 0,-k3,Z[-1] -z],[ 0,-k3,Z[-1] -z-f],[ 0,k3,Z[-1] -z-f],[ 0,k3,Z[-1] -z]])
+ xx=X[x*2+2]
+ vr.extend([[xx,-k3,Z[-1]-xx*H-z],[xx-k4,-k3,Z[-1]-(xx-k4)*H-z-f],[xx-k4,k3,Z[-1]-(xx-k4)*H-z-f],[xx,k3,Z[-1]-xx*H-z]])
+ vr.extend([[xx,-k3,Z[-3] ],[xx-k4,-k3,Z[-3] +k4 ],[xx-k4,k3,Z[-3] +k4 ],[xx,k3,Z[-3] ]])
+ n=len(vr)
+ fc.extend([[n-20,n-19,n-15,n-16],[n-19,n-18,n-14,n-15],[n-18,n-17,n-13,n-14]])
+ fc.extend([[n-16,n-15,n-11,n-12],[n-15,n-14,n-10,n-11],[n-14,n-13,n- 9,n-10]])
+ fc.extend([[n-12,n-11,n- 7,n- 8],[n-11,n-10,n- 6,n- 7],[n-10,n- 9,n- 5,n- 6]])
+ fc.extend([[n- 8,n- 7,n- 3,n- 4],[n- 7,n- 6,n- 2,n- 3],[n- 6,n- 5,n- 1,n- 2]])
+ fc.extend([[n- 4,n- 3,n-19,n-20],[n- 3,n- 2,n-18,n-19],[n- 2,n- 1,n-17,n-18]])
+ xx=X[x*2+1]
+ vr.extend([[xx+k4,-0.005,Z[-3] +k4 ],[xx+k4,0.005,Z[-3] +k4 ]])
+ vr.extend([[xx+k4,-0.005,Z[-1]+(xx+k4)*H-z-f],[xx+k4,0.005,Z[-1]+(xx+k4)*H-z-f]])
+ vr.extend([[ 0,-0.005,Z[-1] -z-f],[ 0,0.005,Z[-1] -z-f]])
+ xx=X[x*2+2]
+ vr.extend([[xx-k4,-0.005,Z[-1]-(xx-k4)*H-z-f],[xx-k4,0.005,Z[-1]-(xx-k4)*H-z-f]])
+ vr.extend([[xx-k4,-0.005,Z[-3] +k4 ],[xx-k4,0.005,Z[-3] +k4 ]])
+ fc.extend([[n+8,n+6,n+4,n+2,n+0],[n+1,n+3,n+5,n+7,n+9]])
+ m=len(fc);cam.extend([m-1,m-2])
+ ftl.extend([m-3,m-4,m-5,m-6,m-7,m-8,m-9,m-10,m-11,m-12,m-13,m-14,m-15,m-16,m-17])
+ #Mermer
+ if self.mr==True:
+ mrh=-self.mr1/100;mrg= self.mr2/100
+ mdv=(self.mr3/200)+mrg;msv=-(mdv+(self.mr4/100))
+ vr.extend([[-u,mdv,0],[u,mdv,0],[-u,msv,0],[u,msv,0],[-u,mdv,mrh],[u,mdv,mrh],[-u,msv,mrh],[u,msv,mrh]])
+ n=len(vr);fc.extend([[n-1,n-2,n-4,n-3],[n-3,n-4,n-8,n-7],[n-6,n-5,n-7,n-8],[n-2,n-1,n-5,n-6],[n-4,n-2,n-6,n-8],[n-5,n-1,n-3,n-7]])
+ n=len(fc);mer.extend([n-1,n-2,n-3,n-4,n-5,n-6])
+#OBJE -----------------------------------------------------------
+ mesh = bpy.data.meshes.new(name='Window')
+ mesh.from_pydata(vr,[],fc)
+ if self.mt1=='1':mesh.materials.append(MAT('PVC', 1.0,1.0,1.0))
+ elif self.mt1=='2':mesh.materials.append(MAT('Wood', 0.3,0.2,0.1))
+ elif self.mt1=='3':mesh.materials.append(MAT('Plastic',0.0,0.0,0.0))
+
+ if self.mt2=='1':mesh.materials.append(MAT('PVC', 1.0,1.0,1.0))
+ elif self.mt2=='2':mesh.materials.append(MAT('Wood', 0.3,0.2,0.1))
+ elif self.mt2=='3':mesh.materials.append(MAT('Plastic',0.0,0.0,0.0))
+
+ mesh.materials.append(MAT('Glass',0.5,0.8,1.0))
+ if self.mr==True:mesh.materials.append(MAT('Marble', 0.9,0.8,0.7))
+
+ for i in ftl:
+ mesh.polygons[i].material_index=1
+ for i in cam:
+ mesh.polygons[i].material_index=2
+ for i in mer:
+ mesh.polygons[i].material_index=3
+ for i in SM:
+ mesh.polygons[i].use_smooth = 1
+ mesh.update(calc_edges=True)
+ from bpy_extras import object_utils
+ return object_utils.object_data_add(context, mesh, operator=None)
+ if bpy.context.mode!='EDIT_MESH':
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+#----------------------------------------------------------------
+class PENCERE(bpy.types.Operator):
+ bl_idname = "mesh.add_say3d_pencere2"
+ bl_label = "Window"
+ bl_description = "Window Generator"
+ bl_options = {'REGISTER', 'UNDO'}
+ prs = EnumProperty(items = (('1',"WINDOW 250X200",""),
+ ('2',"WINDOW 200X200",""),
+ ('3',"WINDOW 180X200",""),
+ ('4',"WINDOW 180X160",""),
+ ('5',"WINDOW 160X160",""),
+ ('6',"WINDOW 50X50",""),
+ ('7',"DOOR 80X250",""),
+ ('8',"DOOR 80X230","")),
+ name="")
+ son=prs
+ gen=IntProperty(name='H Count', min=1,max= 8, default= 3, description='Horizontal Panes')
+ yuk=IntProperty(name='V Count', min=1,max= 5, default= 1, description='Vertical Panes')
+ kl1=IntProperty(name='Outer Frame', min=2,max=50, default= 5, description='Outside Frame Thickness')
+ kl2=IntProperty(name='Risers', min=2,max=50, default= 5, description='Risers Width')
+ fk =IntProperty(name='Inner Frame', min=1,max=20, default= 2, description='Inside Frame Thickness')
+
+ mr=BoolProperty(name='Sill', default=True,description='Window Sill')
+ mr1=IntProperty(name='',min=1, max=20, default= 4, description='Height')
+ mr2=IntProperty(name='',min=0, max=20, default= 4, description='First Depth')
+ mr3=IntProperty(name='',min=1, max=50, default=20, description='Second Depth')
+ mr4=IntProperty(name='',min=0, max=50, default= 0, description='Extrusion for Jamb')
+
+ mt1=EnumProperty(items =(('1',"PVC",""),('2',"WOOD",""),('3',"Plastic","")),name="",default='1')
+ mt2=EnumProperty(items =(('1',"PVC",""),('2',"WOOD",""),('3',"Plastic","")),name="",default='3')
+
+ UST=EnumProperty(items =(('1',"Flat",""),('2',"Arch", ""),('3',"Inclined", ""),('4',"Triangle","")),name="Top",default='1')
+ DT2=EnumProperty(items =(('1',"Difference",""),('2',"Radius", "")), name="",default='1')
+ DT3=EnumProperty(items =(('1',"Difference",""),('2',"Incline %",""),('3',"Incline Angle","")),name="",default='1')
+
+ VL1=IntProperty( name='',min=-10000,max=10000,default=30)#Fark
+ VL2=IntProperty( name='',min= 1,max=10000,default=30)#Cap
+ VL3=IntProperty( name='',min= -100,max= 100,default=30)#Egim %
+ VL4=IntProperty( name='',min= -45,max= 45,default=30)#Egim Aci
+
+ RES=IntProperty(name='Resolution pi/',min=2,max=360,default=36)#Res
+
+ gnx0=IntProperty(name='',min=1,max=300,default= 60,description='1st Window Width')
+ gnx1=IntProperty(name='',min=1,max=300,default=110,description='2nd Window Width')
+ gnx2=IntProperty(name='',min=1,max=300,default= 60,description='3rd Window Width')
+ gnx3=IntProperty(name='',min=1,max=300,default= 60,description='4th Window Width')
+ gnx4=IntProperty(name='',min=1,max=300,default= 60,description='5th Window Width')
+ gnx5=IntProperty(name='',min=1,max=300,default= 60,description='6th Window Width')
+ gnx6=IntProperty(name='',min=1,max=300,default= 60,description='7th Window Width')
+ gnx7=IntProperty(name='',min=1,max=300,default= 60,description='8th Window Width')
+
+ gny0=IntProperty(name='',min=1,max=300,default=190,description='1st Row Height')
+ gny1=IntProperty(name='',min=1,max=300,default= 45,description='2nd Row Height')
+ gny2=IntProperty(name='',min=1,max=300,default= 45,description='3rd Row Height')
+ gny3=IntProperty(name='',min=1,max=300,default= 45,description='4th Row Height')
+ gny4=IntProperty(name='',min=1,max=300,default= 45,description='5th Row Height')
+
+ k00=BoolProperty(name='',default=True); k01=BoolProperty(name='',default=False)
+ k02=BoolProperty(name='',default=True); k03=BoolProperty(name='',default=False)
+ k04=BoolProperty(name='',default=False);k05=BoolProperty(name='',default=False)
+ k06=BoolProperty(name='',default=False);k07=BoolProperty(name='',default=False)
+
+ k10=BoolProperty(name='',default=False);k11=BoolProperty(name='',default=False)
+ k12=BoolProperty(name='',default=False);k13=BoolProperty(name='',default=False)
+ k14=BoolProperty(name='',default=False);k15=BoolProperty(name='',default=False)
+ k16=BoolProperty(name='',default=False);k17=BoolProperty(name='',default=False)
+
+ k20=BoolProperty(name='',default=False);k21=BoolProperty(name='',default=False)
+ k22=BoolProperty(name='',default=False);k23=BoolProperty(name='',default=False)
+ k24=BoolProperty(name='',default=False);k25=BoolProperty(name='',default=False)
+ k26=BoolProperty(name='',default=False);k27=BoolProperty(name='',default=False)
+
+ k30=BoolProperty(name='',default=False);k31=BoolProperty(name='',default=False)
+ k32=BoolProperty(name='',default=False);k33=BoolProperty(name='',default=False)
+ k34=BoolProperty(name='',default=False);k35=BoolProperty(name='',default=False)
+ k36=BoolProperty(name='',default=False);k37=BoolProperty(name='',default=False)
+
+ k40=BoolProperty(name='',default=False);k41=BoolProperty(name='',default=False)
+ k42=BoolProperty(name='',default=False);k43=BoolProperty(name='',default=False)
+ k44=BoolProperty(name='',default=False);k45=BoolProperty(name='',default=False)
+ k46=BoolProperty(name='',default=False);k47=BoolProperty(name='',default=False)
+ #--------------------------------------------------------------
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self,'prs')
+ box=layout.box()
+ box.prop(self,'gen');box.prop(self,'yuk')
+ box.prop(self,'kl1');box.prop(self,'kl2')
+ box.prop(self, 'fk')
+
+ box.prop(self,'mr')
+ if self.mr==True:
+ row=box.row();row.prop(self,'mr1');row.prop(self,'mr2')
+ row=box.row();row.prop(self,'mr3');row.prop(self,'mr4')
+ row =layout.row();row.label('Frame');row.label('Inner Frame')
+ row =layout.row();row.prop(self,'mt1');row.prop(self,'mt2')
+
+ box.prop(self,'UST')
+ if self.UST=='2':
+ row= box.row(); row.prop(self,'DT2')
+ if self.DT2=='1':row.prop(self,'VL1')
+ elif self.DT2=='2':row.prop(self,'VL2')
+ box.prop(self,'RES')
+ elif self.UST=='3':
+ row= box.row(); row.prop(self,'DT3')
+ if self.DT3=='1':row.prop(self,'VL1')
+ elif self.DT3=='2':row.prop(self,'VL3')
+ elif self.DT3=='3':row.prop(self,'VL4')
+ elif self.UST=='4':
+ row= box.row(); row.prop(self,'DT3')
+ if self.DT3=='1':row.prop(self,'VL1')
+ elif self.DT3=='2':row.prop(self,'VL3')
+ elif self.DT3=='3':row.prop(self,'VL4')
+ row =layout.row()
+ for i in range(0,self.gen):
+ row.prop(self,'gnx'+str(i))
+ for j in range(0,self.yuk):
+ row=layout.row()
+ row.prop(self,'gny'+str(self.yuk-j-1))
+ for i in range(0,self.gen):
+ row.prop(self,'k'+str(self.yuk-j-1)+str(i))
+ def execute(self, context):
+ if self.son!=self.prs:
+ Prs(self)
+ self.son=self.prs
+ add_object(self,context)
+ return {'FINISHED'}
+# Registration
+def menu_func_pencere(self, context):
+ self.layout.operator(PENCERE.bl_idname,text="Window",icon="MOD_LATTICE")
+def register():
+ bpy.utils.register_class(PENCERE)
+ bpy.types.INFO_MT_mesh_add.append(menu_func_pencere)
+def unregister():
+ bpy.utils.unregister_class(PENCERE)
+ bpy.types.INFO_MT_mesh_add.remove(menu_func_pencere)
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/general.py b/release/scripts/addons_contrib/add_mesh_building_objects/general.py
new file mode 100644
index 0000000..4012735
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/general.py
@@ -0,0 +1,65 @@
+# Stairbuilder - General
+#
+# General is an object for creating meshes given the verts and faces.
+# Stair Type (typ):
+# - id1 = Freestanding staircase
+# - id2 = Housed-open staircase
+# - id3 = Box staircase
+# - id4 = Circular staircase
+#
+# Paul "BrikBot" Marshall
+# Created: September 19, 2011
+# Last Modified: January 29, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.61.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import bpy
+from bpy_extras import object_utils
+from math import atan
+from mathutils import Vector
+
+class General:
+ def __init__(self,rise,run,N):
+ self.stop=float(N)*Vector([run,0,rise])
+ self.slope=rise/run
+ self.angle=atan(self.slope)
+ #identical quads for all objects except stringer
+ self.faces=[[0,1,3,2],[0,1,5,4],[0,2,6,4],[4,5,7,6],[2,3,7,6],[1,3,7,5]]
+
+ def Make_mesh(self, verts, faces, name):
+ # Create new mesh
+ mesh = bpy.data.meshes.new(name)
+
+ # Make a mesh from a list of verts/edges/faces.
+ mesh.from_pydata(verts, [], faces)
+
+ # Set mesh to use auto smoothing:
+ mesh.use_auto_smooth = True
+
+ # Update mesh geometry after adding stuff.
+ mesh.update()
+
+ return object_utils.object_data_add(bpy.context, mesh, operator=None)
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/post.py b/release/scripts/addons_contrib/add_mesh_building_objects/post.py
new file mode 100644
index 0000000..949e081
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/post.py
@@ -0,0 +1,87 @@
+# Stairbuilder - Post generation
+#
+# Generates posts for stair generation.
+# Stair Type (typ):
+# - id1 = Freestanding staircase
+# - id2 = Housed-open staircase
+# - id3 = Box staircase
+# - id4 = Circular staircase
+#
+# Paul "BrikBot" Marshall
+# Created: September 19, 2011
+# Last Modified: January 29, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.61.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+from mathutils import Vector
+
+class Posts:
+ def __init__(self,G,rise,run,d,w,wT,nP,hR,tR, rEnable, lEnable):
+ self.G = G #General
+ self.rise = rise #Stair rise
+ self.run = run #Stair run
+ self.x1=Vector([0,0,hR-tR]) #rail start
+ self.x2=G.stop+Vector([0,0,hR-tR]) #rail stop
+ self.d=d #post depth
+ self.w=w #post width
+ self.wT=wT #tread width
+ self.nP=nP #number of posts
+ self.sp=Vector([(self.x2[0]-self.x1[0])/float(nP+1),0,0]) #spacing between posts
+ self.rEnable = rEnable
+ self.lEnable = lEnable
+ self.Create()
+
+ def Intersect(self,i,d):
+ """find intersection point, x, for rail and post"""
+ x3=self.x1+i*self.sp+Vector([d,d,d])
+ x4=x3+Vector([0,0,self.x2[-1]])
+ a=self.x2-self.x1
+ b=x4-x3
+ c=x3-self.x1
+ cr_ab=a.cross(b)
+ mag_cr_ab=(cr_ab * cr_ab)
+ return self.x1+a*((c.cross(b).dot(cr_ab))/mag_cr_ab)
+
+ def Create(self):
+ for i in range(0,self.nP+2,1):
+ coords = []
+ #intersections with rail
+ coords.append(self.Intersect(i,0.0))
+ coords.append(self.Intersect(i,self.d))
+ #intersections with tread
+ coords.append(Vector([self.x1[0]+i*self.sp[0],0,
+ int(coords[0][0]/self.run)*self.rise]))
+ coords.append(coords[2]+Vector([self.d,0,0]))
+ #inner face
+ for j in range(4):
+ coords.append(coords[j]+Vector([0,self.w,0]))
+ if self.rEnable:
+ self.G.Make_mesh(coords, self.G.faces, 'posts')
+ if self.lEnable:
+ #make post on other side of steps as well
+ for j in coords:
+ j += Vector([0,self.wT-self.w,0])
+ self.G.Make_mesh(coords, self.G.faces, 'posts')
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/rail.py b/release/scripts/addons_contrib/add_mesh_building_objects/rail.py
new file mode 100644
index 0000000..85c31dd
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/rail.py
@@ -0,0 +1,79 @@
+# Stairbuilder - Retainer generation
+#
+# Generates retainers for stair generation.
+# Stair Type (typ):
+# - id1 = Freestanding staircase
+# - id2 = Housed-open staircase
+# - id3 = Box staircase
+# - id4 = Circular staircase
+#
+# Paul "BrikBot" Marshall
+# Created: September 19, 2011
+# Last Modified: January 29, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.61.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+from math import tan
+from mathutils import Vector
+
+class Rails:
+ def __init__(self,G,w,t,h,tT,wP,dP,wT, rEnable, lEnable):
+ self.G = G #General
+ self.w=w #rail width
+ self.t=t #rail thickness
+ self.h=h #rail height
+ self.start=Vector([0,0,self.h-self.t]) #rail start
+ self.stop=G.stop+Vector([0,0,self.h-self.t]) #rail stop
+ self.tT=tT #tread toe
+ self.wP=wP #post width
+ self.dP=dP #post depth
+ self.wT=wT #tread width
+ self.rEnable = rEnable
+ self.lEnable = lEnable
+ self.Create()
+
+ def Create(self):
+ #determine offset to include railing toe
+ offset=Vector([self.tT,0,self.tT*tan(self.G.angle)])
+ coords = []
+ coords.append(self.start-offset)
+ coords.append(self.stop+offset+Vector([self.dP,0,
+ self.dP*tan(self.G.angle)]))
+ coords.append(self.start-offset+Vector([0,self.w,0]))
+ coords.append(self.stop+offset+Vector([self.dP,self.w,
+ self.dP*tan(self.G.angle)]))
+ for j in range(4):
+ coords.append(coords[j]+Vector([0,0,self.t]))
+ #centre over posts
+ for j in coords:
+ j += Vector([0,0.5*(-self.w+self.wP),0])
+ if self.rEnable:
+ self.G.Make_mesh(coords, self.G.faces, 'rails')
+ if self.lEnable:
+ #make rail on other side
+ for j in coords:
+ j += Vector([0,self.wT-self.wP,0])
+ self.G.Make_mesh(coords, self.G.faces, 'rails')
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/retainer.py b/release/scripts/addons_contrib/add_mesh_building_objects/retainer.py
new file mode 100644
index 0000000..8c8a22c
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/retainer.py
@@ -0,0 +1,73 @@
+# Stairbuilder - Retainer generation
+#
+# Generates retainers for stair generation.
+# Stair Type (typ):
+# - id1 = Freestanding staircase
+# - id2 = Housed-open staircase
+# - id3 = Box staircase
+# - id4 = Circular staircase
+#
+# Paul "BrikBot" Marshall
+# Created: September 19, 2011
+# Last Modified: January 29, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.61.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+from mathutils import Vector
+
+class Retainers:
+ def __init__(self,G,w,h,wP,wT,hR,n, rEnable, lEnable):
+ self.G = G #General
+ self.w=w #retainer width
+ self.h=h #retainer height
+ self.wP=wP #post width
+ self.wT=wT #tread width
+ self.nR=n #number of retainers
+ self.sp=hR/float(n+1) #retainer spacing
+ self.rEnable = rEnable
+ self.lEnable = lEnable
+ self.Create()
+
+ def Create(self):
+ for i in range(self.nR):
+ coords = []
+ offset=(i+1)*Vector([0,0,self.sp])
+ coords.append(offset)
+ coords.append(self.G.stop + offset)
+ coords.append(offset + Vector([0,self.w,0]))
+ coords.append(self.G.stop + offset + Vector([0,self.w,0]))
+ for j in range(4):
+ coords.append(coords[j] + Vector([0,0,self.h]))
+ #centre in posts
+ for j in coords:
+ j += Vector([0,0.5*(self.wP-self.w),0])
+ if self.rEnable:
+ self.G.Make_mesh(coords, self.G.faces, 'retainers')
+ if self.lEnable:
+ #make retainer on other side
+ for j in coords:
+ j += Vector([0,self.wT-self.wP,0])
+ self.G.Make_mesh(coords,self.G.faces, 'retainers')
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/stairbuilder.py b/release/scripts/addons_contrib/add_mesh_building_objects/stairbuilder.py
new file mode 100644
index 0000000..0c2336b
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/stairbuilder.py
@@ -0,0 +1,561 @@
+# Stairs and railing creator script for blender 2.49
+# Author: Nick van Adium
+# Date: 2010 08 09
+#
+# Creates a straight-run staircase with railings and stringer
+# All components are optional and can be turned on and off by setting e.g. makeTreads=True or makeTreads=False
+# No GUI for the script, all parameters must be defined below
+# Current values assume 1 blender unit = 1 metre
+#
+# Stringer will rest on lower landing and hang from upper landing
+# Railings start on the lowest step and end on the upper landing
+#
+# NOTE: You must have numpy installed for this script to work!
+# numpy is used to easily perform the necessary algebra
+# numpy can be found at http://www.scipy.org/Download
+#
+# Note: I'm not sure how to use recalcNormals so not all normals points ouwards.
+# Perhaps someone else can contribute this.
+#
+#-----------------------------------------------------------
+#
+# Converted to Blender 2.5:
+# - Still uses NumPy.
+# - Classes are basically copy-paste from the original code
+# - New Make_mesh copied from BrikBot's rock generator
+# - Implemented standard add mesh GUI.
+# @todo:
+# - global vs. local needs cleaned up.
+# - Join separate stringer objects and then clean up the mesh.
+# - Put all objects into a group.
+# - Generate left/right posts/railings/retainers separatly with
+# option to disable just the left/right.
+# - Add wall railing type as an option for left/right
+# - Add different rail styles (profiles). Select with enum.
+# - Should have a non-NumPy code path for cross-compatability.
+# - Could be another file with equivalent classes/functions?
+# Then we would just import from there instead of from
+# NumPy without having to change the actual code. It
+# would instead be a "try-except" block that trys to use
+# NumPy.
+# - Would like to add additional staircase types.
+# - Spiral staircase
+# - "L" staircase
+# - "T" staircase
+#
+# Last Modified By: Paul "brikbot" Marshall
+# Last Modification: January 29, 2011
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+#-----------------------------------------------------------
+# BEGIN NEW B2.5/Py3.2 CODE
+import bpy
+from add_mesh_building_objects.general import General
+from add_mesh_building_objects.post import Posts
+from add_mesh_building_objects.rail import Rails
+from add_mesh_building_objects.retainer import Retainers
+from add_mesh_building_objects.stringer import Stringer
+from add_mesh_building_objects.tread import Treads
+from bpy.props import (BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty)
+from mathutils import Vector
+
+global G
+global typ
+global typ_s
+global typ_t
+global rise
+global run
+
+class stairs(bpy.types.Operator):
+ """Add stair objects"""
+ bl_idname = "mesh.stairs"
+ bl_label = "Add Stairs"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Add stairs"
+
+ # Stair types for enum:
+ id1 = ("id1", "Freestanding", "Generate a freestanding staircase.")
+ id2 = ("id2", "Housed-Open", "Generate a housed-open staircase.")
+ id3 = ("id3", "Box", "Generate a box staircase.")
+ id4 = ("id4", "Circular", "Generate a circular or spiral staircase.")
+
+ # Tread types for enum:
+ tId1 = ("tId1", "Classic", "Generate wooden style treads")
+ tId2 = ("tId2", "Basic Steel", "Generate common steel style treads")
+ tId3 = ("tId3", "Bar 1", "Generate bar/slat steel treads")
+ tId4 = ("tId4", "Bar 2", "Generate bar-grating steel treads")
+ tId5 = ("tId5", "Bar 3", "Generate bar-support steel treads")
+
+ # Stringer types for enum:
+ sId1 = ("sId1", "Classic", "Generate a classic style stringer")
+ sId2 = ("sId2", "I-Beam", "Generate a steel I-beam stringer")
+ sId3 = ("sId3", "C-Beam", "Generate a C-channel style stringer")
+
+ typ = EnumProperty(name = "Type",
+ description = "Type of staircase to generate",
+ items = [id1, id2, id3, id4])
+
+ rise = FloatProperty(name = "Rise",
+ description = "Single tread rise",
+ min = 0.0, max = 1024.0,
+ default = 0.20)
+ run = FloatProperty(name = "Run",
+ description = "Single tread run",
+ min = 0.0, max = 1024.0,
+ default = 0.30)
+
+ #for circular
+ rad1 = FloatProperty(name = "Inner Radius",
+ description = "Inner radius for circular staircase",
+ min = 0.0, max = 1024.0,
+ soft_max = 10.0,
+ default = 0.25)
+ rad2 = FloatProperty(name = "Outer Radius",
+ description = "Outer radius for circular staircase",
+ min = 0.0, max = 1024.0,
+ soft_min = 0.015625, soft_max = 32.0,
+ default = 1.0)
+ deg = FloatProperty(name = "Degrees",
+ description = "Number of degrees the stairway rotates",
+ min = 0.0, max = 92160.0, step = 5.0,
+ default = 450.0)
+ center = BoolProperty(name = "Center Pillar",
+ description = "Generate a central pillar",
+ default = False)
+
+ #for treads
+ make_treads = BoolProperty(name = "Make Treads",
+ description = "Enable tread generation",
+ default = True)
+ tread_w = FloatProperty(name = "Tread Width",
+ description = "Width of each generated tread",
+ min = 0.0001, max = 1024.0,
+ default = 1.2)
+ tread_h = FloatProperty(name = "Tread Height",
+ description = "Height of each generated tread",
+ min = 0.0001, max = 1024.0,
+ default = 0.04)
+ tread_t = FloatProperty(name = "Tread Toe",
+ description = "Toe (aka \"nosing\") of each generated tread",
+ min = 0.0, max = 10.0,
+ default = 0.03)
+ tread_o = FloatProperty(name = "Tread Overhang",
+ description = "How much tread \"overhangs\" the sides",
+ min = 0.0, max = 1024.0,
+ default = 0.025)
+ tread_n = IntProperty(name = "Number of Treads",
+ description = "How many treads to generate",
+ min = 1, max = 1024,
+ default = 10)
+ typ_t = EnumProperty(name = "Tread Type",
+ description = "Type/style of treads to generate",
+ items = [tId1, tId2, tId3, tId4, tId5])
+ tread_tk = FloatProperty(name = "Thickness",
+ description = "Thickness of the treads",
+ min = 0.0001, max = 10.0,
+ default = 0.02)
+ tread_sec = IntProperty(name = "Sections",
+ description = "Number of sections to use for tread",
+ min = 1, max = 1024,
+ default = 5)
+ tread_sp = IntProperty(name = "Spacing",
+ description = "Total spacing between tread sections as a percentage of total tread width",
+ min = 0, max = 80,
+ default = 5)
+ tread_sn = IntProperty(name = "Crosses",
+ description = "Number of cross section supports",
+ min = 2, max = 1024,
+ default = 4)
+ #special circular tread properties:
+ tread_slc = IntProperty(name = "Slices",
+ description = "Number of slices each tread is composed of",
+ min = 1, max = 1024,
+ soft_max = 16,
+ default = 4)
+
+ #for posts
+ make_posts = BoolProperty(name = "Make Posts",
+ description = "Enable post generation",
+ default = True)
+ post_d = FloatProperty(name = "Post Depth",
+ description = "Depth of generated posts",
+ min = 0.0001, max = 10.0,
+ default = 0.04)
+ post_w = FloatProperty(name = "Post Width",
+ description = "Width of generated posts",
+ min = 0.0001, max = 10.0,
+ default = 0.04)
+ post_n = IntProperty(name = "Number of Posts",
+ description = "Number of posts to generated",
+ min = 1, max = 1024,
+ default = 5)
+
+ #for railings
+ make_railings = BoolProperty(name = "Make Railings",
+ description = "Generate railings",
+ default = True)
+ rail_w = FloatProperty(name = "Railings Width",
+ description = "Width of railings to generate",
+ min = 0.0001, max = 10.0,
+ default = 0.12)
+ rail_t = FloatProperty(name = "Railings Thickness",
+ description = "Thickness of railings to generate",
+ min = 0.0001, max = 10.0,
+ default = 0.03)
+ rail_h = FloatProperty(name = "Railings Height",
+ description = "Height of railings to generate",
+ min = 0.0001, max = 10.0,
+ default = 0.90)
+
+ #for retainers
+ make_retainers = BoolProperty(name = "Make Retainers",
+ description = "Generate retainers",
+ default = True)
+ ret_w = FloatProperty(name = "Retainer Width",
+ description = "Width of generated retainers",
+ min = 0.0001, max = 10.0,
+ default = 0.01)
+ ret_h = FloatProperty(name = "Retainer Height",
+ description = "Height of generated retainers",
+ min = 0.0001, max = 10.0,
+ default = 0.01)
+ ret_n = IntProperty(name = "Number of Retainers",
+ description = "Number of retainers to generated",
+ min = 1, max = 1024,
+ default = 3)
+
+ #for stringer
+ make_stringer = BoolProperty(name = "Make Stringer",
+ description = "Generate stair stringer",
+ default = True)
+ typ_s = EnumProperty(name = "Stringer Type",
+ description = "Type/style of stringer to generate",
+ items = [sId1, sId2, sId3])
+ string_n = IntProperty(name = "Number of Stringers",
+ description = "Number of stringers to generate",
+ min = 1, max = 10,
+ default = 1)
+ string_dis = BoolProperty(name = "Distributed",
+ description = "Use distributed stringers",
+ default = False)
+ string_w = FloatProperty(name = "Stringer width",
+ description = "Width of stringer as a percentage of tread width",
+ min = 0.0001, max = 100.0,
+ default = 15.0)
+ string_h = FloatProperty(name = "Stringer Height",
+ description = "Height of the stringer",
+ min = 0.0001, max = 100.0,
+ default = 0.3)
+ string_tw = FloatProperty(name = "Web Thickness",
+ description = "Thickness of the beam's web as a percentage of width",
+ min = 0.0001, max = 100.0,
+ default = 25.0)
+ string_tf = FloatProperty(name = "Flange Thickness",
+ description = "Thickness of the flange",
+ min = 0.0001, max = 100.0,
+ default = 0.05)
+ string_tp = FloatProperty(name = "Flange Taper",
+ description = "Flange thickness taper as a percentage",
+ min = 0.0, max = 100.0,
+ default = 0.0)
+ string_g = BoolProperty(name = "Floating",
+ description = "Cut bottom of strigner to be a \"floating\" section",
+ default = False)
+
+ use_original = BoolProperty(name = "Use legacy method",
+ description = "Use the Blender 2.49 legacy method for stair generation",
+ default = True)
+ rEnable = BoolProperty(name = "Right Details",
+ description = "Generate right side details (posts/rails/retainers)",
+ default = True)
+ lEnable = BoolProperty(name = "Left Details",
+ description = "Generate left side details (posts/rails/retainers)",
+ default = True)
+
+ # Draw the GUI:
+ def draw(self, context):
+ layout = self.layout
+ box = layout.box()
+ box.prop(self, 'typ')
+ box = layout.box()
+ box.prop(self, 'rise')
+ if self.typ != "id4":
+ box.prop(self, 'run')
+ else:
+ box.prop(self, 'deg')
+ box.prop(self, 'rad1')
+ box.prop(self, 'rad2')
+ box.prop(self, 'center')
+ if self.typ == "id1":
+ box.prop(self, 'use_original')
+ if not self.use_original:
+ box.prop(self, 'rEnable')
+ box.prop(self, 'lEnable')
+ else:
+ self.use_original = False
+ box.prop(self, 'rEnable')
+ box.prop(self, 'lEnable')
+
+ # Treads
+ box = layout.box()
+ box.prop(self, 'make_treads')
+ if self.make_treads:
+ if not self.use_original and self.typ != "id4":
+ box.prop(self, 'typ_t')
+ else:
+ self.typ_t = "tId1"
+ if self.typ != "id4":
+ box.prop(self, 'tread_w')
+ box.prop(self, 'tread_h')
+ box.prop(self, 'tread_t')
+ if self.typ not in ["id2", "id4"]:
+ box.prop(self, 'tread_o')
+ else:
+ self.tread_o = 0.0
+ box.prop(self, 'tread_n')
+ if self.typ_t != "tId1":
+ box.prop(self, 'tread_tk')
+ box.prop(self, 'tread_sec')
+ if self.tread_sec > 1 and self.typ_t not in ["tId3", "tId4"]:
+ box.prop(self, 'tread_sp')
+ if self.typ_t in ["tId3", "tId4", "tId5"]:
+ box.prop(self, 'tread_sn')
+ elif self.typ == "id4":
+ box.prop(self, "tread_slc")
+
+ # Posts
+ box = layout.box()
+ box.prop(self, 'make_posts')
+ if self.make_posts:
+ box.prop(self, 'post_d')
+ box.prop(self, 'post_w')
+ box.prop(self, 'post_n')
+
+ # Railings
+ box = layout.box()
+ box.prop(self, 'make_railings')
+ if self.make_railings:
+ box.prop(self, 'rail_w')
+ box.prop(self, 'rail_t')
+ box.prop(self, 'rail_h')
+
+ # Retainers
+ box = layout.box()
+ box.prop(self, 'make_retainers')
+ if self.make_retainers:
+ box.prop(self, 'ret_w')
+ box.prop(self, 'ret_h')
+ box.prop(self, 'ret_n')
+
+ # Stringers
+ box = layout.box()
+ if self.typ != "id2":
+ box.prop(self, 'make_stringer')
+ else:
+ self.make_stringer = True
+ if self.make_stringer:
+ if not self.use_original:
+ box.prop(self, 'typ_s')
+ else:
+ self.typ_s = "sId1"
+ box.prop(self, 'string_w')
+ if self.typ == "id1":
+ if self.typ_s == "sId1" and not self.use_original:
+ box.prop(self, 'string_n')
+ box.prop(self, 'string_dis')
+ elif self.typ_s in ["sId2", "sId3"]:
+ box.prop(self, 'string_n')
+ box.prop(self, 'string_dis')
+ box.prop(self, 'string_h')
+ box.prop(self, 'string_tw')
+ box.prop(self, 'string_tf')
+ box.prop(self, 'string_tp')
+ box.prop(self, 'string_g')
+ elif self.typ == "id2":
+ if self.typ_s in ["sId2", "sId3"]:
+ box.prop(self, 'string_tw')
+ box.prop(self, 'string_tf')
+
+ # Tread support:
+## if self.make_stringer and typ_s in ["sId2", "sId3"]:
+
+ def execute(self, context):
+ global G
+ global typ
+ global typ_s
+ global typ_t
+ global rise
+ global run
+ typ = self.typ
+ typ_s = self.typ_s
+ typ_t = self.typ_t
+ rise = self.rise
+ run = self.run
+ G=General(rise,run,self.tread_n)
+ if self.make_treads:
+ if typ != "id4":
+ Treads(G,
+ typ,
+ typ_t,
+ run,
+ self.tread_w,
+ self.tread_h,
+ self.run,
+ self.rise,
+ self.tread_t,
+ self.tread_o,
+ self.tread_n,
+ self.tread_tk,
+ self.tread_sec,
+ self.tread_sp,
+ self.tread_sn)
+ else:
+ Treads(G,
+ typ,
+ typ_t,
+ self.deg,
+ self.rad2,
+ self.tread_h,
+ self.run,
+ self.rise,
+ self.tread_t,
+ self.rad1,
+ self.tread_n,
+ self.tread_tk,
+ self.tread_sec,
+ self.tread_sp,
+ self.tread_sn,
+ self.tread_slc)
+ if self.make_posts and (self.rEnable or self.lEnable):
+ Posts(G,
+ rise,
+ run,
+ self.post_d,
+ self.post_w,
+ self.tread_w,
+ self.post_n,
+ self.rail_h,
+ self.rail_t,
+ self.rEnable,
+ self.lEnable)
+ if self.make_railings and (self.rEnable or self.lEnable):
+ Rails(G,
+ self.rail_w,
+ self.rail_t,
+ self.rail_h,
+ self.tread_t,
+ self.post_w,
+ self.post_d,
+ self.tread_w,
+ self.rEnable,
+ self.lEnable)
+ if self.make_retainers and (self.rEnable or self.lEnable):
+ Retainers(G,
+ self.ret_w,
+ self.ret_h,
+ self.post_w,
+ self.tread_w,
+ self.rail_h,
+ self.ret_n,
+ self.rEnable,
+ self.lEnable)
+ if self.make_stringer:
+ if typ == "id1" and self.use_original:
+ Stringer(G,
+ typ,
+ typ_s,
+ rise,
+ run,
+ self.string_w,
+ self.string_h,
+ self.tread_n,
+ self.tread_h,
+ self.tread_w,
+ self.tread_t,
+ self.tread_o,
+ self.string_tw,
+ self.string_tf,
+ self.string_tp,
+ not self.string_g)
+ elif typ == "id3":
+ Stringer(G,
+ typ,
+ typ_s,
+ rise,
+ run,
+ 100,
+ self.string_h,
+ self.tread_n,
+ self.tread_h,
+ self.tread_w,
+ self.tread_t,
+ self.tread_o,
+ self.string_tw,
+ self.string_tf,
+ self.string_tp,
+ not self.string_g,
+ 1, False, False)
+ elif typ == "id4":
+ Stringer(G,
+ typ,
+ typ_s,
+ rise,
+ self.deg,
+ self.string_w,
+ self.string_h,
+ self.tread_n,
+ self.tread_h,
+ self.rad2 - self.rad1,
+ self.tread_t,
+ self.rad1,
+ self.string_tw,
+ self.string_tf,
+ self.string_tp,
+ not self.string_g,
+ self.string_n,
+ self.string_dis,
+ self.use_original,
+ self.tread_slc)
+ else:
+ Stringer(G,
+ typ,
+ typ_s,
+ rise,
+ run,
+ self.string_w,
+ self.string_h,
+ self.tread_n,
+ self.tread_h,
+ self.tread_w,
+ self.tread_t,
+ self.tread_o,
+ self.string_tw,
+ self.string_tf,
+ self.string_tp,
+ not self.string_g,
+ self.string_n,
+ self.string_dis,
+ self.use_original)
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/stringer.py b/release/scripts/addons_contrib/add_mesh_building_objects/stringer.py
new file mode 100644
index 0000000..99af723
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/stringer.py
@@ -0,0 +1,504 @@
+# Stairbuilder - Stringer generation
+#
+# Generates stringer mesh for stair generation.
+# Stair Type (typ):
+# - id1 = Freestanding staircase
+# - id2 = Housed-open staircase
+# - id3 = Box staircase
+# - id4 = Circular staircase
+# Stringer Type (typ_s):
+# - sId1 = Classic
+# - sId2 = I-Beam
+# - sId3 = C-Beam
+#
+# Paul "BrikBot" Marshall
+# Created: September 19, 2011
+# Last Modified: January 29, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.61.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+from math import atan, cos, radians, tan
+from mathutils import Matrix, Vector
+from mathutils.geometry import (intersect_line_plane,
+ intersect_line_line)
+
+class Stringer:
+ def __init__(self,G,typ,typ_s,rise,run,w,h,nT,hT,wT,tT,tO,tw,tf,tp,g,
+ nS=1,dis=False,notMulti=True,deg=4):
+ self.G = G #General
+ self.typ = typ # Stair type
+ self.typ_s = typ_s # Stringer type
+ self.rise = rise #Stair rise
+ self.run = run #Stair run. Degrees if self.typ == "id4"
+ if notMulti:
+ self.w = w / 100 #stringer width
+ else:
+ self.w = (wT * (w / 100)) / nS
+ self.h = h #stringer height
+ self.nT = nT #number of treads
+ self.hT = hT #tread height
+ self.wT = wT #tread width
+ self.tT = tT #tread toe
+ self.tO = tO #Tread overhang. Inner radius if self.typ == "id4"
+ self.tw = self.w * (tw / 100) #stringer web thickness
+ self.tf = tf #stringer flange thickness
+ self.tp = 1 - (tp / 100) #stringer flange taper
+ self.g = g #does stringer intersect the ground?
+ self.nS = nS #number of stringers
+ self.dis = dis #Use distributed stringers
+ self.deg = deg #number of sections per "slice". Only applys if self.typ == "id4"
+ # Default stringer object (classic / sId1):
+ self.faces1=[[0,1,3,2],[1,5,3],[3,5,4],[6,7,9,8],[7,11,9],[9,11,10],
+ [0,2,8,6],[0,1,7,6],[1,5,11,7],[2,3,9,8],[3,4,10,9],[4,5,11,10]]
+ # Box stair type stringer:
+ self.faces2=[[0,1,7,6],[1,3,9,7],[3,4,10,9],[4,10,11,5],[5,11,8,2],
+ [2,8,6,0],[0,1,2],[1,2,5,3],[3,4,5],[6,7,8],[7,8,11,9],[9,10,11]]
+ # I-beam stringer (id2 / sId2 / Taper < 100%):
+ self.faces3a=[[0,1,17,16],[1,2,18,17],[2,3,19,18],[3,4,20,19],[4,5,21,20],[5,6,22,21],
+ [6,7,23,22],[7,8,24,23],[8,9,25,24],[9,10,26,25],[10,11,27,26],
+ [11,12,28,27],[12,13,29,28],[13,14,30,29],[14,15,31,30],[15,0,16,31],
+ [0,1,2,15],[2,11,14,15],[11,12,13,14],[2,3,10,11],[3,4,5,6],[3,6,7,10],
+ [7,8,9,10],[16,17,18,31],[18,27,30,31],[27,28,29,30],[18,19,26,27],
+ [19,20,21,22],[19,22,23,26],[23,24,25,26]]
+ # I-beam stringer (id2 / sId2 / Taper = 100%):
+ self.faces3b=[[0,1,9,8],[1,2,10,9],[2,3,11,10],[3,4,12,11],[4,5,13,12],[5,6,14,13],
+ [6,7,15,14],[7,0,8,15],[0,1,6,7],[1,2,5,6],[2,3,4,5],[8,9,14,15],
+ [9,10,13,14],[10,11,12,13]]
+ # I-beam stringer (id3 / sId2 / Taper < 100%):
+ self.faces3c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],
+ [3,4,21,22],[16,17,18,23],[18,19,22,23],[19,20,21,22],
+ [17,8,15,18],[18,15,14,19],[19,14,13,20],[8,9,10,15],
+ [10,11,14,15],[11,12,13,14],[9,10,53,52],[10,11,54,53],
+ [11,12,55,54],[52,53,61,60],[53,54,62,61],[54,55,63,62],
+ [60,61,34,33],[61,62,35,34],[62,63,36,35],[32,33,34,39],
+ [34,35,38,39],[35,36,37,38],[41,32,39,42],[42,39,38,43],
+ [43,38,37,44],[40,41,42,47],[42,43,46,47],[43,44,45,46],
+ [25,26,47,40],[26,27,46,47],[27,28,45,46],[24,25,26,31],
+ [26,27,30,31],[27,28,29,30],[24,31,57,56],[31,30,58,57],
+ [30,29,59,58],[48,49,57,56],[49,50,58,57],[50,51,59,58],
+ [0,7,49,48],[7,6,50,49],[6,5,51,50],[0,1,16,48],[16,40,56,48],
+ [24,25,40,56],[16,17,41,40],[8,9,52,17],[17,52,60,41],
+ [32,33,60,41],[12,13,20,55],[20,44,63,55],[37,44,63,36],
+ [20,21,45,44],[28,29,51,21],[21,51,59,45],[28,45,59,29],
+ [4,5,51,21]]
+ # C-beam stringer (id3 / sId3 / Taper < 100%):
+ self.faces4c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],[3,4,21,22],
+ [16,17,18,23],[18,19,22,23],[19,20,21,22],[17,8,15,18],[18,15,14,19],
+ [19,14,13,20],[8,9,10,15],[10,11,14,15],[11,12,13,14],[0,24,25,7],
+ [7,25,26,6],[6,26,27,5],[9,31,30,10],[10,30,29,11],[11,29,28,12],
+ [24,25,30,31],[25,26,29,30],[26,27,28,29],[0,1,16,24],[16,24,31,17],
+ [8,9,31,17],[4,5,27,21],[20,21,27,28],[12,13,20,28]]
+ self.Create()
+
+
+ def Create(self):
+ if self.typ == "id1":
+ if self.typ_s == "sId1":
+ if self.dis or self.nS == 1:
+ offset = (self.wT / (self.nS + 1)) - (self.w / 2)
+ else:
+ offset = 0
+ for i in range(self.nS):
+ for j in range(self.nT):
+ coords = []
+ coords.append(Vector([0, offset, -self.rise]))
+ coords.append(Vector([self.run, offset, -self.rise]))
+ coords.append(Vector([0, offset, -self.hT]))
+ coords.append(Vector([self.run, offset, -self.hT]))
+ coords.append(Vector([self.run, offset, 0]))
+ coords.append(Vector([self.run * 2, offset, 0]))
+ for k in range(6):
+ coords.append(coords[k]+Vector([0, self.w, 0]))
+ for k in coords:
+ k += j*Vector([self.run, 0, self.rise])
+ self.G.Make_mesh(coords,self.faces1,'stringer')
+ if self.dis or self.nS == 1:
+ offset += self.wT / (self.nS + 1)
+ else:
+ offset += (self.wT - self.w) / (self.nS - 1)
+ elif self.typ_s == "sId2":
+ self.I_beam()
+ elif self.typ == "id2":
+ if self.typ_s == "sId1":
+ coords = []
+ coords.append(Vector([-self.tT, -self.w, -self.rise]))
+ coords.append(Vector([self.hT / self.G.slope, -self.w, -self.rise]))
+ coords.append(Vector([-self.tT, -self.w, 0]))
+ coords.append(Vector([self.nT * self.run, -self.w,
+ ((self.nT - 1) * self.rise) - self.hT]))
+ coords.append(Vector([self.nT * self.run, -self.w, self.nT * self.rise]))
+ coords.append(Vector([(self.nT * self.run) - self.tT, -self.w,
+ self.nT * self.rise]))
+ for i in range(6):
+ coords.append(coords[i] + Vector([0, self.w, 0]))
+ self.G.Make_mesh(coords, self.faces2, 'stringer')
+ for i in coords:
+ i += Vector([0, self.w + self.wT, 0])
+ self.G.Make_mesh(coords, self.faces2, 'stringer')
+ elif self.typ_s == "sId2":
+ self.housed_I_beam()
+ elif self.typ_s == "sId3":
+ self.housed_C_beam()
+ elif self.typ == "id3":
+ h = (self.rise - self.hT) - self.rise #height of top section
+ for i in range(self.nT):
+ coords = []
+ coords.append(Vector([i * self.run,0,-self.rise]))
+ coords.append(Vector([(i + 1) * self.run,0,-self.rise]))
+ coords.append(Vector([i * self.run,0,h + (i * self.rise)]))
+ coords.append(Vector([(i + 1) * self.run,0,h + (i * self.rise)]))
+ for j in range(4):
+ coords.append(coords[j] + Vector([0,self.wT,0]))
+ self.G.Make_mesh(coords, self.G.faces, 'stringer')
+ elif self.typ == "id4":
+ offset = (self.wT / (self.nS + 1)) - (self.w / 2)
+ for s in range(self.nS):
+ base = self.tO + (offset * (s + 1))
+ start = [Vector([0, -base, -self.hT]),
+ Vector([0, -base, -self.hT - self.rise]),
+ Vector([0, -base - self.w, -self.hT]),
+ Vector([0, -base - self.w, -self.hT - self.rise])]
+ self.d = radians(self.run) / self.nT
+ for i in range(self.nT):
+ coords = []
+ # Base faces. Should be able to append more sections:
+ tId4_faces = [[0, 1, 3, 2]]
+ t_inner = Matrix.Rotation(self.d * i, 3, 'Z')
+ coords.append((t_inner * start[0]) + Vector([0, 0, self.rise * i]))
+ coords.append((t_inner * start[1]) + Vector([0, 0, self.rise * i]))
+ t_outer = Matrix.Rotation(self.d * i, 3, 'Z')
+ coords.append((t_outer * start[2]) + Vector([0, 0, self.rise * i]))
+ coords.append((t_outer * start[3]) + Vector([0, 0, self.rise * i]))
+ k = 0
+ for j in range(self.deg):
+ k = (j * 4) + 4
+ tId4_faces.append([k, k - 4, k - 3, k + 1])
+ tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
+ tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
+ tId4_faces.append([k, k - 4, k - 2, k + 2])
+ rot = Matrix.Rotation(((self.d * (j + 1)) / self.deg) + (self.d * i), 3, 'Z')
+ for v in start:
+ coords.append((rot * v) + Vector([0, 0, self.rise * i]))
+ for j in range(self.deg):
+ k = ((j + self.deg) * 4) + 4
+ tId4_faces.append([k, k - 4, k - 3, k + 1])
+ tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
+ tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
+ tId4_faces.append([k, k - 4, k - 2, k + 2])
+ rot = Matrix.Rotation(((self.d * ((j + self.deg) + 1)) / self.deg) + (self.d * i), 3, 'Z')
+ for v in range(4):
+ if v in [1, 3]:
+ incline = (self.rise * i) + (self.rise / self.deg) * (j + 1)
+ coords.append((rot * start[v]) + Vector([0, 0, incline]))
+ else:
+ coords.append((rot * start[v]) + Vector([0, 0, self.rise * i]))
+ self.G.Make_mesh(coords, tId4_faces, 'treads')
+
+ return {'FINISHED'}
+
+
+ def I_beam(self):
+ mid = self.w / 2
+ web = self.tw / 2
+ # Bottom of the stringer:
+ baseZ = -self.rise - self.hT - self.h
+ # Top of the strigner:
+ topZ = -self.rise - self.hT
+ # Vertical taper amount:
+ taper = self.tf * self.tp
+
+ if self.dis or self.nS == 1:
+ offset = (self.wT / (self.nS + 1)) - mid
+ else:
+ offset = 0
+
+ # taper < 100%:
+ if self.tp > 0:
+ for i in range(self.nS):
+ coords = []
+ coords.append(Vector([0, offset, baseZ]))
+ coords.append(Vector([0, offset, baseZ + taper]))
+ coords.append(Vector([0, offset + (mid - web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + (mid - web), topZ - self.tf]))
+ coords.append(Vector([0, offset, topZ - taper]))
+ coords.append(Vector([0, offset, topZ]))
+ coords.append(Vector([0, offset + (mid - web), topZ]))
+ coords.append(Vector([0, offset + (mid + web), topZ]))
+ coords.append(Vector([0, offset + self.w, topZ]))
+ coords.append(Vector([0, offset + self.w, topZ - taper]))
+ coords.append(Vector([0, offset + (mid + web), topZ - self.tf]))
+ coords.append(Vector([0, offset + (mid + web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + self.w, baseZ + taper]))
+ coords.append(Vector([0, offset + self.w, baseZ]))
+ coords.append(Vector([0, offset + (mid + web), baseZ]))
+ coords.append(Vector([0, offset + (mid - web), baseZ]))
+ for j in range(16):
+ coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
+ # If the bottom meets the ground:
+ # Bottom be flat with the xy plane, but shifted down.
+ # Either project onto the plane along a vector (hard) or use the built in
+ # interest found in mathutils.geometry (easy). Using intersect:
+ if self.g:
+ for j in range(16):
+ coords[j] = intersect_line_plane(coords[j], coords[j + 16],
+ Vector([0, 0, topZ]),
+ Vector([0, 0, 1]))
+ self.G.Make_mesh(coords, self.faces3a, 'stringer')
+
+ if self.dis or self.nS == 1:
+ offset += self.wT / (self.nS + 1)
+ else:
+ offset += (self.wT - self.w) / (self.nS - 1)
+ # taper = 100%:
+ else:
+ for i in range(self.nS):
+ coords = []
+ coords.append(Vector([0, offset, baseZ]))
+ coords.append(Vector([0, offset + (mid - web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + (mid - web), topZ - self.tf]))
+ coords.append(Vector([0, offset, topZ]))
+ coords.append(Vector([0, offset + self.w, topZ]))
+ coords.append(Vector([0, offset + (mid + web), topZ - self.tf]))
+ coords.append(Vector([0, offset + (mid + web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + self.w, baseZ]))
+ for j in range(8):
+ coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
+ self.G.Make_mesh(coords, self.faces3b, 'stringer')
+ offset += self.wT / (self.nS + 1)
+
+ return {'FINISHED'}
+
+
+ def housed_I_beam(self):
+ webOrth = Vector([self.rise, 0, -self.run]).normalized()
+ webHeight = Vector([self.run + self.tT, 0, -self.hT]).project(webOrth).length
+ vDelta_1 = self.tf * tan(self.G.angle)
+ vDelta_2 = (self.rise * (self.nT - 1)) - (webHeight + self.tf)
+ flange_y = (self.w - self.tw) / 2
+ front = -self.tT - self.tf
+ outer = -self.tO - self.tw - flange_y
+
+ coords = []
+ if self.tp > 0:
+ # Upper-Outer flange:
+ coords.append(Vector([front, outer, -self.rise]))
+ coords.append(Vector([-self.tT, outer, -self.rise]))
+ coords.append(Vector([-self.tT, outer, 0]))
+ coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
+ self.rise * (self.nT - 1)]))
+ coords.append(Vector([self.run * self.nT, outer,
+ self.rise * (self.nT - 1)]))
+ coords.append(Vector([self.run * self.nT, outer,
+ (self.rise * (self.nT - 1)) + self.tf]))
+ coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
+ (self.rise * (self.nT - 1)) + self.tf]))
+ coords.append(Vector([front, outer, self.tf - vDelta_1]))
+ # Lower-Outer flange:
+ coords.append(coords[0] + Vector([self.tf + webHeight, 0, 0]))
+ coords.append(coords[1] + Vector([self.tf + webHeight, 0, 0]))
+ coords.append(intersect_line_line(coords[9],
+ coords[9] - Vector([0, 0, 1]),
+ Vector([self.run, 0, -self.hT - self.tf]),
+ Vector([self.run * 2, 0, self.rise - self.hT - self.tf]))[0])
+ coords.append(Vector([(self.run * self.nT) - ((webHeight - self.hT) / tan(self.G.angle)),
+ outer, vDelta_2]))
+ coords.append(coords[4] - Vector([0, 0, self.tf + webHeight]))
+ coords.append(coords[5] - Vector([0, 0, self.tf + webHeight]))
+ coords.append(coords[11] + Vector([0, 0, self.tf]))
+ coords.append(intersect_line_line(coords[8],
+ coords[8] - Vector([0, 0, 1]),
+ Vector([self.run, 0, -self.hT]),
+ Vector([self.run * 2, 0, self.rise - self.hT]))[0])
+ # Outer web:
+ coords.append(coords[1] + Vector([0, flange_y, 0]))
+ coords.append(coords[8] + Vector([0, flange_y, 0]))
+ coords.append(coords[15] + Vector([0, flange_y, 0]))
+ coords.append(coords[14] + Vector([0, flange_y, 0]))
+ coords.append(coords[13] + Vector([0, flange_y, 0]))
+ coords.append(coords[4] + Vector([0, flange_y, 0]))
+ coords.append(coords[3] + Vector([0, flange_y, 0]))
+ coords.append(coords[2] + Vector([0, flange_y, 0]))
+ # Upper-Inner flange and lower-inner flange:
+ for i in range(16):
+ coords.append(coords[i] + Vector([0, self.w, 0]))
+ # Inner web:
+ for i in range(8):
+ coords.append(coords[i + 16] + Vector([0, self.tw, 0]))
+ # Mid nodes to so faces will be quads:
+ for i in [0,7,6,5,9,10,11,12]:
+ coords.append(coords[i] + Vector([0, flange_y, 0]))
+ for i in range(8):
+ coords.append(coords[i + 48] + Vector([0, self.tw, 0]))
+
+ self.G.Make_mesh(coords, self.faces3c, 'stringer')
+
+ for i in coords:
+ i += Vector([0, self.wT + self.tw, 0])
+
+ self.G.Make_mesh(coords, self.faces3c, 'stringer')
+
+ # @TODO Taper = 100%
+
+ return {'FINISHED'}
+
+
+ def C_Beam(self):
+ mid = self.w / 2
+ web = self.tw / 2
+ # Bottom of the stringer:
+ baseZ = -self.rise - self.hT - self.h
+ # Top of the strigner:
+ topZ = -self.rise - self.hT
+ # Vertical taper amount:
+ taper = self.tf * self.tp
+
+ if self.dis or self.nS == 1:
+ offset = (self.wT / (self.nS + 1)) - mid
+ else:
+ offset = 0
+
+ # taper < 100%:
+ if self.tp > 0:
+ for i in range(self.nS):
+ coords = []
+ coords.append(Vector([0, offset, baseZ]))
+ coords.append(Vector([0, offset, baseZ + taper]))
+ coords.append(Vector([0, offset + (mid - web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + (mid - web), topZ - self.tf]))
+ coords.append(Vector([0, offset, topZ - taper]))
+ coords.append(Vector([0, offset, topZ]))
+ coords.append(Vector([0, offset + (mid - web), topZ]))
+ coords.append(Vector([0, offset + (mid + web), topZ]))
+ coords.append(Vector([0, offset + self.w, topZ]))
+ coords.append(Vector([0, offset + self.w, topZ - taper]))
+ coords.append(Vector([0, offset + (mid + web), topZ - self.tf]))
+ coords.append(Vector([0, offset + (mid + web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + self.w, baseZ + taper]))
+ coords.append(Vector([0, offset + self.w, baseZ]))
+ coords.append(Vector([0, offset + (mid + web), baseZ]))
+ coords.append(Vector([0, offset + (mid - web), baseZ]))
+ for j in range(16):
+ coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
+ # If the bottom meets the ground:
+ # Bottom be flat with the xy plane, but shifted down.
+ # Either project onto the plane along a vector (hard) or use the built in
+ # interest found in mathutils.geometry (easy). Using intersect:
+ if self.g:
+ for j in range(16):
+ coords[j] = intersect_line_plane(coords[j], coords[j + 16],
+ Vector([0, 0, topZ]),
+ Vector([0, 0, 1]))
+ self.G.Make_mesh(coords, self.faces3a, 'stringer')
+
+ if self.dis or self.nS == 1:
+ offset += self.wT / (self.nS + 1)
+ else:
+ offset += (self.wT - self.w) / (self.nS - 1)
+ # taper = 100%:
+ else:
+ for i in range(self.nS):
+ coords = []
+ coords.append(Vector([0, offset, baseZ]))
+ coords.append(Vector([0, offset + (mid - web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + (mid - web), topZ - self.tf]))
+ coords.append(Vector([0, offset, topZ]))
+ coords.append(Vector([0, offset + self.w, topZ]))
+ coords.append(Vector([0, offset + (mid + web), topZ - self.tf]))
+ coords.append(Vector([0, offset + (mid + web), baseZ + self.tf]))
+ coords.append(Vector([0, offset + self.w, baseZ]))
+ for j in range(8):
+ coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
+ self.G.Make_mesh(coords, self.faces3b, 'stringer')
+ offset += self.wT / (self.nS + 1)
+
+ return {'FINISHED'}
+
+
+ def housed_C_beam(self):
+ webOrth = Vector([self.rise, 0, -self.run]).normalized()
+ webHeight = Vector([self.run + self.tT, 0, -self.hT]).project(webOrth).length
+ vDelta_1 = self.tf * tan(self.G.angle)
+ vDelta_2 = (self.rise * (self.nT - 1)) - (webHeight + self.tf)
+ flange_y = (self.w - self.tw) / 2
+ front = -self.tT - self.tf
+ outer = -self.tO - self.tw - flange_y
+
+ coords = []
+ if self.tp > 0:
+ # Upper-Outer flange:
+ coords.append(Vector([front, outer, -self.rise]))
+ coords.append(Vector([-self.tT, outer, -self.rise]))
+ coords.append(Vector([-self.tT, outer, 0]))
+ coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
+ self.rise * (self.nT - 1)]))
+ coords.append(Vector([self.run * self.nT, outer,
+ self.rise * (self.nT - 1)]))
+ coords.append(Vector([self.run * self.nT, outer,
+ (self.rise * (self.nT - 1)) + self.tf]))
+ coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
+ (self.rise * (self.nT - 1)) + self.tf]))
+ coords.append(Vector([front, outer, self.tf - vDelta_1]))
+ # Lower-Outer flange:
+ coords.append(coords[0] + Vector([self.tf + webHeight, 0, 0]))
+ coords.append(coords[1] + Vector([self.tf + webHeight, 0, 0]))
+ coords.append(intersect_line_line(coords[9],
+ coords[9] - Vector([0, 0, 1]),
+ Vector([self.run, 0, -self.hT - self.tf]),
+ Vector([self.run * 2, 0, self.rise - self.hT - self.tf]))[0])
+ coords.append(Vector([(self.run * self.nT) - ((webHeight - self.hT) / tan(self.G.angle)),
+ outer, vDelta_2]))
+ coords.append(coords[4] - Vector([0, 0, self.tf + webHeight]))
+ coords.append(coords[5] - Vector([0, 0, self.tf + webHeight]))
+ coords.append(coords[11] + Vector([0, 0, self.tf]))
+ coords.append(intersect_line_line(coords[8],
+ coords[8] - Vector([0, 0, 1]),
+ Vector([self.run, 0, -self.hT]),
+ Vector([self.run * 2, 0, self.rise - self.hT]))[0])
+ # Outer web:
+ coords.append(coords[1] + Vector([0, flange_y, 0]))
+ coords.append(coords[8] + Vector([0, flange_y, 0]))
+ coords.append(coords[15] + Vector([0, flange_y, 0]))
+ coords.append(coords[14] + Vector([0, flange_y, 0]))
+ coords.append(coords[13] + Vector([0, flange_y, 0]))
+ coords.append(coords[4] + Vector([0, flange_y, 0]))
+ coords.append(coords[3] + Vector([0, flange_y, 0]))
+ coords.append(coords[2] + Vector([0, flange_y, 0]))
+ # Outer corner nodes:
+ for i in [0, 7, 6, 5, 12, 11, 10, 9]:
+ coords.append(coords[i] + Vector([0, flange_y + self.tw, 0]))
+
+ self.G.Make_mesh(coords, self.faces4c, 'stringer')
+
+ for i in range(16):
+ coords[i] += Vector([0, -outer * 2, 0])
+ for i in range(8):
+ coords[i + 16] += Vector([0, (-outer - flange_y) * 2, 0])
+ for i in coords:
+ i += Vector([0, (self.tO * 2) + self.wT, 0])
+
+ self.G.Make_mesh(coords, self.faces4c, 'stringer')
+
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_building_objects/tread.py b/release/scripts/addons_contrib/add_mesh_building_objects/tread.py
new file mode 100644
index 0000000..1a5af0c
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_building_objects/tread.py
@@ -0,0 +1,242 @@
+# Stairbuilder - Tread generation
+#
+# Generates treads for stair generation.
+# Stair Type (typ):
+# - id1 = Freestanding staircase
+# - id2 = Housed-open staircase
+# - id3 = Box staircase
+# - id4 = Circular staircase
+# Tread Type (typ_t):
+# - tId1 = Classic
+# - tId2 = Basic Steel
+# - tId3 = Bar 1
+# - tId4 = Bar 2
+# - tId5 = Bar 3
+#
+# Paul "BrikBot" Marshall
+# Created: September 19, 2011
+# Last Modified: January 26, 2012
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.61.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# Stairbuilder is for quick stair generation.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import mathutils
+from copy import copy
+from math import radians, sqrt
+from mathutils import Matrix, Vector
+
+class Treads:
+ def __init__(self,G,typ,typ_t,run,w,h,d,r,toe,o,n,tk,sec,sp,sn,deg=4):
+ self.G = G #General
+ self.typ = typ #Stair type
+ self.typ_t = typ_t #Tread type
+ self.run = run #Stair run. Degrees if self.typ == "id4"
+ self.w=w #tread width. Is outer radius if self.typ == "id4"
+ self.h=h #tread height
+ self.d=d #tread run. Ignore for now if self.typ == "id4"
+ self.r=r #tread rise
+ self.t=toe #tread nosing
+ self.o=o #tread side overhang. Is inner radius if self.typ == "id4"
+ self.n=n #number of treads
+ self.tk=tk #thickness of tread metal
+ self.sec=sec #metal sections for tread
+ if sec != 1 and typ_t not in ["tId4", "tId5"]:
+ self.sp=((d+toe)*(sp/100))/(sec-1) #spacing between sections (% of depth)
+ elif typ_t in ["tId4", "tId5"]:
+ self.sp=sp/100 #keep % value
+ else:
+ self.sp=0
+ self.sn=sn #number of cross sections
+ self.deg = deg #number of section per "slice". Only applys if self.typ == "id4"
+ self.tId2_faces = [[0,1,2,3],[0,3,4,5],[4,5,6,7],[6,7,8,9],[8,9,10,11],
+ [12,13,14,15],[12,15,16,17],[16,17,18,19],
+ [18,19,20,21],[20,21,22,23],[0,1,13,12],[1,2,14,13],
+ [2,3,15,14],[3,4,16,15],[4,7,19,16],[7,8,20,19],
+ [8,11,23,20],[11,10,22,23],[10,9,21,22],[9,6,18,21],
+ [6,5,17,18],[5,0,12,17]]
+ self.out_faces = [[0,2,3,1],[0,2,10,8],[9,11,3,1],[9,11,10,8],
+ [2,6,7,3],[2,6,14,10],[11,15,7,3],[11,15,14,10],
+ [0,4,5,1],[0,4,12,8],[9,13,5,1],[9,13,12,8],
+ [4,6,7,5],[4,6,14,12],[13,15,14,12],[13,15,7,5]]
+ self.Create()
+
+ def Create(self):
+ # Setup the coordinates:
+ coords = []
+ coords2 = []
+ coords3 = []
+ cross = 0
+ cW = 0
+ depth = 0
+ offset = 0
+ height = 0
+ if self.typ in ["id1", "id2", "id3"]:
+ if self.typ_t == "tId1":
+ coords.append(Vector([-self.t,-self.o,0]))
+ coords.append(Vector([self.d,-self.o,0]))
+ coords.append(Vector([-self.t,self.w + self.o,0]))
+ coords.append(Vector([self.d,self.w + self.o,0]))
+ for i in range(4):
+ coords.append(coords[i]+Vector([0,0,-self.h]))
+
+ elif self.typ_t == "tId2":
+ depth = (self.d + self.t - (self.sec - 1) * self.sp) / self.sec
+ inset = depth / 4
+ tDepth = depth - self.t
+ coords.append(Vector([-self.t, -self.o, -self.h])) #0
+ coords.append(Vector([inset - self.t, -self.o, -self.h])) #1
+ coords.append(Vector([inset - self.t, -self.o, -self.h + self.tk])) #2
+ coords.append(Vector([self.tk - self.t, -self.o, -self.h + self.tk])) #3
+ coords.append(Vector([self.tk - self.t, -self.o, -self.tk])) #4
+ coords.append(Vector([-self.t, -self.o, 0])) #5
+ coords.append(Vector([tDepth, -self.o, 0])) #6
+ coords.append(Vector([tDepth - self.tk, -self.o, -self.tk])) #7
+ coords.append(Vector([tDepth - self.tk, -self.o, self.tk - self.h])) #8
+ coords.append(Vector([tDepth, -self.o, -self.h])) #9
+ coords.append(Vector([tDepth - inset, -self.o, -self.h])) #10
+ coords.append(Vector([tDepth - inset, -self.o, -self.h + self.tk])) #11
+ for i in range(12):
+ coords.append(coords[i] + Vector([0, self.w + (2 * self.o), 0]))
+
+ elif self.typ_t in ["tId3", "tId4", "tId5"]:
+ # Frame:
+ coords.append(Vector([-self.t,-self.o,-self.h]))
+ coords.append(Vector([self.d,-self.o,-self.h]))
+ coords.append(Vector([-self.t,-self.o,0]))
+ coords.append(Vector([self.d,-self.o,0]))
+ for i in range(4):
+ if (i % 2) == 0:
+ coords.append(coords[i] + Vector([self.tk,self.tk,0]))
+ else:
+ coords.append(coords[i] + Vector([-self.tk,self.tk,0]))
+ for i in range(4):
+ coords.append(coords[i] + Vector([0,self.w + self.o,0]))
+ for i in range(4):
+ coords.append(coords[i + 4] + Vector([0,self.w + self.o - (2 * self.tk),0]))
+
+ # Tread sections:
+ if self.typ_t == "tId3":
+ offset = (self.tk * sqrt(2)) / 2
+ topset = self.h - offset
+ self.sp = ((self.d + self.t - (2 * self.tk)) - (offset * (self.sec) + topset)) / (self.sec + 1)
+ baseX = -self.t + self.sp + self.tk
+ coords2.append(Vector([baseX, self.tk - self.o, offset - self.h]))
+ coords2.append(Vector([baseX + offset, self.tk - self.o, -self.h]))
+ for i in range(2):
+ coords2.append(coords2[i] + Vector([topset, 0, topset]))
+ for i in range(4):
+ coords2.append(coords2[i] + Vector([0, (self.w + self.o) - (2 * self.tk), 0]))
+ elif self.typ_t in ["tId4", "tId5"]:
+ offset = ((self.run + self.t) * self.sp) / (self.sec + 1)
+ topset = (((self.run + self.t) * (1 - self.sp)) - (2 * self.tk)) / self.sec
+ baseX = -self.t + self.tk + offset
+ baseY = self.w + self.o - 2 * self.tk
+ coords2.append(Vector([baseX, -self.o + self.tk, -self.h / 2]))
+ coords2.append(Vector([baseX + topset, -self.o + self.tk, -self.h / 2]))
+ coords2.append(Vector([baseX, -self.o + self.tk, 0]))
+ coords2.append(Vector([baseX + topset, -self.o + self.tk, 0]))
+ for i in range(4):
+ coords2.append(coords2[i] + Vector([0, baseY, 0]))
+
+ # Tread cross-sections:
+ if self.typ_t in ["tId3", "tId4"]:
+ cW = self.tk
+ cross = (self.w + (2 * self.o) - (self.sn + 2) * self.tk) / (self.sn + 1)
+ else: # tId5
+ spacing = self.sp ** (1 / 4)
+ cross = ((2*self.o + self.w) * spacing) / (self.sn + 1)
+ cW = (-2*self.tk + (2*self.o + self.w) * (1 - spacing)) / self.sn
+ self.sp = topset
+ height = -self.h / 2
+ baseY = -self.o + self.tk + cross
+ coords3.append(Vector([-self.t + self.tk, baseY, -self.h]))
+ coords3.append(Vector([self.d - self.tk, baseY, -self.h]))
+ coords3.append(Vector([-self.t + self.tk, baseY, height]))
+ coords3.append(Vector([self.d - self.tk, baseY, height]))
+ for i in range(4):
+ coords3.append(coords3[i] + Vector([0, cW, 0]))
+
+ # Make the treads:
+ for i in range(self.n):
+ if self.typ_t == "tId1":
+ self.G.Make_mesh(coords,self.G.faces,'treads')
+ elif self.typ_t == "tId2":
+ temp = []
+ for j in coords:
+ temp.append(copy(j))
+ for j in range(self.sec):
+ self.G.Make_mesh(temp, self.tId2_faces, 'treads')
+ for k in temp:
+ k += Vector([depth + self.sp, 0, 0])
+ elif self.typ_t in ["tId3", "tId4", "tId5"]:
+ self.G.Make_mesh(coords,self.out_faces,'treads')
+ temp = []
+ for j in coords2:
+ temp.append(copy(j))
+ for j in range(self.sec):
+ self.G.Make_mesh(temp,self.G.faces,'bars')
+ for k in temp:
+ k += Vector([offset + self.sp, 0, 0])
+ for j in coords2:
+ j += Vector([self.d, 0, self.r])
+ temp = []
+ for j in coords3:
+ temp.append(copy(j))
+ for j in range(self.sn):
+ self.G.Make_mesh(temp,self.G.faces,'crosses')
+ for k in temp:
+ k += Vector([0, cW + cross, 0])
+ for j in coords3:
+ j += Vector([self.d, 0, self.r])
+ for j in coords:
+ j += Vector([self.d,0,self.r])
+ # Circular staircase:
+ elif self.typ in ["id4"]:
+ start = [Vector([0, -self.o, 0]), Vector([0, -self.o, -self.h]),
+ Vector([0, -self.w, 0]), Vector([0, -self.w, -self.h])]
+ self.d = radians(self.run) / self.n
+ for i in range(self.n):
+ coords = []
+ # Base faces. Should be able to append more sections:
+ tId4_faces = [[0, 1, 3, 2]]
+ t_inner = Matrix.Rotation((-self.t / self.o) + (self.d * i), 3, 'Z')
+ coords.append((t_inner * start[0]) + Vector([0, 0, self.r * i]))
+ coords.append((t_inner * start[1]) + Vector([0, 0, self.r * i]))
+ t_outer = Matrix.Rotation((-self.t / self.w) + (self.d * i), 3, 'Z')
+ coords.append((t_outer * start[2]) + Vector([0, 0, self.r * i]))
+ coords.append((t_outer * start[3]) + Vector([0, 0, self.r * i]))
+ k = 0
+ for j in range(self.deg + 1):
+ k = (j * 4) + 4
+ tId4_faces.append([k, k - 4, k - 3, k + 1])
+ tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
+ tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
+ tId4_faces.append([k, k - 4, k - 2, k + 2])
+ rot = Matrix.Rotation(((self.d * j) / self.deg) + (self.d * i), 3, 'Z')
+ for v in start:
+ coords.append((rot * v) + Vector([0, 0, self.r * i]))
+ tId4_faces.append([k, k + 1, k + 3, k + 2])
+ self.G.Make_mesh(coords, tId4_faces, 'treads')
+ return
diff --git a/release/scripts/addons_contrib/add_mesh_chain_rope/__init__.py b/release/scripts/addons_contrib/add_mesh_chain_rope/__init__.py
new file mode 100644
index 0000000..9d914bc
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_chain_rope/__init__.py
@@ -0,0 +1,38 @@
+bl_info = {
+ "name": "Oscurart Chain and Rope Maker",
+ "author": "Oscurart",
+ "version": (1,1),
+ "blender": (2, 63, 0),
+ "location": "Add > Mesh",
+ "description": "Create chains and ropes along armatures/curves",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Add_Mesh/Oscurart_Chain_Rope_Maker",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=28136",
+ "category": "Object"}
+
+
+import bpy
+from .oscurart_rope_maker import *
+from .oscurart_chain_maker import *
+
+def register():
+ bpy.utils.register_class(OBJECT_OT_add_object)
+ bpy.types.INFO_MT_curve_add.append(oscRopeButton)
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_mesh_add.append(menu_oscChain)
+
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_add_object)
+ bpy.types.INFO_MT_curve_add.remove(oscRopeButton)
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_mesh_add.remove(menu_oscChain)
+
+if __name__ == "__main__":
+ register()
+
+
+
+
+
diff --git a/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_chain_maker.py b/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_chain_maker.py
new file mode 100644
index 0000000..c5b1e68
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_chain_maker.py
@@ -0,0 +1,191 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Oscurart Chain Maker",
+ "author": "Oscurart",
+ "version": (1,1),
+ "blender": (2, 56, 0),
+ "api": 3800,
+ "location": "Add > Mesh > Oscurart Chain",
+ "description": "Create chain links from armatures.",
+ "warning": "",
+ "wiki_url": "oscurart.blogspot.com",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+
+
+
+import bpy
+
+
+def makeChain (self, context, mult, curverig):
+
+ if bpy.context.active_object.type == 'ARMATURE':
+ bpy.ops.object.mode_set(mode='OBJECT')
+ VAR_SWITCH=abs(1)
+ ARMATURE=bpy.context.active_object
+ def creahuesocero(hueso):
+ ## CREO DATA PARA ESLABON
+ mesh=bpy.data.meshes.new("objectData"+str(hueso.name))
+ object=bpy.data.objects.new("EslabonCero"+str(hueso.name),mesh)
+ mesh.from_pydata(
+ [(-0.04986128956079483,-0.6918092370033264,-0.17846597731113434),(-0.04986128956079483,-0.6918091773986816,0.17846640944480896),(-0.049861326813697815,-0.154555082321167,0.17846627533435822),(-0.049861326813697815,-0.15455523133277893,-0.17846614122390747),(-0.04986133798956871,-0.03475356101989746,0.25805795192718506),(-0.04986133798956871,-0.03475397825241089,-0.25805795192718506),(-0.049861278384923935,-0.8116106986999512,-0.2580576539039612),(-0.049861278384923935,-0.8116104602813721,0.25805822014808655),(-0.04986128211021423,-0.7692053318023682,2.6668965347198537e-07),(-0.04986127093434334,-0.923523485660553,2.7834033744511544e-07),(-0.04986133426427841,-0.0771591067314148,3.5627678585115063e-08),(-0.04986134544014931,0.0771591067314148,-3.5627678585115063e-08),(0.04986133798956871,-0.03475397825241089,-0.25805795192718506),(0.04986133053898811,0.0771591067314148,-3.5627678585115063e-08),(0.04986133798956871,-0.03475356101989746,0.25805795192718506),(0.04986134544014931,-0.15455523133277893,-0.17846614122390747),(0.04986134544014931,-0.0771591067314148,3.5627678585115063e-08),(0.04986134544014931,-0.154555082321167,0.17846627533435822),(0.049861397594213486,-0.8116106986999512,-0.2580576539039612),(0.04986140504479408,-0.923523485660553,2.7834033744511544e-07),(0.049861397594213486,-0.8116104602813721,0.25805822014808655),(0.04986139014363289,-0.6918091773986816,0.17846640944480896),(0.04986139014363289,-0.7692053318023682,2.6668965347198537e-07),(0.04986139014363289,-0.6918092370033264,-0.17846597731113434)],
+ [(1,2),(0,3),(3,5),(2,4),(0,6),(5,6),(1,7),(4,7),(0,8),(1,8),(7,9),(6,9),(8,9),(2,10),(3,10),(4,11),(5,11),(10,11),(5,12),(12,13),(11,13),(13,14),(4,14),(10,16),(15,16),(3,15),(2,17),(16,17),(9,19),(18,19),(6,18),(7,20),(19,20),(8,22),(21,22),(1,21),(0,23),(22,23),(14,20),(12,18),(15,23),(17,21),(12,15),(13,16),(14,17),(20,21),(19,22),(18,23)],
+ [(6,0,3,5),(1,7,4,2),(0,6,9,8),(8,9,7,1),(2,4,11,10),(10,11,5,3),(11,13,12,5),(4,14,13,11),(3,15,16,10),(10,16,17,2),(6,18,19,9),(9,19,20,7),(1,21,22,8),(23,0,8,22),(7,20,14,4),(5,12,18,6),(0,23,15,3),(2,17,21,1),(16,15,12,13),(17,16,13,14),(22,21,20,19),(23,22,19,18),(21,17,14,20),(15,23,18,12)]
+ )
+ bpy.context.scene.objects.link(object)
+ ## ESCALO EL HUESO
+ bpy.data.objects['EslabonCero'+str(hueso.name)].scale= (hueso.length*mult,hueso.length*mult,hueso.length*mult)
+ ## EMPARENTO
+ bpy.data.objects['EslabonCero'+str(hueso.name)].parent=ARMATURE
+ bpy.data.objects['EslabonCero'+str(hueso.name)].parent_type = 'BONE'
+ bpy.data.objects['EslabonCero'+str(hueso.name)].parent_bone=hueso.name
+ def creahuesonoventa(hueso):
+ ## CREO DATA PARA ESLABON
+ mesh=bpy.data.meshes.new("objectData"+str(hueso.name))
+ object=bpy.data.objects.new("EslabonNov"+str(hueso.name),mesh)
+ mesh.from_pydata(
+ [(0.1784660965204239,-0.6918091773986816,-0.049861203879117966),(-0.1784662902355194,-0.6918091773986816,-0.04986126348376274),(-0.17846627533435822,-0.1545550525188446,-0.04986134544014931),(0.17846617102622986,-0.15455520153045654,-0.04986128583550453),(-0.25805795192718506,-0.03475359082221985,-0.049861375242471695),(0.25805795192718506,-0.034753888845443726,-0.04986129328608513),(0.2580578327178955,-0.8116105794906616,-0.04986117407679558),(-0.2580580413341522,-0.8116105198860168,-0.049861256033182144),(-9.672299938756623e-08,-0.7692052721977234,-0.04986122250556946),(-8.99775329799013e-08,-0.923523485660553,-0.04986120015382767),(-7.764004550381287e-09,-0.07715904712677002,-0.049861326813697815),(4.509517737005808e-08,0.0771591067314148,-0.049861349165439606),(0.25805795192718506,-0.034753888845443726,0.049861375242471695),(-2.2038317837314025e-08,0.0771591067314148,0.049861326813697815),(-0.25805795192718506,-0.03475359082221985,0.04986129328608513),(0.17846617102622986,-0.15455520153045654,0.04986138269305229),(-1.529285498236277e-08,-0.07715907692909241,0.049861352890729904),(-0.17846627533435822,-0.1545550525188446,0.049861323088407516),(0.2580578029155731,-0.8116105794906616,0.049861494451761246),(-1.5711103173998708e-07,-0.923523485660553,0.04986147582530975),(-0.2580580711364746,-0.8116105198860168,0.04986141249537468),(-0.1784663051366806,-0.6918091773986816,0.049861419945955276),(-1.340541757599567e-07,-0.7692052721977234,0.049861449748277664),(0.1784660816192627,-0.6918091773986816,0.04986146464943886)],
+ [(1,2),(0,3),(3,5),(2,4),(0,6),(5,6),(1,7),(4,7),(0,8),(1,8),(7,9),(6,9),(8,9),(2,10),(3,10),(4,11),(5,11),(10,11),(5,12),(12,13),(11,13),(13,14),(4,14),(10,16),(15,16),(3,15),(2,17),(16,17),(9,19),(18,19),(6,18),(7,20),(19,20),(8,22),(21,22),(1,21),(0,23),(22,23),(14,20),(12,18),(15,23),(17,21),(12,15),(13,16),(14,17),(20,21),(19,22),(18,23)],
+ [(6,0,3,5),(1,7,4,2),(0,6,9,8),(8,9,7,1),(2,4,11,10),(10,11,5,3),(11,13,12,5),(4,14,13,11),(3,15,16,10),(10,16,17,2),(6,18,19,9),(9,19,20,7),(1,21,22,8),(23,0,8,22),(7,20,14,4),(5,12,18,6),(0,23,15,3),(2,17,21,1),(16,15,12,13),(17,16,13,14),(22,21,20,19),(23,22,19,18),(21,17,14,20),(15,23,18,12)]
+ )
+ bpy.context.scene.objects.link(object)
+ ## ESCALO EL HUESO
+ bpy.data.objects['EslabonNov'+str(hueso.name)].scale= (hueso.length*mult,hueso.length*mult,hueso.length*mult)
+ ## EMPARENTO
+ bpy.data.objects['EslabonNov'+str(hueso.name)].parent=ARMATURE
+ bpy.data.objects['EslabonNov'+str(hueso.name)].parent_type = 'BONE'
+ bpy.data.objects['EslabonNov'+str(hueso.name)].parent_bone=hueso.name
+
+ for hueso in bpy.context.active_object.pose.bones:
+ if VAR_SWITCH == 1:
+ creahuesocero(hueso)
+ else:
+ creahuesonoventa(hueso)
+ if VAR_SWITCH == 1:
+ VAR_SWITCH = 0
+ print(VAR_SWITCH)
+ else :
+ VAR_SWITCH = 1
+ print(VAR_SWITCH)
+ # SI NO TILDAMOS CURVERIG
+ if curverig == True:
+ # VARIABLES
+ LISTA_POINTC=[]
+ ACTARM=bpy.context.active_object
+ # CREO DATA , OBJETO Y LO CONECTO A LA ESCENA
+ crv= bpy.data.curves.new("CurvaCable", "CURVE")
+ obCable=bpy.data.objects.new("Cable",crv)
+ bpy.context.scene.objects.link(obCable)
+ # SETEO ATRIBUTOS
+ crv.dimensions = "3D"
+ crv.resolution_u = 10
+ crv.resolution_v = 10
+ crv.twist_mode = "MINIMUM"
+ # CREO LISTA DE COORDENADAS DE TAIL Y HEAD
+ LISTA_POINTC.append((
+ ACTARM.data.bones[0].head_local[0],
+ ACTARM.data.bones[0].head_local[1],
+ ACTARM.data.bones[0].head_local[2],
+ 1
+ ))
+ print("huesos: "+ str(len(ACTARM.data.bones)))
+ for hueso in ACTARM.data.bones:
+ LISTA_POINTC.append((hueso.tail_local[0],hueso.tail_local[1],hueso.tail_local[2],1))
+ # CREO EL SPLINE
+ spline=crv.splines.new("NURBS")
+ lencoord= len(LISTA_POINTC)
+ print("lencoord--> :"+str(lencoord))
+ rango=range(lencoord)
+ spline.points.add(lencoord-1)
+ for punto in rango:
+ spline.points[punto].co = LISTA_POINTC[punto]
+ print(LISTA_POINTC[punto])
+ # SETEO ENDPOINT
+ bpy.data.objects['Cable'].data.splines[0].use_endpoint_u= True
+ # SELECCIONO LA CURVA
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.data.objects['Cable'].select=1
+ bpy.context.scene.objects.active=bpy.data.objects['Cable']
+ # PASO A EDIT
+ bpy.ops.object.mode_set(mode='EDIT')
+ # CREO HOOKS
+ POINTSTEP=0
+ for POINT in bpy.data.objects['Cable'].data.splines[0].points:
+ bpy.ops.curve.select_all(action="DESELECT")
+ bpy.data.objects['Cable'].data.splines[0].points[POINTSTEP].select=1
+ bpy.ops.object.hook_add_newob()
+ POINTSTEP+=1
+ # PASO A SELECCIONAR LOS OBJETOS
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.select_all(action='DESELECT')
+ ACTARM.select=1
+ bpy.context.scene.objects.active=bpy.data.objects['Armature']
+ bpy.ops.object.mode_set(mode='POSE')
+ bpy.ops.pose.select_all(action='DESELECT')
+ ACTARM.data.bones[-1].select=1
+ ACTARM.data.bones.active=ACTARM.data.bones[-1]
+ # SETEO IK SPLINE
+ bpy.ops.pose.constraint_add_with_targets(type='SPLINE_IK')
+ ACTARM.pose.bones[-1].constraints['Spline IK'].target = bpy.data.objects['Cable']
+ ACTARM.pose.bones[-1].constraints['Spline IK'].chain_count=100
+ bpy.context.active_object.pose.bones[-1].constraints['Spline IK'].use_y_stretch= False
+ # VUELVO A OBJECT MODE
+ bpy.ops.object.mode_set(mode='OBJECT')
+ else:
+ self.report({'WARNING'}, "Active Object must be an Armature")
+
+
+#---------------
+from bpy.props import *
+
+class MESH_OT_chain_maker(bpy.types.Operator):
+ bl_idname="mesh.primitive_oscurart_chain_add"
+ bl_label="Oscurart Chain"
+ bl_options={'REGISTER','UNDO'}
+
+ curverig= BoolProperty(name="Curve Rig", default=False)
+ multiplier= FloatProperty (name="Scale", default=1 , min=0.01, max=100.0)
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object is not None)
+
+ def execute(self, context):
+ makeChain(self, context, self.multiplier,self.curverig)
+ return {'FINISHED'}
+
+def menu_oscChain(self, context):
+ self.layout.operator("mesh.primitive_oscurart_chain_add",
+ text="Oscurart Chain",
+ icon='LINKED')
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_mesh_add.append(menu_oscChain)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_mesh_add.remove(menu_oscChain)
+
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_rope_maker.py b/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_rope_maker.py
new file mode 100644
index 0000000..e355887
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_chain_rope/oscurart_rope_maker.py
@@ -0,0 +1,198 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Oscurart Rope Maker",
+ "author": "Oscurart",
+ "version": (1,1),
+ "blender": (2, 56, 0),
+ "api": 3800,
+ "location": "Add > Curve > Oscurart Rope",
+ "description": "Create ropes",
+ "warning": "",
+ "wiki_url": "oscurart.blogspot.com",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+
+import bpy, math
+
+
+
+
+
+def makeRope (context, DISTPOS, curvaResU, radius, FE, CUERDAS, stResU,DIAMETRO):
+
+ # CREO DATA , OBJETO Y LO CONECTO A LA ESCENA
+ crv= bpy.data.curves.new("CurvaCable", "CURVE")
+ obCable=bpy.data.objects.new("Cable",crv)
+ bpy.context.scene.objects.link(obCable)
+
+ # SETEO ATRIBUTOS
+ crv.dimensions = "3D"
+ crv.resolution_u = 10
+ crv.resolution_v = 10
+ crv.twist_mode = "MINIMUM"
+
+ # LISTA DE COMPONENTES
+ coordenadas= [
+ (0,radius,0,radius),
+ (radius,0,0,radius),
+ (0,-radius,0,radius),
+ (-radius,0,0,radius)
+ ]
+
+
+
+ # CREO EL SPLINE
+ spline=crv.splines.new("NURBS")
+ lencoord= len(coordenadas)
+ #print("lencoord--> :"+str(lencoord))
+ rango=range(lencoord)
+ spline.points.add(lencoord-1)
+ for punto in rango:
+ spline.points[punto].co = coordenadas[punto]
+ #print(punto)
+
+
+ # MODIFICACIONES DE DATA
+ spline.use_cyclic_u = True
+ spline.resolution_u = curvaResU
+ spline.order_u = 3
+ spline.use_endpoint_u = True
+
+
+ ## ==CREO CADENAS==
+
+ ## DIVIDO EL RADIO POR LA CANTIDAD DE LINEAS Y SETEO UNA LISTA
+
+ GRADOS=[]
+ VALORPORPARTE=[]
+ DIVISION=360/CUERDAS
+ TAJADA=0
+
+ for parte in range(0,CUERDAS):
+ GRADOS.append(TAJADA)
+ TAJADA+=DIVISION
+
+
+
+ for GRAD in GRADOS:
+
+
+ # VARIABLES
+ FC=0
+ VARLISTVER=[]
+
+ VARANGLEY=0
+ VARANGLEZ=90
+ VARPOSX=0
+ EDGEINDEX=0
+ # DEFINO EL PESO PARA LAS COORDENADAS
+ WEIGHT = 1
+
+ while FC < FE:
+ ## CREA 3 CADENAS EN 0 90 Y 180 GRADOS
+ VARLISTVER.append((VARPOSX, math.sin(math.radians(GRAD))/(1/DIAMETRO) , math.sin(math.radians(GRAD+90))/(1/DIAMETRO),WEIGHT))
+
+ GRAD += 30
+ FC += 1
+ VARPOSX += DISTPOS
+
+
+
+ # CREO DATA , OBJETO Y LO CONECTO A LA ESCENA
+ crv= bpy.data.curves.new("curvaData", "CURVE")
+ ob=bpy.data.objects.new("Curva",crv)
+ bpy.context.scene.objects.link(ob)
+
+ # SETEO ATRIBUTOS
+ crv.dimensions = "3D"
+ crv.resolution_u = 10
+ crv.resolution_v = 10
+ crv.twist_mode = "MINIMUM"
+
+ # LISTA DE COMPONENTES
+ coordenadas= VARLISTVER
+
+
+
+ # CREO EL SPLINE
+ spline=crv.splines.new("NURBS")
+ lencoord= len(coordenadas)
+ #print("lencoord--> :"+str(lencoord))
+ rango=range(lencoord)
+ spline.points.add(lencoord-1)
+ for punto in rango:
+ spline.points[punto].co = coordenadas[punto]
+ #print(punto)
+
+
+ # MODIFICACIONES DE DATA
+ spline.use_cyclic_u = False
+ spline.resolution_u = stResU
+ spline.order_u = 3
+ spline.use_endpoint_u = True
+
+ ob.data.bevel_object= bpy.data.objects["Cable"]
+
+ #print(VARLISTVER)
+
+#---------------
+from bpy.props import *
+
+class OBJECT_OT_add_object(bpy.types.Operator):
+ bl_idname="curve.primitive_osc_rope_add"
+ bl_label="Oscurart Rope"
+ bl_options={'REGISTER','UNDO'}
+
+ strands = IntProperty (name="Strands", default=5 , min=1, max=1000, step=1)
+ diameter = FloatProperty (name="Diameter", default=1 , min=0, max=1000)
+ distPos= FloatProperty (name="Stretch", default=1 , min=0.01, max=100.0)
+ vertices= IntProperty (name="Length", default=10 , min=0, max=1000, step=1)
+ distResU= IntProperty (name="Resolution V", default=5 , min=1, max=1000, step=1)
+ stResU= IntProperty (name="Resolution U", default=5 , min=1, max=1000, step=1)
+ radio= FloatProperty (name="Radius", default=1 , min=0, max=1000)
+
+ def execute(self, context):
+ makeRope(context,
+ self.distPos,self.distResU,self.radio,self.vertices,self.strands, self.stResU,self.diameter)
+ return {'FINISHED'}
+
+# Registration
+
+def oscRopeButton(self, context):
+ self.layout.operator(
+ OBJECT_OT_add_object.bl_idname,
+ text="Oscurart Rope",
+ icon="PLUGIN")
+
+
+def register():
+ bpy.utils.register_class(OBJECT_OT_add_object)
+ bpy.types.INFO_MT_curve_add.append(oscRopeButton)
+
+
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_add_object)
+ bpy.types.INFO_MT_curve_add.remove(oscRopeButton)
+
+
+if __name__ == '__main__':
+ register()
diff --git a/release/scripts/addons_contrib/add_mesh_clusters/__init__.py b/release/scripts/addons_contrib/add_mesh_clusters/__init__.py
new file mode 100644
index 0000000..8d8f56d
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_clusters/__init__.py
@@ -0,0 +1,524 @@
+# ##### 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 LICENSE BLOCK #####
+
+#
+# Main author : Clemens Barth (Blendphys at root-1.de)
+# Authors : Clemens Barth, Christine Mottet (Icosahedra), ...
+#
+# Homepage(Wiki) : http://development.root-1.de/Atomic_Blender.php
+#
+# Start of project : 2012-03-25 by Clemens Barth
+# First publication in Blender : 2012-05-27 by Clemens Barth
+# Last modified : 2013-01-03
+#
+#
+#
+# To do:
+# ======
+#
+# 1. Include other shapes: dodecahedron, ...
+# 2. Skin option for parabolic shaped clusters
+# 3. Skin option for icosahedron
+# 4. Icosahedron: unlimited size ...
+#
+
+bl_info = {
+ "name": "Atomic Blender - Cluster",
+ "description": "Creating cluster formed by atoms",
+ "author": "Clemens Barth",
+ "version": (0, 5),
+ "blender": (2, 60, 0),
+ "location": "Panel: View 3D - Tools (left side)",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Add_Mesh/Cluster",
+ "tracker_url": "http://projects.blender.org/tracker/"
+ "index.php?func=detail&aid=31618&group_id=153&atid=468",
+ "category": "Add Mesh"
+}
+
+import os
+import io
+import bpy
+from bpy.types import Operator, Panel
+from bpy_extras.io_utils import ImportHelper, ExportHelper
+from bpy.props import (StringProperty,
+ BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty)
+
+from . import add_mesh_cluster
+
+ATOM_Cluster_PANEL = 0
+
+# -----------------------------------------------------------------------------
+# GUI
+
+
+class CLASS_ImportCluster(bpy.types.Operator):
+ bl_idname = "mesh.cluster"
+ bl_label = "Atom cluster"
+ bl_options = {'REGISTER', 'UNDO', 'PRESET'}
+
+ def execute(self, context):
+
+ global ATOM_Cluster_PANEL
+ ATOM_Cluster_PANEL = 1
+
+ return {'FINISHED'}
+
+
+
+class CLASS_atom_cluster_panel(Panel):
+ bl_label = "Atomic Blender - Cluster"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOL_PROPS"
+
+
+ @classmethod
+ def poll(self, context):
+ global ATOM_Cluster_PANEL
+
+ if ATOM_Cluster_PANEL == 0:
+ return False
+
+ return True
+
+ def draw(self, context):
+ layout = self.layout
+
+ scn = context.scene.atom_cluster
+
+ row = layout.row()
+ row.label(text="Cluster properties")
+ box = layout.box()
+ row = box.row()
+ row.prop(scn, "shape")
+
+ if scn.shape in ["parabolid_square","parabolid_ab","parabolid_abc"]:
+ row = box.row()
+ row.prop(scn, "parabol_diameter")
+ row = box.row()
+ row.prop(scn, "parabol_height")
+ elif scn.shape in ["icosahedron"]:
+ row = box.row()
+ row.prop(scn, "icosahedron_size")
+ else:
+ row = box.row()
+ row.prop(scn, "size")
+ row = box.row()
+ row.prop(scn, "skin")
+
+ row = box.row()
+ row.prop(scn, "lattice_parameter")
+ row = box.row()
+ row.prop(scn, "element")
+ row = box.row()
+ row.prop(scn, "radius_type")
+ row = box.row()
+ row.prop(scn, "scale_radius")
+ row = box.row()
+ row.prop(scn, "scale_distances")
+
+ row = layout.row()
+ row.label(text="Load cluster")
+ box = layout.box()
+ row = box.row()
+ row.operator("atom_cluster.load")
+ row = box.row()
+ row.label(text="Number of atoms")
+ row = box.row()
+ row.prop(scn, "atom_number_total")
+ row = box.row()
+ row.prop(scn, "atom_number_drawn")
+
+ row = layout.row()
+ row.label(text="Modify cluster")
+ box = layout.box()
+ row = box.row()
+ row.label(text="All changes concern:")
+ row = box.row()
+ row.prop(scn, "radius_how")
+ row = box.row()
+ row.label(text="1. Change type of radii")
+ row = box.row()
+ row.prop(scn, "radius_type")
+ row = box.row()
+ row.label(text="2. Change atom radii by scale")
+ row = box.row()
+ col = row.column()
+ col.prop(scn, "radius_all")
+ col = row.column(align=True)
+ col.operator( "atom_cluster.radius_all_bigger" )
+ col.operator( "atom_cluster.radius_all_smaller" )
+
+
+# The properties (gadgets) in the panel. They all go to scene
+# during initialization (see end)
+class CLASS_atom_cluster_Properties(bpy.types.PropertyGroup):
+
+ def Callback_radius_type(self, context):
+ scn = bpy.context.scene.atom_cluster
+ DEF_atom_cluster_radius_type(scn.radius_type,
+ scn.radius_how,)
+
+ size = FloatProperty(
+ name = "Size", default=30.0, min=0.1,
+ description = "Size of cluster in Angstroem")
+ skin = FloatProperty(
+ name = "Skin", default=1.0, min=0.0, max = 1.0,
+ description = "Skin of cluster in % of size (skin=1.0: show all atoms, skin=0.1: show only the outer atoms)")
+ parabol_diameter = FloatProperty(
+ name = "Diameter", default=30.0, min=0.1,
+ description = "Top diameter in Angstroem")
+ parabol_height = FloatProperty(
+ name = "Height", default=30.0, min=0.1,
+ description = "Height in Angstroem")
+ icosahedron_size = IntProperty(
+ name = "Size", default=1, min=1, max=13,
+ description = "Size n: 1 (13 atoms), 2 (55 atoms), 3 (147 atoms), 4 (309 atoms), 5 (561 atoms), ..., 13 (8217 atoms)")
+ shape = EnumProperty(
+ name="",
+ description="Choose the shape of the cluster",
+ items=(('sphere_square', "Sphere - square", "Sphere with square lattice"),
+ ('sphere_hex_ab', "Sphere - hex ab", "Sphere with hexagonal ab-lattice"),
+ ('sphere_hex_abc', "Sphere - hex abc", "Sphere with hexagonal abc-lattice"),
+ ('pyramide_square', "Pyramide - Square", "Pyramide: square (abc-lattice)"),
+ ('pyramide_hex_abc', "Pyramide - Tetraeder", "Pyramide: tetraeder (abcabc-lattice)"),
+ ('octahedron', "Octahedron", "Octahedron"),
+ ('truncated_octahedron', "Truncated octahedron", "Truncated octahedron"),
+ ('icosahedron', "Icosahedron", "Icosahedron"),
+ ('parabolid_square', "Paraboloid: square", "Paraboloid with square lattice"),
+ ('parabolid_ab', "Paraboloid: hex ab", "Paraboloid with ab-lattice"),
+ ('parabolid_abc', "Paraboloid: hex abc", "Paraboloid with abc-lattice")),
+ default='sphere_square',)
+ lattice_parameter = FloatProperty(
+ name = "Lattice", default=4.08, min=1.0,
+ description = "Lattice parameter in Angstroem")
+ element = StringProperty(name="Element",
+ default="Gold", description = "Enter the name of the element")
+ radius_type = EnumProperty(
+ name="Radius",
+ description="Which type of atom radii?",
+ items=(('0',"predefined", "Use pre-defined radii"),
+ ('1',"atomic", "Use atomic radii"),
+ ('2',"van der Waals","Use van der Waals radii")),
+ default='0',)
+ scale_radius = FloatProperty(
+ name = "Scale R", default=1.0, min=0.0,
+ description = "Scale radius of atoms")
+ scale_distances = FloatProperty(
+ name = "Scale d", default=1.0, min=0.0,
+ description = "Scale distances")
+
+ atom_number_total = StringProperty(name="Total",
+ default="---", description = "Number of all atoms in the cluster")
+ atom_number_drawn = StringProperty(name="Drawn",
+ default="---", description = "Number of drawn atoms in the cluster")
+
+ radius_how = EnumProperty(
+ name="",
+ description="Which objects shall be modified?",
+ items=(('ALL_ACTIVE',"all active objects", "in the current layer"),
+ ('ALL_IN_LAYER',"all"," in active layer(s)")),
+ default='ALL_ACTIVE',)
+ radius_type = EnumProperty(
+ name="Type",
+ description="Which type of atom radii?",
+ items=(('0',"predefined", "Use pre-defined radii"),
+ ('1',"atomic", "Use atomic radii"),
+ ('2',"van der Waals","Use van der Waals radii")),
+ default='0',update=Callback_radius_type)
+ radius_all = FloatProperty(
+ name="Scale", default = 1.05, min=0.0,
+ description="Put in the scale factor")
+
+
+# The button for reloading the atoms and creating the scene
+class CLASS_atom_cluster_load_button(Operator):
+ bl_idname = "atom_cluster.load"
+ bl_label = "Load"
+ bl_description = "Load the cluster"
+
+ def execute(self, context):
+ scn = context.scene.atom_cluster
+
+ add_mesh_cluster.DEF_atom_read_atom_data()
+ del add_mesh_cluster.ATOM_CLUSTER_ALL_ATOMS[:]
+
+ if scn.shape in ["parabolid_ab", "parabolid_abc", "parabolid_square"]:
+ parameter1 = scn.parabol_height
+ parameter2 = scn.parabol_diameter
+ elif scn.shape == "pyramide_hex_abc":
+ parameter1 = scn.size * 1.6
+ parameter2 = scn.skin
+ elif scn.shape == "pyramide_square":
+ parameter1 = scn.size * 1.4
+ parameter2 = scn.skin
+ elif scn.shape in ["octahedron", "truncated_octahedron"]:
+ parameter1 = scn.size * 1.4
+ parameter2 = scn.skin
+ elif scn.shape in ["icosahedron"]:
+ parameter1 = scn.icosahedron_size
+ else:
+ parameter1 = scn.size
+ parameter2 = scn.skin
+
+ if scn.shape in ["octahedron", "truncated_octahedron", "sphere_square", "pyramide_square", "parabolid_square"]:
+ numbers = add_mesh_cluster.create_square_lattice(
+ scn.shape,
+ parameter1,
+ parameter2,
+ (scn.lattice_parameter/2.0))
+
+ if scn.shape in ["sphere_hex_ab", "parabolid_ab"]:
+ numbers = add_mesh_cluster.create_hexagonal_abab_lattice(
+ scn.shape,
+ parameter1,
+ parameter2,
+ scn.lattice_parameter)
+
+ if scn.shape in ["sphere_hex_abc", "pyramide_hex_abc", "parabolid_abc"]:
+ numbers = add_mesh_cluster.create_hexagonal_abcabc_lattice(
+ scn.shape,
+ parameter1,
+ parameter2,
+ scn.lattice_parameter)
+
+ if scn.shape in ["icosahedron"]:
+ numbers = add_mesh_cluster.create_icosahedron(
+ parameter1,
+ scn.lattice_parameter)
+
+ DEF_atom_draw_atoms(scn.element,
+ scn.radius_type,
+ scn.scale_radius,
+ scn.scale_distances)
+
+ scn.atom_number_total = str(numbers[0])
+ scn.atom_number_drawn = str(numbers[1])
+
+ return {'FINISHED'}
+
+
+def DEF_atom_draw_atoms(prop_element,
+ prop_radius_type,
+ prop_scale_radius,
+ prop_scale_distances):
+
+ current_layers=bpy.context.scene.layers
+
+ for element in add_mesh_cluster.ATOM_CLUSTER_ELEMENTS:
+ if prop_element in element.name:
+ number = element.number
+ name = element.name
+ color = element.color
+ radii = element.radii
+ break
+
+ material = bpy.data.materials.new(name)
+ material.name = name
+ material.diffuse_color = color
+
+ atom_vertices = []
+ for atom in add_mesh_cluster.ATOM_CLUSTER_ALL_ATOMS:
+ atom_vertices.append( atom.location * prop_scale_distances )
+
+ # Build the mesh
+ atom_mesh = bpy.data.meshes.new("Mesh_"+name)
+ atom_mesh.from_pydata(atom_vertices, [], [])
+ atom_mesh.update()
+ new_atom_mesh = bpy.data.objects.new(name, atom_mesh)
+ bpy.context.scene.objects.link(new_atom_mesh)
+
+ bpy.ops.surface.primitive_nurbs_surface_sphere_add(
+ view_align=False, enter_editmode=False,
+ location=(0,0,0), rotation=(0.0, 0.0, 0.0),
+ layers=current_layers)
+
+ ball = bpy.context.scene.objects.active
+ ball.scale = (radii[int(prop_radius_type)]*prop_scale_radius,) * 3
+
+ ball.active_material = material
+ ball.parent = new_atom_mesh
+ new_atom_mesh.dupli_type = 'VERTS'
+
+ # ------------------------------------------------------------------------
+ # SELECT ALL LOADED OBJECTS
+ bpy.ops.object.select_all(action='DESELECT')
+ new_atom_mesh.select = True
+ bpy.context.scene.objects.active = new_atom_mesh
+
+ return True
+
+
+# Routine to modify the radii via the type: predefined, atomic or van der Waals
+# Explanations here are also valid for the next 3 DEFs.
+def DEF_atom_cluster_radius_type(rtype,how):
+
+ if how == "ALL_IN_LAYER":
+
+ # Note all layers that are active.
+ layers = []
+ for i in range(20):
+ if bpy.context.scene.layers[i] == True:
+ layers.append(i)
+
+ # Put all objects, which are in the layers, into a list.
+ change_objects = []
+ for obj in bpy.context.scene.objects:
+ for layer in layers:
+ if obj.layers[layer] == True:
+ change_objects.append(obj)
+
+ # Consider all objects, which are in the list 'change_objects'.
+ for obj in change_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH":
+ for element in add_mesh_cluster.ATOM_CLUSTER_ELEMENTS:
+ if element.name in obj.name:
+ obj.children[0].scale = (element.radii[int(rtype)],) * 3
+ else:
+ if obj.type == "SURFACE" or obj.type == "MESH":
+ for element in add_mesh_cluster.ATOM_CLUSTER_ELEMENTS:
+ if element.name in obj.name:
+ obj.scale = (element.radii[int(rtype)],) * 3
+
+
+# Routine to scale the radii of all atoms
+def DEF_atom_cluster_radius_all(scale, how):
+
+ if how == "ALL_IN_LAYER":
+
+ layers = []
+ for i in range(20):
+ if bpy.context.scene.layers[i] == True:
+ layers.append(i)
+
+ change_objects = []
+ for obj in bpy.context.scene.objects:
+ for layer in layers:
+ if obj.layers[layer] == True:
+ change_objects.append(obj)
+
+ for obj in change_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH":
+ if "Stick" not in obj.name:
+ obj.children[0].scale *= scale
+ else:
+ if obj.type == "SURFACE" or obj.type == "MESH":
+ if "Stick" not in obj.name:
+ obj.scale *= scale
+
+ if how == "ALL_ACTIVE":
+ for obj in bpy.context.selected_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH":
+ if "Stick" not in obj.name:
+ obj.children[0].scale *= scale
+ else:
+ if obj.type == "SURFACE" or obj.type == "MESH":
+ if "Stick" not in obj.name:
+ obj.scale *= scale
+
+
+# Button for increasing the radii of all atoms
+class CLASS_atom_cluster_radius_all_bigger_button(Operator):
+ bl_idname = "atom_cluster.radius_all_bigger"
+ bl_label = "Bigger ..."
+ bl_description = "Increase the radii of the atoms"
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_cluster
+ DEF_atom_cluster_radius_all(
+ scn.radius_all,
+ scn.radius_how,)
+ return {'FINISHED'}
+
+
+# Button for decreasing the radii of all atoms
+class CLASS_atom_cluster_radius_all_smaller_button(Operator):
+ bl_idname = "atom_cluster.radius_all_smaller"
+ bl_label = "Smaller ..."
+ bl_description = "Decrease the radii of the atoms"
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_cluster
+ DEF_atom_cluster_radius_all(
+ 1.0/scn.radius_all,
+ scn.radius_how,)
+ return {'FINISHED'}
+
+
+# Routine to scale the radii of all atoms
+def DEF_atom_cluster_radius_all(scale, how):
+
+ if how == "ALL_IN_LAYER":
+
+ layers = []
+ for i in range(20):
+ if bpy.context.scene.layers[i] == True:
+ layers.append(i)
+
+ change_objects = []
+ for obj in bpy.context.scene.objects:
+ for layer in layers:
+ if obj.layers[layer] == True:
+ change_objects.append(obj)
+
+
+ for obj in change_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH":
+ if "Stick" not in obj.name:
+ obj.children[0].scale *= scale
+ else:
+ if obj.type == "SURFACE" or obj.type == "MESH":
+ if "Stick" not in obj.name:
+ obj.scale *= scale
+
+ if how == "ALL_ACTIVE":
+ for obj in bpy.context.selected_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type == "SURFACE" or obj.children[0].type == "MESH":
+ if "Stick" not in obj.name:
+ obj.children[0].scale *= scale
+ else:
+ if obj.type == "SURFACE" or obj.type == "MESH":
+ if "Stick" not in obj.name:
+ obj.scale *= scale
+
+
+# The entry into the menu 'file -> import'
+def DEF_menu_func(self, context):
+ self.layout.operator(CLASS_ImportCluster.bl_idname, icon='PLUGIN')
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.atom_cluster = bpy.props.PointerProperty(type=
+ CLASS_atom_cluster_Properties)
+ bpy.types.INFO_MT_mesh_add.append(DEF_menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_mesh_add.remove(DEF_menu_func)
+
+if __name__ == "__main__":
+
+ register()
diff --git a/release/scripts/addons_contrib/add_mesh_clusters/add_mesh_cluster.py b/release/scripts/addons_contrib/add_mesh_clusters/add_mesh_cluster.py
new file mode 100644
index 0000000..9e30203
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_clusters/add_mesh_cluster.py
@@ -0,0 +1,1321 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+import io
+import math
+import os
+import copy
+from math import pi, cos, sin, tan, sqrt
+from mathutils import Vector, Matrix
+from copy import copy
+
+# -----------------------------------------------------------------------------
+# Atom, stick and element data
+
+
+# This is a list that contains some data of all possible elements. The structure
+# is as follows:
+#
+# 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means
+#
+# No., name, short name, color, radius (used), radius (covalent), radius (atomic),
+#
+# charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
+# charge states for any atom are listed, if existing.
+# The list is fixed and cannot be changed ... (see below)
+
+ATOM_CLUSTER_ELEMENTS_DEFAULT = (
+( 1, "Hydrogen", "H", ( 1.0, 1.0, 1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
+( 2, "Helium", "He", ( 0.85, 1.0, 1.0), 0.93, 0.93, 0.49 ),
+( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ),
+( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ),
+( 5, "Boron", "B", ( 1.0, 0.70, 0.70), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ),
+( 6, "Carbon", "C", ( 0.56, 0.56, 0.56), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ),
+( 7, "Nitrogen", "N", ( 0.18, 0.31, 0.97), 0.75, 0.75, 0.75 , -3 , 1.71 , 1 , 0.25 , 3 , 0.16 , 5 , 0.13 ),
+( 8, "Oxygen", "O", ( 1.0, 0.05, 0.05), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 , 1 , 0.22 , 6 , 0.09 ),
+( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ),
+(10, "Neon", "Ne", ( 0.70, 0.89, 0.96), 0.71, 0.71, 0.51 , 1 , 1.12 ),
+(11, "Sodium", "Na", ( 0.67, 0.36, 0.94), 1.54, 1.54, 2.23 , 1 , 0.97 ),
+(12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ),
+(13, "Aluminium", "Al", ( 0.74, 0.65, 0.65), 1.18, 1.18, 1.82 , 3 , 0.51 ),
+(14, "Silicon", "Si", ( 0.94, 0.78, 0.62), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 , 1 , 0.65 , 4 , 0.42 ),
+(15, "Phosphorus", "P", ( 1.0, 0.50, 0.0), 1.06, 1.06, 1.23 , -3 , 2.12 , 3 , 0.44 , 5 , 0.35 ),
+(16, "Sulfur", "S", ( 1.0, 1.0, 0.18), 1.02, 1.02, 1.09 , -2 , 1.84 , 2 , 2.19 , 4 , 0.37 , 6 , 0.30 ),
+(17, "Chlorine", "Cl", ( 0.12, 0.94, 0.12), 0.99, 0.99, 0.97 , -1 , 1.81 , 5 , 0.34 , 7 , 0.27 ),
+(18, "Argon", "Ar", ( 0.50, 0.81, 0.89), 0.98, 0.98, 0.88 , 1 , 1.54 ),
+(19, "Potassium", "K", ( 0.56, 0.25, 0.83), 2.03, 2.03, 2.77 , 1 , 0.81 ),
+(20, "Calcium", "Ca", ( 0.23, 1.0, 0.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ),
+(21, "Scandium", "Sc", ( 0.90, 0.90, 0.90), 1.44, 1.44, 2.09 , 3 , 0.73 ),
+(22, "Titanium", "Ti", ( 0.74, 0.76, 0.78), 1.32, 1.32, 2.00 , 1 , 0.96 , 2 , 0.94 , 3 , 0.76 , 4 , 0.68 ),
+(23, "Vanadium", "V", ( 0.65, 0.65, 0.67), 1.22, 1.22, 1.92 , 2 , 0.88 , 3 , 0.74 , 4 , 0.63 , 5 , 0.59 ),
+(24, "Chromium", "Cr", ( 0.54, 0.6, 0.78), 1.18, 1.18, 1.85 , 1 , 0.81 , 2 , 0.89 , 3 , 0.63 , 6 , 0.52 ),
+(25, "Manganese", "Mn", ( 0.61, 0.47, 0.78), 1.17, 1.17, 1.79 , 2 , 0.80 , 3 , 0.66 , 4 , 0.60 , 7 , 0.46 ),
+(26, "Iron", "Fe", ( 0.87, 0.4, 0.2), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ),
+(27, "Cobalt", "Co", ( 0.94, 0.56, 0.62), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ),
+(28, "Nickel", "Ni", ( 0.31, 0.81, 0.31), 1.15, 1.15, 1.62 , 2 , 0.69 ),
+(29, "Copper", "Cu", ( 0.78, 0.50, 0.2), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ),
+(30, "Zinc", "Zn", ( 0.49, 0.50, 0.69), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ),
+(31, "Gallium", "Ga", ( 0.76, 0.56, 0.56), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ),
+(32, "Germanium", "Ge", ( 0.4, 0.56, 0.56), 1.22, 1.22, 1.52 , -4 , 2.72 , 2 , 0.73 , 4 , 0.53 ),
+(33, "Arsenic", "As", ( 0.74, 0.50, 0.89), 1.20, 1.20, 1.33 , -3 , 2.22 , 3 , 0.58 , 5 , 0.46 ),
+(34, "Selenium", "Se", ( 1.0, 0.63, 0.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 , 1 , 0.66 , 4 , 0.50 , 6 , 0.42 ),
+(35, "Bromine", "Br", ( 0.65, 0.16, 0.16), 1.14, 1.14, 1.12 , -1 , 1.96 , 5 , 0.47 , 7 , 0.39 ),
+(36, "Krypton", "Kr", ( 0.36, 0.72, 0.81), 1.31, 1.31, 1.24 ),
+(37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69), 2.16, 2.16, 2.98 , 1 , 1.47 ),
+(38, "Strontium", "Sr", ( 0.0, 1.0, 0.0), 1.91, 1.91, 2.45 , 2 , 1.12 ),
+(39, "Yttrium", "Y", ( 0.58, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ),
+(40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ),
+(41, "Niobium", "Nb", ( 0.45, 0.76, 0.78), 1.34, 1.34, 2.08 , 1 , 1.00 , 4 , 0.74 , 5 , 0.69 ),
+(42, "Molybdenum", "Mo", ( 0.32, 0.70, 0.70), 1.30, 1.30, 2.01 , 1 , 0.93 , 4 , 0.70 , 6 , 0.62 ),
+(43, "Technetium", "Tc", ( 0.23, 0.61, 0.61), 1.27, 1.27, 1.95 , 7 , 0.97 ),
+(44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56), 1.25, 1.25, 1.89 , 4 , 0.67 ),
+(45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54), 1.25, 1.25, 1.83 , 3 , 0.68 ),
+(46, "Palladium", "Pd", ( 0.0, 0.41, 0.52), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ),
+(47, "Silver", "Ag", ( 0.75, 0.75, 0.75), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ),
+(48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ),
+(49, "Indium", "In", ( 0.65, 0.45, 0.45), 1.44, 1.44, 2.00 , 3 , 0.81 ),
+(50, "Tin", "Sn", ( 0.4, 0.50, 0.50), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 , 2 , 0.93 , 4 , 0.71 ),
+(51, "Antimony", "Sb", ( 0.61, 0.38, 0.70), 1.40, 1.40, 1.53 , -3 , 2.45 , 3 , 0.76 , 5 , 0.62 ),
+(52, "Tellurium", "Te", ( 0.83, 0.47, 0.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 , 1 , 0.82 , 4 , 0.70 , 6 , 0.56 ),
+(53, "Iodine", "I", ( 0.58, 0.0, 0.58), 1.33, 1.33, 1.32 , -1 , 2.20 , 5 , 0.62 , 7 , 0.50 ),
+(54, "Xenon", "Xe", ( 0.25, 0.61, 0.69), 1.31, 1.31, 1.24 ),
+(55, "Caesium", "Cs", ( 0.34, 0.09, 0.56), 2.35, 2.35, 3.35 , 1 , 1.67 ),
+(56, "Barium", "Ba", ( 0.0, 0.78, 0.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ),
+(57, "Lanthanum", "La", ( 0.43, 0.83, 1.0), 1.69, 1.69, 2.74 , 1 , 1.39 , 3 , 1.06 ),
+(58, "Cerium", "Ce", ( 1.0, 1.0, 0.78), 1.65, 1.65, 2.70 , 1 , 1.27 , 3 , 1.03 , 4 , 0.92 ),
+(59, "Praseodymium", "Pr", ( 0.85, 1.0, 0.78), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ),
+(60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78), 1.64, 1.64, 2.64 , 3 , 0.99 ),
+(61, "Promethium", "Pm", ( 0.63, 1.0, 0.78), 1.63, 1.63, 2.62 , 3 , 0.97 ),
+(62, "Samarium", "Sm", ( 0.56, 1.0, 0.78), 1.62, 1.62, 2.59 , 3 , 0.96 ),
+(63, "Europium", "Eu", ( 0.38, 1.0, 0.78), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ),
+(64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78), 1.61, 1.61, 2.54 , 3 , 0.93 ),
+(65, "Terbium", "Tb", ( 0.18, 1.0, 0.78), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ),
+(66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78), 1.59, 1.59, 2.49 , 3 , 0.90 ),
+(67, "Holmium", "Ho", ( 0.0, 1.0, 0.61), 1.58, 1.58, 2.47 , 3 , 0.89 ),
+(68, "Erbium", "Er", ( 0.0, 0.90, 0.45), 1.57, 1.57, 2.45 , 3 , 0.88 ),
+(69, "Thulium", "Tm", ( 0.0, 0.83, 0.32), 1.56, 1.56, 2.42 , 3 , 0.87 ),
+(70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ),
+(71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14), 1.56, 1.56, 2.25 , 3 , 0.85 ),
+(72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ),
+(73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ),
+(74, "Tungsten", "W", ( 0.12, 0.58, 0.83), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ),
+(75, "Rhenium", "Re", ( 0.14, 0.49, 0.67), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ),
+(76, "Osmium", "Os", ( 0.14, 0.4, 0.58), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ),
+(77, "Iridium", "Ir", ( 0.09, 0.32, 0.52), 1.27, 1.27, 1.87 , 4 , 0.68 ),
+(78, "Platinium", "Pt", ( 0.81, 0.81, 0.87), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ),
+(79, "Gold", "Au", ( 1.0, 0.81, 0.13), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ),
+(80, "Mercury", "Hg", ( 0.72, 0.72, 0.81), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ),
+(81, "Thallium", "Tl", ( 0.65, 0.32, 0.30), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ),
+(82, "Lead", "Pb", ( 0.34, 0.34, 0.38), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ),
+(83, "Bismuth", "Bi", ( 0.61, 0.30, 0.70), 1.46, 1.46, 1.63 , 1 , 0.98 , 3 , 0.96 , 5 , 0.74 ),
+(84, "Polonium", "Po", ( 0.67, 0.36, 0.0), 1.46, 1.46, 1.53 , 6 , 0.67 ),
+(85, "Astatine", "At", ( 0.45, 0.30, 0.27), 1.45, 1.45, 1.43 , -3 , 2.22 , 3 , 0.85 , 5 , 0.46 ),
+(86, "Radon", "Rn", ( 0.25, 0.50, 0.58), 1.00, 1.00, 1.34 ),
+(87, "Francium", "Fr", ( 0.25, 0.0, 0.4), 1.00, 1.00, 1.00 , 1 , 1.80 ),
+(88, "Radium", "Ra", ( 0.0, 0.49, 0.0), 1.00, 1.00, 1.00 , 2 , 1.43 ),
+(89, "Actinium", "Ac", ( 0.43, 0.67, 0.98), 1.00, 1.00, 1.00 , 3 , 1.18 ),
+(90, "Thorium", "Th", ( 0.0, 0.72, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ),
+(91, "Protactinium", "Pa", ( 0.0, 0.63, 1.0), 1.00, 1.00, 1.00 , 3 , 1.13 , 4 , 0.98 , 5 , 0.89 ),
+(92, "Uranium", "U", ( 0.0, 0.56, 1.0), 1.42, 1.42, 1.00 , 4 , 0.97 , 6 , 0.80 ),
+(93, "Neptunium", "Np", ( 0.0, 0.50, 1.0), 1.00, 1.00, 1.00 , 3 , 1.10 , 4 , 0.95 , 7 , 0.71 ),
+(94, "Plutonium", "Pu", ( 0.0, 0.41, 1.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ),
+(95, "Americium", "Am", ( 0.32, 0.36, 0.94), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ),
+(96, "Curium", "Cm", ( 0.47, 0.36, 0.89), 1.00, 1.00, 1.00 ),
+(97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89), 1.00, 1.00, 1.00 ),
+(98, "Californium", "Cf", ( 0.63, 0.21, 0.83), 1.00, 1.00, 1.00 ),
+(99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83), 1.00, 1.00, 1.00 ),
+(100, "Fermium", "Fm", ( 0.70, 0.12, 0.72), 1.00, 1.00, 1.00 ),
+(101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65), 1.00, 1.00, 1.00 ),
+(102, "Nobelium", "No", ( 0.74, 0.05, 0.52), 1.00, 1.00, 1.00 ),
+(103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4), 1.00, 1.00, 1.00 ),
+(104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00),
+(105, "Default", "Default", ( 1.0, 1.0, 1.0), 1.00, 1.00, 1.00),
+(106, "Stick", "Stick", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00),
+)
+
+# This list here contains all data of the elements and will be used during
+# runtime. It is a list of classes.
+# During executing Atomic Blender, the list will be initialized with the fixed
+# data from above via the class structure below (CLASS_atom_pdb_Elements). We
+# have then one fixed list (above), which will never be changed, and a list of
+# classes with same data. The latter can be modified via loading a separate
+# custom data file.
+ATOM_CLUSTER_ELEMENTS = []
+ATOM_CLUSTER_ALL_ATOMS = []
+
+# This is the class, which stores the properties for one element.
+class CLASS_atom_cluster_Elements(object):
+ __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic')
+ def __init__(self, number, name, short_name, color, radii, radii_ionic):
+ self.number = number
+ self.name = name
+ self.short_name = short_name
+ self.color = color
+ self.radii = radii
+ self.radii_ionic = radii_ionic
+
+# This is the class, which stores the properties of one atom.
+class CLASS_atom_cluster_atom(object):
+ __slots__ = ('location')
+ def __init__(self, location):
+ self.location = location
+
+# -----------------------------------------------------------------------------
+# Read atom data
+
+def DEF_atom_read_atom_data():
+
+ del ATOM_CLUSTER_ELEMENTS[:]
+
+ for item in ATOM_CLUSTER_ELEMENTS_DEFAULT:
+
+ # All three radii into a list
+ radii = [item[4],item[5],item[6]]
+ # The handling of the ionic radii will be done later. So far, it is an
+ # empty list.
+ radii_ionic = []
+
+ li = CLASS_atom_cluster_Elements(item[0],item[1],item[2],item[3],
+ radii,radii_ionic)
+ ATOM_CLUSTER_ELEMENTS.append(li)
+
+
+# -----------------------------------------------------------------------------
+# Routines for shapes
+
+def vec_in_sphere(atom_pos,size, skin):
+
+ regular = True
+ inner = True
+
+ if atom_pos.length > size/2.0:
+ regular = False
+
+ if atom_pos.length < (size/2.0)*(1-skin):
+ inner = False
+
+ return (regular, inner)
+
+
+def vec_in_parabole(atom_pos, height, diameter):
+
+ regular = True
+ inner = True
+
+ px = atom_pos[0]
+ py = atom_pos[1]
+ pz = atom_pos[2] + height/2.0
+
+ a = diameter / sqrt(4 * height)
+
+
+ if pz < 0.0:
+ return (False, False)
+ if px == 0.0 and py == 0.0:
+ return (True, True)
+
+ if py == 0.0:
+ y = 0.0
+ x = a * a * pz / px
+ z = x * x / (a * a)
+ else:
+ y = pz * py * a * a / (px*px + py*py)
+ x = y * px / py
+ z = (x*x + y*y) / (a * a)
+
+ if( atom_pos.length > sqrt(x*x+y*y+z*z) ):
+ regular = False
+
+ return (regular, inner)
+
+
+def vec_in_pyramide_square(atom_pos, size, skin):
+
+ """
+ Please, if possible leave all this! The code documents the
+ mathemetical way of cutting a pyramide with square base.
+
+ P1 = Vector((-size/2, 0.0, -size/4))
+ P2 = Vector((0.0, -size/2, -size/4))
+ P4 = Vector((size/2, 0.0, -size/4))
+ P5 = Vector((0.0, size/2, -size/4))
+ P6 = Vector((0.0, 0.0, size/4))
+
+ # First face
+ v11 = P1 - P2
+ v12 = P1 - P6
+ n1 = v11.cross(v12)
+ g1 = -n1 * P1
+
+ # Second face
+ v21 = P6 - P4
+ v22 = P6 - P5
+ n2 = v21.cross(v22)
+ g2 = -n2 * P6
+
+ # Third face
+ v31 = P1 - P5
+ v32 = P1 - P6
+ n3 = v32.cross(v31)
+ g3 = -n3 * P1
+
+ # Forth face
+ v41 = P6 - P2
+ v42 = P2 - P4
+ n4 = v41.cross(v42)
+ g4 = -n4 * P2
+
+ # Fith face, base
+ v51 = P2 - P1
+ v52 = P2 - P4
+ n5 = v51.cross(v52)
+ g5 = -n5 * P2
+ """
+
+ # A much faster way for calculation:
+ size2 = size * size
+ size3 = size2 * size
+ n1 = Vector((-1/4, -1/4, 1/4)) * size2
+ g1 = -1/16 * size3
+ n2 = Vector(( 1/4, 1/4, 1/4)) * size2
+ g2 = g1
+ n3 = Vector((-1/4, 1/4, 1/4)) * size2
+ g3 = g1
+ n4 = Vector(( 1/4, -1/4, 1/4)) * size2
+ g4 = g1
+ n5 = Vector(( 0.0, 0.0, -1/2)) * size2
+ g5 = -1/8 * size3
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+ distance_plane_5 = abs((n5 * atom_pos - g5)/n5.length)
+ on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
+
+ regular = True
+ inner = True
+ if(atom_pos.length > on_plane_1):
+ regular = False
+ if(atom_pos.length > on_plane_2):
+ regular = False
+ if(atom_pos.length > on_plane_3):
+ regular = False
+ if(atom_pos.length > on_plane_4):
+ regular = False
+ if(atom_pos.length > on_plane_5):
+ regular = False
+
+ if skin == 1.0:
+ return (regular, inner)
+
+ size = size * (1.0 - skin)
+
+ size2 = size * size
+ size3 = size2 * size
+ n1 = Vector((-1/4, -1/4, 1/4)) * size2
+ g1 = -1/16 * size3
+ n2 = Vector(( 1/4, 1/4, 1/4)) * size2
+ g2 = g1
+ n3 = Vector((-1/4, 1/4, 1/4)) * size2
+ g3 = g1
+ n4 = Vector(( 1/4, -1/4, 1/4)) * size2
+ g4 = g1
+ n5 = Vector(( 0.0, 0.0, -1/2)) * size2
+ g5 = -1/8 * size3
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+ distance_plane_5 = abs((n5 * atom_pos - g5)/n5.length)
+ on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
+
+ inner = False
+ if(atom_pos.length > on_plane_1):
+ inner = True
+ if(atom_pos.length > on_plane_2):
+ inner = True
+ if(atom_pos.length > on_plane_3):
+ inner = True
+ if(atom_pos.length > on_plane_4):
+ inner = True
+ if(atom_pos.length > on_plane_5):
+ inner = True
+
+ return (regular, inner)
+
+
+def vec_in_pyramide_hex_abc(atom_pos, size, skin):
+
+ a = size/2.0
+ #c = size/2.0*cos((30/360)*2.0*pi)
+ c = size * 0.4330127020
+ #s = size/2.0*sin((30/360)*2.0*pi)
+ s = size * 0.25
+ #h = 2.0 * (sqrt(6.0)/3.0) * c
+ h = 1.632993162 * c
+
+ """
+ Please, if possible leave all this! The code documents the
+ mathemetical way of cutting a tetraeder.
+
+ P1 = Vector((0.0, a, 0.0))
+ P2 = Vector(( -c, -s, 0.0))
+ P3 = Vector(( c, -s, 0.0))
+ P4 = Vector((0.0, 0.0, h))
+ C = (P1+P2+P3+P4)/4.0
+ P1 = P1 - C
+ P2 = P2 - C
+ P3 = P3 - C
+ P4 = P4 - C
+
+ # First face
+ v11 = P1 - P2
+ v12 = P1 - P4
+ n1 = v11.cross(v12)
+ g1 = -n1 * P1
+
+ # Second face
+ v21 = P2 - P3
+ v22 = P2 - P4
+ n2 = v21.cross(v22)
+ g2 = -n2 * P2
+
+ # Third face
+ v31 = P3 - P1
+ v32 = P3 - P4
+ n3 = v31.cross(v32)
+ g3 = -n3 * P3
+
+ # Forth face
+ v41 = P2 - P1
+ v42 = P2 - P3
+ n4 = v41.cross(v42)
+ g4 = -n4 * P1
+ """
+
+ n1 = Vector(( -h*(a+s), c*h, c*a ))
+ g1 = -1/2*c*(a*h+s*h)
+ n2 = Vector(( 0, -2*c*h, 2*c*s ))
+ g2 = -1/2*c*(a*h+s*h)
+ n3 = Vector(( h*(a+s), c*h, a*c ))
+ g3 = -1/2*c*(a*h+s*h)
+ n4 = Vector(( 0, 0, -2*c*(s+a) ))
+ g4 = -1/2*h*c*(s+a)
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+
+ regular = True
+ inner = True
+ if(atom_pos.length > on_plane_1):
+ regular = False
+ if(atom_pos.length > on_plane_2):
+ regular = False
+ if(atom_pos.length > on_plane_3):
+ regular = False
+ if(atom_pos.length > on_plane_4):
+ regular = False
+
+ if skin == 1.0:
+ return (regular, inner)
+
+ size = size * (1.0 - skin)
+
+ a = size/2.0
+ #c = size/2.0*cos((30/360)*2.0*pi)
+ c= size * 0.4330127020
+ #s = size/2.0*sin((30/360)*2.0*pi)
+ s = size * 0.25
+ #h = 2.0 * (sqrt(6.0)/3.0) * c
+ h = 1.632993162 * c
+
+ n1 = Vector(( -h*(a+s), c*h, c*a ))
+ g1 = -1/2*c*(a*h+s*h)
+ n2 = Vector(( 0, -2*c*h, 2*c*s ))
+ g2 = -1/2*c*(a*h+s*h)
+ n3 = Vector(( h*(a+s), c*h, a*c ))
+ g3 = -1/2*c*(a*h+s*h)
+ n4 = Vector(( 0, 0, -2*c*(s+a) ))
+ g4 = -1/2*h*c*(s+a)
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+
+ inner = False
+ if(atom_pos.length > on_plane_1):
+ inner = True
+ if(atom_pos.length > on_plane_2):
+ inner = True
+ if(atom_pos.length > on_plane_3):
+ inner = True
+ if(atom_pos.length > on_plane_4):
+ inner = True
+
+ return (regular, inner)
+
+
+
+def vec_in_octahedron(atom_pos,size, skin):
+
+ regular = True
+ inner = True
+
+ """
+ Please, if possible leave all this! The code documents the
+ mathemetical way of cutting an octahedron.
+
+ P1 = Vector((-size/2, 0.0, 0.0))
+ P2 = Vector((0.0, -size/2, 0.0))
+ P3 = Vector((0.0, 0.0, -size/2))
+ P4 = Vector((size/2, 0.0, 0.0))
+ P5 = Vector((0.0, size/2, 0.0))
+ P6 = Vector((0.0, 0.0, size/2))
+
+ # First face
+ v11 = P2 - P1
+ v12 = P2 - P3
+ n1 = v11.cross(v12)
+ g1 = -n1 * P2
+
+ # Second face
+ v21 = P1 - P5
+ v22 = P1 - P3
+ n2 = v21.cross(v22)
+ g2 = -n2 * P1
+
+ # Third face
+ v31 = P1 - P2
+ v32 = P1 - P6
+ n3 = v31.cross(v32)
+ g3 = -n3 * P1
+
+ # Forth face
+ v41 = P6 - P2
+ v42 = P2 - P4
+ n4 = v41.cross(v42)
+ g4 = -n4 * P2
+
+ # Fith face
+ v51 = P2 - P3
+ v52 = P2 - P4
+ n5 = v51.cross(v52)
+ g5 = -n5 * P2
+
+ # Six face
+ v61 = P6 - P4
+ v62 = P6 - P5
+ n6 = v61.cross(v62)
+ g6 = -n6 * P6
+
+ # Seventh face
+ v71 = P5 - P4
+ v72 = P5 - P3
+ n7 = v71.cross(v72)
+ g7 = -n7 * P5
+
+ # Eigth face
+ v81 = P1 - P5
+ v82 = P1 - P6
+ n8 = v82.cross(v81)
+ g8 = -n8 * P1
+ """
+
+ # A much faster way for calculation:
+ size2 = size * size
+ size3 = size2 * size
+ n1 = Vector((-1/4, -1/4, -1/4)) * size2
+ g1 = -1/8 * size3
+ n2 = Vector((-1/4, 1/4, -1/4)) * size2
+ g2 = g1
+ n3 = Vector((-1/4, -1/4, 1/4)) * size2
+ g3 = g1
+ n4 = Vector(( 1/4, -1/4, 1/4)) * size2
+ g4 = g1
+ n5 = Vector(( 1/4, -1/4, -1/4)) * size2
+ g5 = g1
+ n6 = Vector(( 1/4, 1/4, 1/4)) * size2
+ g6 = g1
+ n7 = Vector(( 1/4, 1/4, -1/4)) * size2
+ g7 = g1
+ n8 = Vector((-1/4, 1/4, 1/4)) * size2
+ g8 = g1
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+ distance_plane_5 = abs((n5 * atom_pos - g5)/n5.length)
+ on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
+ distance_plane_6 = abs((n6 * atom_pos - g6)/n6.length)
+ on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
+ distance_plane_7 = abs((n7 * atom_pos - g7)/n7.length)
+ on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
+ distance_plane_8 = abs((n8 * atom_pos - g8)/n8.length)
+ on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
+
+ if(atom_pos.length > on_plane_1):
+ regular = False
+ if(atom_pos.length > on_plane_2):
+ regular = False
+ if(atom_pos.length > on_plane_3):
+ regular = False
+ if(atom_pos.length > on_plane_4):
+ regular = False
+ if(atom_pos.length > on_plane_5):
+ regular = False
+ if(atom_pos.length > on_plane_6):
+ regular = False
+ if(atom_pos.length > on_plane_7):
+ regular = False
+ if(atom_pos.length > on_plane_8):
+ regular = False
+
+ if skin == 1.0:
+ return (regular, inner)
+
+ size = size * (1.0 - skin)
+
+ size2 = size * size
+ size3 = size2 * size
+ n1 = Vector((-1/4, -1/4, -1/4)) * size2
+ g1 = -1/8 * size3
+ n2 = Vector((-1/4, 1/4, -1/4)) * size2
+ g2 = g1
+ n3 = Vector((-1/4, -1/4, 1/4)) * size2
+ g3 = g1
+ n4 = Vector(( 1/4, -1/4, 1/4)) * size2
+ g4 = g1
+ n5 = Vector(( 1/4, -1/4, -1/4)) * size2
+ g5 = g1
+ n6 = Vector(( 1/4, 1/4, 1/4)) * size2
+ g6 = g1
+ n7 = Vector(( 1/4, 1/4, -1/4)) * size2
+ g7 = g1
+ n8 = Vector((-1/4, 1/4, 1/4)) * size2
+ g8 = g1
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+ distance_plane_5 = abs((n5 * atom_pos - g5)/n5.length)
+ on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
+ distance_plane_6 = abs((n6 * atom_pos - g6)/n6.length)
+ on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
+ distance_plane_7 = abs((n7 * atom_pos - g7)/n7.length)
+ on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
+ distance_plane_8 = abs((n8 * atom_pos - g8)/n8.length)
+ on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
+
+ inner = False
+ if(atom_pos.length > on_plane_1):
+ inner = True
+ if(atom_pos.length > on_plane_2):
+ inner = True
+ if(atom_pos.length > on_plane_3):
+ inner = True
+ if(atom_pos.length > on_plane_4):
+ inner = True
+ if(atom_pos.length > on_plane_5):
+ inner = True
+ if(atom_pos.length > on_plane_6):
+ inner = True
+ if(atom_pos.length > on_plane_7):
+ inner = True
+ if(atom_pos.length > on_plane_8):
+ inner = True
+
+ return (regular, inner)
+
+
+def vec_in_truncated_octahedron(atom_pos,size, skin):
+
+ regular = True
+ inner = True
+
+ # The normal octahedron
+ size2 = size * size
+ size3 = size2 * size
+ n1 = Vector((-1/4, -1/4, -1/4)) * size2
+ g1 = -1/8 * size3
+ n2 = Vector((-1/4, 1/4, -1/4)) * size2
+ g2 = g1
+ n3 = Vector((-1/4, -1/4, 1/4)) * size2
+ g3 = g1
+ n4 = Vector(( 1/4, -1/4, 1/4)) * size2
+ g4 = g1
+ n5 = Vector(( 1/4, -1/4, -1/4)) * size2
+ g5 = g1
+ n6 = Vector(( 1/4, 1/4, 1/4)) * size2
+ g6 = g1
+ n7 = Vector(( 1/4, 1/4, -1/4)) * size2
+ g7 = g1
+ n8 = Vector((-1/4, 1/4, 1/4)) * size2
+ g8 = g1
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+ distance_plane_5 = abs((n5 * atom_pos - g5)/n5.length)
+ on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
+ distance_plane_6 = abs((n6 * atom_pos - g6)/n6.length)
+ on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
+ distance_plane_7 = abs((n7 * atom_pos - g7)/n7.length)
+ on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
+ distance_plane_8 = abs((n8 * atom_pos - g8)/n8.length)
+ on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
+
+ # Here are the 6 additional faces
+ # pp = (size/2.0) - (sqrt(2.0)/2.0) * ((size/sqrt(2.0))/3.0)
+ pp = size / 3.0
+
+ n_1 = Vector((1.0,0.0,0.0))
+ n_2 = Vector((-1.0,0.0,0.0))
+ n_3 = Vector((0.0,1.0,0.0))
+ n_4 = Vector((0.0,-1.0,0.0))
+ n_5 = Vector((0.0,0.0,1.0))
+ n_6 = Vector((0.0,0.0,-1.0))
+
+ distance_plane_1b = abs((n_1 * atom_pos + pp)/n_1.length)
+ on_plane_1b = (atom_pos - n_1 * (distance_plane_1b/n_1.length)).length
+ distance_plane_2b = abs((n_2 * atom_pos + pp)/n_2.length)
+ on_plane_2b = (atom_pos - n_2 * (distance_plane_2b/n_2.length)).length
+ distance_plane_3b = abs((n_3 * atom_pos + pp)/n_3.length)
+ on_plane_3b = (atom_pos - n_3 * (distance_plane_3b/n_3.length)).length
+ distance_plane_4b = abs((n_4 * atom_pos + pp)/n_4.length)
+ on_plane_4b = (atom_pos - n_4 * (distance_plane_4b/n_4.length)).length
+ distance_plane_5b = abs((n_5 * atom_pos + pp)/n_5.length)
+ on_plane_5b = (atom_pos - n_5 * (distance_plane_5b/n_5.length)).length
+ distance_plane_6b = abs((n_6 * atom_pos + pp)/n_6.length)
+ on_plane_6b = (atom_pos - n_6 * (distance_plane_6b/n_6.length)).length
+
+ if(atom_pos.length > on_plane_1):
+ regular = False
+ if(atom_pos.length > on_plane_2):
+ regular = False
+ if(atom_pos.length > on_plane_3):
+ regular = False
+ if(atom_pos.length > on_plane_4):
+ regular = False
+ if(atom_pos.length > on_plane_5):
+ regular = False
+ if(atom_pos.length > on_plane_6):
+ regular = False
+ if(atom_pos.length > on_plane_7):
+ regular = False
+ if(atom_pos.length > on_plane_8):
+ regular = False
+ if(atom_pos.length > on_plane_1b):
+ regular = False
+ if(atom_pos.length > on_plane_2b):
+ regular = False
+ if(atom_pos.length > on_plane_3b):
+ regular = False
+ if(atom_pos.length > on_plane_4b):
+ regular = False
+ if(atom_pos.length > on_plane_5b):
+ regular = False
+ if(atom_pos.length > on_plane_6b):
+ regular = False
+
+ if skin == 1.0:
+ return (regular, inner)
+
+ size = size * (1.0 - skin)
+
+ # The normal octahedron
+ size2 = size * size
+ size3 = size2 * size
+ n1 = Vector((-1/4, -1/4, -1/4)) * size2
+ g1 = -1/8 * size3
+ n2 = Vector((-1/4, 1/4, -1/4)) * size2
+ g2 = g1
+ n3 = Vector((-1/4, -1/4, 1/4)) * size2
+ g3 = g1
+ n4 = Vector(( 1/4, -1/4, 1/4)) * size2
+ g4 = g1
+ n5 = Vector(( 1/4, -1/4, -1/4)) * size2
+ g5 = g1
+ n6 = Vector(( 1/4, 1/4, 1/4)) * size2
+ g6 = g1
+ n7 = Vector(( 1/4, 1/4, -1/4)) * size2
+ g7 = g1
+ n8 = Vector((-1/4, 1/4, 1/4)) * size2
+ g8 = g1
+
+ distance_plane_1 = abs((n1 * atom_pos - g1)/n1.length)
+ on_plane_1 = (atom_pos - n1 * (distance_plane_1/n1.length)).length
+ distance_plane_2 = abs((n2 * atom_pos - g2)/n2.length)
+ on_plane_2 = (atom_pos - n2 * (distance_plane_2/n2.length)).length
+ distance_plane_3 = abs((n3 * atom_pos - g3)/n3.length)
+ on_plane_3 = (atom_pos - n3 * (distance_plane_3/n3.length)).length
+ distance_plane_4 = abs((n4 * atom_pos - g4)/n4.length)
+ on_plane_4 = (atom_pos - n4 * (distance_plane_4/n4.length)).length
+ distance_plane_5 = abs((n5 * atom_pos - g5)/n5.length)
+ on_plane_5 = (atom_pos - n5 * (distance_plane_5/n5.length)).length
+ distance_plane_6 = abs((n6 * atom_pos - g6)/n6.length)
+ on_plane_6 = (atom_pos - n6 * (distance_plane_6/n6.length)).length
+ distance_plane_7 = abs((n7 * atom_pos - g7)/n7.length)
+ on_plane_7 = (atom_pos - n7 * (distance_plane_7/n7.length)).length
+ distance_plane_8 = abs((n8 * atom_pos - g8)/n8.length)
+ on_plane_8 = (atom_pos - n8 * (distance_plane_8/n8.length)).length
+
+ # Here are the 6 additional faces
+ # pp = (size/2.0) - (sqrt(2.0)/2.0) * ((size/sqrt(2.0))/3.0)
+ pp = size / 3.0
+
+ n_1 = Vector((1.0,0.0,0.0))
+ n_2 = Vector((-1.0,0.0,0.0))
+ n_3 = Vector((0.0,1.0,0.0))
+ n_4 = Vector((0.0,-1.0,0.0))
+ n_5 = Vector((0.0,0.0,1.0))
+ n_6 = Vector((0.0,0.0,-1.0))
+
+ distance_plane_1b = abs((n_1 * atom_pos + pp)/n_1.length)
+ on_plane_1b = (atom_pos - n_1 * (distance_plane_1b/n_1.length)).length
+ distance_plane_2b = abs((n_2 * atom_pos + pp)/n_2.length)
+ on_plane_2b = (atom_pos - n_2 * (distance_plane_2b/n_2.length)).length
+ distance_plane_3b = abs((n_3 * atom_pos + pp)/n_3.length)
+ on_plane_3b = (atom_pos - n_3 * (distance_plane_3b/n_3.length)).length
+ distance_plane_4b = abs((n_4 * atom_pos + pp)/n_4.length)
+ on_plane_4b = (atom_pos - n_4 * (distance_plane_4b/n_4.length)).length
+ distance_plane_5b = abs((n_5 * atom_pos + pp)/n_5.length)
+ on_plane_5b = (atom_pos - n_5 * (distance_plane_5b/n_5.length)).length
+ distance_plane_6b = abs((n_6 * atom_pos + pp)/n_6.length)
+ on_plane_6b = (atom_pos - n_6 * (distance_plane_6b/n_6.length)).length
+
+ inner = False
+
+ if(atom_pos.length > on_plane_1):
+ inner = True
+ if(atom_pos.length > on_plane_2):
+ inner = True
+ if(atom_pos.length > on_plane_3):
+ inner = True
+ if(atom_pos.length > on_plane_4):
+ inner = True
+ if(atom_pos.length > on_plane_5):
+ inner = True
+ if(atom_pos.length > on_plane_6):
+ inner = True
+ if(atom_pos.length > on_plane_7):
+ inner = True
+ if(atom_pos.length > on_plane_8):
+ inner = True
+ if(atom_pos.length > on_plane_1b):
+ inner = True
+ if(atom_pos.length > on_plane_2b):
+ inner = True
+ if(atom_pos.length > on_plane_3b):
+ inner = True
+ if(atom_pos.length > on_plane_4b):
+ inner = True
+ if(atom_pos.length > on_plane_5b):
+ inner = True
+ if(atom_pos.length > on_plane_6b):
+ inner = True
+
+ return (regular, inner)
+
+# -----------------------------------------------------------------------------
+# Routines for lattices
+
+def create_hexagonal_abcabc_lattice(ctype, size, skin, lattice):
+
+ atom_number_total = 0
+ atom_number_drawn = 0
+ y_displ = 0
+ z_displ = 0
+
+ """
+ e = (1/sqrt(2.0)) * lattice
+ f = sqrt(3.0/4.0) * e
+ df1 = (e/2.0) * tan((30.0/360.0)*2.0*pi)
+ df2 = (e/2.0) / cos((30.0/360.0)*2.0*pi)
+ g = sqrt(2.0/3.0) * e
+ """
+
+ e = 0.7071067810 * lattice
+ f = 0.8660254038 * e
+ df1 = 0.2886751348 * e
+ df2 = 0.5773502690 * e
+ g = 0.8164965810 * e
+
+ if ctype == "parabolid_abc":
+ # size = height, skin = diameter
+ number_x = int(skin/(2*e))+4
+ number_y = int(skin/(2*f))+4
+ number_z = int(size/(2*g))
+ else:
+ number_x = int(size/(2*e))+4
+ number_y = int(size/(2*f))+4
+ number_z = int(size/(2*g))+1+4
+
+
+ for k in range(-number_z,number_z+1):
+ for j in range(-number_y,number_y+1):
+ for i in range(-number_x,number_x+1):
+ atom = Vector((float(i)*e,float(j)*f,float(k)*g))
+
+ if y_displ == 1:
+ if z_displ == 1:
+ atom[0] += e/2.0
+ else:
+ atom[0] -= e/2.0
+ if z_displ == 1:
+ atom[0] -= e/2.0
+ atom[1] += df1
+ if z_displ == 2:
+ atom[0] += 0.0
+ atom[1] += df2
+
+ if ctype == "sphere_hex_abc":
+ message = vec_in_sphere(atom, size, skin)
+ elif ctype == "pyramide_hex_abc":
+ # size = height, skin = diameter
+ message = vec_in_pyramide_hex_abc(atom, size, skin)
+ elif ctype == "parabolid_abc":
+ message = vec_in_parabole(atom, size, skin)
+
+ if message[0] == True and message[1] == True:
+ atom_add = CLASS_atom_cluster_atom(atom)
+ ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
+ atom_number_total += 1
+ atom_number_drawn += 1
+ if message[0] == True and message[1] == False:
+ atom_number_total += 1
+
+ if y_displ == 1:
+ y_displ = 0
+ else:
+ y_displ = 1
+
+ y_displ = 0
+ if z_displ == 0:
+ z_displ = 1
+ elif z_displ == 1:
+ z_displ = 2
+ else:
+ z_displ = 0
+
+ print("Atom positions calculated")
+
+ return (atom_number_total, atom_number_drawn)
+
+
+def create_hexagonal_abab_lattice(ctype, size, skin, lattice):
+
+ atom_number_total = 0
+ atom_number_drawn = 0
+ y_displ = "even"
+ z_displ = "even"
+
+ """
+ e = (1/sqrt(2.0)) * lattice
+ f = sqrt(3.0/4.0) * e
+ df = (e/2.0) * tan((30.0/360.0)*2*pi)
+ g = sqrt(2.0/3.0) * e
+ """
+
+ e = 0.7071067814 * lattice
+ f = 0.8660254038 * e
+ df = 0.2886751348 * e
+ g = 0.8164965810 * e
+
+
+ if ctype == "parabolid_ab":
+ # size = height, skin = diameter
+ number_x = int(skin/(2*e))+4
+ number_y = int(skin/(2*f))+4
+ number_z = int(size/(2*g))
+ else:
+ number_x = int(size/(2*e))+4
+ number_y = int(size/(2*f))+4
+ number_z = int(size/(2*g))+1+4
+
+
+ for k in range(-number_z,number_z+1):
+ for j in range(-number_y,number_y+1):
+ for i in range(-number_x,number_x+1):
+
+ atom = Vector((float(i)*e,float(j)*f,float(k)*g))
+
+ if "odd" in y_displ:
+ if "odd" in z_displ:
+ atom[0] += e/2.0
+ else:
+ atom[0] -= e/2.0
+ if "odd" in z_displ:
+ atom[0] -= e/2.0
+ atom[1] += df
+
+ if ctype == "sphere_hex_ab":
+ message = vec_in_sphere(atom, size, skin)
+ elif ctype == "parabolid_ab":
+ # size = height, skin = diameter
+ message = vec_in_parabole(atom, size, skin)
+
+ if message[0] == True and message[1] == True:
+ atom_add = CLASS_atom_cluster_atom(atom)
+ ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
+ atom_number_total += 1
+ atom_number_drawn += 1
+ if message[0] == True and message[1] == False:
+ atom_number_total += 1
+
+ if "even" in y_displ:
+ y_displ = "odd"
+ else:
+ y_displ = "even"
+
+ y_displ = "even"
+ if "even" in z_displ:
+ z_displ = "odd"
+ else:
+ z_displ = "even"
+
+ print("Atom positions calculated")
+
+ return (atom_number_total, atom_number_drawn)
+
+
+def create_square_lattice(ctype, size, skin, lattice):
+
+ atom_number_total = 0
+ atom_number_drawn = 0
+
+ if ctype == "parabolid_square":
+ # size = height, skin = diameter
+ number_k = int(size/(2.0*lattice))
+ number_j = int(skin/(2.0*lattice)) + 5
+ number_i = int(skin/(2.0*lattice)) + 5
+ else:
+ number_k = int(size/(2.0*lattice))
+ number_j = int(size/(2.0*lattice))
+ number_i = int(size/(2.0*lattice))
+
+
+ for k in range(-number_k,number_k+1):
+ for j in range(-number_j,number_j+1):
+ for i in range(-number_i,number_i+1):
+
+ atom = Vector((float(i),float(j),float(k))) * lattice
+
+ if ctype == "sphere_square":
+ message = vec_in_sphere(atom, size, skin)
+ elif ctype == "pyramide_square":
+ message = vec_in_pyramide_square(atom, size, skin)
+ elif ctype == "parabolid_square":
+ # size = height, skin = diameter
+ message = vec_in_parabole(atom, size, skin)
+ elif ctype == "octahedron":
+ message = vec_in_octahedron(atom, size, skin)
+ elif ctype == "truncated_octahedron":
+ message = vec_in_truncated_octahedron(atom,size, skin)
+
+ if message[0] == True and message[1] == True:
+ atom_add = CLASS_atom_cluster_atom(atom)
+ ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
+ atom_number_total += 1
+ atom_number_drawn += 1
+ if message[0] == True and message[1] == False:
+ atom_number_total += 1
+
+ print("Atom positions calculated")
+
+ return (atom_number_total, atom_number_drawn)
+
+
+
+# -----------------------------------------------------------------------------
+# Routine for the icosahedron
+
+
+# Note that the icosahedron needs a special treatment since it requires a
+# non-common crystal lattice. The faces are (111) facets and the geometry
+# is five-fold. So far, a max size of 8217 atoms can be chosen.
+# More details about icosahedron shaped clusters can be found in:
+#
+# 1. C. Mottet, G. Tréglia, B. Legrand, Surface Science 383 (1997) L719-L727
+# 2. C. R. Henry, Surface Science Reports 31 (1998) 231-325
+
+# The following code is a translation from an existing Fortran code into Python.
+# The Fortran code has been created by Christine Mottet and translated by me
+# (Clemens Barth).
+
+# Although a couple of code lines are non-typical for Python, it is best to
+# leave the code as is.
+#
+# To do:
+#
+# 1. Unlimited cluster size
+# 2. Skin effect
+
+def create_icosahedron(size, lattice):
+
+ natot = int(1 + (10*size*size+15*size+11)*size/3)
+
+ x = list(range(natot+1))
+ y = list(range(natot+1))
+ z = list(range(natot+1))
+
+ xs = list(range(12+1))
+ ys = list(range(12+1))
+ zs = list(range(12+1))
+
+ xa = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(20+1)]
+ ya = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(20+1)]
+ za = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(20+1)]
+
+ naret = [[ [] for i in range(12+1)] for j in range(12+1)]
+ nfacet = [[[ [] for i in range(12+1)] for j in range(12+1)] for k in range(12+1)]
+
+ rac2 = sqrt(2.0)
+ rac5 = sqrt(5.0)
+ tdef = (rac5+1.0)/2.0
+
+ rapp = sqrt(2.0*(1.0-tdef/(tdef*tdef+1.0)))
+ nats = 2 * (5*size*size+1)
+ nat = 13
+ epsi = 0.01
+
+ x[1] = 0.0
+ y[1] = 0.0
+ z[1] = 0.0
+
+ for i in range(2, 5+1):
+ z[i] = 0.0
+ y[i+4] = 0.0
+ x[i+8] = 0.0
+
+ for i in range(2, 3+1):
+ x[i] = tdef
+ x[i+2] = -tdef
+ x[i+4] = 1.0
+ x[i+6] = -1.0
+ y[i+8] = tdef
+ y[i+10] = -tdef
+
+ for i in range(2, 4+1, 2):
+ y[i] = 1.0
+ y[i+1] = -1.0
+ z[i+4] = tdef
+ z[i+5] = -tdef
+ z[i+8] = 1.0
+ z[i+9] = -1.0
+
+ xdef = rac2 / sqrt(tdef * tdef + 1)
+
+ for i in range(2, 13+1):
+ x[i] = x[i] * xdef / 2.0
+ y[i] = y[i] * xdef / 2.0
+ z[i] = z[i] * xdef / 2.0
+
+ if size > 1:
+
+ for n in range (2, size+1):
+ ifacet = 0
+ iaret = 0
+ inatf = 0
+ for i in range(1, 12+1):
+ for j in range(1, 12+1):
+ naret[i][j] = 0
+ for k in range (1, 12+1):
+ nfacet[i][j][k] = 0
+
+ nl1 = 6
+ nl2 = 8
+ nl3 = 9
+ k1 = 0
+ k2 = 0
+ k3 = 0
+ k12 = 0
+ for i in range(1, 12+1):
+ nat += 1
+ xs[i] = n * x[i+1]
+ ys[i] = n * y[i+1]
+ zs[i] = n * z[i+1]
+ x[nat] = xs[i]
+ y[nat] = ys[i]
+ z[nat] = zs[i]
+ k1 += 1
+
+ for i in range(1, 12+1):
+ for j in range(2, 12+1):
+ if j <= i:
+ continue
+
+ xij = xs[j] - xs[i]
+ yij = ys[j] - ys[i]
+ zij = zs[j] - zs[i]
+ xij2 = xij * xij
+ yij2 = yij * yij
+ zij2 = zij * zij
+ dij2 = xij2 + yij2 + zij2
+ dssn = n * rapp / rac2
+ dssn2 = dssn * dssn
+ diffij = abs(dij2-dssn2)
+ if diffij >= epsi:
+ continue
+
+ for k in range(3, 12+1):
+ if k <= j:
+ continue
+
+ xjk = xs[k] - xs[j]
+ yjk = ys[k] - ys[j]
+ zjk = zs[k] - zs[j]
+ xjk2 = xjk * xjk
+ yjk2 = yjk * yjk
+ zjk2 = zjk * zjk
+ djk2 = xjk2 + yjk2 + zjk2
+ diffjk = abs(djk2-dssn2)
+ if diffjk >= epsi:
+ continue
+
+ xik = xs[k] - xs[i]
+ yik = ys[k] - ys[i]
+ zik = zs[k] - zs[i]
+ xik2 = xik * xik
+ yik2 = yik * yik
+ zik2 = zik * zik
+ dik2 = xik2 + yik2 + zik2
+ diffik = abs(dik2-dssn2)
+ if diffik >= epsi:
+ continue
+
+ if nfacet[i][j][k] != 0:
+ continue
+
+ ifacet += 1
+ nfacet[i][j][k] = ifacet
+
+ if naret[i][j] == 0:
+ iaret += 1
+ naret[i][j] = iaret
+ for l in range(1,n-1+1):
+ nat += 1
+ xa[i][j][l] = xs[i]+l*(xs[j]-xs[i]) / n
+ ya[i][j][l] = ys[i]+l*(ys[j]-ys[i]) / n
+ za[i][j][l] = zs[i]+l*(zs[j]-zs[i]) / n
+ x[nat] = xa[i][j][l]
+ y[nat] = ya[i][j][l]
+ z[nat] = za[i][j][l]
+
+ if naret[i][k] == 0:
+ iaret += 1
+ naret[i][k] = iaret
+ for l in range(1, n-1+1):
+ nat += 1
+ xa[i][k][l] = xs[i]+l*(xs[k]-xs[i]) / n
+ ya[i][k][l] = ys[i]+l*(ys[k]-ys[i]) / n
+ za[i][k][l] = zs[i]+l*(zs[k]-zs[i]) / n
+ x[nat] = xa[i][k][l]
+ y[nat] = ya[i][k][l]
+ z[nat] = za[i][k][l]
+
+ if naret[j][k] == 0:
+ iaret += 1
+ naret[j][k] = iaret
+ for l in range(1, n-1+1):
+ nat += 1
+ xa[j][k][l] = xs[j]+l*(xs[k]-xs[j]) / n
+ ya[j][k][l] = ys[j]+l*(ys[k]-ys[j]) / n
+ za[j][k][l] = zs[j]+l*(zs[k]-zs[j]) / n
+ x[nat] = xa[j][k][l]
+ y[nat] = ya[j][k][l]
+ z[nat] = za[j][k][l]
+
+ for l in range(2, n-1+1):
+ for ll in range(1, l-1+1):
+ xf = xa[i][j][l]+ll*(xa[i][k][l]-xa[i][j][l]) / l
+ yf = ya[i][j][l]+ll*(ya[i][k][l]-ya[i][j][l]) / l
+ zf = za[i][j][l]+ll*(za[i][k][l]-za[i][j][l]) / l
+ nat += 1
+ inatf += 1
+ x[nat] = xf
+ y[nat] = yf
+ z[nat] = zf
+ k3 += 1
+
+ atom_number_total = 0
+ atom_number_drawn = 0
+
+ for i in range (1,natot+1):
+
+ atom = Vector((x[i],y[i],z[i])) * lattice
+
+ atom_add = CLASS_atom_cluster_atom(atom)
+ ATOM_CLUSTER_ALL_ATOMS.append(atom_add)
+ atom_number_total += 1
+ atom_number_drawn += 1
+
+ return (atom_number_total, atom_number_drawn)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/__init__.py b/release/scripts/addons_contrib/add_mesh_rocks/__init__.py
new file mode 100644
index 0000000..c4c9f3e
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_rocks/__init__.py
@@ -0,0 +1,77 @@
+# Paul "BrikBot" Marshall
+# Created: July 1, 2011
+# Last Modified: November 17, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas
+# and testing.
+#
+# Coded in IDLE, tested in Blender 2.59. NumPy Recommended.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# The Blender Rock Creation tool is for rapid generation of
+# mesh rocks in Blender.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Rock Generator",
+ "author": "Paul Marshall (brikbot)",
+ "version": (1, 3),
+ "blender": (2, 61, 0),
+ "location": "View3D > Add > Rock Generator",
+ "description": "Adds a mesh rock to the Add Mesh menu",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6"\
+ "/Py/Scripts/Add_Mesh/Rock_Generator",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27314",
+ "category": "Add Mesh"}
+
+if "bpy" in locals():
+ import imp
+ imp.reload(rockgen)
+else:
+ from add_mesh_rocks import rockgen
+
+import bpy
+
+
+# Register:
+def menu_func_rocks(self, context):
+ self.layout.operator(rockgen.rocks.bl_idname,
+ text="Rock Generator",
+ icon="PLUGIN")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_mesh_add.append(menu_func_rocks)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_mesh_add.remove(menu_func_rocks)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml b/release/scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml
new file mode 100644
index 0000000..0202486
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml
@@ -0,0 +1,403 @@
+<?xml version="1.0" ?>
+<!DOCTYPE settings [
+<!ELEMENT settings (default,preset*)>
+<!ELEMENT default (title,size,shape,material,random)>
+<!ELEMENT preset (title,size,shape,material,random)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT size (scale+,skew+,use_scale_dis,scale_fac)>
+<!ELEMENT scale (axis,lower,upper)>
+<!ELEMENT axis (#PCDATA)>
+<!ELEMENT lower (#PCDATA)>
+<!ELEMENT upper (#PCDATA)>
+<!ELEMENT skew (axis,value)>
+<!ELEMENT value (#PCDATA)>
+<!ELEMENT use_scale_dis (#PCDATA)>
+<!ELEMENT scale_fac (#PCDATA)>
+<!ELEMENT shape (deform,rough,detail,display_detail,smooth_fac,smooth_it)>
+<!ELEMENT deform (#PCDATA)>
+<!ELEMENT rough (#PCDATA)>
+<!ELEMENT detail (#PCDATA)>
+<!ELEMENT display_detail (#PCDATA)>
+<!ELEMENT smooth_fac (#PCDATA)>
+<!ELEMENT smooth_it (#PCDATA)>
+<!ELEMENT material (mat_enable,mat_color,mat_bright,mat_rough,mat_spec,mat_hard,mat_use_trans,mat_alpha,mat_cloudy,mat_IOR,mat_mossy)>
+<!ELEMENT mat_enable (#PCDATA)>
+<!ELEMENT mat_color (#PCDATA)>
+<!ELEMENT mat_bright (#PCDATA)>
+<!ELEMENT mat_rough (#PCDATA)>
+<!ELEMENT mat_spec (#PCDATA)>
+<!ELEMENT mat_hard (#PCDATA)>
+<!ELEMENT mat_use_trans (#PCDATA)>
+<!ELEMENT mat_alpha (#PCDATA)>
+<!ELEMENT mat_cloudy (#PCDATA)>
+<!ELEMENT mat_IOR (#PCDATA)>
+<!ELEMENT mat_mossy (#PCDATA)>
+<!ELEMENT random (use_random_seed,user_seed)>
+<!ELEMENT use_generate (#PCDATA)>
+<!ELEMENT use_random_seed (#PCDATA)>
+<!ELEMENT user_seed (#PCDATA)>
+
+<!ATTLIST preset id ID #REQUIRED>
+]>
+<settings>
+ <default>
+ <title>Default</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>5.0</deform>
+ <rough>2.5</rough>
+ <detail>3</detail>
+ <display_detail>2</display_detail>
+ <smooth_fac>0.0</smooth_fac>
+ <smooth_it>0</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>False</mat_enable>
+ <mat_color>[0.5, 0.5, 0.5]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>1.0</mat_rough>
+ <mat_spec>0.2</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </default>
+ <preset id="1">
+ <title>River Rock</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>0.5</lower>
+ <upper>1.25</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>0.5</lower>
+ <upper>1.25</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>0.5</lower>
+ <upper>1.25</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>-0.5</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>-0.5</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>-0.5</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>3.0</deform>
+ <rough>2.0</rough>
+ <detail>2</detail>
+ <display_detail>2</display_detail>
+ <smooth_fac>2.0</smooth_fac>
+ <smooth_it>2</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.5, 0.5, 0.5]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>0.125</mat_rough>
+ <mat_spec>0.5</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="2">
+ <title>Astroid</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>1.0</lower>
+ <upper>5.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>1.0</lower>
+ <upper>5.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>1.0</lower>
+ <upper>5.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>7.5</deform>
+ <rough>3.0</rough>
+ <detail>4</detail>
+ <display_detail>3</display_detail>
+ <smooth_fac>0.0</smooth_fac>
+ <smooth_it>0</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.3, 0.25, 0.2]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>1.5</mat_rough>
+ <mat_spec>0.25</mat_spec>
+ <mat_hard>30</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="3">
+ <title>Sandstone</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>True</use_scale_dis>
+ <scale_fac>[5.0, 5.0, 0.1]</scale_fac>
+ </size>
+ <shape>
+ <deform>0.5</deform>
+ <rough>1.0</rough>
+ <detail>3</detail>
+ <display_detail>3</display_detail>
+ <smooth_fac>2.0</smooth_fac>
+ <smooth_it>2</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.5, 0.4, 0.35]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>0.1</mat_rough>
+ <mat_spec>0.2</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="4">
+ <title>Ice</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>0.0</lower>
+ <upper>2.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>0.0</lower>
+ <upper>2.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>0.0</lower>
+ <upper>2.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>5.0</deform>
+ <rough>1.0</rough>
+ <detail>3</detail>
+ <display_detail>2</display_detail>
+ <smooth_fac>2.0</smooth_fac>
+ <smooth_it>1</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.9, 0.95, 1.0]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>0.25</mat_rough>
+ <mat_spec>0.2</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>True</mat_use_trans>
+ <mat_alpha>0.9</mat_alpha>
+ <mat_cloudy>0.1</mat_cloudy>
+ <mat_IOR>1.31</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="5">
+ <title>Fake Ocean</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>10.0</lower>
+ <upper>10.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>10.0</lower>
+ <upper>10.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>0.0</lower>
+ <upper>0.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>7.5</deform>
+ <rough>3.0</rough>
+ <detail>4</detail>
+ <display_detail>3</display_detail>
+ <smooth_fac>0.0</smooth_fac>
+ <smooth_it>0</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.1, 0.12, 0.125]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>1.5</mat_rough>
+ <mat_spec>0.25</mat_spec>
+ <mat_hard>30</mat_hard>
+ <mat_use_trans>True</mat_use_trans>
+ <mat_alpha>0.5</mat_alpha>
+ <mat_cloudy>0.5</mat_cloudy>
+ <mat_IOR>1.333</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+</settings>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/factory.xml b/release/scripts/addons_contrib/add_mesh_rocks/factory.xml
new file mode 100644
index 0000000..0202486
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_rocks/factory.xml
@@ -0,0 +1,403 @@
+<?xml version="1.0" ?>
+<!DOCTYPE settings [
+<!ELEMENT settings (default,preset*)>
+<!ELEMENT default (title,size,shape,material,random)>
+<!ELEMENT preset (title,size,shape,material,random)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT size (scale+,skew+,use_scale_dis,scale_fac)>
+<!ELEMENT scale (axis,lower,upper)>
+<!ELEMENT axis (#PCDATA)>
+<!ELEMENT lower (#PCDATA)>
+<!ELEMENT upper (#PCDATA)>
+<!ELEMENT skew (axis,value)>
+<!ELEMENT value (#PCDATA)>
+<!ELEMENT use_scale_dis (#PCDATA)>
+<!ELEMENT scale_fac (#PCDATA)>
+<!ELEMENT shape (deform,rough,detail,display_detail,smooth_fac,smooth_it)>
+<!ELEMENT deform (#PCDATA)>
+<!ELEMENT rough (#PCDATA)>
+<!ELEMENT detail (#PCDATA)>
+<!ELEMENT display_detail (#PCDATA)>
+<!ELEMENT smooth_fac (#PCDATA)>
+<!ELEMENT smooth_it (#PCDATA)>
+<!ELEMENT material (mat_enable,mat_color,mat_bright,mat_rough,mat_spec,mat_hard,mat_use_trans,mat_alpha,mat_cloudy,mat_IOR,mat_mossy)>
+<!ELEMENT mat_enable (#PCDATA)>
+<!ELEMENT mat_color (#PCDATA)>
+<!ELEMENT mat_bright (#PCDATA)>
+<!ELEMENT mat_rough (#PCDATA)>
+<!ELEMENT mat_spec (#PCDATA)>
+<!ELEMENT mat_hard (#PCDATA)>
+<!ELEMENT mat_use_trans (#PCDATA)>
+<!ELEMENT mat_alpha (#PCDATA)>
+<!ELEMENT mat_cloudy (#PCDATA)>
+<!ELEMENT mat_IOR (#PCDATA)>
+<!ELEMENT mat_mossy (#PCDATA)>
+<!ELEMENT random (use_random_seed,user_seed)>
+<!ELEMENT use_generate (#PCDATA)>
+<!ELEMENT use_random_seed (#PCDATA)>
+<!ELEMENT user_seed (#PCDATA)>
+
+<!ATTLIST preset id ID #REQUIRED>
+]>
+<settings>
+ <default>
+ <title>Default</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>5.0</deform>
+ <rough>2.5</rough>
+ <detail>3</detail>
+ <display_detail>2</display_detail>
+ <smooth_fac>0.0</smooth_fac>
+ <smooth_it>0</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>False</mat_enable>
+ <mat_color>[0.5, 0.5, 0.5]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>1.0</mat_rough>
+ <mat_spec>0.2</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </default>
+ <preset id="1">
+ <title>River Rock</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>0.5</lower>
+ <upper>1.25</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>0.5</lower>
+ <upper>1.25</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>0.5</lower>
+ <upper>1.25</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>-0.5</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>-0.5</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>-0.5</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>3.0</deform>
+ <rough>2.0</rough>
+ <detail>2</detail>
+ <display_detail>2</display_detail>
+ <smooth_fac>2.0</smooth_fac>
+ <smooth_it>2</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.5, 0.5, 0.5]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>0.125</mat_rough>
+ <mat_spec>0.5</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="2">
+ <title>Astroid</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>1.0</lower>
+ <upper>5.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>1.0</lower>
+ <upper>5.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>1.0</lower>
+ <upper>5.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>7.5</deform>
+ <rough>3.0</rough>
+ <detail>4</detail>
+ <display_detail>3</display_detail>
+ <smooth_fac>0.0</smooth_fac>
+ <smooth_it>0</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.3, 0.25, 0.2]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>1.5</mat_rough>
+ <mat_spec>0.25</mat_spec>
+ <mat_hard>30</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="3">
+ <title>Sandstone</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>1.0</lower>
+ <upper>1.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>True</use_scale_dis>
+ <scale_fac>[5.0, 5.0, 0.1]</scale_fac>
+ </size>
+ <shape>
+ <deform>0.5</deform>
+ <rough>1.0</rough>
+ <detail>3</detail>
+ <display_detail>3</display_detail>
+ <smooth_fac>2.0</smooth_fac>
+ <smooth_it>2</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.5, 0.4, 0.35]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>0.1</mat_rough>
+ <mat_spec>0.2</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>False</mat_use_trans>
+ <mat_alpha>0.0</mat_alpha>
+ <mat_cloudy>0.0</mat_cloudy>
+ <mat_IOR>1.0</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="4">
+ <title>Ice</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>0.0</lower>
+ <upper>2.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>0.0</lower>
+ <upper>2.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>0.0</lower>
+ <upper>2.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>5.0</deform>
+ <rough>1.0</rough>
+ <detail>3</detail>
+ <display_detail>2</display_detail>
+ <smooth_fac>2.0</smooth_fac>
+ <smooth_it>1</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.9, 0.95, 1.0]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>0.25</mat_rough>
+ <mat_spec>0.2</mat_spec>
+ <mat_hard>50</mat_hard>
+ <mat_use_trans>True</mat_use_trans>
+ <mat_alpha>0.9</mat_alpha>
+ <mat_cloudy>0.1</mat_cloudy>
+ <mat_IOR>1.31</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+ <preset id="5">
+ <title>Fake Ocean</title>
+ <size>
+ <scale>
+ <axis>X</axis>
+ <lower>10.0</lower>
+ <upper>10.0</upper>
+ </scale>
+ <scale>
+ <axis>Y</axis>
+ <lower>10.0</lower>
+ <upper>10.0</upper>
+ </scale>
+ <scale>
+ <axis>Z</axis>
+ <lower>0.0</lower>
+ <upper>0.0</upper>
+ </scale>
+ <skew>
+ <axis>X</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Y</axis>
+ <value>0.0</value>
+ </skew>
+ <skew>
+ <axis>Z</axis>
+ <value>0.0</value>
+ </skew>
+ <use_scale_dis>False</use_scale_dis>
+ <scale_fac>[1.0, 1.0, 1.0]</scale_fac>
+ </size>
+ <shape>
+ <deform>7.5</deform>
+ <rough>3.0</rough>
+ <detail>4</detail>
+ <display_detail>3</display_detail>
+ <smooth_fac>0.0</smooth_fac>
+ <smooth_it>0</smooth_it>
+ </shape>
+ <material>
+ <mat_enable>True</mat_enable>
+ <mat_color>[0.1, 0.12, 0.125]</mat_color>
+ <mat_bright>0.85</mat_bright>
+ <mat_rough>1.5</mat_rough>
+ <mat_spec>0.25</mat_spec>
+ <mat_hard>30</mat_hard>
+ <mat_use_trans>True</mat_use_trans>
+ <mat_alpha>0.5</mat_alpha>
+ <mat_cloudy>0.5</mat_cloudy>
+ <mat_IOR>1.333</mat_IOR>
+ <mat_mossy>0.0</mat_mossy>
+ </material>
+ <random>
+ <use_generate>True</use_generate>
+ <use_random_seed>True</use_random_seed>
+ <user_seed>1</user_seed>
+ </random>
+ </preset>
+</settings>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/rockgen.py b/release/scripts/addons_contrib/add_mesh_rocks/rockgen.py
new file mode 100644
index 0000000..25df19a
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_rocks/rockgen.py
@@ -0,0 +1,1602 @@
+# Blender rock creation tool
+#
+# Based on BlenderGuru's asteroid tutorial and personal experimentation.
+# Tutorial: http://www.blenderguru.com/how-to-make-a-realistic-asteroid/
+# Update with another tutorial shared by "rusted" of BlenderArtists:
+# Tutorial: http://saschahenrichs.blogspot.com/2010/03/3dsmax-environment-modeling-1.html
+#
+# Uses the NumPy Gaussian random number generator to generate a
+# a rock within a given range and give some randomness to the displacement
+# texture values. NumPy's gaussian generator was chosen as, based on
+# profiling I performed, it runs in about half the time as the built in
+# Python gaussian equivalent. I would like to shift the script to use the
+# NumPy beta distribution as it ran in about half the time as the NumPy
+# gaussian once the skew calculations are added.
+#
+# Set lower and upper bounds to the same for no randomness.
+#
+# Tasks:
+# Generate meshes with random scaling between given values.
+# - Allow for a skewed distribution
+# *** Completed on 4/17/2011 ***
+# - Create a set of meshes that can be used
+# Give the user the ability to set the subsurf level (detail level)
+# *** Completed on 4/29/2011 ***
+# - Set subsurf modifiers to default at view:3, render:3.
+# *** Completed on 4/17/2011 ***
+# - Set crease values to allow for hard edges on first subsurf.
+# *** Completed on 4/29/2011 ***
+# Be able to generate and add a texture to the displacement modifiers.
+# *** Completed 5/17/2011 ***
+# - Generate three displacement modifiers.
+# - The first only uses a Musgrave for initial intentations.
+# *** Now generating four displacement modifiers ***
+# *** Completed on 5/17/2011 ***
+# - Set a randomness for the type and values of the displacement texture.
+# *** Completed 5/9/2011 ***
+# - Allow the user to set a value for the range of displacement.
+# -> Modification: have user set "roughness" and "roughness range".
+# *** Compleded on 4/23/2011 ***
+# Set material settings and assign material textures
+# *** Completed 6/9/2011 ***
+# - Mossiness of the rocks.
+# *** Completed 6/9/2011 ***
+# - Color of the rocks.
+# *** Completed 5/16/2011 ***
+# - Wetness/shinyness of the rock.
+# *** Completed 5/6/2011 ***
+# - For all the user provides a mean value for a skewed distribution.
+# *** Removed to lessen usage complexity ***
+# Add some presets (mesh) to make it easier to use
+# - Examples: river rock, asteroid, quaried rock, etc
+# *** Completed 7/12/2011 ***
+#
+# Code Optimization:
+# Remove all "bpy.ops" operations with "bpy.data" base operations.
+# Remove material/texture cataloging with building a list of
+# returned values from bpy.data.*.new() operations.
+# *** Completed on 9/6/2011 ***
+# Search for places where list comprehensions can be used.
+# Look for alternate methods
+# - Possible alternate and more efficient data structures
+# - Possible alternate algorithms may realize greater performance
+# - Look again at multi-processing. Without bpy.ops is might
+# be viable.
+#
+# Future tasks:
+# Multi-thread the script
+# *** Will not be implemented. Multi-processing is adding to much
+# overhead to realize a performance increase ***
+# - Learn basic multi-threading in Python (multiprocessing)
+# - Break material generation into separate threads (processes)
+# - Break mesh generation into separate threads (processes)
+# - Move name generation, texture ID generation, etc to process first
+# - Roll version to 2.0 on completion
+#
+# Paul "BrikBot" Marshall
+# Created: April 17, 2011
+# Last Modified: November 17, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas
+# and testing.
+#
+# Coded in IDLE, tested in Blender 2.59. NumPy Recommended.
+# Search for "@todo" to quickly find sections that need work.
+#
+# Remeber -
+# Functional code comes before fast code. Once it works, then worry about
+# making it faster/more efficient.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# The Blender Rock Creation tool is for rapid generation of mesh rocks.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+import math
+import time
+from add_mesh_rocks import (settings,
+ utils)
+from bpy_extras import object_utils
+from mathutils import (Color,
+ Vector)
+from bpy.props import (BoolProperty,
+ IntProperty,
+ FloatProperty,
+ FloatVectorProperty,
+ EnumProperty)
+
+# This try block allows for the script to psudo-intelligently select the
+# appropriate random to use. If Numpy's random is present it will use that.
+# If Numpy's random is not present, it will through a "module not found"
+# exception and instead use the slower built-in random that Python has.
+try:
+ from numpy.random import random_integers as randint
+ from numpy.random import normal as gauss
+ from numpy.random import (beta,
+ uniform,
+ seed,
+ weibull)
+ print("Rock Generator: Numpy found.")
+ numpy = True
+except:
+ from random import (randint,
+ gauss,
+ uniform,
+ seed)
+ from random import betavariate as beta
+ from random import weibullvariate as weibull
+ print("Rock Generator: Numpy not found. Using Python's random.")
+ numpy = False
+
+# Global variables:
+lastRock = 0
+
+
+# Creates a new mesh:
+#
+# param: verts - Vector of vertices for the mesh.
+# edges - Edges for the mesh. Can be "[]".
+# faces - Face tuples corresponding to vertices.
+# name - Name of the mesh.
+def createMeshObject(context, verts, edges, faces, name):
+ # Create new mesh
+ mesh = bpy.data.meshes.new(name)
+
+ # Make a mesh from a list of verts/edges/faces.
+ mesh.from_pydata(verts, edges, faces)
+
+ # Set mesh to use auto smoothing:
+ mesh.use_auto_smooth = True
+
+ # Update mesh geometry after adding stuff.
+ mesh.update()
+
+ return object_utils.object_data_add(context, mesh, operator=None)
+
+
+# Set the values for a texture from parameters.
+#
+# param: texture - bpy.data.texture to modify.
+# level - designated tweaked settings to use
+# -> Below 10 is a displacment texture
+# -> Between 10 and 20 is a base material texture
+def randomizeTexture(texture, level=1):
+ noises = ['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN', 'IMPROVED_PERLIN',
+ 'VORONOI_F1', 'VORONOI_F2', 'VORONOI_F3', 'VORONOI_F4',
+ 'VORONOI_F2_F1', 'VORONOI_CRACKLE']
+ if texture.type == 'CLOUDS':
+ if randint(0, 1) == 0:
+ texture.noise_type = 'SOFT_NOISE'
+ else:
+ texture.noise_type = 'HARD_NOISE'
+ if level != 11:
+ tempInt = randint(0, 6)
+ else:
+ tempInt = randint(0, 8)
+ texture.noise_basis = noises[tempInt]
+ texture.noise_depth = 8
+
+ if level == 0:
+ texture.noise_scale = gauss(0.625, 1 / 24)
+ elif level == 2:
+ texture.noise_scale = 0.15
+ elif level == 11:
+ texture.noise_scale = gauss(0.5, 1 / 24)
+
+ if texture.noise_basis in ['BLENDER_ORIGINAL', 'ORIGINAL_PERLIN',
+ 'IMPROVED_PERLIN', 'VORONOI_F1']:
+ texture.intensity = gauss(1, 1 / 6)
+ texture.contrast = gauss(4, 1 / 3)
+ elif texture.noise_basis in ['VORONOI_F2', 'VORONOI_F3', 'VORONOI_F4']:
+ texture.intensity = gauss(0.25, 1 / 12)
+ texture.contrast = gauss(2, 1 / 6)
+ elif texture.noise_basis == 'VORONOI_F2_F1':
+ texture.intensity = gauss(0.5, 1 / 6)
+ texture.contrast = gauss(2, 1 / 6)
+ elif texture.noise_basis == 'VORONOI_CRACKLE':
+ texture.intensity = gauss(0.5, 1 / 6)
+ texture.contrast = gauss(2, 1 / 6)
+ elif texture.type == 'MUSGRAVE':
+ musgraveType = ['MULTIFRACTAL', 'RIDGED_MULTIFRACTAL',
+ 'HYBRID_MULTIFRACTAL', 'FBM', 'HETERO_TERRAIN']
+ texture.musgrave_type = 'MULTIFRACTAL'
+ texture.dimension_max = abs(gauss(0, 0.6)) + 0.2
+ texture.lacunarity = beta(3, 8) * 8.2 + 1.8
+
+ if level == 0:
+ texture.noise_scale = gauss(0.625, 1 / 24)
+ texture.noise_intensity = 0.2
+ texture.octaves = 1.0
+ elif level == 2:
+ texture.intensity = gauss(1, 1 / 6)
+ texture.contrast = 0.2
+ texture.noise_scale = 0.15
+ texture.octaves = 8.0
+ elif level == 10:
+ texture.intensity = gauss(0.25, 1 / 12)
+ texture.contrast = gauss(1.5, 1 / 6)
+ texture.noise_scale = 0.5
+ texture.octaves = 8.0
+ elif level == 12:
+ texture.octaves = uniform(1, 3)
+ elif level > 12:
+ texture.octaves = uniform(2, 8)
+ else:
+ texture.intensity = gauss(1, 1 / 6)
+ texture.contrast = 0.2
+ texture.octaves = 8.0
+ elif texture.type == 'DISTORTED_NOISE':
+ tempInt = randint(0, 8)
+ texture.noise_distortion = noises[tempInt]
+ tempInt = randint(0, 8)
+ texture.noise_basis = noises[tempInt]
+ texture.distortion = skewedGauss(2.0, 2.6666, (0.0, 10.0), False)
+
+ if level == 0:
+ texture.noise_scale = gauss(0.625, 1 / 24)
+ elif level == 2:
+ texture.noise_scale = 0.15
+ elif level >= 12:
+ texture.noise_scale = gauss(0.2, 1 / 48)
+ elif texture.type == 'STUCCI':
+ stucciTypes = ['PLASTIC', 'WALL_IN', 'WALL_OUT']
+ if randint(0, 1) == 0:
+ texture.noise_type = 'SOFT_NOISE'
+ else:
+ texture.noise_type = 'HARD_NOISE'
+ tempInt = randint(0, 2)
+ texture.stucci_type = stucciTypes[tempInt]
+
+ if level == 0:
+ tempInt = randint(0, 6)
+ texture.noise_basis = noises[tempInt]
+ texture.noise_scale = gauss(0.625, 1 / 24)
+ elif level == 2:
+ tempInt = randint(0, 6)
+ texture.noise_basis = noises[tempInt]
+ texture.noise_scale = 0.15
+ elif level >= 12:
+ tempInt = randint(0, 6)
+ texture.noise_basis = noises[tempInt]
+ texture.noise_scale = gauss(0.2, 1 / 30)
+ else:
+ tempInt = randint(0, 6)
+ texture.noise_basis = noises[tempInt]
+ elif texture.type == 'VORONOI':
+ metrics = ['DISTANCE', 'DISTANCE_SQUARED', 'MANHATTAN', 'CHEBYCHEV',
+ 'MINKOVSKY_HALF', 'MINKOVSKY_FOUR', 'MINKOVSKY']
+ # Settings for first dispalcement level:
+ if level == 0:
+ tempInt = randint(0, 1)
+ texture.distance_metric = metrics[tempInt]
+ texture.noise_scale = gauss(0.625, 1 / 24)
+ texture.contrast = 0.5
+ texture.intensity = 0.7
+ elif level == 2:
+ texture.noise_scale = 0.15
+ tempInt = randint(0, 6)
+ texture.distance_metric = metrics[tempInt]
+ elif level >= 12:
+ tempInt = randint(0, 1)
+ texture.distance_metric = metrics[tempInt]
+ texture.noise_scale = gauss(0.125, 1 / 48)
+ texture.contrast = 0.5
+ texture.intensity = 0.7
+ else:
+ tempInt = randint(0, 6)
+ texture.distance_metric = metrics[tempInt]
+
+ return
+
+
+# Randomizes the given material given base values.
+#
+# param: Material to randomize
+def randomizeMaterial(material, color, dif_int, rough, spec_int, spec_hard,
+ use_trans, alpha, cloudy, mat_IOR, mossiness, spec_IOR):
+ skew = False
+ stddev = 0.0
+ lastUsedTex = 1
+ numTex = 6
+ baseColor = []
+
+ # Diffuse settings:
+ material.diffuse_shader = 'OREN_NAYAR'
+ if 0.5 > dif_int:
+ stddev = dif_int / 3
+ skew = False
+ else:
+ stddev = (1 - dif_int) / 3
+ skew = True
+ material.diffuse_intensity = skewedGauss(dif_int, stddev, (0.0, 1.0), skew)
+ if 1.57 > rough:
+ stddev = rough / 3
+ skew = False
+ else:
+ stddev = (3.14 - rough) / 3
+ skew = True
+ material.roughness = skewedGauss(rough, stddev, (0.0, 3.14), skew)
+
+ for i in range(3):
+ if color[i] > 0.9 or color[i] < 0.1:
+ baseColor.append(skewedGauss(color[i], color[i] / 30,
+ (0, 1), color[i] > 0.9))
+ else:
+ baseColor.append(gauss(color[i], color[i] / 30))
+ material.diffuse_color = baseColor
+
+ # Specular settings:
+ material.specular_shader = 'BLINN'
+ if 0.5 > spec_int:
+ variance = spec_int / 3
+ skew = False
+ else:
+ variance = (1 - spec_int) / 3
+ skew = True
+ material.specular_intensity = skewedGauss(spec_int, stddev,
+ (0.0, 1.0), skew)
+ if 256 > spec_hard:
+ variance = (spec_hard - 1) / 3
+ skew = False
+ else:
+ variance = (511 - spec_hard) / 3
+ skew = True
+ material.specular_hardness = int(round(skewedGauss(spec_hard, stddev,
+ (1.0, 511.0), skew)))
+ if 5.0 > spec_IOR:
+ variance = spec_IOR / 3
+ skew = False
+ else:
+ variance = (10.0 - spec_IOR) / 3
+ skew = True
+ material.specular_ior = skewedGauss(spec_IOR, stddev, (0.0, 10.0), skew)
+
+ # Raytrans settings:
+ # *** Added on 11/17/2011 ***
+ material.use_transparency = use_trans
+ if use_trans:
+ trans = material.raytrace_transparency
+ # Fixed values:
+ material.transparency_method = 'RAYTRACE'
+ trans.depth = 24
+ trans.gloss_samples = 32
+ trans.falloff = 1.0
+ # Needs randomization:
+ material.alpha = -gauss(alpha, 0.05) + 1;
+ trans.gloss_factor = -gauss(cloudy, 0.05) + 1
+ trans.filter = gauss(cloudy, 0.1)
+ trans.ior = skewedGauss(mat_IOR, 0.01, [0.25, 4.0], mat_IOR > 2.125)
+
+ #Misc. settings:
+ material.use_transparent_shadows = True
+
+ # Rock textures:
+ # Now using slot.texture for texture access instead of
+ # bpy.data.textures[newTex[<index>]]
+ # *** Completed on 9/6/2011 ***
+ # Create the four new textures:
+ textureTypes = ['MUSGRAVE', 'CLOUDS', 'DISTORTED_NOISE',
+ 'STUCCI', 'VORONOI']
+
+ for i in range(numTex):
+ texColor = []
+
+ # Set the active material slot:
+ material.active_texture_index = i
+ # Assign a texture to the active material slot:
+ material.active_texture = bpy.data.textures.new(name = 'stone_tex',
+ type = 'NONE')
+ # Store the slot to easy coding access:
+ slot = material.texture_slots[i]
+
+ # If the texture is not a moss texture:
+ if i > 1:
+ slot.texture.type = textureTypes[randint(0, 3)]
+
+ # Set the texture's color (RGB):
+ for j in range(3):
+ if color[j] > 0.9 or color[j] < 0.1:
+ texColor.append(skewedGauss(color[j], color[j] / 30,
+ (0, 1), color[j] > 0.9))
+ else:
+ texColor.append(gauss(color[j], color[j] / 30))
+ slot.color = texColor
+ # Randomize the value (HSV):
+ v = material.diffuse_color.v
+ if v == 0.5:
+ slot.color.v = gauss(v, v / 3)
+ elif v > 0.5:
+ slot.color.v = skewedGauss(v, v / 3, (0, 1), True)
+ else:
+ slot.color.v = skewedGauss(v, (1 - v) / 3, (0, 1), False)
+
+ # Adjust scale and normal based on texture type:
+ if slot.texture.type == 'VORONOI':
+ slot.scale = (gauss(5, 1), gauss(5, 1), gauss(5, 1))
+ slot.normal_factor = gauss(rough / 10, rough / 30)
+ elif slot.texture.type == 'STUCCI':
+ slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
+ gauss(1.5, 0.25))
+ slot.normal_factor = gauss(rough / 10, rough / 30)
+ elif slot.texture.type == 'DISTORTED_NOISE':
+ slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
+ gauss(1.5, 0.25))
+ slot.normal_factor = gauss(rough / 10, rough / 30)
+ elif slot.texture.type == 'MUSGRAVE':
+ slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
+ gauss(1.5, 0.25))
+ slot.normal_factor = gauss(rough, rough / 3)
+ elif slot.texture.type == 'CLOUDS':
+ slot.scale = (gauss(1.5, 0.25), gauss(1.5, 0.25),
+ gauss(1.5, 0.25))
+ slot.normal_factor = gauss(rough, rough / 3)
+
+ # Set the color influence to 0.5.
+ # This allows for the moss textures to show:
+ slot.diffuse_color_factor = 0.5
+ # Set additional influence booleans:
+ slot.use_stencil = True
+ slot.use_map_specular = True
+ slot.use_map_color_spec = True
+ slot.use_map_hardness = True
+ slot.use_map_normal = True
+ # The following is for setting up the moss textures:
+ else:
+ slot.texture.type = textureTypes[i]
+
+ # Set the mosses color (RGB):
+ texColor.append(gauss(0.5, 1 / 6))
+ texColor.append(1)
+ texColor.append(0)
+ slot.color = texColor
+ # Randomize the value (HSV):
+ slot.color.v = gauss(0.275, 1 / 24)
+
+ # Scale the texture size:
+ slot.scale = (gauss(1.5, 0.25),
+ gauss(1.5, 0.25),
+ gauss(1.5, 0.25))
+
+ # Set the strength of the moss color:
+ slot.diffuse_color_factor = mossiness
+ # Have it influence spec and hardness:
+ slot.use_map_specular = True
+ slot.use_map_color_spec = True
+ slot.use_map_hardness = True
+
+ # If the texutre is a voronoi crackle clouds, use "Negative":
+ if slot.texture.type == 'CLOUDS':
+ if slot.texture.noise_basis == 'VORONOI_CRACKLE':
+ slot.invert = True
+
+ if mossiness == 0:
+ slot.use = False
+
+ randomizeTexture(slot.texture, 10 + i)
+
+ return
+
+
+# Generates an object based on one of several different mesh types.
+# All meshes have exactly eight vertices, and may be built from either
+# tri's or quads.
+#
+# param: muX - mean X offset value
+# sigmaX - X offset standard deviation
+# scaleX - X upper and lower bounds
+# upperSkewX - Is the distribution upperskewed?
+# muY - mean Y offset value
+# sigmaY - Y offset standard deviation
+# scaleY - Y upper and lower bounds
+# upperSkewY - Is the distribution upperskewed?
+# muZ - mean Z offset value
+# sigmaZ - Z offset standard deviation
+# scaleZ - Z upper and lower bounds
+# upperSkewY - Is the distribution upperskewed?
+# base - base number on the end of the object name
+# shift - Addition to the base number for multiple runs.
+# scaleDisplace - Scale the displacement maps
+#
+# return: name - the built name of the object
+def generateObject(context, muX, sigmaX, scaleX, upperSkewX, muY, sigmaY,
+ scaleY, upperSkewY, muZ, sigmaZ, scaleZ, upperSkewZ, base,
+ shift, scaleDisplace, scale_fac):
+ x = []
+ y = []
+ z = []
+ shape = randint(0, 11)
+
+ # Cube
+ # Use parameters to re-scale cube:
+ # Reversed if/for nesting. Should be a little faster.
+ if shape == 0:
+ for j in range(8):
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 1:
+ for j in range(8):
+ if j in [0, 1, 3, 4]:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j in [2, 5]:
+ if sigmaX == 0:
+ x.append(0)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j in [6, 7]:
+ if sigmaX == 0:
+ x.append(0)
+ else:
+ x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 4)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 2:
+ for j in range(8):
+ if j in [0, 2, 5, 7]:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 4)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 4)
+ elif j in [1, 3, 4, 6]:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 3:
+ for j in range(8):
+ if j > 0:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ else:
+ if sigmaX == 0:
+ x.append(0)
+ else:
+ x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 8)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 8)
+ if sigmaZ == 0:
+ z.append(0)
+ else:
+ z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 8)
+ elif shape == 4:
+ for j in range(10):
+ if j in [0, 9]:
+ if sigmaX == 0:
+ x.append(0)
+ else:
+ x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j in [1, 2, 3, 4]:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j in [5, 7]:
+ if sigmaX == 0:
+ x.append(0)
+ else:
+ x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 3)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 3)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 3)
+ if sigmaZ == 0:
+ z.append(0)
+ else:
+ z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 6)
+ elif j in [6, 8]:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 3)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 3)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 3)
+ if sigmaZ == 0:
+ z.append(0)
+ else:
+ z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 6)
+ elif shape == 5:
+ for j in range(10):
+ if j == 0:
+ if sigmaX == 0:
+ x.append(0)
+ else:
+ x.append(skewedGauss(0, sigmaX, scaleX, upperSkewX) / 8)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 8)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j in [1, 2]:
+ if sigmaX == 0:
+ x.append(scaleZ[0] * .125)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.125)
+ if sigmaY == 0:
+ y.append(scaleZ[0] * 0.2165)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.2165)
+ if sigmaZ == 0:
+ z.append(0)
+ else:
+ z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 4)
+ elif j == 3:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 4)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
+ if sigmaZ == 0:
+ z.append(0)
+ else:
+ z.append(skewedGauss(0, sigmaZ, scaleZ, upperSkewZ) / 4)
+ elif j in [4, 6]:
+ if sigmaX == 0:
+ x.append(scaleX[0] * 0.25)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.25)
+ if sigmaY == 0:
+ y.append(scaleY[0] * 0.433)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.433)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j == 5:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 4)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 4)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j in [7, 9]:
+ if sigmaX == 0:
+ x.append(scaleX[0] * 0.10825)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) * 0.10825)
+ if sigmaY == 0:
+ y.append(scaleY[0] * 0.2165)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) * 0.2165)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif j == 8:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 4)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 6:
+ for j in range(7):
+ if j > 0:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ else:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 7:
+ for j in range(10):
+ if j in [1, 3, 4, 5, 8, 9]:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ else:
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(0)
+ else:
+ y.append(skewedGauss(0, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 8:
+ for j in range(7):
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 9:
+ for j in range(8):
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 10:
+ for j in range(7):
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+ elif shape == 11:
+ for j in range(7):
+ if sigmaX == 0:
+ x.append(scaleX[0] / 2)
+ else:
+ x.append(skewedGauss(muX, sigmaX, scaleX, upperSkewX) / 2)
+ if sigmaY == 0:
+ y.append(scaleY[0] / 2)
+ else:
+ y.append(skewedGauss(muY, sigmaY, scaleY, upperSkewY) / 2)
+ if sigmaZ == 0:
+ z.append(scaleZ[0] / 2)
+ else:
+ z.append(skewedGauss(muZ, sigmaZ, scaleZ, upperSkewZ) / 2)
+
+ # This is for scaling the displacement textures.
+ # Scale the vertices so that their average is equal to 1 * scale factor.
+ if scaleDisplace:
+ averageX = (sum(x) / len(x)) * scale_fac[0]
+ for i in range(len(x)):
+ x[i] /= averageX
+ averageY = (sum(y) / len(y)) * scale_fac[1]
+ for i in range(len(y)):
+ y[i] /= averageY
+ averageZ = (sum(z) / len(z)) * scale_fac[2]
+ for i in range(len(z)):
+ z[i] /= averageZ
+
+ # Build vertex and face arrays:
+ if shape == 1:
+ verts = [(-x[0],-y[0],-z[0]),(x[1],-y[1],-z[1]),(x[2],-y[2],z[2]),
+ (-x[3],y[3],-z[3]),(x[4],y[4],-z[4]),(x[5],y[5],z[5]),
+ (x[6],y[6],z[6]),(x[7],y[7],-z[7])]
+ faces = [[0,1,2],[0,1,7],[3,0,7],[3,4,7],[1,4,7],[3,4,5],[1,2,6],
+ [1,4,6],[4,5,6],[0,2,6],[0,3,6],[3,5,6]]
+ elif shape == 2:
+ verts = [(-x[0],y[0],-z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
+ (-x[3],y[3],-z[3]),(-x[4],-y[4],z[4]),(x[5],y[5],z[5]),
+ (x[6],y[6],z[6]),(-x[7],y[7],z[7])]
+ faces = [[0,1,2],[0,2,3],[0,3,7],[0,7,4],[1,4,5],[0,1,4],[5,1,2],
+ [5,2,6],[3,2,6],[3,6,7],[5,4,7],[5,6,7]]
+ elif shape == 3:
+ verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
+ (-x[3],y[3],-z[3]),(x[4],-y[4],z[4]),(x[5],y[5],z[5]),
+ (-x[6],y[6],z[6]),(-x[7],-y[7],z[7])]
+ faces = [[0,1,2],[0,2,3],[0,3,6],[0,6,7],[0,7,4],[0,4,1],[5,4,1,2],
+ [5,6,3,2],[5,4,7,6]]
+ elif shape == 4:
+ verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
+ (-x[3],y[3],-z[3]),(-x[4],-y[4],-z[4]),(x[5],-y[5],-z[5]),
+ (x[6],y[6],-z[6]),(x[7],y[7],-z[7]),(-x[8],y[8],-z[8]),
+ (x[9],y[9],-z[9])]
+ faces = [[0,1,6],[0,6,2],[0,2,7],[0,7,3],[0,3,8],[0,8,4],[0,4,5],
+ [0,5,1],[1,9,2],[2,9,3],[3,9,4],[4,9,1],[1,6,2],[2,7,3],
+ [3,8,4],[4,5,1]]
+ elif shape == 5:
+ verts = [(x[0],y[0],z[0]),(x[1],-y[1],z[1]),(x[2],y[2],z[2]),
+ (-x[3],y[3],z[3]),(x[4],-y[4],-z[4]),(x[5],y[5],-z[5]),
+ (x[6],y[6],-z[6]),(-x[7],y[7],-z[7]),(-x[8],y[8],-z[8]),
+ (-x[9],-y[9],-z[9])]
+ faces = [[0,1,2],[0,2,3],[0,3,1],[1,4,5],[1,5,2],[2,5,6],[2,6,7],
+ [2,7,3],[3,7,8],[3,8,9],[3,9,1],[1,9,4],[4,5,9],[5,6,7],
+ [7,8,9],[9,5,7]]
+ elif shape == 6:
+ verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
+ (-x[3],y[3],-z[3]),(-x[4],y[4],z[4]),(-x[5],-y[5],z[5]),
+ (-x[6],-y[6],-z[6])]
+ faces = [[0,1,2],[0,2,3,4],[0,1,6,5],[0,4,5],[1,2,3,6],[3,4,5,6]]
+ elif shape == 7:
+ verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
+ (x[3],y[3],-z[3]),(-x[4],y[4],-z[4]),(-x[5],y[5],z[5]),
+ (-x[6],y[6],z[6]),(-x[7],y[7],-z[7]),(-x[8],-y[8],-z[8]),
+ (-x[9],-y[9],z[9])]
+ faces = [[0,1,2],[0,2,3],[0,5,6],[0,6,9],[0,1,8,9],[0,3,4,5],
+ [1,2,7,8],[2,3,4,7],[4,5,6,7],[6,7,8,9]]
+ elif shape == 8:
+ verts = [(x[0],y[0],z[0]),(x[1],-y[1],-z[1]),(x[2],y[2],-z[2]),
+ (-x[3],y[3],-z[3]),(-x[4],-y[4],-z[4]),(-x[5],-y[5],z[5]),
+ (-x[6],y[6],z[6])]
+ faces = [[0,2,1],[0,1,4],[0,4,5],[0,5,6],[0,6,3,2],[2,1,4,3],
+ [3,6,5,4]]
+ elif shape == 9:
+ verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],y[2],z[2]),
+ (-x[3],-y[3],z[3]),(x[4],-y[4],-z[4]),(x[5],y[5],-z[5]),
+ (x[6],y[6],z[6]),(x[7],-y[7],z[7])]
+ faces = [[0,1,6,2],[1,5,7,6],[5,4,3,7],[4,0,2,3],[0,1,5,4],[3,2,6,7]]
+ elif shape == 10:
+ verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],y[2],z[2]),
+ (x[3],-y[3],z[3]),(x[4],y[4],z[4]),(x[5],y[5],-z[5]),
+ (x[6],-y[6],-z[6])]
+ faces = [[0,2,3],[0,3,6],[0,1,5,6],[2,3,4],[0,1,2],[1,2,4,5],[3,4,5,6]]
+ elif shape == 11:
+ verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],y[2],z[2]),
+ (x[3],-y[3],z[3]),(x[4],y[4],z[4]),(x[5],y[5],-z[5]),
+ (x[6],-y[6],-z[6])]
+ faces = [[0,2,3],[0,3,6],[0,1,5,6],[2,3,4],[5,6,3],[1,5,3,4],[0,1,4,2]]
+ else:
+ verts = [(-x[0],-y[0],-z[0]),(-x[1],y[1],-z[1]),(-x[2],-y[2],z[2]),
+ (-x[3],y[3],z[3]),(x[4],-y[4],-z[4]),(x[5],y[5],-z[5]),
+ (x[6],-y[6],z[6]),(x[7],y[7],z[7])]
+ faces = [[0,1,3,2],[0,1,5,4],[0,4,6,2],[7,5,4,6],[7,3,2,6],[7,5,1,3]]
+
+ name = "Rock." + str(base + shift).zfill(3)
+
+ # Make object:
+ obj = createMeshObject(context, verts, [], faces, name)
+
+ if scaleDisplace:
+ bpy.data.objects[name].scale = Vector((averageX, averageY, averageZ))
+
+ # For a slight speed bump / Readability:
+ mesh = bpy.data.meshes[name]
+
+ # Apply creasing:
+ if shape == 0:
+ for i in range(12):
+ # todo: "0.375 / 3"? WTF? That = 0.125. . . .
+ # *** Completed 7/15/2011: Changed second one ***
+ mesh.edges[i].crease = gauss(0.125, 0.125)
+ elif shape == 1:
+ for i in [0, 2]:
+ mesh.edges[i].crease = gauss(0.5, 0.125)
+ for i in [6, 9, 11, 12]:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ for i in [5, 7, 15, 16]:
+ mesh.edges[i].crease = gauss(0.125, 0.025)
+ elif shape == 2:
+ for i in range(18):
+ mesh.edges[i].crease = gauss(0.125, 0.025)
+ elif shape == 3:
+ for i in [0, 1, 6, 10, 13]:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ mesh.edges[8].crease = gauss(0.5, 0.125)
+ elif shape == 4:
+ for i in [5, 6, 7, 10, 14, 16, 19, 21]:
+ mesh.edges[i].crease = gauss(0.5, 0.125)
+ elif shape == 7:
+ for i in range(18):
+ if i in [0, 1, 2, 3, 6, 7, 8, 9, 13, 16]:
+ mesh.edges[i].crease = gauss(0.5, 0.125)
+ elif i in [11,17]:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ else:
+ mesh.edges[i].crease = gauss(0.125, 0.025)
+ elif shape == 8:
+ for i in range(12):
+ if i in [0, 3, 8, 9, 10]:
+ mesh.edges[i].crease = gauss(0.5, 0.125)
+ elif i == 11:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ else:
+ mesh.edges[i].crease = gauss(0.125, 0.025)
+ elif shape == 9:
+ for i in range(12):
+ if i in [0, 3, 4, 11]:
+ mesh.edges[i].crease = gauss(0.5, 0.125)
+ else:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ elif shape == 10:
+ for i in range(12):
+ if i in [0, 2, 3, 4, 8, 11]:
+ mesh.edges[i].crease = gauss(0.5, 0.125)
+ elif i in [1, 5, 7]:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ else:
+ mesh.edges[i].crease = gauss(0.125, 0.025)
+ elif shape == 11:
+ for i in range(11):
+ if i in [1, 2, 3, 4, 8, 11]:
+ mesh.edges[i].crease = gauss(0.25, 0.05)
+ else:
+ mesh.edges[i].crease = gauss(0.125, 0.025)
+
+ return name
+
+
+# Artifically skews a normal (gaussian) distribution. This will not create
+# a continuous distribution curve but instead acts as a piecewise finction.
+# This linearly scales the output on one side to fit the bounds.
+#
+# Example output historgrams:
+#
+# Upper skewed: Lower skewed:
+# | ▄ | _
+# | █ | █
+# | █_ | █
+# | ██ | _█
+# | _██ | ██
+# | _▄███_ | ██ _
+# | ▄██████ | ▄██▄█▄_
+# | _█▄███████ | ███████
+# | _██████████_ | ████████▄▄█_ _
+# | _▄▄████████████ | ████████████▄█_
+# | _▄_ ▄███████████████▄_ | _▄███████████████▄▄_
+# ------------------------- -----------------------
+# |mu |mu
+# Historgrams were generated in R (http://www.r-project.org/) based on the
+# calculations below and manually duplicated here.
+#
+# param: mu - mu is the mean of the distribution.
+# sigma - sigma is the standard deviation of the distribution.
+# bounds - bounds[0] is the lower bound and bounds[1]
+# is the upper bound.
+# upperSkewed - if the distribution is upper skewed.
+# return: out - Rondomly generated value from the skewed distribution.
+#
+# @todo: Because NumPy's random value generators are faster when called
+# a bunch of times at once, maybe allow this to generate and return
+# multiple values at once?
+def skewedGauss(mu, sigma, bounds, upperSkewed=True):
+ raw = gauss(mu, sigma)
+
+ # Quicker to check an extra condition than do unnecessary math. . . .
+ if raw < mu and not upperSkewed:
+ out = ((mu - bounds[0]) / (3 * sigma)) * raw + ((mu * (bounds[0] - (mu - 3 * sigma))) / (3 * sigma))
+ elif raw > mu and upperSkewed:
+ out = ((mu - bounds[1]) / (3 * -sigma)) * raw + ((mu * (bounds[1] - (mu + 3 * sigma))) / (3 * -sigma))
+ else:
+ out = raw
+
+ return out
+
+
+# @todo create a def for generating an alpha and beta for a beta distribution
+# given a mu, sigma, and an upper and lower bound. This proved faster in
+# profiling in addition to providing a much better distribution curve
+# provided multiple iterations happen within this function; otherwise it was
+# slower.
+# This might be a scratch because of the bounds placed on mu and sigma:
+#
+# For alpha > 1 and beta > 1:
+# mu^2 - mu^3 mu^3 - mu^2 + mu
+# ----------- < sigma < ----------------
+# 1 + mu 2 - mu
+#
+##def generateBeta(mu, sigma, scale, repitions=1):
+## results = []
+##
+## return results
+
+# Creates rock objects:
+def generateRocks(context, scaleX, skewX, scaleY, skewY, scaleZ, skewZ,
+ scale_fac, detail, display_detail, deform, rough,
+ smooth_fac, smooth_it, mat_enable, color, mat_bright,
+ mat_rough, mat_spec, mat_hard, mat_use_trans, mat_alpha,
+ mat_cloudy, mat_IOR, mat_mossy, numOfRocks=1, userSeed=1.0,
+ scaleDisplace=False, randomSeed=True):
+ global lastRock
+ newMat = []
+ sigmaX = 0
+ sigmaY = 0
+ sigmaZ = 0
+ upperSkewX = False
+ upperSkewY = False
+ upperSkewZ = False
+ shift = 0
+ lastUsedTex = 1
+ vertexScaling = []
+
+ # Seed the random Gaussian value generator:
+ if randomSeed:
+ seed(int(time.time()))
+ else:
+ seed(userSeed)
+
+ if mat_enable:
+ # Calculate the number of materials to use.
+ # If less than 10 rocks are being generated, generate one material
+ # per rock.
+ # If more than 10 rocks are being generated, generate
+ # ceil[(1/9)n + (80/9)] materials.
+ # -> 100 rocks will result in 20 materials
+ # -> 1000 rocks will result in 120 materials.
+ if numOfRocks < 10:
+ numOfMats = numOfRocks
+ else:
+ numOfMats = math.ceil((1/9) * numOfRocks + (80/9))
+
+ # newMat = generateMaterialsList(numOfMats)
+ # *** No longer needed on 9/6/2011 ***
+
+ # todo Set general material settings:
+ # *** todo completed 5/25/2011 ***
+ # Material roughness actual max = 3.14. Needs scaling.
+ mat_rough *= 0.628
+ spec_IOR = 1.875 * (mat_spec ** 2) + 7.125 * mat_spec + 1
+
+ # Changed as material mapping is no longer needed.
+ # *** Complete 9/6/2011 ***
+ for i in range(numOfMats):
+ newMat.append(bpy.data.materials.new(name = 'stone'))
+ randomizeMaterial(newMat[i], color, mat_bright,
+ mat_rough, mat_spec, mat_hard, mat_use_trans,
+ mat_alpha, mat_cloudy, mat_IOR, mat_mossy,
+ spec_IOR)
+
+ # These values need to be really small to look good.
+ # So the user does not have to use such ridiculously small values:
+ deform /= 10
+ rough /= 100
+
+ # Verify that the min really is the min:
+ if scaleX[1] < scaleX[0]:
+ scaleX[0], scaleX[1] = scaleX[1], scaleX[0]
+ if scaleY[1] < scaleY[0]:
+ scaleY[0], scaleY[1] = scaleY[1], scaleY[0]
+ if scaleZ[1] < scaleZ[0]:
+ scaleZ[0], scaleZ[1] = scaleZ[1], scaleZ[0]
+
+ # todo: edit below to allow for skewing the distribution
+ # *** todo completed 4/22/2011 ***
+ # *** Code now generating "int not scriptable error" in Blender ***
+ #
+ # Calculate mu and sigma for a Gaussian distributed random number
+ # generation:
+ # If the lower and upper bounds are the same, skip the math.
+ #
+ # sigma is the standard deviation of the values. The 95% interval is three
+ # standard deviations, which is what we want most generated values to fall
+ # in. Since it might be skewed we are going to use half the difference
+ # betwee the mean and the furthest bound and scale the other side down
+ # post-number generation.
+ if scaleX[0] != scaleX[1]:
+ skewX = (skewX + 1) / 2
+ muX = scaleX[0] + ((scaleX[1] - scaleX[0]) * skewX)
+ if skewX < 0.5:
+ sigmaX = (scaleX[1] - muX) / 3
+ else:
+ sigmaX = (muX - scaleX[0]) / 3
+ upperSkewX = True
+ else:
+ muX = scaleX[0]
+ if scaleY[0] != scaleY[1]:
+ skewY = (skewY + 1) / 2
+ muY = scaleY[0] + ((scaleY[1] - scaleY[0]) * skewY)
+ if skewY < 0.5:
+ sigmaY = (scaleY[1] - muY) / 3
+ else:
+ sigmaY = (muY - scaleY[0]) / 3
+ upperSkewY = True
+ else:
+ muY = scaleY[0]
+ if scaleZ[0] != scaleZ[1]:
+ skewZ = (skewZ + 1) / 2
+ muZ = scaleZ[0] + ((scaleZ[1] - scaleZ[0]) * skewZ)
+ if skewZ < 0.5:
+ sigmaZ = (scaleZ[1] - muZ) / 3
+ else:
+ sigmaZ = (muZ - scaleZ[0]) / 3
+ upperSkewZ = True
+ else:
+ muZ = scaleZ
+
+ for i in range(numOfRocks):
+ # todo: enable different random values for each (x,y,z) corrdinate for
+ # each vertex. This will add additional randomness to the shape of the
+ # generated rocks.
+ # *** todo completed 4/19/2011 ***
+ # *** Code is notably slower at high rock counts ***
+
+ name = generateObject(context, muX, sigmaX, scaleX, upperSkewX, muY,
+ sigmaY, scaleY, upperSkewY, muZ, sigmaZ, scaleZ,
+ upperSkewZ, i, lastRock, scaleDisplace, scale_fac)
+
+ rock = bpy.data.objects[name]
+
+ # todo Map what the two new textures will be:
+ # This is not working. It works on paper so . . . ???
+ # *** todo completed on 4/23/2011 ***
+ # *** todo re-added as the first rock is getting
+ # 'Texture.001' twice. ***
+ # *** todo completed on 4/25/2011 ***
+ # *** Script no longer needs to map new texture names 9/6/2011 ***
+
+ # Create the four new textures:
+ # todo Set displacement texture parameters:
+ # *** todo completed on 5/31/2011 ***
+ # Voronoi has been removed from being an option for the fine detail
+ # texture.
+ texTypes = ['CLOUDS', 'MUSGRAVE', 'DISTORTED_NOISE', 'STUCCI', 'VORONOI']
+ newTex = []
+ # The first texture is to give a more ranodm base shape appearance:
+ newTex.append(bpy.data.textures.new(name = 'rock_displacement',
+ type = texTypes[1]))
+ randomizeTexture(newTex[0], 0)
+ newTex.append(bpy.data.textures.new(name = 'rock_displacement',
+ type = texTypes[4]))
+ randomizeTexture(newTex[1], 0)
+ if numpy:
+ newTex.append(bpy.data.textures.new(name = 'rock_displacement',
+ type = texTypes[int(round(weibull(1, 1)[0] / 2.125))]))
+ randomizeTexture(newTex[2], 1)
+ newTex.append(bpy.data.textures.new(name = 'rock_displacement',
+ type = texTypes[int(round(weibull(1, 1)[0] / 2.125))]))
+ randomizeTexture(newTex[3], 2)
+ else:
+ newTex.append(bpy.data.textures.new(name = 'rock_displacement',
+ type = texTypes[int(round(weibull(1, 1) / 2.125))]))
+ randomizeTexture(newTex[2], 1)
+ newTex.append(bpy.data.textures.new(name = 'rock_displacement',
+ type = texTypes[int(round(weibull(1, 1) / 2.125))]))
+ randomizeTexture(newTex[3], 2)
+
+ # Add modifiers:
+ rock.modifiers.new(name = "Subsurf", type = 'SUBSURF')
+ rock.modifiers.new(name = "Subsurf", type = 'SUBSURF')
+ rock.modifiers.new(name = "Displace", type = 'DISPLACE')
+ rock.modifiers.new(name = "Displace", type = 'DISPLACE')
+ rock.modifiers.new(name = "Displace", type = 'DISPLACE')
+ rock.modifiers.new(name = "Displace", type = 'DISPLACE')
+
+ # If smoothing is enabled, allow a little randomness into the
+ # smoothing factor. Then add the smoothing modifier.
+ if smooth_fac > 0.0 and smooth_it > 0:
+ rock.modifiers.new(name = "Smooth", type='SMOOTH')
+ rock.modifiers[6].factor = gauss(smooth_fac, (smooth_fac ** 0.5) / 12)
+ rock.modifiers[6].iterations = smooth_it
+ # Make a call to random to keep things consistant:
+ else:
+ gauss(0, 1)
+
+ # Set subsurf modifier parameters:
+ rock.modifiers[0].levels = display_detail
+ rock.modifiers[0].render_levels = detail
+ rock.modifiers[1].levels = display_detail
+ rock.modifiers[1].render_levels = detail
+
+ # todo Set displacement modifier parameters:
+ # *** todo completed on 4/23/2011 ***
+ # *** toned down the variance on 4/26/2011 ***
+ # *** added third modifier on 4/28/2011 ***
+ # *** texture access changed on 9/6/2011 ***
+ rock.modifiers[2].texture = newTex[0]
+ rock.modifiers[2].strength = gauss(deform / 100, (1 / 300) * deform)
+ rock.modifiers[2].mid_level = 0
+ rock.modifiers[3].texture = newTex[1]
+ rock.modifiers[3].strength = gauss(deform, (1 / 3) * deform)
+ rock.modifiers[3].mid_level = 0
+ rock.modifiers[4].texture = newTex[2]
+ rock.modifiers[4].strength = gauss(rough * 2, (1 / 3) * rough)
+ rock.modifiers[5].texture = newTex[3]
+ rock.modifiers[5].strength = gauss(rough, (1 / 3) * rough)
+
+ # Set mesh to be smooth and fix the normals:
+ utils.smooth(bpy.data.meshes[name])
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.mesh.normals_make_consistent()
+ bpy.ops.object.editmode_toggle()
+
+ if mat_enable:
+ bpy.ops.object.material_slot_add()
+ rock.material_slots[0].material = newMat[randint(0, numOfMats - 1)]
+
+ # Store the last value of i:
+ shift = i
+
+ # Add the shift to lastRock:
+ lastRock += shift + 1
+
+ return
+
+
+# Much of the code below is more-or-less imitation of other addons and as such
+# I have left it undocumented.
+
+class rocks(bpy.types.Operator):
+ """Add rock objects"""
+ bl_idname = "mesh.rocks"
+ bl_label = "Add Rocks"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Add rocks"
+
+ # Get the preset values from the XML file.
+ # -> The script was morphed into a Python module
+ # to support this.
+ # Tell settings.py to parse the XML file with the settings.
+ # Then get the default values resulting from the parsing.
+ # Make a list containing the default values and append to that
+ # the presets specified in the same XML file. This list will
+ # be used to load preset values.
+ settings.parse()
+ defaults = settings.getDefault()
+ presetsList = [defaults]
+ presetsList += settings.getPresetLists()
+ presets = []
+ lastPreset = 0
+
+ # Build the presets list for the enum property.
+ # This needs to be a for loop as the user might add presets to
+ # the XML file and those should show here:
+ for i in range(len(presetsList)):
+ value = str(i)
+ name = presetsList[i][0]
+ description = name + " preset values."
+ presets.append((value, name, description))
+
+ preset_values = EnumProperty(items = presets,
+ name = "Presets",
+ description = "Preset values for some rock types")
+
+ num_of_rocks = IntProperty(name = "Number of rocks",
+ description = "Number of rocks to generate. WARNING: Slow at high values!",
+ min = 1, max = 1048576,
+ soft_max = 20,
+ default = 1)
+
+ scale_X = FloatVectorProperty(name = "X scale",
+ description = "X axis scaling range.",
+ min = 0.0, max = 256.0, step = 1,
+ default = defaults[1], size = 2)
+ skew_X = FloatProperty(name = "X skew",
+ description = "X Skew ratio. 0.5 is no skew.",
+ min = -1.0, max = 1.0, default = defaults[4])
+ scale_Y = FloatVectorProperty(name = "Y scale",
+ description = "Y axis scaling range.",
+ min = 0.0, max = 256.0, step = 1,
+ default = defaults[2], size = 2)
+ skew_Y = FloatProperty(name = "Y skew",
+ description = "Y Skew ratio. 0.5 is no skew.",
+ min = -1.0, max = 1.0, default = defaults[5])
+ scale_Z = FloatVectorProperty(name = "Z scale",
+ description = "Z axis scaling range.",
+ min = 0.0, max = 256.0, step = 1,
+ default = defaults[3], size = 2)
+ skew_Z = FloatProperty(name = "Z skew",
+ description = "Z Skew ratio. 0.5 is no skew.",
+ min = -1.0, max = 1.0, default = defaults[6])
+ use_scale_dis = BoolProperty(name = "Scale displace textures",
+ description = "Scale displacement textures with dimensions. May cause streched textures.",
+ default = defaults[7])
+ scale_fac = FloatVectorProperty(name = "Scaling Factor",
+ description = "XYZ scaling factor. 1 = no scaling.",
+ min = 0.0001, max = 256.0, step = 0.1,
+ default = defaults[8], size = 3)
+
+ # @todo Possible to title this section "Physical Properties:"?
+ deform = FloatProperty(name = "Deformation",
+ description = "Rock deformation",
+ min = 0.0, max = 1024.0, default = defaults[9])
+ rough = FloatProperty(name = "Roughness",
+ description = "Rock roughness",
+ min = 0.0, max = 1024.0, default = defaults[10])
+ detail = IntProperty(name = "Detail level",
+ description = "Detail level. WARNING: Slow at high values!",
+ min = 1, max = 1024, default = defaults[11])
+ display_detail = IntProperty(name = "Display Detail",
+ description = "Display detail. Use a lower value for high numbers of rocks.",
+ min = 1, max = 128, default = defaults[12])
+ smooth_fac = FloatProperty(name = "Smooth Factor",
+ description = "Smoothing factor. A value of 0 disables.",
+ min = 0.0, max = 128.0, default = defaults[13])
+ smooth_it = IntProperty(name = "Smooth Iterations",
+ description = "Smoothing iterations. A value of 0 disables.",
+ min = 0, max = 128, default = defaults[14])
+
+ # @todo Add material properties
+ mat_enable = BoolProperty(name = "Generate materials",
+ description = "Generate materials and textures for the rocks",
+ default = defaults[15])
+ mat_color = FloatVectorProperty(name = "Color",
+ description = "Base color settings (RGB)",
+ min = 0.0, max = 1.0, default = defaults[16], size = 3, subtype = 'COLOR')
+ mat_bright = FloatProperty(name = "Brightness",
+ description = "Material brightness",
+ min = 0.0, max = 1.0, default = defaults[17])
+ mat_rough = FloatProperty(name = "Roughness",
+ description = "Material roughness",
+ min = 0.0, max = 5.0, default = defaults[18])
+ mat_spec = FloatProperty(name = "Shine",
+ description = "Material specularity strength",
+ min = 0.0, max = 1.0, default = defaults[19])
+ mat_hard = IntProperty(name = "Hardness",
+ description = "Material hardness",
+ min = 0, max = 511, default = defaults[20])
+ mat_use_trans = BoolProperty(name = "Use Transparency",
+ description = "Enables transparency in rocks (WARNING: SLOW RENDER TIMES)",
+ default = defaults[21])
+ mat_alpha = FloatProperty(name = "Alpha",
+ description = "Transparency of the rocks",
+ min = 0.0, max = 1.0, default = defaults[22])
+ mat_cloudy = FloatProperty(name = "Cloudy",
+ description = "How cloudy the transparent rocks look",
+ min = 0.0, max = 1.0, default = defaults[23])
+ mat_IOR = FloatProperty(name = "IoR",
+ description = "Index of Refraction",
+ min = 0.25, max = 4.0, soft_max = 2.5,
+ default = defaults[24])
+ mat_mossy = FloatProperty(name = "Mossiness",
+ description = "Amount of mossiness on the rocks",
+ min = 0.0, max = 1.0, default = defaults[25])
+
+ use_generate = BoolProperty(name = "Generate Rocks",
+ description = "Enable actual generation.",
+ default = defaults[26])
+ use_random_seed = BoolProperty(name = "Use a random seed",
+ description = "Create a seed based on time. Causes user seed to be ignored.",
+ default = defaults[27])
+ user_seed = IntProperty(name = "User seed",
+ description = "Use a specific seed for the generator.",
+ min = 0, max = 1048576, default = defaults[28])
+
+
+ def draw(self, context):
+ layout = self.layout
+ box = layout.box()
+ box.prop(self, 'num_of_rocks')
+ box = layout.box()
+ box.prop(self, 'scale_X')
+ box.prop(self, 'skew_X')
+ box.prop(self, 'scale_Y')
+ box.prop(self, 'skew_Y')
+ box.prop(self, 'scale_Z')
+ box.prop(self, 'skew_Z')
+ box.prop(self, 'use_scale_dis')
+ if self.use_scale_dis:
+ box.prop(self, 'scale_fac')
+ else:
+ self.scale_fac = utils.toFloats(self.defaults[8])
+ box = layout.box()
+ box.prop(self, 'deform')
+ box.prop(self, 'rough')
+ box.prop(self, 'detail')
+ box.prop(self, 'display_detail')
+ box.prop(self, 'smooth_fac')
+ box.prop(self, 'smooth_it')
+ box = layout.box()
+ box.prop(self, 'mat_enable')
+ if self.mat_enable:
+ box.prop(self, 'mat_color')
+ box.prop(self, 'mat_bright')
+ box.prop(self, 'mat_rough')
+ box.prop(self, 'mat_spec')
+ box.prop(self, 'mat_hard')
+ box.prop(self, 'mat_use_trans')
+ if self.mat_use_trans:
+ box.prop(self, 'mat_alpha')
+ box.prop(self, 'mat_cloudy')
+ box.prop(self, 'mat_IOR')
+ box.prop(self, 'mat_mossy')
+ box = layout.box()
+ box.prop(self, 'use_generate')
+ box.prop(self, 'use_random_seed')
+ if not self.use_random_seed:
+ box.prop(self, 'user_seed')
+ box.prop(self, 'preset_values')
+
+
+ def execute(self, context):
+ # The following "if" block loads preset values:
+ if self.lastPreset != int(self.preset_values):
+ self.scale_X = utils.toFloats(self.presetsList[int(self.preset_values)][1])
+ self.scale_Y = utils.toFloats(self.presetsList[int(self.preset_values)][2])
+ self.scale_Z = utils.toFloats(self.presetsList[int(self.preset_values)][3])
+ self.skew_X = float(self.presetsList[int(self.preset_values)][4])
+ self.skew_Y = float(self.presetsList[int(self.preset_values)][5])
+ self.skew_Z = float(self.presetsList[int(self.preset_values)][6])
+ self.use_scale_dis = bool(self.presetsList[int(self.preset_values)][7])
+ self.scale_fac = utils.toFloats(self.presetsList[int(self.preset_values)][8])
+ self.deform = float(self.presetsList[int(self.preset_values)][9])
+ self.rough = float(self.presetsList[int(self.preset_values)][10])
+ self.detail = int(self.presetsList[int(self.preset_values)][11])
+ self.display_detail = int(self.presetsList[int(self.preset_values)][12])
+ self.smooth_fac = float(self.presetsList[int(self.preset_values)][13])
+ self.smooth_it = int(self.presetsList[int(self.preset_values)][14])
+ self.mat_enable = bool(self.presetsList[int(self.preset_values)][15])
+ self.mat_color = utils.toFloats(self.presetsList[int(self.preset_values)][16])
+ self.mat_bright = float(self.presetsList[int(self.preset_values)][17])
+ self.mat_rough = float(self.presetsList[int(self.preset_values)][18])
+ self.mat_spec = float(self.presetsList[int(self.preset_values)][19])
+ self.mat_hard = int(self.presetsList[int(self.preset_values)][20])
+ self.mat_use_trans = bool(self.presetsList[int(self.preset_values)][21])
+ self.mat_alpha = float(self.presetsList[int(self.preset_values)][22])
+ self.mat_cloudy = float(self.presetsList[int(self.preset_values)][23])
+ self.mat_IOR = float(self.presetsList[int(self.preset_values)][24])
+ self.mat_mossy = float(self.presetsList[int(self.preset_values)][25])
+ self.use_generate = bool(self.presetsList[int(self.preset_values)][26])
+ self.use_random_seed = bool(self.presetsList[int(self.preset_values)][27])
+ self.user_seed = int(self.presetsList[int(self.preset_values)][28])
+ self.lastPreset = int(self.preset_values)
+
+ # todo Add deform, deform_Var, rough, and rough_Var:
+ # *** todo completed 4/23/2011 ***
+ # *** Eliminated "deform_Var" and "rough_Var" so the script is not
+ # as complex to use. May add in again as advanced features. ***
+ if self.use_generate:
+ generateRocks(context,
+ self.scale_X,
+ self.skew_X,
+ self.scale_Y,
+ self.skew_Y,
+ self.scale_Z,
+ self.skew_Z,
+ self.scale_fac,
+ self.detail,
+ self.display_detail,
+ self.deform,
+ self.rough,
+ self.smooth_fac,
+ self.smooth_it,
+ self.mat_enable,
+ self.mat_color,
+ self.mat_bright,
+ self.mat_rough,
+ self.mat_spec,
+ self.mat_hard,
+ self.mat_use_trans,
+ self.mat_alpha,
+ self.mat_cloudy,
+ self.mat_IOR,
+ self.mat_mossy,
+ self.num_of_rocks,
+ self.user_seed,
+ self.use_scale_dis,
+ self.use_random_seed)
+
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/settings.py b/release/scripts/addons_contrib/add_mesh_rocks/settings.py
new file mode 100644
index 0000000..647a62d
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_rocks/settings.py
@@ -0,0 +1,184 @@
+# Paul "BrikBot" Marshall
+# Created: July 1, 2011
+# Last Modified: November 17, 2011
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+# Thanks to Meta-Androco, RickyBlender, Ace Dragon, and PKHG for ideas
+# and testing.
+#
+# Coded in IDLE, tested in Blender 2.59. NumPy Recommended.
+# Search for "@todo" to quickly find sections that need work.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# The Blender Rock Creation tool is for rapid generation of
+# mesh rocks in Blender.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import inspect
+import shutil
+from add_mesh_rocks import utils
+from xml.dom import minidom
+
+basePath = inspect.getfile(inspect.currentframe())[0:-len("settings.py")]
+path = basePath + "add_mesh_rocks.xml"
+
+try:
+ source = minidom.parse(path)
+ print("Rock generator settings file found:\n" + path)
+except:
+ print("Rock generator settings file not found. Creating settings file.")
+ shutil.copy(basePath + "factory.xml", path)
+ source = minidom.parse(path)
+
+xmlDefault = source.getElementsByTagName('default')[0]
+xmlPresets = source.getElementsByTagName('preset')
+default = []
+presets = []
+
+#----- Gets and Sets -----#
+
+
+def getDefault():
+ global default
+ return default
+
+
+def getPresetLists():
+ global presets
+ return presets
+
+
+def getPreset(ID=0):
+ global presets
+ return presets[ID]
+
+#---------- Core ----------#
+
+
+def parse():
+ global xmlDefault
+ global xmlPresets
+ global default
+ global presets
+
+ # Parse default values
+ default = parseNode(xmlDefault)
+
+ # Parse preset values
+ for setting in xmlPresets:
+ presets.append(parseNode(setting))
+
+ return '{FINISHED}'
+
+
+# Takes a node and parses it for data. Relies on that setting.xml has
+# a valid format as specified by the DTD.
+# For some reason minidom places an empty child node for every other node.
+def parseNode(setting, title=True):
+ loc = 1
+
+ if title:
+ # Preset name (xmlPreset.childNodes[1]):
+ title = setting.childNodes[loc].childNodes[0].data
+ loc += 2
+
+ # Preset size values (xmlPreset.childNodes[3]):
+ scaleX = [float(setting.childNodes[loc].childNodes[1].childNodes[3].childNodes[0].data),
+ float(setting.childNodes[loc].childNodes[1].childNodes[5].childNodes[0].data)]
+ scaleY = [float(setting.childNodes[loc].childNodes[3].childNodes[3].childNodes[0].data),
+ float(setting.childNodes[loc].childNodes[3].childNodes[5].childNodes[0].data)]
+ scaleZ = [float(setting.childNodes[loc].childNodes[5].childNodes[3].childNodes[0].data),
+ float(setting.childNodes[loc].childNodes[5].childNodes[5].childNodes[0].data)]
+ skewX = float(setting.childNodes[loc].childNodes[7].childNodes[3].childNodes[0].data)
+ skewY = float(setting.childNodes[loc].childNodes[9].childNodes[3].childNodes[0].data)
+ skewZ = float(setting.childNodes[loc].childNodes[11].childNodes[3].childNodes[0].data)
+ if setting.childNodes[loc].childNodes[13].childNodes[0].data == 'False':
+ use_scale_dis = False
+ else:
+ use_scale_dis = True
+ scale_fac = utils.toList(setting.childNodes[loc].childNodes[15].childNodes[0].data)
+ loc += 2
+
+ # Presst shape values (xmlPreset.childNodes[5]):
+ deform = float(setting.childNodes[loc].childNodes[1].childNodes[0].data)
+ rough = float(setting.childNodes[loc].childNodes[3].childNodes[0].data)
+ detail = int(setting.childNodes[loc].childNodes[5].childNodes[0].data)
+ display_detail = int(setting.childNodes[loc].childNodes[7].childNodes[0].data)
+ smooth_fac = float(setting.childNodes[loc].childNodes[9].childNodes[0].data)
+ smooth_it = int(setting.childNodes[loc].childNodes[11].childNodes[0].data)
+ loc += 2
+
+ # Preset material values (xmlPreset.childNodes[7]):
+ if setting.childNodes[loc].childNodes[1].childNodes[0].data == 'False':
+ mat_enable = False
+ else:
+ mat_enable = True
+ mat_color = utils.toList(setting.childNodes[loc].childNodes[3].childNodes[0].data)
+ mat_bright = float(setting.childNodes[loc].childNodes[5].childNodes[0].data)
+ mat_rough = float(setting.childNodes[loc].childNodes[7].childNodes[0].data)
+ mat_spec = float(setting.childNodes[loc].childNodes[9].childNodes[0].data)
+ mat_hard = int(setting.childNodes[loc].childNodes[11].childNodes[0].data)
+ mat_use_trans = bool(setting.childNodes[loc].childNodes[13].childNodes[0].data)
+ mat_alpha = float(setting.childNodes[loc].childNodes[15].childNodes[0].data)
+ mat_cloudy = float(setting.childNodes[loc].childNodes[17].childNodes[0].data)
+ mat_IOR = float(setting.childNodes[loc].childNodes[19].childNodes[0].data)
+ #mat_use_mirror = float(setting.childNodes[loc].childNodes[21].childNodes[0].data)
+ #mat_mossy = float(setting.childNodes[loc].childNodes[23].childNodes[0].data)
+ #mat_mossy = float(setting.childNodes[loc].childNodes[25].childNodes[0].data)
+ mat_mossy = float(setting.childNodes[loc].childNodes[21].childNodes[0].data)
+ loc += 2
+
+ # Preset random values (xmlPreset.childNodes[9]):
+ if setting.childNodes[loc].childNodes[1].childNodes[0].data == 'True':
+ use_generate = True
+ else:
+ use_generate = False
+ if setting.childNodes[loc].childNodes[3].childNodes[0].data == 'False':
+ use_random_seed = False
+ else:
+ use_random_seed = True
+ user_seed = int(setting.childNodes[loc].childNodes[5].childNodes[0].data)
+
+ if title:
+ parsed = [title, scaleX, scaleY, scaleZ, skewX, skewY, skewZ,
+ use_scale_dis, scale_fac, deform, rough, detail,
+ display_detail, smooth_fac, smooth_it, mat_enable, mat_color,
+ mat_bright, mat_rough, mat_spec, mat_hard, mat_use_trans,
+ mat_alpha, mat_cloudy, mat_IOR, mat_mossy, use_generate,
+ use_random_seed, user_seed]
+ else:
+ parsed = [scaleX, scaleY, scaleZ, skewX, skewY, skewZ, use_scale_dis,
+ scale_fac, deform, rough, detail, display_detail, smooth_fac,
+ smooth_it, mat_enable, mat_color, mat_bright, mat_rough,
+ mat_spec, mat_hard, mat_use_trans, mat_alpha, mat_cloudy,
+ mat_IOR, mat_mossy, use_generate, use_random_seed, user_seed]
+
+ return parsed
+
+
+def save():
+ return '{FINISHED}'
+
+
+def _print():
+ for i in presets:
+ print(i)
+ return '{FINISHED}'
diff --git a/release/scripts/addons_contrib/add_mesh_rocks/utils.py b/release/scripts/addons_contrib/add_mesh_rocks/utils.py
new file mode 100644
index 0000000..94acaf7
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_rocks/utils.py
@@ -0,0 +1,69 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# The Blender Rock Creation tool is for rapid generation of mesh rocks.
+# Copyright (C) 2011 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+
+# Converts a formated string to a float tuple:
+# IN - '(0.5, 0.2)' -> CONVERT -> OUT - (0.5, 0.2)
+def toTuple(stringIn):
+ sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ')
+ fTemp = []
+ for i in sTemp:
+ fTemp.append(float(i))
+ return tuple(fTemp)
+
+
+# Converts a formated string to a float tuple:
+# IN - '[0.5, 0.2]' -> CONVERT -> OUT - [0.5, 0.2]
+def toList(stringIn):
+ sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ')
+ fTemp = []
+ for i in sTemp:
+ fTemp.append(float(i))
+ return fTemp
+
+
+# Converts each item of a list into a float:
+def toFloats(inList):
+ outList = []
+ for i in inList:
+ outList.append(float(i))
+ return outList
+
+
+# Converts each item of a list into an integer:
+def toInts(inList):
+ outList = []
+ for i in inList:
+ outList.append(int(i))
+ return outList
+
+
+# Sets all faces smooth. Done this way since I can't
+# find a simple way without using bpy.ops:
+def smooth(mesh):
+ import bmesh
+ bm = bmesh.new()
+ bm.from_mesh(mesh)
+ for f in bm.faces:
+ f.smooth = True
+ bm.to_mesh(mesh)
+ return mesh
diff --git a/release/scripts/addons_contrib/add_mesh_symmetrical_empty.py b/release/scripts/addons_contrib/add_mesh_symmetrical_empty.py
new file mode 100644
index 0000000..697be49
--- /dev/null
+++ b/release/scripts/addons_contrib/add_mesh_symmetrical_empty.py
@@ -0,0 +1,97 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Add Symmetrical Empty",
+ "author": "Pablo Vazquez",
+ "version": (1,0,2),
+ "blender": (2, 64, 0),
+ "location": "View3D > Add > Mesh > Symmetrical Empty",
+ "description": "Add an empty mesh with a Mirror Modifier for quick symmetrical modeling",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Add_Mesh/Add_Symmetrical_Empty",
+ "tracker_url": "",
+ "category": "Add Mesh"}
+'''
+Adds an empty mesh with a mirror modifier.
+'''
+
+import bpy
+from bpy.props import BoolProperty
+
+def Add_Symmetrical_Empty():
+
+ bpy.ops.mesh.primitive_plane_add(enter_editmode = True)
+
+ sempty = bpy.context.object
+ sempty.name = "SymmEmpty"
+
+ # check if we have a mirror modifier, otherwise add
+ if (sempty.modifiers and sempty.modifiers['Mirror']):
+ pass
+ else:
+ bpy.ops.object.modifier_add(type ='MIRROR')
+
+ # Delete all!
+ bpy.ops.mesh.select_all(action='TOGGLE')
+ bpy.ops.mesh.select_all(action='TOGGLE')
+ bpy.ops.mesh.delete(type ='VERT')
+
+
+class AddSymmetricalEmpty(bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_symmetrical_empty_add"
+ bl_label = "Add Symmetrical Empty Mesh"
+ bl_description = "Add an empty mesh with a Mirror Modifier for quick symmetrical modeling"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def draw(self, context):
+ layout = self.layout
+ mirror = bpy.context.object.modifiers['Mirror']
+
+ layout.prop(mirror,'use_clip', text="Use Clipping")
+
+ layout.label("Mirror Axis")
+ row = layout.row(align=True)
+ row.prop(mirror, "use_x")
+ row.prop(mirror, "use_y")
+ row.prop(mirror, "use_z")
+
+ def execute(self, context):
+ Add_Symmetrical_Empty()
+ return {'FINISHED'}
+
+## menu option ##
+def menu_item(self, context):
+ # only in object mode
+ if bpy.context.mode == "OBJECT":
+ self.layout.operator("mesh.primitive_symmetrical_empty_add",
+ text="Symmetrical Empty", icon="EMPTY_DATA")
+
+## register and add it on top of the list ##
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_mesh_add.prepend(menu_item)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_mesh_add.remove(menu_item)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/add_scene_elements/__init__.py b/release/scripts/addons_contrib/add_scene_elements/__init__.py
new file mode 100644
index 0000000..604b500
--- /dev/null
+++ b/release/scripts/addons_contrib/add_scene_elements/__init__.py
@@ -0,0 +1,102 @@
+# ##### 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 LICENSE BLOCK #####
+# by meta-androcto, parts based on work by Erich Toven #
+
+bl_info = {
+ "name": "Scene Elements",
+ "author": "Meta Androcto, ",
+ "version": (0, 2),
+ "blender": (2, 64, 0),
+ "location": "View3D > Add > Scene Elements",
+ "description": "Add Scenes & Lights, Objects.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6"\
+ "/Py/Scripts",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=32682",
+ "category": "Object"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(scene_camera)
+ imp.reload(scene_lighting)
+ imp.reload(scene_materials)
+ imp.reload(scene_objects)
+ imp.reload(scene_objects_cycles)
+
+else:
+ from . import scene_camera
+ from . import scene_lighting
+ from . import scene_materials
+ from . import scene_objects
+ from . import scene_objects_cycles
+
+import bpy
+
+class INFO_MT_mesh_objects_add(bpy.types.Menu):
+ # Define the "mesh objects" menu
+ bl_idname = "INFO_MT_scene_elements"
+ bl_label = "Scene Elements"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("camera.add_scene",
+ text="Scene_Camera")
+ layout.operator("materials.add_scene",
+ text="Scene_Objects_BI")
+ layout.operator("plane.add_scene",
+ text="Scene_Plane")
+ layout.operator("objects_cycles.add_scene",
+ text="Scene_Objects_Cycles")
+
+class INFO_MT_mesh_lamps_add(bpy.types.Menu):
+ # Define the "mesh objects" menu
+ bl_idname = "INFO_MT_scene_lamps"
+ bl_label = "Lighting Elements"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("object.add_single_spot",
+ text="Add Single Spot")
+ layout.operator("object.add_basic_3point",
+ text="Add 3 Point Spot Setup")
+ layout.operator("object.add_basic_2point",
+ text="Add 2 Point Setup")
+ layout.operator("object.add_area_3point",
+ text="Add 3 Point Setup")
+
+# Register all operators and panels
+# Define "Extras" menu
+def menu_func(self, context):
+ self.layout.menu("INFO_MT_scene_elements", icon="PLUGIN")
+ self.layout.menu("INFO_MT_scene_lamps", icon="PLUGIN")
+def register():
+ bpy.utils.register_module(__name__)
+ # Add "Extras" menu to the "Add Mesh" menu
+ bpy.types.INFO_MT_add.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ # Remove "Extras" menu from the "Add Mesh" menu.
+ bpy.types.INFO_MT_add.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/add_scene_elements/scene_camera.py b/release/scripts/addons_contrib/add_scene_elements/scene_camera.py
new file mode 100644
index 0000000..043bcec
--- /dev/null
+++ b/release/scripts/addons_contrib/add_scene_elements/scene_camera.py
@@ -0,0 +1,89 @@
+'''# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Scene Lighting Presets",
+ "author": "meta-androcto",
+ "version": (0,1),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tool Shelf > Scene Lighting Presets",
+ "description": "Creates Scenes with Lighting presets",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/",
+ "tracker_url": "",
+ "category": "Object"}
+'''
+import bpy, mathutils, math
+from math import pi
+from bpy.props import *
+from mathutils import Vector
+
+class add_scene_camera(bpy.types.Operator):
+ bl_idname = "camera.add_scene"
+ bl_label = "Camera Only"
+ bl_description = "Empty scene with Camera"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+
+# add new scene
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ scene.name = "scene_camera"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("Camera_World")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+ world.light_settings.use_ambient_occlusion = True
+ world.light_settings.ao_factor = 0.25
+# add camera
+ bpy.ops.object.camera_add(location = (7.48113,-6.50764,5.34367), rotation = (1.109319,0.010817,0.814928),)
+ cam = bpy.context.active_object.data
+ cam.lens = 35
+ cam.draw_size = 0.1
+
+ return {"FINISHED"}
+
+#### REGISTER ####
+def add_object_button(self, context):
+ self.layout.menu("INFO_MT_camera.add_scene", icon="PLUGIN")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_add.append(add_object_button)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_add.remove(add_object_button)
+
+
+if __name__ == '__main__':
+ register()
diff --git a/release/scripts/addons_contrib/add_scene_elements/scene_lighting.py b/release/scripts/addons_contrib/add_scene_elements/scene_lighting.py
new file mode 100644
index 0000000..3226477
--- /dev/null
+++ b/release/scripts/addons_contrib/add_scene_elements/scene_lighting.py
@@ -0,0 +1,244 @@
+'''
+bl_info = {
+ "name": "Add 3 Point Lighting Setup",
+ "author": "Erich Toven" meta-androcto
+ "version": (1, 1),
+ "blender": (2, 56, 0),
+ "api": 34765,
+ "location": "View3D > Add",
+ "description": "Adds a new 3 point lighting setup",
+ "warning": "Very Alpha!",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+'''
+import bpy, mathutils, math
+from math import pi
+from bpy.props import FloatVectorProperty
+#from add_utils import AddObjectHelper, add_object_data
+from mathutils import Vector
+
+
+class functions():
+ def addTrackToConstraint(ob, name, target):
+ cns = ob.constraints.new('TRACK_TO')
+ cns.name = name
+ cns.target = target
+ cns.track_axis = 'TRACK_NEGATIVE_Z'
+ cns.up_axis = 'UP_Y'
+ cns.owner_space = 'LOCAL'
+ cns.target_space = 'LOCAL'
+ return
+
+class AddSingleSpot(bpy.types.Operator):
+
+ bl_idname = "object.add_single_spot"
+ bl_label = "Add Single Spot Setup"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ ### Add basic 3 point lighting setup ###
+ bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=(0.000000, 0.000000, 0.000000))
+ empty1 = bpy.context.object
+
+ bpy.ops.object.lamp_add(type='SPOT', view_align=False, location=(0.000000, -10.000000, 10.000000), rotation=(-52.103, 15.548, -169.073))
+ lamp1 = bpy.context.object
+
+ ### Configure Lighting Setup ###
+ lamp1.name = 'Single_Spot1'
+
+ lamp1.data.energy = 4.0
+ lamp1.data.distance = 25.0
+ lamp1.data.spot_size = 1.396264
+ lamp1.data.spot_blend = 1
+ lamp1.data.shadow_method = 'BUFFER_SHADOW'
+ lamp1.data.shadow_buffer_type = 'HALFWAY'
+ lamp1.data.shadow_filter_type = 'GAUSS'
+ lamp1.data.shadow_buffer_soft = 10
+ lamp1.data.shadow_buffer_size = 2048
+ lamp1.data.shadow_buffer_bias = 0.100
+ lamp1.data.shadow_buffer_samples = 8
+ lamp1.data.use_auto_clip_start = True
+ lamp1.data.use_auto_clip_end = True
+
+ functions.addTrackToConstraint(lamp1,'AutoTrack',empty1)
+
+ return {'FINISHED'}
+
+class AddArea3point(bpy.types.Operator):
+ bl_idname = "object.add_area_3point"
+ bl_label = "add 3 Point Area Setup"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Add 3 Point lights to Scene"
+ def execute(self, context):
+ ### Add basic 3 point lighting setup ###
+
+ bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(-12.848104, 18.574114, 7.496113), rotation=(1.537930, 0.711540, 3.687180))
+ lamp1 = bpy.context.object
+
+ bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(-13.168015, -18.672356, 15.276655), rotation=(0.941318, 0.917498, -1.187617))
+ lamp2 = bpy.context.object
+
+ bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(19.430519, -20.502472, 7.496113), rotation=(1.614763, 0.709077, 0.853816))
+ lamp3 = bpy.context.object
+
+
+ ### Configure Lighting Setup ###
+ lamp1.name = 'Point1'
+ lamp2.name = 'Point2'
+ lamp3.name = 'Point3'
+
+ lamp1.data.energy = 0.75
+ lamp1.data.distance = 15.0
+ lamp1.data.shadow_method = 'RAY_SHADOW'
+
+
+ lamp2.data.energy = 0.75
+ lamp2.data.distance = 16.0
+ lamp2.data.shadow_method = 'RAY_SHADOW'
+
+
+ lamp3.data.energy = 0.6
+ lamp3.data.distance = 8.0
+ lamp3.data.shadow_method = 'RAY_SHADOW'
+
+ return {'FINISHED'}
+
+class AddBasic3Point(bpy.types.Operator):
+
+ bl_idname = "object.add_basic_3point"
+ bl_label = "Add 3 Point Spot Setup"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ ### Add basic 3 point lighting setup ###
+ bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=(0.000000, -3.817210, 8.279530), rotation=(0, 0, 0))
+ empty1 = bpy.context.object
+
+ bpy.ops.object.lamp_add(type='SPOT', view_align=False, location=(19.430519, -20.502472, 7.496113), rotation=(1.614763, 0.709077, 0.853816))
+ lamp1 = bpy.context.object
+
+ bpy.ops.object.lamp_add(type='SPOT', view_align=False, location=(-12.848104, 18.574114, 7.496113), rotation=(1.537930, 1.537930, 3.687180))
+ lamp2 = bpy.context.object
+
+ bpy.ops.object.lamp_add(type='SPOT', view_align=False, location=(-13.168015, -18.672356, 15.276655), rotation=(0.941318, 0.917498, -1.187617))
+ lamp3 = bpy.context.object
+
+ ### Configure Lighting Setup ###
+ lamp1.name = 'Spot1'
+ lamp2.name = 'Spot2'
+ lamp3.name = 'Key'
+
+ lamp1.data.energy = 4.0
+ lamp1.data.distance = 25.0
+ lamp1.data.spot_size = 1.396264
+ lamp1.data.spot_blend = 1
+ lamp1.data.shadow_method = 'BUFFER_SHADOW'
+ lamp1.data.shadow_buffer_type = 'HALFWAY'
+ lamp1.data.shadow_filter_type = 'GAUSS'
+ lamp1.data.shadow_buffer_soft = 10
+ lamp1.data.shadow_buffer_size = 2048
+ lamp1.data.shadow_buffer_bias = 0.100
+ lamp1.data.shadow_buffer_samples = 8
+ lamp1.data.use_auto_clip_start = True
+ lamp1.data.use_auto_clip_end = True
+
+
+ lamp2.data.energy = 2.0
+ lamp2.data.distance = 25.0
+ lamp2.data.spot_size = 1.047198
+ lamp2.data.spot_blend = 1
+ lamp2.data.shadow_method = 'BUFFER_SHADOW'
+ lamp2.data.shadow_buffer_type = 'HALFWAY'
+ lamp2.data.shadow_filter_type = 'GAUSS'
+ lamp2.data.shadow_buffer_soft = 5
+ lamp2.data.shadow_buffer_size = 2048
+ lamp2.data.shadow_buffer_bias = 0.100
+ lamp2.data.shadow_buffer_samples = 16
+ lamp2.data.use_auto_clip_start = True
+ lamp2.data.use_auto_clip_end = True
+
+ lamp3.data.energy = 2.0
+ lamp3.data.distance = 30.0
+ lamp3.data.spot_size = 1.570797
+ lamp3.data.spot_blend = 1
+ lamp3.data.shadow_method = 'BUFFER_SHADOW'
+ lamp3.data.shadow_buffer_type = 'HALFWAY'
+ lamp3.data.shadow_filter_type = 'GAUSS'
+ lamp3.data.shadow_buffer_soft = 20
+ lamp3.data.shadow_buffer_size = 2048
+ lamp3.data.shadow_buffer_bias = 1
+ lamp3.data.shadow_buffer_samples = 16
+ lamp3.data.use_auto_clip_start = True
+ lamp3.data.use_auto_clip_end = True
+
+ functions.addTrackToConstraint(lamp3,'AutoTrack',empty1)
+
+ return {'FINISHED'}
+class AddBasic2Point(bpy.types.Operator):
+
+ bl_idname = "object.add_basic_2point"
+ bl_label = "Add 2 Point Setup"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+# add point lamp
+ bpy.ops.object.lamp_add(type="POINT", location = (4.07625,1.00545,5.90386), rotation =(0.650328,0.055217,1.866391))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Point_Right"
+ lamp1.energy = 1.0
+ lamp1.distance = 30.0
+ lamp1.shadow_method = "RAY_SHADOW"
+ lamp1.use_sphere = True
+# add point lamp2
+ bpy.ops.object.lamp_add(type="POINT", location = (-0.57101,-4.24586,5.53674), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Point_Left"
+ lamp2.energy = 1.0
+ lamp2.distance = 30.0
+ lamp2.shadow_method = "RAY_SHADOW"
+
+ return {'FINISHED'}
+
+class INFO_MT_add_3pointsetup(bpy.types.Menu):
+ bl_idname = "INFO_MT_lighting.add"
+ bl_label = "Lighting Setups"
+ bl_description = "Add 3 point light sets to Scene"
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.operator("object.add_single_spot",
+ text="Add Single Spot")
+ layout.operator("object.add_basic_3point",
+ text="Add 3 Point Spot Setup")
+ layout.operator("object.add_basic_2point",
+ text="Add 2 Point Setup")
+ layout.operator("object.add_area_3point",
+ text="Add 3 Point Setup")
+
+#import space_info
+
+
+#### REGISTER ####
+def menu_func(self, context):
+ self.layout.menu("INFO_MT_lighting.add", icon="PLUGIN")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_add.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_add.remove(menu_func)
+
+
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_scene_elements/scene_materials.py b/release/scripts/addons_contrib/add_scene_elements/scene_materials.py
new file mode 100644
index 0000000..81ac8f8
--- /dev/null
+++ b/release/scripts/addons_contrib/add_scene_elements/scene_materials.py
@@ -0,0 +1,250 @@
+'''
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Scene Lighting Presets",
+ "author": "meta-androcto",
+ "version": (0,1),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tool Shelf > Scene Lighting Presets",
+ "description": "Creates Scenes with Lighting presets",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/",
+ "tracker_url": "",
+ "category": "Object"}
+'''
+import bpy, mathutils, math
+from math import pi
+from bpy.props import *
+from mathutils import Vector
+
+class add_scene(bpy.types.Operator):
+ bl_idname = "materials.add_scene"
+ bl_label = "Create test scene"
+ bl_description = "Materials Scene with Objects"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+
+# add new scene
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ scene.name = "scene_materials"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("Materials_World")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+ world.light_settings.use_ambient_occlusion = True
+ world.light_settings.ao_factor = 0.25
+# add camera
+ bpy.ops.object.camera_add(location = (7.48113,-6.50764,5.34367), rotation = (1.109319,0.010817,0.814928))
+ cam = bpy.context.active_object.data
+ cam.lens = 35
+ cam.draw_size = 0.1
+
+# add point lamp
+ bpy.ops.object.lamp_add(type="POINT", location = (4.07625,1.00545,5.90386), rotation =(0.650328,0.055217,1.866391))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Point_Right"
+ lamp1.energy = 1.0
+ lamp1.distance = 30.0
+ lamp1.shadow_method = "RAY_SHADOW"
+ lamp1.use_sphere = True
+# add point lamp2
+ bpy.ops.object.lamp_add(type="POINT", location = (-0.57101,-4.24586,5.53674), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Point_Left"
+ lamp2.energy = 1.0
+ lamp2.distance = 30.0
+# lamp2.shadow_method = "RAY_SHADOW"
+
+# light Rim
+ """
+ # add spot lamp3
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
+ lamp3 = bpy.context.active_object.data
+ lamp3.name = "Rim Light"
+ lamp3.color = (0.194,0.477,1)
+ lamp3.energy = 3
+ lamp3.distance = 1.5
+ lamp3.shadow_buffer_soft = 5
+ lamp3.shadow_buffer_size = 4096
+ lamp3.shadow_buffer_clip_end = 1.5
+ lamp3.spot_blend = 0.5
+ """
+
+# add cube
+ bpy.ops.mesh.primitive_cube_add()
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.mesh.subdivide(number_cuts=2)
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.modifier_add(type='BEVEL')
+ bpy.ops.object.modifier_add(type='SUBSURF')
+ bpy.ops.object.shade_smooth()
+
+
+ cube = bpy.context.active_object
+# add new material
+
+ cubeMaterial = blend_data.materials.new("Cube_Material")
+ bpy.ops.object.material_slot_add()
+ cube.material_slots[0].material = cubeMaterial
+
+
+#Material settings
+# Diffuse
+ cubeMaterial.preview_render_type = "CUBE"
+ cubeMaterial.diffuse_color = (1.000, 0.373, 0.00)
+ cubeMaterial.diffuse_shader = 'OREN_NAYAR'
+ cubeMaterial.diffuse_intensity = 1.0
+ cubeMaterial.roughness = 0.09002
+# Specular
+ cubeMaterial.specular_color = (1.000, 0.800, 0.136)
+ cubeMaterial.specular_shader = "PHONG"
+ cubeMaterial.specular_intensity = 1.0
+ cubeMaterial.specular_hardness = 511.0
+# Shading
+ cubeMaterial.ambient = 1.00
+ cubeMaterial.use_cubic = False
+# Transparency
+ cubeMaterial.use_transparency = False
+ cubeMaterial.alpha = 0
+# Mirror
+ cubeMaterial.raytrace_mirror.use = True
+ cubeMaterial.mirror_color = (1.000, 0.793, 0.0)
+ cubeMaterial.raytrace_mirror.reflect_factor = 0.394
+ cubeMaterial.raytrace_mirror.fresnel = 2.0
+ cubeMaterial.raytrace_mirror.fresnel_factor = 1.641
+ cubeMaterial.raytrace_mirror.fade_to = "FADE_TO_SKY"
+ cubeMaterial.raytrace_mirror.gloss_anisotropic = 1.0
+# Shadow
+ cubeMaterial.use_transparent_shadows = True
+
+# Add a texture
+ cubetex = blend_data.textures.new("CloudTex", type='CLOUDS')
+ cubetex.noise_type = 'SOFT_NOISE'
+ cubetex.noise_scale = 0.25
+ mtex = cubeMaterial.texture_slots.add()
+ mtex.texture = cubetex
+ mtex.texture_coords = 'ORCO'
+ mtex.scale = (0.800, 0.800, 0.800)
+ mtex.use_map_mirror = True
+ mtex.mirror_factor = 0.156
+ mtex.use_map_color_diffuse = True
+ mtex.diffuse_color_factor = 0.156
+ mtex.use_map_normal = True
+ mtex.normal_factor = 0.010
+ mtex.blend_type = "ADD"
+ mtex.use_rgb_to_intensity = True
+ mtex.color = (1.000, 0.207, 0.000)
+#add monkey #
+ bpy.ops.mesh.primitive_monkey_add(location = (-0.32639,0.08901,1.49976))
+ bpy.ops.transform.rotate(value=(1.15019), axis=(0, 0, 1))
+ bpy.ops.transform.rotate(value=(-0.683882), axis=(0, 1, 0))
+ bpy.ops.object.modifier_add(type='SUBSURF')
+ bpy.ops.object.shade_smooth()
+ monkey = bpy.context.active_object
+# add new material
+
+ monkeyMaterial = blend_data.materials.new("Monkey_Material")
+ bpy.ops.object.material_slot_add()
+ monkey.material_slots[0].material = monkeyMaterial
+
+#Material settings
+ monkeyMaterial.preview_render_type = "MONKEY"
+ monkeyMaterial.diffuse_color = (0.239, 0.288, 0.288)
+ monkeyMaterial.specular_color = (0.604, 0.465, 0.136)
+ monkeyMaterial.diffuse_shader = 'LAMBERT'
+ monkeyMaterial.diffuse_intensity = 1.0
+ monkeyMaterial.specular_intensity = 0.3
+ monkeyMaterial.ambient = 0
+ monkeyMaterial.type = 'SURFACE'
+ monkeyMaterial.use_cubic = True
+ monkeyMaterial.use_transparency = False
+ monkeyMaterial.alpha = 0
+ monkeyMaterial.use_transparent_shadows = True
+ monkeyMaterial.raytrace_mirror.use = True
+ monkeyMaterial.raytrace_mirror.reflect_factor = 0.65
+ monkeyMaterial.raytrace_mirror.fade_to = "FADE_TO_MATERIAL"
+# add plane
+
+ bpy.ops.mesh.primitive_plane_add(location = (0.0,0.0,-1.0))
+ bpy.ops.transform.rotate(value=(-0.820305), axis=(0, 0, 1))
+ bpy.ops.transform.resize(value=(22.0, 22.0, 0.0))
+ bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
+
+ plane = bpy.context.active_object
+# add new material
+
+ planeMaterial = blend_data.materials.new("Plane_Material")
+ bpy.ops.object.material_slot_add()
+ plane.material_slots[0].material = planeMaterial
+
+
+#Material settings
+ planeMaterial.preview_render_type = "CUBE"
+ planeMaterial.diffuse_color = (0.2, 0.2, 0.2)
+ planeMaterial.specular_color = (0.604, 0.465, 0.136)
+ planeMaterial.specular_intensity = 0.3
+ planeMaterial.ambient = 0
+ planeMaterial.use_cubic = True
+ planeMaterial.use_transparency = False
+ planeMaterial.alpha = 0
+ planeMaterial.use_transparent_shadows = True
+ return {"FINISHED"}
+
+class INFO_MT_add_scenesetup(bpy.types.Menu):
+ bl_idname = "INFO_MT_materials.add_scene"
+ bl_label = "Materials Scene"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.operator("materials.add_scene",
+ text="Add scene")
+
+#### REGISTER ####
+def menu_func(self, context):
+ self.layout.menu("INFO_MT_materials.add_scene", icon="PLUGIN")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_add.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_add.remove(menu_func)
+
+
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_scene_elements/scene_objects.py b/release/scripts/addons_contrib/add_scene_elements/scene_objects.py
new file mode 100644
index 0000000..d825b84
--- /dev/null
+++ b/release/scripts/addons_contrib/add_scene_elements/scene_objects.py
@@ -0,0 +1,157 @@
+'''
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Scene Lighting Presets",
+ "author": "meta-androcto",
+ "version": (0,1),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tool Shelf > Scene Lighting Presets",
+ "description": "Creates Scenes with Lighting presets",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/",
+ "tracker_url": "",
+ "category": "Object"}
+'''
+import bpy, mathutils, math
+from math import pi
+from bpy.props import *
+from mathutils import Vector
+
+class add_scene(bpy.types.Operator):
+ bl_idname = "plane.add_scene"
+ bl_label = "Create test scene"
+ bl_description = "Scene with 'infinite' plane"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+
+# add new scene
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ scene.name = "scene_plane"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("Plane_World")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+ world.light_settings.use_ambient_occlusion = True
+ world.light_settings.ao_factor = 0.25
+# add camera
+ bpy.ops.object.camera_add(location = (7.48113,-6.50764,5.34367), rotation = (1.109319,0.010817,0.814928))
+ cam = bpy.context.active_object.data
+ cam.lens = 35
+ cam.draw_size = 0.1
+
+# add point lamp
+ bpy.ops.object.lamp_add(type="POINT", location = (4.07625,1.00545,5.90386), rotation =(0.650328,0.055217,1.866391))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Point_Right"
+ lamp1.energy = 1.0
+ lamp1.distance = 30.0
+ lamp1.shadow_method = "RAY_SHADOW"
+ lamp1.use_sphere = True
+# add point lamp2
+ bpy.ops.object.lamp_add(type="POINT", location = (-0.57101,-4.24586,5.53674), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Point_Left"
+ lamp2.energy = 1.0
+ lamp2.distance = 30.0
+# lamp2.shadow_method = "RAY_SHADOW"
+
+# light Rim
+ """
+ # add spot lamp3
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
+ lamp3 = bpy.context.active_object.data
+ lamp3.name = "Rim Light"
+ lamp3.color = (0.194,0.477,1)
+ lamp3.energy = 3
+ lamp3.distance = 1.5
+ lamp3.shadow_buffer_soft = 5
+ lamp3.shadow_buffer_size = 4096
+ lamp3.shadow_buffer_clip_end = 1.5
+ lamp3.spot_blend = 0.5
+ """
+
+# add plane
+
+ bpy.ops.mesh.primitive_plane_add(location = (0.0,0.0,-1.0))
+ bpy.ops.transform.rotate(value=(-0.820305), axis=(0, 0, 1))
+ bpy.ops.transform.resize(value=(22.0, 22.0, 0.0))
+ bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
+
+ plane = bpy.context.active_object
+# add new material
+
+ planeMaterial = blend_data.materials.new("Plane_Material")
+ bpy.ops.object.material_slot_add()
+ plane.material_slots[0].material = planeMaterial
+
+
+#Material settings
+ planeMaterial.preview_render_type = "CUBE"
+ planeMaterial.diffuse_color = (0.2, 0.2, 0.2)
+ planeMaterial.specular_color = (0.604, 0.465, 0.136)
+ planeMaterial.specular_intensity = 0.3
+ planeMaterial.ambient = 0
+ planeMaterial.use_cubic = True
+ planeMaterial.use_transparency = False
+ planeMaterial.alpha = 0
+ planeMaterial.use_transparent_shadows = True
+ return {"FINISHED"}
+
+class INFO_MT_add_scenesetup(bpy.types.Menu):
+ bl_idname = "INFO_MT_plane.add_scene"
+ bl_label = "Lighting Setups"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.operator("planet.add_scene",
+ text="Add scene")
+
+#### REGISTER ####
+def add_object_button(self, context):
+ self.layout.menu("INFO_MT_plane.add_scene", icon="PLUGIN")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_add.append(add_object_button)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_add.remove(add_object_button)
+
+
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/add_scene_elements/scene_objects_cycles.py b/release/scripts/addons_contrib/add_scene_elements/scene_objects_cycles.py
new file mode 100644
index 0000000..0f895ad
--- /dev/null
+++ b/release/scripts/addons_contrib/add_scene_elements/scene_objects_cycles.py
@@ -0,0 +1,261 @@
+'''
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Scene Lighting Presets",
+ "author": "meta-androcto",
+ "version": (0,1),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tool Shelf > Scene Lighting Presets",
+ "description": "Creates Scenes with Lighting presets",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/",
+ "tracker_url": "",
+ "category": "Object"}
+'''
+import bpy, mathutils, math
+from math import pi
+from bpy.props import *
+from mathutils import Vector
+
+class add_scene(bpy.types.Operator):
+ bl_idname = "objects_cycles.add_scene"
+ bl_label = "Create test scene"
+ bl_description = "Cycles Scene with Objects"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+
+# add new scene
+
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ bpy.context.scene.render.engine='CYCLES'
+ scene.name = "scene_object_cycles"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("Cycles_Object_World")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+ world.light_settings.use_ambient_occlusion = True
+ world.light_settings.ao_factor = 0.25
+# add camera
+ bpy.ops.object.camera_add(location = (7.48113,-6.50764,5.34367), rotation = (1.109319,0.010817,0.814928))
+ cam = bpy.context.active_object.data
+ cam.lens = 35
+ cam.draw_size = 0.1
+
+# add point lamp
+ bpy.ops.object.lamp_add(type="POINT", location = (4.07625,1.00545,5.90386), rotation =(0.650328,0.055217,1.866391))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Point_Right"
+ lamp1.energy = 1.0
+ lamp1.distance = 30.0
+ lamp1.shadow_method = "RAY_SHADOW"
+ lamp1.use_sphere = True
+# add point lamp2
+ bpy.ops.object.lamp_add(type="POINT", location = (-0.57101,-4.24586,5.53674), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Point_Left"
+ lamp2.energy = 1.0
+ lamp2.distance = 30.0
+# lamp2.shadow_method = "RAY_SHADOW"
+
+# light Rim
+ """
+ # add spot lamp3
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
+ lamp3 = bpy.context.active_object.data
+ lamp3.name = "Rim Light"
+ lamp3.color = (0.194,0.477,1)
+ lamp3.energy = 3
+ lamp3.distance = 1.5
+ lamp3.shadow_buffer_soft = 5
+ lamp3.shadow_buffer_size = 4096
+ lamp3.shadow_buffer_clip_end = 1.5
+ lamp3.spot_blend = 0.5
+ """
+
+# add cube
+ bpy.ops.mesh.primitive_cube_add()
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.mesh.subdivide(number_cuts=2)
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.modifier_add(type='BEVEL')
+ bpy.ops.object.modifier_add(type='SUBSURF')
+ bpy.ops.object.shade_smooth()
+
+
+ cube = bpy.context.active_object
+# add new material
+
+ cubeMaterial = blend_data.materials.new("Cycles_Cube_Material")
+ bpy.ops.object.material_slot_add()
+ cube.material_slots[0].material = cubeMaterial
+
+
+#Material settings
+# Diffuse
+ cubeMaterial.preview_render_type = "CUBE"
+ cubeMaterial.diffuse_color = (1.000, 0.373, 0.00)
+ cubeMaterial.diffuse_shader = 'OREN_NAYAR'
+ cubeMaterial.diffuse_intensity = 1.0
+ cubeMaterial.roughness = 0.09002
+# Specular
+ cubeMaterial.specular_color = (1.000, 0.800, 0.136)
+ cubeMaterial.specular_shader = "PHONG"
+ cubeMaterial.specular_intensity = 1.0
+ cubeMaterial.specular_hardness = 511.0
+# Shading
+ cubeMaterial.ambient = 1.00
+ cubeMaterial.use_cubic = False
+# Transparency
+ cubeMaterial.use_transparency = False
+ cubeMaterial.alpha = 0
+# Mirror
+ cubeMaterial.raytrace_mirror.use = True
+ cubeMaterial.mirror_color = (1.000, 0.793, 0.0)
+ cubeMaterial.raytrace_mirror.reflect_factor = 0.394
+ cubeMaterial.raytrace_mirror.fresnel = 2.0
+ cubeMaterial.raytrace_mirror.fresnel_factor = 1.641
+ cubeMaterial.raytrace_mirror.fade_to = "FADE_TO_SKY"
+ cubeMaterial.raytrace_mirror.gloss_anisotropic = 1.0
+# Shadow
+ cubeMaterial.use_transparent_shadows = True
+## Cycles ##
+
+ cubeMaterial.use_nodes = True
+
+# Add a texture
+ cubetex = blend_data.textures.new("CloudTex", type='CLOUDS')
+ cubetex.noise_type = 'SOFT_NOISE'
+ cubetex.noise_scale = 0.25
+ mtex = cubeMaterial.texture_slots.add()
+ mtex.texture = cubetex
+ mtex.texture_coords = 'ORCO'
+ mtex.scale = (0.800, 0.800, 0.800)
+ mtex.use_map_mirror = True
+ mtex.mirror_factor = 0.156
+ mtex.use_map_color_diffuse = True
+ mtex.diffuse_color_factor = 0.156
+ mtex.use_map_normal = True
+ mtex.normal_factor = 0.010
+ mtex.blend_type = "ADD"
+ mtex.use_rgb_to_intensity = True
+ mtex.color = (1.000, 0.207, 0.000)
+#add monkey #
+ bpy.ops.mesh.primitive_monkey_add(location = (-0.32639,0.08901,1.49976))
+ bpy.ops.transform.rotate(value=(1.15019), axis=(0, 0, 1))
+ bpy.ops.transform.rotate(value=(-0.683882), axis=(0, 1, 0))
+ bpy.ops.object.modifier_add(type='SUBSURF')
+ bpy.ops.object.shade_smooth()
+ monkey = bpy.context.active_object
+# add new material
+
+ monkeyMaterial = blend_data.materials.new("Cycles_Monkey_Material")
+ bpy.ops.object.material_slot_add()
+ monkey.material_slots[0].material = monkeyMaterial
+
+#Material settings
+ monkeyMaterial.preview_render_type = "MONKEY"
+ monkeyMaterial.diffuse_color = (0.239, 0.288, 0.288)
+ monkeyMaterial.specular_color = (0.604, 0.465, 0.136)
+ monkeyMaterial.diffuse_shader = 'LAMBERT'
+ monkeyMaterial.diffuse_intensity = 1.0
+ monkeyMaterial.specular_intensity = 0.3
+ monkeyMaterial.ambient = 0
+ monkeyMaterial.type = 'SURFACE'
+ monkeyMaterial.use_cubic = True
+ monkeyMaterial.use_transparency = False
+ monkeyMaterial.alpha = 0
+ monkeyMaterial.use_transparent_shadows = True
+ monkeyMaterial.raytrace_mirror.use = True
+ monkeyMaterial.raytrace_mirror.reflect_factor = 0.65
+ monkeyMaterial.raytrace_mirror.fade_to = "FADE_TO_MATERIAL"
+ monkeyMaterial.use_nodes=True
+# add plane
+
+ bpy.ops.mesh.primitive_plane_add(location = (0.0,0.0,-1.0))
+ bpy.ops.transform.rotate(value=(-0.820305), axis=(0, 0, 1))
+ bpy.ops.transform.resize(value=(22.0, 22.0, 0.0))
+ bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
+
+ plane = bpy.context.active_object
+# add new material
+
+ planeMaterial = blend_data.materials.new("Cycles_Plane_Material")
+ bpy.ops.object.material_slot_add()
+ plane.material_slots[0].material = planeMaterial
+
+
+#Material settings
+ planeMaterial.preview_render_type = "CUBE"
+ planeMaterial.diffuse_color = (0.2, 0.2, 0.2)
+ planeMaterial.specular_color = (0.604, 0.465, 0.136)
+ planeMaterial.specular_intensity = 0.3
+ planeMaterial.ambient = 0
+ planeMaterial.use_cubic = True
+ planeMaterial.use_transparency = False
+ planeMaterial.alpha = 0
+ planeMaterial.use_transparent_shadows = True
+ mats = bpy.data.materials
+ sc = bpy.context.scene
+ planeMaterial.use_nodes=True
+ TreeNodes=planeMaterial.node_tree
+ links = TreeNodes.links
+ shader = TreeNodes.nodes.new('BSDF_GLOSSY')
+ return {'FINISHED'}
+class INFO_MT_add_scenesetup(bpy.types.Menu):
+ bl_idname = "INFO_MT_objects_cycles.add_scene"
+ bl_label = "Lighting Setups"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.operator("light.add_scene",
+ text="Add scene")
+
+#### REGISTER ####
+def menu_func(self, context):
+ self.layout.menu("INFO_MT_objects_cycles.add_scene", icon="PLUGIN")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_add.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_add.remove(menu_func)
+
+
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/anim_selection_sets.py b/release/scripts/addons_contrib/anim_selection_sets.py
new file mode 100644
index 0000000..5b87add
--- /dev/null
+++ b/release/scripts/addons_contrib/anim_selection_sets.py
@@ -0,0 +1,353 @@
+ # ***** 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, see <http://www.gnu.org/licenses/>
+ # and write to the Free Software Foundation, Inc., 51 Franklin Street,
+ # Fifth Floor, Boston, MA 02110-1301, USA..
+ #
+ # The Original Code is Copyright (C) 2012 Blender Foundation ###
+ # All rights reserved.
+ #
+ #
+ # The Original Code is: all of this file.
+ #
+ # Contributor(s): Dan Eicher.
+ #
+ # ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+import string
+import bpy
+
+bl_info = {
+ "name": "Selection Set",
+ "author": "Dan Eicher",
+ "version": (0, 1, 0),
+ "blender": (2, 63, 0),
+ "location": "Properties -> Object Data -> Selection Sets",
+ "description": "Selection Sets to select groups of bones",
+ "warning": "Proxy armatures need to export sets and run generated script on re-opening file",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Animation/SelectionSets",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=31492",
+ "category": "Animation"
+}
+
+
+script_template = '''# generated by ANIM_OT_selection_set_export -- abandon all hope, ye who hand edit!
+
+import bpy
+
+def selection_set_import():
+ arm = bpy.data.armatures['${name}']
+
+ set_list = [${set_list}
+ ]
+
+ for name, bones in set_list:
+ if arm.selection_sets.find(name) == -1:
+ sel_set = arm.selection_sets.add()
+ sel_set.name = name
+
+ for bone in bones:
+ set_bone = sel_set.bones.add()
+ set_bone.name = bone
+
+
+if __name__ == "__main__":
+ selection_set_import()
+'''
+
+
+def generic_poll(context):
+ return (context.mode == 'POSE' and context.object and context.object.type == 'ARMATURE')
+
+
+def active_selection_set_update_func(self, context):
+ idx = self.active_selection_set
+ if idx < -1 or idx >= len(self.selection_sets):
+ self.active_selection_set = -1
+ raise IndexError('Armature.active_selection_set: out of range')
+
+
+class SelectionSetBone(bpy.types.PropertyGroup):
+ name = bpy.props.StringProperty()
+
+
+class SelectionSet(bpy.types.PropertyGroup):
+ name = bpy.props.StringProperty(options={'LIBRARY_EDITABLE'})
+ bones = bpy.props.CollectionProperty(type=SelectionSetBone)
+
+
+class ANIM_OT_selection_set_add(bpy.types.Operator):
+ """Add a new selection set"""
+ bl_idname = "anim.selection_set_add"
+ bl_label = "Selection Set Add"
+
+ @classmethod
+ def poll(cls, context):
+ return generic_poll(context)
+
+ def execute(self, context):
+ arm = context.active_object.data
+
+ tmp_name = name = 'Set'
+ name_sub = 1
+ while arm.selection_sets.find(name) != -1:
+ name = tmp_name + ' ' + str(name_sub)
+ name_sub += 1
+
+ sel_set = arm.selection_sets.add()
+ sel_set.name = name
+
+ arm.active_selection_set = arm.selection_sets.find(name)
+
+ return {'FINISHED'}
+
+
+class ANIM_OT_selection_set_remove(bpy.types.Operator):
+ """Remove the active selection set"""
+ bl_idname = "anim.selection_set_remove"
+ bl_label = "Selection Set Remove"
+
+ @classmethod
+ def poll(cls, context):
+ arm = context.active_object.data
+ return (generic_poll(context) and arm.active_selection_set != -1)
+
+ def execute(self, context):
+ arm = context.active_object.data
+ active_index = arm.active_selection_set
+
+ arm.selection_sets.remove(active_index)
+
+ if active_index >= len(arm.selection_sets):
+ arm.active_selection_set = len(arm.selection_sets) - 1
+
+ return {'FINISHED'}
+
+
+class ANIM_OT_selection_set_assign(bpy.types.Operator):
+ """Add selected bones to the active selection set"""
+ bl_idname = "anim.selection_set_assign"
+ bl_label = "Selection Set Assign"
+
+ @classmethod
+ def poll(cls, context):
+ arm = context.active_object.data
+ return (generic_poll(context) and arm.active_selection_set != -1)
+
+ def execute(self, context):
+ arm = context.active_object.data
+ sel_set = arm.selection_sets[arm.active_selection_set]
+ bones = [bone for bone in arm.bones if bone.select]
+
+ for bone in bones:
+ if sel_set.bones.find(bone.name) == -1:
+ set_bone = sel_set.bones.add()
+ set_bone.name = bone.name
+
+ return {'FINISHED'}
+
+
+class ANIM_OT_selection_set_unassign(bpy.types.Operator):
+ """Remove selected bones from the active selection set"""
+ bl_idname = "anim.selection_set_unassign"
+ bl_label = "Selection Set Unassign"
+
+ @classmethod
+ def poll(cls, context):
+ arm = context.active_object.data
+ return (generic_poll(context) and arm.active_selection_set != -1)
+
+ def execute(self, context):
+ arm = context.active_object.data
+ sel_set = arm.selection_sets[arm.active_selection_set]
+ bones = [bone for bone in arm.bones if bone.select]
+
+ for bone in bones:
+ bone_index = sel_set.bones.find(bone.name)
+ if bone_index != -1:
+ sel_set.bones.remove(bone_index)
+
+ return {'FINISHED'}
+
+
+class ANIM_OT_selection_set_select(bpy.types.Operator):
+ """Select bones in selection set"""
+ bl_idname = "anim.selection_set_select"
+ bl_label = "Selection Set Select Bones"
+
+ @classmethod
+ def poll(cls, context):
+ arm = context.active_object.data
+ return (generic_poll(context) and arm.active_selection_set != -1)
+
+ def execute(self, context):
+ arm = context.active_object.data
+ sel_set = arm.selection_sets[arm.active_selection_set]
+
+ for bone in sel_set.bones:
+ try:
+ arm.bones[bone.name].select = True
+ except:
+ bone_index = sel_set.bones.find(bone.name)
+ sel_set.bones.remove(bone_index)
+
+ return {'FINISHED'}
+
+
+class ANIM_OT_selection_set_deselect(bpy.types.Operator):
+ """Deselect bones in selection set"""
+ bl_idname = "anim.selection_set_deselect"
+ bl_label = "Selection Set Deselect Bones"
+
+ @classmethod
+ def poll(cls, context):
+ arm = context.active_object.data
+ return (generic_poll(context) and arm.active_selection_set != -1)
+
+ def execute(self, context):
+ arm = context.active_object.data
+ sel_set = arm.selection_sets[arm.active_selection_set]
+
+ for bone in sel_set.bones:
+ try:
+ arm.bones[bone.name].select = False
+ except:
+ bone_index = sel_set.bones.find(bone.name)
+ sel_set.bones.remove(bone_index)
+
+ return {'FINISHED'}
+
+
+class ANIM_OT_selection_set_export(bpy.types.Operator):
+ """Export selection set data to a python script"""
+ bl_idname = "anim.selection_set_export"
+ bl_label = "Selection Set Export"
+
+ @classmethod
+ def poll(cls, context):
+ return generic_poll(context)
+
+ def execute(self, context):
+ arm = context.active_object.data
+ set_script = string.Template(script_template)
+ set_list = ""
+
+ for sel_set in arm.selection_sets:
+ set_bones = ""
+ for bone in sel_set.bones:
+ set_bones += "'" + bone.name + "',"
+ set_list += "\n ('{name}', [{bones}]),".format(name=sel_set.name, bones=set_bones)
+
+ try:
+ script_file = bpy.data.texts['{arm.name}SelectionSetImport.py'.format(arm=arm)]
+ except:
+ script_file = bpy.data.texts.new('{arm.name}SelectionSetImport.py'.format(arm=arm))
+
+ script_file.clear()
+ script_file.write(set_script.substitute(name=arm.name, set_list=set_list))
+
+ return {'FINISHED'}
+
+
+class DATA_PT_bone_sets(bpy.types.Panel):
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "data"
+ bl_label = "Selection Sets"
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type == 'ARMATURE' and context.object.pose)
+
+ def draw(self, context):
+ layout = self.layout
+ ob = context.object
+ arm = ob.data
+ sel_set = None
+
+ if arm.active_selection_set != -1:
+ try:
+ sel_set = arm.selection_sets[arm.active_selection_set]
+ except:
+ pass
+
+ row = layout.row()
+
+ row.template_list(arm, "selection_sets", arm, "active_selection_set",
+ rows=(5 if len(arm.selection_sets) else 2))
+
+ col = row.column(align=True)
+ col.operator("anim.selection_set_add", icon='ZOOMIN', text="")
+ col.operator("anim.selection_set_remove", icon='ZOOMOUT', text="")
+
+ if sel_set:
+ col = layout.column()
+ col.prop(sel_set, "name", text="Name")
+
+ row = layout.row()
+
+ sub = row.row(align=True)
+ sub.operator("anim.selection_set_assign", text="Assign")
+ sub.operator("anim.selection_set_unassign", text="Remove")
+
+ sub = row.row(align=True)
+ sub.operator("anim.selection_set_select", text="Select")
+ sub.operator("anim.selection_set_deselect", text="Deselect")
+
+ row = layout.row()
+ row.operator("anim.selection_set_export", text="Export Selection Sets")
+
+
+def register():
+ bpy.utils.register_class(SelectionSetBone)
+ bpy.utils.register_class(SelectionSet)
+ bpy.utils.register_class(ANIM_OT_selection_set_add)
+ bpy.utils.register_class(ANIM_OT_selection_set_remove)
+ bpy.utils.register_class(ANIM_OT_selection_set_assign)
+ bpy.utils.register_class(ANIM_OT_selection_set_unassign)
+ bpy.utils.register_class(ANIM_OT_selection_set_select)
+ bpy.utils.register_class(ANIM_OT_selection_set_deselect)
+ bpy.utils.register_class(ANIM_OT_selection_set_export)
+ bpy.utils.register_class(DATA_PT_bone_sets)
+
+ bpy.types.Armature.selection_sets = bpy.props.CollectionProperty(type=SelectionSet,
+ name="Selection Sets",
+ description="Collection of bones to be selected")
+
+ bpy.types.Armature.active_selection_set = bpy.props.IntProperty(name="Active Selection Set",
+ default=-1,
+ options={'LIBRARY_EDITABLE'},
+ update=active_selection_set_update_func)
+
+
+def unregister():
+ del bpy.types.Armature.selection_sets
+ del bpy.types.Armature.active_selection_set
+
+ bpy.utils.unregister_class(SelectionSet)
+ bpy.utils.unregister_class(SelectionSetBone)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_add)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_remove)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_assign)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_unassign)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_select)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_deselect)
+ bpy.utils.unregister_class(ANIM_OT_selection_set_export)
+ bpy.utils.unregister_class(DATA_PT_bone_sets)
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/animation_motion_trail.py b/release/scripts/addons_contrib/animation_motion_trail.py
new file mode 100644
index 0000000..af38480
--- /dev/null
+++ b/release/scripts/addons_contrib/animation_motion_trail.py
@@ -0,0 +1,1740 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+
+bl_info = {
+ "name": "Motion Trail",
+ "author": "Bart Crouch",
+ "version": (3, 1, 1),
+ "blender": (2, 61, 0),
+ "location": "View3D > Toolbar > Motion Trail tab",
+ "warning": "",
+ "description": "Display and edit motion trails in the 3d-view",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/"
+ "Py/Scripts/Animation/Motion_Trail",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=26374",
+ "category": "Animation"}
+
+
+import bgl
+import blf
+import bpy
+from bpy_extras import view3d_utils
+import math
+import mathutils
+
+
+# fake fcurve class, used if no fcurve is found for a path
+class fake_fcurve():
+ def __init__(self, object, index, rotation=False, scale=False):
+ # location
+ if not rotation and not scale:
+ self.loc = object.location[index]
+ # scale
+ elif scale:
+ self.loc = object.scale[index]
+ # rotation
+ elif rotation == 'QUATERNION':
+ self.loc = object.rotation_quaternion[index]
+ elif rotation == 'AXIS_ANGLE':
+ self.loc = object.rotation_axis_angle[index]
+ else:
+ self.loc = object.rotation_euler[index]
+ self.keyframe_points = []
+
+ def evaluate(self, frame):
+ return(self.loc)
+
+ def range(self):
+ return([])
+
+
+# get location curves of the given object
+def get_curves(object, child=False):
+ if object.animation_data and object.animation_data.action:
+ action = object.animation_data.action
+ if child:
+ # posebone
+ curves = [fc for fc in action.fcurves if len(fc.data_path)>=14 \
+ and fc.data_path[-9:]=='.location' and \
+ child.name in fc.data_path.split("\"")]
+ else:
+ # normal object
+ curves = [fc for fc in action.fcurves if \
+ fc.data_path == 'location']
+ elif object.animation_data and object.animation_data.use_nla:
+ curves = []
+ strips = []
+ for track in object.animation_data.nla_tracks:
+ not_handled = [s for s in track.strips]
+ while not_handled:
+ current_strip = not_handled.pop(-1)
+ if current_strip.action:
+ strips.append(current_strip)
+ if current_strip.strips:
+ # meta strip
+ not_handled += [s for s in current_strip.strips]
+
+ for strip in strips:
+ if child:
+ # posebone
+ curves = [fc for fc in strip.action.fcurves if \
+ len(fc.data_path)>=14 and fc.data_path[-9:]=='.location' \
+ and child.name in fc.data_path.split("\"")]
+ else:
+ # normal object
+ curves = [fc for fc in strip.action.fcurves if \
+ fc.data_path == 'location']
+ if curves:
+ # use first strip with location fcurves
+ break
+ else:
+ # should not happen?
+ curves = []
+
+ # ensure we have three curves per object
+ fcx = None
+ fcy = None
+ fcz = None
+ for fc in curves:
+ if fc.array_index == 0:
+ fcx = fc
+ elif fc.array_index == 1:
+ fcy = fc
+ elif fc.array_index == 2:
+ fcz = fc
+ if fcx == None:
+ fcx = fake_fcurve(object, 0)
+ if fcy == None:
+ fcy = fake_fcurve(object, 1)
+ if fcz == None:
+ fcz = fake_fcurve(object, 2)
+
+ return([fcx, fcy, fcz])
+
+
+# turn screen coordinates (x,y) into world coordinates vector
+def screen_to_world(context, x, y):
+ depth_vector = view3d_utils.region_2d_to_vector_3d(\
+ context.region, context.region_data, [x,y])
+ vector = view3d_utils.region_2d_to_location_3d(\
+ context.region, context.region_data, [x,y], depth_vector)
+
+ return(vector)
+
+
+# turn 3d world coordinates vector into screen coordinate integers (x,y)
+def world_to_screen(context, vector):
+ prj = context.region_data.perspective_matrix * \
+ mathutils.Vector((vector[0], vector[1], vector[2], 1.0))
+ width_half = context.region.width / 2.0
+ height_half = context.region.height / 2.0
+
+ x = int(width_half + width_half * (prj.x / prj.w))
+ y = int(height_half + height_half * (prj.y / prj.w))
+
+ # correction for corner cases in perspective mode
+ if prj.w < 0:
+ if x < 0:
+ x = context.region.width * 2
+ else:
+ x = context.region.width * -2
+ if y < 0:
+ y = context.region.height * 2
+ else:
+ y = context.region.height * -2
+
+ return(x, y)
+
+
+# calculate location of display_ob in worldspace
+def get_location(frame, display_ob, offset_ob, curves):
+ if offset_ob:
+ bpy.context.scene.frame_set(frame)
+ display_mat = getattr(display_ob, "matrix", False)
+ if not display_mat:
+ # posebones have "matrix", objects have "matrix_world"
+ display_mat = display_ob.matrix_world
+ if offset_ob:
+ loc = display_mat.to_translation() + \
+ offset_ob.matrix_world.to_translation()
+ else:
+ loc = display_mat.to_translation()
+ else:
+ fcx, fcy, fcz = curves
+ locx = fcx.evaluate(frame)
+ locy = fcy.evaluate(frame)
+ locz = fcz.evaluate(frame)
+ loc = mathutils.Vector([locx, locy, locz])
+
+ return(loc)
+
+
+# get position of keyframes and handles at the start of dragging
+def get_original_animation_data(context, keyframes):
+ keyframes_ori = {}
+ handles_ori = {}
+
+ if context.active_object and context.active_object.mode == 'POSE':
+ armature_ob = context.active_object
+ objects = [[armature_ob, pb, armature_ob] for pb in \
+ context.selected_pose_bones]
+ else:
+ objects = [[ob, False, False] for ob in context.selected_objects]
+
+ for action_ob, child, offset_ob in objects:
+ if not action_ob.animation_data:
+ continue
+ curves = get_curves(action_ob, child)
+ if len(curves) == 0:
+ continue
+ fcx, fcy, fcz = curves
+ if child:
+ display_ob = child
+ else:
+ display_ob = action_ob
+
+ # get keyframe positions
+ frame_old = context.scene.frame_current
+ keyframes_ori[display_ob.name] = {}
+ for frame in keyframes[display_ob.name]:
+ loc = get_location(frame, display_ob, offset_ob, curves)
+ keyframes_ori[display_ob.name][frame] = [frame, loc]
+
+ # get handle positions
+ handles_ori[display_ob.name] = {}
+ for frame in keyframes[display_ob.name]:
+ handles_ori[display_ob.name][frame] = {}
+ left_x = [frame, fcx.evaluate(frame)]
+ right_x = [frame, fcx.evaluate(frame)]
+ for kf in fcx.keyframe_points:
+ if kf.co[0] == frame:
+ left_x = kf.handle_left[:]
+ right_x = kf.handle_right[:]
+ break
+ left_y = [frame, fcy.evaluate(frame)]
+ right_y = [frame, fcy.evaluate(frame)]
+ for kf in fcy.keyframe_points:
+ if kf.co[0] == frame:
+ left_y = kf.handle_left[:]
+ right_y = kf.handle_right[:]
+ break
+ left_z = [frame, fcz.evaluate(frame)]
+ right_z = [frame, fcz.evaluate(frame)]
+ for kf in fcz.keyframe_points:
+ if kf.co[0] == frame:
+ left_z = kf.handle_left[:]
+ right_z = kf.handle_right[:]
+ break
+ handles_ori[display_ob.name][frame]["left"] = [left_x, left_y,
+ left_z]
+ handles_ori[display_ob.name][frame]["right"] = [right_x, right_y,
+ right_z]
+
+ if context.scene.frame_current != frame_old:
+ context.scene.frame_set(frame_old)
+
+ return(keyframes_ori, handles_ori)
+
+
+# callback function that calculates positions of all things that need be drawn
+def calc_callback(self, context):
+ if context.active_object and context.active_object.mode == 'POSE':
+ armature_ob = context.active_object
+ objects = [[armature_ob, pb, armature_ob] for pb in \
+ context.selected_pose_bones]
+ else:
+ objects = [[ob, False, False] for ob in context.selected_objects]
+ if objects == self.displayed:
+ selection_change = False
+ else:
+ selection_change = True
+
+ if self.lock and not selection_change and \
+ context.region_data.perspective_matrix == self.perspective and not \
+ context.window_manager.motion_trail.force_update:
+ return
+
+ # dictionaries with key: objectname
+ self.paths = {} # value: list of lists with x, y, color
+ self.keyframes = {} # value: dict with frame as key and [x,y] as value
+ self.handles = {} # value: dict of dicts
+ self.timebeads = {} # value: dict with frame as key and [x,y] as value
+ self.click = {} # value: list of lists with frame, type, loc-vector
+ if selection_change:
+ # value: editbone inverted rotation matrix or None
+ self.edit_bones = {}
+ if selection_change or not self.lock or context.window_manager.\
+ motion_trail.force_update:
+ # contains locations of path, keyframes and timebeads
+ self.cached = {"path":{}, "keyframes":{}, "timebeads_timing":{},
+ "timebeads_speed":{}}
+ if self.cached["path"]:
+ use_cache = True
+ else:
+ use_cache = False
+ self.perspective = context.region_data.perspective_matrix.copy()
+ self.displayed = objects # store, so it can be checked next time
+ context.window_manager.motion_trail.force_update = False
+
+ global_undo = context.user_preferences.edit.use_global_undo
+ context.user_preferences.edit.use_global_undo = False
+
+ for action_ob, child, offset_ob in objects:
+ if selection_change:
+ if not child:
+ self.edit_bones[action_ob.name] = None
+ else:
+ bpy.ops.object.mode_set(mode='EDIT')
+ editbones = action_ob.data.edit_bones
+ mat = editbones[child.name].matrix.copy().to_3x3().inverted()
+ bpy.ops.object.mode_set(mode='POSE')
+ self.edit_bones[child.name] = mat
+
+ if not action_ob.animation_data:
+ continue
+ curves = get_curves(action_ob, child)
+ if len(curves) == 0:
+ continue
+
+ if context.window_manager.motion_trail.path_before == 0:
+ range_min = context.scene.frame_start
+ else:
+ range_min = max(context.scene.frame_start,
+ context.scene.frame_current - \
+ context.window_manager.motion_trail.path_before)
+ if context.window_manager.motion_trail.path_after == 0:
+ range_max = context.scene.frame_end
+ else:
+ range_max = min(context.scene.frame_end,
+ context.scene.frame_current + \
+ context.window_manager.motion_trail.path_after)
+ fcx, fcy, fcz = curves
+ if child:
+ display_ob = child
+ else:
+ display_ob = action_ob
+
+ # get location data of motion path
+ path = []
+ speeds = []
+ frame_old = context.scene.frame_current
+ step = 11 - context.window_manager.motion_trail.path_resolution
+
+ if not use_cache:
+ if display_ob.name not in self.cached["path"]:
+ self.cached["path"][display_ob.name] = {}
+ if use_cache and range_min-1 in self.cached["path"][display_ob.name]:
+ prev_loc = self.cached["path"][display_ob.name][range_min-1]
+ else:
+ prev_loc = get_location(range_min-1, display_ob, offset_ob, curves)
+ self.cached["path"][display_ob.name][range_min-1] = prev_loc
+
+ for frame in range(range_min, range_max + 1, step):
+ if use_cache and frame in self.cached["path"][display_ob.name]:
+ loc = self.cached["path"][display_ob.name][frame]
+ else:
+ loc = get_location(frame, display_ob, offset_ob, curves)
+ self.cached["path"][display_ob.name][frame] = loc
+ if not context.region or not context.space_data:
+ continue
+ x, y = world_to_screen(context, loc)
+ if context.window_manager.motion_trail.path_style == 'simple':
+ path.append([x, y, [0.0, 0.0, 0.0], frame, action_ob, child])
+ else:
+ dloc = (loc - prev_loc).length
+ path.append([x, y, dloc, frame, action_ob, child])
+ speeds.append(dloc)
+ prev_loc = loc
+
+ # calculate color of path
+ if context.window_manager.motion_trail.path_style == 'speed':
+ speeds.sort()
+ min_speed = speeds[0]
+ d_speed = speeds[-1] - min_speed
+ for i, [x, y, d_loc, frame, action_ob, child] in enumerate(path):
+ relative_speed = (d_loc - min_speed) / d_speed # 0.0 to 1.0
+ red = min(1.0, 2.0 * relative_speed)
+ blue = min(1.0, 2.0 - (2.0 * relative_speed))
+ path[i][2] = [red, 0.0, blue]
+ elif context.window_manager.motion_trail.path_style == 'acceleration':
+ accelerations = []
+ prev_speed = 0.0
+ for i, [x, y, d_loc, frame, action_ob, child] in enumerate(path):
+ accel = d_loc - prev_speed
+ accelerations.append(accel)
+ path[i][2] = accel
+ prev_speed = d_loc
+ accelerations.sort()
+ min_accel = accelerations[0]
+ max_accel = accelerations[-1]
+ for i, [x, y, accel, frame, action_ob, child] in enumerate(path):
+ if accel < 0:
+ relative_accel = accel / min_accel # values from 0.0 to 1.0
+ green = 1.0 - relative_accel
+ path[i][2] = [1.0, green, 0.0]
+ elif accel > 0:
+ relative_accel = accel / max_accel # values from 0.0 to 1.0
+ red = 1.0 - relative_accel
+ path[i][2] = [red, 1.0, 0.0]
+ else:
+ path[i][2] = [1.0, 1.0, 0.0]
+ self.paths[display_ob.name] = path
+
+ # get keyframes and handles
+ keyframes = {}
+ handle_difs = {}
+ kf_time = []
+ click = []
+ if not use_cache:
+ if display_ob.name not in self.cached["keyframes"]:
+ self.cached["keyframes"][display_ob.name] = {}
+
+ for fc in curves:
+ for kf in fc.keyframe_points:
+ # handles for location mode
+ if context.window_manager.motion_trail.mode == 'location':
+ if kf.co[0] not in handle_difs:
+ handle_difs[kf.co[0]] = {"left":mathutils.Vector(),
+ "right":mathutils.Vector(), "keyframe_loc":None}
+ handle_difs[kf.co[0]]["left"][fc.array_index] = \
+ (mathutils.Vector(kf.handle_left[:]) - \
+ mathutils.Vector(kf.co[:])).normalized()[1]
+ handle_difs[kf.co[0]]["right"][fc.array_index] = \
+ (mathutils.Vector(kf.handle_right[:]) - \
+ mathutils.Vector(kf.co[:])).normalized()[1]
+ # keyframes
+ if kf.co[0] in kf_time:
+ continue
+ kf_time.append(kf.co[0])
+ co = kf.co[0]
+
+ if use_cache and co in \
+ self.cached["keyframes"][display_ob.name]:
+ loc = self.cached["keyframes"][display_ob.name][co]
+ else:
+ loc = get_location(co, display_ob, offset_ob, curves)
+ self.cached["keyframes"][display_ob.name][co] = loc
+ if handle_difs:
+ handle_difs[co]["keyframe_loc"] = loc
+
+ x, y = world_to_screen(context, loc)
+ keyframes[kf.co[0]] = [x, y]
+ if context.window_manager.motion_trail.mode != 'speed':
+ # can't select keyframes in speed mode
+ click.append([kf.co[0], "keyframe",
+ mathutils.Vector([x,y]), action_ob, child])
+ self.keyframes[display_ob.name] = keyframes
+
+ # handles are only shown in location-altering mode
+ if context.window_manager.motion_trail.mode == 'location' and \
+ context.window_manager.motion_trail.handle_display:
+ # calculate handle positions
+ handles = {}
+ for frame, vecs in handle_difs.items():
+ if child:
+ # bone space to world space
+ mat = self.edit_bones[child.name].copy().inverted()
+ vec_left = vecs["left"] * mat
+ vec_right = vecs["right"] * mat
+ else:
+ vec_left = vecs["left"]
+ vec_right = vecs["right"]
+ if vecs["keyframe_loc"] != None:
+ vec_keyframe = vecs["keyframe_loc"]
+ else:
+ vec_keyframe = get_location(frame, display_ob, offset_ob,
+ curves)
+ x_left, y_left = world_to_screen(context, vec_left*2 + \
+ vec_keyframe)
+ x_right, y_right = world_to_screen(context, vec_right*2 + \
+ vec_keyframe)
+ handles[frame] = {"left":[x_left, y_left],
+ "right":[x_right, y_right]}
+ click.append([frame, "handle_left",
+ mathutils.Vector([x_left, y_left]), action_ob, child])
+ click.append([frame, "handle_right",
+ mathutils.Vector([x_right, y_right]), action_ob, child])
+ self.handles[display_ob.name] = handles
+
+ # calculate timebeads for timing mode
+ if context.window_manager.motion_trail.mode == 'timing':
+ timebeads = {}
+ n = context.window_manager.motion_trail.timebeads * (len(kf_time) \
+ - 1)
+ dframe = (range_max - range_min) / (n + 1)
+ if not use_cache:
+ if display_ob.name not in self.cached["timebeads_timing"]:
+ self.cached["timebeads_timing"][display_ob.name] = {}
+
+ for i in range(1, n+1):
+ frame = range_min + i * dframe
+ if use_cache and frame in \
+ self.cached["timebeads_timing"][display_ob.name]:
+ loc = self.cached["timebeads_timing"][display_ob.name]\
+ [frame]
+ else:
+ loc = get_location(frame, display_ob, offset_ob, curves)
+ self.cached["timebeads_timing"][display_ob.name][frame] = \
+ loc
+ x, y = world_to_screen(context, loc)
+ timebeads[frame] = [x, y]
+ click.append([frame, "timebead", mathutils.Vector([x,y]),
+ action_ob, child])
+ self.timebeads[display_ob.name] = timebeads
+
+ # calculate timebeads for speed mode
+ if context.window_manager.motion_trail.mode == 'speed':
+ angles = dict([[kf, {"left":[], "right":[]}] for kf in \
+ self.keyframes[display_ob.name]])
+ for fc in curves:
+ for i, kf in enumerate(fc.keyframe_points):
+ if i != 0:
+ angle = mathutils.Vector([-1, 0]).angle(mathutils.\
+ Vector(kf.handle_left) - mathutils.Vector(kf.co),
+ 0)
+ if angle != 0:
+ angles[kf.co[0]]["left"].append(angle)
+ if i != len(fc.keyframe_points) - 1:
+ angle = mathutils.Vector([1, 0]).angle(mathutils.\
+ Vector(kf.handle_right) - mathutils.Vector(kf.co),
+ 0)
+ if angle != 0:
+ angles[kf.co[0]]["right"].append(angle)
+ timebeads = {}
+ kf_time.sort()
+ if not use_cache:
+ if display_ob.name not in self.cached["timebeads_speed"]:
+ self.cached["timebeads_speed"][display_ob.name] = {}
+
+ for frame, sides in angles.items():
+ if sides["left"]:
+ perc = (sum(sides["left"]) / len(sides["left"])) / \
+ (math.pi / 2)
+ perc = max(0.4, min(1, perc * 5))
+ previous = kf_time[kf_time.index(frame) - 1]
+ bead_frame = frame - perc * ((frame - previous - 2) / 2)
+ if use_cache and bead_frame in \
+ self.cached["timebeads_speed"][display_ob.name]:
+ loc = self.cached["timebeads_speed"][display_ob.name]\
+ [bead_frame]
+ else:
+ loc = get_location(bead_frame, display_ob, offset_ob,
+ curves)
+ self.cached["timebeads_speed"][display_ob.name]\
+ [bead_frame] = loc
+ x, y = world_to_screen(context, loc)
+ timebeads[bead_frame] = [x, y]
+ click.append([bead_frame, "timebead", mathutils.\
+ Vector([x,y]), action_ob, child])
+ if sides["right"]:
+ perc = (sum(sides["right"]) / len(sides["right"])) / \
+ (math.pi / 2)
+ perc = max(0.4, min(1, perc * 5))
+ next = kf_time[kf_time.index(frame) + 1]
+ bead_frame = frame + perc * ((next - frame - 2) / 2)
+ if use_cache and bead_frame in \
+ self.cached["timebeads_speed"][display_ob.name]:
+ loc = self.cached["timebeads_speed"][display_ob.name]\
+ [bead_frame]
+ else:
+ loc = get_location(bead_frame, display_ob, offset_ob,
+ curves)
+ self.cached["timebeads_speed"][display_ob.name]\
+ [bead_frame] = loc
+ x, y = world_to_screen(context, loc)
+ timebeads[bead_frame] = [x, y]
+ click.append([bead_frame, "timebead", mathutils.\
+ Vector([x,y]), action_ob, child])
+ self.timebeads[display_ob.name] = timebeads
+
+ # add frame positions to click-list
+ if context.window_manager.motion_trail.frame_display:
+ path = self.paths[display_ob.name]
+ for x, y, color, frame, action_ob, child in path:
+ click.append([frame, "frame", mathutils.Vector([x,y]),
+ action_ob, child])
+
+ self.click[display_ob.name] = click
+
+ if context.scene.frame_current != frame_old:
+ context.scene.frame_set(frame_old)
+
+ context.user_preferences.edit.use_global_undo = global_undo
+
+
+# draw in 3d-view
+def draw_callback(self, context):
+ # polling
+ if context.mode not in ['OBJECT', 'POSE'] or \
+ context.window_manager.motion_trail.enabled != 1:
+ return
+
+ # display limits
+ if context.window_manager.motion_trail.path_before != 0:
+ limit_min = context.scene.frame_current - \
+ context.window_manager.motion_trail.path_before
+ else:
+ limit_min = -1e6
+ if context.window_manager.motion_trail.path_after != 0:
+ limit_max = context.scene.frame_current + \
+ context.window_manager.motion_trail.path_after
+ else:
+ limit_max = 1e6
+
+ # draw motion path
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glLineWidth(context.window_manager.motion_trail.path_width)
+ alpha = 1.0 - (context.window_manager.motion_trail.path_transparency / \
+ 100.0)
+ if context.window_manager.motion_trail.path_style == 'simple':
+ bgl.glColor4f(0.0, 0.0, 0.0, alpha)
+ for objectname, path in self.paths.items():
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ for x, y, color, frame, action_ob, child in path:
+ if frame < limit_min or frame > limit_max:
+ continue
+ bgl.glVertex2i(x, y)
+ bgl.glEnd()
+ else:
+ for objectname, path in self.paths.items():
+ for i, [x, y, color, frame, action_ob, child] in enumerate(path):
+ if frame < limit_min or frame > limit_max:
+ continue
+ r, g, b = color
+ if i != 0:
+ prev_path = path[i-1]
+ halfway = [(x + prev_path[0])/2, (y + prev_path[1])/2]
+ bgl.glColor4f(r, g, b, alpha)
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2i(int(halfway[0]), int(halfway[1]))
+ bgl.glVertex2i(x, y)
+ bgl.glEnd()
+ if i != len(path) - 1:
+ next_path = path[i+1]
+ halfway = [(x + next_path[0])/2, (y + next_path[1])/2]
+ bgl.glColor4f(r, g, b, alpha)
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2i(x, y)
+ bgl.glVertex2i(int(halfway[0]), int(halfway[1]))
+ bgl.glEnd()
+
+ # draw frames
+ if context.window_manager.motion_trail.frame_display:
+ bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
+ bgl.glPointSize(1)
+ bgl.glBegin(bgl.GL_POINTS)
+ for objectname, path in self.paths.items():
+ for x, y, color, frame, action_ob, child in path:
+ if frame < limit_min or frame > limit_max:
+ continue
+ if self.active_frame and objectname == self.active_frame[0] \
+ and abs(frame - self.active_frame[1]) < 1e-4:
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
+ bgl.glPointSize(3)
+ bgl.glBegin(bgl.GL_POINTS)
+ bgl.glVertex2i(x,y)
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
+ bgl.glPointSize(1)
+ bgl.glBegin(bgl.GL_POINTS)
+ else:
+ bgl.glVertex2i(x,y)
+ bgl.glEnd()
+
+ # time beads are shown in speed and timing modes
+ if context.window_manager.motion_trail.mode in ['speed', 'timing']:
+ bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
+ bgl.glPointSize(4)
+ bgl.glBegin(bgl.GL_POINTS)
+ for objectname, values in self.timebeads.items():
+ for frame, coords in values.items():
+ if frame < limit_min or frame > limit_max:
+ continue
+ if self.active_timebead and \
+ objectname == self.active_timebead[0] and \
+ abs(frame - self.active_timebead[1]) < 1e-4:
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_POINTS)
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+ bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_POINTS)
+ else:
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+
+ # handles are only shown in location mode
+ if context.window_manager.motion_trail.mode == 'location':
+ # draw handle-lines
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+ bgl.glLineWidth(1)
+ bgl.glBegin(bgl.GL_LINES)
+ for objectname, values in self.handles.items():
+ for frame, sides in values.items():
+ if frame < limit_min or frame > limit_max:
+ continue
+ for side, coords in sides.items():
+ if self.active_handle and \
+ objectname == self.active_handle[0] and \
+ side == self.active_handle[2] and \
+ abs(frame - self.active_handle[1]) < 1e-4:
+ bgl.glEnd()
+ bgl.glColor4f(.75, 0.25, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_LINES)
+ bgl.glVertex2i(self.keyframes[objectname][frame][0],
+ self.keyframes[objectname][frame][1])
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_LINES)
+ else:
+ bgl.glVertex2i(self.keyframes[objectname][frame][0],
+ self.keyframes[objectname][frame][1])
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+
+ # draw handles
+ bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
+ bgl.glPointSize(4)
+ bgl.glBegin(bgl.GL_POINTS)
+ for objectname, values in self.handles.items():
+ for frame, sides in values.items():
+ if frame < limit_min or frame > limit_max:
+ continue
+ for side, coords in sides.items():
+ if self.active_handle and \
+ objectname == self.active_handle[0] and \
+ side == self.active_handle[2] and \
+ abs(frame - self.active_handle[1]) < 1e-4:
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_POINTS)
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_POINTS)
+ else:
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+
+ # draw keyframes
+ bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
+ bgl.glPointSize(6)
+ bgl.glBegin(bgl.GL_POINTS)
+ for objectname, values in self.keyframes.items():
+ for frame, coords in values.items():
+ if frame < limit_min or frame > limit_max:
+ continue
+ if self.active_keyframe and \
+ objectname == self.active_keyframe[0] and \
+ abs(frame - self.active_keyframe[1]) < 1e-4:
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_POINTS)
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+ bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_POINTS)
+ else:
+ bgl.glVertex2i(coords[0], coords[1])
+ bgl.glEnd()
+
+ # draw keyframe-numbers
+ if context.window_manager.motion_trail.keyframe_numbers:
+ blf.size(0, 12, 72)
+ bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
+ for objectname, values in self.keyframes.items():
+ for frame, coords in values.items():
+ if frame < limit_min or frame > limit_max:
+ continue
+ blf.position(0, coords[0] + 3, coords[1] + 3, 0)
+ text = str(frame).split(".")
+ if len(text) == 1:
+ text = text[0]
+ elif len(text[1]) == 1 and text[1] == "0":
+ text = text[0]
+ else:
+ text = text[0] + "." + text[1][0]
+ if self.active_keyframe and \
+ objectname == self.active_keyframe[0] and \
+ abs(frame - self.active_keyframe[1]) < 1e-4:
+ bgl.glColor4f(1.0, 0.5, 0.0, 1.0)
+ blf.draw(0, text)
+ bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
+ else:
+ blf.draw(0, text)
+
+ # restore opengl defaults
+ bgl.glLineWidth(1)
+ bgl.glDisable(bgl.GL_BLEND)
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+ bgl.glPointSize(1)
+
+
+# change data based on mouse movement
+def drag(context, event, drag_mouse_ori, active_keyframe, active_handle,
+active_timebead, keyframes_ori, handles_ori, edit_bones):
+ # change 3d-location of keyframe
+ if context.window_manager.motion_trail.mode == 'location' and \
+ active_keyframe:
+ objectname, frame, frame_ori, action_ob, child = active_keyframe
+ if child:
+ mat = action_ob.matrix_world.copy().inverted() * \
+ edit_bones[child.name].copy().to_4x4()
+ else:
+ mat = 1
+
+ mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
+ drag_mouse_ori[1]) * mat
+ vector = screen_to_world(context, event.mouse_region_x,
+ event.mouse_region_y) * mat
+ d = vector - mouse_ori_world
+
+ loc_ori_ws = keyframes_ori[objectname][frame][1]
+ loc_ori_bs = loc_ori_ws * mat
+ new_loc = loc_ori_bs + d
+ curves = get_curves(action_ob, child)
+
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if kf.co[0] == frame:
+ kf.co[1] = new_loc[i]
+ kf.handle_left[1] = handles_ori[objectname][frame]\
+ ["left"][i][1] + d[i]
+ kf.handle_right[1] = handles_ori[objectname][frame]\
+ ["right"][i][1] + d[i]
+ break
+
+ # change 3d-location of handle
+ elif context.window_manager.motion_trail.mode == 'location' and \
+ active_handle:
+ objectname, frame, side, action_ob, child = active_handle
+ if child:
+ mat = action_ob.matrix_world.copy().inverted() * \
+ edit_bones[child.name].copy().to_4x4()
+ else:
+ mat = 1
+
+ mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
+ drag_mouse_ori[1]) * mat
+ vector = screen_to_world(context, event.mouse_region_x,
+ event.mouse_region_y) * mat
+ d = vector - mouse_ori_world
+ curves = get_curves(action_ob, child)
+
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if kf.co[0] == frame:
+ if side == "left":
+ # change handle type, if necessary
+ if kf.handle_left_type in ['AUTO', 'AUTO_CLAMPED',
+ 'ANIM_CLAMPED']:
+ kf.handle_left_type = 'ALIGNED'
+ elif kf.handle_left_type == 'VECTOR':
+ kf.handle_left_type = 'FREE'
+ # change handle position(s)
+ kf.handle_left[1] = handles_ori[objectname][frame]\
+ ["left"][i][1] + d[i]
+ if kf.handle_left_type in ['ALIGNED', 'ANIM_CLAMPED',
+ 'AUTO', 'AUTO_CLAMPED']:
+ dif = (abs(handles_ori[objectname][frame]["right"]\
+ [i][0] - kf.co[0]) / abs(kf.handle_left[0] - \
+ kf.co[0])) * d[i]
+ kf.handle_right[1] = handles_ori[objectname]\
+ [frame]["right"][i][1] - dif
+ elif side == "right":
+ # change handle type, if necessary
+ if kf.handle_right_type in ['AUTO', 'AUTO_CLAMPED',
+ 'ANIM_CLAMPED']:
+ kf.handle_left_type = 'ALIGNED'
+ kf.handle_right_type = 'ALIGNED'
+ elif kf.handle_right_type == 'VECTOR':
+ kf.handle_left_type = 'FREE'
+ kf.handle_right_type = 'FREE'
+ # change handle position(s)
+ kf.handle_right[1] = handles_ori[objectname][frame]\
+ ["right"][i][1] + d[i]
+ if kf.handle_right_type in ['ALIGNED', 'ANIM_CLAMPED',
+ 'AUTO', 'AUTO_CLAMPED']:
+ dif = (abs(handles_ori[objectname][frame]["left"]\
+ [i][0] - kf.co[0]) / abs(kf.handle_right[0] - \
+ kf.co[0])) * d[i]
+ kf.handle_left[1] = handles_ori[objectname]\
+ [frame]["left"][i][1] - dif
+ break
+
+ # change position of all keyframes on timeline
+ elif context.window_manager.motion_trail.mode == 'timing' and \
+ active_timebead:
+ objectname, frame, frame_ori, action_ob, child = active_timebead
+ curves = get_curves(action_ob, child)
+ ranges = [val for c in curves for val in c.range()]
+ ranges.sort()
+ range_min = round(ranges[0])
+ range_max = round(ranges[-1])
+ range = range_max - range_min
+ dx_screen = -(mathutils.Vector([event.mouse_region_x,
+ event.mouse_region_y]) - drag_mouse_ori)[0]
+ dx_screen = dx_screen / context.region.width * range
+ new_frame = frame + dx_screen
+ shift_low = max(1e-4, (new_frame - range_min) / (frame - range_min))
+ shift_high = max(1e-4, (range_max - new_frame) / (range_max - frame))
+
+ new_mapping = {}
+ for i, curve in enumerate(curves):
+ for j, kf in enumerate(curve.keyframe_points):
+ frame_map = kf.co[0]
+ if frame_map < range_min + 1e-4 or \
+ frame_map > range_max - 1e-4:
+ continue
+ frame_ori = False
+ for f in keyframes_ori[objectname]:
+ if abs(f - frame_map) < 1e-4:
+ frame_ori = keyframes_ori[objectname][f][0]
+ value_ori = keyframes_ori[objectname][f]
+ break
+ if not frame_ori:
+ continue
+ if frame_ori <= frame:
+ frame_new = (frame_ori - range_min) * shift_low + \
+ range_min
+ else:
+ frame_new = range_max - (range_max - frame_ori) * \
+ shift_high
+ frame_new = max(range_min + j, min(frame_new, range_max - \
+ (len(curve.keyframe_points)-j)+1))
+ d_frame = frame_new - frame_ori
+ if frame_new not in new_mapping:
+ new_mapping[frame_new] = value_ori
+ kf.co[0] = frame_new
+ kf.handle_left[0] = handles_ori[objectname][frame_ori]\
+ ["left"][i][0] + d_frame
+ kf.handle_right[0] = handles_ori[objectname][frame_ori]\
+ ["right"][i][0] + d_frame
+ del keyframes_ori[objectname]
+ keyframes_ori[objectname] = {}
+ for new_frame, value in new_mapping.items():
+ keyframes_ori[objectname][new_frame] = value
+
+ # change position of active keyframe on the timeline
+ elif context.window_manager.motion_trail.mode == 'timing' and \
+ active_keyframe:
+ objectname, frame, frame_ori, action_ob, child = active_keyframe
+ if child:
+ mat = action_ob.matrix_world.copy().inverted() * \
+ edit_bones[child.name].copy().to_4x4()
+ else:
+ mat = action_ob.matrix_world.copy().inverted()
+
+ mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
+ drag_mouse_ori[1]) * mat
+ vector = screen_to_world(context, event.mouse_region_x,
+ event.mouse_region_y) * mat
+ d = vector - mouse_ori_world
+
+ locs_ori = [[f_ori, coords] for f_mapped, [f_ori, coords] in \
+ keyframes_ori[objectname].items()]
+ locs_ori.sort()
+ direction = 1
+ range = False
+ for i, [f_ori, coords] in enumerate(locs_ori):
+ if abs(frame_ori - f_ori) < 1e-4:
+ if i == 0:
+ # first keyframe, nothing before it
+ direction = -1
+ range = [f_ori, locs_ori[i+1][0]]
+ elif i == len(locs_ori) - 1:
+ # last keyframe, nothing after it
+ range = [locs_ori[i-1][0], f_ori]
+ else:
+ current = mathutils.Vector(coords)
+ next = mathutils.Vector(locs_ori[i+1][1])
+ previous = mathutils.Vector(locs_ori[i-1][1])
+ angle_to_next = d.angle(next - current, 0)
+ angle_to_previous = d.angle(previous-current, 0)
+ if angle_to_previous < angle_to_next:
+ # mouse movement is in direction of previous keyframe
+ direction = -1
+ range = [locs_ori[i-1][0], locs_ori[i+1][0]]
+ break
+ direction *= -1 # feels more natural in 3d-view
+ if not range:
+ # keyframe not found, is impossible, but better safe than sorry
+ return(active_keyframe, active_timebead, keyframes_ori)
+ # calculate strength of movement
+ d_screen = mathutils.Vector([event.mouse_region_x,
+ event.mouse_region_y]) - drag_mouse_ori
+ if d_screen.length != 0:
+ d_screen = d_screen.length / (abs(d_screen[0])/d_screen.length*\
+ context.region.width + abs(d_screen[1])/d_screen.length*\
+ context.region.height)
+ d_screen *= direction # d_screen value ranges from -1.0 to 1.0
+ else:
+ d_screen = 0.0
+ new_frame = d_screen * (range[1] - range[0]) + frame_ori
+ max_frame = range[1]
+ if max_frame == frame_ori:
+ max_frame += 1
+ min_frame = range[0]
+ if min_frame == frame_ori:
+ min_frame -= 1
+ new_frame = min(max_frame - 1, max(min_frame + 1, new_frame))
+ d_frame = new_frame - frame_ori
+ curves = get_curves(action_ob, child)
+
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if abs(kf.co[0] - frame) < 1e-4:
+ kf.co[0] = new_frame
+ kf.handle_left[0] = handles_ori[objectname][frame_ori]\
+ ["left"][i][0] + d_frame
+ kf.handle_right[0] = handles_ori[objectname][frame_ori]\
+ ["right"][i][0] + d_frame
+ break
+ active_keyframe = [objectname, new_frame, frame_ori, action_ob, child]
+
+ # change position of active timebead on the timeline, thus altering speed
+ elif context.window_manager.motion_trail.mode == 'speed' and \
+ active_timebead:
+ objectname, frame, frame_ori, action_ob, child = active_timebead
+ if child:
+ mat = action_ob.matrix_world.copy().inverted() * \
+ edit_bones[child.name].copy().to_4x4()
+ else:
+ mat = 1
+
+ mouse_ori_world = screen_to_world(context, drag_mouse_ori[0],
+ drag_mouse_ori[1]) * mat
+ vector = screen_to_world(context, event.mouse_region_x,
+ event.mouse_region_y) * mat
+ d = vector - mouse_ori_world
+
+ # determine direction (to next or previous keyframe)
+ curves = get_curves(action_ob, child)
+ fcx, fcy, fcz = curves
+ locx = fcx.evaluate(frame_ori)
+ locy = fcy.evaluate(frame_ori)
+ locz = fcz.evaluate(frame_ori)
+ loc_ori = mathutils.Vector([locx, locy, locz]) # bonespace
+ keyframes = [kf for kf in keyframes_ori[objectname]]
+ keyframes.append(frame_ori)
+ keyframes.sort()
+ frame_index = keyframes.index(frame_ori)
+ kf_prev = keyframes[frame_index - 1]
+ kf_next = keyframes[frame_index + 1]
+ vec_prev = (mathutils.Vector(keyframes_ori[objectname][kf_prev][1]) \
+ * mat - loc_ori).normalized()
+ vec_next = (mathutils.Vector(keyframes_ori[objectname][kf_next][1]) \
+ * mat - loc_ori).normalized()
+ d_normal = d.copy().normalized()
+ dist_to_next = (d_normal - vec_next).length
+ dist_to_prev = (d_normal - vec_prev).length
+ if dist_to_prev < dist_to_next:
+ direction = 1
+ else:
+ direction = -1
+
+ if (kf_next - frame_ori) < (frame_ori - kf_prev):
+ kf_bead = kf_next
+ side = "left"
+ else:
+ kf_bead = kf_prev
+ side = "right"
+ d_frame = d.length * direction * 2 # *2 to make it more sensitive
+
+ angles = []
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if abs(kf.co[0] - kf_bead) < 1e-4:
+ if side == "left":
+ # left side
+ kf.handle_left[0] = min(handles_ori[objectname]\
+ [kf_bead]["left"][i][0] + d_frame, kf_bead - 1)
+ angle = mathutils.Vector([-1, 0]).angle(mathutils.\
+ Vector(kf.handle_left) - mathutils.Vector(kf.co),
+ 0)
+ if angle != 0:
+ angles.append(angle)
+ else:
+ # right side
+ kf.handle_right[0] = max(handles_ori[objectname]\
+ [kf_bead]["right"][i][0] + d_frame, kf_bead + 1)
+ angle = mathutils.Vector([1, 0]).angle(mathutils.\
+ Vector(kf.handle_right) - mathutils.Vector(kf.co),
+ 0)
+ if angle != 0:
+ angles.append(angle)
+ break
+
+ # update frame of active_timebead
+ perc = (sum(angles) / len(angles)) / (math.pi / 2)
+ perc = max(0.4, min(1, perc * 5))
+ if side == "left":
+ bead_frame = kf_bead - perc * ((kf_bead - kf_prev - 2) / 2)
+ else:
+ bead_frame = kf_bead + perc * ((kf_next - kf_bead - 2) / 2)
+ active_timebead = [objectname, bead_frame, frame_ori, action_ob, child]
+
+ return(active_keyframe, active_timebead, keyframes_ori)
+
+
+# revert changes made by dragging
+def cancel_drag(context, active_keyframe, active_handle, active_timebead,
+keyframes_ori, handles_ori, edit_bones):
+ # revert change in 3d-location of active keyframe and its handles
+ if context.window_manager.motion_trail.mode == 'location' and \
+ active_keyframe:
+ objectname, frame, frame_ori, active_ob, child = active_keyframe
+ curves = get_curves(active_ob, child)
+ loc_ori = keyframes_ori[objectname][frame][1]
+ if child:
+ loc_ori = loc_ori * edit_bones[child.name] * \
+ active_ob.matrix_world.copy().inverted()
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if kf.co[0] == frame:
+ kf.co[1] = loc_ori[i]
+ kf.handle_left[1] = handles_ori[objectname][frame]\
+ ["left"][i][1]
+ kf.handle_right[1] = handles_ori[objectname][frame]\
+ ["right"][i][1]
+ break
+
+ # revert change in 3d-location of active handle
+ elif context.window_manager.motion_trail.mode == 'location' and \
+ active_handle:
+ objectname, frame, side, active_ob, child = active_handle
+ curves = get_curves(active_ob, child)
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if kf.co[0] == frame:
+ kf.handle_left[1] = handles_ori[objectname][frame]\
+ ["left"][i][1]
+ kf.handle_right[1] = handles_ori[objectname][frame]\
+ ["right"][i][1]
+ break
+
+ # revert position of all keyframes and handles on timeline
+ elif context.window_manager.motion_trail.mode == 'timing' and \
+ active_timebead:
+ objectname, frame, frame_ori, active_ob, child = active_timebead
+ curves = get_curves(active_ob, child)
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ for kf_ori, [frame_ori, loc] in keyframes_ori[objectname].\
+ items():
+ if abs(kf.co[0] - kf_ori) < 1e-4:
+ kf.co[0] = frame_ori
+ kf.handle_left[0] = handles_ori[objectname]\
+ [frame_ori]["left"][i][0]
+ kf.handle_right[0] = handles_ori[objectname]\
+ [frame_ori]["right"][i][0]
+ break
+
+ # revert position of active keyframe and its handles on the timeline
+ elif context.window_manager.motion_trail.mode == 'timing' and \
+ active_keyframe:
+ objectname, frame, frame_ori, active_ob, child = active_keyframe
+ curves = get_curves(active_ob, child)
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if abs(kf.co[0] - frame) < 1e-4:
+ kf.co[0] = keyframes_ori[objectname][frame_ori][0]
+ kf.handle_left[0] = handles_ori[objectname][frame_ori]\
+ ["left"][i][0]
+ kf.handle_right[0] = handles_ori[objectname][frame_ori]\
+ ["right"][i][0]
+ break
+ active_keyframe = [objectname, frame_ori, frame_ori, active_ob, child]
+
+ # revert position of handles on the timeline
+ elif context.window_manager.motion_trail.mode == 'speed' and \
+ active_timebead:
+ objectname, frame, frame_ori, active_ob, child = active_timebead
+ curves = get_curves(active_ob, child)
+ keyframes = [kf for kf in keyframes_ori[objectname]]
+ keyframes.append(frame_ori)
+ keyframes.sort()
+ frame_index = keyframes.index(frame_ori)
+ kf_prev = keyframes[frame_index - 1]
+ kf_next = keyframes[frame_index + 1]
+ if (kf_next - frame_ori) < (frame_ori - kf_prev):
+ kf_frame = kf_next
+ else:
+ kf_frame = kf_prev
+ for i, curve in enumerate(curves):
+ for kf in curve.keyframe_points:
+ if kf.co[0] == kf_frame:
+ kf.handle_left[0] = handles_ori[objectname][kf_frame]\
+ ["left"][i][0]
+ kf.handle_right[0] = handles_ori[objectname][kf_frame]\
+ ["right"][i][0]
+ break
+ active_timebead = [objectname, frame_ori, frame_ori, active_ob, child]
+
+ return(active_keyframe, active_timebead)
+
+
+# return the handle type of the active selection
+def get_handle_type(active_keyframe, active_handle):
+ if active_keyframe:
+ objectname, frame, side, action_ob, child = active_keyframe
+ side = "both"
+ elif active_handle:
+ objectname, frame, side, action_ob, child = active_handle
+ else:
+ # no active handle(s)
+ return(False)
+
+ # properties used when changing handle type
+ bpy.context.window_manager.motion_trail.handle_type_frame = frame
+ bpy.context.window_manager.motion_trail.handle_type_side = side
+ bpy.context.window_manager.motion_trail.handle_type_action_ob = \
+ action_ob.name
+ if child:
+ bpy.context.window_manager.motion_trail.handle_type_child = child.name
+ else:
+ bpy.context.window_manager.motion_trail.handle_type_child = ""
+
+ curves = get_curves(action_ob, child=child)
+ for c in curves:
+ for kf in c.keyframe_points:
+ if kf.co[0] == frame:
+ if side in ["left", "both"]:
+ return(kf.handle_left_type)
+ else:
+ return(kf.handle_right_type)
+
+ return("AUTO")
+
+
+# turn the given frame into a keyframe
+def insert_keyframe(self, context, frame):
+ objectname, frame, frame, action_ob, child = frame
+ curves = get_curves(action_ob, child)
+ for c in curves:
+ y = c.evaluate(frame)
+ if c.keyframe_points:
+ c.keyframe_points.insert(frame, y)
+
+ bpy.context.window_manager.motion_trail.force_update = True
+ calc_callback(self, context)
+
+
+# change the handle type of the active selection
+def set_handle_type(self, context):
+ if not context.window_manager.motion_trail.handle_type_enabled:
+ return
+ if context.window_manager.motion_trail.handle_type_old == \
+ context.window_manager.motion_trail.handle_type:
+ # function called because of selection change, not change in type
+ return
+ context.window_manager.motion_trail.handle_type_old = \
+ context.window_manager.motion_trail.handle_type
+
+ frame = bpy.context.window_manager.motion_trail.handle_type_frame
+ side = bpy.context.window_manager.motion_trail.handle_type_side
+ action_ob = bpy.context.window_manager.motion_trail.handle_type_action_ob
+ action_ob = bpy.data.objects[action_ob]
+ child = bpy.context.window_manager.motion_trail.handle_type_child
+ if child:
+ child = action_ob.pose.bones[child]
+ new_type = context.window_manager.motion_trail.handle_type
+
+ curves = get_curves(action_ob, child=child)
+ for c in curves:
+ for kf in c.keyframe_points:
+ if kf.co[0] == frame:
+ # align if necessary
+ if side in ["right", "both"] and new_type in \
+ ["AUTO", "AUTO_CLAMPED", "ALIGNED"]:
+ # change right handle
+ normal = (kf.co - kf.handle_left).normalized()
+ size = (kf.handle_right[0] - kf.co[0]) / normal[0]
+ normal = normal*size + kf.co
+ kf.handle_right[1] = normal[1]
+ elif side == "left" and new_type in ["AUTO", "AUTO_CLAMPED",
+ "ALIGNED"]:
+ # change left handle
+ normal = (kf.co - kf.handle_right).normalized()
+ size = (kf.handle_left[0] - kf.co[0]) / normal[0]
+ normal = normal*size + kf.co
+ kf.handle_left[1] = normal[1]
+ # change type
+ if side in ["left", "both"]:
+ kf.handle_left_type = new_type
+ if side in ["right", "both"]:
+ kf.handle_right_type = new_type
+
+ context.window_manager.motion_trail.force_update = True
+
+
+class MotionTrailOperator(bpy.types.Operator):
+ """Edit motion trails in 3d-view"""
+ bl_idname = "view3d.motion_trail"
+ bl_label = "Motion Trail"
+
+ _handle1 = None
+ _handle2 = None
+
+ def modal(self, context, event):
+ if context.window_manager.motion_trail.enabled == -1:
+ context.window_manager.motion_trail.enabled = 0
+ try:
+ context.region.callback_remove(self._handle1)
+ except:
+ pass
+ try:
+ context.region.callback_remove(self._handle2)
+ except:
+ pass
+ context.area.tag_redraw()
+ return {'FINISHED'}
+
+ if not context.area:
+ return {'PASS_THROUGH'}
+ if not context.region or event.type == 'NONE':
+ context.area.tag_redraw()
+ return {'PASS_THROUGH'}
+
+ select = context.user_preferences.inputs.select_mouse
+ if not context.active_object or not context.active_object.mode in \
+ ['OBJECT', 'POSE']:
+ if self.drag:
+ self.drag = False
+ self.lock = True
+ context.window_manager.motion_trail.force_update = True
+ # default hotkeys should still work
+ if event.type == self.transform_key and event.value == 'PRESS':
+ if bpy.ops.transform.translate.poll():
+ bpy.ops.transform.translate('INVOKE_DEFAULT')
+ elif event.type == select + 'MOUSE' and event.value == 'PRESS' \
+ and not self.drag and not event.shift and not event.alt \
+ and not event.ctrl:
+ if bpy.ops.view3d.select.poll():
+ bpy.ops.view3d.select('INVOKE_DEFAULT')
+ elif event.type == 'LEFTMOUSE' and event.value == 'PRESS' and not\
+ event.alt and not event.ctrl and not event.shift:
+ if eval("bpy.ops."+self.left_action+".poll()"):
+ eval("bpy.ops."+self.left_action+"('INVOKE_DEFAULT')")
+ return {'PASS_THROUGH'}
+ # check if event was generated within 3d-window, dragging is exception
+ if not self.drag:
+ if not (0 < event.mouse_region_x < context.region.width) or \
+ not (0 < event.mouse_region_y < context.region.height):
+ return {'PASS_THROUGH'}
+
+ if event.type == self.transform_key and event.value == 'PRESS' and \
+ (self.active_keyframe or self.active_handle or self.active_timebead \
+ or self.active_frame):
+ # override default translate()
+ if not self.drag:
+ # start drag
+ if self.active_frame:
+ insert_keyframe(self, context, self.active_frame)
+ self.active_keyframe = self.active_frame
+ self.active_frame = False
+ self.keyframes_ori, self.handles_ori = \
+ get_original_animation_data(context, self.keyframes)
+ self.drag_mouse_ori = mathutils.Vector([event.mouse_region_x,
+ event.mouse_region_y])
+ self.drag = True
+ self.lock = False
+ else:
+ # stop drag
+ self.drag = False
+ self.lock = True
+ context.window_manager.motion_trail.force_update = True
+ elif event.type == self.transform_key and event.value == 'PRESS':
+ # call default translate()
+ if bpy.ops.transform.translate.poll():
+ bpy.ops.transform.translate('INVOKE_DEFAULT')
+ elif (event.type == 'ESC' and self.drag and event.value == 'PRESS') \
+ or (event.type == 'RIGHTMOUSE' and self.drag and event.value == \
+ 'PRESS'):
+ # cancel drag
+ self.drag = False
+ self.lock = True
+ context.window_manager.motion_trail.force_update = True
+ self.active_keyframe, self.active_timebead = cancel_drag(context,
+ self.active_keyframe, self.active_handle,
+ self.active_timebead, self.keyframes_ori, self.handles_ori,
+ self.edit_bones)
+ elif event.type == 'MOUSEMOVE' and self.drag:
+ # drag
+ self.active_keyframe, self.active_timebead, self.keyframes_ori = \
+ drag(context, event, self.drag_mouse_ori,
+ self.active_keyframe, self.active_handle,
+ self.active_timebead, self.keyframes_ori, self.handles_ori,
+ self.edit_bones)
+ elif event.type == select + 'MOUSE' and event.value == 'PRESS' and \
+ not self.drag and not event.shift and not event.alt and not \
+ event.ctrl:
+ # select
+ treshold = 10
+ clicked = mathutils.Vector([event.mouse_region_x,
+ event.mouse_region_y])
+ self.active_keyframe = False
+ self.active_handle = False
+ self.active_timebead = False
+ self.active_frame = False
+ context.window_manager.motion_trail.force_update = True
+ context.window_manager.motion_trail.handle_type_enabled = True
+ found = False
+
+ if context.window_manager.motion_trail.path_before == 0:
+ frame_min = context.scene.frame_start
+ else:
+ frame_min = max(context.scene.frame_start,
+ context.scene.frame_current - \
+ context.window_manager.motion_trail.path_before)
+ if context.window_manager.motion_trail.path_after == 0:
+ frame_max = context.scene.frame_end
+ else:
+ frame_max = min(context.scene.frame_end,
+ context.scene.frame_current + \
+ context.window_manager.motion_trail.path_after)
+
+ for objectname, values in self.click.items():
+ if found:
+ break
+ for frame, type, coord, action_ob, child in values:
+ if frame < frame_min or frame > frame_max:
+ continue
+ if (coord - clicked).length <= treshold:
+ found = True
+ if type == "keyframe":
+ self.active_keyframe = [objectname, frame, frame,
+ action_ob, child]
+ elif type == "handle_left":
+ self.active_handle = [objectname, frame, "left",
+ action_ob, child]
+ elif type == "handle_right":
+ self.active_handle = [objectname, frame, "right",
+ action_ob, child]
+ elif type == "timebead":
+ self.active_timebead = [objectname, frame, frame,
+ action_ob, child]
+ elif type == "frame":
+ self.active_frame = [objectname, frame, frame,
+ action_ob, child]
+ break
+ if not found:
+ context.window_manager.motion_trail.handle_type_enabled = False
+ # no motion trail selections, so pass on to normal select()
+ if bpy.ops.view3d.select.poll():
+ bpy.ops.view3d.select('INVOKE_DEFAULT')
+ else:
+ handle_type = get_handle_type(self.active_keyframe,
+ self.active_handle)
+ if handle_type:
+ context.window_manager.motion_trail.handle_type_old = \
+ handle_type
+ context.window_manager.motion_trail.handle_type = \
+ handle_type
+ else:
+ context.window_manager.motion_trail.handle_type_enabled = \
+ False
+ elif event.type == 'LEFTMOUSE' and event.value == 'PRESS' and \
+ self.drag:
+ # stop drag
+ self.drag = False
+ self.lock = True
+ context.window_manager.motion_trail.force_update = True
+ elif event.type == 'LEFTMOUSE' and event.value == 'PRESS' and not\
+ event.alt and not event.ctrl and not event.shift:
+ if eval("bpy.ops."+self.left_action+".poll()"):
+ eval("bpy.ops."+self.left_action+"('INVOKE_DEFAULT')")
+
+ if context.area: # not available if other window-type is fullscreen
+ context.area.tag_redraw()
+
+ return {'PASS_THROUGH'}
+
+ def invoke(self, context, event):
+ if context.area.type == 'VIEW_3D':
+ # get clashing keymap items
+ select = context.user_preferences.inputs.select_mouse
+ kms = [bpy.context.window_manager.keyconfigs.active.\
+ keymaps['3D View'], bpy.context.window_manager.keyconfigs.\
+ active.keymaps['Object Mode']]
+ kmis = []
+ self.left_action = None
+ self.right_action = None
+ for km in kms:
+ for kmi in km.keymap_items:
+ if kmi.idname == "transform.translate" and \
+ kmi.map_type == 'KEYBOARD' and not \
+ kmi.properties.texture_space:
+ kmis.append(kmi)
+ self.transform_key = kmi.type
+ elif (kmi.type == 'ACTIONMOUSE' and select == 'RIGHT') \
+ and not kmi.alt and not kmi.any and not kmi.ctrl \
+ and not kmi.shift:
+ kmis.append(kmi)
+ self.left_action = kmi.idname
+ elif kmi.type == 'SELECTMOUSE' and not kmi.alt and not \
+ kmi.any and not kmi.ctrl and not kmi.shift:
+ kmis.append(kmi)
+ if select == 'RIGHT':
+ self.right_action = kmi.idname
+ else:
+ self.left_action = kmi.idname
+ elif kmi.type == 'LEFTMOUSE' and not kmi.alt and not \
+ kmi.any and not kmi.ctrl and not kmi.shift:
+ kmis.append(kmi)
+ self.left_action = kmi.idname
+
+ if context.window_manager.motion_trail.enabled == 0:
+ # enable
+ context.window_manager.motion_trail.enabled = 1
+ self.active_keyframe = False
+ self.active_handle = False
+ self.active_timebead = False
+ self.active_frame = False
+ self.click = {}
+ self.drag = False
+ self.lock = True
+ self.perspective = context.region_data.perspective_matrix
+ self.displayed = []
+ context.window_manager.motion_trail.force_update = True
+ context.window_manager.motion_trail.handle_type_enabled = False
+ self.cached = {"path":{}, "keyframes":{},
+ "timebeads_timing":{}, "timebeads_speed":{}}
+
+ for kmi in kmis:
+ kmi.active = False
+
+ self._handle1 = context.region.callback_add(calc_callback,
+ (self, context), 'POST_VIEW')
+ self._handle2 = context.region.callback_add(draw_callback,
+ (self, context), 'POST_PIXEL')
+ if context.area:
+ context.area.tag_redraw()
+
+ context.window_manager.modal_handler_add(self)
+ else:
+ # disable
+ context.window_manager.motion_trail.enabled = -1
+ for kmi in kmis:
+ kmi.active = True
+
+ return {'RUNNING_MODAL'}
+
+ else:
+ self.report({'WARNING'}, "View3D not found, cannot run operator")
+ return {'CANCELLED'}
+
+
+class MotionTrailPanel(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Motion Trail"
+ bl_options = {'DEFAULT_CLOSED'}
+ @classmethod
+ def poll(cls, context):
+ if not context.active_object:
+ return(False)
+ return(context.active_object.mode in ['OBJECT', 'POSE'])
+
+ def draw(self, context):
+ col = self.layout.column()
+ if context.window_manager.motion_trail.enabled != 1:
+ col.operator("view3d.motion_trail", text="Enable motion trail")
+ else:
+ col.operator("view3d.motion_trail", text="Disable motion trail")
+
+ box = self.layout.box()
+ box.prop(context.window_manager.motion_trail, "mode")
+ #box.prop(context.window_manager.motion_trail, "calculate")
+ if context.window_manager.motion_trail.mode in ['timing']:
+ box.prop(context.window_manager.motion_trail, "timebeads")
+
+ box = self.layout.box()
+ col = box.column()
+ row = col.row()
+ if context.window_manager.motion_trail.path_display:
+ row.prop(context.window_manager.motion_trail, "path_display",
+ icon="DOWNARROW_HLT", text="", emboss=False)
+ else:
+ row.prop(context.window_manager.motion_trail, "path_display",
+ icon="RIGHTARROW", text="", emboss=False)
+ row.label("Path options")
+ if context.window_manager.motion_trail.path_display:
+ col.prop(context.window_manager.motion_trail, "path_style",
+ text="Style")
+ grouped = col.column(align=True)
+ grouped.prop(context.window_manager.motion_trail, "path_width",
+ text="Width")
+ grouped.prop(context.window_manager.motion_trail,
+ "path_transparency", text="Transparency")
+ grouped.prop(context.window_manager.motion_trail,
+ "path_resolution")
+ row = grouped.row(align=True)
+ row.prop(context.window_manager.motion_trail, "path_before")
+ row.prop(context.window_manager.motion_trail, "path_after")
+ col = col.column(align=True)
+ col.prop(context.window_manager.motion_trail, "keyframe_numbers")
+ col.prop(context.window_manager.motion_trail, "frame_display")
+
+ if context.window_manager.motion_trail.mode in ['location']:
+ box = self.layout.box()
+ col = box.column(align=True)
+ col.prop(context.window_manager.motion_trail, "handle_display",
+ text="Handles")
+ if context.window_manager.motion_trail.handle_display:
+ row = col.row()
+ row.enabled = context.window_manager.motion_trail.\
+ handle_type_enabled
+ row.prop(context.window_manager.motion_trail, "handle_type")
+
+
+class MotionTrailProps(bpy.types.PropertyGroup):
+ def internal_update(self, context):
+ context.window_manager.motion_trail.force_update = True
+ if context.area:
+ context.area.tag_redraw()
+
+ # internal use
+ enabled = bpy.props.IntProperty(default=0)
+ force_update = bpy.props.BoolProperty(name="internal use",
+ description="Force calc_callback to fully execute",
+ default=False)
+ handle_type_enabled = bpy.props.BoolProperty(default=False)
+ handle_type_frame = bpy.props.FloatProperty()
+ handle_type_side = bpy.props.StringProperty()
+ handle_type_action_ob = bpy.props.StringProperty()
+ handle_type_child = bpy.props.StringProperty()
+ handle_type_old = bpy.props.EnumProperty(items=(("AUTO", "", ""),
+ ("AUTO_CLAMPED", "", ""), ("VECTOR", "", ""), ("ALIGNED", "", ""),
+ ("FREE", "", "")), default='AUTO',)
+
+ # visible in user interface
+ calculate = bpy.props.EnumProperty(name="Calculate",
+ items=(("fast", "Fast", "Recommended setting, change if the "\
+ "motion path is positioned incorrectly"),
+ ("full", "Full", "Takes parenting and modifiers into account, "\
+ "but can be very slow on complicated scenes")),
+ description="Calculation method for determining locations",
+ default='full',
+ update=internal_update)
+ frame_display = bpy.props.BoolProperty(name="Frames",
+ description="Display frames, \n test",
+ default=True,
+ update=internal_update)
+ handle_display = bpy.props.BoolProperty(name="Display",
+ description="Display handles",
+ default=True,
+ update=internal_update)
+ handle_type = bpy.props.EnumProperty(name="Type",
+ items=(("AUTO", "Automatic", ""),
+ ("AUTO_CLAMPED", "Auto Clamped", ""),
+ ("VECTOR", "Vector", ""),
+ ("ALIGNED", "Aligned", ""),
+ ("FREE", "Free", "")),
+ description="Set handle type for the selected handle",
+ default='AUTO',
+ update=set_handle_type)
+ keyframe_numbers = bpy.props.BoolProperty(name="Keyframe numbers",
+ description="Display keyframe numbers",
+ default=False,
+ update=internal_update)
+ mode = bpy.props.EnumProperty(name="Mode",
+ items=(("location", "Location", "Change path that is followed"),
+ ("speed", "Speed", "Change speed between keyframes"),
+ ("timing", "Timing", "Change position of keyframes on timeline")),
+ description="Enable editing of certain properties in the 3d-view",
+ default='location',
+ update=internal_update)
+ path_after = bpy.props.IntProperty(name="After",
+ description="Number of frames to show after the current frame, "\
+ "0 = display all",
+ default=50,
+ min=0,
+ update=internal_update)
+ path_before = bpy.props.IntProperty(name="Before",
+ description="Number of frames to show before the current frame, "\
+ "0 = display all",
+ default=50,
+ min=0,
+ update=internal_update)
+ path_display = bpy.props.BoolProperty(name="Path options",
+ description="Display path options",
+ default=True)
+ path_resolution = bpy.props.IntProperty(name="Resolution",
+ description="10 is smoothest, but could be "\
+ "slow when adjusting keyframes, handles or timebeads",
+ default=10,
+ min=1,
+ max=10,
+ update=internal_update)
+ path_style = bpy.props.EnumProperty(name="Path style",
+ items=(("acceleration", "Acceleration", "Gradient based on relative "\
+ "acceleration"),
+ ("simple", "Simple", "Black line"),
+ ("speed", "Speed", "Gradient based on relative speed")),
+ description="Information conveyed by path color",
+ default='simple',
+ update=internal_update)
+ path_transparency = bpy.props.IntProperty(name="Path transparency",
+ description="Determines visibility of path",
+ default=0,
+ min=0,
+ max=100,
+ subtype='PERCENTAGE',
+ update=internal_update)
+ path_width = bpy.props.IntProperty(name="Path width",
+ description="Width in pixels",
+ default=1,
+ min=1,
+ soft_max=5,
+ update=internal_update)
+ timebeads = bpy.props.IntProperty(name="Time beads",
+ description="Number of time beads to display per segment",
+ default=5,
+ min=1,
+ soft_max = 10,
+ update=internal_update)
+
+
+classes = [MotionTrailProps,
+ MotionTrailOperator,
+ MotionTrailPanel]
+
+
+def register():
+ for c in classes:
+ bpy.utils.register_class(c)
+ bpy.types.WindowManager.motion_trail = bpy.props.PointerProperty(\
+ type=MotionTrailProps)
+
+
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+ del bpy.types.WindowManager.motion_trail
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/btrace/__init__.py b/release/scripts/addons_contrib/btrace/__init__.py
new file mode 100644
index 0000000..7aba88d
--- /dev/null
+++ b/release/scripts/addons_contrib/btrace/__init__.py
@@ -0,0 +1,68 @@
+#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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#END GPL LICENCE BLOCK
+
+bl_info = {
+ "name": "Btrace",
+ "author": "liero, crazycourier, Atom, Meta-Androcto, MacKracken",
+ "version": (1, 1, ),
+ "blender": (2, 62, 0),
+ "location": "View3D > Tools",
+ "description": "Tools for converting/animating objects/particles into curves",
+ "warning": "Still under development, bug reports appreciated",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Curve/Btrace",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=29563",
+ "category": "Add Curve"
+ }
+
+import bpy
+from .bTrace import *
+import selection_utils
+from bpy.props import FloatProperty, EnumProperty, IntProperty, BoolProperty, FloatVectorProperty
+
+### Define Classes to register
+classes = [
+ TracerProperties,
+ TracerPropertiesMenu,
+ addTracerObjectPanel,
+ OBJECT_OT_convertcurve,
+ OBJECT_OT_objecttrace,
+ OBJECT_OT_objectconnect,
+ OBJECT_OT_writing,
+ OBJECT_OT_particletrace,
+ OBJECT_OT_traceallparticles,
+ OBJECT_OT_curvegrow,
+ OBJECT_OT_reset,
+ OBJECT_OT_fcnoise,
+ OBJECT_OT_meshfollow,
+ OBJECT_OT_materialChango,
+ OBJECT_OT_clearColorblender
+ ]
+
+def register():
+ for c in classes:
+ bpy.utils.register_class(c)
+ bpy.types.WindowManager.curve_tracer = bpy.props.PointerProperty(type=TracerProperties)
+ bpy.types.WindowManager.btrace_menu = bpy.props.PointerProperty(type=TracerPropertiesMenu, update=deselect_others)
+
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+ del bpy.types.WindowManager.curve_tracer
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/btrace/bTrace.py b/release/scripts/addons_contrib/btrace/bTrace.py
new file mode 100644
index 0000000..8fd7447
--- /dev/null
+++ b/release/scripts/addons_contrib/btrace/bTrace.py
@@ -0,0 +1,1565 @@
+#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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#END GPL LICENCE BLOCK
+
+bl_info = {
+ "name": "Btrace",
+ "author": "liero, crazycourier, Atom, Meta-Androcto, MacKracken",
+ "version": (1, 1, ),
+ "blender": (2, 62, 0),
+ "location": "View3D > Tools",
+ "description": "Tools for converting/animating objects/particles into curves",
+ "warning": "Still under development, bug reports appreciated",
+ "wiki_url": "",
+ "tracker_url": "http://projects.blender.org/tracker/?func=detail&atid=468&aid=29563&group_id=153",
+ "category": "Add Curve"
+ }
+
+#### TO DO LIST ####
+### [ ] Add more options to curve radius/modulation plus cyclic/connect curve option
+
+import bpy
+import selection_utils
+from bpy.props import FloatProperty, EnumProperty, IntProperty, BoolProperty, FloatVectorProperty
+
+
+def deselect_others(ob, context):
+ """For tool menu select, deselects others if one selected"""
+ selected = addTracerObjectPanel.selected
+ ob[selected] = False
+ keys = [key for key in ob.keys() if ob[key]] # all the True keys
+ if len(keys) <= 0:
+ ob[selected] = True # reselect
+ return None
+ for key in keys:
+ addTracerObjectPanel.selected = key
+ ob[key] = True
+
+
+# Class for properties panel
+class TracerPropertiesMenu(bpy.types.PropertyGroup):
+ """Toolbar show/hide booleans for tool options"""
+ tool_objectTrace = BoolProperty(name="Object Trace", default=False, description="Trace selected mesh object with a curve", update=deselect_others)
+ tool_objectsConnect = BoolProperty(name="Objects Connect", default=False, description="Connect objects with a curve controlled by hooks", update=deselect_others)
+ tool_particleTrace = BoolProperty(name="Particle Trace", default=False, description="Trace particle path with a curve", update=deselect_others)
+ tool_meshFollow = BoolProperty(name="Mesh Follow", default=False, description="Follow selection items on animated mesh object", update=deselect_others)
+ tool_particleConnect = BoolProperty(name="Particle Connect", default=False, description="Connect particles with a curves and animated over particle lifetime", update=deselect_others)
+ tool_growCurve = BoolProperty(name="Grow Curve", default=False, description="Animate curve bevel over time by keyframing points radius", update=deselect_others)
+ tool_handwrite = BoolProperty(name="Handwriting", default=False, description="Create and Animate curve using the grease pencil", update=deselect_others)
+ tool_fcurve = BoolProperty(name="F-Curve Noise", default=False, description="Add F-Curve noise to selected objects", update=deselect_others)
+ tool_colorblender = BoolProperty(name="Color Blender", default=False, description="Add F-Curve noise to selected objects", update=deselect_others)
+
+
+# Class to define properties
+class TracerProperties(bpy.types.PropertyGroup):
+ """Options for tools"""
+ curve_spline = EnumProperty(name="Spline", items=(("POLY", "Poly", "Use Poly spline type"), ("NURBS", "Nurbs", "Use Nurbs spline type"), ("BEZIER", "Bezier", "Use Bezier spline type")), description="Choose which type of spline to use when curve is created", default="BEZIER")
+ curve_handle = EnumProperty(name="Handle", items=(("ALIGNED", "Aligned", "Use Aligned Handle Type"), ("AUTOMATIC", "Automatic", "Use Auto Handle Type"), ("FREE_ALIGN", "Free Align", "Use Free Handle Type"), ("VECTOR", "Vector", "Use Vector Handle Type")), description="Choose which type of handle to use when curve is created", default="VECTOR")
+ curve_resolution = IntProperty(name="Bevel Resolution", min=1, max=32, default=4, description="Adjust the Bevel resolution")
+ curve_depth = FloatProperty(name="Bevel Depth", min=0.0, max=100.0, default=0.1, description="Adjust the Bevel depth")
+ curve_u = IntProperty(name="Resolution U", min=0, max=64, default=12, description="Adjust the Surface resolution")
+ curve_join = BoolProperty(name="Join Curves", default=False, description="Join all the curves after they have been created")
+ curve_smooth = BoolProperty(name="Smooth", default=True, description="Render curve smooth")
+ # Option to Duplicate Mesh
+ object_duplicate = BoolProperty(name="Apply to Copy", default=False, description="Apply curve to a copy of object")
+ # Distort Mesh options
+ distort_modscale = IntProperty(name="Modulation Scale", min=0, max=50, default=2, description="Add a scale to modulate the curve at random points, set to 0 to disable")
+ distort_noise = FloatProperty(name="Mesh Noise", min=0.0, max=50.0, default=0.00, description="Adjust noise added to mesh before adding curve")
+ # Particle Options
+ particle_step = IntProperty(name="Step Size", min=1, max=50, default=5, description="Sample one every this number of frames")
+ particle_auto = BoolProperty(name='Auto Frame Range', default=True, description='Calculate Frame Range from particles life')
+ particle_f_start = IntProperty(name='Start Frame', min=1, max=5000, default=1, description='Start frame')
+ particle_f_end = IntProperty(name='End Frame', min=1, max=5000, default=250, description='End frame')
+ # F-Curve Modifier Properties
+ fcnoise_rot = BoolProperty(name="Rotation", default=False, description="Affect Rotation")
+ fcnoise_loc = BoolProperty(name="Location", default=True, description="Affect Location")
+ fcnoise_scale = BoolProperty(name="Scale", default=False, description="Affect Scale")
+ fcnoise_amp = IntProperty(name="Amp", min=1, max=500, default=5, description="Adjust the amplitude")
+ fcnoise_timescale = FloatProperty(name="Time Scale", min=1, max=500, default=50, description="Adjust the time scale")
+ fcnoise_key = BoolProperty(name="Add Keyframe", default=True, description="Keyframe is needed for tool, this adds a LocRotScale keyframe")
+ show_curve_settings = BoolProperty(name="Curve Settings", default=False, description="Change the curve settings for the created curve")
+ material_settings = BoolProperty(name="Material Settings", default=False, description="Change the material settings for the created curve")
+ particle_settings = BoolProperty(name="Particle Settings", default=False, description="Show the settings for the created curve")
+ animation_settings = BoolProperty(name="Animation Settings", default=False, description="Show the settings for the Animations")
+ distort_curve = BoolProperty(name="Add Distortion", default=False, description="Set options to distort the final curve")
+ connect_noise = BoolProperty(name="F-Curve Noise", default=False, description="Adds F-Curve Noise Modifier to selected objects")
+ settings_objectTrace = BoolProperty(name="Object Trace Settings", default=False, description="Trace selected mesh object with a curve")
+ settings_objectsConnect = BoolProperty(name="Objects Connect Settings", default=False, description="Connect objects with a curve controlled by hooks")
+ settings_objectTrace = BoolProperty(name="Object Trace Settings", default=False, description="Trace selected mesh object with a curve")
+ respect_order = BoolProperty(name="Order", default=False, description="Remember order objects were selected")
+ settings_particleTrace = BoolProperty(name="Particle Trace Settings", default=False, description="Trace particle path with a curve")
+ settings_particleConnect = BoolProperty(name="Particle Connect Settings", default=False, description="Connect particles with a curves and animated over particle lifetime")
+ settings_growCurve = BoolProperty(name="Grow Curve Settings", default=False, description="Animate curve bevel over time by keyframing points radius")
+ settings_fcurve = BoolProperty(name="F-Curve Settings", default=False, description="F-Curve Settings")
+ settings_toggle = BoolProperty(name="Settings", default=False, description="Toggle Settings")
+ # Animation Options
+ anim_auto = BoolProperty(name='Auto Frame Range', default=True, description='Automatically calculate Frame Range')
+ anim_f_start = IntProperty(name='Start', min=1, max=2500, default=1, description='Start frame / Hidden object')
+ anim_length = IntProperty(name='Duration', min=1, soft_max=1000, max=2500, default=100, description='Animation Length')
+ anim_f_fade = IntProperty(name='Fade After', min=0, soft_max=250, max=2500, default=10, description='Fade after this frames / Zero means no fade')
+ anim_delay = IntProperty(name='Grow', min=0, max=50, default=5, description='Frames it takes a point to grow')
+ anim_tails = BoolProperty(name='Tails on endpoints', default=True, description='Set radius to zero for open splines endpoints')
+ anim_keepr = BoolProperty(name='Keep Radius', default=True, description='Try to keep radius data from original curve')
+ animate = BoolProperty(name="Animate Result", default=False, description='Animate the final curve objects')
+ # Convert to Curve options
+ convert_conti = BoolProperty(name='Continuous', default=True, description='Create a continuous curve using verts from mesh')
+ convert_everyedge = BoolProperty(name='Every Edge', default=False, description='Create a curve from all verts in a mesh')
+ convert_edgetype = EnumProperty(name="Edge Type for Curves",
+ items=(("CONTI", "Continuous", "Create a continuous curve using verts from mesh"), ("EDGEALL", "All Edges", "Create a curve from every edge in a mesh")),
+ description="Choose which type of spline to use when curve is created", default="CONTI")
+ convert_joinbefore = BoolProperty(name="Join objects before convert", default=False, description='Join all selected mesh to one object before converting to mesh')
+ # Mesh Follow Options
+ fol_edge_select = BoolProperty(name='Edge', default=False, description='Grow from edges')
+ fol_vert_select = BoolProperty(name='Vertex', default=False, description='Grow from verts')
+ fol_face_select = BoolProperty(name='Face', default=True, description='Grow from faces')
+ fol_mesh_type = EnumProperty(name='Mesh type', default='VERTS', description='Mesh feature to draw cruves from', items=(
+ ("VERTS", "Verts", "Draw from Verts"), ("EDGES", "Edges", "Draw from Edges"), ("FACES", "Faces", "Draw from Faces"), ("OBJECT", "Object", "Draw from Object origin")))
+ fol_start_frame = IntProperty(name="Start Frame", min=1, max=2500, default=1, description="Start frame for range to trace")
+ fol_end_frame = IntProperty(name="End Frame", min=1, max=2500, default=250, description="End frame for range to trace")
+ fol_perc_verts = FloatProperty(name="Reduce selection by", min=0.001, max=1.000, default=0.5, description="percentage of total verts to trace")
+ fol_sel_option = EnumProperty(name="Selection type", description="Choose which objects to follow", default="RANDOM", items=(
+ ("RANDOM", "Random", "Follow Random items"), ("CUSTOM", "Custom Select", "Follow selected items"), ("ALL", "All", "Follow all items")))
+ trace_mat_color = FloatVectorProperty(name="Material Color", description="Choose material color", min=0, max=1, default=(0.0,0.3,0.6), subtype="COLOR")
+ trace_mat_random = BoolProperty(name="Random Color", default=False, description='Make the material colors random')
+
+ # Material custom Properties properties
+ mat_simple_adv_toggle = EnumProperty(name="Material Options", items=(("SIMPLE", "Simple", "Show Simple Material Options"), ("ADVANCED", "Advanced", "Show Advanced Material Options")), description="Choose which Material Options to show", default="SIMPLE")
+ mat_run_color_blender = BoolProperty(name="Run Color Blender", default=False, description="Generate colors from a color scheme")
+ mmColors = bpy.props.EnumProperty(
+ items=(("RANDOM", "Random", "Use random colors"),
+ ("CUSTOM", "Custom", "Use custom colors"),
+ ("BW", "Black/White", "Use Black and White"),
+ ("BRIGHT", "Bright Colors", "Use Bright colors"),
+ ("EARTH", "Earth", "Use Earth colors"),
+ ("GREENBLUE", "Green to Blue", "Use Green to Blue colors")),
+ description="Choose which type of colors the materials uses",
+ default="BRIGHT",
+ name="Define a color palette")
+ # Custom property for how many keyframes to skip
+ mmSkip = bpy.props.IntProperty(name="frames", min=1, max=500, default=20, description="Number of frames between each keyframes")
+ # Custom property to enable/disable random order for the
+ mmBoolRandom = bpy.props.BoolProperty(name="Random Order", default=False, description="Randomize the order of the colors")
+ # Custom Color properties
+ mmColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.8, 0.8), description="Custom Color 1", subtype="COLOR")
+ mmColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.8, 0.3), description="Custom Color 2", subtype="COLOR")
+ mmColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.5, 0.6), description="Custom Color 3", subtype="COLOR")
+ mmColor4 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.2, 0.8, 0.289), description="Custom Color 4", subtype="COLOR")
+ mmColor5 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0, 0.348, 0.8), description="Custom Color 5", subtype="COLOR")
+ mmColor6 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.4, 0.67, 0.8), description="Custom Color 6", subtype="COLOR")
+ mmColor7 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.66, 0.88, 0.8), description="Custom Color 7", subtype="COLOR")
+ mmColor8 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.8, 0.38, 0.22), description="Custom Color 8", subtype="COLOR")
+ # BW Color properties
+ bwColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.0,0.0,0.0), description="Black/White Color 1", subtype="COLOR")
+ bwColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0,1.0,1.0), description="Black/White Color 2", subtype="COLOR")
+ # Bright Color properties
+ brightColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0, 0.0, 0.75), description="Bright Color 1", subtype="COLOR")
+ brightColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.0,1.0,1.0), description="Bright Color 2", subtype="COLOR")
+ brightColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.0,1.0,0.0), description="Bright Color 3", subtype="COLOR")
+ brightColor4 = bpy.props.FloatVectorProperty(min=0, max=1, default=(1.0,1.0,0.0), description="Bright Color 4", subtype="COLOR")
+ # Earth Color Properties
+ earthColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.068, 0.019, 0.014), description="Earth Color 1", subtype="COLOR")
+ earthColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.089, 0.060, 0.047), description="Earth Color 2", subtype="COLOR")
+ earthColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.188, 0.168, 0.066), description="Earth Color 3", subtype="COLOR")
+ earthColor4 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.445, 0.296, 0.065), description="Earth Color 4", subtype="COLOR")
+ earthColor5 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.745, 0.332, 0.065), description="Earth Color 5", subtype="COLOR")
+ # Green to Blue Color properties
+ greenblueColor1 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.296, 0.445, 0.074), description="Green/Blue Color 1", subtype="COLOR")
+ greenblueColor2 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.651, 1.0, 0.223), description="Green/Blue Color 2", subtype="COLOR")
+ greenblueColor3 = bpy.props.FloatVectorProperty(min=0, max=1, default=(0.037, 0.047, 0.084), description="Green/Blue Color 3", subtype="COLOR")
+
+
+############################
+## Draw Brush panel in Toolbar
+############################
+class addTracerObjectPanel(bpy.types.Panel):
+ bl_label = "Btrace: Panel"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_context = 'objectmode'
+ selected = "tool_objectTrace"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ Btrace = bpy.context.window_manager.curve_tracer
+ btracemenu = props = bpy.context.window_manager.btrace_menu
+ obj = bpy.context.object
+
+
+ ############################
+ ## Color Blender Panel options
+ ############################
+ def color_blender():
+ """Buttons for Color Blender"""
+ row = box.row()
+ row.label("Color palette")
+ row.prop(Btrace, 'mmColors', text="")
+ # Show Custom Colors if selected
+ if Btrace.mmColors == 'CUSTOM':
+ row = box.row(align=True)
+ row.prop(Btrace, 'mmColor1', text="")
+ row.prop(Btrace, 'mmColor2', text="")
+ row.prop(Btrace, 'mmColor3', text="")
+ row.prop(Btrace, 'mmColor4', text="")
+ row.prop(Btrace, 'mmColor5', text="")
+ row.prop(Btrace, 'mmColor6', text="")
+ row.prop(Btrace, 'mmColor7', text="")
+ row.prop(Btrace, 'mmColor8', text="")
+ # Show Earth Colors
+ elif Btrace.mmColors == 'BW':
+ row = box.row(align=True)
+ row.prop(Btrace, 'bwColor1', text="")
+ row.prop(Btrace, 'bwColor2', text="")
+ # Show Earth Colors
+ elif Btrace.mmColors == 'BRIGHT':
+ row = box.row(align=True)
+ row.prop(Btrace, 'brightColor1', text="")
+ row.prop(Btrace, 'brightColor2', text="")
+ row.prop(Btrace, 'brightColor3', text="")
+ row.prop(Btrace, 'brightColor4', text="")
+ # Show Earth Colors
+ elif Btrace.mmColors == 'EARTH':
+ row = box.row(align=True)
+ row.prop(Btrace, 'earthColor1', text="")
+ row.prop(Btrace, 'earthColor2', text="")
+ row.prop(Btrace, 'earthColor3', text="")
+ row.prop(Btrace, 'earthColor4', text="")
+ row.prop(Btrace, 'earthColor5', text="")
+ # Show Earth Colors
+ elif Btrace.mmColors == 'GREENBLUE':
+ row = box.row(align=True)
+ row.prop(Btrace, 'greenblueColor1', text="")
+ row.prop(Btrace, 'greenblueColor2', text="")
+ row.prop(Btrace, 'greenblueColor3', text="")
+ elif Btrace.mmColors == 'RANDOM':
+ row = box.row()
+
+ ############################
+ ## Curve Panel options
+ ############################
+ def curve_settings():
+ """Button for curve options"""
+ row = self.layout.row()
+ row = box.row(align=True)
+
+ row.prop(Btrace, 'show_curve_settings', icon='CURVE_BEZCURVE', text="Curve Settings")
+ row.prop(Btrace, 'material_settings', icon='MATERIAL_DATA', text="Material Settings")
+ if Btrace.material_settings:
+ row = box.row()
+ row.label(text="Material Settings", icon='COLOR')
+ row = box.row()
+ row.prop(Btrace, "trace_mat_random")
+ if not Btrace.trace_mat_random:
+ row = box.row()
+ row.prop(Btrace, "trace_mat_color", text="")
+ else:
+ row.prop(Btrace, "mat_run_color_blender")
+ if Btrace.mat_run_color_blender:
+ row = box.row()
+ row.operator("object.colorblenderclear", text="Reset Material Keyframes", icon="KEY_DEHLT")
+ row.prop(Btrace, 'mmSkip', text="Keyframe every")
+
+ color_blender()
+ row = box.row()
+ if Btrace.show_curve_settings:
+ #if or btracemenu.tool_handwrite:
+ if len(bpy.context.selected_objects) > 0 and obj.type == 'CURVE': # selected curve options
+ col = box.column(align=True)
+ col.label(text="Edit Curves for", icon='CURVE_BEZCURVE')
+ col.label(text="Selected Curve Bevel Options")
+ row = col.row(align=True)
+ row.prop(obj.data, 'bevel_depth', text="Depth")
+ row.prop(obj.data, 'bevel_resolution', text="Resolution")
+ row = col.row(align=True)
+ row.prop(obj.data, 'resolution_u')
+ else: # For new curve
+ box.label(text="New Curve Settings", icon='CURVE_BEZCURVE')
+ box.prop(Btrace, "curve_spline")
+ box.prop(Btrace, "curve_handle")
+ box.label(text="Bevel Options")
+ col = box.column(align=True)
+ row = col.row(align=True)
+ row.prop(Btrace, "curve_depth", text="Depth")
+ row.prop(Btrace, "curve_resolution", text="Resolution")
+ row = col.row(align=True)
+ row.prop(Btrace, "curve_u")
+
+ ############################
+ ## Grow Animation Panel options
+ ############################
+ def add_grow():
+ """Button for grow animation option"""
+ row = box.row()
+ row.label(text="Animate Final Curve")
+ row = box.row()
+ row.prop(Btrace, "animate", text="Add Grow Curve Animation", icon="META_BALL")
+ row.label("")
+ if Btrace.animate:
+ box.label(text='Frame Animation Settings:', icon="META_BALL")
+ col = box.column(align=True)
+ col.prop(Btrace, 'anim_auto')
+ if not Btrace.anim_auto:
+ row = col.row(align=True)
+ row.prop(Btrace, 'anim_f_start')
+ row.prop(Btrace, 'anim_length')
+ row = col.row(align=True)
+ row.prop(Btrace, 'anim_delay')
+ row.prop(Btrace, 'anim_f_fade')
+
+ box.label(text='Additional Settings')
+ row = box.row()
+ row.prop(Btrace, 'anim_tails')
+ row.prop(Btrace, 'anim_keepr')
+
+ ##################################################################
+ ## Start Btrace Panel
+ ##################################################################
+ col = self.layout.column(align=True)
+ #col.label(text="Trace Tools")
+ row = col.row()
+ row.prop(btracemenu, "tool_objectTrace", text="Ojbect Trace", icon="FORCE_MAGNETIC")
+ row.prop(btracemenu, "tool_objectsConnect", text="Object Connect", icon="OUTLINER_OB_EMPTY")
+ row = col.row()
+ row.prop(btracemenu, "tool_meshFollow", text="Mesh Follow", icon="DRIVER")
+ row.prop(btracemenu, "tool_handwrite", text="Handwriting", icon='BRUSH_DATA')
+ row = col.row()
+ row.prop(btracemenu, "tool_particleTrace", icon="PARTICLES", text="Particle Trace")
+ row.prop(btracemenu, "tool_particleConnect", icon="MOD_PARTICLES", text="Particle Connect")
+ row = layout.row()
+ col = layout.column(align=True)
+ row = col.row()
+ row.prop(btracemenu, "tool_growCurve", icon="META_BALL", text="Grow Animation")
+ row.prop(btracemenu, "tool_fcurve", text="Fcurve Noise", icon='RNDCURVE')
+ row = col.row()
+ row.prop(btracemenu, "tool_colorblender", text="Color Blender", icon="COLOR")
+ row.label(text="")
+ row = layout.row()
+
+ ##########################
+ ## Start Object Tools
+ ##########################
+ sel = bpy.context.selected_objects
+ ############################
+ ### Object Trace
+ ############################
+ if btracemenu.tool_objectTrace:
+ row = layout.row()
+ row.label(text=" Trace Tool:", icon="FORCE_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="Object Trace", icon="FORCE_MAGNETIC")
+ row.operator("object.btobjecttrace", text="Run!", icon="PLAY")
+ row = box.row()
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ myselected = "Selected %d" % len(bpy.context.selected_objects)
+ row.label(text=myselected)
+ if Btrace.settings_toggle:
+ row = box.row()
+ row.label(text='Edge Draw Method')
+ row = box.row(align=True)
+ row.prop(Btrace, 'convert_edgetype')
+ box.prop(Btrace, "object_duplicate")
+ if len(sel) > 1:
+ box.prop(Btrace, 'convert_joinbefore')
+ else:
+ Btrace.convert_joinbefore = False
+ row = box.row()
+ row.prop(Btrace, "distort_curve")
+ if Btrace.distort_curve:
+ col = box.column(align=True)
+ col.prop(Btrace, "distort_modscale")
+ col.prop(Btrace, "distort_noise")
+ row = box.row()
+ curve_settings() # Show Curve/material settings
+ add_grow() # Grow settings here
+
+ ############################
+ ### Objects Connect
+ ############################
+ if btracemenu.tool_objectsConnect:
+ row = layout.row()
+ row.label(text=" Trace Tool:", icon="FORCE_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="Objects Connect", icon="OUTLINER_OB_EMPTY")
+ row.operator("object.btobjectsconnect", text="Run!", icon="PLAY")
+ row = box.row()
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ row.label(text="")
+ if Btrace.settings_toggle:
+ row = box.row()
+ row.prop(Btrace, "respect_order", text="Selection Options")
+ if Btrace.respect_order:
+ box.operator("object.select_order", text="Click to start order selection", icon='UV_SYNC_SELECT')
+ row = box.row()
+ row.prop(Btrace, "connect_noise", text="Add F-Curve Noise")
+ if Btrace.connect_noise:
+ row = box.row()
+ row.label(text="F-Curve Noise", icon='RNDCURVE')
+ row = box.row(align=True)
+ row.prop(Btrace, "fcnoise_rot")
+ row.prop(Btrace, "fcnoise_loc")
+ row.prop(Btrace, "fcnoise_scale")
+ col = box.column(align=True)
+ col.prop(Btrace, "fcnoise_amp")
+ col.prop(Btrace, "fcnoise_timescale")
+ box.prop(Btrace, "fcnoise_key")
+ curve_settings() # Show Curve/material settings
+ add_grow() # Grow settings here
+
+ ############################
+ ### Mesh Follow
+ ############################
+ if btracemenu.tool_meshFollow:
+ row = layout.row()
+ row.label(text=" Trace Tool:", icon="FORCE_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="Mesh Follow", icon="DRIVER")
+ row.operator("object.btmeshfollow", text="Run!", icon="PLAY")
+ row = box.row()
+ if Btrace.fol_mesh_type == 'OBJECT':
+ a, b = "Trace Object", "SNAP_VOLUME"
+ if Btrace.fol_mesh_type == 'VERTS':
+ a, b = "Trace Verts", "SNAP_VERTEX"
+ if Btrace.fol_mesh_type == 'EDGES':
+ a, b = "Trace Edges", "SNAP_EDGE"
+ if Btrace.fol_mesh_type == 'FACES':
+ a, b = "Trace Faces", "SNAP_FACE"
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ row.label(text=a, icon=b)
+ if Btrace.settings_toggle:
+ col = box.column(align=True)
+ row = col.row(align=True)
+ row.prop(Btrace, "fol_mesh_type", expand=True)
+ row = col.row(align=True)
+ if Btrace.fol_mesh_type != 'OBJECT':
+ row.prop(Btrace, "fol_sel_option", expand=True)
+ row = box.row()
+ if Btrace.fol_sel_option == 'RANDOM':
+ row.label("Random Select of Total")
+ row.prop(Btrace, "fol_perc_verts", text="%")
+ if Btrace.fol_sel_option == 'CUSTOM':
+ row.label("Choose selection in Edit Mode")
+ if Btrace.fol_sel_option == 'ALL':
+ row.label("Select All items")
+ col = box.column(align=True)
+ col.label("Time Options", icon="TIME")
+ col.prop(Btrace, "particle_step")
+ row = col.row(align=True)
+ row.prop(Btrace, "fol_start_frame")
+ row.prop(Btrace, "fol_end_frame")
+ curve_settings() # Show Curve/material settings
+ add_grow() # Grow settings here
+
+ ############################
+ ### Handwriting Tools
+ ############################
+ if btracemenu.tool_handwrite:
+ row = layout.row()
+ row.label(text=" Trace Tool:", icon="FORCE_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text='Handwriting', icon='BRUSH_DATA')
+ row.operator("curve.btwriting", text="Run!", icon='PLAY')
+ row = box.row()
+ row = box.row()
+ row.label(text='Grease Pencil Writing Tools')
+ col = box.column(align=True)
+ row = col.row(align=True)
+ row.operator("gpencil.draw", text="Draw", icon='BRUSH_DATA').mode = 'DRAW'
+ row.operator("gpencil.draw", text="Poly", icon='VPAINT_HLT').mode = 'DRAW_POLY'
+ row = col.row(align=True)
+ row.operator("gpencil.draw", text="Line", icon='ZOOMOUT').mode = 'DRAW_STRAIGHT'
+ row.operator("gpencil.draw", text="Erase", icon='TPAINT_HLT').mode = 'ERASER'
+ row = box.row()
+ row.operator("gpencil.data_unlink", text="Delete Grease Pencil Layer", icon="CANCEL")
+ row = box.row()
+ curve_settings() # Show Curve/material settings
+ add_grow() # Grow settings here
+
+ ############################
+ ### Particle Trace
+ ############################
+ if btracemenu.tool_particleTrace:
+ row = layout.row()
+ row.label(text=" Trace Tool:", icon="FORCE_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="Particle Trace", icon="PARTICLES")
+ row.operator("particles.particletrace", text="Run!", icon="PLAY")
+ row = box.row()
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ row.label(text="")
+ if Btrace.settings_toggle:
+ box.prop(Btrace, "particle_step")
+ row = box.row()
+ row.prop(Btrace, "curve_join")
+ curve_settings() # Show Curve/material settings
+ add_grow() # Grow settings here
+
+ ############################
+ ### Connect Particles
+ ############################
+ if btracemenu.tool_particleConnect:
+ row = layout.row()
+ row.label(text=" Trace Tool:", icon="FORCE_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text='Particle Connect', icon='MOD_PARTICLES')
+ row.operator("particles.connect", icon="PLAY", text='Run!')
+ row = box.row()
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ row.label(text="")
+ if Btrace.settings_toggle:
+ box.prop(Btrace, "particle_step")
+ row = box.row()
+ row.prop(Btrace, 'particle_auto')
+ if not Btrace.particle_auto:
+ row = box.row(align=True)
+ row.prop(Btrace, 'particle_f_start')
+ row.prop(Btrace, 'particle_f_end')
+ curve_settings() # Show Curve/material settings
+ add_grow() # Grow settings here
+
+ #######################
+ #### Grow Animation ####
+ #######################
+ if btracemenu.tool_growCurve:
+ row = layout.row()
+ row.label(text=" Curve Tool:", icon="OUTLINER_OB_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="Grow Curve", icon="META_BALL")
+ row.operator('curve.btgrow', text='Run!', icon='PLAY')
+ row = box.row()
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ row.operator('object.btreset', icon='KEY_DEHLT')
+ if Btrace.settings_toggle:
+ box.label(text='Frame Animation Settings:')
+ col = box.column(align=True)
+ col.prop(Btrace, 'anim_auto')
+ if not Btrace.anim_auto:
+ row = col.row(align=True)
+ row.prop(Btrace, 'anim_f_start')
+ row.prop(Btrace, 'anim_length')
+ row = col.row(align=True)
+ row.prop(Btrace, 'anim_delay')
+ row.prop(Btrace, 'anim_f_fade')
+
+ box.label(text='Additional Settings')
+ row = box.row()
+ row.prop(Btrace, 'anim_tails')
+ row.prop(Btrace, 'anim_keepr')
+
+ #######################
+ #### F-Curve Noise Curve ####
+ #######################
+ if btracemenu.tool_fcurve:
+ row = layout.row()
+ row.label(text=" Curve Tool:", icon="OUTLINER_OB_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="F-Curve Noise", icon='RNDCURVE')
+ row.operator("object.btfcnoise", icon='PLAY', text="Run!")
+ row = box.row()
+ row.prop(Btrace, "settings_toggle", icon='MODIFIER', text='Settings')
+ row.operator('object.btreset', icon='KEY_DEHLT')
+ if Btrace.settings_toggle:
+ row = box.row(align=True)
+ row.prop(Btrace, "fcnoise_rot")
+ row.prop(Btrace, "fcnoise_loc")
+ row.prop(Btrace, "fcnoise_scale")
+ col = box.column(align=True)
+ col.prop(Btrace, "fcnoise_amp")
+ col.prop(Btrace, "fcnoise_timescale")
+ box.prop(Btrace, "fcnoise_key")
+
+ #######################
+ #### Color Blender ####
+ #######################
+ if btracemenu.tool_colorblender:
+ row = layout.row()
+ row.label(text=" Curve/Object Tool:", icon="OUTLINER_OB_CURVE")
+ box = self.layout.box()
+ row = box.row()
+ row.label(text="Color Blender", icon="COLOR")
+ row.operator("object.colorblender", icon='PLAY', text="Run!")
+ row = box.row()
+ row.operator("object.colorblenderclear", text="Reset Keyframes", icon="KEY_DEHLT")
+ row.prop(Btrace, 'mmSkip', text="Keyframe every")
+ color_blender()
+
+###### END PANEL ##############
+###############################
+
+
+################## ################## ################## ############
+## Object Trace
+## creates a curve with a modulated radius connecting points of a mesh
+################## ################## ################## ############
+
+class OBJECT_OT_objecttrace(bpy.types.Operator):
+ bl_idname = "object.btobjecttrace"
+ bl_label = "Btrace: Object Trace"
+ bl_description = "Trace selected mesh object with a curve with the option to animate"
+ bl_options = {'REGISTER', 'UNDO'}
+
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type in {'MESH', 'FONT'})
+
+ def invoke(self, context, event):
+ import bpy
+
+ # Run through each selected object and convert to to a curved object
+ brushObj = bpy.context.selected_objects
+ Btrace = bpy.context.window_manager.curve_tracer
+ # Duplicate Mesh
+ if Btrace.object_duplicate:
+ bpy.ops.object.duplicate_move()
+ brushObj = bpy.context.selected_objects
+ # Join Mesh
+ if Btrace.convert_joinbefore:
+ if len(brushObj) > 1: # Only run if multiple objects selected
+ bpy.ops.object.join()
+ brushObj = bpy.context.selected_objects
+
+ for i in brushObj:
+ bpy.context.scene.objects.active = i
+ if i and i.type != 'CURVE':
+ bpy.ops.object.btconvertcurve()
+ addtracemat(bpy.context.object.data)
+ if Btrace.animate:
+ bpy.ops.curve.btgrow()
+ return {'FINISHED'}
+
+
+################## ################## ################## ############
+## Objects Connect
+## connect selected objects with a curve + hooks to each node
+## possible handle types: 'FREE' 'AUTO' 'VECTOR' 'ALIGNED'
+################## ################## ################## ############
+
+class OBJECT_OT_objectconnect(bpy.types.Operator):
+ bl_idname = "object.btobjectsconnect"
+ bl_label = "Btrace: Objects Connect"
+ bl_description = "Connect selected objects with a curve and add hooks to each node"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return len(bpy.context.selected_objects) > 1
+
+ def invoke(self, context, event):
+ import bpy, selection_utils
+ list = []
+ Btrace = bpy.context.window_manager.curve_tracer
+ curve_handle = Btrace.curve_handle
+ if curve_handle == 'AUTOMATIC': # hackish because of naming conflict in api
+ curve_handle = 'AUTO'
+ # Check if Btrace group exists, if not create
+ bgroup = bpy.data.groups.keys()
+ if 'Btrace' not in bgroup:
+ bpy.ops.group.create(name="Btrace")
+ # check if noise
+ if Btrace.connect_noise:
+ bpy.ops.object.btfcnoise()
+ # check if respect order is checked, create list of objects
+ if Btrace.respect_order == True:
+ selobnames = selection_utils.selected
+ obnames = []
+ for ob in selobnames:
+ obnames.append(bpy.data.objects[ob])
+ else:
+ obnames = bpy.context.selected_objects # No selection order
+
+ for a in obnames:
+ list.append(a)
+ a.select = False
+
+ # trace the origins
+ tracer = bpy.data.curves.new('tracer', 'CURVE')
+ tracer.dimensions = '3D'
+ spline = tracer.splines.new('BEZIER')
+ spline.bezier_points.add(len(list) - 1)
+ curve = bpy.data.objects.new('curve', tracer)
+ bpy.context.scene.objects.link(curve)
+
+ # render ready curve
+ tracer.resolution_u = Btrace.curve_u
+ tracer.bevel_resolution = Btrace.curve_resolution # Set bevel resolution from Panel options
+ tracer.fill_mode = 'FULL'
+ tracer.bevel_depth = Btrace.curve_depth # Set bevel depth from Panel options
+
+ # move nodes to objects
+ for i in range(len(list)):
+ p = spline.bezier_points[i]
+ p.co = list[i].location
+ p.handle_right_type = curve_handle
+ p.handle_left_type = curve_handle
+
+ bpy.context.scene.objects.active = curve
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # place hooks
+ for i in range(len(list)):
+ list[i].select = True
+ curve.data.splines[0].bezier_points[i].select_control_point = True
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.object.hook_add_selob()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ curve.data.splines[0].bezier_points[i].select_control_point = False
+ list[i].select = False
+
+ bpy.ops.object.select_all(action='DESELECT')
+ curve.select = True # selected curve after it's created
+ addtracemat(bpy.context.object.data) # Add material
+ if Btrace.animate: # Add Curve Grow it?
+ bpy.ops.curve.btgrow()
+ bpy.ops.object.group_link(group="Btrace") # add to Btrace group
+ if Btrace.animate:
+ bpy.ops.curve.btgrow() # Add grow curve
+ return {'FINISHED'}
+
+
+################## ################## ################## ############
+## Particle Trace
+## creates a curve from each particle of a system
+################## ################## ################## ############
+def curvetracer(curvename, splinename):
+ Btrace = bpy.context.window_manager.curve_tracer
+ tracer = bpy.data.curves.new(splinename, 'CURVE')
+ tracer.dimensions = '3D'
+ curve = bpy.data.objects.new(curvename, tracer)
+ bpy.context.scene.objects.link(curve)
+ try:
+ tracer.fill_mode = 'FULL'
+ except:
+ tracer.use_fill_front = tracer.use_fill_back = False
+ tracer.bevel_resolution = Btrace.curve_resolution
+ tracer.bevel_depth = Btrace.curve_depth
+ tracer.resolution_u = Btrace.curve_u
+ return tracer, curve
+
+
+class OBJECT_OT_particletrace(bpy.types.Operator):
+ bl_idname = "particles.particletrace"
+ bl_label = "Btrace: Particle Trace"
+ bl_description = "Creates a curve from each particle of a system. Keeping particle amount under 250 will make this run faster"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return (bpy.context.object and bpy.context.object.particle_systems)
+
+ def execute(self, context):
+ Btrace = bpy.context.window_manager.curve_tracer
+ particle_step = Btrace.particle_step # step size in frames
+ obj = bpy.context.object
+ ps = obj.particle_systems.active
+ curvelist = []
+ curve_handle = Btrace.curve_handle
+ if curve_handle == 'AUTOMATIC': # hackish naming conflict
+ curve_handle = 'AUTO'
+ if curve_handle == 'FREE_ALIGN': # hackish naming conflict
+ curve_handle = 'FREE'
+
+ # Check if Btrace group exists, if not create
+ bgroup = bpy.data.groups.keys()
+ if 'Btrace' not in bgroup:
+ bpy.ops.group.create(name="Btrace")
+
+ if Btrace.curve_join:
+ tracer = curvetracer('Tracer', 'Splines')
+ for x in ps.particles:
+ if not Btrace.curve_join:
+ tracer = curvetracer('Tracer.000', 'Spline.000')
+ spline = tracer[0].splines.new('BEZIER')
+ spline.bezier_points.add((x.lifetime - 1) // particle_step) # add point to spline based on step size
+ for t in list(range(int(x.lifetime))):
+ bpy.context.scene.frame_set(t + x.birth_time)
+ if not t % particle_step:
+ p = spline.bezier_points[t // particle_step]
+ p.co = x.location
+ p.handle_right_type = curve_handle
+ p.handle_left_type = curve_handle
+ particlecurve = tracer[1]
+ curvelist.append(particlecurve)
+ # add to group
+ bpy.ops.object.select_all(action='DESELECT')
+ for curveobject in curvelist:
+ curveobject.select = True
+ bpy.context.scene.objects.active = curveobject
+ bpy.ops.object.group_link(group="Btrace")
+ addtracemat(curveobject.data) # Add material
+
+ if Btrace.animate:
+ bpy.ops.curve.btgrow() # Add grow curve
+
+ return {'FINISHED'}
+
+
+###########################################################################
+## Particle Connect
+## connect all particles in active system with a continuous animated curve
+###########################################################################
+
+class OBJECT_OT_traceallparticles(bpy.types.Operator):
+ bl_idname = 'particles.connect'
+ bl_label = 'Connect Particles'
+ bl_description = 'Create a continuous animated curve from particles in active system'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return (bpy.context.object and bpy.context.object.particle_systems)
+
+ def execute(self, context):
+
+ obj = bpy.context.object
+ ps = obj.particle_systems.active
+ set = ps.settings
+
+ # Grids distribution not supported
+ if set.distribution == 'GRID':
+ self.report({'INFO'},"Grid distribution mode for particles not supported.")
+ return{'FINISHED'}
+
+ Btrace = bpy.context.window_manager.curve_tracer
+ particle_f_start = Btrace.particle_f_start # Get frame start
+ particle_f_end = Btrace.particle_f_end # Get frame end
+ curve_handle = Btrace.curve_handle
+ if curve_handle == 'AUTOMATIC': # hackish because of naming conflict in api
+ curve_handle = 'AUTO'
+ if curve_handle == 'FREE_ALIGN':
+ curve_handle = 'FREE'
+ tracer = bpy.data.curves.new('Splines','CURVE') # define what kind of object to create
+ curve = bpy.data.objects.new('Tracer',tracer) # Create new object with settings listed above
+ bpy.context.scene.objects.link(curve) # Link newly created object to the scene
+ spline = tracer.splines.new('BEZIER') # add a new Bezier point in the new curve
+ spline.bezier_points.add(set.count-1)
+
+ tracer.dimensions = '3D'
+ tracer.resolution_u = Btrace.curve_u
+ tracer.bevel_resolution = Btrace.curve_resolution
+ tracer.fill_mode = 'FULL'
+ tracer.bevel_depth = Btrace.curve_depth
+
+ if Btrace.particle_auto:
+ f_start = int(set.frame_start)
+ f_end = int(set.frame_end + set.lifetime)
+ else:
+ if particle_f_end <= particle_f_start:
+ particle_f_end = particle_f_start + 1
+ f_start = particle_f_start
+ f_end = particle_f_end
+
+ for bFrames in range(f_start, f_end):
+ bpy.context.scene.frame_set(bFrames)
+ if not (bFrames-f_start) % Btrace.particle_step:
+ for bFrames in range(set.count):
+ if ps.particles[bFrames].alive_state != 'UNBORN':
+ e = bFrames
+ bp = spline.bezier_points[bFrames]
+ pt = ps.particles[e]
+ bp.co = pt.location
+ #bp.handle_left = pt.location
+ #bp.handle_right = pt.location
+ bp.handle_right_type = curve_handle
+ bp.handle_left_type = curve_handle
+ bp.keyframe_insert('co')
+ bp.keyframe_insert('handle_left')
+ bp.keyframe_insert('handle_right')
+ # Select new curve
+ bpy.ops.object.select_all(action='DESELECT')
+ curve.select = True
+ bpy.context.scene.objects.active = curve
+ addtracemat(curve.data) #Add material
+ if Btrace.animate:
+ bpy.ops.curve.btgrow()
+ return{'FINISHED'}
+
+################## ################## ################## ############
+## Writing Tool
+## Writes a curve by animating its point's radii
+##
+################## ################## ################## ############
+class OBJECT_OT_writing(bpy.types.Operator):
+ bl_idname = 'curve.btwriting'
+ bl_label = 'Write'
+ bl_description = 'Use Grease Pencil to write and convert to curves'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ # @classmethod ### Removed so panel still draws if nothing is selected
+ # def poll(cls, context):
+ # return (context.scene.grease_pencil or context.object.grease_pencil != None)
+
+ def execute(self, context):
+ Btrace = bpy.context.window_manager.curve_tracer
+ obj = bpy.context.object
+ gactive = bpy.context.active_object # set selected object before convert
+ bpy.ops.gpencil.convert(type='CURVE')
+ gactiveCurve = bpy.context.active_object # get curve after convert
+ # render ready curve
+ gactiveCurve.data.resolution_u = Btrace.curve_u
+ gactiveCurve.data.bevel_resolution = Btrace.curve_resolution # Set bevel resolution from Panel options
+ gactiveCurve.data.fill_mode = 'FULL'
+ gactiveCurve.data.bevel_depth = Btrace.curve_depth # Set bevel depth from Panel options
+
+ writeObj = bpy.context.selected_objects
+ if Btrace.animate:
+ for i in writeObj:
+ bpy.context.scene.objects.active = i
+ bpy.ops.curve.btgrow()
+ addtracemat(bpy.context.object.data) #Add material
+ else:
+ for i in writeObj:
+ bpy.context.scene.objects.active = i
+ addtracemat(bpy.context.object.data) #Add material
+
+ # Delete grease pencil strokes
+ bpy.context.scene.objects.active = gactive
+ bpy.ops.gpencil.data_unlink()
+ bpy.context.scene.objects.active = gactiveCurve
+ # Smooth object
+ bpy.ops.object.shade_smooth()
+ # Return to first frame
+ bpy.context.scene.frame_set(Btrace.anim_f_start)
+
+ return{'FINISHED'}
+
+################## ################## ################## ############
+## Create Curve
+## Convert mesh to curve using either Continuous, All Edges, or Sharp Edges
+## Option to create noise
+################## ################## ################## ############
+
+class OBJECT_OT_convertcurve(bpy.types.Operator):
+ bl_idname = "object.btconvertcurve"
+ bl_label = "Btrace: Create Curve"
+ bl_description = "Convert mesh to curve using either Continuous, All Edges, or Sharp Edges"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ import bpy, random, mathutils
+ from mathutils import Vector
+
+ Btrace = bpy.context.window_manager.curve_tracer
+ traceobjects = bpy.context.selected_objects # create a list with all the selected objects
+
+ obj = bpy.context.object
+
+ ### Convert Font
+ if obj.type == 'FONT':
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.convert(target='CURVE') # Convert edges to curve
+ bpy.context.object.data.dimensions = '3D'
+
+ # make a continuous edge through all vertices
+ if obj.type == 'MESH':
+ # Add noise to mesh
+ if Btrace.distort_curve:
+ for v in obj.data.vertices:
+ for u in range(3):
+ v.co[u] += Btrace.distort_noise * (random.uniform(-1,1))
+
+ if Btrace.convert_edgetype == 'CONTI':
+ ## Start Continuous edge
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.delete(type='EDGE_FACE')
+ bpy.ops.mesh.select_all(action='DESELECT')
+ verts = bpy.context.object.data.vertices
+ bpy.ops.object.mode_set(mode='OBJECT')
+ li = []
+ p1 = random.randint(0,len(verts)-1)
+
+ for v in verts:
+ li.append(v.index)
+ li.remove(p1)
+ for z in range(len(li)):
+ x = []
+ for px in li:
+ d = verts[p1].co - verts[px].co # find distance from first vert
+ x.append(d.length)
+ p2 = li[x.index(min(x))] # find the shortest distance list index
+ verts[p1].select = verts[p2].select = True
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.context.tool_settings.mesh_select_mode = [True, False, False]
+ bpy.ops.mesh.edge_face_add()
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+ # verts[p1].select = verts[p2].select = False #Doesn't work after Bmesh merge
+ li.remove(p2) # remove item from list.
+ p1 = p2
+ # Convert edges to curve
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.convert(target='CURVE')
+
+ if Btrace.convert_edgetype == 'EDGEALL':
+ ## Start All edges
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.delete(type='ONLY_FACE')
+ bpy.ops.object.mode_set()
+ bpy.ops.object.convert(target='CURVE')
+ for sp in obj.data.splines:
+ sp.type = Btrace.curve_spline
+
+ obj = bpy.context.object
+ # Set spline type to custom property in panel
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.curve.spline_type_set(type=Btrace.curve_spline)
+ # Set handle type to custom property in panel
+ bpy.ops.curve.handle_type_set(type=Btrace.curve_handle)
+ bpy.ops.object.editmode_toggle()
+ obj.data.fill_mode = 'FULL'
+ # Set resolution to custom property in panel
+ obj.data.bevel_resolution = Btrace.curve_resolution
+ obj.data.resolution_u = Btrace.curve_u
+ # Set depth to custom property in panel
+ obj.data.bevel_depth = Btrace.curve_depth
+ # Smooth object
+ bpy.ops.object.shade_smooth()
+ # Modulate curve radius and add distortion
+ if Btrace.distort_curve:
+ scale = Btrace.distort_modscale
+ if scale == 0:
+ return {'FINISHED'}
+ for u in obj.data.splines:
+ for v in u.bezier_points:
+ v.radius = scale*round(random.random(),3)
+ return {'FINISHED'}
+
+
+################## ################## ################## ############
+## Mesh Follow, trace vertex or faces
+## Create curve at center of selection item, extruded along animation
+## Needs to be animated mesh!!!
+################## ################## ################## ############
+
+class OBJECT_OT_meshfollow(bpy.types.Operator):
+ bl_idname = "object.btmeshfollow"
+ bl_label = "Btrace: Vertex Trace"
+ bl_description = "Trace Vertex or Face on an animated mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type in {'MESH'})
+
+ def execute(self, context):
+ import bpy, random
+ from mathutils import Vector
+
+ Btrace = bpy.context.window_manager.curve_tracer
+ distort_curve = Btrace.distort_curve # modulate the resulting curve
+ stepsize = Btrace.particle_step
+ traceobjects = bpy.context.selected_objects # create a list with all the selected objects
+
+ obj = bpy.context.object
+ scn = bpy.context.scene
+ meshdata = obj.data
+ cursor = bpy.context.scene.cursor_location.copy() # Store the location to restore at end of script
+ drawmethod = Btrace.fol_mesh_type # Draw from Edges, Verts, or Faces
+ if drawmethod == 'VERTS':
+ meshobjs = obj.data.vertices
+ if drawmethod == 'FACES':
+ meshobjs = obj.data.polygons # untested
+ if drawmethod == 'EDGES':
+ meshobjs = obj.data.edges # untested
+
+ # Frame properties
+ start_frame, end_frame = Btrace.fol_start_frame, Btrace.fol_end_frame
+ if start_frame > end_frame: # Make sure the math works
+ startframe = end_frame - 5 # if start past end, goto (end - 5)
+ frames = int((end_frame - start_frame) / stepsize)
+
+ def getsel_option(): # Get selection objects.
+ sel = []
+ seloption, fol_mesh_type = Btrace.fol_sel_option, Btrace.fol_mesh_type # options = 'random', 'custom', 'all'
+ if fol_mesh_type == 'OBJECT':
+ pass
+ else:
+ if seloption == 'CUSTOM':
+ for i in meshobjs:
+ if i.select == True:
+ sel.append(i.index)
+ if seloption == 'RANDOM':
+ for i in list(meshobjs):
+ sel.append(i.index)
+ finalsel = int(len(sel) * Btrace.fol_perc_verts)
+ remove = len(sel) - finalsel
+ for i in range(remove):
+ sel.pop(random.randint(0, len(sel) - 1))
+ if seloption == 'ALL':
+ for i in list(meshobjs):
+ sel.append(i.index)
+
+ return sel
+
+ def get_coord(objindex):
+ obj_co = [] # list of vector coordinates to use
+ frame_x = start_frame
+ for i in range(frames): # create frame numbers list
+ scn.frame_set(frame_x)
+ if drawmethod != 'OBJECT':
+ followed_item = meshobjs[objindex]
+ if drawmethod == 'VERTS':
+ g_co = obj.matrix_local * followed_item.co # find Vert vector
+
+ if drawmethod == 'FACES':
+ g_co = obj.matrix_local * followed_item.normal # find Face vector
+
+ if drawmethod == 'EDGES':
+ v1 = followed_item.vertices[0]
+ v2 = followed_item.vertices[1]
+ co1 = bpy.context.object.data.vertices[v1]
+ co2 = bpy.context.object.data.vertices[v2]
+ localcenter = co1.co.lerp(co2.co, 0.5)
+ g_co = obj.matrix_world * localcenter
+
+ if drawmethod == 'OBJECT':
+ g_co = objindex.location.copy()
+
+ obj_co.append(g_co)
+ frame_x = frame_x + stepsize
+
+ scn.frame_set(start_frame)
+ return obj_co
+
+ def make_curve(co_list):
+ Btrace = bpy.context.window_manager.curve_tracer
+ tracer = bpy.data.curves.new('tracer','CURVE')
+ tracer.dimensions = '3D'
+ spline = tracer.splines.new('BEZIER')
+ spline.bezier_points.add(len(co_list)- 1)
+ curve = bpy.data.objects.new('curve',tracer)
+ scn.objects.link(curve)
+ curvelist.append(curve)
+ # render ready curve
+ tracer.resolution_u = Btrace.curve_u
+ tracer.bevel_resolution = Btrace.curve_resolution # Set bevel resolution from Panel options
+ tracer.fill_mode = 'FULL'
+ tracer.bevel_depth = Btrace.curve_depth # Set bevel depth from Panel options
+ curve_handle = Btrace.curve_handle
+ if curve_handle == 'AUTOMATIC': # hackish AUTOMATIC doesn't work here
+ curve_handle = 'AUTO'
+
+ # move bezier points to objects
+ for i in range(len(co_list)):
+ p = spline.bezier_points[i]
+ p.co = co_list[i]
+ p.handle_right_type = curve_handle
+ p.handle_left_type = curve_handle
+ return curve
+
+ # Run methods
+ # Check if Btrace group exists, if not create
+ bgroup = bpy.data.groups.keys()
+ if 'Btrace' not in bgroup:
+ bpy.ops.group.create(name="Btrace")
+
+ Btrace = bpy.context.window_manager.curve_tracer
+ sel = getsel_option() # Get selection
+ curvelist = [] # list to use for grow curve
+
+ if Btrace.fol_mesh_type == 'OBJECT':
+ vector_list = get_coord(obj)
+ curvelist.append(make_curve(vector_list))
+ else:
+ for i in sel:
+ vector_list = get_coord(i)
+ curvelist.append(make_curve(vector_list))
+ # Select new curves and add to group
+ bpy.ops.object.select_all(action='DESELECT')
+ for curveobject in curvelist:
+ if curveobject.type == 'CURVE':
+ curveobject.select = True
+ bpy.context.scene.objects.active = curveobject
+ bpy.ops.object.group_link(group="Btrace")
+ addtracemat(curveobject.data)
+ curveobject.select = False
+
+ if Btrace.animate: # Add grow curve
+ for curveobject in curvelist:
+ curveobject.select = True
+ bpy.ops.curve.btgrow()
+ for curveobject in curvelist:
+ curveobject.select = False
+
+ obj.select = False # Deselect original object
+ return {'FINISHED'}
+
+###################################################################
+#### Add Tracer Material
+###################################################################
+
+def addtracemat(matobj):
+ # Need to add cycles or BI render material options
+ # if engine == 'CYCLES':
+ # Add cycles mat
+ # if engine == 'BLENDER_RENDER':
+ # Add blender interal mat
+ matslots = bpy.context.object.data.materials.items() # Check if a material exists, skip if it does
+ if len(matslots) < 1: # Make sure there is only one material slot
+ engine = bpy.context.scene.render.engine
+ Btrace = bpy.context.window_manager.curve_tracer
+ if not Btrace.mat_run_color_blender: # Check if color blender is to be run
+ if Btrace.trace_mat_random: # Create Random color for each item
+ # Use random color from chosen palette, assign color lists for each palette
+ import random
+ brightColors = [Btrace.brightColor1, Btrace.brightColor2, Btrace.brightColor3, Btrace.brightColor4]
+ bwColors = [Btrace.bwColor1, Btrace.bwColor2]
+ customColors = [Btrace.mmColor1, Btrace.mmColor2, Btrace.mmColor3, Btrace.mmColor4, Btrace.mmColor5, Btrace.mmColor6, Btrace.mmColor7, Btrace.mmColor8]
+ earthColors = [Btrace.earthColor1, Btrace.earthColor2, Btrace.earthColor3, Btrace.earthColor4, Btrace.earthColor5]
+ greenblueColors = [Btrace.greenblueColor1, Btrace.greenblueColor2, Btrace.greenblueColor3]
+ if Btrace.mmColors == 'BRIGHT':
+ #print(random.randint(0, len(brightColors) - 1))
+ mat_color = brightColors[random.randint(0, len(brightColors) - 1)]
+ if Btrace.mmColors == 'BW':
+ mat_color = bwColors[random.randint(0, len(bwColors) - 1)]
+ if Btrace.mmColors == 'CUSTOM':
+ mat_color = customColors[random.randint(0, len(customColors) - 1)]
+ if Btrace.mmColors == 'EARTH':
+ mat_color = earthColors[random.randint(0, len(earthColors) - 1)]
+ if Btrace.mmColors == 'GREENBLUE':
+ mat_color = greenblueColors[random.randint(0, len(greenblueColors) - 1)]
+ if Btrace.mmColors == 'RANDOM':
+ mat_color = (random.random(), random.random(), random.random())
+ else: # Choose Single color
+ mat_color = Btrace.trace_mat_color
+ # mat_color = Btrace.trace_mat_color
+ TraceMat = bpy.data.materials.new('TraceMat')
+ TraceMat.diffuse_color = mat_color
+ TraceMat.specular_intensity = 0.5
+ matobj.materials.append(bpy.data.materials.get(TraceMat.name))
+
+ else: # Run color blender operator
+ bpy.ops.object.colorblender()
+
+ return {'FINISHED'}
+
+###################################################################
+#### Add Color Blender Material
+###################################################################
+
+# This is the magical material changer!
+class OBJECT_OT_materialChango(bpy.types.Operator):
+ bl_idname = 'object.colorblender'
+ bl_label = 'Color Blender'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+
+ import bpy, random
+ Btrace = bpy.context.window_manager.curve_tracer # properties panel
+ colorObjects = bpy.context.selected_objects
+
+ # Set color lists
+ brightColors = [Btrace.brightColor1, Btrace.brightColor2, Btrace.brightColor3, Btrace.brightColor4]
+ bwColors = [Btrace.bwColor1, Btrace.bwColor2]
+ customColors = [Btrace.mmColor1, Btrace.mmColor2, Btrace.mmColor3, Btrace.mmColor4, Btrace.mmColor5, Btrace.mmColor6, Btrace.mmColor7, Btrace.mmColor8]
+ earthColors = [Btrace.earthColor1, Btrace.earthColor2, Btrace.earthColor3, Btrace.earthColor4, Btrace.earthColor5]
+ greenblueColors = [Btrace.greenblueColor1, Btrace.greenblueColor2, Btrace.greenblueColor3]
+
+ colorList = Btrace.mmColors
+
+ # Go through each selected object and run the operator
+ for i in colorObjects:
+ theObj = i
+ # Check to see if object has materials
+ checkMaterials = len(theObj.data.materials)
+ if checkMaterials == 0:
+ # Add a material
+ materialName = "colorblendMaterial"
+ madMat = bpy.data.materials.new(materialName)
+ theObj.data.materials.append(madMat)
+ else:
+ pass # pass since we have what we need
+
+ # assign the first material of the object to "mat"
+ mat = theObj.data.materials[0]
+
+ # Numbers of frames to skip between keyframes
+ skip = Btrace.mmSkip
+
+ # Random material function
+ def colorblenderRandom():
+ for crazyNumber in range(3):
+ mat.diffuse_color[crazyNumber] = random.random()
+
+ def colorblenderCustom():
+ mat.diffuse_color = random.choice(customColors)
+
+ # Black and white color
+ def colorblenderBW():
+ mat.diffuse_color = random.choice(bwColors)
+
+ # Bright colors
+ def colorblenderBright():
+ mat.diffuse_color = random.choice(brightColors)
+
+ # Earth Tones
+ def colorblenderEarth():
+ mat.diffuse_color = random.choice(earthColors)
+
+ # Green to Blue Tones
+ def colorblenderGreenBlue():
+ mat.diffuse_color = random.choice(greenblueColors)
+
+ # define frame start/end variables
+ scn = bpy.context.scene
+ start = scn.frame_start
+ end = scn.frame_end
+ # Go to each frame in iteration and add material
+ while start<=(end+(skip-1)):
+
+ bpy.ops.anim.change_frame(frame=start)
+
+ # Check what colors setting is checked and run the appropriate function
+ if Btrace.mmColors=='RANDOM':
+ colorblenderRandom()
+ elif Btrace.mmColors=='CUSTOM':
+ colorblenderCustom()
+ elif Btrace.mmColors=='BW':
+ colorblenderBW()
+ elif Btrace.mmColors=='BRIGHT':
+ colorblenderBright()
+ elif Btrace.mmColors=='EARTH':
+ colorblenderEarth()
+ elif Btrace.mmColors=='GREENBLUE':
+ colorblenderGreenBlue()
+ else:
+ pass
+
+ # Add keyframe to material
+ mat.keyframe_insert('diffuse_color')
+
+ # Increase frame number
+ start += skip
+ return{'FINISHED'}
+
+###### This clears the keyframes ######
+class OBJECT_OT_clearColorblender(bpy.types.Operator):
+ bl_idname = 'object.colorblenderclear'
+ bl_label = 'Clear colorblendness'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def invoke(self, context, event):
+
+ import bpy, random
+ mcolorblend = context.window_manager.colorblender_operator # properties panel
+ colorObjects = bpy.context.selected_objects
+
+ # Go through each selected object and run the operator
+ for i in colorObjects:
+ theObj = i
+ # assign the first material of the object to "mat"
+ matCl = theObj.data.materials[0]
+
+ # define frame start/end variables
+ scn = bpy.context.scene
+ start = scn.frame_start
+ end = scn.frame_end
+
+ # Remove all keyframes from diffuse_color, super sloppy need to find better way
+ while start <= (end * 2):
+ bpy.ops.anim.change_frame(frame=start)
+ matCl.keyframe_delete('diffuse_color')
+ start += 1
+
+ return{'FINISHED'}
+
+
+################## ################## ################## ############
+## F-Curve Noise
+## will add noise modifiers to each selected object f-curves
+## change type to: 'rotation' | 'location' | 'scale' | '' to effect all
+## first record a keyframe for this to work (to generate the f-curves)
+################## ################## ################## ############
+
+class OBJECT_OT_fcnoise(bpy.types.Operator):
+ bl_idname = "object.btfcnoise"
+ bl_label = "Btrace: F-curve Noise"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ import bpy, random
+
+ Btrace = bpy.context.window_manager.curve_tracer
+ amp = Btrace.fcnoise_amp
+ timescale = Btrace.fcnoise_timescale
+ addkeyframe = Btrace.fcnoise_key
+
+ # This sets properties for Loc, Rot and Scale if they're checked in the Tools window
+ noise_rot = 'rotation'
+ noise_loc = 'location'
+ noise_scale = 'scale'
+ if not Btrace.fcnoise_rot:
+ noise_rot = 'none'
+ if not Btrace.fcnoise_loc:
+ noise_loc = 'none'
+ if not Btrace.fcnoise_scale:
+ noise_scale = 'none'
+
+ type = noise_loc, noise_rot, noise_scale # Add settings from panel for type of keyframes
+ amplitude = amp
+ time_scale = timescale
+
+ for i in bpy.context.selected_objects:
+ # Add keyframes, this is messy and should only add keyframes for what is checked
+ if addkeyframe == True:
+ bpy.ops.anim.keyframe_insert(type="LocRotScale")
+ for obj in bpy.context.selected_objects:
+ if obj.animation_data:
+ for c in obj.animation_data.action.fcurves:
+ if c.data_path.startswith(type):
+ # clean modifiers
+ for m in c.modifiers :
+ c.modifiers.remove(m)
+ # add noide modifiers
+ n = c.modifiers.new('NOISE')
+ n.strength = amplitude
+ n.scale = time_scale
+ n.phase = random.randint(0,999)
+ return {'FINISHED'}
+
+################## ################## ################## ############
+## Curve Grow Animation
+## Animate curve radius over length of time
+################## ################## ################## ############
+class OBJECT_OT_curvegrow(bpy.types.Operator):
+ bl_idname = 'curve.btgrow'
+ bl_label = 'Run Script'
+ bl_description = 'Keyframe points radius'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type in {'CURVE'})
+
+ def execute(self, context):
+ Btrace = bpy.context.window_manager.curve_tracer
+ anim_f_start, anim_length, anim_auto = Btrace.anim_f_start, Btrace.anim_length, Btrace.anim_auto
+ curve_resolution, curve_depth = Btrace.curve_resolution, Btrace.curve_depth
+ # make the curve visible
+ objs = bpy.context.selected_objects
+ for i in objs: # Execute on multiple selected objects
+ bpy.context.scene.objects.active = i
+ obj = bpy.context.active_object
+ try:
+ obj.data.fill_mode = 'FULL'
+ except:
+ obj.data.dimensions = '3D'
+ obj.data.fill_mode = 'FULL'
+ if not obj.data.bevel_resolution:
+ obj.data.bevel_resolution = curve_resolution
+ if not obj.data.bevel_depth:
+ obj.data.bevel_depth = curve_depth
+ if anim_auto:
+ anim_f_start = bpy.context.scene.frame_start
+ anim_length = bpy.context.scene.frame_end
+ # get points data and beautify
+ actual, total = anim_f_start, 0
+ for sp in obj.data.splines:
+ total += len(sp.points) + len(sp.bezier_points)
+ step = anim_length / total
+ for sp in obj.data.splines:
+ sp.radius_interpolation = 'BSPLINE'
+ po = [p for p in sp.points] + [p for p in sp.bezier_points]
+ if not Btrace.anim_keepr:
+ for p in po:
+ p.radius = 1
+ if Btrace.anim_tails and not sp.use_cyclic_u:
+ po[0].radius = po[-1].radius = 0
+ po[1].radius = po[-2].radius = .65
+ ra = [p.radius for p in po]
+
+ # record the keyframes
+ for i in range(len(po)):
+ po[i].radius = 0
+ po[i].keyframe_insert('radius', frame=actual)
+ actual += step
+ po[i].radius = ra[i]
+ po[i].keyframe_insert('radius', frame=(actual + Btrace.anim_delay))
+
+ if Btrace.anim_f_fade:
+ po[i].radius = ra[i]
+ po[i].keyframe_insert('radius', frame=(actual + Btrace.anim_f_fade - step))
+ po[i].radius = 0
+ po[i].keyframe_insert('radius', frame=(actual + Btrace.anim_delay + Btrace.anim_f_fade))
+
+ bpy.context.scene.frame_set(Btrace.anim_f_start)
+ return{'FINISHED'}
+
+################## ################## ################## ############
+## Remove animation and curve radius data
+################## ################## ################## ############
+class OBJECT_OT_reset(bpy.types.Operator):
+ bl_idname = 'object.btreset'
+ bl_label = 'Clear animation'
+ bl_description = 'Remove animation / curve radius data'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ objs = bpy.context.selected_objects
+ for i in objs: # Execute on multiple selected objects
+ bpy.context.scene.objects.active = i
+ obj = bpy.context.active_object
+ obj.animation_data_clear()
+ if obj.type == 'CURVE':
+ for sp in obj.data.splines:
+ po = [p for p in sp.points] + [p for p in sp.bezier_points]
+ for p in po:
+ p.radius = 1
+ return{'FINISHED'}
+
+### Define Classes to register
+classes = [
+ TracerProperties,
+ TracerPropertiesMenu,
+ addTracerObjectPanel,
+ OBJECT_OT_convertcurve,
+ OBJECT_OT_objecttrace,
+ OBJECT_OT_objectconnect,
+ OBJECT_OT_writing,
+ OBJECT_OT_particletrace,
+ OBJECT_OT_traceallparticles,
+ OBJECT_OT_curvegrow,
+ OBJECT_OT_reset,
+ OBJECT_OT_fcnoise,
+ OBJECT_OT_meshfollow,
+ OBJECT_OT_materialChango,
+ OBJECT_OT_clearColorblender
+ ]
+
+def register():
+ for c in classes:
+ bpy.utils.register_class(c)
+ bpy.types.WindowManager.curve_tracer = bpy.props.PointerProperty(type=TracerProperties)
+ bpy.types.WindowManager.btrace_menu = bpy.props.PointerProperty(type=TracerPropertiesMenu, update=deselect_others)
+
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+ del bpy.types.WindowManager.curve_tracer
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py b/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py
new file mode 100644
index 0000000..771a63c
--- /dev/null
+++ b/release/scripts/addons_contrib/cmu_mocap_browser/__init__.py
@@ -0,0 +1,388 @@
+# ##### 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 3
+# 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 LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+# This script was developed with financial support from the Foundation for
+# Science and Technology of Portugal, under the grant SFRH/BD/66452/2009.
+
+
+bl_info = {
+ "name": "Carnegie Mellon University Mocap Library Browser",
+ "author": "Daniel Monteiro Basso <daniel at basso.inf.br>",
+ "version": (2012, 6, 1, 1),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tools",
+ "description": "Assistant for using CMU Motion Capture data",
+ "warning": "Broken",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/3D_interaction/CMU_Mocap_Library_Browser",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=29086",
+ "category": "3D View"}
+
+
+import os
+import bpy
+import bgl
+import blf
+import math
+from . import library
+
+
+def initialize_subjects():
+ """
+ Initializes the main object and the subjects (actors) list
+ """
+ while bpy.data.scenes[0].cmu_mocap_lib.subject_list:
+ bpy.data.scenes[0].cmu_mocap_lib.subject_list.remove(0)
+ for k, v in library.subjects.items():
+ n = bpy.data.scenes[0].cmu_mocap_lib.subject_list.add()
+ n.name = "{:d} - {}".format(k, v['desc'])
+ n.idx = k
+
+
+def update_motions(self, context):
+ """
+ Updates the motions list after a subject is selected
+ """
+ sidx = -1
+ if self.subject_active != -1:
+ sidx = self.subject_list[self.subject_active].idx
+ while self.motion_list:
+ self.motion_list.remove(0)
+ if sidx != -1:
+ for k, v in library.subjects[sidx]["motions"].items():
+ n = self.motion_list.add()
+ n.name = "{:d} - {}".format(k, v["desc"])
+ n.idx = k
+ self.motion_active = -1
+
+
+class ListItem(bpy.types.PropertyGroup):
+ name = bpy.props.StringProperty()
+ idx = bpy.props.IntProperty()
+
+
+class CMUMocapLib(bpy.types.PropertyGroup):
+ local_storage = bpy.props.StringProperty(
+ name="Local Storage",
+ subtype='DIR_PATH',
+ description="Location to store downloaded resources",
+ default="~/cmu_mocap_lib")
+ follow_structure = bpy.props.BoolProperty(
+ name="Follow Library Folder Structure",
+ description="Store resources in subfolders of the local storage",
+ default=True)
+ automatically_import = bpy.props.BoolProperty(
+ name="Automatically Import after Download",
+ description="Import the resource after the download is finished",
+ default=True)
+ subject_list = bpy.props.CollectionProperty(
+ name="subjects", type=ListItem)
+ subject_active = bpy.props.IntProperty(
+ name="subject_idx", default=-1, update=update_motions)
+ subject_import_name = bpy.props.StringProperty(
+ name="Armature Name",
+ description="Identifier of the imported subject's armature",
+ default="Skeleton")
+ motion_list = bpy.props.CollectionProperty(name="motions", type=ListItem)
+ motion_active = bpy.props.IntProperty(name="motion_idx", default=-1)
+ frame_skip = bpy.props.IntProperty(name="Fps Divisor", default=4,
+ # usually the sample rate is 120, so the default 4 gives you 30fps
+ description="Frame supersampling factor", min=1)
+ cloud_scale = bpy.props.FloatProperty(name="Marker Cloud Scale",
+ description="Scale the marker cloud by this value",
+ default=1., min=0.0001, max=1000000.0,
+ soft_min=0.001, soft_max=100.0)
+
+
+def draw_callback(self, context):
+ mid = int(360 * self.recv / self.fsize)
+ cx = 200
+ cy = 30
+ blf.position(0, 230, 23, 0)
+ blf.size(0, 20, 72)
+ blf.draw(0, "{0:2d}% of {1}".format(
+ 100 * self.recv // self.fsize, self.hfsize))
+
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glColor4f(.7, .7, .7, 0.8)
+ bgl.glBegin(bgl.GL_TRIANGLE_FAN)
+ bgl.glVertex2i(cx, cy)
+ for i in range(mid):
+ x = cx + 20 * math.sin(math.radians(float(i)))
+ y = cy + 20 * math.cos(math.radians(float(i)))
+ bgl.glVertex2f(x, y)
+ bgl.glEnd()
+
+ bgl.glColor4f(.0, .0, .0, 0.6)
+ bgl.glBegin(bgl.GL_TRIANGLE_FAN)
+ bgl.glVertex2i(cx, cy)
+ for i in range(mid, 360):
+ x = cx + 20 * math.sin(math.radians(float(i)))
+ y = cy + 20 * math.cos(math.radians(float(i)))
+ bgl.glVertex2f(x, y)
+ bgl.glEnd()
+
+ bgl.glDisable(bgl.GL_BLEND)
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+
+
+class CMUMocapDownloadImport(bpy.types.Operator):
+ bl_idname = "mocap.download_import"
+ bl_label = "Download and Import a file"
+
+ remote_file = bpy.props.StringProperty(
+ name="Remote File",
+ description="Location from where to download the file data")
+ local_file = bpy.props.StringProperty(
+ name="Local File",
+ description="Destination where to save the file data")
+ do_import = bpy.props.BoolProperty(
+ name="Manual Import",
+ description="Import the resource non-automatically",
+ default=False)
+
+ timer = None
+ fout = None
+ src = None
+ fsize = 0
+ recv = 0
+ cloud_scale = 1
+
+ def modal(self, context, event):
+ context.area.tag_redraw()
+ if event.type == 'ESC':
+ self.fout.close()
+ os.unlink(self.local_file)
+ return self.cancel(context)
+ if event.type == 'TIMER':
+ to_read = min(self.fsize - self.recv, 100 * 2 ** 10)
+ data = self.src.read(to_read)
+ self.fout.write(data)
+ self.recv += to_read
+ if self.fsize == self.recv:
+ self.fout.close()
+ return self.cancel(context)
+ return {'PASS_THROUGH'}
+
+ def cancel(self, context):
+ context.window_manager.event_timer_remove(self.timer)
+ context.region.callback_remove(self.handle)
+ if os.path.exists(self.local_file):
+ self.import_or_open()
+ return {'CANCELLED'}
+
+ def execute(self, context):
+ cml = bpy.data.scenes[0].cmu_mocap_lib
+ if not os.path.exists(self.local_file):
+ try:
+ os.makedirs(os.path.split(self.local_file)[0])
+ except:
+ pass
+ from urllib.request import urlopen
+ self.src = urlopen(self.remote_file)
+ info = self.src.info()
+ self.fsize = int(info["Content-Length"])
+ m = int(math.log10(self.fsize) // 3)
+ self.hfsize = "{:.1f}{}".format(
+ self.fsize * math.pow(10, -m * 3),
+ ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Eb', 'Pb'][m]) # :-p
+ self.fout = open(self.local_file, 'wb')
+ self.recv = 0
+ self.handle = context.region.\
+ callback_add(draw_callback, (self, context), 'POST_PIXEL')
+ self.timer = context.window_manager.\
+ event_timer_add(0.001, context.window)
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ self.import_or_open()
+ return {'FINISHED'}
+
+ def import_or_open(self):
+ cml = bpy.data.scenes[0].cmu_mocap_lib
+ if cml.automatically_import or self.do_import:
+ if self.local_file.endswith("mpg"):
+ bpy.ops.wm.path_open(filepath=self.local_file)
+ elif self.local_file.endswith("asf"):
+ try:
+ bpy.ops.import_anim.asf(
+ filepath=self.local_file,
+ from_inches=True,
+ use_rot_x=True, use_rot_z=True,
+ armature_name=cml.subject_import_name)
+ except AttributeError:
+ self.report({'ERROR'}, "To use this feature "
+ "please enable the Acclaim ASF/AMC Importer addon.")
+ elif self.local_file.endswith("amc"):
+ ob = bpy.context.active_object
+ if not ob or ob.type != 'ARMATURE' or \
+ 'source_file_path' not in ob:
+ self.report({'ERROR'}, "Please select a CMU Armature.")
+ return
+ try:
+ bpy.ops.import_anim.amc(
+ filepath=self.local_file,
+ frame_skip=cml.frame_skip)
+ except AttributeError:
+ self.report({'ERROR'}, "To use this feature please "
+ "enable the Acclaim ASF/AMC Importer addon.")
+ elif self.local_file.endswith("c3d"):
+ try:
+ bpy.ops.import_anim.c3d(
+ filepath=self.local_file,
+ from_inches=False,
+ auto_scale=True,
+ scale=cml.cloud_scale,
+ show_names=False,
+ frame_skip=cml.frame_skip)
+ except AttributeError:
+ self.report({'ERROR'}, "To use this feature "
+ "please enable the C3D Importer addon.")
+
+
+
+class CMUMocapConfig(bpy.types.Panel):
+ bl_idname = "object.cmu_mocap_config"
+ bl_label = "CMU Mocap Browser Configuration"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ if not bpy:
+ return
+ cml = bpy.data.scenes[0].cmu_mocap_lib
+ layout = self.layout
+ layout.operator("wm.url_open",
+ text="Carnegie Mellon University Mocap Library",
+ icon='URL').url = 'http://mocap.cs.cmu.edu/'
+ layout.prop(cml, "local_storage")
+ layout.prop(cml, "follow_structure")
+ layout.prop(cml, "automatically_import")
+
+
+class CMUMocapSubjectBrowser(bpy.types.Panel):
+ bl_idname = "object.cmu_mocap_subject_browser"
+ bl_label = "CMU Mocap Subject Browser"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ if not bpy:
+ return
+ layout = self.layout
+ cml = bpy.data.scenes[0].cmu_mocap_lib
+ # spare space... layout.label("Subjects")
+ layout.template_list(cml, "subject_list", cml, "subject_active")
+ layout.prop(cml, "subject_import_name")
+ if cml.subject_active != -1:
+ sidx = cml.subject_list[cml.subject_active].idx
+ remote_fname = library.skeleton_url.format(sidx)
+ tid = "{0:02d}".format(sidx)
+ local_path = os.path.expanduser(cml.local_storage)
+ if cml.follow_structure:
+ local_path = os.path.join(local_path, tid)
+ local_fname = os.path.join(local_path, tid + ".asf")
+ do_import = False
+ if os.path.exists(local_fname):
+ label = "Import Selected"
+ do_import = True
+ elif cml.automatically_import:
+ label = "Download and Import Selected"
+ else:
+ label = "Download Selected"
+
+ props = layout.operator("mocap.download_import",
+ text=label, icon='ARMATURE_DATA')
+ props.remote_file = remote_fname
+ props.local_file = local_fname
+ props.do_import = do_import
+
+
+class CMUMocapMotionBrowser(bpy.types.Panel):
+ bl_idname = "object.cmu_mocap_motion_browser"
+ bl_label = "CMU Mocap Motion Browser"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ if not bpy:
+ return
+ layout = self.layout
+ cml = bpy.data.scenes[0].cmu_mocap_lib
+ # spare space... layout.label("Motions for selected subject")
+ layout.template_list(cml, "motion_list", cml, "motion_active")
+ if cml.motion_active == -1:
+ return
+ sidx = cml.subject_list[cml.subject_active].idx
+ midx = cml.motion_list[cml.motion_active].idx
+ motion = library.subjects[sidx]['motions'][midx]
+ fps = motion['fps']
+ ifps = fps // cml.frame_skip
+ # layout.label("Original capture frame rate: {0:d} fps.".format(fps))
+ # layout.label("Importing frame rate: {0:d} fps.".format(ifps))
+ row = layout.row()
+ row.column().label("Original: {0:d} fps.".format(fps))
+ row.column().label("Importing: {0:d} fps.".format(ifps))
+ layout.prop(cml, "frame_skip")
+ layout.prop(cml, "cloud_scale")
+ remote_fname = library.motion_url.format(sidx, midx)
+ tid = "{0:02d}".format(sidx)
+ local_path = os.path.expanduser(cml.local_storage)
+ if cml.follow_structure:
+ local_path = os.path.join(local_path, tid)
+ for target, icon, ext in (
+ ('Motion Data', 'POSE_DATA', 'amc'),
+ ('Marker Cloud', 'EMPTY_DATA', 'c3d'),
+ ('Movie', 'FILE_MOVIE', 'mpg')):
+ action = "Import" if ext != 'mpg' else "Open"
+ fname = "{0:02d}_{1:02d}.{2}".format(sidx, midx, ext)
+ local_fname = os.path.join(local_path, fname)
+ do_import = False
+ if os.path.exists(local_fname):
+ label = "{0} {1}".format(action, target)
+ do_import = True
+ elif cml.automatically_import:
+ label = "Download and {0} {1}".format(action, target)
+ else:
+ label = "Download {0}".format(target)
+ row = layout.row()
+ props = row.operator("mocap.download_import", text=label, icon=icon)
+ props.remote_file = remote_fname + ext
+ props.local_file = local_fname
+ props.do_import = do_import
+ row.active = ext in motion['files']
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.cmu_mocap_lib = bpy.props.PointerProperty(type=CMUMocapLib)
+ initialize_subjects()
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/cmu_mocap_browser/library.py b/release/scripts/addons_contrib/cmu_mocap_browser/library.py
new file mode 100644
index 0000000..68c255a
--- /dev/null
+++ b/release/scripts/addons_contrib/cmu_mocap_browser/library.py
@@ -0,0 +1,7487 @@
+#!/usr/bin/env python3
+#-*- coding:utf-8 -*-
+
+# ##### 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 3
+# 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# This script was developed with financial support from the Foundation for
+# Science and Technology of Portugal, under the grant SFRH/BD/66452/2009.
+
+
+skeleton_url = "http://mocap.cs.cmu.edu:8080/subjects/{0:02d}/{0:02d}.asf"
+motion_url = "http://mocap.cs.cmu.edu:8080/subjects/{0:02d}/{0:02d}_{1:02d}."
+search_url = "http://mocap.cs.cmu.edu/search.php?subjectnumber=%&motion=%"
+
+# Carnegie Mellon University Mocap Library - http://mocap.cs.cmu.edu
+
+subjects = {1: {'desc': 'climb, swing, hang on playground equipment',
+ 'motions': {1: {'desc': 'playground - forward jumps, turn around',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'playground - climb',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'playground - climb, hang, swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'playground - climb',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'playground - climb, go under',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'playground - climb, sit, dangle legs, descend',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'playground - climb, sit, dangle legs, jump down',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'playground - climb, sit, dangle legs, rock back, lower self to ground',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'playground - climb, hang, hold self up with arms straight, swing, drop, sit, dangle legs, go under',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'playground - climb, swing, lean back, drop',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'playground - climb, hang, lean over, jump down',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'playground - climb, pull up, dangle, sit, lower self to ground',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'playground - climb, go under, jump down',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'playground - climb, jump down, dangle, legs push off against',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 2: {'desc': 'various expressions and human behaviors',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'jump, balance',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'punch/strike',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'bend over, scoop up, rise, lift arm',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'swordplay',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'swordplay',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'swordplay',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'wash self',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 3: {'desc': 'walk on uneven terrain',
+ 'motions': {1: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk on uneven terrain',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 5: {'desc': 'modern dance',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'dance - expressive arms, pirouette',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'dance - sideways arabesque, turn step, folding arms',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'dance - sideways arabesque, folding arms, bending back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'dance - quasi-cou-de-pied, raised leg above hip-height, jete en tourant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'dance - cartwheel-like start, pirouettes, jete',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'dance - small jetes, attitude/arabesque, shifted-axis pirouette, turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'dance - rond de jambe in the air, jete, turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'dance - glissade devant, glissade derriere, attitude/arabesque',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'dance - glissade devant, glissade derriere, attitude/arabesque',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'dance - sideways steps, pirouette',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'dance - arms held high, pointe tendue a terre, upper body rotation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'dance - small jetes, pirouette',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'dance - retire derriere, attitude/arabesque',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'dance - retire derriere, attitude/arabesque',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'dance - coupe dessous, jete en tourant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'dance - coupe dessous, grand jete en tourant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'dance - attitude/arabesque, jete en tourant, bending back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'dance - attitude/arabesque, jete en tourant, bending back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'dance - attitude/arabesque, jete en tourant, bending back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 6: {'desc': 'dribble, shoot basketball',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'basketball - forward dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'basketball - forward dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'basketball - forward dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'basketball - forward dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'basketball - backward dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'basketball - backward dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'basketball - sideways dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'basketball - sideways dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'basketball - forward dribble, 90-degree left turns',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'basketball - forward dribble, 90-degree right turns',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'basketball - forward dribble, 90-degree right turns, crossover dribble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'basketball - low, fast free style dribble, dribble through legs',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'basketball - crossover dribble, shoot',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'basketball - dribble, shoot',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 7: {'desc': 'walk',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'slow walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'slow walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'brisk walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 8: {'desc': 'walk',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'slow walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walk/stride',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walk, exaggerated stride',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'slow walk/stride',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 9: {'desc': 'run',
+ 'motions': {1: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'navigate - walk forward, backward, sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 10: {'desc': 'kick soccer ball',
+ 'motions': {1: {'desc': 'soccer - kick ball',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'soccer - kick ball',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'soccer - kick ball',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'soccer - kick ball',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'soccer - kick ball',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 11: {'desc': 'kick soccer ball',
+ 'motions': {1: {'desc': 'soccer - kick ball',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 12: {'desc': 'tai chi, walk',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'tai chi',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 13: {'desc': 'various everyday behaviors',
+ 'motions': {1: {'desc': 'sit on high stool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'sit on high stool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'sit on high stool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'sit on stepstool, chin in hand',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'sit on stepstool, hands against chin, fidget, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'sit on stepstool, hands against chin, elbow out, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'unscrew bottlecap, drink soda',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'unscrew bottlecap, drink soda, screw on bottlecap',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'drink soda',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'jump up to grab, reach for, tiptoe',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'jump up to grab, reach for, tiptoe',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'laugh',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'laugh',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'laugh',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'wash windows',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'wash windows',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'wash windows',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'sweep floor',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'sweep floor',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'sweep floor',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'direct traffic, wave',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'direct traffic, wave, point',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'direct traffic, wave, point',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'jumping jacks, side twists, bend over, squats',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'jumping jacks, side twists, squats, jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'jumping jacks, side twists, bend over, jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'climb ladder',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'climb ladder',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 14: {'desc': 'various everyday behaviors',
+ 'motions': {1: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'drink soda, screw on bottlecap',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'unscrew bottlecap, drink soda',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'jumping jacks, jog, squats, side twists, stretches',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'jump up to grab, reach for, tiptoe',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'jump up to grab, reach for, tiptoe',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'jump up to grab, reach for, tiptoe',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'wash windows',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'wash windows',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'wash windows',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'mop floor',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'jumping jacks, jog, squats, side twists, stretches',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'mop floor',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'sweep floor',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'laugh',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'laugh',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'laugh',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'jumping jacks, side twists, reach up, bend over',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'climb 3 steps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'direct traffic, wave, point',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'direct traffic, wave, point',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'direct traffic, wave, point',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'sit on high stool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'sit on high stool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'sit on stepstool, stand up, swing legs',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'sit on stepstool, ankle on other knee, hand on chin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'sit on stepstool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'sit on stepstool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'climb ladder',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'climb ladder',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'climb ladder',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'sit on stepstool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'drink soda',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 15: {'desc': 'various everyday behaviors, dance moves',
+ 'motions': {1: {'desc': 'walk/wander',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'climb, step over, sit on, stand on stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk/wander',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'wash windows, paint; hand signals; dance - Egyptian walk, the Dive, the Twist, the Cabbage Patch; boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'wash windows, paint; hand signals; dance - Egyptian walk, the Dive, the Twist, the Cabbage Patch; boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'lean forward, reach for',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'lean forward, tiptoe, reach for',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'hand signals - horizontally revolve forearms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk/wander',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'sit on high stool, stand up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'wash windows, paint figure eights; hand signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'wash windows; basketball - dribble, lay-up shot, pass; throw ball; dance - Egyptian walk, the Dive, the Twist; strew',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk/wander',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 16: {'desc': 'run, jump, walk',
+ 'motions': {1: {'desc': 'jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'high jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'high jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'run/jog, sudden stop',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'forward jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walk, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'walk, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'walk, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'walk, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'walk, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'walk, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'walk, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'walk, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'walk, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'walk, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'walk, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'walk, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'walk, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'walk, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'walk, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'slow walk, stop',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'slow walk, stop',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'run/jog, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'run/jog, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'run/jog, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'run/jog, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'run/jog, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'run/jog, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'run/jog, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'run/jog, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'run, veer left',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'run, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'run, veer right',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'run, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'run, 90-degree left turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'run, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'run, 90-degree right turn',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 56: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'run/jog, sudden stop',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 58: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 17: {'desc': 'different walking styles',
+ 'motions': {1: {'desc': 'walk with anger, frustration',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk with anger, frustration',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk stealthily',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk stealthily',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walk/hobble',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'whistle, walk jauntily',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'whistle, walk jauntily',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': "muscular, heavyset person's walk",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': "muscular, heavyset person's walk",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 18: {'desc': 'human interaction and communication (2 subjects - subject A)',
+ 'motions': {1: {'desc': 'walk, shake hands (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk, shake hands (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'A pulls B; B resists (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'A pulls B; B resists (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'navigate busy sidewalk; A leads the way, takes B by the arm (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'conversation - explain with hand gestures (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'conversation - explain with hand gestures, walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'quarrel - angry hand gestures (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'quarrel - angry hand gestures (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'friends meet, hang out; A sits, B joins A (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'run, scramble for last seat (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'run, scramble for last seat (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'chicken dance (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 19: {'desc': 'human interaction and communication (2 subjects - subject B)',
+ 'motions': {1: {'desc': 'walk, shake hands (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk, shake hands (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'A pulls B; B resists (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'A pulls B; B resists (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'A pulls B by the elbow; B resists (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'navigate busy sidewalk; A leads the way, takes B by the arm (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'conversation - explain with hand gestures (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'conversation - explain with hand gestures, walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'quarrel - angry hand gestures (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'quarrel - angry hand gestures (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'friends meet, hang out; A sits, B joins A (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'run, scramble for last seat (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'run, scramble for last seat (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'chicken dance (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 20: {'desc': 'human interaction - at play, formations (2 subjects - subject A)',
+ 'motions': {1: {'desc': 'chicken dance (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'link arms, walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'link arms, walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'synchronized walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'synchronized walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'soldiers march (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'soldiers march (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'zombie march (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'nursery rhyme - ring around the rosey (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '360-degree two-person whip (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'high-five, walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'low-five, walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': "blind man's bluff (blindfold tag) (2 subjects - subject A)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 21: {'desc': 'human interaction - at play, formations (2 subjects - subject B)',
+ 'motions': {1: {'desc': 'chicken dance (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'link arms, walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'link arms, walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'synchronized walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'synchronized walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'soldiers march (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'soldiers march (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'zombie march (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'nursery rhyme - ring around the rosey (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '360-degree two-person whip (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'high-five, walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'low-five, walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': "blind man's bluff (blindfold tag) (2 subjects - subject B)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 22: {'desc': 'human interaction (2 subjects - subject A)',
+ 'motions': {1: {'desc': 'B sits; A pulls up B (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'A sits; B pulls up A (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'A sits, holds face in hands; B kneels, comforts A (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': "B comforts A, puts one hand on A's shoulder (2 subjects - subject A)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': "A comforts B, puts both hands on B's shoulders (2 subjects - subject A)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': "B comforts A, puts both hands on A's shoulders (2 subjects - subject A)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': "A comforts B, puts one hand on B's shoulder (2 subjects - subject A)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'hold hands, swing arms, walk (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'A gives B a shoulder rub; B sits, A stands (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'A shelters B, a younger child, from harm (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'B shelters A, a younger child, from harm (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'A stumbles into B (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'A passes soda to B; both drink (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'alternating squats (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'alternating jumping jacks (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'synchronized jumping jacks (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'rush up, arm wrestle (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'A stares down B, leans with hands on high stool (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'B stares down A, leans with hands on high stool (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'violence - A picks up high stool, threatens to strike B (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'conversation - B pounds high stool, points at A (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'walk; B catches keys thrown by A (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'walk; A catches keys thrown by B (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'walk; B catches wallet thrown by A (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'walk; A catches wallet thrown by B (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 23: {'desc': 'human interaction (2 subjects - subject B)',
+ 'motions': {1: {'desc': 'B sits; A pulls up B (subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'A sits; B pulls up A (subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'A sits, holds face in hands; B kneels, comforts A (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': "B comforts A, puts one hand on A's shoulder (2 subjects - subject B)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': "A comforts B, puts both hands on B's shoulders (2 subjects - subject B)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': "B comforts A, puts both hands on A's shoulders (2 subjects - subject B)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': "A comforts B, puts one hand on B's shoulder (2 subjects - subject B)",
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'hold hands, swing arms, walk (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'A gives B a shoulder rub; B sits, A stands (subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'A shelters B, a younger child, from harm (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'B shelters A, a younger child, from harm (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'A stumbles into B (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'A passes soda to B; both drink (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'alternating squats (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'alternating jumping jacks (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'synchronized jumping jacks (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'rush up, arm wrestle (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'A stares down B, leans with hands on high stool (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'B stares down A, leans with hands on high stool (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'violence - A picks up high stool, threatens to strike B (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'conversation - B pounds high stool, points at A (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'walk; B catches keys thrown by A (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'walk; A catches keys thrown by B (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'walk; B catches wallet thrown by A (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'walk; A catches wallet thrown by B (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 24: {'desc': 'nursery rhymes',
+ 'motions': {1: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 25: {'desc': 'nursery rhymes',
+ 'motions': {1: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg'],
+ 'fps': 120}}},
+ 26: {'desc': 'nursery rhymes, basketball, bending',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Alaska vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Alaska vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'bend, pick up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'bend, lift',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'bend, lift',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 27: {'desc': 'recreation, nursery rhymes',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 28: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'whale (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'snake (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'mouse (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'cat (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'elephant (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'dinosaur (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 29: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'whale (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'cat (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'fish (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'elephant (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'mouse (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'dinosaur (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'snake (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 30: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'whale (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'cat (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'elephant (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'mouse (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'snake (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Tyrannosaurus rex (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 31: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'whale (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'cat (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'elephant (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Tyrannosaurus rex (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'mouse (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'snake (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 32: {'desc': 'recreation, nursery rhymes, animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'nursery rhyme - "I\'m a little teapot..."',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'nursery rhyme - Cock Robin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Alaskan vacation',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'cat (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'elephant (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'mouse (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Tyrannosaurus rex (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'snake (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 33: {'desc': 'throw and catch football (2 subjects - subject A)',
+ 'motions': {1: {'desc': 'football - throw, catch (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'football - throw, catch, jump around (2 subjects - subject A)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 34: {'desc': 'throw and catch football (2 subjects - subject B)',
+ 'motions': {1: {'desc': 'football - throw, catch (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'football - throw, catch, jump around (2 subjects - subject B)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 35: {'desc': 'walk, run',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'run/jog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'navigate around obstacles',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 36: {'desc': 'walk on uneven terrain',
+ 'motions': {1: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk forward, turn around, walk back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk forward, turn around, walk back',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk forward, turn around, walk back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'walk on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'jump/hop on uneven terrain',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 37: {'desc': 'walk',
+ 'motions': {1: {'desc': 'slow walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 38: {'desc': 'walk, run',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'run around in a circle',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk around, frequent turns, cyclic walk along a line',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 39: {'desc': 'climb, swing, hang on playground equipment',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walk forward, turn around, walk back',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 40: {'desc': 'navigate from corner to corner, interact with stepstool',
+ 'motions': {2: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'climb, step over, sit on, jump over stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'climb, step over, jump over stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'climb, step over, jump over stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'climb, step over, jump over stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'wait for bus',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'wait for bus',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 41: {'desc': 'navigate from corner to corner, interact with stepstool',
+ 'motions': {2: {'desc': 'navigate - walk forward, backward, sideways, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'navigate - walk forward, backward, sideways, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'navigate - walk forward, backward, on a diagonal',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'climb, step over, jump over, navigate around stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'climb, step over, jump over, navigate around stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'climb, step over, jump over, navigate around stepstool',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'basketball signals',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 42: {'desc': 'stretch',
+ 'motions': {1: {'desc': 'stretch - rotate head, shoulders, arms, legs',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 60}}},
+ 43: {'desc': 'swing on playground equipment',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'playground - grip bar, swing body',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'playground - grip bar, swing body',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 45: {'desc': 'walk',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 46: {'desc': 'walk',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 47: {'desc': 'walk',
+ 'motions': {1: {'desc': 'walk forward, turn around, walk back',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 49: {'desc': 'modern dance, gymnastics',
+ 'motions': {1: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'jump up and down, hop on one foot',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'jump up and down, hop on one foot',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'run, leap',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'run, leap',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'cartwheels',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'dance - arms held high, side arabesque',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'dance - fold in from side arabesque, curl inwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'dance - fold in from side arabesque, curl inwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'dance - lean forward, bring back leg forward, arching arms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'dance - fold in from side arabesque, curl inwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'dance - lean forward, bring back leg forward, arching arms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'static dance pose - folded in, head lowered, leg bent',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'dance - fold in from side arabesque, curl inwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'dance - lean forward, bring back leg forward, arching arms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'balance on one leg, outstretched arms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'balance on one leg, outstretched arms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'balance on one leg, outstretched arms',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'acrobatics - spin/twirl, hang on ropes',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'dance - lean back on bent leg, balance, bend elbow by ear',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 54: {'desc': 'animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'penguin (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'pterosaur (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'pterosaur (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'pterosaur (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'roadrunner (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'insect/praying mantis (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'ghost (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'penguin (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'dragon (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'dragon (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'superhero',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'squirrel (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'squirrel (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'squirrel - robotic like motion (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'follow path, walk around obstacles',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'follow path, walk around obstacles',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'follow path, walk around obstacles',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'hummingbird (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 55: {'desc': 'animal behaviors (pantomime - human subject)',
+ 'motions': {1: {'desc': 'dance, whirl',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'lambada dance',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'genie (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'hummingbird (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'chicken (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'hummingbird (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'animal (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'dancing bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'insect/praying mantis (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'prairie dog (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'roadrunner (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'panda (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'ghost (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'penguin (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'dragon (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'hippo ballerina (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'pterosaur (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'superhero',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'devil',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'various animals (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'dancing animal (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'monkey (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'dancing ant (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'monkey/bear (human subject)',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 56: {'desc': 'vignettes - locomotion, upper-body motions (focus: motion transitions)',
+ 'motions': {1: {'desc': 'walk around',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'vignettes - fists up, wipe window, yawn, stretch, angrily grab, smash against wall',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'vignettes - fists up, wipe window, yawn, stretch, angrily grab, smash against wall, lift open window, throw punches, skip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'vignettes - fists up, wipe window, grab, lift open window, throw punches, yawn, stretch, walk, jump',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'vignettes - walk, drink water, run/jog, jump, wipe window, lift open window, throw punches, yawn, stretch',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'vignettes - throw punches, grab, skip, yawn, stretch, leap, lift open window, walk, jump/bound',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'vignettes - yawn, stretch, walk, run/jog, angrily grab, jump, skip, halt',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'vignettes - lift open window, smash against wall, hop, walk, run/jog, yawn, stretch',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 60: {'desc': 'salsa',
+ 'motions': {1: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60}}},
+ 61: {'desc': 'salsa',
+ 'motions': {1: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'salsa dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60}}},
+ 62: {'desc': 'construction work, random motions',
+ 'motions': {1: {'desc': 'bolt loosening, wrench',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'bolt tightening, wrench',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'sawing, hand saw',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'screwing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'screwing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'unscrewing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'hammering a nail',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'hammering a nail',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'pulling a nail',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'hammering sequence',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'cleaning up',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'hard days drink',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'moving a stool',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'opening umbrella',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'opening umbrella',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 16: {'desc': 'closing umbrella',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 17: {'desc': 'opening and closing umbrella',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 18: {'desc': 'closing a box',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 19: {'desc': 'opening a box',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'closing, moving and opening a box',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 21: {'desc': 'coiling a rope',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 22: {'desc': 'dynamic calibration',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 23: {'desc': 'bolt tightening',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 24: {'desc': 'bolt tightening, with putting bolt in',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 25: {'desc': 'bolt loosening, wrench',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 63: {'desc': 'golf',
+ 'motions': {1: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 64: {'desc': 'golf',
+ 'motions': {1: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Putt',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Putt',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Putt',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Putt',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Putt',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Placing Tee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Placing Tee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Placing Tee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Placing Tee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Placing Tee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Placing Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Placing Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Placing Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Placing Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Placing Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Picking up Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Picking up Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Picking up Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Picking up Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Picking up Ball',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 120}}},
+ 69: {'desc': 'walking',
+ 'motions': {1: {'desc': 'walk forward',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk forward',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk forward',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk forward',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walk forward',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walk and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walk and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walk and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walk and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walk and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'walk and turn both directions (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'walk, turn in place (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk, turn in place (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'walk, turn in place (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'turn in place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'turn in place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'turn in place (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'turn in place (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'walk forward 90 degree right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'walk forward 90 degree right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'walk forward 90 degree right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'walk forward 90 degree right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'walk forward 90 degree left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'walk forward 90 degree left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'walk forward 90 degree left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'walk forward 90 degree left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'walk forward 90 degree smooth right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'walk forward 90 degree smooth right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'walk forward 90 degree smooth right turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'walk forward 90 degree smooth left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'walk forward 90 degree smooth left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'walk forward 90 degree smooth left turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'walk backwards and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'walk backward, turn in place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'walk backward, turn in place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'walk backward, turn in place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'walk sideways and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'walk sideways and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'walk sideways and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'walk sideways and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'walk sideways and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'walk sideways and turn (repeated)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'walk sideways and backwards',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'walk backwards and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 58: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 59: {'desc': 'walk sideways and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 60: {'desc': 'walk sideways and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 61: {'desc': 'walk sideways and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 62: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 63: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 64: {'desc': 'walk sideways and turn (opposite direction)',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 65: {'desc': 'walk sideways and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 66: {'desc': 'walk sideways and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 67: {'desc': 'walk sideways and turn',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 68: {'desc': 'walk forward and pick up object, set down object',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 69: {'desc': 'walk forward and pick up object, carry back object',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 70: {'desc': 'walk up to object, squat, pick up object, set down in another place.',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 71: {'desc': 'walk up to object, squat, pick up object, set down in another place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 72: {'desc': 'walk up to object, pick up object, set down in another place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 73: {'desc': 'walk up to object, lean over, pick up object, set down in another place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 74: {'desc': 'walk up to object, lean over, pick up object, set down in another place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 75: {'desc': 'walk up to object, squat, pick up object, set down in another place',
+ 'files': ['amc', 'avi'],
+ 'fps': 120}}},
+ 70: {'desc': 'suitcase',
+ 'motions': {1: {'desc': 'carry 5.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'carry 5.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'carry 19.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'carry 12.5lb suitcase',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'carry 12.5lb suitcase',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'carry 12.5lb suitcase',
+ 'files': ['amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'carry 12.5lb suitcase',
+ 'files': ['amc', 'avi'],
+ 'fps': 120}}},
+ 74: {'desc': 'kicks and walking on slopes',
+ 'motions': {1: {'desc': 'stiff walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'stiff walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'lifting up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'lifting up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 9: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'peeping',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'peeping',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'thinker',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'Range of motion',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'slope 1',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'slope1',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 16: {'desc': 'slope 2',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 17: {'desc': 'slope 2',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 18: {'desc': 'slope 3',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 19: {'desc': 'slope 3',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'stiff walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60}}},
+ 75: {'desc': 'jumps; hopscotch; sits',
+ 'motions': {1: {'desc': 'run jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'run jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'run jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'wide leg run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'cross leg run',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 6: {'desc': '180 jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'angle jumps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 8: {'desc': '360 jumps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 9: {'desc': '360 jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 10: {'desc': '2 jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 11: {'desc': '2 jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'box jump',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'hopscotch',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'hopscotch',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'long jumps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 16: {'desc': 'jump kick',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 17: {'desc': 'medium sit',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 18: {'desc': 'high sit',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 19: {'desc': 'medium sit',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'low sit',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 76: {'desc': 'avoidance',
+ 'motions': {1: {'desc': 'walk backwards then attack with a punch',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk backwards, feign a few attacks, then attack',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'avoid attacker',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'defensive guard pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'swatting at pesky bug',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'avoid stepping on something',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'careful stepping over things',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walking backwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'turning',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'quick large steps backwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 77: {'desc': 'careful actions',
+ 'motions': {1: {'desc': 'looking around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'standing',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'ready stance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'Looking around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'look around with flashlight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'searching ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'poking ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'investigating thing on ground with two hands',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'duck to avoid flying object',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'careful run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'careful run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'careful run in circle',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'careful run in figure eight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'careful creeping',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'careful creeping',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 16: {'desc': 'laying down, getting up, careful ready pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 17: {'desc': 'laying down, getting up, careful ready pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 18: {'desc': 'laying down on back, getting up, careful ready pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 19: {'desc': 'limping, hurt right leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'limping, hurt right leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 21: {'desc': 'stretching',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 22: {'desc': 'limping, hurt right leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 23: {'desc': 'limping, hurt right leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 24: {'desc': 'limping, hurt right leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 25: {'desc': 'careful walk and search',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 26: {'desc': 'careful walk and search',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 27: {'desc': 'careful walk and search',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 28: {'desc': 'careful walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 29: {'desc': 'creeping walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 30: {'desc': 'creeping walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 31: {'desc': 'silent walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 32: {'desc': 'creeping walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 33: {'desc': 'creeping with limp',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 34: {'desc': 'creep and pause, repeat',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60}}},
+ 78: {'desc': 'walking',
+ 'motions': {1: {'desc': 'LeftTightTurn CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'RightWideTurn CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'LeftWideTurn CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'SuperTightLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'SuperTightRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'RunningStraight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'RunningWideRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'RunningWideLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'RunningTigherLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'RunningTighterRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'calibration',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'RunningNoBall CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'OffensiveMoveSpinLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'OffensiveMoveSpinLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'OffensiveMoveGoRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'OffensiveMoveGoLeft CleanedGRs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'OffensiveMoveSpinRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'WalkEvasiveLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'WalkEvasiveRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'FeintLeftMoveRight CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'FeintRightMoveLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'FakeShotBreakRight CleanedGRs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'FakeShotBreakLeft CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'DefensiveStraightNoStop CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'DefensiveStraightWithStop CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'DefensiveRightStopToStop CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'DefensiveLeftStopToStop CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'DefensiveMoveZigZag CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'DefensiveMoveSideToSide CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'DefensiveMoveSideToSide CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Pivoting CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'SraightDriveFromStop Cleaned GRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'RightDrive (left then right) Cleaned GRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'LeftDrive (right then left) Cleaned GRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'RightTightTurn CleanedGRS',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 79: {'desc': 'actor everyday activities',
+ 'motions': {1: {'desc': 'chopping wood',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'swimming',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'swimming',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'digging',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'sewing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'hand shake',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'lost marker',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'slicing bread',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'chopping onions',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'Subject calibration',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'eating dinner',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'mixing batter',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'making dough',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'eating a sandwich',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 16: {'desc': 'buying something',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 17: {'desc': 'playing violin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 18: {'desc': 'playing drums',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 19: {'desc': 'playing piano',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'hanging a picture',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 21: {'desc': 'putting on a pull over',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 22: {'desc': 'range of motion',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 23: {'desc': 'putting on a jacket',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 24: {'desc': 'putting on button up sweater',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 25: {'desc': 'moving heavy box',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 26: {'desc': 'planting a tree',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 27: {'desc': 'planting a plant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 28: {'desc': 'putting on a ball cap',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 29: {'desc': 'putting on a dress',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 30: {'desc': 'pushing a swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 31: {'desc': 'writing on a chalkboard',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 32: {'desc': 'writing on a chalkboard',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 33: {'desc': 'chug a beer',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 34: {'desc': 'fishing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 35: {'desc': 'fishing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 36: {'desc': 'answering the phone',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 37: {'desc': 'dialing phone',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 38: {'desc': 'drinking water',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 39: {'desc': 'sipping martinee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 40: {'desc': 'drinking a soda',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 41: {'desc': 'sipping coffee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 42: {'desc': 'eating soup',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 43: {'desc': 'painting',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 44: {'desc': 'washing a window',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 45: {'desc': 'bear',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 46: {'desc': 'bear',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 47: {'desc': 'chicken',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 48: {'desc': 'elephant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 49: {'desc': 'monkey',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 50: {'desc': 'mouse',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 51: {'desc': 'chipmunk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 52: {'desc': 'prairie dog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 53: {'desc': 'dog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 54: {'desc': 'snake',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 55: {'desc': 'sweeping',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 56: {'desc': 'T-rex',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 57: {'desc': 'fish',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 58: {'desc': 'bird',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 59: {'desc': 'cat',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 60: {'desc': 'chicken',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 61: {'desc': 'cow',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 62: {'desc': 'chicken',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 63: {'desc': 'tiger',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 64: {'desc': 'penguin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 65: {'desc': 'horse',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 66: {'desc': 'movie and trial dont match',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 67: {'desc': 'no movie',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 68: {'desc': 'cold',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 69: {'desc': 'very happy',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 70: {'desc': 'laughing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 71: {'desc': 'sad',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 72: {'desc': 'crying',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 73: {'desc': 'scared',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 74: {'desc': 'upset',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 75: {'desc': 'channel surfing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 76: {'desc': 'driving',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 77: {'desc': 'vacuuming',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 78: {'desc': 'taking a movie',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 79: {'desc': 'putting on headphones',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 80: {'desc': 'using a palm pilot',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 81: {'desc': 'brushing teeth',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 82: {'desc': 'putting on deoderant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 83: {'desc': 'shaving',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 84: {'desc': 'combing hair',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 85: {'desc': 'typing on a laptop',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 86: {'desc': 'shooting bow and arrow',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 87: {'desc': 'raking',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 88: {'desc': 'swatting at a fly',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 89: {'desc': 'holding a baby',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 90: {'desc': 'washing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 91: {'desc': 'football',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 92: {'desc': 'frisbee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 93: {'desc': 'weight lifting',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 94: {'desc': 'flexing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 95: {'desc': 'rowing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 96: {'desc': 'shooting a gun',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 80: {'desc': 'assorted motions',
+ 'motions': {1: {'desc': 'shaking hands',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'chopping onions',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'shooting a gun',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'sewing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'digging a hole',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'paying for something',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'hanging picture',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'picking up something',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'planting a flower',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'boxing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'putting on a sweater',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 12: {'desc': 'fishing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 13: {'desc': 'drumming',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 14: {'desc': 'teaching',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 15: {'desc': 'putting on a coat',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 16: {'desc': 'mixing batter',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 17: {'desc': 'hand mixing dough',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 18: {'desc': 'vacuuming',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 19: {'desc': 'pushing broom',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'planting',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 21: {'desc': 'pushing swing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 22: {'desc': 'putting on a hat',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 23: {'desc': 'putting on a skirt',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 24: {'desc': 'eating',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 25: {'desc': 'answering a phone',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 26: {'desc': 'dialing phone',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 27: {'desc': 'setting glass of water',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 28: {'desc': 'drinking and smoking',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 29: {'desc': 'chugging',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 30: {'desc': 'range of motion',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 31: {'desc': 'making coffee',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 32: {'desc': 'slicing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 33: {'desc': 'eating soup',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 34: {'desc': 'rake leaves',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 35: {'desc': 'putting on headphones',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 36: {'desc': 'violin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 37: {'desc': 'TV',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 38: {'desc': 'driving',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 39: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 40: {'desc': 'drinking from bottle',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 41: {'desc': 'freezing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 42: {'desc': 'freezing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 43: {'desc': 'happy',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 44: {'desc': 'laughing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 45: {'desc': 'crying',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 46: {'desc': 'crying',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 47: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 48: {'desc': 'arguing',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 49: {'desc': 'gorilla',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 50: {'desc': 'cleaning window',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 51: {'desc': 'chicken',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 52: {'desc': 'dog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 53: {'desc': 'elephant',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 54: {'desc': 'monkey',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 55: {'desc': 'mouse',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 56: {'desc': 'chip monk',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 57: {'desc': 'prairie dog',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 58: {'desc': 'snake',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 59: {'desc': 'panther',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 60: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 61: {'desc': 'sweeping',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 62: {'desc': 'bird',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 63: {'desc': 'chicken',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 64: {'desc': 'cat',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 65: {'desc': 'fish',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 66: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 67: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 68: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 69: {'desc': 'painting',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 70: {'desc': 'piano',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 71: {'desc': 'chopping wood',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 72: {'desc': 'swimming',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 73: {'desc': 'shaking hands',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 81: {'desc': 'pushing a box; jumping off a ledge; walks',
+ 'motions': {1: {'desc': 'fix hair and walk forward',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk forward',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walk',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walk at a brisk pace',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'push heavy object',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'push heavy box',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'pull heavy object',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'drag heavy object',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'drag heavy object',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'push object that is high in air',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'push object that is high in air',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'jump backwards off ledge',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'jump backwards off ledge',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'climb backwards off ledge',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'climb backwards off ledge',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'walk forward',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'adjust hair walk forward',
+ 'files': ['tvd', 'amc', 'avi'],
+ 'fps': 120}}},
+ 82: {'desc': 'jumping; pushing; emotional walks',
+ 'motions': {1: {'desc': 'Static pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Jump off ledge',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Jump off ledge',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Jump off ledge',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'sitting on ground relaxing',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Pushing on heavy object',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Pushing on heavy object',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'stand still; casual walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'confident walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'sad walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'normal walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'happy or fast walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'normal walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'walk forward and slow down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'walk forward and turn sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'bang on high object',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'bang on high object',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'static pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 83: {'desc': 'steps',
+ 'motions': {1: {'desc': 'large sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'sidestep to the right and up a ledge',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'large step to a short ledge',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'large sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'very large sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'very large sidestep to right and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'short sidestep to right and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'medium step forward and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'short step forward and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'medium step forward and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'static pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'medium sidestep to right and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'large sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'short sidestep to left and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'short step forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'medium sidestep to left and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'medium step to left and down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'short step to left and forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'medium sidestep to left',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'medium step forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'large step to left and forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'stretching',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'short sidestep to left and up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'medium step to left and up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'short step forward and up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'medium step to left, forward, and up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'walk forward stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'walk forward stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'walk forward stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'walk forward stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'walk forward stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'walk forward stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'sidestep to right then back to left',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'walk forward and up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'walk forward and stepping up stairs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'walk forward turn 90 degrees left walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'walk forward turn 90 degrees right walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'walk forward turn 90 degrees left walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'walk forward turn 90 degrees right walk forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'hop forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'hop forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'long jump forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'long jump forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'medium step forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'hop forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'medium hop forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'long jump forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'short hop forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'medium hop forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'long jump forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'hop turn 90 degrees left in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'hop turn 90 degrees left in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'hop turn 90 degrees left in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'hop turn 180 degrees left in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'medium sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': 'hop turn left 180 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'hop turn left 180 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 58: {'desc': 'hop turn left 270 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 59: {'desc': 'hop turn left 270 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 60: {'desc': 'hop turn left 270 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 61: {'desc': 'hop turn 360 degrees left in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 62: {'desc': 'hop turn left 360 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 63: {'desc': 'large sidestep to right and forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 64: {'desc': 'hop and turn right 360 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 65: {'desc': 'hop and turn right 360 degrees in air',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 66: {'desc': 'short sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 67: {'desc': 'short sidestep to the right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 68: {'desc': 'medium sidestep to right',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 85: {'desc': 'jumps; flips; breakdance',
+ 'motions': {1: {'desc': 'JumpTwist',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'JumpTwist',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'UpRightSequence',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'FancyFootWork',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'HandStandKicks',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'KickFlip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'KickFlipStumble',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Helicopter',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'motorcycle pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'EndofBreakDance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'UpRightSequence',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'LongSequenceGood',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'BadStartSequnce',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'BreakSequencewithFlips',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': '90TwistsFall',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 86: {'desc': 'sports and various activities',
+ 'motions': {1: {'desc': 'jumps kicks and punches',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'walk, squats, run, stretch, jumps, punches, and drinking',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'walking, running, jumping, kicking, and stretching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'walking, stretching, punching, chopping, and drinking',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'walking, jumping, jumping jacks, jumping on one foot, punching, chopping,',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'walking, running, kicking, punching, knee kicking, and stretching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'walking, swinging arms, stretching, jumping on one leg, and jumping',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'walking, squats, stretching, kicking, and punching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'walking, sitting, looking, stand up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'walk around, sit, stand up, and running',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'walking, stretching, walking and turning',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'walking, dragging, sweeping, dustpan, wipe window, and wipe mirror',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'walking around, walk up ladder, step down ladder',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'bouncing basketball, shooting basketball, dribble basketball, two handed dribble',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'walking, sitting, hand motions',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 87: {'desc': 'acrobatics',
+ 'motions': {1: {'desc': 'Jump with kick and spin',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'T-Pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'Backflip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'backflip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'cartwheels',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60}}},
+ 88: {'desc': 'acrobatics',
+ 'motions': {1: {'desc': 'backflip',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'backflips, jump onto platform, handstands, vertical pushups',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'motorcycle pose',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'stretches, cartwheels, flips, spin kicks, spins, and fall',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'cartwheel into backflip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'jump and spin kick',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 7: {'desc': 'cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 8: {'desc': 'crouch and flip backward on hands',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 9: {'desc': 'stretch and cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 10: {'desc': 'stretch and spin',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 11: {'desc': 'stretches and jumps',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 89: {'desc': 'acrobatics',
+ 'motions': {1: {'desc': 'balance object on forehead',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 2: {'desc': 'motorcycle pose',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 3: {'desc': 'flip and stand on one hand',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 4: {'desc': 'spins, flips, stand on one hand',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 5: {'desc': 'spin upside down, handstand, flips',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60},
+ 6: {'desc': 'balance beam',
+ 'files': ['tvd', 'c3d', 'amc', 'mpg', 'avi'],
+ 'fps': 60}}},
+ 90: {'desc': 'cartwheels; acrobatics; dances',
+ 'motions': {1: {'desc': 'bkwd summersult',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'cartwheel',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'jump kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'jump kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'jump kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'side flip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Flip forward onto hands and back again',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 11: {'desc': 'hand spring',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'bck flp twst fall',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'bck flp twst fall',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'front hand flip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'front hand flip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'fall on face',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'BannanaPeelSlip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'RugPullFall',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'monkey backflip',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'monkey sequence',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'monkey sequence',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'straight walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'straight walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'ball mount',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'fwd ball walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'fwd ball walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'bwk ball walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'breakdance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'sequesnce',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'russian dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'russian dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'moonwalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'arm up wide leg roll',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'wide leg roll',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'wide leg roll',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'wide leg roll',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 91: {'desc': 'walks and turns',
+ 'motions': {1: {'desc': 'Walk digital figure eight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'WalkStraight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Walk figure eight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Walking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Mummy Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Motorcycle Pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'mummy8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'mummyDigital8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'DrunkWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'SlowWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'LavishWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'TooCoolWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'SadWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'DepressedWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'ClumsyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Limp',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'QuickWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'CarefulWalk LookingAround',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'March',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'ShyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'acheyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'CasualQuickWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'CoolWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'HurtLegWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'DragBadLegWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'HurtStomachWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'SlowWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'GhettoWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'NormalWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'SexyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'NormalWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'ScaredWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'MachoWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'NormalWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'TrafficWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'WalkStraight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'SmallForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'JumpSmallForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'JumpSmallForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'Jump Turn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'Jump Turn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'JumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'Jump Turn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'JumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'FurtherJumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'SmallJumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': '180 degree jump',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': '180',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': '180',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': '90',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'WalkForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 58: {'desc': '270',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 59: {'desc': '360 smallStumble',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 60: {'desc': '360',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 61: {'desc': '360',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 62: {'desc': 'walkFigure8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 93: {'desc': 'Charleston Dance',
+ 'motions': {1: {'desc': 'Motorcycle Pose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'rangeOfMotion',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'charleston_01',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'charleston_side_by_side_female',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'charleston_side_by_side_male',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'lindyHop2',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Casual Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'xtra fancY charleston',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 94: {'desc': 'indian dance',
+ 'motions': {1: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 102: {'desc': 'Basketball',
+ 'motions': {1: {'desc': 'RightWideTurn',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 2: {'desc': 'LeftWideTurn',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 3: {'desc': 'SuperTightLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 4: {'desc': 'SuperTightRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 5: {'desc': 'RunningStraight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 6: {'desc': 'RunningWideRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 7: {'desc': 'RunningWideLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 8: {'desc': 'RunningTighterRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 9: {'desc': 'calibration',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 10: {'desc': 'RunningNoBall',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 11: {'desc': 'OffensiveMoveSpinLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 12: {'desc': 'OffensiveMoveSpinLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 13: {'desc': 'OffensiveMoveGoRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 14: {'desc': 'OffensiveMoveGoLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 15: {'desc': 'OffensiveMoveSpinRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 16: {'desc': 'WalkEvasiveLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 17: {'desc': 'WalkEvasiveRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 18: {'desc': 'FeintLeftMoveRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 19: {'desc': 'FeintRightMoveLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 20: {'desc': 'FakeShotBreakRight',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 21: {'desc': 'FakeShotBreakLeft',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 22: {'desc': 'DefensiveStraightNoStop',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 23: {'desc': 'DefensiveStraightWithStop',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 24: {'desc': 'DefensiveRightStopToStop',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 25: {'desc': 'DefensiveLeftStopToStop',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 26: {'desc': 'DefensiveMoveZigZag',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 27: {'desc': 'DefensiveMoveSideToSide',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 28: {'desc': 'DefensiveMoveSideToSide',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 29: {'desc': 'Pivoting',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 30: {'desc': 'SraightDriveFromStop',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 31: {'desc': 'RightDrive (left then right)',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 32: {'desc': 'LeftDrive (right then left)',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 33: {'desc': 'RightTightTurn',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120}}},
+ 103: {'desc': 'Charelston Dancing',
+ 'motions': {1: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'rangeOfMotion_01',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'charleston_01',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'charleston_side_by_side_female',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'charleston_side_by_side_male',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'lindyHop2',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Casual Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'xtra fancY charleston',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 104: {'desc': 'motion',
+ 'motions': {1: {'desc': 'JogThrough',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'neutral Male walk, exact footfalls',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Frankenstein male walk, exact footfalls',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'JogThrough',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'StartJog',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'StartJog',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'JogStop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'JogStop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'HappyGoLuckWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'ExcitedWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'StumbleWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'HappyStartWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'SpasticWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'SpasticStop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'SpasticStop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'CasualWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'RegularWalk8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'RegularWalkRightAngleTurns',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'SternWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'SternWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'SternWalk8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'SternWalkRightAngleTurns',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'SlowWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'SlowWalk8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'RunThrough',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'SlowWalkRightAngleTurns',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'ZombieWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'ZombieWalk8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'ZombieWalkRightAngleTurns',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'AttitudeWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'AttitudeWalk8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'AttitudeWalkRightAngleTurns',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'RunThrough',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'StartRun',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'StartRun',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'StartRun',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': 'RunStop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'RunStop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 105: {'desc': 'motion',
+ 'motions': {1: {'desc': 'WalkDigital8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'WalkStraight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Walk8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Digital8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'mummyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'MotorCyclePose',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'mummy8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'mummyDigital8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'DrunkWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'SlowWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'LavishWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'TooCoolWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'SadWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'DepressedWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'ClumsyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Limp',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'QuickWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'CarefulWalk LookingAround',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'March',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'ShyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'acheyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'CasualQuickWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'CoolWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'HurtLegWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'DragBadLegWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'HurtStomachWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'SlowWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'GhettoWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'NormalWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'SexyWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'NormalWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'ScaredWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'MachoWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'NormalWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'TrafficWalk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'WalkStraight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Forward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'SmallForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'JumpSmallForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'JumpSmallForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'JumpForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'Jump Turn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'Jump Turn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'JumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'Jump Turn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'JumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'FurtherJumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'SmallJumpTurn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': '180',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': '180',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': '180',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': '90',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'WalkForward',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 58: {'desc': '270',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 59: {'desc': '360 smallStumble',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 60: {'desc': '360',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 61: {'desc': '360',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 62: {'desc': 'walkFigure8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 106: {'desc': 'Female General Subject',
+ 'motions': {1: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 2: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 3: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 4: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 5: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 6: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 7: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 8: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 9: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 10: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 11: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 12: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 13: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 14: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 15: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 16: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 17: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 18: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 19: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 20: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 21: {'desc': 'bad AMC',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 22: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 23: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 24: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 25: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 26: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 27: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 28: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 29: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 30: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 31: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 32: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 33: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120},
+ 34: {'desc': 'clean',
+ 'files': ['tvd', 'c3d', 'amc'],
+ 'fps': 120}}},
+ 107: {'desc': 'Walking with obstacles 1',
+ 'motions': {1: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': '',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 108: {'desc': 'Walking with obstacles 2',
+ 'motions': {1: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 111: {'desc': 'Pregnant Woman',
+ 'motions': {1: {'desc': 'Walk backwards',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Bow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Crawling',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Curtsey',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Dance',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Get up from floor',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Get up from floor',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Get up from floor',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Get up from chair',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'get up from chair',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'get up from chair',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Lay down',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'March',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Mope',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Peekaboo',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Pick up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Pick up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Punch Kick',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Ring around the rosie',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Roll over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Range of motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Shrug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Walk sideways',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Walking up stairs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Standing still',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Stepping over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Stepping over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Stepping up / stepping down',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Stretch and yawn',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Throwing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'Walk and carry',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Wave',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'Yoga',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'Yoga',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'Yoga',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'Yoga',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 113: {'desc': 'Post pregnant woman',
+ 'motions': {1: {'desc': 'Walk backwards',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Bow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Curtsey',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Dance',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Walk digital 8',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Walk figure 8',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Lay down and get up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'March',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Walk, mope around',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Peekaboo',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Punch and kick',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Ring around the rosie',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Sit in chair and get up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Shrug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Walk sideway',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Walk sideways',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Walking up and down stairs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Walk up and down stairs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Standing Still',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Step over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Stretch and yawn',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Throw',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Walk and carry',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Wave',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Yoga',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Yoga',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 114: {'desc': 'Pregnant Woman',
+ 'motions': {1: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Getting up from laying down',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Range of motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Getting up from chair',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Sitting in chair',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Getting up from chair',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Walking up and down stairs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Walking up and down stairs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Walking up and down stairs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Stretching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Laying down and getting up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Stretching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Sit down and stretch',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 115: {'desc': 'Bending over',
+ 'motions': {1: {'desc': 'Pick up box, bend from waist',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Pick box up, bend from waist',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Pick box up, bend from waist',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Pick box up, bend from waist',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Pick box up, bend from waist',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Picking box up, bending knees',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Picking box up, bending knees',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Picking box up, bending knees',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Picking box up, bending knees',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Pick box up, bend from waist',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 118: {'desc': 'Jumping',
+ 'motions': {1: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Range of motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 120: {'desc': 'Various Style Walks',
+ 'motions': {1: {'desc': 'Alien Turn',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Gorilla',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Mickey cast spell',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Mickey Conducting',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Mickey Dance',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Mickey Dance',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Mickey Dance',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Mickey sneaky walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Mickey sneaking walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Mickey sneaking walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Mickey sneaking walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Mickey sneaking walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Mickey sneaking walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Mickey sneaking walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Mickey Surprised',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Mickey Surprised',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Mickey Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Mickey Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Walk slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Robot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Zombie',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 122: {'desc': 'Varying Height and Length Steps',
+ 'motions': {1: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': '',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 57: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 58: {'desc': 'cleaned',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 59: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 60: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 61: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 62: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 63: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 64: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 65: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 66: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 67: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 68: {'desc': 'clean',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 123: {'desc': 'Carry Suitcase with Varying Weights',
+ 'motions': {1: {'desc': '15.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': '15.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': '19.5lb',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': '19.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': '19.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': '19.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': '12.5lb',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': '12.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': '12.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': '12.5lb',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': '15.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': '15.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': '15.5 lbs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 124: {'desc': 'Sports Related Motions',
+ 'motions': {1: {'desc': 'Baseball Pitch',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Baseball Pitch',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Basketball Shoot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Basketball Free Throw',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Basketball Jump Shot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Basketball Lay Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Baseball Swing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Baseball Bunt',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Frisbee',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': '2 Foot Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Underhand Toss',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Underhand Fast Pitch',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 125: {'desc': 'Swimming',
+ 'motions': {1: {'desc': 'Breast Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Breast Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Break Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Breast Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Butterfly',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Free Style',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 126: {'desc': 'Swimming 2',
+ 'motions': {1: {'desc': 'Back Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Back Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Breast Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Breast Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Breast Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Fly Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Fly Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Fly Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Fly Stroke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Free Style',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Free Style',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Free Style',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Range of Motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 127: {'desc': 'Action Adventure Obstacles, running, jumping, ducking, rolling',
+ 'motions': {1: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Range of Motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Walk to Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Run to Quick Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Run Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Run Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Run Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Run Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Run Side Step Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Run Side Step Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Run Turn Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Run Turn Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Run Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Run Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Run Quick Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Run Quick Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Run Jump Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Run Jump Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Run Dive Over Roll Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Run Dive Over Roll Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Run Jump Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Run Jump Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Run Jump Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Run Jump Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Run Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Run Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'Run Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'Run Over',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 128: {'desc': 'Action Adventure Motions running, ducking, rolling, stopping',
+ 'motions': {1: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Run Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Run Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Run Duck Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Run Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Run Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Run Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Run Stop Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Run Roll Underneath',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Run Dive Over Roll Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Run Dive Over Roll Run',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 131: {'desc': 'Michael Jackson Styled Motions',
+ 'motions': {1: {'desc': 'Start Walk Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Start Walk Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Start Hop Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Start Hop Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Start Duck Underneath Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Start Duck Underneath Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Jump Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Jump Stop',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Start Walk Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Start Walk Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Start Walk Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Start Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Start Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Start Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 132: {'desc': 'Varying Weird Walks',
+ 'motions': {1: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Walk With Arms Out, balancing',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Walk Backwards',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Walk Duck Footed',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Walk With Knees Bent',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Walk Crossover',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Walk Fast',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Walk Fast',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Walk Fast',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Walk Fast',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Walk Fast',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Walk Fast',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Hop on left foot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Hop on left foot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Hop on left foot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Hop on left foot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Hop on left foot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Hop on left foot',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Bouncy Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Bouncy Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Bouncy Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Bouncy Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Bouncy Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Bouncy Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'Walk Leaning To The Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'Walk Leaning To The Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'Pigeon Toed Walking',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'Walk With Stiff Arms',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'Walk With Stiff Arms',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'Walk Swinging Shoulders',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'Walk Swinging Shoulders',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'Walk Swinging Shoulders',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'Walk Slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'Walk Slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'Walk Slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'Walk Slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'Walk Slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'Walk Slow',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'Tpose',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'Range of Motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'Walk With Legs Apart',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'Walk With Wild Arms',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'Walk With Wild Legs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 56: {'desc': 'Walk With Wild Legs',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 133: {'desc': 'Baby Styled Walk',
+ 'motions': {1: {'desc': 'Walk Crawl',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Walk Crawl',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Walk Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Walk Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Walk Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Walk Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Walk Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Stretch Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Stretch Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Stretch Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Walk Stop Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Walk Stop Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Walk Stop Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Walk Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Walk Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Walk Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Walk Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Walk ZigZag',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Range of Motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 134: {'desc': 'Skateboard Motions',
+ 'motions': {1: {'desc': 'Duck Under',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Go Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Lean Turn Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Pump Jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Push Turn Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Push Turn Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Push Turn Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Push Turn Right',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Start',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Start',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Stop and Go',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Stop and Go',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Stop ang Go',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Lean Turn Left',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 135: {'desc': 'Martial Arts Walks',
+ 'motions': {1: {'desc': 'Bassai',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Empi',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Empi',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Front Kick',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Gedanbarai',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Heiansyodan',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Mawashigeri',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Oiduki',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Syutouuke',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Yokogeri',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 136: {'desc': 'Weird Walks',
+ 'motions': {1: {'desc': 'Walk Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Walk Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Walk Backwards Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Walk Backwards Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Walk on Toes Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Walk on Toes Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Walk Backward on Toes Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Walk Backward on Toes Bent Forward',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Walk Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Walk Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Walk Backwards Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Walk Backwards Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Walk on Toes Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Walk on Toes Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Walk Backwards on Toes Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Walk Backwards on Toes Crouched',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Flamingo, lift legs high',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Flamingo, lift legs high',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Motorcycle',
+ 'files': ['amc', 'avi'],
+ 'fps': 60},
+ 20: {'desc': 'Normal Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Normal Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Normal Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Normal Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Normal Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Normal Walk Backwards',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Normal Walk Backwards',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Walk on Toes',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Walk on Toes',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Walk Backwards on Toes',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Walk Backwards on Toes',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Quail, quick little steps',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Quail, quick little steps',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Range of Motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 137: {'desc': 'Stylized Motions',
+ 'motions': {1: {'desc': 'Cat Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Cat Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Cat Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Cat Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Chicken Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Chicken Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Chicken Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Chicken Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Dinosaur Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Dinosaur Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Dinosaur Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Dinosaur Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Drunk Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Drunk Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Drunk Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Drunk Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Gangly Teen Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Gangly Teen Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Gangly Teen Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Gangly Teen Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Graceful Lady Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Graceful Lady Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Graceful Lady Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Graceful Lady Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Motorcycle',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Normal Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Normal Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Normal Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Normal Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Old Man Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Old Man Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Old Man Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Old Man Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Range of Motion',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'Sexy Lady Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'Sexy Lady Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Sexy Lady Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'Sexy Lady Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'Strong Man Coffee Mug',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'Strong Man Pick Up',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'Strong Man Wait',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'Strong Man Walk',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 138: {'desc': 'Marching, Walking and Talking',
+ 'motions': {1: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 43: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 44: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 45: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 46: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 47: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 48: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 49: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 50: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 51: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 52: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 53: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 54: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 55: {'desc': 'Story',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 139: {'desc': 'Action Walks, sneaking, wounded, looking around',
+ 'motions': {1: {'desc': 'Looking Around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Shifting Weight',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Looking Around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Looking Around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Pulling a Gun',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Poking Around On The Ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Poking Around On The Ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Poking Around On The Ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Ducking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Run To Sneak',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Run in Circles',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Run in Circles',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Sneak Sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Sneak Sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Get Up From Ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Get Up From Ground',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Get Up From Ground Laying on Back',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Walk Wounded Leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Walk Wounded Leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Range Of Motion',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Walk Wounded Leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Walk Wounded Leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Walk Wounded Leg',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Giving Directions',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Looking Around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Looking Around',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Walking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Sneaking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Walking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Sneaking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Sneaking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Sneaking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Sneaking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 140: {'desc': 'Getting Up From Ground',
+ 'motions': {1: {'desc': 'Get Up Face Down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Get Up Face Down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Get Up Laying on Side',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Get Up Laying on Side',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Motorcycle',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Idle',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Idle',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Get Up From Ground Laying on Back',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Get Up From Ground Laying on Back',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 141: {'desc': 'General Subject Capture',
+ 'motions': {1: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Jump Distances',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Jump Sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Jump Twist',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Walk Up and Over',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Steop On Walk Down',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Step Over',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Toss and Catch',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Throw and Catch',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Dance, Twist',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Stretch and Yawn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Punch and Kick',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Range of Motion',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Wave Hello',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Sit on Stool',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Peek a Boo',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Waiting',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Shrug',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'High Five',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Shake Hands',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Around the world High Five Low',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Curtsey',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Mope',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Slap Hands, Throw it Back',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Random Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Random Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Walk Backwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Walk Sideways, Cross Legs',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Walk Sideways, Foot to Foot',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 142: {'desc': 'Stylized Walks',
+ 'motions': {1: {'desc': 'Childish',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Clumsy',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Clumsy',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Cool',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Depressed',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Elated',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Elderlyman',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Happy',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Joy',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Lavish',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Marching',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Painfulleftknee',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Relaxed',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Rushed',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Sad',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Scared',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Scared',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Sexy',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Shy',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Singing in the rain jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Singing in the rain jump',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Sneaky',
+ 'files': ['c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 143: {'desc': 'General Subject Capture',
+ 'motions': {1: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 2: {'desc': 'Run to Stop',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 3: {'desc': 'Start to Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 4: {'desc': 'Run Figure 8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 5: {'desc': 'Jumping Distances',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 6: {'desc': 'Jumping Heights',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 7: {'desc': 'Jumping Sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 8: {'desc': 'Jumping Twists',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 9: {'desc': 'Jumping Twists',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 10: {'desc': 'Walk And Pick up Tool Box',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 11: {'desc': 'Walk And Pick up Box',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 12: {'desc': 'Walk And Pick up Toolbox',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 13: {'desc': 'Walk and Pick up Laundry Basket',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 14: {'desc': 'Walk And Step Over',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 15: {'desc': 'Walk And Step Over',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 16: {'desc': 'Walk And Step Over',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 17: {'desc': 'Walk Up Stairs And Over',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 18: {'desc': 'Sit Down And Get Up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 19: {'desc': 'Sit On Stool And Get Up',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 20: {'desc': 'Catch And Throw',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 21: {'desc': 'Range Of Motion',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 22: {'desc': 'Catch And Throw Football',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 23: {'desc': 'Punching',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 24: {'desc': 'Kicking',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 25: {'desc': 'Waving',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 26: {'desc': 'Washing Window',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 27: {'desc': 'Washing Window',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 28: {'desc': 'Sweeping, Push Broom',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 29: {'desc': 'Pacing',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 30: {'desc': 'Stretch And Yawn',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 31: {'desc': 'Hopscotch',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 32: {'desc': 'Walk',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 33: {'desc': 'Peek A Boo',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 34: {'desc': 'Chicken Dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 35: {'desc': 'Macarena Dance',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 36: {'desc': 'Airplane',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 37: {'desc': 'Climb Up And Down Ladder',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 38: {'desc': 'Walk Digital 8',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 39: {'desc': 'Walk Backwards',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 40: {'desc': 'Walk Sideways',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 41: {'desc': 'Sneak',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120},
+ 42: {'desc': 'Run',
+ 'files': ['tvd', 'c3d', 'amc', 'avi'],
+ 'fps': 120}}},
+ 144: {'desc': 'punching female',
+ 'motions': {1: {'desc': 'Cartwheels',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 2: {'desc': 'Cartwheels001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 3: {'desc': 'Figure8s',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 4: {'desc': 'Figure8s001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 5: {'desc': 'Front_Kicking',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 6: {'desc': 'Front_Kicking001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 7: {'desc': 'Left_Blocks',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 8: {'desc': 'Left_Blocks001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 9: {'desc': 'Left_Front_Kicking',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 10: {'desc': 'Left_Front_Kicking001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 11: {'desc': 'Left_Lunges',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 12: {'desc': 'Left_Lunges001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 13: {'desc': 'Left_Punch_Sequence001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 14: {'desc': 'Left_Punch_Sequence002',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 15: {'desc': 'Left_Spin_reach001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 16: {'desc': 'Left_Spin_reach002',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 17: {'desc': 'Lunges',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 18: {'desc': 'Lunges001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 19: {'desc': 'motorcycle pose',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 20: {'desc': 'Punch_Sequence',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 21: {'desc': 'Punch_Sequence001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 22: {'desc': 'Reach_Left001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 23: {'desc': 'Reach_Left002',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 24: {'desc': 'Reach_Right',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 25: {'desc': 'Reach_Right001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 26: {'desc': 'Right_Blocks',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 27: {'desc': 'Right_Blocks001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 28: {'desc': 'Right_Spin_reach',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 29: {'desc': 'Right_Spin_reach001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 30: {'desc': 'Sun Salutation',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 31: {'desc': 'Sun Salutation001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 32: {'desc': 'Sun Salutation002',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 33: {'desc': 'Walking',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120},
+ 34: {'desc': 'Walking001',
+ 'files': ['c3d', 'amc'],
+ 'fps': 120}}}}
+
+# End of Mocap Library
+
+if __name__ == '__main__':
+ # The following is the code that compiled the data above.
+ # If you execute this file it should output to stdout the exact same code.
+
+ import re
+ import os
+ from pprint import pformat
+ from urllib.request import urlopen
+
+ subjects_re = re.compile(
+ r"(?ms)909090.*?Subject\ \#(?P<subjno>\d+)\s+(?P<desc>[^<]*).*?"
+ r"(?P<subjskel>http.*?asf).*?BGCOLOR(?P<motionBlock>.*?)/TR>\n")
+ motions_re = re.compile(
+ r"(?ms)<TD>(?P<motno>\d+)</TD><TD>(?P<desc>[^<].*?)"
+ r"</TD>(?P<urls>.*?)<TD>(?P<fps>\d+)</TD>")
+ urls_re = re.compile('(http.*?)(...)"')
+ myself_re = re.compile(r"(?ms)(.*# Carnegie.*?\n).*?(# End of.*$)")
+
+ subjects = {}
+ if not os.path.exists("search.html"):
+ src = urlopen(search_url)
+ data = src.read()
+ with open("search.html", 'wb') as out:
+ out.write(data)
+ for match in subjects_re.finditer(open("search.html", 'rt').read()):
+ d = match.groupdict()
+ sub = subjects.setdefault(int(d['subjno']), {})
+ sub['desc'] = d['desc'][1:-2]
+ assert(d['subjskel'] == skeleton_url.format(int(d['subjno'])))
+ sub['motions'] = {}
+ for m2 in motions_re.finditer(d['motionBlock']):
+ d2 = m2.groupdict()
+ mot = sub['motions'].setdefault(int(d2['motno']), {})
+ mot['desc'] = d2['desc'].strip()
+ mot['fps'] = int(d2['fps'])
+ for u in urls_re.finditer(d2['urls']):
+ murl = motion_url.format(int(d['subjno']), int(d2['motno']))
+ assert(u.group(1) == murl)
+ mot.setdefault('files', []).append(u.group(2))
+
+ m = myself_re.match(open(__file__).read())
+ print("{0}\nsubjects={1}\n\n{2}".format(
+ m.group(1), pformat(subjects), m.group(2)), end='')
diff --git a/release/scripts/addons_contrib/cursor_control/__init__.py b/release/scripts/addons_contrib/cursor_control/__init__.py
new file mode 100644
index 0000000..7da634a
--- /dev/null
+++ b/release/scripts/addons_contrib/cursor_control/__init__.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+# ##### 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 LICENSE BLOCK #####
+
+
+
+# Blender Add-Ons menu registration (in User Prefs)
+bl_info = {
+ "name": "Cursor Control",
+ "author": "Morgan Mörtsell (Seminumerical)",
+ "version": (0, 7, 0),
+ "blender": (2, 59, 0),
+ "location": "View3D > Properties > Cursor",
+ "description": "Control the Cursor",
+ "warning": "buggy, may crash other addons", # used for warning icon and text in addons panel
+ "wiki_url": "http://blenderpythonscripts.wordpress.com/",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27253",
+ "category": "3D View"}
+
+
+
+import bpy
+
+# To support reload properly, try to access a package var, if it's there, reload everything
+if "local_var" in locals():
+ import imp
+ imp.reload(data)
+ imp.reload(ui)
+ imp.reload(operators)
+ imp.reload(history)
+ imp.reload(memory)
+else:
+ from cursor_control import data
+ from cursor_control import ui
+ from cursor_control import operators
+ from cursor_control import history
+ from cursor_control import memory
+
+local_var = True
+
+def register():
+ bpy.utils.register_module(__name__)
+ # Register Cursor Control Structure
+ bpy.types.Scene.cursor_control = bpy.props.PointerProperty(type=data.CursorControlData, name="")
+ bpy.types.Scene.cursor_history = bpy.props.PointerProperty(type=history.CursorHistoryData, name="")
+ bpy.types.Scene.cursor_memory = bpy.props.PointerProperty(type=memory.CursorMemoryData, name="")
+ # Register menu
+ bpy.types.VIEW3D_MT_snap.append(ui.menu_callback)
+
+def unregister():
+ # Register menu
+ bpy.types.VIEW3D_MT_snap.remove(ui.menu_callback)
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/cursor_control/data.py b/release/scripts/addons_contrib/cursor_control/data.py
new file mode 100644
index 0000000..fcd82d1
--- /dev/null
+++ b/release/scripts/addons_contrib/cursor_control/data.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+# ##### 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 LICENSE BLOCK #####
+
+
+
+"""
+ TODO:
+
+ IDEAS:
+
+ LATER:
+
+ ISSUES:
+ Bugs:
+ Mites:
+
+ QUESTIONS:
+
+
+"""
+
+
+
+import bpy
+import bgl
+import math
+from mathutils import Vector, Matrix
+from mathutils import geometry
+from misc_utils import *
+from constants_utils import *
+from cursor_utils import *
+from ui_utils import *
+from geometry_utils import *
+
+
+PRECISION = 4
+
+
+class CursorControlData(bpy.types.PropertyGroup):
+ # Step length properties
+ stepLengthEnable = bpy.props.BoolProperty(name="Use step length",description="Use step length",default=0)
+ stepLengthMode = bpy.props.EnumProperty(items=[
+ ("Mode", "Mode", "Mode"),
+ ("Absolute", "Absolute", "Absolute"),
+ ("Proportional", "Proportional", "Proportional")],
+ default="Proportional")
+ stepLengthValue = bpy.props.FloatProperty(name="",precision=PRECISION,default=PHI)
+ # Property for linex result select...
+ linexChoice = bpy.props.IntProperty(name="",default=-1)
+ deltaVector = bpy.props.FloatVectorProperty(name="",precision=PRECISION,default=(1,0,0))
+
+ def hideLinexChoice(self):
+ self.linexChoice = -1
+
+ def cycleLinexCoice(self,limit):
+ qc = self.linexChoice + 1
+ if qc<0:
+ qc = 1
+ if qc>=limit:
+ qc = 0
+ self.linexChoice = qc
+
+ def setCursor(self,v):
+ if self.stepLengthEnable:
+ c = CursorAccess.getCursor()
+ if((Vector(c)-Vector(v)).length>0):
+ if self.stepLengthMode=='Absolute':
+ v = Vector(v)-Vector(c)
+ v.normalize()
+ v = v*self.stepLengthValue + Vector(c)
+ if self.stepLengthMode=='Proportional':
+ v = (Vector(v)-Vector(c))*self.stepLengthValue + Vector(c)
+ CursorAccess.setCursor(Vector(v))
+
+ def guiStates(self,context):
+ tvs = 0
+ tes = 0
+ tfs = 0
+ edit_mode = False
+ obj = context.active_object
+ if (context.mode == 'EDIT_MESH'):
+ if (obj and obj.type=='MESH' and obj.data):
+ tvs = obj.data.total_vert_sel
+
+ tes = obj.data.total_edge_sel
+ tfs = obj.data.total_face_sel
+ edit_mode = True
+ return (tvs, tes, tfs, edit_mode)
+
+ def invertDeltaVector(self):
+ self.deltaVector = Vector([0,0,0])-Vector(self.deltaVector)
+
+ def normalizeDeltaVector(self):
+ q = Vector(self.deltaVector)
+ q.normalize()
+ self.deltaVector = q
+
+ def addDeltaVectorToCursor(self):
+ c = CursorAccess.getCursor()
+ CursorAccess.setCursor(Vector(c)+Vector(self.deltaVector))
+
+ def subDeltaVectorToCursor(self):
+ c = CursorAccess.getCursor()
+ CursorAccess.setCursor(Vector(c)-Vector(self.deltaVector))
diff --git a/release/scripts/addons_contrib/cursor_control/history.py b/release/scripts/addons_contrib/cursor_control/history.py
new file mode 100644
index 0000000..14f354d
--- /dev/null
+++ b/release/scripts/addons_contrib/cursor_control/history.py
@@ -0,0 +1,288 @@
+# -*- coding: utf-8 -*-
+# ##### 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 LICENSE BLOCK #####
+
+
+
+"""
+ TODO:
+
+ IDEAS:
+
+ LATER:
+
+ ISSUES:
+ Bugs:
+ Seg-faults when unregistering addon...
+ Mites:
+ * History back button does not light up on first cursor move.
+ It does light up on the second, or when mouse enters the tool-area
+ * Switching between local and global view triggers new cursor position in history trace.
+ * Each consecutive click on the linex operator triggers new cursor position in history trace.
+ (2011-01-16) Was not able to fix this because of some strange script behaviour
+ while trying to clear linexChoice from addHistoryLocation
+
+ QUESTIONS:
+
+
+
+"""
+
+
+
+import bpy
+import bgl
+import math
+from mathutils import Vector, Matrix
+from mathutils import geometry
+from misc_utils import *
+from constants_utils import *
+from cursor_utils import *
+from ui_utils import *
+
+
+
+class CursorHistoryData(bpy.types.PropertyGroup):
+ # History tracker
+ historyDraw = bpy.props.BoolProperty(description="Draw history trace in 3D view",default=1)
+ historyDepth = 144
+ historyWindow = 12
+ historyPosition = [-1] # Integer must be in a list or else it can not be written to
+ historyLocation = []
+ #historySuppression = [False] # Boolean must be in a list or else it can not be written to
+
+ def addHistoryLocation(self, l):
+ if(self.historyPosition[0]==-1):
+ self.historyLocation.append(l.copy())
+ self.historyPosition[0]=0
+ return
+ if(l==self.historyLocation[self.historyPosition[0]]):
+ return
+ #if self.historySuppression[0]:
+ #self.historyPosition[0] = self.historyPosition[0] - 1
+ #else:
+ #self.hideLinexChoice()
+ while(len(self.historyLocation)>self.historyPosition[0]+1):
+ self.historyLocation.pop(self.historyPosition[0]+1)
+ #self.historySuppression[0] = False
+ self.historyLocation.append(l.copy())
+ if(len(self.historyLocation)>self.historyDepth):
+ self.historyLocation.pop(0)
+ self.historyPosition[0] = len(self.historyLocation)-1
+ #print (self.historyLocation)
+
+ #def enableHistorySuppression(self):
+ #self.historySuppression[0] = True
+
+ def previousLocation(self):
+ if(self.historyPosition[0]<=0):
+ return
+ self.historyPosition[0] = self.historyPosition[0] - 1
+ CursorAccess.setCursor(self.historyLocation[self.historyPosition[0]].copy())
+
+ def nextLocation(self):
+ if(self.historyPosition[0]<0):
+ return
+ if(self.historyPosition[0]+1==len(self.historyLocation)):
+ return
+ self.historyPosition[0] = self.historyPosition[0] + 1
+ CursorAccess.setCursor(self.historyLocation[self.historyPosition[0]].copy())
+
+
+
+class VIEW3D_OT_cursor_previous(bpy.types.Operator):
+ """Previous cursor location"""
+ bl_idname = "view3d.cursor_previous"
+ bl_label = "Previous cursor location"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_history
+ cc.previousLocation()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_next(bpy.types.Operator):
+ """Next cursor location"""
+ bl_idname = "view3d.cursor_next"
+ bl_label = "Next cursor location"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_history
+ cc.nextLocation()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_history_show(bpy.types.Operator):
+ """Show cursor trace"""
+ bl_idname = "view3d.cursor_history_show"
+ bl_label = "Show cursor trace"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_history
+ cc.historyDraw = True
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_history_hide(bpy.types.Operator):
+ """Hide cursor trace"""
+ bl_idname = "view3d.cursor_history_hide"
+ bl_label = "Hide cursor trace"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_history
+ cc.historyDraw = False
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_PT_cursor_history(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Cursor History"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ # Display in object or edit mode.
+ cc = context.scene.cursor_history
+ cc.addHistoryLocation(CursorAccess.getCursor())
+ if (context.area.type == 'VIEW_3D' and
+ (context.mode == 'EDIT_MESH'
+ or context.mode == 'OBJECT')):
+ return 1
+
+ return 0
+
+ def draw_header(self, context):
+ layout = self.layout
+ cc = context.scene.cursor_history
+ if cc.historyDraw:
+ GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_OFF', "view3d.cursor_history_hide", False)
+ else:
+ GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_ON' , "view3d.cursor_history_show", False)
+
+ def draw(self, context):
+ layout = self.layout
+ sce = context.scene
+ cc = context.scene.cursor_history
+
+ row = layout.row()
+ row.label("Navigation: ")
+ GUI.drawIconButton(cc.historyPosition[0]>0, row, 'PLAY_REVERSE', "view3d.cursor_previous")
+ #if(cc.historyPosition[0]<0):
+ #row.label(" -- ")
+ #else:
+ #row.label(" "+str(cc.historyPosition[0])+" ")
+ GUI.drawIconButton(cc.historyPosition[0]<len(cc.historyLocation)-1, row, 'PLAY', "view3d.cursor_next")
+
+ row = layout.row()
+ col = row.column()
+ col.prop(CursorAccess.findSpace(), "cursor_location")
+
+
+
+
+class VIEW3D_PT_cursor_history_init(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Register callback"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ initDone = False
+
+ @classmethod
+ def poll(cls, context):
+ if VIEW3D_PT_cursor_history_init.initDone:
+ return 0
+ print ("Cursor History draw-callback registration...")
+ sce = context.scene
+ if context.area.type == 'VIEW_3D':
+ for reg in context.area.regions:
+ if reg.type == 'WINDOW':
+ # Register callback for SL-draw
+ reg.callback_add(
+ cursor_history_draw,
+ (cls,context),
+ 'POST_PIXEL')
+ VIEW3D_PT_cursor_history_init.initDone = True
+ print ("Cursor History draw-callback registered")
+ # Unregister to prevent double registration...
+ # Started to fail after v2.57
+ # bpy.types.unregister(VIEW3D_PT_cursor_history_init)
+ else:
+ print("View3D not found, cannot run operator")
+ return 0
+
+ def draw_header(self, context):
+ pass
+
+ def draw(self, context):
+ pass
+
+
+
+def cursor_history_draw(cls,context):
+ cc = context.scene.cursor_history
+
+ draw = 0
+ if hasattr(cc, "historyDraw"):
+ draw = cc.historyDraw
+
+ if(draw):
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glShadeModel(bgl.GL_FLAT)
+ alpha = 1-PHI_INV
+ # History Trace
+ if cc.historyPosition[0]<0:
+ return
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ ccc = 0
+ for iii in range(cc.historyWindow+1):
+ ix_rel = iii - int(cc.historyWindow / 2)
+ ix = cc.historyPosition[0] + ix_rel
+ if(ix<0 or ix>=len(cc.historyLocation)):
+ continue
+ ppp = region3d_get_2d_coordinates(context, cc.historyLocation[ix])
+ if(ix_rel<=0):
+ bgl.glColor4f(0, 0, 0, alpha)
+ else:
+ bgl.glColor4f(1, 0, 0, alpha)
+ bgl.glVertex2f(ppp[0], ppp[1])
+ ccc = ccc + 1
+ bgl.glEnd()
diff --git a/release/scripts/addons_contrib/cursor_control/memory.py b/release/scripts/addons_contrib/cursor_control/memory.py
new file mode 100644
index 0000000..1d2d9db
--- /dev/null
+++ b/release/scripts/addons_contrib/cursor_control/memory.py
@@ -0,0 +1,307 @@
+# -*- coding: utf-8 -*-
+# ##### 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 LICENSE BLOCK #####
+
+
+
+"""
+ TODO:
+
+ IDEAS:
+ Add/Subtract
+
+ LATER:
+
+ ISSUES:
+ Bugs:
+ Mites:
+ CTRL-Z forces memory to world origin (0,0,0)... why??
+ Happens only if undo reaches 'default world state'
+ How to Reproduce:
+ 1. File->New
+ 2. Move 3D-cursor
+ 3. Set memory
+ 4. Move cube
+ 5. CTRL-Z
+
+ QUESTIONS:
+
+
+"""
+
+
+
+import bpy
+import bgl
+import math
+from mathutils import Vector, Matrix
+from mathutils import geometry
+from misc_utils import *
+from constants_utils import *
+from cursor_utils import *
+from ui_utils import *
+
+
+
+PRECISION = 4
+
+
+
+class CursorMemoryData(bpy.types.PropertyGroup):
+
+ savedLocationDraw = bpy.props.BoolProperty(description="Draw SL cursor in 3D view",default=1)
+ savedLocation = bpy.props.FloatVectorProperty(name="",description="Saved Location",precision=PRECISION)
+
+
+class VIEW3D_OT_cursor_memory_save(bpy.types.Operator):
+ """Save cursor location"""
+ bl_idname = "view3d.cursor_memory_save"
+ bl_label = "Save cursor location"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_memory
+ cc.savedLocation = CursorAccess.getCursor()
+ CursorAccess.setCursor(cc.savedLocation)
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_memory_swap(bpy.types.Operator):
+ """Swap cursor location"""
+ bl_idname = "view3d.cursor_memory_swap"
+ bl_label = "Swap cursor location"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ location = CursorAccess.getCursor().copy()
+ cc = context.scene.cursor_memory
+ CursorAccess.setCursor(cc.savedLocation)
+ cc.savedLocation = location
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_memory_recall(bpy.types.Operator):
+ """Recall cursor location"""
+ bl_idname = "view3d.cursor_memory_recall"
+ bl_label = "Recall cursor location"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_memory
+ CursorAccess.setCursor(cc.savedLocation)
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_memory_show(bpy.types.Operator):
+ """Show cursor memory"""
+ bl_idname = "view3d.cursor_memory_show"
+ bl_label = "Show cursor memory"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_memory
+ cc.savedLocationDraw = True
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_memory_hide(bpy.types.Operator):
+ """Hide cursor memory"""
+ bl_idname = "view3d.cursor_memory_hide"
+ bl_label = "Hide cursor memory"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_memory
+ cc.savedLocationDraw = False
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_PT_cursor_memory(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Cursor Memory"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ # Display in object or edit mode.
+ if (context.area.type == 'VIEW_3D' and
+ (context.mode == 'EDIT_MESH'
+ or context.mode == 'OBJECT')):
+ return 1
+
+ return 0
+
+ def draw_header(self, context):
+ layout = self.layout
+ cc = context.scene.cursor_memory
+ if cc.savedLocationDraw:
+ GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_OFF', "view3d.cursor_memory_hide", False)
+ else:
+ GUI.drawIconButton(True, layout, 'RESTRICT_VIEW_ON' , "view3d.cursor_memory_show", False)
+ #layout.prop(sce, "cursor_memory.savedLocationDraw")
+
+ def draw(self, context):
+ layout = self.layout
+ sce = context.scene
+ cc = context.scene.cursor_memory
+
+ row = layout.row()
+ col = row.column()
+ row2 = col.row()
+ GUI.drawIconButton(True, row2, 'FORWARD', "view3d.cursor_memory_save")
+ row2 = col.row()
+ GUI.drawIconButton(True, row2, 'FILE_REFRESH', "view3d.cursor_memory_swap")
+ row2 = col.row()
+ GUI.drawIconButton(True, row2, 'BACK' , "view3d.cursor_memory_recall")
+ col = row.column()
+ col.prop(cc, "savedLocation")
+
+
+
+class VIEW3D_PT_cursor_memory_init(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Register callback"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ initDone = False
+
+ @classmethod
+ def poll(cls, context):
+ if VIEW3D_PT_cursor_memory_init.initDone:
+ return 0
+ print ("Cursor Memory draw-callback registration...")
+ sce = context.scene
+ if context.area.type == 'VIEW_3D':
+ for reg in context.area.regions:
+ if reg.type == 'WINDOW':
+ # Register callback for SL-draw
+ reg.callback_add(
+ cursor_memory_draw,
+ (cls,context),
+ 'POST_PIXEL')
+ VIEW3D_PT_cursor_memory_init.initDone = True
+ print ("Cursor Memory draw-callback registered")
+ # Unregister to prevent double registration...
+ # Started to fail after v2.57
+ # bpy.types.unregister(VIEW3D_PT_cursor_memory_init)
+ else:
+ print("View3D not found, cannot run operator")
+ return 0
+
+ def draw_header(self, context):
+ pass
+
+ def draw(self, context):
+ pass
+
+
+
+def cursor_memory_draw(cls,context):
+ cc = context.scene.cursor_memory
+
+ draw = 0
+ if hasattr(cc, "savedLocationDraw"):
+ draw = cc.savedLocationDraw
+
+ if(draw):
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glShadeModel(bgl.GL_FLAT)
+ p1 = Vector(cc.savedLocation)
+ location = region3d_get_2d_coordinates(context, p1)
+ alpha = 1-PHI_INV
+ # Circle
+ color = ([0.33, 0.33, 0.33],
+ [1, 1, 1],
+ [0.33, 0.33, 0.33],
+ [1, 1, 1],
+ [0.33, 0.33, 0.33],
+ [1, 1, 1],
+ [0.33, 0.33, 0.33],
+ [1, 1, 1],
+ [0.33, 0.33, 0.33],
+ [1, 1, 1],
+ [0.33, 0.33, 0.33],
+ [1, 1, 1],
+ [0.33, 0.33, 0.33],
+ [1, 1, 1])
+ offset = ([-4.480736161291701, -8.939966636005579],
+ [-0.158097634992133, -9.998750178787843],
+ [4.195854066857877, -9.077158622037636],
+ [7.718765411993642, -6.357724476147943],
+ [9.71288060283854, -2.379065025383466],
+ [9.783240669628, 2.070797430975971],
+ [7.915909938224691, 6.110513059466902],
+ [4.480736161291671, 8.939966636005593],
+ [0.15809763499209872, 9.998750178787843],
+ [-4.195854066857908, 9.077158622037622],
+ [-7.718765411993573, 6.357724476148025],
+ [-9.712880602838549, 2.379065025383433],
+ [-9.783240669627993, -2.070797430976005],
+ [-7.915909938224757, -6.110513059466818])
+ bgl.glBegin(bgl.GL_LINE_LOOP)
+ for i in range(14):
+ bgl.glColor4f(color[i][0], color[i][1], color[i][2], alpha)
+ bgl.glVertex2f(location[0]+offset[i][0], location[1]+offset[i][1])
+ bgl.glEnd()
+
+ # Crosshair
+ offset2 = 20
+ offset = 5
+ bgl.glColor4f(0, 0, 0, alpha)
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2f(location[0]-offset2, location[1])
+ bgl.glVertex2f(location[0]- offset, location[1])
+ bgl.glEnd()
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2f(location[0]+ offset, location[1])
+ bgl.glVertex2f(location[0]+offset2, location[1])
+ bgl.glEnd()
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2f(location[0], location[1]-offset2)
+ bgl.glVertex2f(location[0], location[1]- offset)
+ bgl.glEnd()
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2f(location[0], location[1]+ offset)
+ bgl.glVertex2f(location[0], location[1]+offset2)
+ bgl.glEnd()
+
+
diff --git a/release/scripts/addons_contrib/cursor_control/operators.py b/release/scripts/addons_contrib/cursor_control/operators.py
new file mode 100644
index 0000000..3840db5
--- /dev/null
+++ b/release/scripts/addons_contrib/cursor_control/operators.py
@@ -0,0 +1,895 @@
+# -*- coding: utf-8 -*-
+# ##### 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 LICENSE BLOCK #####
+
+
+
+"""
+ TODO:
+
+ IDEAS:
+
+ LATER:
+
+ ISSUES:
+ Bugs:
+ Mites:
+
+ QUESTIONS:
+
+
+"""
+
+
+
+import bpy
+import bgl
+import math
+from mathutils import Vector, Matrix
+from mathutils import geometry
+from misc_utils import *
+from constants_utils import *
+from cursor_utils import *
+from ui_utils import *
+from geometry_utils import *
+
+
+class VIEW3D_OT_cursor_to_origin(bpy.types.Operator):
+ """Move to world origin"""
+ bl_idname = "view3d.cursor_to_origin"
+ bl_label = "Move to world origin"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ cc.setCursor([0,0,0])
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_to_active_object_center(bpy.types.Operator):
+ """Move to active object origin"""
+ bl_idname = "view3d.cursor_to_active_object_center"
+ bl_label = "Move to active object origin"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ cc.setCursor(context.active_object.location)
+ return {'FINISHED'}
+
+
+
+#class VIEW3D_OT_cursor_to_nearest_object(bpy.types.Operator):
+ #"""Move to center of nearest object"""
+ #bl_idname = "view3d.cursor_to_nearest_object"
+ #bl_label = "Move to center of nearest object"
+ #bl_options = {'REGISTER'}
+
+ #def modal(self, context, event):
+ #return {'FINISHED'}
+
+ #def execute(self, context):
+ #cc.setCursor(context.active_object.location)
+ #return {'FINISHED'}
+
+
+
+#class VIEW3D_OT_cursor_to_selection_midpoint(bpy.types.Operator):
+ #"""Move to active objects median"""
+ #bl_idname = "view3d.cursor_to_selection_midpoint"
+ #bl_label = "Move to active objects median"
+ #bl_options = {'REGISTER'}
+
+ #def modal(self, context, event):
+ #return {'FINISHED'}
+
+ #def execute(self, context):
+ #location = Vector((0,0,0))
+ #n = 0
+ #for obj in context.selected_objects:
+ #location = location + obj.location
+ #n += 1
+ #if (n==0):
+ #return {'CANCELLED'}
+ #location = location / n
+ #cc.setCursor(location)
+ #return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_to_sl(bpy.types.Operator):
+ """Move to saved location"""
+ bl_idname = "view3d.cursor_to_sl"
+ bl_label = "Move to saved location"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ if hasattr(context.scene, "cursor_memory"):
+ cm = context.scene.cursor_memory
+ cc.hideLinexChoice()
+ cc.setCursor(cm.savedLocation)
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_to_sl_mirror(bpy.types.Operator):
+ """Mirror cursor around SL or selection"""
+ bl_idname = "view3d.cursor_to_sl_mirror"
+ bl_label = "Mirror cursor around SL or selection"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def mirror(self, cc, p):
+ v = p - Vector(CursorAccess.getCursor())
+ cc.setCursor(p + v)
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ obj = context.active_object
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+
+ if obj==None or obj.data.total_vert_sel==0:
+ if hasattr(context.scene, "cursor_memory"):
+ cm = context.scene.cursor_memory
+ self.mirror(cc, Vector(cm.savedLocation))
+ return {'FINISHED'}
+
+ mat = obj.matrix_world
+
+ if obj.data.total_vert_sel==1:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ self.mirror(cc, mat*Vector(sf[0].co))
+ return {'FINISHED'}
+
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ if obj.data.total_vert_sel==2:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ p = G3.closestP2L(c, Vector(sf[0].co), Vector(sf[1].co))
+ self.mirror(cc, mat*p)
+ return {'FINISHED'}
+
+ if obj.data.total_vert_sel==3:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ normal = (v1-v0).cross(v2-v0)
+ normal.normalize();
+ p = G3.closestP2S(c, v0, normal)
+ self.mirror(cc, mat*p)
+ return {'FINISHED'}
+
+ if obj.data.total_face_sel==1:
+ sf = [f for f in obj.data.faces if f.select == 1]
+ v0 = Vector(obj.data.vertices[sf[0].vertices[0]].co)
+ v1 = Vector(obj.data.vertices[sf[0].vertices[1]].co)
+ v2 = Vector(obj.data.vertices[sf[0].vertices[2]].co)
+ normal = (v1-v0).cross(v2-v0)
+ normal.normalize();
+ p = G3.closestP2S(c, v0, normal)
+ self.mirror(cc, mat*p)
+ return {'FINISHED'}
+
+ return {'CANCELLED'}
+
+
+class VIEW3D_OT_cursor_to_vertex(bpy.types.Operator):
+ """Move to closest vertex"""
+ bl_idname = "view3d.cursor_to_vertex"
+ bl_label = "Move to closest vertex"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = context.active_object
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ vs = obj.data.vertices
+ c = mati*Vector(CursorAccess.getCursor())
+ v = None
+ d = -1
+ for vv in vs:
+ if not vv.select:
+ continue
+ w = Vector(vv.co)
+ dd = G3.distanceP2P(c, w)
+ if d<0 or dd<d:
+ v = w
+ d = dd
+ if v==None:
+ return
+ cc.setCursor(mat*v)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_line(bpy.types.Operator):
+ """Move to closest point on line"""
+ bl_idname = "view3d.cursor_to_line"
+ bl_label = "Move to closest point on line"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mat = obj.matrix_world
+ if obj.data.total_vert_sel==2:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ p = CursorAccess.getCursor()
+ v0 = mat*sf[0].co
+ v1 = mat*sf[1].co
+ q = G3.closestP2L(p, v0, v1)
+ cc.setCursor(q)
+ return {'FINISHED'}
+ if obj.data.total_edge_sel<2:
+ return {'CANCELLED'}
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+ q = None
+ d = -1
+ for ee in obj.data.edges:
+ if not ee.select:
+ continue
+ e1 = Vector(obj.data.vertices[ee.vertices[0]].co)
+ e2 = Vector(obj.data.vertices[ee.vertices[1]].co)
+ qq = G3.closestP2L(c, e1, e2)
+ dd = G3.distanceP2P(c, qq)
+ if d<0 or dd<d:
+ q = qq
+ d = dd
+ if q==None:
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_edge(bpy.types.Operator):
+ """Move to closest point on edge"""
+ bl_idname = "view3d.cursor_to_edge"
+ bl_label = "Move to closest point on edge"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mat = obj.matrix_world
+ if obj.data.total_vert_sel==2:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ p = CursorAccess.getCursor()
+ v0 = mat*sf[0].co
+ v1 = mat*sf[1].co
+ q = G3.closestP2E(p, v0, v1)
+ cc.setCursor(q)
+ return {'FINISHED'}
+ if obj.data.total_edge_sel<2:
+ return {'CANCELLED'}
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+ q = None
+ d = -1
+ for ee in obj.data.edges:
+ if not ee.select:
+ continue
+ e1 = Vector(obj.data.vertices[ee.vertices[0]].co)
+ e2 = Vector(obj.data.vertices[ee.vertices[1]].co)
+ qq = G3.closestP2E(c, e1, e2)
+ dd = G3.distanceP2P(c, qq)
+ if d<0 or dd<d:
+ q = qq
+ d = dd
+ if q==None:
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_plane(bpy.types.Operator):
+ """Move to closest point on a plane"""
+ bl_idname = "view3d.cursor_to_plane"
+ bl_label = "Move to closest point on a plane"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ if obj.data.total_vert_sel==3:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ normal = (v1-v0).cross(v2-v0)
+ normal.normalize();
+ p = CursorAccess.getCursor()
+ n = mat*normal-obj.location
+ v = mat*v0
+ k = - (p-v).dot(n) / n.dot(n)
+ q = p+n*k
+ cc.setCursor(q)
+ return {'FINISHED'}
+
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+ q = None
+ d = -1
+ for ff in obj.data.polygons:
+ if not ff.select:
+ continue
+ qq = G3.closestP2S(c, Vector(obj.data.vertices[ff.vertices[0]].co), ff.normal)
+ dd = G3.distanceP2P(c, qq)
+ if d<0 or dd<d:
+ q = qq
+ d = dd
+ if q==None:
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_face(bpy.types.Operator):
+ """Move to closest point on a face"""
+ bl_idname = "view3d.cursor_to_face"
+ bl_label = "Move to closest point on a face"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+ if obj.data.total_vert_sel==3:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ fv = [v0, v1, v2]
+ normal = (v1-v0).cross(v2-v0)
+ normal.normalize();
+ q = G3.closestP2F(c, fv, normal)
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+ #visual = True
+
+ qqq = []
+ q = None
+ d = -1
+ for ff in obj.data.polygons:
+ if not ff.select:
+ continue
+ fv=[]
+ for vi in ff.vertices:
+ fv.append(Vector(obj.data.vertices[vi].co))
+ qq = G3.closestP2F(c, fv, ff.normal)
+ #if visual:
+ #qqq.append(qq)
+ dd = G3.distanceP2P(c, qq)
+ if d<0 or dd<d:
+ q = qq
+ d = dd
+ if q==None:
+ return {'CANCELLED'}
+
+ #if visual:
+ #ci = MeshEditor.addVertex(c)
+ #for qq in qqq:
+ #qqi = MeshEditor.addVertex(qq)
+ #MeshEditor.addEdge(ci, qqi)
+
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_vertex_median(bpy.types.Operator):
+ """Move to median of vertices"""
+ bl_idname = "view3d.cursor_to_vertex_median"
+ bl_label = "Move to median of vertices"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = context.active_object
+ mat = obj.matrix_world
+ vs = obj.data.vertices
+ selv = [v for v in vs if v.select == 1]
+ location = Vector((0,0,0))
+ for v in selv:
+ location = location + v.co
+ n = len(selv)
+ if (n==0):
+ return {'CANCELLED'}
+ location = location / n
+ cc.setCursor(mat*location)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_linex(bpy.types.Operator):
+ """Alternate between closest encounter points of two lines"""
+ bl_idname = "view3d.cursor_to_linex"
+ bl_label = "Alternate between to closest encounter points of two lines"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ obj = bpy.context.active_object
+ mat = obj.matrix_world
+
+ se = [e for e in obj.data.edges if (e.select == 1)]
+ e1v1 = obj.data.vertices[se[0].vertices[0]].co
+ e1v2 = obj.data.vertices[se[0].vertices[1]].co
+ e2v1 = obj.data.vertices[se[1].vertices[0]].co
+ e2v2 = obj.data.vertices[se[1].vertices[1]].co
+
+ qq = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)
+
+ q = None
+ if len(qq)==0:
+ #print ("lx 0")
+ return {'CANCELLED'}
+
+ if len(qq)==1:
+ #print ("lx 1")
+ q = qq[0]
+
+ if len(qq)==2:
+ cc = context.scene.cursor_control
+ cc.cycleLinexCoice(2)
+ q = qq[cc.linexChoice]
+
+ #q = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)[qc] * mat
+ #i2 = geometry.intersect_line_line (e2v1, e2v2, e1v1, e1v2)[0] * mat
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_cylinderaxis(bpy.types.Operator):
+ """Move to closest point on cylinder axis"""
+ bl_idname = "view3d.cursor_to_cylinderaxis"
+ bl_label = "Move to closest point on cylinder axis"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ fv = [v0, v1, v2]
+ q = G3.closestP2CylinderAxis(c, fv)
+ if(q==None):
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+
+
+class VIEW3D_OT_cursor_to_spherecenter(bpy.types.Operator):
+ """Move to center of cylinder or sphere"""
+ bl_idname = "view3d.cursor_to_spherecenter"
+ bl_label = "Move to center of cylinder or sphere"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ if obj.data.total_vert_sel==3:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ fv = [v0, v1, v2]
+ q = G3.closestP2CylinderAxis(c, fv)
+ #q = G3.centerOfSphere(fv)
+ if(q==None):
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+ if obj.data.total_vert_sel==4:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ v3 = Vector(sf[3].co)
+ fv = [v0, v1, v2, v3]
+ q = G3.centerOfSphere(fv)
+ if(q==None):
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+ return {'CANCELLED'}
+
+
+
+class VIEW3D_OT_cursor_to_perimeter(bpy.types.Operator):
+ """Move to perimeter of cylinder or sphere"""
+ bl_idname = "view3d.cursor_to_perimeter"
+ bl_label = "Move to perimeter of cylinder or sphere"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ if obj.data.total_vert_sel==3:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ fv = [v0, v1, v2]
+ q = G3.closestP2Cylinder(c, fv)
+ if(q==None):
+ return {'CANCELLED'}
+ #q = G3.centerOfSphere(fv)
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+ if obj.data.total_vert_sel==4:
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ v2 = Vector(sf[2].co)
+ v3 = Vector(sf[3].co)
+ fv = [v0, v1, v2, v3]
+ q = G3.closestP2Sphere(c, fv)
+ if(q==None):
+ return {'CANCELLED'}
+ cc.setCursor(mat*q)
+ return {'FINISHED'}
+ return {'CANCELLED'}
+
+
+
+#class VIEW3D_OT_cursor_offset_from_radius(bpy.types.Operator):
+ #"""Calculate offset from radius"""
+ #bl_idname = "view3d.cursor_offset_from_radius"
+ #bl_label = "Calculate offset from radius"
+ #bl_options = {'REGISTER'}
+
+ #def modal(self, context, event):
+ #return {'FINISHED'}
+
+ #def execute(self, context):
+ #BlenderFake.forceUpdate()
+ #cc = context.scene.cursor_control
+ #cc.hideLinexChoice()
+ #obj = bpy.context.active_object
+ #mesh = obj.data.vertices
+ #mat = obj.matrix_world
+ #mati = mat.copy()
+ #mati.invert()
+ #c = mati*Vector(CursorAccess.getCursor())
+
+ #if obj.data.total_vert_sel==3:
+ #sf = [f for f in obj.data.vertices if f.select == 1]
+ #v0 = Vector(sf[0].co)
+ #v1 = Vector(sf[1].co)
+ #v2 = Vector(sf[2].co)
+ #fv = [v0, v1, v2]
+ #q = G3.centerOfSphere(fv)
+ #d = (v0-q).length
+ #cc.stepLengthValue = d
+ #return {'FINISHED'}
+ #if obj.data.total_vert_sel==4:
+ #sf = [f for f in obj.data.vertices if f.select == 1]
+ #v0 = Vector(sf[0].co)
+ #v1 = Vector(sf[1].co)
+ #v2 = Vector(sf[2].co)
+ #v3 = Vector(sf[3].co)
+ #fv = [v0, v1, v2, v3]
+ #q = G3.centerOfSphere(fv)
+ #d = (v0-q).length
+ #cc.stepLengthValue = d
+ #return {'FINISHED'}
+ #return {'CANCELLED'}
+
+
+
+class VIEW3D_OT_cursor_stepval_phinv(bpy.types.Operator):
+ """Set step value to 1/Phi"""
+ bl_idname = "view3d.cursor_stepval_phinv"
+ bl_label = "Set step value to 1/Phi"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.stepLengthValue = PHI_INV
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_stepval_phi(bpy.types.Operator):
+ """Set step value to Phi"""
+ bl_idname = "view3d.cursor_stepval_phi"
+ bl_label = "Set step value to Phi"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.stepLengthValue = PHI
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_stepval_phi2(bpy.types.Operator):
+ """Set step value to Phi²"""
+ bl_idname = "view3d.cursor_stepval_phi2"
+ bl_label = "Set step value to Phi²"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.stepLengthValue = PHI_SQR
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_cursor_stepval_vvdist(bpy.types.Operator):
+ """Set step value to distance vertex-vertex"""
+ bl_idname = "view3d.cursor_stepval_vvdist"
+ bl_label = "Set step value to distance vertex-vertex"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ cc.hideLinexChoice()
+ obj = bpy.context.active_object
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ q = (v0-v1).length
+ cc.stepLengthValue = q
+
+ BlenderFake.forceRedraw()
+ return {'FINISHED'}
+
+
+
+
+class VIEW3D_OT_ccdelta_invert(bpy.types.Operator):
+ """Invert delta vector"""
+ bl_idname = "view3d.ccdelta_invert"
+ bl_label = "Invert delta vector"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.invertDeltaVector()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_ccdelta_normalize(bpy.types.Operator):
+ """Normalize delta vector"""
+ bl_idname = "view3d.ccdelta_normalize"
+ bl_label = "Normalize delta vector"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.normalizeDeltaVector()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_ccdelta_add(bpy.types.Operator):
+ """Add delta vector to 3D cursor"""
+ bl_idname = "view3d.ccdelta_add"
+ bl_label = "Add delta vector to 3D cursor"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.addDeltaVectorToCursor()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_ccdelta_sub(bpy.types.Operator):
+ """Subtract delta vector to 3D cursor"""
+ bl_idname = "view3d.ccdelta_sub"
+ bl_label = "Subtract delta vector to 3D cursor"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ cc = context.scene.cursor_control
+ cc.subDeltaVectorToCursor()
+ return {'FINISHED'}
+
+
+
+class VIEW3D_OT_ccdelta_vvdist(bpy.types.Operator):
+ """Set delta vector from selection"""
+ bl_idname = "view3d.ccdelta_vvdist"
+ bl_label = "Set delta vector from selection"
+ bl_options = {'REGISTER'}
+
+ def modal(self, context, event):
+ return {'FINISHED'}
+
+ def execute(self, context):
+ BlenderFake.forceUpdate()
+ cc = context.scene.cursor_control
+ obj = bpy.context.active_object
+ if obj.data.total_vert_sel==0:
+ if hasattr(context.scene, "cursor_memory"):
+ cm = context.scene.cursor_memory
+
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ v0 = Vector(cm.savedLocation)
+ v1 = Vector(c)
+ cc.deltaVector = v0-v1
+
+
+ if obj.data.total_vert_sel==1:
+ mesh = obj.data.vertices
+ mat = obj.matrix_world
+ mati = mat.copy()
+ mati.invert()
+ c = mati*Vector(CursorAccess.getCursor())
+
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(c)
+ cc.deltaVector = v0-v1
+
+ if obj.data.total_vert_sel==2:
+ #mesh = obj.data.vertices
+ #mat = obj.matrix_world
+ #mati = mat.copy()
+ #mati.invert()
+ #c = mati*Vector(CursorAccess.getCursor())
+
+ sf = [f for f in obj.data.vertices if f.select == 1]
+ v0 = Vector(sf[0].co)
+ v1 = Vector(sf[1].co)
+ cc.deltaVector = v1-v0
+
+ return {'FINISHED'}
+
+
+
+
diff --git a/release/scripts/addons_contrib/cursor_control/ui.py b/release/scripts/addons_contrib/cursor_control/ui.py
new file mode 100644
index 0000000..4863836
--- /dev/null
+++ b/release/scripts/addons_contrib/cursor_control/ui.py
@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+# ##### 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 LICENSE BLOCK #####
+
+
+
+"""
+ TODO:
+
+ IDEAS:
+
+ LATER:
+
+ ISSUES:
+ Bugs:
+ Mites:
+
+ QUESTIONS:
+
+
+"""
+
+
+
+import bpy
+import bgl
+import math
+from mathutils import Vector, Matrix
+from mathutils import geometry
+from misc_utils import *
+from constants_utils import *
+from cursor_utils import *
+from ui_utils import *
+from geometry_utils import *
+
+
+class VIEW3D_PT_cursor(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Cursor Target"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ # Display in object or edit mode.
+ if (context.area.type == 'VIEW_3D' and
+ (context.mode == 'EDIT_MESH'
+ or context.mode == 'OBJECT')):
+ return 1
+
+ return 0
+
+ def draw_header(self, context):
+ pass
+
+ def draw(self, context):
+ layout = self.layout
+ sce = context.scene
+
+ cc = context.scene.cursor_control
+ (tvs,tes,tfs,edit_mode) = cc.guiStates(context)
+
+ # Mesh data elements
+ if(edit_mode):
+ row = layout.row()
+ GUI.drawIconButton(tvs>=1 , row, 'STICKY_UVS_DISABLE', "view3d.cursor_to_vertex")
+ GUI.drawIconButton(tvs==2 or tes>=1, row, 'MESH_DATA' , "view3d.cursor_to_line")
+ GUI.drawIconButton(tvs==2 or tes>=1, row, 'OUTLINER_OB_MESH' , "view3d.cursor_to_edge")
+ GUI.drawIconButton(tvs==3 or tfs>=1, row, 'SNAP_FACE' , "view3d.cursor_to_plane")
+ GUI.drawIconButton(tvs==3 or tfs>=1, row, 'FACESEL' , "view3d.cursor_to_face")
+
+ # Geometry from mesh
+ if(edit_mode):
+ row = layout.row()
+ GUI.drawIconButton(tvs<=3 or tfs==1 , row, 'MOD_MIRROR' , "view3d.cursor_to_sl_mirror")
+ GUI.drawIconButton(tes==2, row, 'PARTICLE_TIP', "view3d.cursor_to_linex")
+ GUI.drawIconButton(tvs>1 , row, 'ROTATECENTER', "view3d.cursor_to_vertex_median") #EDITMODE_HLT
+ GUI.drawIconButton(tvs==3 or tvs==4, row, 'FORCE_FORCE' , "view3d.cursor_to_spherecenter")
+ GUI.drawIconButton(tvs==3 or tvs==4, row, 'MATERIAL' , "view3d.cursor_to_perimeter")
+
+ # Objects
+ #row = layout.row()
+
+ #GUI.drawIconButton(context.active_object!=None , row, 'ROTATE' , "view3d.cursor_to_active_object_center")
+ #GUI.drawIconButton(len(context.selected_objects)>1, row, 'ROTATECOLLECTION', "view3d.cursor_to_selection_midpoint")
+ #GUI.drawIconButton(len(context.selected_objects)>1, row, 'ROTATECENTER' , "view3d.cursor_to_selection_midpoint")
+
+ # References World Origin, Object Origin, SL and CL
+ row = layout.row()
+ GUI.drawIconButton(True , row, 'WORLD_DATA' , "view3d.cursor_to_origin")
+ GUI.drawIconButton(context.active_object!=None, row, 'ROTACTIVE' , "view3d.cursor_to_active_object_center")
+ GUI.drawIconButton(True , row, 'CURSOR' , "view3d.cursor_to_sl")
+ #GUI.drawIconButton(True, row, 'GRID' , "view3d.cursor_sl_recall")
+ #GUI.drawIconButton(True, row, 'SNAP_INCREMENT', "view3d.cursor_sl_recall")
+ #row.label("("+str(cc.linexChoice)+")")
+ cc = context.scene.cursor_control
+ if cc.linexChoice>=0:
+ col = row.column()
+ col.enabled = False
+ col.prop(cc, "linexChoice")
+
+ # Limit/Clamping Properties
+ row = layout.row()
+ row.prop(cc, "stepLengthEnable")
+ if (cc.stepLengthEnable):
+ row = layout.row()
+ row.prop(cc, "stepLengthMode")
+ row.prop(cc, "stepLengthValue")
+ row = layout.row()
+ GUI.drawTextButton(True, row, '1/Phi' , "view3d.cursor_stepval_phinv")
+ GUI.drawTextButton(True, row, 'Phi' , "view3d.cursor_stepval_phi")
+ GUI.drawTextButton(True, row, 'Phi²' , "view3d.cursor_stepval_phi2")
+ GUI.drawIconButton(tvs==2, row, 'EDGESEL' , "view3d.cursor_stepval_vvdist")
+
+
+
+class VIEW3D_PT_ccDelta(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Cursor Delta"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ # Display in object or edit mode.
+ if (context.area.type == 'VIEW_3D' and
+ (context.mode == 'EDIT_MESH'
+ or context.mode == 'OBJECT')):
+ return 1
+
+ return 0
+
+ def draw_header(self, context):
+ pass
+
+ def draw(self, context):
+ layout = self.layout
+ #sce = context.scene
+
+ cc = context.scene.cursor_control
+ (tvs,tes,tfs,edit_mode) = cc.guiStates(context)
+
+ row = layout.row()
+ col = row.column();
+ GUI.drawIconButton(True , col, 'FF' , "view3d.ccdelta_add")
+ GUI.drawIconButton(True , col, 'REW' , "view3d.ccdelta_sub")
+ GUI.drawIconButton(tvs<=2 , col, 'FORWARD' , "view3d.ccdelta_vvdist")
+
+ col = row.column();
+ col.prop(cc, "deltaVector")
+
+ col = row.column();
+ GUI.drawIconButton(True , col, 'MOD_MIRROR' , "view3d.ccdelta_invert")
+ GUI.drawIconButton(True , col, 'SNAP_NORMAL' , "view3d.ccdelta_normalize")
+
+
+
+class CursorControlMenu(bpy.types.Menu):
+ """menu"""
+ bl_idname = "cursor_control_calls"
+ bl_label = "Cursor Control"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ #layout.operator(VIEW3D_OT_cursor_to_vertex.bl_idname, text = "Vertex")
+ #layout.operator(VIEW3D_OT_cursor_to_line.bl_idname, text = "Line")
+ #obj = context.active_object
+ #if (context.mode == 'EDIT_MESH'):
+ #if (obj and obj.type=='MESH' and obj.data):
+ cc = context.scene.cursor_control
+ (tvs,tes,tfs,edit_mode) = cc.guiStates(context)
+
+ if(edit_mode):
+ if(tvs>=1):
+ layout.operator(VIEW3D_OT_cursor_to_vertex.bl_idname, text = "Closest Vertex")
+ if(tvs==2 or tes>=1):
+ layout.operator(VIEW3D_OT_cursor_to_line.bl_idname, text = "Closest Line")
+ if(tvs==2 or tes>=1):
+ layout.operator(VIEW3D_OT_cursor_to_edge.bl_idname, text = "Closest Edge")
+ if(tvs==3 or tfs>=1):
+ layout.operator(VIEW3D_OT_cursor_to_plane.bl_idname, text = "Closest Plane")
+ if(tvs==3 or tfs>=1):
+ layout.operator(VIEW3D_OT_cursor_to_face.bl_idname, text = "Closest Face")
+
+ if(edit_mode):
+ if(tvs<=3 or tfs==1):
+ layout.operator(VIEW3D_OT_cursor_to_sl_mirror.bl_idname, text = "Mirror")
+ if(tes==2):
+ layout.operator(VIEW3D_OT_cursor_to_linex.bl_idname, text = "Line Intersection")
+ if(tvs>1):
+ layout.operator(VIEW3D_OT_cursor_to_vertex_median.bl_idname, text = "Vertex Median")
+ if(tvs==3 or tvs==4):
+ layout.operator(VIEW3D_OT_cursor_to_spherecenter.bl_idname, text = "Circle Center")
+ if(tvs==3 or tvs==4):
+ layout.operator(VIEW3D_OT_cursor_to_perimeter.bl_idname, text = "Circle Perimeter")
+
+ layout.operator(VIEW3D_OT_cursor_to_origin.bl_idname, text = "World Origin")
+ layout.operator(VIEW3D_OT_cursor_to_active_object_center.bl_idname, text = "Active Object")
+ layout.operator(VIEW3D_OT_cursor_to_sl.bl_idname, text = "Cursor Memory")
+
+
+
+def menu_callback(self, context):
+ #obj = context.active_object
+ #if (context.mode == 'EDIT_MESH'):
+ #if (obj and obj.type=='MESH' and obj.data):
+ self.layout.menu(CursorControlMenu.bl_idname, icon="PLUGIN")
+
diff --git a/release/scripts/addons_contrib/curve_tools.py b/release/scripts/addons_contrib/curve_tools.py
new file mode 100644
index 0000000..c1debf4
--- /dev/null
+++ b/release/scripts/addons_contrib/curve_tools.py
@@ -0,0 +1,1353 @@
+# #####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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Curve Tools",
+ "author": "Zak",
+ "version": (0, 1, 5),
+ "blender": (2, 59, 0),
+ "location": "Properties > Object data",
+ "description": "Creates driven Lofts or Birails between curves",
+ "warning": "may be buggy or incomplete",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Curve/Curve_Tools",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27720",
+ "category": "Add Curve"}
+
+### UPDATES
+#1.5
+
+#-Fixed birail function
+#-Added Curve Snap to W key specials menu.
+#-Removed some functions that arent needed and wrapped into the operators.
+#-nurbs with weights for loft and birail
+#-Panel Moved to view 3d tools
+#-inserted TODO comments
+#-tried to implement live tension and bias for Hermite interpolation by driving the mesh but
+#i dont know why, the code is executed all the time even if you dont change the variables.
+#-snap to curves affects all the curves on the scene
+#-i was able to preserve handle types when split or subdivide
+
+
+#1.4
+#-incorporate curve snap
+#assign a copy transform to helper
+#-nurbs implemented (in progress)
+
+import bpy
+from mathutils import *
+from bpy.props import *
+
+print("----------")
+
+
+### PROPERTIES
+class sprops(bpy.types.PropertyGroup):
+ pass
+
+
+bpy.utils.register_class(sprops)
+
+#bpy.selection will store objects names in the order they were selected
+bpy.selection=[]
+
+
+#dodriver a simple checker to chosse whether you want a driven mesh or not.
+bpy.types.Scene.dodriver = BoolProperty(name = "dodriver", default=False)
+
+#interpolation types
+myitems = (('0','Linear', ''),('1','Cubic',''),('2','Catmull',''), ('3','Hermite',''))
+bpy.types.Scene.intype = EnumProperty(name="intype", items = myitems, default='3')
+
+#number of steps and spans to be created
+bpy.types.Scene.steps = IntProperty(name="steps", default=12, min=2)
+bpy.types.Scene.spans = IntProperty(name="spans", default=12, min=2)
+
+#parameters for Hermite interpolation
+bpy.types.Scene.tension = FloatProperty(name = "tension", min=0.0, default=0.0)
+bpy.types.Scene.bias = FloatProperty(name = "bias", min=0.0, default = 0.5)
+
+#proportional birail
+bpy.types.Scene.proportional = BoolProperty(name="proportional", default=False)
+
+#this stores the result of calculating the curve length
+bpy.types.Scene.clen = FloatProperty(name="clen", default=0.0, precision=5)
+
+#minimun distance for merge curve tool
+bpy.types.Scene.limit = FloatProperty(name="limit", default=0.1, precision=3)
+
+
+### SELECT BY ORDER BLOCK
+
+#i dont know what to do with this. Im not using it yet.
+def selected_points(curve):
+
+ selp = []
+ for spl in curve.splines:
+ if spl.type=="BEZIER":
+ points = spl.bezier_points
+ for p in points:
+ if p.select_control_point:
+ selp.append(p)
+
+ elif spl.type=="NURBS":
+ points = spl.points
+ for p in points:
+ if p.select:
+ selp.append(p)
+ return selp
+
+#writes bpy.selection when a new object is selected or deselected
+#it compares bpy.selection with bpy.context.selected_objects
+
+def select():
+
+ #print(bpy.context.mode)
+ if bpy.context.mode=="OBJECT":
+ obj = bpy.context.object
+ sel = len(bpy.context.selected_objects)
+
+ if sel==0:
+ bpy.selection=[]
+ else:
+ if sel==1:
+ bpy.selection=[]
+ bpy.selection.append(obj)
+ elif sel>len(bpy.selection):
+ for sobj in bpy.context.selected_objects:
+ if (sobj in bpy.selection)==False:
+ bpy.selection.append(sobj)
+
+ elif sel<len(bpy.selection):
+ for it in bpy.selection:
+ if (it in bpy.context.selected_objects)==False:
+ bpy.selection.remove(it)
+
+ #on edit mode doesnt work well
+
+
+#executes selection by order at 3d view
+class Selection(bpy.types.Header):
+ bl_label = "Selection"
+ bl_space_type = "VIEW_3D"
+
+ def __init__(self):
+ #print("hey")
+ select()
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row.label("Sel: "+str(len(bpy.selection)))
+
+### GENERAL CURVE FUNCTIONS
+
+#distance between 2 points
+def dist(p1, p2):
+ return (p2-p1).magnitude
+
+#sets cursors position for debugging porpuses
+def cursor(pos):
+ bpy.context.scene.cursor_location = pos
+
+#cuadratic bezier value
+def quad(p, t):
+ return p[0]*(1.0-t)**2.0 + 2.0*t*p[1]*(1.0-t) + p[2]*t**2.0
+
+#cubic bezier value
+def cubic(p, t):
+ return p[0]*(1.0-t)**3.0 + 3.0*p[1]*t*(1.0-t)**2.0 + 3.0*p[2]*(t**2.0)*(1.0-t) + p[3]*t**3.0
+
+#gets a bezier segment's control points on global coordinates
+def getbezpoints(spl, mt, seg=0):
+ points = spl.bezier_points
+ p0 = mt * points[seg].co
+ p1 = mt * points[seg].handle_right
+ p2 = mt * points[seg+1].handle_left
+ p3 = mt * points[seg+1].co
+ return p0, p1, p2, p3
+
+#gets nurbs polygon control points on global coordinates
+def getnurbspoints(spl, mw):
+ pts = []
+ ws = []
+ for p in spl.points:
+ v = Vector(p.co[0:3])*mw
+ pts.append(v)
+ ws.append(p.weight)
+ return pts , ws
+
+#calcs a nurbs knot vector
+def knots(n, order, type=0):#0 uniform 1 endpoints 2 bezier
+
+ kv = []
+
+ t = n+order
+ if type==0:
+ for i in range(0, t):
+ kv.append(1.0*i)
+
+ elif type==1:
+ k=0.0
+ for i in range(1, t+1):
+ kv.append(k)
+ if i>=order and i<=n:
+ k+=1.0
+ elif type==2:
+ if order==4:
+ k=0.34
+ for a in range(0,t):
+ if a>=order and a<=n: k+=0.5
+ kv.append(floor(k))
+ k+=1.0/3.0
+
+ elif order==3:
+ k=0.6
+ for a in range(0, t):
+ if a >=order and a<=n: k+=0.5
+ kv.append(floor(k))
+
+ ##normalize the knot vector
+ for i in range(0, len(kv)):
+ kv[i]=kv[i]/kv[-1]
+
+ return kv
+
+#nurbs curve evaluation
+def C(t, order, points, weights, knots):
+ #c = Point([0,0,0])
+ c = Vector()
+ rational = 0
+ i = 0
+ while i < len(points):
+ b = B(i, order, t, knots)
+ p = points[i] * (b * weights[i])
+ c = c + p
+ rational = rational + b*weights[i]
+ i = i + 1
+
+ return c * (1.0/rational)
+
+#nurbs basis function
+def B(i,k,t,knots):
+ ret = 0
+ if k>0:
+ n1 = (t-knots[i])*B(i,k-1,t,knots)
+ d1 = knots[i+k] - knots[i]
+ n2 = (knots[i+k+1] - t) * B(i+1,k-1,t,knots)
+ d2 = knots[i+k+1] - knots[i+1]
+ if d1 > 0.0001 or d1 < -0.0001:
+ a = n1 / d1
+ else:
+ a = 0
+ if d2 > 0.0001 or d2 < -0.0001:
+ b = n2 / d2
+ else:
+ b = 0
+ ret = a + b
+ #print "B i = %d, k = %d, ret = %g, a = %g, b = %g\n"%(i,k,ret,a,b)
+ else:
+ if knots[i] <= t and t <= knots[i+1]:
+ ret = 1
+ else:
+ ret = 0
+ return ret
+
+#calculates a global parameter t along all control points
+#t=0 begining of the curve
+#t=1 ending of the curve
+
+def calct(obj, t):
+
+ spl=None
+ mw = obj.matrix_world
+ if obj.data.splines.active==None:
+ if len(obj.data.splines)>0:
+ spl=obj.data.splines[0]
+ else:
+ spl = obj.data.splines.active
+
+ if spl==None:
+ return False
+
+ if spl.type=="BEZIER":
+ points = spl.bezier_points
+ nsegs = len(points)-1
+
+ d = 1.0/nsegs
+ seg = int(t/d)
+ t1 = t/d - int(t/d)
+
+ if t==1:
+ seg-=1
+ t1 = 1.0
+
+ p = getbezpoints(spl,mw, seg)
+
+ coord = cubic(p, t1)
+
+ return coord
+
+ elif spl.type=="NURBS":
+ data = getnurbspoints(spl, mw)
+ pts = data[0]
+ ws = data[1]
+ order = spl.order_u
+ n = len(pts)
+ ctype = spl.use_endpoint_u
+ kv = knots(n, order, ctype)
+
+ coord = C(t, order-1, pts, ws, kv)
+
+ return coord
+
+#length of the curve
+def arclength(objs):
+ length = 0.0
+
+ for obj in objs:
+ if obj.type=="CURVE":
+ prec = 1000 #precision
+ inc = 1/prec #increments
+
+ ### TODO: set a custom precision value depending the number of curve points
+ #that way it can gain on accuracy in less operations.
+
+ #subdivide the curve in 1000 lines and sum its magnitudes
+ for i in range(0, prec):
+ ti = i*inc
+ tf = (i+1)*inc
+ a = calct(obj, ti)
+ b = calct(obj, tf)
+ r = (b-a).magnitude
+ length+=r
+
+ return length
+
+
+class ArcLengthOperator(bpy.types.Operator):
+
+ bl_idname = "curve.arc_length_operator"
+ bl_label = "Measures the length of a curve"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ objs = context.selected_objects
+ context.scene.clen = arclength(objs)
+ return {'FINISHED'}
+
+### LOFT INTERPOLATIONS
+
+#objs = selected objects
+#i = object index
+#t = parameter along u direction
+#tr = parameter along v direction
+
+#linear
+def intl(objs, i, t, tr):
+ p1 = calct(objs[i],t)
+ p2 = calct(objs[i+1], t)
+
+ r = p1 + (p2 - p1)*tr
+
+ return r
+
+#tipo = interpolation type
+#tension and bias are for hermite interpolation
+#they can be changed to obtain different lofts.
+
+#cubic
+def intc(objs, i, t, tr, tipo=3, tension=0.0, bias=0.0):
+
+ ncurves =len(objs)
+
+ #if 2 curves go to linear interpolation regardless the one you choose
+ if ncurves<3:
+ return intl(objs, i, t, tr)
+ else:
+
+ #calculates the points to be interpolated on each curve
+ if i==0:
+ p0 = calct(objs[i], t)
+ p1 = p0
+ p2 = calct(objs[i+1], t)
+ p3 = calct(objs[i+2], t)
+ else:
+ if ncurves-2 == i:
+ p0 = calct(objs[i-1], t)
+ p1 = calct(objs[i], t)
+ p2 = calct(objs[i+1], t)
+ p3 = p2
+ else:
+ p0 = calct(objs[i-1], t)
+ p1 = calct(objs[i], t)
+ p2 = calct(objs[i+1], t)
+ p3 = calct(objs[i+2], t)
+
+
+ #calculates the interpolation between those points
+ #i used methods from this page: http://paulbourke.net/miscellaneous/interpolation/
+
+ if tipo==0:
+ #linear
+ return intl(objs, i, t, tr)
+ elif tipo == 1:
+ #natural cubic
+ t2 = tr*tr
+ a0 = p3-p2-p0+p1
+ a1 = p0-p1-a0
+ a2 = p2-p0
+ a3 = p1
+ return a0*tr*t2 + a1*t2+a2*tr+a3
+ elif tipo == 2:
+ #catmull it seems to be working. ill leave it for now.
+ t2 = tr*tr
+ a0 = -0.5*p0 +1.5*p1 -1.5*p2 +0.5*p3
+ a1 = p0 - 2.5*p1 + 2*p2 -0.5*p3
+ a2 = -0.5*p0 + 0.5 *p2
+ a3 = p1
+ return a0*tr*tr + a1*t2+a2*tr+a3
+
+ elif tipo == 3:
+ #hermite
+ tr2 = tr*tr
+ tr3 = tr2*tr
+ m0 = (p1-p0)*(1+bias)*(1-tension)/2
+ m0+= (p2-p1)*(1-bias)*(1-tension)/2
+ m1 = (p2-p1)*(1+bias)*(1-tension)/2
+ m1+= (p3-p2)*(1-bias)*(1-tension)/2
+ a0 = 2*tr3 - 3*tr2 + 1
+ a1 = tr3 - 2 * tr2+ tr
+ a2 = tr3 - tr2
+ a3 = -2*tr3 + 3*tr2
+
+ return a0*p1+a1*m0+a2*m1+a3*p2
+
+
+#handles loft driver expression
+#example: loftdriver('Loft', 'BezierCurve;BezierCurve.001;BezierCurve.002', 3)
+
+#name: its the name of the mesh to be driven
+#objs: the names of the curves that drives the mesh
+#3 interpolation type
+
+def loftdriver(name, objs, intype):
+ #print("ejecutando "+name)
+ intype = int(intype)
+
+ tension = 0.0
+ bias = 0.5
+ #if the loft object still exists proceed normal
+ try:
+ resobj = bpy.data.objects[name]
+ spans = resobj["spans"]
+ steps = resobj["steps"]
+ if intype==3: #hermite
+ tension = resobj['tension']
+ bias = resobj['bias']
+
+ #if not delete the driver
+ except:
+ curve = bpy.context.object
+ for it in curve.keys():
+ if it == "driver":
+ curve.driver_remove('["driver"]')
+ return False
+
+ objs = objs.split(";")
+ #objs = objs[0:-1]
+
+
+ #retrieves the curves from the objs string
+ for i, l in enumerate(objs):
+ objs[i] = bpy.data.objects[l]
+
+
+
+ #calcs the new vertices coordinates if we change the curves.
+ vxs = loft(objs, steps, spans, intype, tension, bias)
+
+ #apply the new cordinates to the loft object
+ me = resobj.data
+
+ for i in range(0, len(me.vertices)):
+ me.vertices[i].co = vxs[i]
+ me.update()
+ return spans
+
+#NOTES:
+#loftdriver function will fail or produce weird results if:
+#the user changes resobj["spans"] or resobj["steps"]
+#if we delete any vertex from the loft object
+
+### TODO:check if thats the case to remove the drivers
+
+#creates the drivers expressions for each curve
+def createloftdriver(objs, res, intype):
+
+ line = ""
+ for obj in objs:
+ line+=obj.name+";"
+ line=line[0:-1]
+ name = res.name
+
+ interp = str(intype)
+
+ for obj in objs:
+ obj["driver"] = 1.0
+
+ obj.driver_add('["driver"]')
+ obj.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")"
+
+
+ ### creating this driver will execute loft all the time without reason,
+ #and if i cant drive the mesh i cannot implement live tension and bias
+
+# res['driver'] = 1.0
+# if res.animation_data==None:
+# res.animation_data_create()
+# res.driver_add('["driver"]')
+# res.animation_data.drivers[0].driver.expression = "loftdriver('"+ name +"', '" + line + "', "+interp+")"
+
+#calculates the vertices position of the loft object
+def loft(objs, steps, spans, interpolation=1, tension=0.0, bias=0.5):
+ verts=[]
+
+ for i in range(0, len(objs)):
+
+ for j in range(0,steps+1):
+ t = 1.0*j/steps
+ verts.append(calct(objs[i], t))
+
+ temp2=[]
+ if i<len(objs)-1:
+ for l in range(1, spans):
+ tr = 1.0*l/spans
+ for k in range(0, steps+1):
+ t=1.0*k/steps
+ if interpolation:
+ pos = intc(objs, i, t, tr, interpolation, tension, bias)
+ else:
+ pos = intl(objs,i, t, tr)
+
+ temp2.append(pos)
+ verts.extend(temp2)
+ return verts
+
+
+#loft operator
+
+class LoftOperator(bpy.types.Operator):
+ """Tooltip"""
+ bl_idname = "mesh.loft_operator"
+ bl_label = "Loft between bezier curves"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ #retrieves the curves in the order they were selected
+ objs = bpy.selection
+
+ spans = context.scene.spans
+ steps = context.scene.steps
+
+ intype = int(context.scene.intype)
+
+ verts = loft(objs, steps, spans, intype)
+
+ nfaces = steps*spans*(len(objs)-1)
+ faces=[]
+ for i in range(0, nfaces):
+ d = int(i/steps)
+ f = [i+d,i+d+1, i+d+steps+2, i+d+steps+1]
+ #inverts normals
+ #f = [i+d,i+d+steps+1, i+d+steps+2, i+d+1]
+ faces.append(f)
+
+
+ me = bpy.data.meshes.new("Loft")
+ me.from_pydata(verts,[], faces)
+ me.update()
+ newobj = bpy.data.objects.new("Loft", me)
+ #newobj.data = me
+ scn = context.scene
+ scn.objects.link(newobj)
+ scn.objects.active = newobj
+ newobj.select = True
+ bpy.ops.object.shade_smooth()
+
+ #the object stores its own steps and spans
+ #this way the driver will know how to deform the mesh
+ newobj["steps"] = steps
+ newobj["spans"] = spans
+
+ if intype==3:
+ newobj['tension'] = context.scene.tension
+ newobj['bias'] = context.scene.bias
+
+
+ if context.scene.dodriver:
+ createloftdriver(objs, newobj, intype)
+
+ return {'FINISHED'}
+
+class UpdateFix(bpy.types.Operator):
+ """Tooltip"""
+ bl_idname = "mesh.update_fix"
+ bl_label = "Update fix"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ #print("------------")
+# for it in bpy.app.driver_namespace:
+# print(it)
+ bpy.app.driver_namespace['loftdriver'] = loftdriver
+ bpy.app.driver_namespace['birail1driver'] = birail1driver
+ for obj in context.scene.objects:
+ if obj.type=="CURVE" and obj.animation_data!=None and len(obj.animation_data.drivers)>0:
+ for drv in obj.animation_data.drivers:
+ if drv.data_path=='["driver"]':
+ cad = drv.driver.expression
+ drv.driver.expression = ""
+ drv.driver.expression = cad
+
+ return {'FINISHED'}
+
+
+#derives a curve at a given parameter
+def deriv(curve, t, unit=False):
+
+ a = t + 0.001
+ if t==1: a=t-0.001
+
+ pos = calct(curve, t)
+ der = (pos-calct(curve, a))/(t-a)
+ if unit:
+ der = der/der.magnitude
+ return der
+
+### BIRAIL1 BLOCK
+
+
+#see explanation video about the construction
+#http://vimeo.com/25455967
+
+#calculates birail vertices
+
+### TODO: when the 3 curves are coplanar it should fail, cause the cross product. check that
+def birail1(objs, steps, spans, proportional):
+
+ profile=objs[0]
+ ### TODO: identify which path is left or right
+ path1 = objs[1]
+ path2 = objs[2]
+
+ trans = []
+
+ r0 = [calct(path1,0), calct(path2, 0)]
+ r0mag = (r0[1]-r0[0]).magnitude
+
+ for i in range(0, steps):
+ u = i/(steps-1)
+ appr0 = r0[0]+(r0[1]-r0[0])*u
+ trans.append(calct(profile, u)-appr0)
+
+ der10 = deriv(path1, 0)
+ der20 = deriv(path2, 0)
+
+ verts = []
+
+ mult = 1.0
+
+ for i in range(0, spans):
+ v = i/(spans-1)
+ r = [calct(path1, v),calct(path2, v)]
+ rmag = (r[1]-r[0]).magnitude
+
+ der1 = deriv(path1, v)
+ der2 = deriv(path2, v)
+
+ angle1 = der10.angle(der1)
+ angle2 = der20.angle(der2)
+
+ #if angle1!=0.0 and angle2!=0: we can avoid some operations by doing this check but im lazy
+ cr1 = der1.cross(der10)
+ rot1 = Matrix().Rotation(-angle1, 3, cr1)
+
+ cr2 = der2.cross(der20)
+ rot2 = Matrix().Rotation(-angle2, 3, cr2)
+
+ if proportional:
+ mult = rmag/r0mag
+
+ for j in range(0, steps):
+ u = j/(steps-1)
+
+ app = r[0]+(r[1]-r[0])*u
+
+ newtr1 = trans[j].copy()
+ newtr1.rotate(rot1)
+
+ newtr2 = trans[j].copy()
+ newtr2.rotate(rot2)
+
+ r1 = (newtr1-trans[j])*(1-u)
+ r2 = (newtr2-trans[j])*(u)
+
+ res = r1+r2+app+mult*trans[j]
+
+ verts.append(res)
+
+ return verts
+
+
+#same as loft driver
+### TODO check if it is registered
+def birail1driver(name, objs):
+
+ objs = objs.split(";")
+ #objs = objs[0:-1]
+
+ for i, l in enumerate(objs):
+ objs[i] = bpy.data.objects[l]
+
+ try:
+ resobj = bpy.data.objects[name]
+ spans = resobj["spans"]
+ steps = resobj["steps"]
+ prop = resobj["prop"]
+
+ except:
+ curve = bpy.context.object
+ curve.driver_remove('["driver"]')
+ return False
+
+ vxs = birail1(objs, steps, spans, prop)
+
+ me = resobj.data
+
+ for i in range(0, len(me.vertices)):
+ me.vertices[i].co = vxs[i]
+ me.update()
+ return spans
+
+def createbirail1driver(objs, res):
+
+ line = ""
+ for obj in objs:
+ line+=obj.name+";"
+ line=line[0:-1]
+ for obj in objs:
+ obj["driver"] = 1.0
+ obj.driver_add('["driver"]')
+ obj.animation_data.drivers[0].driver.expression = "birail1driver('"+ res.name +"', '" + line + "')"
+
+### TODO: check polls and if initial variables are ok to perform the birail
+class Birail1Operator(bpy.types.Operator):
+
+ bl_idname = "mesh.birail1_operator"
+ bl_label = "Birail between 3 bezier curves"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+
+ objs = bpy.selection
+
+ if len(objs)!=3:
+ self.report({'ERROR'},"Please select 3 curves")
+ return {'FINISHED'}
+
+ scn = context.scene
+ spans = scn.spans
+ steps = scn.steps
+ prop = scn.proportional
+
+ verts = birail1(objs, steps, spans, prop)
+
+ if verts!=[]:
+ faces=[]
+
+ nfaces = (steps-1)*(spans-1)
+
+ for i in range(0, nfaces):
+ d = int(i/(steps-1))
+ f = [i+d+1, i+d, i+d+steps, i+d+steps+1 ]
+ faces.append(f)
+
+ me = bpy.data.meshes.new("Birail")
+ me.from_pydata(verts,[], faces)
+ me.update()
+ newobj = bpy.data.objects.new("Birail", me)
+ newobj.data = me
+
+ scn.objects.link(newobj)
+ scn.objects.active = newobj
+ newobj.select = True
+ bpy.ops.object.shade_smooth()
+ newobj['steps']=steps
+ newobj['spans']=spans
+ newobj['prop']=prop
+
+ if scn.dodriver:
+ createbirail1driver(objs, newobj)
+
+ return {'FINISHED'}
+
+#register the drivers
+bpy.app.driver_namespace['loftdriver'] = loftdriver
+bpy.app.driver_namespace['birail1driver'] = birail1driver
+
+### MERGE SPLINES BLOCK
+
+#reads spline points
+#spl spline to read
+#rev reads the spline forward or backwards
+def readspline(spl, rev=0):
+ res = []
+
+ if spl.type=="BEZIER":
+ points = spl.bezier_points
+ for p in points:
+ if rev:
+ h2 = p.handle_left
+ h1 = p.handle_right
+ h2type = p.handle_left_type
+ h1type = p.handle_right_type
+ else:
+ h1 = p.handle_left
+ h2 = p.handle_right
+ h1type = p.handle_left_type
+ h2type = p.handle_right_type
+
+ co = p.co
+ res.append([h1, co, h2, h1type, h2type])
+ if rev:
+ res.reverse()
+
+ return res
+
+#returns a new merged spline
+#cu curve object
+#pts1 points from the first spline
+#pts2 points from the second spline
+
+def merge(cu, pts1, pts2):
+ newspl = cu.data.splines.new(type="BEZIER")
+ for i, p in enumerate(pts1):
+
+ if i>0: newspl.bezier_points.add()
+ newspl.bezier_points[i].handle_left = p[0]
+ newspl.bezier_points[i].co = p[1]
+ newspl.bezier_points[i].handle_right = p[2]
+ newspl.bezier_points[i].handle_left_type = p[3]
+ newspl.bezier_points[i].handle_right_type = p[4]
+
+ newspl.bezier_points[-1].handle_right_type="FREE"
+ newspl.bezier_points[-1].handle_left_type="FREE"
+
+ newspl.bezier_points[-1].handle_right = pts2[0][2]
+
+
+ for j in range(1, len(pts2)):
+
+ newspl.bezier_points.add()
+ newspl.bezier_points[-1].handle_left = pts2[j][0]
+ newspl.bezier_points[-1].co = pts2[j][1]
+ newspl.bezier_points[-1].handle_right = pts2[j][2]
+ newspl.bezier_points[-1].handle_left_type = pts2[j][3]
+ newspl.bezier_points[-1].handle_right_type = pts2[j][4]
+
+ return newspl
+
+#looks if the splines first and last points are close to another spline
+### TODO: Check if the objects selected are valid
+### if possible implement nurbs
+
+class MergeSplinesOperator(bpy.types.Operator):
+
+ bl_idname = "curve.merge_splines"
+ bl_label = "Merges spline points inside a limit"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ curves = []
+ limit = context.scene.limit
+ print("merguing")
+ for obj in context.selected_objects:
+ if obj.type=="CURVE":
+ curves.append(obj)
+
+ for cu in curves:
+ splines = []
+ for spl in cu.data.splines:
+ splines.append(spl)
+ print(splines)
+ #compares all the splines inside a curve object
+ for spl1 in splines:
+ for spl2 in splines:
+ print(spl1, spl2)
+ if spl1!=spl2 and spl1.type==spl2.type=="BEZIER" and spl1.use_cyclic_u==spl2.use_cyclic_u==False:
+ print("not cyclic")
+ if len(spl1.bezier_points)>1 and len(spl2.bezier_points)>1:
+
+ #edges of the 2 splines
+ p1i = spl1.bezier_points[0].co
+ p1f = spl1.bezier_points[-1].co
+ p2i = spl2.bezier_points[0].co
+ p2f = spl2.bezier_points[-1].co
+
+ if dist(p1i, p2i)<limit:
+ print("join p1i p2i")
+
+ p1 = readspline(spl2, 1)
+ p2 = readspline(spl1)
+ res=merge(cu, p1, p2)
+ cu.data.splines.remove(spl1)
+ cu.data.splines.remove(spl2)
+ splines.append(res)
+ break
+ elif dist(p1i, p2f)<limit:
+ print("join p1i p2f")
+ p1 = readspline(spl2)
+ p2 = readspline(spl1)
+ res = merge(cu, p1, p2)
+ cu.data.splines.remove(spl1)
+ cu.data.splines.remove(spl2)
+ splines.append(res)
+ break
+ elif dist(p1f, p2i)<limit:
+ print("join p1f p2i")
+ p1 = readspline(spl1)
+ p2 = readspline(spl2)
+ res = merge(cu, p1, p2)
+ cu.data.splines.remove(spl1)
+ cu.data.splines.remove(spl2)
+ splines.append(res)
+ break
+ elif dist(p1f, p2f)<limit:
+ print("unir p1f p2f")
+ p1 = readspline(spl1)
+ p2 = readspline(spl2, 1)
+ res = merge(cu, p1, p2)
+ cu.data.splines.remove(spl1)
+ cu.data.splines.remove(spl2)
+ splines.append(res)
+ break
+
+ #splines.remove(spl1)
+ return {'FINISHED'}
+
+### NURBS WEIGHTS
+
+class NurbsWeightsPanel(bpy.types.Panel):
+ bl_label = "Nurbs Weights"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ #bl_context = "data"
+
+ @classmethod
+ def poll(cls, context):
+ if context.active_object != None and context.active_object.type =="CURVE" and context.active_object.data.splines.active!=None and context.active_object.data.splines.active.type=="NURBS":
+ return True
+ else:
+ return False
+
+
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+
+ for p in obj.data.splines.active.points:
+ if p.select:
+ row = layout.row()
+ row.prop(p, "weight")
+
+### CUT / SUBDIVIDE CURVE
+#obj curve object
+#t parameter to perform the cut or split
+#method True = subdivide, Flase= Split
+
+def cutcurve(obj, t, method=True):
+
+ #flocal to global transforms or viceversa
+
+
+ #retrieves the active spline or the first spline if there no one active
+
+ spline=None
+ if obj.data.splines.active==None:
+ for sp in obj.data.splines:
+ if sp.type=="BEZIER":
+ spline= sp
+ break
+ else:
+ if obj.data.splines.active.type!="BEZIER":
+ return False
+ else:
+ spline=obj.data.splines.active
+
+ if spline==None: return False
+
+ points = spline.bezier_points
+ nsegs = len(points)-1
+
+ #transform global t into local t1
+ d = 1.0/nsegs
+ seg = int(t/d)
+ t1 = t/d-int(t/d)
+ if t>=1.0:
+ t=1.0
+ seg-=1
+ t1 = 1.0
+
+ #if t1 is not inside a segment dont perform any action
+ if t1>0.0 and t1<1.0:
+ mw = obj.matrix_world
+ mwi = obj.matrix_world.copy().inverted()
+
+ pts = getbezpoints(spline, mw, seg)
+
+ #position on the curve to perform the action
+ pos = calct(obj, t)
+
+ #De Casteljau's algorithm to get the handles
+ #http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
+ h1 = pts[0]+(pts[1]-pts[0])*t1
+ h4 = pts[2]+(pts[3]-pts[2])*t1
+ r = pts[1]+(pts[2]-pts[1])*t1
+ h2 = h1+(r-h1)*t1
+ h3 = r+(h4-r)*t1
+
+
+ if method:
+ #SUBDIVIDE
+ splp = []
+ type = "ALIGNED"
+ for i, p in enumerate(points):
+ ph1 = p.handle_left*mw
+ pco = p.co*mw
+ ph2 = p.handle_right*mw
+ ph1type = p.handle_left_type
+ ph2type = p.handle_right_type
+ splp.append([ph1, pco, ph2, ph1type, ph2type])
+ p.handle_left_type = type
+ p.handle_right_type = type
+
+ if i==seg:
+ splp[-1][2]=h1
+ splp.append([h2, pos, h3, type, type])
+
+ if i==seg+1:
+ splp[-1][0]=h4
+ splp[-1][3]=type
+ splp[-1][4]=type
+ #if i dont set all the handles to "FREE"
+ #it returns weirds result
+ ### TODO: find out how to preserve handle's types
+
+ points.add()
+ for i, p in enumerate(points):
+ p.handle_left_type = "FREE"
+ p.handle_right_type ="FREE"
+ p.handle_left = splp[i][0]*mwi
+ p.co = splp[i][1]*mwi
+ p.handle_right=splp[i][2]*mwi
+ p.handle_left_type = splp[i][3]
+ p.handle_right_type =splp[i][4]
+ else:
+ #SPLIT CURVE
+ spl1 = []
+ spl2 = []
+ k=0 #changes to 1 when the first spline is processed
+ type = "ALIGNED"
+ for i, p in enumerate(points):
+ ph1 = p.handle_left*mw
+ pco = p.co*mw
+ ph2 = p.handle_right*mw
+ ph1type = p.handle_left_type
+ ph2type = p.handle_right_type
+ if k==0:
+ spl1.append([ph1, pco, ph2, ph1type, ph2type])
+ else:
+ spl2.append([ph1, pco, ph2, ph1type, ph2type])
+
+ if i==seg:
+ spl1[-1][2]=h1
+ spl1.append([h2, pos, h3, type, type])
+ spl2.append([h2, pos, h3, type, type])
+ k=1
+
+ if i==seg+1:
+ spl2[-1][0]=h4
+ spl2[-1][3]=type
+ spl2[-1][4]=type
+
+ sp1 = obj.data.splines.new(type="BEZIER")
+ for i, p in enumerate(spl1):
+ if i>0: sp1.bezier_points.add()
+ sp1.bezier_points[i].handle_left_type = "FREE"
+ sp1.bezier_points[i].handle_right_type ="FREE"
+ sp1.bezier_points[i].handle_left = spl1[i][0]*mwi
+ sp1.bezier_points[i].co = spl1[i][1]*mwi
+ sp1.bezier_points[i].handle_right=spl1[i][2]*mwi
+ #i tried to preserve the handles here but
+ #didnt work well
+
+ sp1.bezier_points[i].handle_left_type = spl1[i][3]
+ sp1.bezier_points[i].handle_right_type =spl1[i][4]
+
+ sp2 = obj.data.splines.new(type="BEZIER")
+ for i, p in enumerate(spl2):
+ if i>0: sp2.bezier_points.add()
+ sp2.bezier_points[i].handle_left_type = "FREE"
+ sp2.bezier_points[i].handle_right_type = "FREE"
+ sp2.bezier_points[i].handle_left = spl2[i][0]*mwi
+ sp2.bezier_points[i].co = spl2[i][1]*mwi
+ sp2.bezier_points[i].handle_right=spl2[i][2]*mwi
+ sp2.bezier_points[i].handle_left_type = spl2[i][3]
+ sp2.bezier_points[i].handle_right_type =spl2[i][4]
+
+ obj.data.splines.remove(spline)
+
+class CutCurveOperator(bpy.types.Operator):
+ """Subdivide / Split a bezier curve"""
+ bl_idname = "curve.cut_operator"
+ bl_label = "Cut curve operator"
+
+ #cut or split
+ method = bpy.props.BoolProperty(default=False)
+ t = 0.0
+
+ @classmethod
+ def poll(self, context):
+ if context.active_object!=None:
+ return context.active_object.type=="CURVE"
+ else:
+ return False
+
+
+ def modal(self, context, event):
+
+ if event.type == 'MOUSEMOVE':
+ #full screen width
+ #not tested for multiple monitors
+ fullw = context.window_manager.windows[0].screen.areas[0].regions[0].width
+
+ self.t = event.mouse_x/fullw
+
+ #limit t to [0,...,1]
+ if self.t<0:
+ self.t=0.0
+ elif self.t>1.0:
+ self.t=1.0
+
+ obj = context.object
+ pos = calct(obj, self.t)
+
+ #if calct() detects a non bezier spline returns false
+ if pos==False:
+ return {'CANCELLED'}
+ cursor(pos)
+
+ elif event.type == 'LEFTMOUSE':
+ #print(self.method, self.t)
+ cutcurve(context.object, self.t, self.method)
+ return {'FINISHED'}
+
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
+ #print("Cancelled")
+
+ return {'CANCELLED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+
+ if context.object:
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ self.report({'WARNING'}, "No active object, could not finish")
+ return {'CANCELLED'}
+
+### CURVE SNAP BLOCK
+
+class AllowCurveSnap(bpy.types.Operator):
+ bl_idname = "curve.allow_curve_snap"
+ bl_label = "Allow Curve Snap"
+
+ add = bpy.props.BoolProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object!=None
+
+ def execute(self, context):
+ add = self.add
+
+ scn = context.scene
+
+ if add==False:
+ for helper in context.scene.objects:
+ for key in helper.keys():
+ print(key)
+ if key=="is_snap_helper" and helper[key]==1:
+ scn.objects.unlink(helper)
+ else:
+ #objs = context.selected_objects
+ objs = context.scene.objects
+ for obj in objs:
+ if obj.type=="CURVE":
+
+ res = obj.data.resolution_u
+
+ obj.data.resolution_u = 100
+
+ me = obj.to_mesh(scene=scn, apply_modifiers=True,settings = "PREVIEW" )
+ obj.data.resolution_u = res
+ newobj = bpy.data.objects.new(obj.name+"_snap", me)
+ scn.objects.link(newobj)
+ newobj.layers = obj.layers
+ newobj.matrix_world = obj.matrix_world
+ newobj["is_snap_helper"]=True
+ newobj.hide_render=True
+ newobj.hide_select = True
+ cons = newobj.constraints.new(type="COPY_TRANSFORMS")
+ cons.target =obj
+
+ return {'FINISHED'}
+
+def menu_func(self, context):
+ self.layout.operator("curve.allow_curve_snap").add=True
+ self.layout.operator("curve.allow_curve_snap", text = "Delete Snap Helpers").add=False
+
+### PANEL
+class CurvePanel(bpy.types.Panel):
+ bl_label = "Curve Tools"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ #bl_options = {'REGISTER', 'UNDO'}
+ #bl_context = "data"
+ bl_options = {'DEFAULT_CLOSED'}
+ steps = IntProperty(min=2, default = 12)
+
+ @classmethod
+ def poll(cls, context):
+ return (context.active_object != None) and (context.active_object.type=="CURVE")
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+ scn = context.scene
+
+ align = True
+ row = layout.row(align=align)
+
+ row.prop(context.scene, "intype", text = "")
+ row.prop(context.scene, "dodriver", text = "Driven")
+ if scn.intype=='3': #Hermite interp
+ row = layout.row(align=align)
+ row.prop(scn, "tension")
+ row.prop(scn, "bias")
+
+ row = layout.row(align=align)
+ row.prop(context.scene, "steps")
+ row.prop(context.scene, "spans")
+ row = layout.row(align=align)
+ row.operator("mesh.loft_operator", text = "Loft")
+ row.operator("mesh.update_fix", text = "Update Fix")
+ row = layout.row(align=align)
+ row.operator("mesh.birail1_operator", text = "Birail 1")
+ row.prop(context.scene, "proportional", text = "Proportional")
+ row = layout.row(align=align)
+ row.operator("curve.arc_length_operator", text = "Calc Length")
+ row.prop(context.scene, "clen", text = "")
+ row = layout.row(align=align)
+ row.operator("curve.merge_splines", text = "Merge")
+ row.prop(context.scene,"limit", text = "Limit")
+ row = layout.row(align=align)
+ row.operator("curve.cut_operator", text="Subdivide").method=True
+ row.operator("curve.cut_operator", text="Split").method=False
+
+# col1 = row.column()
+# col1.prop(context.scene, "intype", text = "")
+# col1.prop(context.scene, "dodriver", text = "Driven")
+# row = layout.row(align=align)
+# col2 = row.column(align=align)
+# col2.prop(context.scene, "steps")
+# col2.prop(context.scene, "spans")
+# row = layout.row(align=align)
+# row.operator("mesh.loft_operator", text = "Loft")
+# row.operator("mesh.update_fix", text = "Update Fix")
+# row = layout.row(align=align)
+# row.operator("mesh.birail1_operator", text = "Birail 1")
+# row.prop(context.scene, "proportional", text = "Proportional")
+# row = layout.row(align=align)
+# row.operator("curve.arc_length_operator", text = "Calc Length")
+# row.prop(context.scene, "clen", text = "")
+# row = layout.row(align=align)
+# row.operator("curve.merge_splines", text = "Merge")
+# row.prop(context.scene,"limit", text = "Limit")
+# row = layout.row(align=align)
+# row.operator("curve.cut_operator", text="Subdivide").method=True
+# row.operator("curve.cut_operator", text="Split").method=False
+
+classes = [AllowCurveSnap, Selection, LoftOperator, Birail1Operator,
+ ArcLengthOperator, UpdateFix, MergeSplinesOperator, CutCurveOperator, NurbsWeightsPanel, CurvePanel]
+
+bpy.app.driver_namespace['loftdriver'] = loftdriver
+bpy.app.driver_namespace['birail1driver'] = birail1driver
+
+def register():
+
+ domenu=1
+ for op in dir(bpy.types):
+ if op=="CURVE_OT_allow_curve_snap":
+ domenu=0
+ break
+ if domenu:
+ bpy.types.VIEW3D_MT_object_specials.append(menu_func)
+
+ for c in classes:
+ bpy.utils.register_class(c)
+
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+
+ bpy.types.VIEW3D_MT_object_specials.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/development_class_viewer.py b/release/scripts/addons_contrib/development_class_viewer.py
new file mode 100644
index 0000000..31a0a5c
--- /dev/null
+++ b/release/scripts/addons_contrib/development_class_viewer.py
@@ -0,0 +1,194 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Class Viewer",
+ "author": "Mackraken", "batFinger"
+ "version": (0, 1, 2),
+ "blender": (2, 58, 0),
+ "location": "Text Editor > Toolbar, Text Editor > Right Click",
+ "warning": "",
+ "description": "List classes and definitions of a text block",
+ "wiki_url": "https://sites.google.com/site/aleonserra/home/scripts/class-viewer",
+ "category": "Development"}
+
+import bpy
+
+#lists all defs, comment or classes
+#space = current text editor
+#sort = sort result
+#tipo = kind of struct to look for
+#escape = character right next to the class or def name
+
+def getfunc(space, sort, tipo="def ", escape= ""):
+ defs = []
+ if space.type=="TEXT_EDITOR":
+ if space.text!=None:
+ txt = space.text
+
+ for i, l in enumerate(txt.lines):
+ try:
+ line = l.body
+ except:
+ line=""
+
+ if line[0:len(tipo)]==tipo:
+ end = line.find(escape)
+ if end==0:
+ func = line[len(tipo)::]
+ else:
+ func = line[len(tipo):end]
+ defs.append([func, i+1])
+
+ if sort: defs.sort()
+
+ return defs
+
+class TEXT_OT_Jumptoline(bpy.types.Operator):
+ bl_label = "Jump"
+ bl_idname = "text.jumptoline"
+ __doc__ = "Jump to line"
+ line = bpy.props.IntProperty(default=-1)
+
+ @classmethod
+ def poll(cls, context):
+ if context.area.spaces[0].type!="TEXT_EDITOR":
+ return False
+ else:
+ return context.area.spaces[0].text!=None
+
+ def execute(self, context):
+
+ scn = context.scene
+
+ if self.line!=-1:
+ bpy.ops.text.jump(line=self.line)
+
+ return {'FINISHED'}
+
+
+
+class CommentsMenu(bpy.types.Menu):
+ bl_idname = "OBJECT_MT_select_comments"
+ bl_label = "Select"
+
+
+
+ @classmethod
+ def poll(cls, context):
+ if context.area.spaces[0].type!="TEXT_EDITOR":
+ return False
+ else:
+ return context.area.spaces[0].text!=None
+
+ def draw(self, context):
+
+ layout = self.layout
+ space = context.area.spaces[0]
+
+ items = getfunc(space, 1, "### ", "")
+
+ for it in items:
+ layout.operator("text.jumptoline",text=it[0]).line = it[1]
+
+class DefsMenu(bpy.types.Menu):
+ bl_idname = "OBJECT_MT_select_defs"
+ bl_label = "Select"
+
+ tipo = bpy.props.BoolProperty(default=False)
+
+ @classmethod
+ def poll(cls, context):
+ if context.area.spaces[0].type!="TEXT_EDITOR":
+ return False
+ else:
+ return context.area.spaces[0].text!=None
+
+ def draw(self, context):
+ scn = context.scene
+ layout = self.layout
+ space = context.area.spaces[0]
+ tipo = self.tipo
+
+
+ items = getfunc(space, 1, "def ", "(")
+
+ for it in items:
+ layout.operator("text.jumptoline",text=it[0]).line = it[1]
+
+class ClassesMenu(bpy.types.Menu):
+ bl_idname = "OBJECT_MT_select_classes"
+ bl_label = "Select"
+
+
+
+ @classmethod
+ def poll(cls, context):
+ if context.area.spaces[0].type!="TEXT_EDITOR":
+ return False
+ else:
+ return context.area.spaces[0].text!=None
+
+ def draw(self, context):
+
+ layout = self.layout
+ space = context.area.spaces[0]
+
+
+
+ items = getfunc(space, 1, "class ", "(")
+
+ for it in items:
+ layout.operator("text.jumptoline",text=it[0]).line = it[1]
+
+
+
+def GotoComments(self, context):
+ self.layout.menu("OBJECT_MT_select_comments", text="Comments", icon='PLUGIN')
+ return False
+
+def GotoDefs(self, context):
+ self.layout.menu("OBJECT_MT_select_defs", text="Defs", icon='PLUGIN')
+ return False
+
+def GotoClasses(self, context):
+ self.layout.menu("OBJECT_MT_select_classes", text="Classes", icon='PLUGIN')
+ return False
+
+
+classes = [TEXT_OT_Jumptoline, ClassesMenu, DefsMenu, CommentsMenu]
+
+
+def register():
+ for c in classes:
+ bpy.utils.register_class(c)
+
+ bpy.types.TEXT_MT_toolbox.append(GotoComments)
+ bpy.types.TEXT_MT_toolbox.append(GotoDefs)
+ bpy.types.TEXT_MT_toolbox.append(GotoClasses)
+
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+
+ bpy.types.TEXT_MT_toolbox.remove(GotoComments)
+ bpy.types.TEXT_MT_toolbox.remove(GotoDefs)
+ bpy.types.TEXT_MT_toolbox.remove(GotoClasses)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py
new file mode 100644
index 0000000..75ea386
--- /dev/null
+++ b/release/scripts/addons_contrib/game_engine_ragdolls_kit/__init__.py
@@ -0,0 +1,91 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Script copyright (C) Marcus Jenkins (Blenderartists user name FunkyWyrm)
+# Modified by Kees Brouwer (Blenderartists user name Wraaah)
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+bl_info = {
+ "name": "BRIK - Blender Ragdoll Implementation Kit",
+ "author": "FunkyWyrm",
+ "version": (0,2),
+ "blender": (2, 55, 0),
+ "api": 31965,
+ "location": "View 3D > Tool Shelf > BRIK Panel",
+ "description": "Kit for creating ragdoll structures from armatures and implementing them in the game engine.",
+ "warning": "Preliminary release for testing purposes. Use with caution on important files.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
+ "Scripts/Game_Engine/BRIK_ragdolls",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=24946",
+ "category": "Game Engine"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(brik)
+else:
+ from . import brik
+
+import bpy
+
+################################################################################
+
+##### REGISTER #####
+def register():
+ #Register brik add-on
+ bpy.utils.register_module(__name__)
+
+ #Set-up gui menu properties using the bpy.types.Scene type
+ scnType = bpy.types.Scene
+
+ FloatProperty = bpy.props.FloatProperty
+ scnType.brik_ragdoll_mass = FloatProperty( name = "Ragdoll mass",
+ default = 80.0, min = 0.05, max= 99999,
+ description = "The total mass of the ragdoll rigid body structure created with BRIK",
+ update = brik.calc_ragdoll_mass)
+
+ # triplet setup.... ( return value, name, description )
+ EnumProperty = bpy.props.EnumProperty
+ menu_options = [ ( "All", "All", "Use all armature bones" ) ]
+ #enumProp = EnumProperty( name = "Bone selection", items = menu_options,
+ enumProp = EnumProperty( name = "Bone selection", items = brik_bone_list,
+ description = "Use the bones from the selected bone group" )
+
+ scnType.brik_bone_groups = enumProp
+ pass
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ pass
+
+def brik_bone_list(self, context):
+ ob = bpy.context.object
+ group_list = [ ( "All", "All", "Use all armature bones" ) ]
+ if ob.type == 'ARMATURE':
+ #Select bone groups
+ ob_pose = ob.pose
+ bone_groups = ob_pose.bone_groups
+ for item in bone_groups:
+ group_list = group_list + [(item.name, item.name, "Use bones in selected bone group")]
+
+ return group_list
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik.py
new file mode 100644
index 0000000..6cafaa5
--- /dev/null
+++ b/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik.py
@@ -0,0 +1,1243 @@
+#brik_0_2.py
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Script copyright (C) Marcus Jenkins (Blenderartists user name FunkyWyrm)
+# Modified by Kees Brouwer (Blenderartists user name Wraaah)
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+"""
+brik is the Blender Ragdoll Implementation Kit.
+
+It aims to provide a tool kit that enables the easy implementation of ragdolls in Blender.
+
+Acnowledgements:
+ This section comes first because I am grateful to Thomas Eldredge (teldredge on
+www.blenderartists.com). Without his great script to take apart, I would never have got
+around to this even though it's been in my todo list for a while. The link to his thread is
+http://blenderartists.org/forum/showthread.php?t=152150
+
+Website:
+ Blenderartists script development thread is:
+ http://blenderartists.org/forum/showthread.php?t=199191
+
+Bugs:
+
+ Editing a text file after hitting the create or destroy button and then
+ changing an option such as writing the hierarchy file will undo the edits
+ to the text. This is a known bug due to the lack of a text editor global
+ undo push. See the bug tracker:
+ https://projects.blender.org/tracker/index.php?func=detail&aid=21043&group_id=9&atid=498
+
+ Creating rigid body structures based on multiple armatures in the scene that have similarly
+ named bones can cause some rigid body objects to be removed. This can probably be fixed by
+ testing for membership of a group. However, similarly named bones should be renamed to a
+ unique name since bone name and driver object name being similar is essential for correct
+ operation of both the brik script and the brik_Use_doll game engine script.
+
+ Running Create multiple times on the same armature will recreate the rigid body joints
+ rather than editing existing ones.
+
+Notes:
+
+ The mass of each object could be calculated using their volume. The
+ armature could be assigned a mass and the bones' mass could be calculated
+ from this using their volume.
+
+ Non-deforming bones do not have rigid body objects created for them.
+ Perhaps this would be better given as a toggle option.
+"""
+
+import bpy
+from bpy.props import *
+import mathutils
+from mathutils import Vector
+from game_engine_ragdolls_kit.brik_funcs import *
+
+class VIEW3D_PT_brik_panel(bpy.types.Panel):
+
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_context = 'objectmode'
+ bl_label = 'brik'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ #Draws the panel header in the tools pane
+ def draw_header(self, context):
+ layout = self.layout
+ layout.label(text='', icon='CONSTRAINT_BONE')
+
+ #Draws the brik panel in the tools pane
+ def draw(self, context):
+ ob = bpy.context.object
+ scn = bpy.context.scene
+ layout = self.layout
+
+ col = layout.column()
+
+ if ob:
+ col.prop(ob, 'name', text = 'Selected', icon = 'OUTLINER_OB_'+str(ob.type))
+
+ layout.separator()
+
+ box = layout.box()
+ box.label(text = 'Create or remove?')
+
+
+ if ob.type == 'ARMATURE':
+ brik_structure = 'brik_structure_created' in ob.keys() and ob['brik_structure_created']
+ hitboxes = 'brik_hit_boxes_created' in ob.keys() and ob['brik_hit_boxes_created']
+
+ col.label(text = 'BRIK structure settings')
+ row = col.row()
+ col.prop( scn, "brik_ragdoll_mass" )
+ col.prop( scn, "brik_bone_groups" )
+
+ col = box.column(align=True)
+ row = col.row()
+ row.active = not(brik_structure)
+ row.operator('object.brik_create_structure', text = 'Create structure')
+
+ row = col.row()
+ row.active = brik_structure
+ row.operator('object.brik_destroy_structure', text = 'Remove structure')
+
+ row = col.row()
+ row.active = not(hitboxes)
+# col = box.column(align = True)
+ row.operator('object.brik_create_hit_boxes', text = 'Create hit boxes')
+
+ row = col.row()
+ row.active = hitboxes
+ row.operator('object.brik_remove_hit_boxes', text = 'Remove hit boxes')
+
+ row = col.row()
+ row.active = hitboxes and brik_structure
+ row.operator('object.brik_link_structure', text = 'Link objects')
+
+ else:
+ box.label(text='Select armature')
+
+ game_options_active = 'brik_structure_created' in ob.keys() and ob['brik_structure_created'] \
+ and 'brik_hit_boxes_created' in ob.keys() and ob['brik_hit_boxes_created']
+ col = box.column(align = True)
+ col.active = game_options_active
+ col.label(text='Game options:')
+ col.operator('object.brik_write_game_file', text = 'Write game file')
+ create_logic_active = 'brik_file_written' in ob.keys() and ob['brik_file_written']
+ row = col.row()
+ row.active = create_logic_active
+ row.operator('object.brik_create_game_logic', text = 'Create game logic')
+
+ else:
+ col.label(text='Select an object')
+
+ def test_func(operator):
+ print(operator)
+
+class brik_link_structure(bpy.types.Operator):
+ bl_label = 'brik link structure operator'
+ bl_idname = 'object.brik_link_structure'
+ bl_description = 'Links the object data of the hitboxes and corresponding rigid bodies'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def draw(self, context):
+ #No menu options available
+ pass
+ #Create links
+ def execute(self, context):
+ armature = bpy.context.active_object
+ driver_dict = armature['brik_bone_driver_dict']
+ hitbox_dict = armature['brik_bone_hit_box_dict']
+ objects = bpy.data.objects
+ for bone_name in hitbox_dict:
+ hitbox = objects[hitbox_dict[bone_name]]
+# print(driver_dict, bone_name, objects)
+ driver_box = objects[driver_dict[bone_name]]
+ #select hitbox
+ select_name(name = hitbox_dict[bone_name], extend = False)
+ #select driver_box
+ select_name(name = driver_dict[bone_name], extend = True)
+ #create link
+ bpy.ops.object.make_links_data(type='OBDATA')
+ #return original selection
+ select_name(name = armature.name, extend = False)
+
+ return{'FINISHED'}
+
+class brik_create_structure(bpy.types.Operator):
+ bl_label = 'brik create structure operator'
+ bl_idname = 'object.brik_create_structure'
+ bl_description = 'Create a rigid body structure based on an amature.'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ #Properties that can be changed by the user
+
+ prefix = StringProperty(name='Prefix', \
+ description='Prefix to be appended to the bone name that defines the rigid body object.',\
+ default='RB_')
+
+ driver_length = FloatProperty(name='Driver length',\
+ description='Length of rigid body driver objects as proportion of bone length.',\
+ min=0.05,\
+ max=1.0,\
+ step=0.05,\
+ default=0.8)
+
+ driver_width = FloatProperty(name = 'Driver width',\
+ description='Width of rigid body driver objects as proportion of bone length',\
+ min=0.05,\
+ max=1.0,\
+ step=0.05,\
+ default=0.2)
+
+ add_to_group = BoolProperty(name='Add to group',\
+ description='Add all created objects to a group',\
+ default=True)
+
+ invisible = BoolProperty(name='Invisible',\
+ description='Make boxes invisible for rendering',\
+ default=True)
+
+
+ box_type = EnumProperty(name="Box type",
+ description="Shape that rigid body objects are created from.",
+ items=[ \
+ ('BONE', "Bone",
+ "Plain bone dimensions are used."),
+ ('ENVELOPE', "Envelope",
+ "Bone envelope dimensions are used."),
+ ('BBONE', "BBone",
+ "BBone dimensions are used. "\
+ "(BBones can be scaled using Ctrl+Alt+S in armature edit mode.)"),
+ ],
+ default='BBONE')
+
+ #Create the rigid body boxes
+ def create_boxes(self, armature):
+ bones = bone_group_list(armature)
+
+ RB_dict = {} #Dictionary of rigid body objects
+
+ armature['brik_bone_driver_dict'] = {}
+ armature['brik_armature_locator_name'] = ''
+
+ #All deforming bones within selected group(s) have boxes created for them
+ for bone in bones:
+
+ box = None
+ #Create boxes that do not exist
+ if self.box_type == 'BONE':
+ box, volume = create_box(self.prefix, self.driver_length, self.driver_width, armature, bone)
+ elif self.box_type == 'BBONE':
+ box, volume = create_box_bbone(self.prefix, armature, bone)
+ elif self.box_type == 'ENVELOPE':
+ box, volume = create_box_envelope(self.prefix, armature, bone)
+
+ RB_dict[box.name] = box
+ armature['brik_bone_driver_dict'][bone.name] = box.name
+
+ #Orientate and position the box
+ position_box(armature, bone, box)
+ box['brik_bone_name'] = bone.name
+
+ #### Contributed by Wraaah #########
+# box.game.physics_type = 'RIGID_BODY'
+ box.game.mass = volume
+ box.hide_render = self.invisible
+ ##############################
+ return RB_dict
+
+ def make_bone_constraints(self, armature, RB_dict):
+ bones = bone_group_list(armature)
+ #bones_dict = armature.pose.bones
+
+ #for bone in bones_dict:
+ for bone in bones:
+ if not 'brik_copy_rot' in bone.constraints:
+ constraint = bone.constraints.new(type='COPY_ROTATION')
+ constraint.name = 'brik_copy_rot'
+ constraint.target = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
+ #Enable posing armature after creating brik structure
+ constraint.influence = 0.0
+ if not 'brik_copy_loc' in bone.constraints:
+ #Check if copy loc is needed
+ use_copy_loc = False
+ #rigid_body_name = rigid_bodies[bone_name]
+ if bone.parent:
+ if bones.count(bone.parent) == 0:
+ use_copy_loc = True
+ else:
+ use_copy_loc = True
+
+ if use_copy_loc:
+ RB_object = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
+ loc_targ_name = RB_object.name + "_loc"
+ #print(bone.head, bone.tail)
+ if bpy.data.objects.get(loc_targ_name, False):
+ locator = bpy.data.objects[loc_targ_name]
+ locator.location = (0.0,-bone.length/2,0.0)
+ locator.parent = RB_object
+ else:
+ bpy.ops.object.add(type='EMPTY')
+ locator = bpy.context.object
+ locator.name = loc_targ_name
+ locator.location = (0.0,-bone.length/2,0.0)
+ locator.parent = RB_object
+ #bpy.ops.object.select_all(action='DESELECT')
+ #armature.select = True
+ select_name(name=armature.name, extend=False)
+ constraint = bone.constraints.new(type='COPY_LOCATION')
+ constraint.name = 'brik_copy_loc'
+ constraint.target = locator
+ #Enable posing armature after creating brik structure
+ constraint.influence = 0.0
+
+ def reshape_boxes(self, armature):
+ """
+ Reshape an existing box based on parameter changes.
+ I introduced this as an attempt to improve responsiveness. This should
+ eliminate the overhead from creating completely new meshes or objects on
+ each refresh.
+ """
+ objects = bpy.context.scene.objects
+
+ for bone_name in armature['brik_bone_driver_dict']:
+ bone = armature.bones[bone_name]
+ box = objects[armature['brik_bone_driver_dict'][bone_name]]
+
+ height = bone.length
+ #gap = height * self.hit_box_length #The distance between two boxes
+ box_length = bone.length*self.driver_length
+ width = bone.length * self.driver_width
+
+ x = width/2
+ y = box_length/2
+ z = width/2
+
+ verts = [[-x,y,-z],[-x,y,z],[x,y,z],[x,y,-z],\
+ [x,-y,-z],[-x,-y,-z],[-x,-y,z],[x,-y,z]]
+
+ #This could be a problem if custom object shapes are used...
+ count = 0
+ for vert in box.data.vertices:
+ vert.co = Vector(verts[count])
+ count += 1
+
+
+ #Set up the objects for rigid body physics and create rigid body joints.
+ def make_RB_constraints(self, armature, RB_dict):
+ bones_dict = armature.pose.bones
+
+ for box in RB_dict:
+ bone = bones_dict[RB_dict[box]['brik_bone_name']]
+
+ boxObj = RB_dict[box]
+
+ #Make the radius half the length of the longest axis of the box
+ radius_driver_length = (bone.length*self.driver_length)/2
+ radius_driver_width = (bone.length*self.driver_width)/2
+ radius = radius_driver_length
+ if radius_driver_width > radius:
+ radius = radius_driver_width
+
+
+ #Set up game physics attributes
+ boxObj.game.use_actor = True
+ boxObj.game.use_ghost = False
+ boxObj.game.physics_type = 'RIGID_BODY'
+ boxObj.game.use_collision_bounds = True
+ boxObj.game.collision_bounds_type = 'BOX'
+ boxObj.game.radius = radius
+
+ #Make the rigid body joints
+ if bone.parent:
+ #print(bone, bone.parent)
+ boxObj['brik_joint_target'] = armature['brik_bone_driver_dict'][bone.parent.name]
+ RB_joint = boxObj.constraints.new('RIGID_BODY_JOINT')
+ RB_joint.pivot_y = -bone.length/2
+ RB_joint.target = RB_dict[boxObj['brik_joint_target']]
+ RB_joint.use_linked_collision = True
+ RB_joint.pivot_type = ("GENERIC_6_DOF")
+ RB_joint.limit_angle_max_x = bone.ik_max_x
+ RB_joint.limit_angle_max_y = bone.ik_max_y
+ RB_joint.limit_angle_max_z = bone.ik_max_z
+ RB_joint.limit_angle_min_x = bone.ik_min_x
+ RB_joint.limit_angle_min_y = bone.ik_min_y
+ RB_joint.limit_angle_min_z = bone.ik_min_z
+ RB_joint.use_limit_x = True
+ RB_joint.use_limit_y = True
+ RB_joint.use_limit_z = True
+ RB_joint.use_angular_limit_x = True
+ RB_joint.use_angular_limit_y = True
+ RB_joint.use_angular_limit_z = True
+ else:
+ boxObj['brik_joint_target'] = 'None'
+
+ def add_boxes_to_group(self, armature, RB_dict):
+
+ #print("Adding boxes to group")
+ group_name = self.prefix+armature.name+"_Group"
+ if not group_name in bpy.data.groups:
+ group = bpy.data.groups.new(group_name)
+ else:
+ group = bpy.data.groups[group_name]
+ #print(group)
+ #print(RB_dict)
+ for box in RB_dict:
+ if not box in group.objects:
+ group.objects.link(bpy.context.scene.objects[box])
+ box_loc = box + "_loc"
+ print(box_loc)
+ if bpy.context.scene.objects.get(box_loc, None):
+ if not box_loc in group.objects:
+ group.objects.link(bpy.context.scene.objects[box_loc])
+
+ armature["ragdoll_group"] = group.name
+ return
+
+ #Armature and mesh need to be set to either no collision or ghost. No collision
+ #is much faster.
+ #=> also affects Hitboxes & armature collision shape, need to be fixed/reconsidered
+ def set_armature_physics(self, armature):
+ armature.game.physics_type = 'NO_COLLISION'
+# for child in armature.children:
+# if hasattr(armature, "['brik_hit_boxes_created']"):
+# if child.name in armature['brik_bone_hit_box_dict'].values():
+# continue
+# else:
+# child.game.physics_type = 'NO_COLLISION'
+# else:
+# child.game.physics_type = 'NO_COLLISION'
+
+
+ #The ui of the create operator that appears when the operator is called
+ def draw(self, context):
+ layout = self.layout
+
+ box = layout.box()
+ box.prop(self.properties, 'prefix')
+ box.prop(self.properties, 'add_to_group')
+ box.prop(self.properties, 'invisible')
+ box.prop(self.properties, 'box_type')
+ if self.box_type == 'BONE':
+ box.prop(self.properties, 'driver_length')
+ box.prop(self.properties, 'driver_width')
+
+ #The main part of the create operator
+ def execute(self, context):
+ #print("\n##########\n")
+ #print("EXECUTING brik_create_structure\n")
+
+ armature = context.object
+
+ self.set_armature_physics(armature)
+
+
+ if 'brik_structure_created' in armature.keys()\
+ and armature['brik_structure_created'] == True\
+ and self.box_type == 'BONE':
+
+ self.reshape_boxes(armature)
+
+ else:
+ RB_dict = self.create_boxes(armature)
+ armature['brik_structure_created'] = True
+ armature['brik_prefix'] = self.prefix
+
+ self.make_RB_constraints(armature, RB_dict)
+ self.make_bone_constraints(armature, RB_dict)
+
+ if self.add_to_group:
+ self.add_boxes_to_group(armature, RB_dict)
+
+ calc_ragdoll_mass(self, context)
+
+ return{'FINISHED'}
+
+class brik_destroy_structure(bpy.types.Operator):
+ bl_label = 'brik destroy structure operator'
+ bl_idname = 'object.brik_destroy_structure'
+ bl_description = 'Destroy a rigid body structure created by this brik.'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ """
+ For some reason the remove operators give a "cyclic" warning in the console.
+
+ I have no idea what this means and have not been able to find out what this means.
+ """
+
+ def execute(self, context):
+ print("\n##########\n")
+ print("EXECUTING brik_remove_structure")
+ armature = context.object
+ scene = context.scene
+
+ bpy.ops.object.select_all(action='DESELECT')
+ #Clean up all created objects, their meshes and bone constraints
+ for bone_name in armature['brik_bone_driver_dict']:
+ driver = scene.objects[armature['brik_bone_driver_dict'][bone_name]]
+ #Unlink and remove the mesh
+# mesh = driver.data
+# driver.data = None
+# mesh.user_clear()
+# bpy.data.meshes.remove(mesh)
+ select_name( name = armature['brik_bone_driver_dict'][bone_name], extend = True)
+ objects = bpy.data.objects
+ driver_loc = objects.get(driver.name + "_loc", None)
+ if driver_loc:
+ select_name( name = driver_loc.name, extend = True)
+
+ #Unlink and remove the object
+# scene.objects.unlink(driver)
+# driver.user_clear()
+# bpy.data.objects.remove(driver)
+
+ #Remove bone constraints
+ bone = armature.pose.bones[bone_name]
+ if 'brik_copy_rot' in bone.constraints:
+ const = bone.constraints['brik_copy_rot']
+ bone.constraints.remove(const)
+ if 'brik_copy_loc' in bone.constraints:
+ const = bone.constraints['brik_copy_loc']
+ locator = const.target
+ bone.constraints.remove(const)
+
+ #Remove armature locator
+ #locator = bpy.data.objects[armature['brik_armature_locator_name']]
+# scene.objects.unlink(locator)
+# locator.user_clear()
+# bpy.data.objects.remove(locator)
+ bpy.ops.object.delete(use_global=False)
+ bpy.ops.object.select_all(action='DESELECT')
+ scene.objects.active = armature
+
+ #Remove driver group
+ group_name = armature['brik_prefix']+armature.name+'_Group'
+ if group_name in bpy.data.groups:
+ group = bpy.data.groups[group_name]
+ bpy.data.groups.remove(group)
+
+ #Remove custom properties
+ #del armature['brik_armature_locator_name']
+ del armature['brik_structure_created']
+ del armature['brik_bone_driver_dict']
+ del armature['brik_prefix']
+
+ return{'FINISHED'}
+
+class brik_create_game_logic(bpy.types.Operator):
+ bl_label = 'brik create game logic operator'
+ bl_idname = 'object.brik_create_game_logic'
+ bl_description = 'Create the game logic for the created objects.'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ template_path = bpy.utils.script_paths()[0]+'\\addons_contrib\\game_engine_ragdolls_kit\\templates\\'
+
+ game_script_list = ['brik_load.py', \
+ 'brik_init_ragdoll.py', \
+ 'brik_spawn.py']
+
+
+ def set_up_armature_logic(self, armature):
+
+ if not 'brik_use_ragdoll' in armature.game.properties:
+
+ bpy.ops.object.game_property_new()
+ prop = armature.game.properties[-1]
+ prop.name = 'brik_use_ragdoll'
+ prop.type = 'BOOL'
+ prop.value = False
+
+ bpy.ops.object.game_property_new()
+ prop = armature.game.properties[-1]
+ prop.name = 'brik_init_ragdoll'
+ prop.type = 'BOOL'
+ prop.value = True
+ #Add groups if needed
+ hitbox_group = armature["hitbox_group"]
+ if not(bpy.data.objects.get(hitbox_group, None)):
+ bpy.ops.object.group_instance_add(group=hitbox_group)
+ ragdoll_group = armature["ragdoll_group"]
+ if not(bpy.data.objects.get(ragdoll_group, None)):
+ bpy.ops.object.group_instance_add(group=ragdoll_group)
+
+ #Logic to spawn the rigid body boxes
+ bpy.ops.logic.sensor_add(type='PROPERTY', name='brik_use_changed_sens', object=armature.name)
+ sens = armature.game.sensors[-1]
+ sens.property = 'brik_use_ragdoll'
+ sens.evaluation_type = 'PROPCHANGED'
+
+ bpy.ops.logic.controller_add(type='PYTHON', name='brik_init_ragdoll_cont', object=armature.name)
+ cont = armature.game.controllers[-1]
+ cont.mode = 'MODULE'
+ cont.module = 'brik_init_ragdoll.main'
+
+ bpy.ops.logic.actuator_add(type='EDIT_OBJECT', name='brik_spawn_boxes_act', object=armature.name)
+ act = armature.game.actuators[-1]
+ act.mode = 'ADDOBJECT'
+ act.object = (bpy.data.objects.get(ragdoll_group, None))
+
+ cont.link(sens, act)
+
+ #Logic to change the value of brik_use_ragdoll property
+ bpy.ops.logic.sensor_add(type='KEYBOARD', name='brik_set_use_ragdoll_sens', object=armature.name)
+ sens = armature.game.sensors[-1]
+ sens.key = 'SPACE'
+
+ bpy.ops.logic.controller_add(type='LOGIC_AND', name='brik_set_use_ragdoll_cont', object=armature.name)
+ cont = armature.game.controllers[-1]
+
+ bpy.ops.logic.actuator_add(type='PROPERTY', name='brik_set_use_ragdoll_act', object=armature.name)
+ act = armature.game.actuators[-1]
+ act.mode = 'ASSIGN'
+ act.property = 'brik_use_ragdoll'
+ act.value = "True"
+
+ cont.link(sens, act)
+
+ #Logic to use the ragdoll.
+ bpy.ops.logic.sensor_add(type='PROPERTY', name='brik_use_sens', object=armature.name)
+ sens = armature.game.sensors[-1]
+ sens.property = 'brik_use_ragdoll'
+ sens.value = 'True'
+# sens.use_pulse_true_level = True
+
+ bpy.ops.logic.controller_add(type='LOGIC_AND', name='brik_use_cont', object=armature.name)
+ cont = armature.game.controllers[-1]
+
+ bpy.ops.logic.actuator_add(type='ACTION', name='brik_use_act', object=armature.name)
+ act = armature.game.actuators[-1]
+ act.type = 'ARMATURE'
+# act.mode = 'RUN'
+
+ cont.link(sens, act)
+
+ def set_up_spawn_logic(self, armature):
+ print('SETTING UP SPAWN LOGIC')
+ scene = bpy.context.scene
+
+ spawn_ob_name = armature.name + "_spawn"
+ #Need to use data to avoid naming conflicts
+ if not spawn_ob_name in bpy.data.objects:
+ bpy.ops.object.add()
+ spawn_object = bpy.context.object
+ spawn_object.name = spawn_ob_name
+
+ bpy.ops.object.game_property_new()
+ prop = spawn_object.game.properties[-1]
+ prop.name = "armature_name"
+ prop.type = 'STRING'
+# prop.value = armature.name
+ else:
+ spawn_object = bpy.data.objects[spawn_ob_name]
+
+ bpy.ops.object.select_all(action='DESELECT')
+ select_name(name=armature.name, extend=False)
+
+ prop = spawn_object.game.properties["armature_name"]
+ prop.value = armature.name
+
+ spawn_object.game.show_state_panel = False
+
+ #Add groups if needed
+ hitbox_group = armature["hitbox_group"]
+ if not(bpy.data.objects.get(hitbox_group, None)):
+ bpy.ops.object.group_instance_add(group=hitbox_group)
+ ragdoll_group = armature["ragdoll_group"]
+ if not(bpy.data.objects.get(ragdoll_group, None)):
+ bpy.ops.object.group_instance_add(group=ragdoll_group)
+
+ #Quick and dirty check to see if the spawn logic is already set up.
+ if not 'brik_spawn_cont' in spawn_object.game.controllers:
+ #The logic to spawn the mob
+ bpy.ops.logic.sensor_add(type='KEYBOARD', name='brik_Tab_sens', object=spawn_object.name)
+ sens = spawn_object.game.sensors[-1]
+ sens.key = 'TAB'
+
+ bpy.ops.logic.controller_add(type='PYTHON', name='brik_spawn_cont', object=spawn_object.name)
+ cont = spawn_object.game.controllers[-1]
+ cont.mode = 'MODULE'
+ cont.module = 'brik_spawn.main'
+
+ bpy.ops.logic.actuator_add(type='EDIT_OBJECT', name='brik_spawn_act', object=spawn_object.name)
+ act = spawn_object.game.actuators[-1]
+ act.object = bpy.data.objects.get(hitbox_group, None)
+
+ cont.link(sens, act)
+
+ #Logic to load structure information
+ bpy.ops.logic.sensor_add(type='ALWAYS', name='brik_load_sens', object=spawn_object.name)
+ sens = spawn_object.game.sensors[-1]
+
+ bpy.ops.logic.controller_add(type='PYTHON', name='brik_load_cont', object=spawn_object.name)
+ cont = spawn_object.game.controllers[-1]
+ cont.text = bpy.data.texts['brik_load.py']
+
+ sens.link(cont)
+
+ #Logic to initialise the spawn point with object to add, added object list and added object count.
+ bpy.ops.logic.controller_add(type='PYTHON', name='brik_spawn_init_cont', object=spawn_object.name)
+ cont = spawn_object.game.controllers[-1]
+ cont.mode = 'MODULE'
+ cont.module = 'brik_spawn.initialize'
+
+ sens.link(cont)
+
+ #Properties and text files to define the mobs that can be spawned.
+ for text in bpy.data.texts:
+
+ print('CONSIDERING TEXT '+text.name)
+ prefix = armature['brik_prefix']
+ print(text.name[len(prefix):-4])
+
+
+ #If there is an armature and text pair.
+ if text.name[len(prefix):-4] == armature.name:
+ #If no mobs have been accounted for yet.
+ if not 'brik_mob_count' in spawn_object.game.properties:
+ print('CREATING PROPERTY brik_mob_count')
+ bpy.ops.object.select_all(action='DESELECT')
+ spawn_object.select = True
+ scene.objects.active = spawn_object
+
+ bpy.ops.object.game_property_new()
+ count_prop = spawn_object.game.properties[-1]
+ count_prop.name = 'brik_mob_count'
+ count_prop.type = 'INT'
+ count_prop.value = -1 #Initialised to -1 meaning no data controllers yet created.
+
+ bpy.ops.object.select_all(action='DESELECT')
+ select_name(name=armature.name, extend=False)
+ else:
+ count_prop = spawn_object.game.properties['brik_mob_count']
+
+ #Find a list of armature texts currently accounted for in logic.
+ current_texts = []
+ for cont in spawn_object.game.controllers:
+ if cont.name[:-1] == 'brik_ragdoll_data_':
+ current_texts.append(cont.text)
+
+ #Create a new data controller for any text not considered.
+ if not text in current_texts:
+ count_prop.value += 1
+ #Controller to store structure information.
+ print('CREATING DATA CONTROLLER')
+ bpy.ops.logic.controller_add(type='PYTHON', name='brik_ragdoll_data_'+str(int(count_prop.value)), object=spawn_object.name)
+ cont = spawn_object.game.controllers[-1]
+ cont.text = text
+
+
+ def set_up_hit_box_logic(self, armature, bone_name):
+ hit_box = bpy.data.objects[armature['brik_bone_hit_box_dict'][bone_name]]
+ scene = bpy.context.scene
+
+ #Simply create a property for the ray cast to look for.
+ if not 'brik_can_hit' in hit_box.game.properties:
+ hit_box.select = True
+ scene.objects.active = hit_box
+ bpy.ops.object.game_property_new()
+ print(*hit_box.game.properties)
+ prop = hit_box.game.properties[-1]
+ prop.name = 'brik_can_hit'
+ prop.type = 'BOOL'
+ prop.value = True
+ scene.objects.active = armature
+ hit_box.select = False
+
+ return
+
+ def load_game_scripts(self):
+
+ for script_name in self.game_script_list:
+ if not script_name in bpy.data.texts:
+ bpy.data.texts.load(self.template_path+script_name)
+
+ return
+
+
+ def execute(self, context):
+ self.load_game_scripts()
+
+ armature = context.object
+
+ self.set_up_armature_logic(armature)
+ #Is ray property required?
+ #bones = bone_group_list(armature)
+ #for bone_name in bones:
+ # self.set_up_hit_box_logic(armature, bone_name)
+ self.set_up_spawn_logic(armature)
+
+
+
+ return{'FINISHED'}
+
+class brik_write_game_file(bpy.types.Operator):
+ bl_label = 'brik write game file operator'
+ bl_idname = 'object.brik_write_game_file'
+ bl_description = 'Write a file containing a description of the rigid body structure'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ #Find the most efficient order to calculate bone rotations in the game engine
+ #Not used
+ def calculate_structure(self, armature):
+ bones = bone_group_list(armature)
+# boneDict = armature.pose.bones
+
+ boneChainsDict = {}
+ maxLength = 0 #This is the length of the longest chain of bones
+
+ #Find the chains of bone parentage in the armature
+ for poseBone in boneDict:
+ bone = poseBone.bone
+ boneChain = []
+ while True:
+ boneChain.append(bone.name)
+ if bone.parent:
+ bone = bone.parent
+ else:
+ boneChainsDict[boneChain[0]] = boneChain
+ if len(boneChain) > maxLength:
+ maxLength = len(boneChain)
+ break
+
+ #Sort the bone chains to find which bone rotations to calculate first
+ optimalBoneOrder = self.find_optimal_bone_order(boneChainsDict, maxLength)
+
+ return optimalBoneOrder, boneChainsDict
+
+ #Not used
+ def find_optimal_bone_order(self, boneChainsDict, maxLength):
+ tempBoneChainsOrder = []
+
+ #Reorder the bone chains so that shorter bone chains are at the start of the list
+ for n in range(1,maxLength+1):
+ for chain in boneChainsDict:
+ if len(boneChainsDict[chain]) == n:
+ tempBoneChainsOrder.append(boneChainsDict[chain])
+
+ #Create a final list of bones so that the bones that need to be calculated first are
+ #at the start
+ finalBoneOrder = []
+ for chain in tempBoneChainsOrder:
+ finalBoneOrder.append(chain[0])
+ return finalBoneOrder
+
+ """
+ I've found a method of reading from an internal text file in the game
+ engine... Place the text file in a python script controller set to 'script'
+ and it can be accessed as a string through cont.script. To avoid throwing
+ a script compilation error on startup, all text must be enclosed within
+ triple quotation marks as a block comment.
+ There is no need to mess with different file systems and platforms... It can
+ all be done internally. =D
+ """
+
+# def save_structure_data(self, armature, optimalBoneOrder, boneChainsDict):
+ def save_structure_data(self, armature, bones):
+
+ prefix = armature['brik_prefix']
+ #Create or clear the text file for this armature
+ texts = bpy.data.texts
+ if prefix+armature.name+".txt" not in texts:
+ dataFile = texts.new(prefix+armature.name+".txt")
+ else:
+ dataFile = texts[prefix+armature.name+".txt"]
+ dataFile.clear()
+
+ #Write to the text file
+ dataFile.write("'''\n")
+
+ dataFile.write(armature.name+"\n")
+
+ dataFile.write("'' Bone : Hitbox : Rigid body : Location constraint (optional)\n")
+ #Write bone data to the file
+ rigid_bodies = armature['brik_bone_driver_dict']
+ hitboxes = armature['brik_bone_hit_box_dict']
+ for bone in bones:
+ #How to first bone => also copy locations needs to be activated
+ bone_name = bone.name
+ hitbox_name = hitboxes[bone_name]
+ rigid_body_name = rigid_bodies[bone_name]
+ text_str = " : ".join([bone_name, hitbox_name, rigid_body_name])
+
+ if bone.parent:
+ if bones.count(bone.parent) == 0:
+ text_str = text_str + " : " + rigid_bodies[bone_name] + "_loc"
+ else:
+ text_str = text_str + " : " + rigid_bodies[bone_name] + "_loc"
+
+ dataFile.write(text_str +"\n")
+ dataFile.write("'' 6DOF constraints\n")
+ dataFile.write("'' 6DOF parameters are optional, if not defined default values are used\n")
+ id_num = 1
+ for bone in bones:
+ if bone.parent:
+ bone_name = bone.name
+ bone_parent = bone.parent
+ parent_name = bone_parent.name
+ ob = rigid_bodies[bone_name]
+ targ = rigid_bodies[parent_name]
+
+ #6DOF name
+# dataFile.write("constraint_name = 6DOF" + str(id_num) + "\n")
+ dataFile.write("constraint_name = 6DOF_" + ob + "_" + targ + "\n")
+ id_num = id_num + 1
+ #ob name
+ dataFile.write("object = " + ob + "\n")
+ #targ name
+ dataFile.write("target = " + targ + "\n")
+ #optional
+ #x,y,z point, default 0.0
+ pivot_y = - bone.length * 0.5
+ dataFile.write("pivot_y = " + str(pivot_y) + "\n")
+ #Rx,Ry,Rz point, default 0.0
+ #min/max x,y,z limit, default 0.0
+ #min/max Rx,Ry,Rz limit, default off & Rx,Ry,Rz spring, default off
+ if bone.use_ik_limit_x == True:
+ Rx_min = str(bone.ik_min_x)
+ dataFile.write("Rx_min = " + Rx_min + "\n")
+ Rx_max = str(bone.ik_max_x)
+ dataFile.write("Rx_max = " + Rx_max + "\n")
+ if bone.ik_stiffness_x != 0:
+ Rx_spring = str(bone.ik_stiffness_x)
+ dataFile.write("Rx_spring = " + Rx_spring + "\n")
+ if bone.use_ik_limit_y == True:
+ Ry_min = str(bone.ik_min_y)
+ dataFile.write("Ry_min = " + Ry_min + "\n")
+ Ry_max = str(bone.ik_max_y)
+ dataFile.write("Ry_max = " + Ry_max + "\n")
+ if bone.ik_stiffness_y != 0:
+ Ry_spring = str(bone.ik_stiffness_y)
+ dataFile.write("Ry_spring = " + Ry_spring + "\n")
+ if bone.use_ik_limit_z == True:
+ Rz_min = str(bone.ik_min_z)
+ dataFile.write("Rz_min = " + Rz_min + "\n")
+ Rz_max = str(bone.ik_max_z)
+ dataFile.write("Rz_max = " + Rz_max + "\n")
+ if bone.ik_stiffness_z != 0:
+ Rz_spring = str(bone.ik_stiffness_z)
+ dataFile.write("Rz_spring = " + Rz_spring + "\n")
+ #x,y,z spring, default off
+ #motors..., default off
+ dataFile.write("'''")
+
+ return
+
+ #Not used
+ def store_joint_data(self, armature):
+ """
+ Joint data is stored on the rigid body objects themselves. This will not be
+ necessary when the convertor is properly transferring these values from Blender
+ to the game engine.
+ """
+ for bone_name in armature['brik_optimal_order']:
+ box = bpy.data.objects[armature['brik_bone_driver_dict'][bone_name]]
+ if not box['brik_joint_target'] == 'None':
+ RB_joint = box.constraints[0]
+ bone = armature.pose.bones[box['brik_bone_name']]
+
+ ###############################
+ #Required for dynamic creation of joint in game
+ box['joint_position_x'] = RB_joint.pivot_x
+ box['joint_position_y'] = RB_joint.pivot_y
+ box['joint_position_z'] = RB_joint.pivot_z
+
+
+ """
+ It would be nice to use IK limits to define rigid body joint limits,
+ but the limit arrays have not yet been wrapped in RNA apparently...
+ properties_object_constraint.py in ui directory, line 554 says:
+ Missing: Limit arrays (not wrapped in RNA yet)
+
+ It is necessary to create the joint when spawning ragdolls anyway.
+ Joints can still be created in the game.
+ """
+
+ box['rot_max_x'] = bone.ik_max_x
+ box['rot_max_y'] = bone.ik_max_y
+ box['rot_max_z'] = bone.ik_max_z
+ box['rot_min_x'] = bone.ik_min_x
+ box['rot_min_y'] = bone.ik_min_y
+ box['rot_min_z'] = bone.ik_min_z
+
+ def execute(self, context):
+ armature = context.object
+
+ bones = bone_group_list(armature)
+# optimalBoneOrder, boneChainsDict = self.calculate_structure(armature)
+
+# armature['brik_optimal_order'] = optimalBoneOrder
+
+# self.store_joint_data(armature)
+
+ self.save_structure_data( armature, bones)
+
+ armature['brik_file_written'] = True
+
+
+ return{'FINISHED'}
+
+class brik_create_hit_boxes(bpy.types.Operator):
+ bl_label = 'brik create hit boxes operator'
+ bl_idname = 'object.brik_create_hit_boxes'
+ bl_description = 'Create hit boxes for each bone in an armature and parent them to the bones.'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ hit_box_prefix = StringProperty(name='Hit box prefix',\
+ description='Prefix to be appended to the bone name that defines the hit box',\
+ default='HIT')
+
+ hit_box_length = FloatProperty(name='Hit box length',\
+ description='Length of a hit box as a proportion of bone length.',\
+ min=0.05,\
+ max=1.0,\
+ step=0.05,\
+ default=0.8)
+
+ hit_box_width = FloatProperty(name = 'Hit box width',\
+ description='Width of a hit box as a proportion of bone length.',\
+ min=0.05,\
+ max=1.0,\
+ step=0.05,\
+ default=0.2)
+
+ add_to_group = BoolProperty(name='Add to group',\
+ description='Add hit boxes to a group',\
+ default=True)
+
+ invisible = BoolProperty(name='Invisible',\
+ description='Make boxes invisible for rendering',\
+ default=True)
+
+ box_type = EnumProperty(name="Box type",
+ description="Shape that hitbox objects are created from.",
+ items=[ \
+ ('BONE', "Bone",
+ "Plain bone dimensions are used."),
+ ('ENVELOPE', "Envelope",
+ "Bone envelope dimensions are used."),
+ ('BBONE', "BBone",
+ "BBone dimensions are used. "\
+ "(BBones can be scaled using Ctrl+Alt+S in armature edit mode.)"),
+ ],
+ default='BBONE')
+
+ #Create the hit boxes
+ def create_hit_boxes(self, armature):
+ bones = bone_group_list(armature)
+ hit_box_dict = {}
+ scn = bpy.context.scene
+
+ armature['brik_bone_hit_box_dict'] = {}
+# armature['brik_bone_driver_dict'] = {}
+# armature['brik_armature_locator_name'] = ''
+
+ #All deforming bones within selected group(s) have boxes created for them
+ for bone in bones:
+
+ box = None
+ #Create boxes that do not exist
+ if self.box_type == 'BONE':
+ hit_box, volume = create_box(self.hit_box_prefix, self.hit_box_length, self.hit_box_width, armature, bone)
+ elif self.box_type == 'BBONE':
+ hit_box, volume = create_box_bbone(self.hit_box_prefix, armature, bone)
+ elif self.box_type == 'ENVELOPE':
+ hit_box, volume = create_box_envelope(self.hit_box_prefix, armature, bone)
+
+ hit_box_dict[hit_box.name] = hit_box
+ # RB_dict[box.name] = box
+ armature['brik_bone_hit_box_dict'][bone.name] = hit_box.name
+# armature['brik_bone_driver_dict'][bone.name] = box.name
+
+ #Orientate and position the hitbox
+ self.parent_to_bone(armature, hit_box, bone.name)
+# position_box(armature, bone, hit_box)
+#=> do not set location rotation, they are relative to the parent bone thus need to be zero delta
+
+ hit_box['brik_bone_name'] = bone.name
+
+ hit_box.game.physics_type = 'STATIC'
+ hit_box.game.use_ghost = True
+ hit_box.hide_render = self.invisible
+
+ hit_box.game.mass = volume
+ return hit_box_dict
+
+ #Reshape an existing box based on parameter changes.
+ #I introduced this as an attempt to improve responsiveness. This should
+ #eliminate the overhead from creating completely new meshes or objects on
+ #each refresh.
+ #NOT USED
+ def reshape_hit_box(self, armature, bone):
+ #print('RESHAPING BOX')
+ armature_object = bpy.context.object
+ scene = bpy.context.scene
+ hit_box = scene.objects[armature['brik_bone_hit_box_dict'][bone.name]]
+
+ height = bone.length
+ box_length = bone.length*self.hit_box_length
+ width = bone.length * self.hit_box_width
+
+ x = width/2
+ y = box_length/2
+ z = width/2
+
+ verts = [[-x,y,-z],[-x,y,z],[x,y,z],[x,y,-z],\
+ [x,-y,-z],[-x,-y,-z],[-x,-y,z],[x,-y,z]]
+
+ #This could be a problem if custom object shapes are used...
+ count = 0
+ for vert in hit_box.data.vertices:
+ vert.co = Vector(verts[count])
+ count += 1
+
+ return(hit_box)
+
+ def add_hit_boxes_to_group(self, armature):
+ #print("Adding hit boxes to group")
+ group_name = self.hit_box_prefix+armature.name+"_Group"
+ if not group_name in bpy.data.groups:
+ group = bpy.data.groups.new(group_name)
+ else:
+ group = bpy.data.groups[group_name]
+
+ bone_hitbox = armature['brik_bone_hit_box_dict']
+ #Add armature to group
+# bone_hitbox["brik_armature_group"] = armature.name
+ for bone_name in bone_hitbox:
+ hit_box_name = bone_hitbox[bone_name]
+ if not hit_box_name in group.objects:
+ group.objects.link(bpy.data.objects[hit_box_name])
+ #Add armature to group
+ if not armature.name in group.objects:
+ group.objects.link( armature )
+
+ armature["hitbox_group"] = group.name
+
+ return
+
+ def parent_to_bone(self, armature, hit_box, bone_name):
+ #Thanks Uncle Entity. :)
+ hit_box.parent = armature
+ hit_box.parent_bone = bone_name
+ hit_box.parent_type = 'BONE'
+
+ return
+
+ #The ui of the create operator that appears when the operator is called
+ def draw(self, context):
+ layout = self.layout
+
+ box = layout.box()
+ box.prop(self.properties, 'hit_box_prefix')
+ box.prop(self.properties, 'add_to_group')
+ box.prop(self.properties, 'invisible')
+ box.prop(self.properties, 'box_type')
+ if self.box_type == 'BONE':
+ box.prop(self.properties, 'hit_box_length')
+ box.prop(self.properties, 'hit_box_width')
+
+ #The main part of the create operator
+ def execute(self, context):
+ #print("\n##########\n")
+ #print("EXECUTING brik_create_structure\n")
+
+ armature = context.object
+
+ hit_box_dict = self.create_hit_boxes(armature)
+
+ if self.add_to_group:
+ self.add_hit_boxes_to_group(armature)
+
+ armature['brik_hit_box_prefix'] = self.hit_box_prefix
+ armature['brik_hit_boxes_created'] = True
+
+ return{'FINISHED'}
+
+class brik_remove_hit_boxes(bpy.types.Operator):
+ bl_label = 'brik remove hit boxes operator'
+ bl_idname = 'object.brik_remove_hit_boxes'
+ bl_description = 'Remove hit boxes crested by this addon'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ """
+ For some reason the remove operators give a "cyclic" warning in the console.
+
+ I have no idea what this means and have not been able to find out what this means.
+ """
+
+ def remove_hit_box(self, scene, bone_name, armature):
+ #Function crashes with linked objects
+ hit_box = scene.objects[armature['brik_bone_hit_box_dict'][bone_name]]
+ #Unlink and remove the mesh
+# mesh = hit_box.data
+# hit_box.data = None
+# mesh.user_clear()
+# bpy.data.meshes.remove(mesh)
+ #Unlink and remove the object
+# scene.objects.unlink(hit_box)
+# hit_box.user_clear()
+# bpy.data.objects.remove(hit_box)
+
+ def draw(self, context):
+ pass
+
+ def execute(self, context):
+ armature = context.object
+ scene = context.scene
+
+ bpy.ops.object.select_all(action='DESELECT')
+ for bone_name in armature['brik_bone_hit_box_dict']:
+ #hit_box = scene.objects[armature['brik_bone_hit_box_dict'][bone_name]]
+ select_name( name = armature['brik_bone_hit_box_dict'][bone_name], extend = True)
+# self.remove_hit_box(scene, bone_name, armature)
+ bpy.ops.object.delete(use_global=False)
+ bpy.ops.object.select_all(action='DESELECT')
+ scene.objects.active = armature
+
+ group_name = armature['brik_hit_box_prefix']+armature.name+"_Group"
+ if group_name in bpy.data.groups:
+ group = bpy.data.groups[group_name]
+ bpy.data.groups.remove(group)
+
+ del armature['brik_bone_hit_box_dict']
+ del armature['brik_hit_boxes_created']
+ del armature['brik_hit_box_prefix']
+ return{'FINISHED'}
+
+
+def calc_ragdoll_mass(self, context):
+ armature = context.object
+ set_mass = context.scene.brik_ragdoll_mass
+ brik_structure_created = armature.get('brik_structure_created', False)
+ if brik_structure_created:
+ RB_dict = armature['brik_bone_driver_dict']
+ objects = bpy.data.objects
+ tot_mass = 0
+ for bone in RB_dict:
+ box_name = RB_dict[bone]
+ ob = objects[box_name]
+ tot_mass = tot_mass + ob.game.mass
+ mass_scale = set_mass / tot_mass
+ for bone in RB_dict:
+ box_name = RB_dict[bone]
+ ob = objects[box_name]
+ ob.game.mass = ob.game.mass * mass_scale
+ return None
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik_funcs.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik_funcs.py
new file mode 100644
index 0000000..633250c
--- /dev/null
+++ b/release/scripts/addons_contrib/game_engine_ragdolls_kit/brik_funcs.py
@@ -0,0 +1,173 @@
+#brik_funcs.py
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Script copyright (C) Marcus Jenkins (Blenderartists user name FunkyWyrm)
+# Modified by Kees Brouwer (Blenderartists user name Wraaah)
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+"""
+This will be a collection of useful functions that can be reused across the different operators.
+
+"""
+
+import bpy
+
+#Create a box based on envelope size (easier matching of box to model proportions)
+def create_box_bbone(prefix, armature, poseBone):
+ #Thanks to Wraaah for this function
+
+ ########################
+ #INSERT SHAPE CODE HERE#
+
+ #Strange looking code as I am referencing the editbone data from the posebone.
+ h = poseBone.bone.bbone_x
+ w = poseBone.bone.bbone_z
+ l = poseBone.bone.length/2.0
+ #The bone points along it's y axis so head is -y and tail is +y
+ verts = [[h,-l, w],[h,-l,-w],[-h,-l,-w],[-h,-l,w],\
+ [h,l,w],[h,l,-w],[-h,l,-w],[-h,l,w]]
+ edges = [[0,1],[1,2],[2,3],[3,0],\
+ [4,5],[5,6],[6,7],[7,4],\
+ [0,4],[1,5],[2,6],[3,7]]
+ faces = [[3,2,1,0],[4,5,6,7],[0,4,7,3],[1,5,4,0],[2,6,5,1],[3,7,6,2]]
+
+ ########################
+
+ #Create the mesh
+ mesh = bpy.data.meshes.new(prefix + poseBone.name)
+ mesh.from_pydata(verts, edges, faces)
+
+ #Create an object for the mesh and link it to the scene
+ box = bpy.data.objects.new(prefix + poseBone.name, mesh)
+ bpy.context.scene.objects.link(box)
+
+ #Move the hit box so that when parented the object centre is at the bone centre
+ box.location.y = -poseBone.length/2
+ volume = h * l * w * 8.0
+ return(box, volume)
+
+#Create a box based on envelope size (easier matching of box to model proportions)
+def create_box_envelope(prefix, armature, poseBone):
+ ########################
+ #INSERT SHAPE CODE HERE#
+
+ #Strange looking code as I am referencing the editbone data from the posebone.
+ l = poseBone.bone.length/2
+ h = poseBone.bone.head_radius
+ t = poseBone.bone.tail_radius
+ #The bone points along it's y axis so head is -y and tail is +y
+ verts = [[h,-l, h],[h,-l,-h],[-h,-l,-h],[-h,-l,h],\
+ [t,l,t],[t,l,-t],[-t,l,-t],[-t,l,t]]
+ edges = [[0,1],[1,2],[2,3],[3,0],\
+ [4,5],[5,6],[6,7],[7,4],\
+ [0,4],[1,5],[2,6],[3,7]]
+ faces = [[3,2,1,0],[4,5,6,7],[0,4,7,3],[1,5,4,0],[2,6,5,1],[3,7,6,2]]
+
+ ########################
+
+ #Create the mesh
+ mesh = bpy.data.meshes.new(prefix + poseBone.name)
+ mesh.from_pydata(verts, edges, faces)
+
+ #Create an object for the mesh and link it to the scene
+ box = bpy.data.objects.new(prefix + poseBone.name, mesh)
+ bpy.context.scene.objects.link(box)
+
+ #Move the hit box so that when parented the object centre is at the bone centre
+ box.location.y = -poseBone.length/2
+ volume = (((2*h)**2 + (2*t)**2)/2) * (2*l)
+ return(box, volume)
+
+#Create a box based on bone size (manual resizing of bones)
+def create_box(prefix, length, width, armature, bone):
+ scene = bpy.context.scene
+
+ height = bone.length
+ #gap = height * self.hit_box_length #The distance between two boxes
+ box_length = bone.length * length
+ box_width = bone.length * width
+
+ x = box_width/2
+ y = box_length/2
+ z = box_width/2
+
+ verts = [[x,-y,z],[x,-y,-z],[-x,-y,-z],[-x,-y,z],\
+ [x,y,z],[x,y,-z],[-x,y,-z],[-x,y,z]]
+ edges = [[0,1],[1,2],[2,3],[3,0],\
+ [4,5],[5,6],[6,7],[7,4],\
+ [0,4],[1,5],[2,6],[3,7]]
+ faces = [[3,2,1,0],[4,5,6,7],[0,4,7,3],[1,5,4,0],[2,6,5,1],[3,7,6,2]]
+
+ #Create the mesh
+ mesh = bpy.data.meshes.new(prefix + bone.name)
+ mesh.from_pydata(verts, edges, faces)
+
+ #Create an object for the mesh and link it to the scene
+ obj = bpy.data.objects.new(prefix + bone.name, mesh)
+ scene.objects.link(obj)
+
+ volume = x*y*z
+
+ return(obj, volume)
+
+#Function to select only the correct bones from an armature
+#so only deform bones in the selected bone group(s)
+def bone_group_list(armature):
+ bones = armature.pose.bones
+ scn = bpy.context.scene
+ bone_groups = scn.brik_bone_groups
+
+ #Check if bone is part of the selected bone group(s)
+ bone_list = []
+ for bone in bones:
+ use_bone = True
+ #Check bone group membership
+ if bone_groups != "All":
+ if bone.bone_group:
+ if bone.bone_group.name != bone_groups:
+ use_bone = False
+ else:
+ use_bone = False
+ #Check deform bone
+ if bone.bone.use_deform == False:
+ use_bone = False
+
+ if use_bone == True:
+ bone_list = bone_list + [bone]
+
+ #Return list of bones to be used
+ return bone_list
+
+#Orient the box to the bone and set the box object centre to the bone location
+def position_box( armature, bone, box):
+ #scene = bpy.context.scene
+
+ #Set the box to the bone orientation and location
+ box.matrix_world = bone.matrix
+ box.location = armature.location + ( bone.bone.head_local + bone.bone.tail_local ) / 2
+
+
+
+def select_name( name = "", extend = True ):
+ if extend == False:
+ bpy.ops.object.select_all(action='DESELECT')
+ ob = bpy.data.objects.get(name)
+ ob.select = True
+ bpy.context.scene.objects.active = ob
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_init_ragdoll.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_init_ragdoll.py
new file mode 100644
index 0000000..e08c8de
--- /dev/null
+++ b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_init_ragdoll.py
@@ -0,0 +1,237 @@
+#brik_init_ragdoll.py
+
+# ***** BEGIN MIT LICENSE BLOCK *****
+#
+#Script Copyright (c) 2010 Marcus P. Jenkins (Blenderartists user name FunkyWyrm)
+# Modified by Kees Brouwer (Blenderartists user name Wraaah)
+#
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+#
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+#
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+#
+# ***** END MIT LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+"""
+This script spawns rigid body objects when ragdoll physics is activated.
+
+It spawns the rigid body objects, turns off the mob collision object's dynamics
+and makes the mob collision object 'Ghost'.
+
+ Objects cannot have 'Ghost' toggled from within the game. :(
+
+ Mobs can probably be static, ghost anyway. If a mob needs to be dynamic
+ then it can be parented to a physics mesh and then the physics mesh can be
+ removed from the scene by this script to avoid collision conflicts with
+ the rigid bodies.
+
+It then sets the orientation and position to that of the hit boxes and links
+the rigid body objects together with rigid body joints.
+
+Rest orientations can be taken from the rigid body objects that remain on the
+hidden layer. I thought this would be a problem to set. It's so nice when
+something turns out easier than expected for a change. :)
+"""
+debug = False
+
+import bge
+
+scene = bge.logic.getCurrentScene()
+
+objects = scene.objects
+hidden_objects = scene.objectsInactive
+
+"""
+NOTE:
+ If a collision box is used then this will be the main added object
+ that is added and so will have the spawn_point and spawn_id
+ properties.
+ The collision box would need to be removed here.
+ In this case, the spawn_id and spawn_point would need to be copied
+ to the armature in order to properly identify which object is to be
+ ultimately removed from the scene.
+"""
+
+def main():
+
+ """
+ Sensor disabled. Using brik_use_ragdoll 'changed' sensor
+ """
+ #sens = spawn_boxes_cont.sensors['brik_spawn_boxes_sens']
+ #if sens.getKeyStatus(sens.key) == 1:
+
+ init_ragdoll_controller = bge.logic.getCurrentController()
+ spawn_boxes_act = init_ragdoll_controller.actuators['brik_spawn_boxes_act']
+
+ armature = init_ragdoll_controller.owner
+
+
+ #########################
+# hidden_armature = hidden_objects[armature.name]
+ #########################
+
+
+# spawn_point = armature['spawn_point']
+# spawn_id = armature['spawn_id']
+
+ if armature['brik_use_ragdoll'] and armature['brik_init_ragdoll']:
+
+ print('#########################')
+ print('SPAWNING RIGID BODY OBJECTS')
+ spawn_boxes_act.instantAddObject()
+ scene = bge.logic.getCurrentScene()
+ objects = scene.objects
+ objects.reverse()
+
+ #Expand existing group
+ group_objects = armature["group"]
+
+ group = spawn_boxes_act.object
+ for ob in objects:
+ group_objects[ob.name] = ob
+ ob["pivot"] = armature
+ if ob.name == group.name:
+ #Stop for loop once group start point is found
+ break
+
+# armature_name = spawn_empty["armature_name"]
+# armature = group_objects[ armature_name ]
+ armature["group"] = group_objects
+
+ #Set up constraints
+ constraints = armature["constraints"]
+ for constraint in constraints:
+ settings = constraints[constraint]
+ constraint_name = settings.get("constraint_name", None)
+ print("Create 6DOF constraint")
+ print(constraint_name)
+ object = group_objects[ settings.get("object", None) ]
+ object_id = object.getPhysicsId()
+ target = group_objects[ settings.get("target", None) ]
+ target_id = target.getPhysicsId()
+ print(object)
+ print(target)
+
+ piv_x = float( settings.get("pivot_x", 0.0) )
+ piv_y = float( settings.get("pivot_y", 0.0) )
+ piv_z = float( settings.get("pivot_z", 0.0) )
+
+ piv_Rx = float( settings.get("pivot_Rx", 0.0) )
+ piv_Ry = float( settings.get("pivot_Ry", 0.0) )
+ piv_Rz = float( settings.get("pivot_Rz", 0.0) )
+
+ constraint_type = 12 #6DoF joint
+ flag = 128 #No collision with joined object.
+ joint = bge.constraints.createConstraint(object_id, target_id, constraint_type, piv_x, piv_y, piv_z, piv_Rx, piv_Ry, piv_Rz, flag)
+ joint.setParam(0, float( settings.get("x_min", 0.0) ), float( settings.get("x_max", 0.0) ) )
+ joint.setParam(1, float( settings.get("y_min", 0.0) ), float( settings.get("y_max", 0.0) ) )
+ joint.setParam(2, float( settings.get("z_min", 0.0) ), float( settings.get("z_max", 0.0) ) )
+ #Parameters 3 = limit x rotation, 4 = limit y rotation, 5 = limit z rotation
+ if settings.get("Rx_min", None):
+ joint.setParam(3, float( settings.get("Rx_min", 0.0) ), float( settings.get("Rx_max", 0.0) ) )
+ if settings.get("Ry_min", None):
+ joint.setParam(4, float( settings.get("Ry_min", 0.0) ), float( settings.get("Ry_max", 0.0) ) )
+ if settings.get("Rz_min", None):
+ joint.setParam(5, float( settings.get("Rz_min", 0.0) ), float( settings.get("Rz_max", 0.0) ) )
+
+ #Translational motor
+ #setParam(type, vel, maxForce)
+ if settings.get("x_mot", None):
+ joint.setParam(6, float( settings.get("x_mot", 0.0) ), float( settings.get("x_mot_max", 999.0) ) )
+ if settings.get("y_mot", None):
+ joint.setParam(7, float( settings.get("y_mot", 0.0) ), float( settings.get("y_mot_max", 999.0) ) )
+ if settings.get("z_mot", None):
+ joint.setParam(8, float( settings.get("z_mot", 0.0) ), float( settings.get("z_mot_max", 999.0) ) )
+ #Rotational motor
+ #setParam(type, angVel, maxForce)
+ if settings.get("Rx_mot", None):
+ joint.setParam(9, float( settings.get("Rx_mot", 0.0) ), float( settings.get("Rx_mot_max", 999.0) ) )
+ if settings.get("Ry_mot", None):
+ joint.setParam(10, float( settings.get("Ry_mot", 0.0) ), float( settings.get("Ry_mot_max", 999.0) ) )
+ if settings.get("Rz_mot", None):
+ joint.setParam(11, float( settings.get("Rz_mot", 0.0) ), float( settings.get("Rz_mot_max", 999.0) ) )
+
+ #Translational spring
+ #setParam(type, stiffness, reset)
+ if settings.get("x_spring", None):
+ joint.setParam(12, float( settings.get("x_spring", 0.0) ), float( settings.get("x_spring_reset", 0) ) )
+ if settings.get("y_spring", None):
+ joint.setParam(13, float( settings.get("y_spring", 0.0) ), float( settings.get("y_spring_reset", 0) ) )
+ if settings.get("z_spring", None):
+ joint.setParam(14, float( settings.get("z_spring", 0.0) ), float( settings.get("z_spring_reset", 0) ) )
+ #Rotational spring
+ #setParam(type, stiffness, reset)
+ if settings.get("Rx_spring", None):
+ joint.setParam(15, float( settings.get("Rx_spring", 0.0) ), float( settings.get("Rx_spring_reset", 0) ) )
+ if settings.get("Ry_spring", None):
+ joint.setParam(16, float( settings.get("Ry_spring", 0.0) ), float( settings.get("Ry_spring_reset", 0) ) )
+ if settings.get("Rz_spring", None):
+ joint.setParam(17, float( settings.get("Rz_spring", 0.0) ), float( settings.get("Rz_spring_reset", 0) ) )
+
+ #Store joint in object, can be used to change the parameter settings
+ #For example when a joint is broken you can widen the angle rotations
+ #Also possible to sever the joint completely but CLEAR THE VARIABLE FIRST
+ #BEFORE REMOVING THE JOINT else BGE CRASHES
+ object[constraint_name] = joint
+
+ #Copy hitbox positions + remove hitboxes, activate armature constraints
+ bone_hitbox = armature["bone_hitbox"]
+ bone_rigidbody = armature["bone_rigidbody"]
+ bone_loc = armature["bone_loc"]
+
+ for bone_name in bone_hitbox:
+ hitbox = group_objects[ bone_hitbox[ bone_name ] ]
+ rigidbody = group_objects[ bone_rigidbody[ bone_name ] ]
+
+ rigidbody.worldPosition = hitbox.worldPosition
+ rigidbody.worldOrientation = hitbox.worldOrientation
+
+ #Set up the copy rotation bone constraint for this driver
+ print('######################')
+ print('SETTING UP ROT BONE CONSTRAINTS FOR '+rigidbody.name)
+ print('BONE NAME ' + bone_name)
+ constraint_rot = armature.constraints[bone_name+":brik_copy_rot"]
+ constraint_rot.target = rigidbody
+ constraint_rot.enforce = 1.0
+
+ copy_loc_target = bone_loc.get(bone_name, None)
+ if copy_loc_target:
+ #Set up the copy location constraint
+ constraint_loc = armature.constraints[bone_name+':brik_copy_loc']
+ constraint_loc.target = group_objects[ copy_loc_target ]
+ constraint_loc.enforce = 1.0
+
+ rigidbody.worldLinearVelocity = hitbox.worldLinearVelocity
+ rigidbody.worldAngularVelocity = hitbox.worldAngularVelocity
+
+ hitbox.endObject()
+
+ #for act in armature.actuators:
+ #There appears to be no direct way of checking that an actuator is an action actuator.
+ #act.type would be nice.
+ # if hasattr(act, 'action'):
+ # if not act.name == 'brik_use_act':
+ # init_ragdoll_controller.deactivate(act)
+ #==> Why needed?
+
+ #Needed to prevent brik_use_changed_sens second pulse from re-triggering the script.
+ armature['brik_init_ragdoll'] = False
+
+ #if debug == True:
+
+if __name__ == '__main__':
+ main()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_load.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_load.py
new file mode 100644
index 0000000..b1ccb38
--- /dev/null
+++ b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_load.py
@@ -0,0 +1,141 @@
+#brik_load_0_1.py
+
+# ***** BEGIN MIT LICENSE BLOCK *****
+#
+#Script Copyright (c) 2010 Marcus P. Jenkins (Blenderartists user name FunkyWyrm)
+# Modified by Kees Brouwer (Blenderartists user name Wraaah)
+#
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+#
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+#
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+#
+# ***** END MIT LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+"""
+This script loads the necessary data from a text file and stores it in the
+appropriate locations.
+
+It should run once at the very start of the game/level to avoid issues with
+frame rate later on.
+
+This is a load better than my first attempt at parsing a text file, but could
+probably still be optimised more.
+
+FOR MULTIPLE RAGDOLLS IN THE SAME SCENE:
+
+The correct armature data fileS need to be loaded at the start of the game.
+To do this, the name of the text file in the brik_ragdoll_data controller needs
+to be changed so it corresponds with the correct armature.
+
+This needs to be done when brik creates the logic.
+A separate spawn point should be created for each new ragdoll structure that is
+added to the scene. Each spawn point would load the data for it's corresponding
+ragdoll.
+ Alternatively, the brik_load.py script should iterate through all ragdoll
+ structures and load them in turn.
+
+ The spawn point would need a new property that is a list of all ragdoll armatures
+ in the scene.
+
+ For each ragdoll:
+ Set the data controller to use the correct data file.
+ Load the data.
+
+ This would allow for a single spawn point to load all structure data.
+"""
+print('###########################')
+print('RUNNING brik_load_0_1.py')
+
+import bge
+import mathutils
+from mathutils import Vector, Quaternion
+
+scene = bge.logic.getCurrentScene()
+cont = bge.logic.getCurrentController()
+
+objects = scene.objectsInactive
+
+spawn_point = cont.owner
+
+def load_data(data_cont):
+
+ data_file = data_cont.script
+ #remove whitespaces
+ data_file = data_file.replace(" ", "")
+ lines = data_file.splitlines(False)
+
+ bone_hitbox = {}
+ bone_rigidbody = {}
+ bone_loc = {}
+ constraint_settings = {}
+ constraint_settings["constraint_name"] = ""
+ constraints = {}
+
+ for line in lines:
+
+ if (len(line) == 0) or (line.count("''") != 0):
+ #ignore short lines or lines (starting) with ''
+ pass
+ elif line.count(":") != 0:
+ #bone, hitbox, rigidbody link
+ items = line.split(":")
+ bone_name = items[0]
+ bone_hitbox[bone_name] = items[1]
+ bone_rigidbody[bone_name] = items[2]
+ if len(items) == 4:
+ bone_loc[bone_name] = items[3]
+
+ elif line.count("=") == 1:
+ #Constraint settings
+ par, value = line.split("=")
+ if par == "constraint_name":
+ prev_name = constraint_settings["constraint_name"]
+ if prev_name != "":
+ #save previous constraint
+ constraints[prev_name] = constraint_settings
+
+ constraint_settings = {}
+ constraint_settings[par] = value
+
+ else:
+ #main settings
+ armature_name = line
+ #save last constraint
+ constraints[constraint_settings["constraint_name"]] = constraint_settings
+
+ return bone_hitbox, bone_rigidbody, bone_loc, constraints, armature_name
+# spawn_point['mob_object'] = armature.name
+
+def main():
+# mob_total = spawn_point['brik_mob_count']
+
+# for count in range(0, mob_total+1):
+
+ for cont in spawn_point.controllers:
+# #if cont.name[:-8] == 'brik_ragdoll_data_'+str(count):
+ if cont.name[:] == 'brik_ragdoll_data_0':#removed -8,Wraaah
+ data_cont = cont
+
+ bone_hitbox, bone_rigidbody, bone_loc, constraints, armature_name = load_data(data_cont)
+ armature = objects[armature_name]
+ armature["bone_hitbox"] = bone_hitbox
+ armature["bone_rigidbody"] = bone_rigidbody
+ armature["bone_loc"] = bone_loc
+ armature["constraints"] = constraints
+
+if __name__ == '__main__':
+ main()
diff --git a/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_spawn.py b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_spawn.py
new file mode 100644
index 0000000..6789fef
--- /dev/null
+++ b/release/scripts/addons_contrib/game_engine_ragdolls_kit/templates/brik_spawn.py
@@ -0,0 +1,103 @@
+#brik_spawn_init.py
+
+# ***** BEGIN MIT LICENSE BLOCK *****
+#
+#Script Copyright (c) 2010 Marcus P. Jenkins (Blenderartists user name FunkyWyrm)
+# Modified by Kees Brouwer (Blenderartists user name Wraaah)
+#
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+#
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+#
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+#
+# ***** END MIT LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+import bge
+
+def initialize():
+ spawn_point = bge.logic.getCurrentController().owner
+
+ #This is a list of all objects added by this spawn point.
+ spawn_point['added_objects'] = []
+
+ #This is the total number of objects added by this spawn point.
+ #It is used to supply a unique Id to each added object.
+ spawn_point['add_count'] = 0
+
+def main():
+
+ cont = bge.logic.getCurrentController()
+ #Best replace sensor with message?
+ sens = cont.sensors['brik_Tab_sens']
+
+ if sens.getKeyStatus(sens.key) == 1:
+ print('#########################')
+ print('SPAWNING MOB AND HIT BOXES')
+
+ spawn_act = cont.actuators['brik_spawn_act']
+
+ #scene = bge.logic.getCurrentScene()
+ #objects = scene.objects
+ #hidden_objects = scene.objectsInactive
+
+ spawn_empty = cont.owner
+
+ #mob_object = hidden_objects[spawn_empty['mob_object']]
+ #mob_object = hidden_objects['Armature.001']
+
+ #spawn_act.object = mob_object.name
+ spawn_act.instantAddObject()
+ scene = bge.logic.getCurrentScene()
+ objects = scene.objects
+ objects.reverse()
+
+ group_objects = {}
+ group = spawn_act.object
+ for ob in objects:
+ group_objects[ob.name] = ob
+# ob["pivot"] = "test_pivot"
+ if ob.name == group.name:
+ #Stop for loop once group start point is found
+ break
+
+ armature_name = spawn_empty["armature_name"]
+ armature = group_objects[ armature_name ]
+ armature["group"] = group_objects
+
+ for ob_name in group_objects:
+ ob = group_objects[ob_name]
+ ob["pivot"] = armature
+
+# last_spawned = spawn_act.objectLastCreated
+ #print(dir(last_spawned))
+# spawn_empty['added_objects'].append(last_spawned)
+# spawn_empty['add_count'] += 1
+
+ #This is used to identify which spawn point the spawned object was added by.
+# last_spawned['spawn_point'] = spawn_empty.name
+ #This is a unique Id used to identify the added object.
+# last_spawned['spawn_id'] = spawn_empty['add_count']
+ #This is the dictionary of drivers that are unique to the added object.
+ """
+ Originally this dictionary was defined in the brik_load.py script, but since
+ dictionaries are stored as a reference, and the added objects are copies of the
+ hidden object, the added objects had a copy of the reference to the dictionary
+ and all used the same dictionary.
+ Defining the dictionary after the objects are added to the scene ensures that
+ they each have a unique dictionary.
+ """
+# last_spawned['driver_dict'] = {}
diff --git a/release/scripts/addons_contrib/geodesic_domes/__init__.py b/release/scripts/addons_contrib/geodesic_domes/__init__.py
new file mode 100644
index 0000000..eebad0c
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/__init__.py
@@ -0,0 +1,56 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Geodesic Domes",
+ "author": "PKHG , Meta Androcto, Kilon original for 2.49 from Andy Houston",
+ "version": (0,2,3),
+ "blender": (2, 61, 0),
+ "location": "View3D > UI > Geodesic...",
+ "description": "Choice for objects",
+ "warning": "not yet finished",
+ "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/Py/Scripts/Modeling/Geodesic_Domes",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=29609",
+ "category": "Object"}
+
+"""
+Added save and load of parameters 14-12-2011 PKHG
+Added one possible *.bak for GD_0.GD (one time) 17-12-2011
+"""
+if "bpy" in locals():
+ import imp
+ imp.reload(third_domes_panel)
+
+else:
+ from geodesic_domes import third_domes_panel
+
+import bpy
+from bpy.props import *
+
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
+
+
+
diff --git a/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py b/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py
new file mode 100644
index 0000000..1fe3183
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/add_shape_geodesic.py
@@ -0,0 +1,100 @@
+import bpy
+import mathutils
+
+def reset_transform(ob):
+ m = mathutils.Matrix()
+ ob.matrix_local = m
+
+def func_add_corrective_pose_shape_fast(source, target):
+ result = ""
+ reset_transform(target)
+ # If target object doesn't have Basis shape key, create it.
+ try:
+ num_keys = len( target.data.shape_keys.key_blocks )
+ except:
+ basis = target.shape_key_add()
+ basis.name = "Basis"
+ target.data.update()
+ key_index = target.active_shape_key_index
+ if key_index == 0:
+ # Insert new shape key
+ new_shapekey = target.shape_key_add()
+ new_shapekey.name = "Shape_" + source.name
+ new_shapekey_name = new_shapekey.name
+ key_index = len(target.data.shape_keys.key_blocks)-1
+ target.active_shape_key_index = key_index
+ # else, the active shape will be used (updated)
+ target.show_only_shape_key = True
+ shape_key_verts = target.data.shape_keys.key_blocks[ key_index ].data
+ try:
+ vgroup = target.active_shape_key.vertex_group
+ target.active_shape_key.vertex_group = ''
+ except:
+ print("blub")
+ result = "***ERROR*** blub"
+ pass
+ # copy the local vertex positions to the new shape
+ verts = source.data.vertices
+ try:
+ for n in range( len(verts)):
+ shape_key_verts[n].co = verts[n].co
+ # go to all armature modifies and unpose the shape
+ except:
+ message = "***ERROR***, meshes have different number of vertices"
+ result = message
+ for n in target.modifiers:
+ if n.type == 'ARMATURE' and n.show_viewport:
+ #~ print("got one")
+ n.use_bone_envelopes = False
+ n.use_deform_preserve_volume = False
+ n.use_vertex_groups = True
+ armature = n.object
+ unposeMesh( shape_key_verts, target, armature)
+ break
+
+ # set the new shape key value to 1.0, so we see the result instantly
+ target.data.shape_keys.key_blocks[ target.active_shape_key_index].value = 1.0
+ try:
+ target.active_shape_key.vertex_group = vgroup
+ except:
+ print("bluba")
+ result = result + "bluba"
+ pass
+ target.show_only_shape_key = False
+ target.data.update()
+ return result
+
+class add_corrective_pose_shape_fast(bpy.types.Operator):
+ """Add 1st object as shape to 2nd object as pose shape (only 1 armature)"""
+ bl_idname = "object.add_corrective_pose_shape_fast"
+ bl_label = "Add object as corrective shape faster"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+
+ if len(context.selected_objects) > 2:
+ print("Select source and target objects please")
+ return {'FINISHED'}
+
+ selection = context.selected_objects
+ target = context.active_object
+ if context.active_object == selection[0]:
+ source = selection[1]
+ else:
+ source = selection[0]
+ print(source)
+ print(target)
+ func_add_corrective_pose_shape_fast( source, target)
+ return {'FINISHED'}
+
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/geodesic_domes/forms_259.py b/release/scripts/addons_contrib/geodesic_domes/forms_259.py
new file mode 100644
index 0000000..4e451a5
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/forms_259.py
@@ -0,0 +1,222 @@
+import math
+from math import pi,sin,cos,atan,tan,fabs
+from geodesic_domes.vefm_259 import *
+class form(mesh):
+ def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
+ mesh.__init__(self)
+ #PKHG alredey in vefm259 mesh: self.a360 = pi * 2.0
+ self.PKHG_parameters = [uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform]
+ self.ures = uresolution
+ self.vres = vresolution
+
+ self.uscale = uscale
+ self.vscale = vscale
+ self.upart = upart
+ self.vpart = vpart
+ self.uphase = uphase * self.a360
+ self.vphase = vphase * self.a360
+ self.utwist = utwist
+ self.vtwist = vtwist
+
+ self.xscale = xscale
+ self.yscale = yscale
+ self.sform = sform
+
+ if self.upart != 1.0: ## there is a gap in the major radius
+ self.uflag = 1
+ else:
+ self.uflag = 0
+ if self.vpart != 1.0: ## there is a gap in the minor radius
+ self.vflag = 1
+ else:
+ self.vflag = 0
+ if self.uflag:
+ self.ufinish = self.ures + 1
+ else:
+ self.ufinish = self.ures
+ if self.vflag:
+ self.vfinish = self.vres + 1
+ else:
+ self.vfinish = self.vres
+ self.ustep = (self.a360 / self.ures) * self.upart
+ self.vstep = (self.a360 / self.vres) * self.vpart
+ if self.xscale != 1.0:
+ self.xscaleflag = 1
+ else:
+ self.xscaleflag = 0
+ if self.yscale != 1.0:
+ self.yscaleflag = 1
+ else:
+ self.yscaleflag = 0
+ self.rowlist=[]
+
+ def generatepoints(self):
+ for i in range(self.ufinish):
+ row=[]
+ for j in range(self.vfinish):
+ u = self.ustep * i + self.uphase
+ v = self.vstep * j + self.vphase
+ # if self.xscaleflag:
+ # u = self.ellipsecomp(self.xscale,u)
+ # if self.yscaleflag:
+ # v = self.ellipsecomp(self.yscale,v)
+ if self.sform[12]:
+ r1 = self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14] + u,self.sform[4],self.sform[5],self.sform[16] * v)
+ else:
+ r1 = 1.0
+ if self.sform[13]:
+ r2 = self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15] + v,self.sform[10],self.sform[11],self.sform[17] * v)
+ else:
+ r2 = 1.0
+ x,y,z = self.formula(u,v,r1,r2)
+ point = vertex((x,y,z))
+ row.append(point)
+ self.verts.append(point)
+ self.rowlist.append(row)
+ if self.vflag:
+ pass
+ else:
+ for i in range(len(self.rowlist)):
+ self.rowlist[i].append(self.rowlist[i][0])
+ if self.uflag:
+ pass
+ else:
+ self.rowlist.append(self.rowlist[0])
+
+# def formula(self,u,v,r1,r2):
+# pass
+
+ def generatefaces(self):
+ ufin = len(self.rowlist) - 1
+ vfin = len(self.rowlist[0]) - 1
+ for i in range(ufin):
+ for j in range(vfin):
+ top = i
+ bottom = i + 1
+ left = j
+ right = j + 1
+ a = self.rowlist[top][left]
+ b = self.rowlist[top][right]
+ c = self.rowlist[bottom][right]
+ d = self.rowlist[bottom][left]
+ face1 = face([a,b,c,d])
+ self.faces.append(face1)
+ edge1 = edge(a,b)
+ edge2 = edge(a,d)
+ self.edges.append(edge1)
+ self.edges.append(edge2)
+ if i + 1 == ufin:
+ edge3 = edge(d,c)
+ self.edges.append(edge3)
+ if j + 1 == vfin:
+ edge4 = edge(b,c)
+ self.edges.append(edge4)
+
+class grid(form):
+ def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
+ form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
+ unit = 1.0 / self.a360
+ if self.ures == 1 :
+ print("\n***ERRORin forms_259.grid L121***, ures is 1, changed into 2\n\n")
+ self.ures = 2
+ if self.vres == 1 :
+ print("\n***ERROR in grid forms_259.grid L124***, vres is 1, changed into 2\n\n")
+ self.vres = 2
+ self.ustep = self.a360 / (self.ures - 1)
+ self.vstep = self.a360 / (self.vres - 1)
+
+ self.uflag = 1
+ self.vflag = 1
+
+ self.xscaleflag = 0
+ self.yscaleflag = 0
+ self.uexpand = unit * self.uscale
+ self.vexpand = unit * self.vscale
+ self.ushift = self.uscale * 0.5
+ self.vshift = self.vscale * 0.5
+
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self,u,v,r1,r2):
+ x = u * self.uexpand - self.ushift
+ y = v * self.vexpand - self.vshift
+ z = r1 * r2 - 1.0
+ return x,y,z
+
+
+class cylinder(form):
+ def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
+ form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
+ unit = 1.0 / self.a360
+ self.vshift = self.vscale * 0.5
+ self.vexpand = unit * self.vscale
+ self.vflag = 1
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self,u,v,r1,r2):
+ x = sin(u) * self.uscale * r1 * r2 * self.xscale
+ y = cos(u) * self.uscale * r1 * r2
+ z = v * self.vexpand - self.vshift
+ return x,y,z
+
+class parabola(form):
+ def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
+ form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
+ unit = 1.0 / self.a360
+ self.vshift = self.vscale * 0.5
+ self.vexpand = unit * self.vscale
+ self.vflag = 1
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self,u,v,r1,r2):
+ factor = sqrt(v) + 0.001
+ x = sin(u) * factor * self.uscale * r1 * r2 * self.xscale
+ y = cos(u) * factor * self.uscale * r1 * r2
+ z = - v * self.vexpand + self.vshift
+ return x,y,z
+
+class torus(form):
+ def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
+ form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self,u,v,r1,r2):
+ z = sin(v) * self.uscale * r2 * self.yscale
+ y = (self.vscale + self.uscale * cos(v)) * cos(u) * r1 * r2
+ x = (self.vscale + self.uscale * cos(v)) * sin(u) * r1 * r2 * self.xscale
+ return x,y,z
+
+class sphere(form):
+
+ def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):
+ form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)
+ self.vstep = (self.a360 / (self.vres - 1)) * self.vpart
+ self.vflag = 1
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self,u,v,r1,r2):
+ v = (v * 0.5) - (self.a360 * 0.25)
+ x = r1 * cos(u) * r2 * cos(v) * self.uscale * self.xscale
+ y = r1 * sin(u) * r2 * cos(v) * self.uscale
+ z = r2 * sin(v) * self.uscale * self.yscale
+ return x,y,z
diff --git a/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py b/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py
new file mode 100644
index 0000000..15378ce
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/geodesic_classes_259.py
@@ -0,0 +1,754 @@
+#werkt from geodesic_domes.vefm_259 import *
+from geodesic_domes.vefm_259 import mesh, vertex, edge, face
+
+import math
+from math import pi,acos,sin,cos,atan,tan,fabs, sqrt
+
+def check_contains(cl,name , print_value = False):
+ dir_class = dir(cl)
+ for el in dir_class:
+ if el.startswith("_"):
+ pass
+ else:
+ if print_value:
+ tmp = getattr(cl,el)
+ print(name , " contains ==>",el," value = ", tmp)
+ else:
+ print(name , " contains ==>",el)
+ print("\ncheck_contains finished\n\n")
+
+class geodesic(mesh):
+ def __init__(self):
+ mesh.__init__(self)
+ self.PKHG_parameters = None
+# print("\n------ geodesic L11 PKHG_parameters",PKHG_parameters)
+ self.panels = []
+ self.vertsdone = []
+ self.skeleton = [] ## List of verts in the full skeleton edges.
+ self.vertskeleton = [] # config needs this member
+ self.edgeskeleton = [] # config needs this member
+ self.sphericalverts = []
+ self.a45 = pi * 0.25
+ self.a90 = pi * 0.5
+ self.a180 = pi
+ self.a270 = pi * 1.5
+ self.a360 = pi * 2
+ #define members here
+ #setparams needs:
+ self.frequency = None
+ self.eccentricity = None
+ self.squish = None
+ self.radius = None
+ self.square = None
+ self.squarez = None
+ self.cart = None
+ self.shape = None
+ self.baselevel = None
+ self.faceshape = None
+ self.dualflag = None
+ self.rotxy = None
+ self.rotz = None
+ self.klass = None
+ self.sform = None
+ self.super = None
+ self.odd = None
+ #config needs
+ self.panelpoints = None
+ self.paneledges = None
+ self.reversepanel = None
+ self.edgelength = None
+ self.vertsdone = None
+ self.panels = []
+
+#PKHG because of unittest approach for a while the following three lines commentd
+#PKHG do not understand the problems with the next three lines
+#no does not work self.setparameters()
+# self.makegeodesic()
+# self.connectivity()
+
+ def setparameters(self,params):
+ parameters = self.PKHG_parameters = params
+ self.frequency = parameters[0] ## How many subdivisions - up to 20.
+ self.eccentricity = parameters[1] ## Elliptical if >1.0.
+ self.squish = parameters[2] ## Flattened if < 1.0.
+ self.radius = parameters[3] ## Exactly what it says.
+ self.square = parameters[4] ## Controls amount of superellipse in X/Y plane.
+ self.squarez = parameters[5] ## Controls amount of superellipse in Z dimension.
+ self.cart = parameters[6] ## Cuts out sphericalisation step.
+ self.shape = parameters[7] ## Full sphere, dome, flatbase.
+ self.baselevel = parameters[8] ## Where the base is cut on a flatbase dome.
+ self.faceshape = parameters[9] ## Triangular, hexagonal, tri-hex.
+ self.dualflag = parameters[10]
+ self.rotxy = parameters[11]
+ self.rotz = parameters[12]
+ self.klass = parameters[13]
+ self.sform = parameters[14]
+ self.super = 0 ## Toggles superellipse.
+ if self.square != 2.0 or self.squarez != 2.0:
+ self.super = 1
+ self.odd = 0 ## Is the frequency odd. It matters for dome building.
+ if self.frequency % 2 != 0:
+ self.odd = 1
+
+ def makegeodesic(self):
+ self.vertedgefacedata() #PKHG only a pass 13okt11
+ self.config() ## Generate all the configuration information.
+ if self.klass:
+ self.class2()
+ if self.faceshape == 1:
+ self.hexify() ## Hexagonal faces
+ elif self.faceshape == 2:
+ self.starify() ## Hex and Triangle faces
+ if self.dualflag:
+ self.dual()
+ if not self.cart:
+ self.sphericalize() ## Convert x,y,z positions into spherical u,v.
+ self.sphere2cartesian() ## Convert spherical uv back into cartesian x,y,z for final shape.
+ for i in range(len( self.verts)):
+ self.verts[i].index = i
+ for edg in self.edges:
+ edg.findvect()
+
+ def vertedgefacedata(self):
+ pass
+
+#PKHG 23.1 def config(self, frequency = 1): #???PKHG frequency problem 20 oct.
+ def config(self): #???PKHG frequency problem 20 oct.
+#PKHG_OK print("\n20-11 >>>>>>>>>DBG geodesic_classes_259 config L117 called")
+ for i in range(len(self.vertskeleton)):
+ self.vertskeleton[i].index = i
+ for edges in self.edgeskeleton:
+#???PKHG TODO s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic
+ s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic
+ self.skeleton.append(s)
+ for i in range(len( self.verts)):
+ self.verts[i].index = i
+ for i in range(len(self.panelpoints)):
+ a = self.vertsdone[self.panelpoints[i][0]][1]
+ b = self.vertsdone[self.panelpoints[i][1]][1]
+ c = self.vertsdone[self.panelpoints[i][2]][1]
+ panpoints = [ self.verts[a],
+ self.verts[b],
+ self.verts[c]]
+ panedges = [ self.skeleton[self.paneledges[i][0]],
+ self.skeleton[self.paneledges[i][1]],
+ self.skeleton[self.paneledges[i][2]] ]
+ reverseflag = 0
+ for flag in self.reversepanel:
+ if flag == i:
+ reverseflag = 1
+ p = panel(panpoints, panedges, reverseflag, self)
+#PKHG_panels not used?! self.panels.append(p)
+
+ def sphericalize(self):
+ if self.shape == 2:
+ self.cutbasecomp()
+ for vert in(self.verts):
+#PKHG test 20111030
+# x = vert.x
+# y = vert.y
+# z = vert.z
+ x = vert.vector.x
+ y = vert.vector.y
+ z = vert.vector.z
+
+ u = self.usphericalise(x,y,z)
+ v = self.vsphericalise(x,y,z)
+ self.sphericalverts.append([u,v])
+
+ def sphere2cartesian(self):
+#PKHG_TODOnot_now check_contains(self,"sphereto self",True)
+ for i in range(len(self.verts)):
+ if self.cart:
+#PKHG test 20111030
+# x = self.verts[i].x * self.radius * self.eccentricity
+# y = self.verts[i].y * self.radius
+# z = self.verts[i].z * self.radius * self.squish
+ x = self.verts[i].vector.x * self.radius * self.eccentricity
+ y = self.verts[i].vector.y * self.radius
+ z = self.verts[i].vector.z * self.radius * self.squish
+ else:
+ u = self.sphericalverts[i][0]
+ v = self.sphericalverts[i][1]
+ if self.squish != 1.0 or self.eccentricity>1.0:
+ scalez = 1 / self.squish
+ v = self.ellipsecomp(scalez,v)
+ u = self.ellipsecomp(self.eccentricity,u)
+ if self.super:
+ r1 = self.superell(self.square,u,self.rotxy)
+ r2 = self.superell(self.squarez,v,self.rotz)
+ else:
+ r1 = 1.0
+ r2 = 1.0
+
+ # print "sform",self.sform," u",u," v",v
+ if self.sform[12]:
+
+ r1 = r1 * self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14] + u,self.sform[4],self.sform[5],self.sform[16] * v)
+ if self.sform[13]:
+
+ r2 = r2 * self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15] + v,self.sform[10],self.sform[11],self.sform[17] * v)
+ x,y,z = self.cartesian(u,v,r1,r2)
+#PKHG test 20111030
+# self.verts[i].x = x
+# self.verts[i].y = y
+# self.verts[i].z = z
+ self.verts[i] = vertex((x,y,z))
+
+ def usphericalise(self,x,y,z):
+ if y == 0.0:
+ if x>0:
+ theta = 0.0
+ else:
+ theta = self.a180
+ elif x == 0.0:
+ if y>0:
+ theta = self.a90
+ else:
+ theta = self.a270
+
+ else:
+ theta = atan(y / x)
+ if x < 0.0 and y < 0.0:
+ theta = theta + self.a180
+ elif x < 0.0 and y>0.0:
+ theta = theta + self.a180
+ u = theta
+ return u
+
+ def vsphericalise(self,x,y,z) :
+ if z == 0.0:
+ phi = self.a90
+ else:
+ rho = sqrt(x ** 2 + y**2 + z**2)
+ phi = acos(z / rho)
+ v = phi
+ return v
+ def ellipsecomp(self,efactor,theta):
+ if theta == self.a90:
+ result = self.a90
+ elif theta == self.a270:
+ result = self.a270
+ else:
+ result = atan(tan(theta) / efactor**0.5)
+ if result>=0.0:
+ x = result
+ y = self.a180 + result
+ if fabs(x - theta) <= fabs(y - theta):
+ result = x
+ else:
+ result = y
+ else:
+ x = self.a180 + result
+ y = result
+
+ if fabs(x - theta) <= fabs(y - theta):
+ result = x
+ else:
+ result = y
+ return result
+ def cutbasecomp(self):
+ pass
+
+ def cartesian(self,u,v,r1,r2):
+ x = r1 * cos(u) * r2 * sin(v) * self.radius * self.eccentricity
+ y = r1 * sin(u) * r2 * sin(v) * self.radius
+ z = r2 * cos(v) * self.radius * self.squish
+ return x,y,z
+# def connectivity(self):
+#
+# self.dovertedge()
+# self.dovertface()
+# self.dofaceedge()
+
+class edgerow:
+ def __init__(self, count, anchor, leftindex, rightindex, stepvector, endflag, parentgeo):
+ self.points = []
+ self.edges = []
+ ## Make a row of evenly spaced points.
+ for i in range(count + 1):
+ if i == 0:
+ self.points.append(leftindex)
+ elif i == count and not endflag:
+ self.points.append(rightindex)
+ else: #PKHG Vectors added!
+ newpoint = anchor + (stepvector * i)
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.verts.append(newpoint)
+ for i in range(count):
+ a = parentgeo.verts[self.points[i]]
+ b = parentgeo.verts[self.points[i + 1]]
+ line = edge(a,b)
+ self.edges.append(len(parentgeo.edges))
+ parentgeo.edges.append(line)
+
+class skeletonrow:
+ def __init__(self, count, skeletonedge, shortflag, parentgeo):
+ self.points = []
+ self.edges = []
+ self.vect = skeletonedge.vect
+ self.step = skeletonedge.vect / float(count)
+ ## Make a row of evenly spaced points.
+ for i in range(count + 1):
+ vert1 = skeletonedge.a
+ vert2 = skeletonedge.b
+ if i == 0:
+ if parentgeo.vertsdone[vert1.index][0]:
+ self.points.append(parentgeo.vertsdone[vert1.index][1])
+ else:
+#PKHG test 20111030
+# newpoint = vertex((vert1.x, vert1.y, vert1.z))
+ newpoint = vertex(vert1.vector)
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.vertsdone[vert1.index] = [1,vertcount]
+ parentgeo.verts.append(newpoint)
+
+ elif i == count:
+ if parentgeo.vertsdone[vert2.index][0]:
+ self.points.append(parentgeo.vertsdone[vert2.index][1])
+ else:
+#PKHG test 20111030
+# newpoint = vertex((vert2.x, vert2.y, vert2.z))
+ newpoint = vertex(vert2.vector)
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.vertsdone[vert2.index] = [1,vertcount]
+ parentgeo.verts.append(newpoint)
+ else:
+ newpoint = vertex(vert1.vector + (self.step * i)) #must be a vertex!
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.verts.append(newpoint)
+ for i in range(count):
+ a = parentgeo.verts[self.points[i]]
+ b = parentgeo.verts[self.points[i + 1]]
+ line = edge(a,b)
+ self.edges.append(len(parentgeo.edges))
+ parentgeo.edges.append(line)
+
+class facefill:
+ def __init__(self, upper, lower, reverseflag, parentgeo, finish):
+ for i in range(finish):
+ a,b,c = upper.points[i],lower.points[i + 1],lower.points[i]
+ if reverseflag:
+ upface = face([parentgeo.verts[a],parentgeo.verts[c],parentgeo.verts[b]])
+ else:
+ upface = face([parentgeo.verts[a],parentgeo.verts[b],parentgeo.verts[c]])
+ parentgeo.faces.append(upface)
+ if i == finish - 1:
+ pass
+ else:
+ d = upper.points[i + 1]
+ if reverseflag:
+ downface = face([parentgeo.verts[b],parentgeo.verts[d],parentgeo.verts[a]])
+ else:
+ downface = face([parentgeo.verts[b],parentgeo.verts[a],parentgeo.verts[d]])
+ line = edge(parentgeo.verts[a],parentgeo.verts[b])
+ line2 = edge(parentgeo.verts[d],parentgeo.verts[b])
+ parentgeo.faces.append(downface)
+ parentgeo.edges.append(line)
+ parentgeo.edges.append(line2)
+class panel:
+ def __init__(self, points, edges, reverseflag, parentgeo):
+ self.cardinal = points[0]
+ self.leftv = points[1]
+ self.rightv = points[2]
+ self.leftedge = edges[0]
+ self.rightedge = edges[1]
+ self.baseedge = edges[2]
+ self.rows=[]
+ self.orient(parentgeo,edges)
+ self.createrows(parentgeo)
+ self.createfaces(parentgeo,reverseflag)
+
+ def orient(self,parentgeo,edges):
+ if self.leftedge.points[0] != self.cardinal.index:
+ self.leftedge.points.reverse()
+ self.leftedge.vect.negative()
+
+ if self.rightedge.points[0] != self.cardinal.index:
+ self.rightedge.points.reverse()
+ self.rightedge.vect.negative()
+
+ if self.baseedge.points[0] != self.leftv.index:
+
+ self.baseedge.points.reverse()
+ self.baseedge.vect.negative()
+
+ def createrows(self, parentgeo):
+ for i in range(len(self.leftedge.points)):
+ if i == parentgeo.frequency:
+ newrow = self.baseedge
+ else:
+ newrow = edgerow(i, parentgeo.verts[self.leftedge.points[i]], self.leftedge.points[i], self.rightedge.points[i], self.baseedge.step, 0, parentgeo )
+ self.rows.append(newrow)
+ def createfaces(self, parentgeo,reverseflag):
+ for i in range(len(self.leftedge.points) - 1):
+ facefill(self.rows[i], self.rows[i + 1], reverseflag, parentgeo, len(self.rows[i].points))
+#############################
+#############################
+
+#for point on top? YES!
+class tetrahedron(geodesic,mesh):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , 0.0 , 1.73205080757 )),
+ vertex(( 0.0 , -1.63299316185 , -0.577350269185 )),
+ vertex(( 1.41421356237 , 0.816496580927 , -0.57735026919 )),
+ vertex(( -1.41421356237 , 0.816496580927 , -0.57735026919 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]) ]
+
+### probably to be removed, other gui! : "#??? delete PKHG"
+ self.panelpoints=[[0,1,2],[0,2,3],[0,1,3],[1,2,3]]
+ self.paneledges=[[0,1,3],[1,2,4],[0,2,5],[3,5,4]]
+ self.reversepanel=[2,3]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+#for edge on top? YES
+class tetraedge(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , -1.41421356237 , 1.0 )),
+ vertex(( 0.0 , 1.41421356237 , 1.0 )),
+ vertex(( 1.41421356237 , 0.0 , -1.0 )),
+ vertex(( -1.41421356237 , 0.0 , -1.0 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]) ]
+ for i in range(len(self.vertskeleton)):
+ self.vertskeleton[i].index = i
+ self.panelpoints=[[0,1,2],[1,2,3],[0,1,3],[0,2,3]]
+ self.paneledges=[[0,1,4],[4,3,5],[0,2,3],[1,2,5]]
+ self.reversepanel=[0,3]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+#for face on top? YES
+class tetraface(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( -1.41421356237 , -0.816496580927 , 0.57735026919 )),
+ vertex(( 1.41421356237 , -0.816496580927 , 0.57735026919 )),
+ vertex(( 0.0 , 1.63299316185 , 0.577350269185 )),
+ vertex(( 0.0 , 0.0 , -1.73205080757 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[0]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]) ]
+ self.panelpoints=[[2,0,1],[0,1,3],[2,1,3],[2,0,3]]
+ self.paneledges=[[2,1,0],[0,3,4],[1,5,4],[2,5,3]]
+ self.reversepanel=[1,3]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class octahedron(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex((0.0,0.0,1.0)),
+ vertex((0.0,1.0,0.0)),
+ vertex((-1.0,0.0,0.0)),
+ vertex((0.0,-1.0,0.0)),
+ vertex((1.0,0.0,0.0)),
+ vertex((0.0,0.0,-1.0)) ]
+ for i in range(len(self.vertskeleton)):
+ self.vertskeleton[i].index = i
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[1]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]) ]
+ self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]]
+ self.paneledges=[[0,1,4],[1,2,5],[2,3,6],[3,0,7],[4,8,9],[5,9,10],[6,10,11],[7,11,8]]
+ self.reversepanel=[4,5,6,7]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+class octaedge(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , -0.707106781187 , 0.707106781187 )),
+ vertex(( 0.0 , 0.707106781187 , 0.707106781187 )),
+ vertex(( 1.0 , 0.0 , 0.0 )),
+ vertex(( -1.0 , 0.0 , 0.0 )),
+ vertex(( 0.0 , -0.707106781187 , -0.707106781187 )),
+ vertex(( 0.0 , 0.707106781187 , -0.707106781187 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[2],self.vertskeleton[4]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]) ]
+ self.panelpoints=[[0,1,2],[0,1,3],[0,2,4],[1,2,5],[1,3,5],[0,3,4],[2,4,5],[3,4,5]]
+ self.paneledges=[[0,2,3],[0,6,5],[2,1,7],[3,4,8],[5,4,9],[6,1,10],[7,8,11],[10,9,11]]
+ self.reversepanel=[0,2,4,7]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+class octaface(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.408248458663 , -0.707106781187 , 0.577350150255 )),
+ vertex(( 0.408248458663 , 0.707106781187 , 0.577350150255 )),
+ vertex(( -0.816496412728 , 0.0 , 0.577350507059 )),
+ vertex(( -0.408248458663 , -0.707106781187 , -0.577350150255 )),
+ vertex(( 0.816496412728 , 0.0 , -0.577350507059 )),
+ vertex(( -0.408248458663 , 0.707106781187 , -0.577350150255 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[0]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]) ]
+ self.panelpoints=[[2,0,1],[0,3,4],[0,1,4],[1,4,5],[2,1,5],[2,3,5],[2,0,3],[3,4,5]]
+ self.paneledges=[[2,1,0],[3,4,9],[0,4,5],[5,6,10],[1,7,6],[8,7,11],[2,8,3],[9,11,10]]
+ self.reversepanel=[2,5,6,7]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+class icosahedron(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , 0.0 , 0.587785252292 )),
+ vertex(( 0.0 , -0.525731096637 , 0.262865587024 )),
+ vertex(( 0.5 , -0.162459832634 , 0.262865565628 )),
+ vertex(( 0.309016994375 , 0.425325419658 , 0.262865531009 )),
+ vertex(( -0.309016994375 , 0.425325419658 , 0.262865531009 )),
+ vertex(( -0.5 , -0.162459832634 , 0.262865565628 )),
+ vertex(( 0.309016994375 , -0.425325419658 , -0.262865531009 )),
+ vertex(( 0.5 , 0.162459832634 , -0.262865565628 )),
+ vertex(( 0.0 , 0.525731096637 , -0.262865587024 )),
+ vertex(( -0.5 , 0.162459832634 , -0.262865565628 )),
+ vertex(( -0.309016994375 , -0.425325419658 , -0.262865531009 )),
+ vertex(( 0.0 , 0.0 , -0.587785252292 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[0],self.vertskeleton[5]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]),
+ edge(self.vertskeleton[5],self.vertskeleton[1]),
+ edge(self.vertskeleton[1],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[7]),
+ edge(self.vertskeleton[3],self.vertskeleton[7]),
+ edge(self.vertskeleton[3],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[9]),
+ edge(self.vertskeleton[5],self.vertskeleton[9]),
+ edge(self.vertskeleton[5],self.vertskeleton[10]),
+ edge(self.vertskeleton[1],self.vertskeleton[10]),
+ edge(self.vertskeleton[6],self.vertskeleton[7]),
+ edge(self.vertskeleton[7],self.vertskeleton[8]),
+ edge(self.vertskeleton[8],self.vertskeleton[9]),
+ edge(self.vertskeleton[9],self.vertskeleton[10]),
+ edge(self.vertskeleton[10],self.vertskeleton[6]),
+ edge(self.vertskeleton[6],self.vertskeleton[11]),
+ edge(self.vertskeleton[7],self.vertskeleton[11]),
+ edge(self.vertskeleton[8],self.vertskeleton[11]),
+ edge(self.vertskeleton[9],self.vertskeleton[11]),
+ edge(self.vertskeleton[10],self.vertskeleton[11]) ]
+ self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],[2,6,7],[2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],[5,9,10],[5,1,10],[1,10,6],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11]]
+ self.paneledges=[[0,1,5],[1,2,6],[2,3,7],[3,4,8],[4,0,9],[5,10,11],[11,12,20],[6,12,13],[13,14,21],[7,14,15],[15,16,22],[8,16,17],[17,18,23],[9,18,19],[19,10,24],[20,25,26],[21,26,27],[22,27,28],[23,28,29],[24,29,25]]
+ self.reversepanel=[5,7,9,11,13,15,16,17,18,19]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+class icoedge(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0 , 0.309016994375 , 0.5 )),
+ vertex(( 0 , -0.309016994375 , 0.5 )),
+ vertex(( -0.5 , 0 , 0.309016994375 )),
+ vertex(( 0.5 , 0 , 0.309016994375 )),
+ vertex(( -0.309016994375 , -0.5 , 0 )),
+ vertex(( 0.309016994375 , -0.5 , 0 )),
+ vertex(( 0.309016994375 , 0.5 , 0 )),
+ vertex(( -0.309016994375 , 0.5 , 0 )),
+ vertex(( -0.5 , 0 , -0.309016994375 )),
+ vertex(( 0.5 , 0 , -0.309016994375 )),
+ vertex(( 0 , 0.309016994375 , -0.5 )),
+ vertex(( 0 , -0.309016994375 , -0.5 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[7]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[7]),
+ edge(self.vertskeleton[2],self.vertskeleton[8]),
+ edge(self.vertskeleton[2],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[9]),
+ edge(self.vertskeleton[3],self.vertskeleton[6]),
+ edge(self.vertskeleton[6],self.vertskeleton[7]),
+ edge(self.vertskeleton[7],self.vertskeleton[10]),
+ edge(self.vertskeleton[7],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[11]),
+ edge(self.vertskeleton[5],self.vertskeleton[11]),
+ edge(self.vertskeleton[5],self.vertskeleton[9]),
+ edge(self.vertskeleton[6],self.vertskeleton[9]),
+ edge(self.vertskeleton[6],self.vertskeleton[10]),
+ edge(self.vertskeleton[8],self.vertskeleton[10]),
+ edge(self.vertskeleton[8],self.vertskeleton[11]),
+ edge(self.vertskeleton[9],self.vertskeleton[11]),
+ edge(self.vertskeleton[9],self.vertskeleton[10]),
+ edge(self.vertskeleton[10],self.vertskeleton[11]) ]
+ self.panelpoints=[ [0,1,2],[0,1,3],[0,2,7],[1,2,4],[1,4,5],[1,3,5],[0,3,6],[0,6,7],[2,7,8],[2,4,8],
+ [3,5,9],[3,6,9],[7,8,10],[4,8,11],[4,5,11],[5,9,11],[6,9,10],[6,7,10],[8,10,11],[9,10,11]]
+ self.paneledges=[[0,2,3],[0,7,6],[2,1,9],[3,4,11],[4,5,12],[6,5,13],[7,8,15],[8,1,16],[9,10,18],[11,10,19],
+ [13,14,22],[15,14,23],[18,17,25],[19,20,26],[12,20,21],[22,21,27],[23,24,28],[16,24,17],[25,26,29],[28,27,29]]
+ self.reversepanel=[0,2,5,9,11,12,14,15,17,19]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+class icoface(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( -0.17841104489 , 0.309016994375 , 0.46708617948 )),
+ vertex(( -0.17841104489 , -0.309016994375 , 0.46708617948 )),
+ vertex(( 0.35682208977 , 0.0 , 0.467086179484 )),
+ vertex(( -0.57735026919 , 0.0 , 0.110264089705 )),
+ vertex(( -0.288675134594 , -0.5 , -0.11026408971 )),
+ vertex(( 0.288675134594 , -0.5 , 0.11026408971 )),
+ vertex(( 0.57735026919 , 0.0 , -0.110264089705 )),
+ vertex(( 0.288675134594 , 0.5 , 0.11026408971 )),
+ vertex(( -0.288675134594 , 0.5 , -0.11026408971 )),
+ vertex(( -0.35682208977 , 0.0 , -0.467086179484 )),
+ vertex(( 0.17841104489 , -0.309016994375 , -0.46708617948 )),
+ vertex(( 0.17841104489 , 0.309016994375 , -0.46708617948 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[0]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[7]),
+ edge(self.vertskeleton[0],self.vertskeleton[7]),
+ edge(self.vertskeleton[0],self.vertskeleton[8]),
+ edge(self.vertskeleton[3],self.vertskeleton[9]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[5],self.vertskeleton[4]),
+ edge(self.vertskeleton[5],self.vertskeleton[10]),
+ edge(self.vertskeleton[5],self.vertskeleton[6]),
+ edge(self.vertskeleton[7],self.vertskeleton[6]),
+ edge(self.vertskeleton[7],self.vertskeleton[11]),
+ edge(self.vertskeleton[7],self.vertskeleton[8]),
+ edge(self.vertskeleton[3],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[9]),
+ edge(self.vertskeleton[4],self.vertskeleton[10]),
+ edge(self.vertskeleton[6],self.vertskeleton[10]),
+ edge(self.vertskeleton[6],self.vertskeleton[11]),
+ edge(self.vertskeleton[8],self.vertskeleton[11]),
+ edge(self.vertskeleton[8],self.vertskeleton[9]),
+ edge(self.vertskeleton[9],self.vertskeleton[10]),
+ edge(self.vertskeleton[11],self.vertskeleton[10]),
+ edge(self.vertskeleton[11],self.vertskeleton[9]) ]
+ self.panelpoints=[[2,0,1],[0,1,3],[2,1,5],[2,0,7],[1,3,4],[1,5,4],[2,5,6],[2,7,6],[0,7,8],[0,3,8],[3,4,9],[5,4,10],[5,6,10],[7,6,11],[7,8,11],[3,8,9],[4,9,10],[6,11,10],[8,11,9],[11,9,10]]
+ self.paneledges=[[2,1,0],[0,3,4],[1,7,6],[2,9,10],[4,5,13],[6,5,14],[7,8,16],[9,8,17],[10,11,19],[3,11,20],
+ [13,12,21],[14,15,22],[16,15,23],[17,18,24],[19,18,25],[20,12,26],[21,22,27],[24,23,28],[25,26,29],[29,28,27]]
+ self.reversepanel=[1,3,5,7,9,10,12,14,17,19]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+##???PKHG TODO this does not work yet ...
+def creategeo(geo,polytype,orientation,parameters):
+
+ if polytype == 'Tetrahedron':
+ if orientation == 'PointUp':
+ #return
+ #geo(parameters)
+# geo.setparameters()
+ my_tetrahedron = tetrahedron(geodesic)
+ my_tetrahedron.set_vert_edge_skeleons()
+ my_tetrahedron.config()
+ check_contains(my_tetrahedron,"my_tetra",True)
+ vefm_add_object(geo)
+ elif orientation == 'EdgeUp':
+ geo = tetraedge(parameters)
+ else: # orientation==2:
+ geo=tetraface(parameters)
+ elif polytype == 'Octahedron': # octahedron
+ if orientation == 'PointUp':
+ geo = octahedron(parameters)
+ elif orientation == 'EdgeUp':
+ geo = octaedge(parameters)
+ else: #if orientation==2:
+ geo = octaface(parameters)
+ elif polytype == 'Icosahedron': # icosahedron
+ if orientation == 'PointUp':
+ geo = icosahedron(parameters)
+ elif orientation == 'EdgeUp':
+ geo = icoedge(parameters)
+ else: #if orientation==2:
+ geo = icoface(parameters)
+ return geo
diff --git a/release/scripts/addons_contrib/geodesic_domes/read_me.txt b/release/scripts/addons_contrib/geodesic_domes/read_me.txt
new file mode 100644
index 0000000..ad20376
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/read_me.txt
@@ -0,0 +1,28 @@
+Geodesic_Domes
+Based on a script by Andy Houston (serendipiti) for Blender 2.49
+Original Script Documentation:
+http://wiki.blender.org/index.php/Extensions:2.4/Py/Scripts/Wizards/Geodesic_dome
+Licence:
+GPL
+
+PKHG (did the conversion)
+BIG change after revision 2551 GUI adjusted ...
+You should download anew if older then 24-november-2011
+
+In principle all parts work:
+the *hedrons with superformparameters
+Grid ... Sphere with superformparameters
+Faces **
+Hubs **
+Struts **
+
+** means will be adjusted ... at the moment you have to name objects and
+execute eventually again ;-( ...
+
+but PKHG is content with a this nearly 95% converted version.
+
+TODO, ranges of parameters could be chosen differently. Inform PKHG!
+
+Uplaod will be done today (25-11 at about 19.30... GMT -+1)
+
+_259 in the names is not important ... but let it be so (now) ;-)
diff --git a/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py b/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py
new file mode 100644
index 0000000..171a96a
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/third_domes_panel.py
@@ -0,0 +1,1062 @@
+import bpy
+import os
+from geodesic_domes import vefm_259
+from geodesic_domes import forms_259
+from geodesic_domes import geodesic_classes_259
+from geodesic_domes import add_shape_geodesic
+
+from bpy.props import EnumProperty, IntProperty, FloatProperty, StringProperty, BoolProperty
+import math
+from math import pi
+from mathutils import Vector #needed to check vertex.vector values
+try:
+ breakpoint = bpy.types.bp.bp
+except:
+ print("add breakpoint addon!")
+
+
+########global######
+last_generated_object = None
+last_imported_mesh = None
+basegeodesic = None
+imported_hubmesh_to_use = None
+########global end######
+
+########EIND FOR SHAPEKEYS######
+### error messages?!
+bpy.types.Scene.error_message = StringProperty(name="actual error", default = "")
+
+
+bpy.types.Scene.geodesic_not_yet_called = BoolProperty(name="geodesic_not_called",default = True)
+
+bpy.types.Scene.gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20)
+
+class Geodesic_Domes_Operator_Panel(bpy.types.Panel):
+ """start a GD object here"""
+ bl_label = "Geodesic Domes"
+ bl_region_type = "TOOLS" #UI possible too
+ bl_space_type = "VIEW_3D"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self,context):
+ sce = context.scene
+ layout = self.layout
+ col = layout.column()
+ col.label("To start an GD object: ")
+ col.operator(GenerateGeodesicDome.bl_idname,"execute me!")
+
+class GenerateGeodesicDome(bpy.types.Operator):
+ bl_label = "Modify Geodesic Objects"
+ bl_idname = "mesh.generate_geodesic_dome"
+ bl_description = "Create object dependent on selection"
+ bl_options = {'REGISTER','UNDO'}
+
+#PKHG_NEW saving and loading parameters
+ save_parameters = BoolProperty(name = "save params",\
+ description = "activation save */tmp/GD_0.GD", default = False)
+ load_parameters = BoolProperty(name = "load params",\
+ description = "read */tmp/GD_0.GD", default = False)
+
+ gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20)
+
+
+ mainpages = EnumProperty(
+ name="Menu",
+ description="Create Faces, Struts & Hubs",
+ items=[("Main","Main","Geodesic objects"),
+ ("Faces","Faces","Generate Faces"),
+ ("Struts","Struts","Generate Struts"),
+ ("Hubs","Hubs","Generate Hubs"),
+ ("Help","Help","Not implemented"),
+ ],
+ default='Main')
+
+#for Faces!
+ facetype_menu = EnumProperty(
+ name="Faces",
+ description="choose a facetype",
+ items=[("0","strip","strip"),
+ ("1","open vertical","vertical"),
+ ("2","opwn slanted","slanted"),
+ ("3","closed point","closed point"),
+ ("4","pillow","pillow"),
+ ("5","closed vertical","closed vertical"),
+ ("6","stepped","stepped"),
+ ("7","spikes","spikes"),
+ ("8","boxed","boxed"),
+ ("9","diamond","diamond"),
+ ("10","bar","bar"),
+ ],
+ default='0')
+
+ facetoggle = BoolProperty(name="Activate: Face Object", description = "Activate Faces for Geodesic object", default = False )
+# faceimporttoggle = BoolProperty(name="faceimporttoggle", default = False )
+ face_use_imported_object = BoolProperty(name="Use: Imported Object",\
+ description = "Activate faces on your Imported object", default = False)
+ facewidth = FloatProperty(name="facewidth", min = -8, max = 8, default = .50)
+ fwtog = BoolProperty(name="fwtog", default = False )
+ faceheight = FloatProperty(name="faceheight", min = -8, max = 8, default = 1 )
+ fhtog = BoolProperty(name="fhtog", default = False )
+ face_detach = BoolProperty(name="face_detach", default = False )
+ fmeshname = StringProperty(name="fmeshname", default = "defaultface")
+
+
+ geodesic_types = EnumProperty(
+ name="Objects",
+ description="Choose Geodesic, Grid, Cylinder,Parabola, Torus, Sphere, Import your mesh or Superparameters",
+ items=[("Geodesic","Geodesic","Generate Geodesic"),
+ ("Grid","Grid","Generate Grid"),
+ ("Cylinder","Cylinder","Generate Cylinder"),
+ ("Parabola","Parabola","Generate Parabola"),
+ ("Torus","Torus","Generate Torus"),
+ ("Sphere","Sphere","Generate Sphere"),
+ ("Import your mesh","Import your mesh","Import Your Mesh"),
+ ],
+ default='Geodesic')
+
+ import_mesh_name = StringProperty(name = "mesh to import",\
+ description = "the name has to be the name of a meshobject", default = "None")
+
+ base_type = EnumProperty(
+ name="Hedron",
+ description="Choose between Tetrahedron, Octahedron, Icosahedron ",
+ items=[("Tetrahedron","Tetrahedron","Generate Tetrahedron"),
+ ("Octahedron","Octahedron","Generate Octahedron"),
+ ("Icosahedron","Icosahedron","Generate Icosahedron"),
+ ],
+ default='Tetrahedron')
+
+ orientation = EnumProperty(
+ name="Point^",
+ description="Point (Vert), Edge or Face pointing upwards",
+ items=[("PointUp","PointUp","Point up"),
+ ("EdgeUp","EdgeUp","Edge up"),
+ ("FaceUp","FaceUp","Face up"),
+ ],
+ default='PointUp')
+
+ geodesic_class = EnumProperty(
+ name="Class",
+ description="Subdivide Basic/Triacon",
+ items=[("Class 1","Class 1","class one"),
+ ("Class 2","Class 2","class two"),
+ ],
+ default='Class 1')
+
+ tri_hex_star = EnumProperty(
+ name="Shape",
+ description="Choose between tri hex star face types",
+ items=[("tri","tri","tri faces"),
+ ("hex","hex","hex faces(by tri)"),
+ ("star","star","star faces(by tri)"),
+ ],
+ default='tri')
+
+ spherical_flat = EnumProperty(
+ name="Round",
+ description="Choose between spherical or flat ",
+ items=[("spherical","spherical","Generate spherical"),
+ ("flat","flat","Generate flat"),
+ ],
+ default='spherical')
+
+ use_imported_mesh = BoolProperty(name="use import",\
+ description = "Use an imported mesh", default = False)
+
+#Cylinder
+ cyxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\
+ description = "number of faces around x/y", default = 5 )
+ cyyres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 5 )
+ cyxsz= FloatProperty(name="Scale x/y", min = 0.01, max = 10,\
+ description = "scale in x/y direction", default = 1 )
+ cyysz= FloatProperty(name="Scale z", min = 0.01, max = 10,\
+ description = "scale in z direction", default = 1 )
+ cyxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
+ description = "stretch in x direction", default = 1 )
+ cygap= FloatProperty(name="Gap", min = -2, max = 2, precision = 4,\
+ description = "shrink in % around radius", default = 1 )
+ cygphase= FloatProperty(name="Phase", min = -4, max = 4,\
+ description = "rotate around pivot x/y", default = 0 )
+#Parabola
+ paxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\
+ description = "number of faces around x/y", default = 5 )
+ payres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 5 )
+ paxsz= FloatProperty(name="Scale x/y", min = 0.001, max = 10,\
+ description = "scale in x/y direction", default = 0.30)
+ paysz= FloatProperty(name="Scale z", min = 0.001, max = 10,\
+ description = "scale in z direction", default = 1 )
+ paxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
+ description = "stretch in x direction", default = 1 )
+ pagap= FloatProperty(name="Gap", min = -2, max = 2,\
+ description = "shrink in % around radius", precision = 4, default = 1 )
+ pagphase= FloatProperty(name="Phase", min = -4, max = 4,\
+ description = "rotate around pivot x/y", default = 0 )
+#Torus
+ ures= IntProperty(name="Resolution x/y",min = 3, max = 32,\
+ description = "number of faces around x/y", default = 8 )
+ vres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 8 )
+ urad= FloatProperty(name="Radius x/y", min = 0.001, max = 10,\
+ description = "radius in x/y plane", default = 1 )
+ vrad= FloatProperty(name="Radius z", min = 0.001, max = 10,\
+ description = "radius in z plane", default = 0.250)
+ uellipse= FloatProperty(name="Stretch x", min = 0.001, max = 10,\
+ description = "number of faces in z direction", default = 1 )
+ vellipse= FloatProperty(name="Stretch z", min = 0.001, max = 10,\
+ description = "number of faces in z direction", default = 1 )
+ upart= FloatProperty(name="Gap x/y", min = -4, max = 4, precision = 4,\
+ description = "shrink faces around x/y", default = 1 )
+ vpart= FloatProperty(name="Gap z", min = -4, max = 4, precision = 4,\
+ description = "shrink faces in z direction", default = 1 )
+ ugap= FloatProperty(name="Phase x/y", min = -4, max = 4, precision = 4,\
+ description = "rotate around pivot x/y", default = 0 )
+ vgap= FloatProperty(name="Phase z", min = -4, max = 4, precision = 4,\
+ description = "rotate around pivot z", default = 0 )
+ uphase= FloatProperty(name="uphase", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ vphase= FloatProperty(name="vphase", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ uexp= FloatProperty(name="uexp", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ vexp= FloatProperty(name="vexp", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ usuper= FloatProperty(name="usuper", min = -4, max = 4,\
+ description = "first set of superform parameters", default = 2 )
+ vsuper= FloatProperty(name="vsuper", min = -4, max = 4,\
+ description = "second set of superform parameters", default = 2 )
+ utwist= FloatProperty(name="Twist x/y", min = -4, max = 4,\
+ description = " use with superformular u", default = 0 )
+ vtwist= FloatProperty(name="Twist z", min = -4, max = 4,\
+ description = "use with superformular v", default = 0 )
+
+#Sphere
+ bures= IntProperty(name="Resolution x/y", min = 3, max = 32,\
+ description = "number of faces around x/y", default = 8 )
+ bvres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 8 )
+ burad= FloatProperty(name="Radius", min = -4, max = 4,\
+ description = "overall radius", default = 1 )
+ bupart= FloatProperty(name="Gap x/y", min = -4, max = 4, precision = 4,\
+ description = "shrink faces around x/y", default = 1 )
+ bvpart= FloatProperty(name="Gap z", min = -4, max = 4, precision = 4,\
+ description = "shrink faces in z direction", default = 1 )
+ buphase= FloatProperty(name="Phase x/y", min = -4, max = 4,
+ description = "rotate around pivot x/y", default = 0 )
+ bvphase= FloatProperty(name="Phase z", min = -4, max = 4,\
+ description = "rotate around pivot z", default = 0 )
+ buellipse= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
+ description = "stretch in the x direction", default = 1 )
+ bvellipse= FloatProperty(name="Stretch z", min = 0.001, max = 4,\
+ description = "stretch in the z direction", default = 1 )
+#Grid
+ grxres = IntProperty(name="Resolution x", min = 2, soft_max = 10, max = 20,\
+ description = "number of faces in x direction", default = 5 )
+ gryres = IntProperty(name="Resolution z",min = 2, soft_min = 2, soft_max=10, max = 20,\
+ description = "number of faces in x direction", default = 2)
+ grxsz = FloatProperty(name = "X size", min = 1, soft_min=0.01, soft_max=5, max = 10,\
+ description = "x size", default = 2.0)
+ grysz = FloatProperty(name="Y size",min = 1, soft_min=0.01, soft_max=5, max = 10,\
+ description = "y size", default = 1.0)
+
+#PKHG_TODO_??? what means cart
+ cart = IntProperty(name = "cart",min = 0, max = 2, default = 0)
+
+ frequency = IntProperty(name="Frequency", min = 1, max = 8,\
+ description ="subdivide base triangles", default = 1 )
+ eccentricity = FloatProperty(name = "Eccentricity", min = 0.01 , max = 4,\
+ description = "scaling in x/y dimension", default = 1 )
+ squish = FloatProperty(name = "Squish",min = 0.01, soft_max = 4, max = 10,\
+ description = "scaling in z dimension", default = 1 )
+ radius = FloatProperty(name = "Radius",min = 0.01, soft_max = 4, max = 10,\
+ description = "overall radius", default = 1 )
+ squareness = FloatProperty(name="Square x/y", min = 0.1, max = 5,\
+ description = "superelipse action in x/y", default = 2 )
+ squarez = FloatProperty(name="Square z", min = 0.1, soft_max = 5, max = 10,\
+ description = "superelipse action in z", default = 2 )
+ baselevel = IntProperty(name="baselevel", default = 5 )
+ dual = BoolProperty(name="Dual", description = "faces become verts, verts become faces, edges flip", default = False)
+ rotxy = FloatProperty(name="Rotate x/y", min= -4, max = 4,\
+ description = "rotate superelipse action in x/y", default = 0 )
+ rotz = FloatProperty(name="Rotate z", min= -4, max = 4,\
+ description = "rotate superelipse action in z", default = 0 )
+
+#for choice of superformula
+ uact = BoolProperty(name = 'superformula u (x/y)', description = "activate superformula u parameters", default = False)
+ vact = BoolProperty(name = 'superformula v (z)', description = "activate superformula v parameters", default = False)
+ um = FloatProperty(name = 'um', min = 0, soft_min=0.1, soft_max = 10, max = 20,\
+ description = "to do", default = 3)
+ un1 = FloatProperty(name = 'un1', min = 0, soft_min=0.1, soft_max = 10,max = 20,\
+ description = "to do", default = 1)
+ un2 = FloatProperty(name = 'un2', min = 0, soft_min=0.1, soft_max = 10,max = 20,\
+ description = "to do", default = 1)
+ un3 = FloatProperty(name = 'un3', min = 0, soft_min=0.1, soft_max = 10, max = 20,\
+ description = "to do", default = 1)
+ ua = FloatProperty(name = 'ua', min = 0.01, soft_min=0.1, soft_max = 8, max = 16,\
+ description = "semi-diameter (has both soft pars!)", default = 1.0)
+ ub = FloatProperty(name = 'ub', min = 0.01, soft_min = 0.1, soft_max = 8, max = 16,\
+ description = "semi-diameter (has both soft pars!)", default = 1.0)
+ vm = FloatProperty(name = 'vm', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 1)
+ vn1 = FloatProperty(name = 'vn1', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 1)
+ vn2 = FloatProperty(name = 'vn2', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 1)
+ vn3 = FloatProperty(name = 'vn3', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 1)
+ va = FloatProperty(name = 'va', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 1)
+ vb = FloatProperty(name = 'vb', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 1)
+
+ uturn = FloatProperty(name = 'uturn', min = -5, soft_min=0, soft_max=5,max = 10,\
+ description = "to do", default = 0)
+ vturn = FloatProperty(name = 'vturn', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 0)
+ utwist = FloatProperty(name = 'utwist', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 0)
+ vtwist = FloatProperty(name = 'vtwist', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "to do", default = 0)
+
+#Strut
+ struttype= IntProperty(name="struttype", default= 0)
+ struttoggle = BoolProperty(name="struttoggle", default = False )
+ strutimporttoggle= BoolProperty(name="strutimporttoggle", default = False )
+ strutimpmesh= StringProperty(name="strutimpmesh", default = "None")
+ strutwidth= FloatProperty(name="strutwidth", min = -10, soft_min = 5, soft_max = 5, max = 10, default = 1 )
+ swtog= BoolProperty(name="swtog", default = False )
+ strutheight= FloatProperty(name="strutheight", min = -5, soft_min = -1, soft_max = 5, max = 10, default = 1 )
+ shtog= BoolProperty(name="shtog", default = False )
+ strutshrink= FloatProperty(name="strutshrink", min = 0.001, max = 4, default = 1 )
+ sstog= BoolProperty(name="sstog", default = False )
+ stretch= FloatProperty(name="stretch", min= -4, max = 4, default = 1.0 )
+ lift= FloatProperty(name="lift", min = 0.001, max = 10, default = 0 )
+ smeshname= StringProperty(name="smeshname", default = "defaultstrut")
+
+#Hubs
+ hubtype = BoolProperty(name ="hubtype", description = "not used", default = True )
+ hubtoggle = BoolProperty(name ="hubtoggle", default = False )
+ hubimporttoggle = BoolProperty(name="new import", description = "import a mesh", default = False )
+ hubimpmesh = StringProperty(name="hubimpmesh",\
+ description = "name of mesh to import", default = "None")
+ hubwidth = FloatProperty(name="hubwidth", min = 0.01, max = 10,\
+ default = 1 )
+ hwtog = BoolProperty(name="hwtog", default = False )
+ hubheight = FloatProperty(name="hubheight", min = 0.01, max = 10,\
+ default = 1 )
+ hhtog = BoolProperty(name="hhtog", default = False )
+ hublength = FloatProperty(name ="hublength", min = 0.1, max = 10,\
+ default = 1 )
+ hstog= BoolProperty(name="hstog", default = False )
+ hmeshname= StringProperty(name="hmeshname", description = "Name of an existing mesh needed!", default = "None")
+
+ name_list = ['facetype_menu','facetoggle','face_use_imported_object',
+'facewidth','fwtog','faceheight','fhtog',
+'face_detach','fmeshname','geodesic_types','import_mesh_name',
+'base_type','orientation','geodesic_class','tri_hex_star',
+'spherical_flat','use_imported_mesh','cyxres','cyyres',
+'cyxsz','cyysz','cyxell','cygap',
+'cygphase','paxres','payres','paxsz',
+'paysz','paxell','pagap','pagphase',
+'ures','vres','urad','vrad',
+'uellipse','vellipse','upart','vpart',
+'ugap','vgap','uphase','vphase',
+'uexp','vexp','usuper','vsuper',
+'utwist','vtwist','bures','bvres',
+'burad','bupart','bvpart','buphase',
+'bvphase','buellipse','bvellipse','grxres',
+'gryres','grxsz','grysz',
+'cart','frequency','eccentricity','squish',
+'radius','squareness','squarez','baselevel',
+'dual','rotxy','rotz',
+'uact','vact','um','un1',
+'un2','un3','ua','ub',
+'vm','vn1','vn2','vn3',
+'va','vb','uturn','vturn',
+'utwist','vtwist','struttype','struttoggle',
+'strutimporttoggle','strutimpmesh','strutwidth','swtog',
+'strutheight','shtog','strutshrink','sstog',
+'stretch','lift','smeshname','hubtype',
+'hubtoggle','hubimporttoggle','hubimpmesh','hubwidth',
+'hwtog','hubheight','hhtog','hublength',
+'hstog','hmeshname']
+
+ def write_params(self,filename):
+ file = open(filename, "w", encoding="utf8", newline="\n")
+ fw = file.write
+ #for Faces!
+ for el in self.name_list:
+ fw(el + ",")
+ fw(repr(getattr(self,el)))
+ fw(",\n")
+ file.close()
+
+ def read_file(self,filename):
+ file = open(filename, "r", newline="\n")
+ result = []
+ line = file.readline()
+ while(line):
+ tmp = line.split(",")
+ result.append(eval(tmp[1]))
+ line = file.readline()
+ return result
+
+
+ def draw(self,context):
+ sce = context.scene
+ layout = self.layout
+ row = layout.row()
+ row.prop(self,"save_parameters")
+ row.prop(self,"load_parameters")
+ col = layout.column()
+ col.label(" ")
+ col.prop(self,"mainpages")
+ which_mainpages = self.mainpages
+ if which_mainpages == 'Main':
+ col = layout.column()
+ col.prop(self,"geodesic_types")
+ tmp = self.geodesic_types
+ if tmp == "Geodesic":
+ col.label(text="Geodesic Object Types:")
+ col.prop(self, "geodesic_class")
+ col.prop(self, "base_type")
+ col.prop(self, "orientation")
+ col.prop(self, "tri_hex_star")
+ col.prop(self, "spherical_flat")
+ col.label("Geodesic Object Parameters:")
+ row = layout.row()
+ row.prop(self,"frequency")
+ row = layout.row()
+ row.prop(self,"radius")
+ row = layout.row()
+ row.prop(self,"eccentricity")
+ row = layout.row()
+ row.prop(self,"squish")
+ row = layout.row()
+ row.prop(self,"squareness")
+ row = layout.row()
+ row.prop(self,"squarez")
+ row = layout.row()
+ row.prop(self,"rotxy")
+ row = layout.row()
+ row.prop(self,"rotz")
+ row = layout.row()
+ row.prop(self,"dual")
+ elif tmp == 'Torus':
+ col.label("Torus Parameters")
+ row = layout.row()
+ row.prop(self, "ures")
+ row = layout.row()
+ row.prop(self, "vres")
+ row = layout.row()
+ row.prop(self, "urad")
+ row = layout.row()
+ row.prop(self, "vrad")
+ row = layout.row()
+ row.prop(self, "uellipse")
+ row = layout.row()
+ row.prop(self, "vellipse")
+ row = layout.row()
+ row.prop(self, "upart")
+ row = layout.row()
+ row.prop(self, "vpart")
+ row = layout.row()
+ row.prop(self, "ugap")
+ row.prop(self, "vgap")
+ row = layout.row()
+ row.prop(self, "uphase")
+ row.prop(self, "vphase")
+ row = layout.row()
+ row.prop(self, "uexp")
+ row.prop(self, "vexp")
+ row = layout.row()
+ row.prop(self, "usuper")
+ row.prop(self, "vsuper")
+ row = layout.row()
+ row.prop(self, "vgap")
+ row = layout.row()
+ elif tmp == 'Sphere':
+ col.label("Sphere Parameters")
+ row = layout.row()
+ row.prop(self,"bures")
+ row = layout.row()
+ row.prop(self,"bvres")
+ row = layout.row()
+ row.prop(self,"burad")
+ row = layout.row()
+ row.prop(self,"bupart")
+ row = layout.row()
+ row.prop(self,"buphase")
+ row = layout.row()
+ row.prop(self,"bvpart")
+ row = layout.row()
+ row.prop(self,"bvphase")
+ row = layout.row()
+ row.prop(self,"buellipse")
+ row = layout.row()
+ row.prop(self,"bvellipse")
+ elif tmp == 'Parabola':
+ col.label("Parabola Parameters")
+ row = layout.row()
+ row.prop(self, "paxres")
+ row = layout.row()
+ row.prop(self, "payres")
+ row = layout.row()
+ row.prop(self, "paxsz")
+ row = layout.row()
+ row.prop(self, "paysz")
+ row = layout.row()
+ row.prop(self, "paxell")
+ row = layout.row()
+ row.prop(self, "pagap")
+ row = layout.row()
+ row.prop(self, "pagphase")
+ elif tmp == 'Cylinder':
+ col.label("Cylinder Parameters")
+ col.prop(self, "cyxres")
+ col.prop(self, "cyyres")
+ col.prop(self, "cyxsz")
+ col.prop(self, "cyysz")
+ col.prop(self, "cyxell")
+ col.prop(self, "cygap")
+ col.prop(self, "cygphase")
+ elif tmp == 'Grid':
+ col.label("Grid Parameters")
+ row = layout.row()
+ row.prop(self, "grxres")
+ row = layout.row()
+ row.prop(self, "gryres")
+ row = layout.row()
+ row.prop(self, "grxsz")
+ row = layout.row()
+ row.prop(self, "grysz")
+ elif tmp == 'Import your mesh':
+ col.prop(self,"use_imported_mesh")
+ col.prop(self, "import_mesh_name")
+#######superform parameters only where possible
+ row = layout.row()
+ row.prop(self,"uact")
+ row = layout.row()
+ row.prop(self,"vact")
+ row = layout.row()
+ if not(tmp == 'Import your mesh'):
+ if (self.uact == False) and (self.vact == False):
+ row.label("no checkbox active!")
+ else:
+ row.label("Superform Parameters")
+ if self.uact:
+ row = layout.row()
+ row.prop(self,"um")
+ row = layout.row()
+ row.prop(self,"un1")
+ row = layout.row()
+ row.prop(self,"un2")
+ row = layout.row()
+ row.prop(self,"un3")
+ row = layout.row()
+ row.prop(self,"ua")
+ row = layout.row()
+ row.prop(self,"ub")
+ row = layout.row()
+ row.prop(self,"uturn")
+ row = layout.row()
+ row.prop(self,"utwist")
+ if self.vact:
+ row = layout.row()
+ row.prop(self,"vm")
+ row = layout.row()
+ row.prop(self,"vn1")
+ row = layout.row()
+ row.prop(self,"vn2")
+ row = layout.row()
+ row.prop(self,"vn3")
+ row = layout.row()
+ row.prop(self,"va")
+ row = layout.row()
+ row.prop(self,"vb")
+ row = layout.row()
+ row.prop(self,"vturn")
+ row = layout.row()
+ row.prop(self,"vtwist")
+########einde superfo
+ elif which_mainpages == "Hubs":
+ row = layout.row()
+ row.prop(self, "hubtoggle")
+#PKHG_NOT_USDED_YET_24-11 row.prop(self, "hubtype")
+ row = layout.row()
+#25-11 not needed row.prop(self, "hubimporttoggle")
+ row = layout.row()
+ if self.hubimpmesh == "None":
+ row = layout.row()
+ row.label("name of a hub to use")
+ row = layout.row()
+ row.prop(self, "hubimpmesh")
+ row = layout.row()
+ if self.hmeshname == "None":
+ row = layout.row()
+ row.label("name of mesh to be filled in!")
+ row = layout.row()
+ row.prop(self,"hmeshname")
+ row = layout.row()
+ row.prop(self, "hwtog")
+ if self.hwtog:
+ row.prop(self, "hubwidth")
+ row = layout.row()
+ row.prop(self, "hhtog")
+ if self.hhtog:
+ row.prop(self, "hubheight")
+ row = layout.row()
+ row.prop(self, "hublength")
+ elif which_mainpages == "Struts":
+ row = layout.row()
+# row.prop(self, "struttype")
+ row.prop(self, "struttoggle")
+# row = layout.row()
+# row.prop(self, "strutimporttoggle")
+ row = layout.row()
+ row.prop(self, "strutimpmesh")
+ row = layout.row()
+ row.prop(self, "swtog")
+ if self.swtog:
+ row.prop(self, "strutwidth")
+ row = layout.row()
+ row.prop(self, "shtog")
+ if self.shtog:
+ row.prop(self, "strutheight")
+ row = layout.row()
+ row.prop(self, "sstog")
+ if self.sstog:
+ row.prop(self, "strutshrink")
+ row = layout.row()
+ row.prop(self, "stretch")
+ row = layout.row()
+ row.prop(self, "lift")
+ row = layout.row()
+ row.prop(self, "smeshname")
+ elif which_mainpages == "Faces":
+ row = layout.row()
+ row.prop(self,"facetoggle")
+ row = layout.row()
+ row.prop(self,"face_use_imported_object")
+ row = layout.row()
+ row.prop(self,"facetype_menu")
+ row = layout.row()
+ row.prop(self,"fwtog")
+ if self.fwtog:
+ row.prop(self,"facewidth")
+ row = layout.row()
+ row.prop(self,"fhtog")
+ if self.fhtog:
+ row.prop(self,"faceheight")
+ row = layout.row()
+ row.prop(self,"face_detach")
+ row = layout.row()
+ row.prop(self,"fmeshname")
+ row = layout.row()
+
+ #help menu GUI
+ elif which_mainpages == "Help":
+ import textwrap
+
+ # a function that allows for multiple labels with text that wraps
+ # you can allow the user to set where the text wraps with the
+ # text_width parameter
+ # other parameters are ui : here you usually pass layout
+ # text: is a list with each index representing a line of text
+
+ def multi_label(text, ui,text_width=120):
+ for x in range(0,len(text)):
+ el = textwrap.wrap(text[x], width = text_width )
+
+ for y in range(0,len(el)):
+ ui.label(text=el[y])
+
+ box = layout.box()
+ help_text = ["NEW! ",
+ "New facility: save or load (nearly all) parameters ",
+ "A file GD_0.GD will be used, living in: ",
+ "geodesic_domes/tmp ",
+ "and if possible two backups "
+ "--------",
+ "After loading you have to change a ",
+ "parameter back and forth "
+ "to see it"]
+ text_width = self.gd_help_text_width
+ box.prop(self,"gd_help_text_width",slider=True)
+ multi_label(help_text,box, text_width)
+
+ def execute(self, context):
+ global last_generated_object, last_imported_mesh, basegeodesic, imported_hubmesh_to_use
+ #default superformparam = [3, 10, 10, 10, 1, 1, 4, 10, 10, 10, 1, 1, 0, 0, 0.0, 0.0, 0, 0]]
+ superformparam = [self.um, self.un1, self.un2, self.un3, self.ua,\
+ self.ub, self.vm, self.vn1, self.vn2, self.vn3,\
+ self.va, self.vb, self.uact, self.vact,\
+ self.uturn*pi, self.vturn*pi, \
+ self.utwist, self.vtwist]
+ context.scene.error_message = ""
+ if self.mainpages == 'Main':
+ if self.geodesic_types == "Geodesic":
+ tmp_fs = self.tri_hex_star
+ faceshape = 0 # tri!
+ if tmp_fs == "hex":
+ faceshape = 1
+ elif tmp_fs == "star":
+ faceshape = 2
+ tmp_cl = self.geodesic_class
+ klass = 0
+ if tmp_cl == "Class 2":
+ klass = 1
+ shape = 0
+ parameters = [self.frequency, self.eccentricity, self.squish,\
+ self.radius, self.squareness, self.squarez, 0,\
+ shape, self.baselevel, faceshape, self.dual,\
+ self.rotxy, self.rotz, klass, superformparam]
+ basegeodesic = creategeo(self.base_type,self.orientation,parameters)
+ basegeodesic.makegeodesic()
+ basegeodesic.connectivity()
+ mesh = vefm_259.mesh()
+ vefm_259.finalfill(basegeodesic,mesh) #always! for hexifiy etc. necessarry!!!
+ vefm_259.vefm_add_object(mesh)
+ last_generated_object = context.active_object
+ last_generated_object.location = (0,0,0)
+ context.scene.objects.active = last_generated_object
+ elif self.geodesic_types == 'Grid':
+ basegeodesic = forms_259.grid(self.grxres,self.gryres,\
+ self.grxsz,self.grysz,1.0,1.0,0,0,0,\
+ 0,1.0,1.0,superformparam)
+ vefm_259.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Cylinder":
+ basegeodesic = forms_259.cylinder(self.cyxres, self.cyyres, \
+ self.cyxsz, self.cyysz, self.cygap, \
+ 1.0, self.cygphase, 0, 0, 0, self.cyxell,\
+ 1.0, superformparam)
+ vefm_259.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+
+ elif self.geodesic_types == "Parabola":
+ basegeodesic=forms_259.parabola(self.paxres, self.payres,\
+ self.paxsz, self.paysz, self.pagap,1.0, self.pagphase,\
+ 0,0,0, self.paxell,1.0,superformparam)
+ vefm_259.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Torus":
+ basegeodesic = forms_259.torus(self.ures, self.vres,\
+ self.vrad, self.urad, self.upart, self.vpart,\
+ self.ugap, self.vgap,0,0, self.uellipse,\
+ self.vellipse, superformparam)
+ vefm_259.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Sphere":
+ basegeodesic=forms_259.sphere(self.bures, self.bvres,\
+ self.burad,1.0, self.bupart, self.bvpart,\
+ self.buphase, self.bvphase,0,0, self.buellipse,\
+ self.bvellipse,superformparam)
+
+ vefm_259.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Import your mesh":
+ obj_name = self.import_mesh_name
+ if obj_name == "None":
+ message = "fill in a name \nof an existing mesh\nto be imported"
+ context.scene.error_message = message
+ self.report({'INFO'}, message)
+ print("***INFO*** you have to fill in the name of an existing mesh")
+ else:
+# obj_in_scene = context.objects
+ names = [el.name for el in context.scene.objects]
+ if obj_name in names and context.scene.objects[obj_name].type == "MESH":
+ obj = context.scene.objects[obj_name]
+# if obj.type == "MESH":
+ your_obj = vefm_259.importmesh(obj.name,False)
+ last_imported_mesh = your_obj
+ vefm_259.vefm_add_object(your_obj)
+ last_generated_object = bpy.context.active_object
+ last_generated_object.name ="Imported mesh"
+ bpy.context.active_object.location = (0,0,0)
+ else:
+ message = obj_name +" does not exist \nor is not a MESH"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ self.report({'ERROR'}, message)
+ print("***ERROR***" + obj_name +" does not exist or is not a MESH")
+ elif self.mainpages == "Hubs":
+ hubtype = self.hubtype
+ hubtoggle = self.hubtoggle
+ hubimporttoggle = self.hubimporttoggle
+ hubimpmesh = self.hubimpmesh
+ hubwidth = self.hubwidth
+ hwtog = self.hwtog
+ hubheight = self.hubheight
+ hhtog = self.hhtog
+ hublength = self.hublength
+ hstog = self.hstog
+ hmeshname= self.hmeshname
+#PKHG_TODO_27-11 better info!??
+ if not (hmeshname == "None") and not (hubimpmesh == "None") and hubtoggle:
+ try:
+ hub_obj = vefm_259.importmesh(hmeshname,0)
+ hub = vefm_259.hub(hub_obj, True,\
+ hubwidth, hubheight, hublength,\
+ hwtog, hhtog, hstog, hubimpmesh)
+ mesh = vefm_259.mesh("test")
+ vefm_259.finalfill(hub,mesh)
+ vefm_259.vefm_add_object(mesh)
+ bpy.data.objects[-1].location = (0,0,0)
+ except:
+ message = "***ERROR*** \neither no mesh for hub\nor " + hmeshname + " available"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ print(message)
+ else:
+ message = "***INFO***\nuse the hub toggle!"
+ context.scene.error_message = message
+ print("\n***INFO*** use the hub toggle!")
+ elif self.mainpages == "Struts":
+ struttype = self.struttype
+ struttoggle = self.struttoggle
+ strutimporttoggle = self.strutimporttoggle
+ strutimpmesh = self.strutimpmesh
+ strutwidth = self.strutwidth
+ swtog = self.swtog
+ strutheight = self.strutheight
+ shtog = self.shtog
+ strutshrink = self.strutshrink
+ sstog = self.sstog
+ stretch = self.stretch
+ lift = self.lift
+ smeshname = self.smeshname
+ if not (strutimpmesh == "None") and struttoggle:
+ names = [el.name for el in context.scene.objects]
+ if strutimpmesh in names and context.scene.objects[strutimpmesh].type == "MESH":
+ strut = vefm_259.strut(basegeodesic, struttype,strutwidth,strutheight,stretch,swtog,shtog,swtog,strutimpmesh,sstog,lift)
+ strutmesh = vefm_259.mesh()
+ vefm_259.finalfill(strut,strutmesh)
+ vefm_259.vefm_add_object(strutmesh)
+ last_generated_object = context.active_object
+ last_generated_object.name = smeshname
+ last_generated_object.location = (0,0,0)
+ else:
+ message = "***ERROR***\n" + strutimpmesh + "\nis not a MESH"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ print("***ERROR*** strut obj is not a MESH")
+ else:
+ vefm_259.vefm_add_object(basegeodesic)
+ elif self.mainpages == "Faces":
+ if self.facetoggle:
+ faceparams=[[self.face_detach,0,[[0.5,0.0]]], #0 strip
+ [self.face_detach,0,[[0.0,0.5]]], #1 vertical
+ [self.face_detach,0,[[0.5,0.5]]], #2 slanted
+ [self.face_detach,1,[[0.25,0.25],[0.5,0.5]]], #3 closed point
+ [self.face_detach,1,[[0.1,0.03],[0.33,0.06],[0.0,0.1]]], #4 pillow
+ [self.face_detach,2,[[0.0,0.5]]], #5 closed vertical
+ [self.face_detach,2,[[0.0,0.25],[0.25,0.25],[0.25,0.5]]], #6 stepped
+ [self.face_detach,1,[[0.2,0.1],[0.4,0.2],[0.0,1.0]]], #7 spikes
+ [self.face_detach,3,[[0.25,0.0],[0.25,0.5],[0.0,0.5]]], #8 boxed
+ [self.face_detach,3,[[0.25,0.5],[0.5,0.0],[0.25,-0.5]]], #9 diamond
+ [self.face_detach,4,[[0.5,0.0],[0.5,0.5],[0.0,0.5]]],] #10 bar
+ facedata = faceparams[int(self.facetype_menu)]
+ if not self.face_use_imported_object:
+ faceobject = vefm_259.facetype(basegeodesic,facedata,self.facewidth,self.faceheight,self.fwtog)
+ else:
+ if last_imported_mesh:
+ faceobject = vefm_259.facetype(last_imported_mesh, facedata,self.facewidth,self.faceheight,self.fwtog)
+ else:
+ message = "***ERROR***\nno imported message available\n" + "last geodesic used"
+ self.face_use_imported_object = False
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ print("\n***ERROR*** no imported mesh available")
+ print("last geodesic used!")
+ faceobject = vefm_259.facetype(basegeodesic,facedata,\
+ self.facewidth,self.faceheight,self.fwtog)
+ facemesh = vefm_259.mesh()
+ finalfill(faceobject,facemesh)
+
+ vefm_259.vefm_add_object(facemesh)
+ obj = bpy.data.objects[-1]
+ obj.name = self.fmeshname
+ obj.location = (0,0,0)
+#PKHG save or load (nearly) all parameters
+ if self.save_parameters:
+ self.save_parameters = False
+ try:
+ print("DBG L884")
+ message = ""
+ scriptpath = bpy.utils.script_paths()[0]
+ sep = os.path.sep
+ tmpdir = os.path.join(scriptpath,"addons", "geodesic_domes" , "tmp")
+#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp"
+ print("tmpdirL890 = ",tmpdir)
+ if not os.path.isdir(tmpdir):
+ message += "***ERROR***\n" + tmpdir + "\nnot (yet) available\n"
+ print(message)
+ else:
+ filename = tmpdir + sep + "GD_0.GD"
+ filename_ren = tmpdir + sep + "GD_0.GD.bak"
+ filename_ren2 = tmpdir + sep + "GD_0.GD.2bak"
+ if os.path.isfile(filename_ren2):
+ try:
+ os.remove(filename_ren2)
+ message = "***Info***\nGD_0.GD.2bak removed\n"
+ except:
+ message = "***ERROR***\n,GD_0.GD.2bak could not be removed\n"
+ print(message)
+ if os.path.isfile(filename_ren):
+ try:
+ os.rename(filename_ren,filename_ren2)
+ message += "***INFO***\nGD_0.GD.bak renamed into GD_0.GD.2bak\n"
+ except:
+ message += "***Info***\nrenaming GD_0.GD.bak not possible\n"
+ if os.path.isfile(filename):
+ try:
+ os.rename(filename,filename_ren)
+ message += "***INFO***\nGD_0.GD renamed into GD_0.GD.bak\n"
+ except:
+ message += "***ERROR***\ncreation of GD_0.GD.bak not possible\n"
+ try:
+ print("DBG L921")
+ self.write_params(filename)
+ message += "***OK***\nparameters saved in\n" + filename
+ print(message)
+ except:
+ message = "***ERRROR***\n" + "writing " + filename + "\nnot possible"
+ print(message)
+ except:
+
+ message += "***ERROR***\n Contakt PKHG, something wrong happened"
+ print(message)
+
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+
+ if self.load_parameters:
+ self.load_parameters = False
+ try:
+ scriptpath = bpy.utils.script_paths()[0]
+ sep = os.path.sep
+ tmpdir = os.path.join(scriptpath,"addons", "geodesic_domes" , "tmp")
+#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp"
+ if not os.path.isdir(tmpdir):
+ message = "***ERROR***\n" + tmpdir + "\nnot available"
+ print(message)
+ filename = tmpdir + sep + "GD_0.GD"
+# self.read_file(filename)
+ try:
+ res = self.read_file(filename)
+ for i,el in enumerate(self.name_list):
+ setattr(self,el,res[i])
+
+ message = "***OK***\nparameters read from\n" + filename
+ print(message)
+
+ except:
+ message = "***ERRROR***\n" + "writing " + filename + "\nnot possible"
+ #bpy.context.scene.instant_filenames = filenames
+
+ except:
+ message = "***ERROR***\n Contakt PKHG,\nsomething went wrong reading params happened"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ global basegeodesic
+ bpy.ops.view3d.snap_cursor_to_center()
+ tmp = context.scene.geodesic_not_yet_called
+ if tmp:
+ context.scene.geodesic_not_yet_called = False
+ self.execute(context)
+ return {'FINISHED'}
+
+def creategeo(polytype,orientation,parameters):
+ geo = None
+ if polytype == "Tetrahedron":
+ if orientation == "PointUp":
+ geo = geodesic_classes_259.tetrahedron(parameters)
+ elif orientation == "EdgeUp":
+ geo=geodesic_classes_259.tetraedge(parameters)
+ elif orientation == "FaceUp":
+ geo=geodesic_classes_259.tetraface(parameters)
+ elif polytype == "Octahedron":
+ if orientation == "PointUp":
+ geo=geodesic_classes_259.octahedron(parameters)
+ elif orientation == "EdgeUp":
+ geo=geodesic_classes_259.octaedge(parameters)
+ elif orientation == "FaceUp":
+ geo=geodesic_classes_259.octaface(parameters)
+ elif polytype == "Icosahedron":
+ if orientation == "PointUp":
+ geo=geodesic_classes_259.icosahedron(parameters)
+ elif orientation == "EdgeUp":
+ geo=geodesic_classes_259.icoedge(parameters)
+ elif orientation == "FaceUp":
+ geo=geodesic_classes_259.icoface(parameters)
+ return geo
+
+basegeodesic,fmeshname,smeshname,hmeshname,outputmeshname,strutimpmesh,hubimpmesh = [None]*7
+
+def finalfill(source,target):
+ count=0
+ for point in source.verts:
+ newvert = vefm_259.vertex(point.vector)
+ target.verts.append(newvert)
+ point.index = count
+ count += 1
+ for facey in source.faces:
+ row=len(facey.vertices)
+ if row >= 5:
+ newvert = vefm_259.average(facey.vertices).centroid()
+ centre = vefm_259.vertex(newvert.vector)
+ target.verts.append(centre)
+ for i in range(row):
+ if i == row - 1:
+ a = target.verts[facey.vertices[-1].index]
+ b = target.verts[facey.vertices[0].index]
+ else:
+ a = target.verts[facey.vertices[i].index]
+ b = target.verts[facey.vertices[i+1].index]
+ c = centre
+ f = [a,b,c]
+ target.faces.append(f)
+ else:
+ f = []
+ for j in range(len(facey.vertices)):
+
+ a = facey.vertices[j]
+ f.append(target.verts[a.index])
+ target.faces.append(f)
+
+###for error messages
+class DialogOperator(bpy.types.Operator):
+ bl_idname = "object.dialog_operator"
+ bl_label = "INFO"
+
+ def draw(self,context):
+ layout = self.layout
+ message = context.scene.error_message
+ col = layout.column()
+ tmp = message.split("\n")
+ for el in tmp:
+ col.label(el)
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self)
+
+
+######### register all
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD b/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD
new file mode 100644
index 0000000..cdf5422
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/tmp/GD_0.GD
@@ -0,0 +1,115 @@
+facetype_menu,'3',
+facetoggle,True,
+face_use_imported_object,False,
+facewidth,0.26006004214286804,
+fwtog,True,
+faceheight,1.0,
+fhtog,False,
+face_detach,False,
+fmeshname,'defaultface',
+geodesic_types,'Geodesic',
+import_mesh_name,'None',
+base_type,'Octahedron',
+orientation,'EdgeUp',
+geodesic_class,'Class 1',
+tri_hex_star,'tri',
+spherical_flat,'spherical',
+use_imported_mesh,False,
+cyxres,5,
+cyyres,5,
+cyxsz,1.0,
+cyysz,1.0,
+cyxell,1.0,
+cygap,1.0,
+cygphase,0.0,
+paxres,5,
+payres,5,
+paxsz,0.30000001192092896,
+paysz,1.0,
+paxell,1.0,
+pagap,1.0,
+pagphase,0.0,
+ures,8,
+vres,8,
+urad,1.0,
+vrad,0.25,
+uellipse,1.0,
+vellipse,1.0,
+upart,1.0,
+vpart,1.0,
+ugap,0.0,
+vgap,0.0,
+uphase,0.0,
+vphase,0.0,
+uexp,0.0,
+vexp,0.0,
+usuper,2.0,
+vsuper,2.0,
+utwist,0.0,
+vtwist,0.0,
+bures,8,
+bvres,8,
+burad,1.0,
+bupart,1.0,
+bvpart,1.0,
+buphase,0.0,
+bvphase,0.0,
+buellipse,1.0,
+bvellipse,1.0,
+grxres,5,
+gryres,2,
+grxsz,2.0,
+grysz,1.0,
+cart,0,
+frequency,2,
+eccentricity,1.0,
+squish,1.0,
+radius,2.8912599086761475,
+squareness,2.0,
+squarez,2.0,
+baselevel,5,
+dual,False,
+rotxy,0.0,
+rotz,0.0,
+uact,False,
+vact,False,
+um,3.0,
+un1,1.0,
+un2,1.0,
+un3,1.0,
+ua,1.0,
+ub,4.0,
+vm,1.0,
+vn1,1.0,
+vn2,1.0,
+vn3,1.0,
+va,1.0,
+vb,1.0,
+uturn,0.0,
+vturn,0.0,
+utwist,0.0,
+vtwist,0.0,
+struttype,0,
+struttoggle,True,
+strutimporttoggle,False,
+strutimpmesh,'GD_mesh',
+strutwidth,1.0,
+swtog,False,
+strutheight,1.0,
+shtog,False,
+strutshrink,1.0,
+sstog,False,
+stretch,1.0,
+lift,0.0010000000474974513,
+smeshname,'defaultstrut',
+hubtype,True,
+hubtoggle,False,
+hubimporttoggle,False,
+hubimpmesh,'None',
+hubwidth,1.0,
+hwtog,False,
+hubheight,1.0,
+hhtog,False,
+hublength,1.0,
+hstog,False,
+hmeshname,'None',
diff --git a/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD b/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD
new file mode 100644
index 0000000..a75eafb
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/tmp/GD_start.GD
@@ -0,0 +1,115 @@
+facetype_menu,'0',
+facetoggle,False,
+face_use_imported_object,False,
+facewidth,0.5,
+fwtog,False,
+faceheight,1.0,
+fhtog,False,
+face_detach,False,
+fmeshname,'defaultface',
+geodesic_types,'Geodesic',
+import_mesh_name,'None',
+base_type,'Tetrahedron',
+orientation,'PointUp',
+geodesic_class,'Class 1',
+tri_hex_star,'tri',
+spherical_flat,'spherical',
+use_imported_mesh,False,
+cyxres,5,
+cyyres,5,
+cyxsz,1.0,
+cyysz,1.0,
+cyxell,1.0,
+cygap,1.0,
+cygphase,0.0,
+paxres,5,
+payres,5,
+paxsz,0.30000001192092896,
+paysz,1.0,
+paxell,1.0,
+pagap,1.0,
+pagphase,0.0,
+ures,8,
+vres,8,
+urad,1.0,
+vrad,0.25,
+uellipse,1.0,
+vellipse,1.0,
+upart,1.0,
+vpart,1.0,
+ugap,0.0,
+vgap,0.0,
+uphase,0.0,
+vphase,0.0,
+uexp,0.0,
+vexp,0.0,
+usuper,2.0,
+vsuper,2.0,
+utwist,0.0,
+vtwist,0.0,
+bures,8,
+bvres,8,
+burad,1.0,
+bupart,1.0,
+bvpart,1.0,
+buphase,0.0,
+bvphase,0.0,
+buellipse,1.0,
+bvellipse,1.0,
+grxres,5,
+gryres,2,
+grxsz,2.0,
+grysz,1.0,
+cart,0,
+frequency,1,
+eccentricity,1.0,
+squish,1.0,
+radius,1.0,
+squareness,2.0,
+squarez,2.0,
+baselevel,5,
+dual,False,
+rotxy,0.0,
+rotz,0.0,
+uact,False,
+vact,False,
+um,3.0,
+un1,1.0,
+un2,1.0,
+un3,1.0,
+ua,1.0,
+ub,4.0,
+vm,1.0,
+vn1,1.0,
+vn2,1.0,
+vn3,1.0,
+va,1.0,
+vb,1.0,
+uturn,0.0,
+vturn,0.0,
+utwist,0.0,
+vtwist,0.0,
+struttype,0,
+struttoggle,False,
+strutimporttoggle,False,
+strutimpmesh,'None',
+strutwidth,1.0,
+swtog,False,
+strutheight,1.0,
+shtog,False,
+strutshrink,1.0,
+sstog,False,
+stretch,1.0,
+lift,0.0,
+smeshname,'defaultstrut',
+hubtype,True,
+hubtoggle,False,
+hubimporttoggle,False,
+hubimpmesh,'None',
+hubwidth,1.0,
+hwtog,False,
+hubheight,1.0,
+hhtog,False,
+hublength,1.0,
+hstog,False,
+hmeshname,'None',
diff --git a/release/scripts/addons_contrib/geodesic_domes/vefm_259.py b/release/scripts/addons_contrib/geodesic_domes/vefm_259.py
new file mode 100644
index 0000000..986f97b
--- /dev/null
+++ b/release/scripts/addons_contrib/geodesic_domes/vefm_259.py
@@ -0,0 +1,1218 @@
+# vert class and overloading experiments
+import bpy
+import math
+from math import sqrt,acos,pi,sin,cos,atan,tan,fabs
+from mathutils import Vector
+
+#dbg = True
+sgn = lambda x : (x>0) - (x<0) #missing signum functin in Python
+try:
+ breakpoint = bpy.types.bp.bp
+except:
+ pass
+
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+
+from collections import Counter
+
+'''PKHG not needed?
+def find_twice_vert(l1,l2):
+ tmp = [el for el in l1]
+ tmp.extend(l2)
+ tt = Counter(tmp)
+ result = max(tt.keys(),key = lambda k:tt[k])
+ print("twice give", result)
+ return result
+'''
+
+def vefm_add_object(selfobj):
+ for i in range(len(selfobj.verts)):
+ selfobj.verts[i].index = i
+ v = [el.vector for el in selfobj.verts]
+# e = [[edge.a.index,edge.b.index] for edge in selfobj.edges]
+ e = []
+ if type(selfobj.faces[0]) == type([]):
+# print("\n=========== selfobj.faces[0]", selfobj.faces[0],type(selfobj.faces[0]))
+#PKHG should be a list of vertices, which have an index
+ f = [[v.index for v in face] for face in selfobj.faces]
+ else:
+ f = [[v.index for v in face.vertices] for face in selfobj.faces]
+#PKHG_DBG_25-11 print("dbg 25-11 f list =",f)
+#PKHG_DBG_25-11 print("dgb 25-11 v list +",v)
+ m = bpy.data.meshes.new(name= selfobj.name)
+ m.from_pydata(v, e, f )
+ # useful for development when the mesh may be invalid.
+#PKHG not needed, as ideasman_42 says m.validate(verbose = False)
+ object_data_add(bpy.context, m, operator = None)
+#???ERROR PKHG in AddSelf setMaterial(bpy.context.active_object,pkhg_red_color)
+
+#extra test phase
+
+
+
+
+class vertex:
+
+ def __init__(self,vec=(0,0,0)): #default x = 0,y = 0,z = 0):
+ self.vector = Vector(vec)
+ self.length = self.vector.length
+ self.index = 0
+ self.normal = 0
+ self.edges = []
+ self.faces = []
+ self.boundary = 0
+
+ def findlength(self):
+ self.length = self.vector.length
+
+ def normalize(self):
+ self.findlength()
+ if self.length > 0:
+ tmp = 1.0/self.length
+ self.vector = tmp * self.vector
+# self.x = self.vector[0] #(1.0/self.length)
+# self.y = self.vector[1] #(1.0/self.length)
+# self.z = self.vector[2] #(1.0/self.length)
+ self.length = 1.0
+
+ def findnormal(self):
+ target = []
+ if self.faces[:] == []:
+ print("vefm vertex L81 pkhg:*****ERROR**** findnormal has no faces")
+ return
+ for currentface in self.faces:
+ target.append(currentface.normal)
+ self.normal = average(target).centroid()
+ self.normal.findlength()
+ if self.length == 0:
+ print("******ERROR*** length zero in findnormal, j = (0,1,0) replcaced")
+ self.normal = vertex((0,1,0))
+ self.normal.normalize()
+
+ def clockwise(self): #PKHG self is a vertex
+ if self.boundary:
+ start = self.boundarystart() #???PKHG TODO error
+ else:
+ start = self.faces[0]
+#PKHG TODO do understand 21-11 solves starify of a normal tetrahedron
+# start = self.faces[0] #PKHG TODO see error above!
+# start.docorners() #PKHG????
+ self.tempedges = []
+ self.tempfaces = []
+ for i in range(len(self.edges)):
+ #print("\n----------------------voor breakpunt pkhg in clockwise")
+ #breakpoint(locals(), self.index == 0)
+ self.tempfaces.append(start)
+ for corner in start.corners:
+ if corner[0] is not self:
+ pass
+ elif corner[0] is self:
+ self.tempedges.append(corner[1])
+ nextedge = corner[2]
+ for facey in nextedge.faces:
+ if facey is not start:
+ start = facey
+ break
+ self.edges = self.tempedges
+ self.faces = self.tempfaces
+
+ def boundarystart(self):
+ #PKHG not implemented, needed?
+ pass
+
+#???PKHG TODO why are add and sub different? Solved check the two cases used
+ def __add__(self,other):
+ if isinstance(other, Vector):
+ tmp = self.vector + other
+ else:
+ tmp = self.vector + other.vector
+ return vertex(tmp)
+
+ def __sub__(self,other):
+ if isinstance(other, Vector):
+ tmp = self.vector - other
+ else:
+ tmp = self.vector - other.vector
+# tmp = self.vector - other.vector
+ return vertex(tmp)
+
+ def __mul__(self,other):
+ tmp = self.vector * other
+ return vertex(tmp)
+
+ def __truediv__(self,other):
+ denom = 1.0/other
+ tmp = self.vector * denom
+ return (tmp)
+
+ def negative(self):
+ return vertex(-self.vector)
+
+class crossp:
+ ## Takes in two vertices(vectors), returns the cross product.
+ def __init__(self,v1,v2):
+ self.v1 = v1
+ self.v2 = v2
+#
+ def docrossproduct(self):
+ tmp = self.v1.vector.cross(self.v2.vector)
+ return vertex(tmp)
+
+class average:
+ ## Takes a list of vertices and returns the average. If two verts are passed, returns midpoint.
+ def __init__(self,vertlist):
+ self.vertlist = vertlist
+
+ def centroid(self):
+ tmp = Vector()
+#PKHG avoid emptylist problems
+ divisor = 1.0
+ nr_vertices = len(self.vertlist)
+ if nr_vertices > 1:
+ divisor = 1.0 / len(self.vertlist)
+ elif nr_vertices == 0:
+ print("\n***WARNING*** empty list in vefm_259.centroid! L180")
+ for vert in self.vertlist:
+ tmp = tmp + vert.vector
+ tmp = tmp * divisor
+ return vertex(tmp)
+
+class edge:
+ def __init__(self,a = 0,b = 0):
+ self.a = a
+ self.b = b
+ self.index = 0
+ self.normal = 0
+ self.cross = 0
+ self.unit = 0
+ self.faces = []
+ self.vect = 0 #PKHG becomes b - a
+ self.vectb = 0 #PKHG becomes a - b
+# self.length = 0
+ self.boundary = 0
+ self.findvect()
+# print("vect len before",self.vect.length)
+ self.findlength()
+# print("vect after",self.vect.length)
+
+ def findvect(self):
+ self.vect = self.b - self.a
+ self.vectb = self.a - self.b
+
+ def findlength(self):
+ self.vect.findlength()
+ self.vectb.length = self.vect.length
+
+ def findnormal(self):
+
+ if self.boundary:
+ self.normal = self.faces[0].normal #average([self.a,self.b]).centroid()
+ else:
+ self.normal = average([self.faces[0].normal,self.faces[1].normal]).centroid()
+ self.normal.normalize()
+# def findother(self,vertindex):
+#
+# if vertindex==self.a:
+#
+# return self.b
+#
+# else:
+# return self.a
+## different classes for 3,4,> sides??
+
+class face:
+ def __init__(self,vertices=[]):
+#PKHG ok good for tri's at least print("\n ========= vefm L226======dbg face vertices = ",vertices)
+ self.vertices = vertices ## List of vertex instances.
+ self.edges=[] ## Will be filled with the sides of the face.
+ self.boundary = 0 ## When set will have bool and id of edge concerned.
+ self.normal = 0 ## Face normal found through cross product.
+ self.corners=[]
+ self.spokes=[] ## Vectors of the bisecting angles from each corner to the centre + dotproduct.
+ self.index = 0
+
+ #dotproduct is misleading name, it is the hook between two vectors!
+ def dotproduct(self,v1,v2):
+ v1.findlength()
+ v2.findlength()
+ if v1.length == 0 or v2.length == 0:
+ print("\nPKHG warning, =====vefm_259 dotproduct L245====== at least one zero vector 0 used")
+ return 0 # pi * 0.25 #PKHT_TEST04nov pi * 0.25 #45 degrees??? #PKHG???TODO
+ dot = v1.vector.dot(v2.vector)
+ costheta = dot / (v1.length * v2.length)
+ tmp = acos(costheta)
+ return tmp
+
+ def orderedges(self):
+ temp=[]
+ finish = len(self.vertices)
+ for i in range(finish):
+ current = self.vertices[i]
+ if i==finish-1:
+ next = self.vertices[0]
+ else:
+ next = self.vertices[i+1]
+ for edge in face.edges:
+ if edge.a==current and edge.b==next:
+ face.clockw.append(edge.vect)
+ face.aclockw.append(edge.vectb)
+ temp.append(edge)
+ if edge.b==current and edge.a==next:
+ face.clockw.append(edge.vectb)
+ face.aclockw.append(edge.vect)
+ temp.append(edge)
+ for edge in face.edges:
+ if edge.a==current and edge.b==next:
+ face.clockw.append(edge.vect)
+ face.aclockw.append(edge.vectb)
+ temp.append(edge)
+ if edge.b==current and edge.a==next:
+ face.clockw.append(edge.vectb)
+ face.aclockw.append(edge.vect)
+ temp.append(edge)
+ face.vertices = temp
+
+
+ def docorners(self):
+ ## This function identifies and stores the vectors coming from each vertex
+ ## allowing easier calculation of cross and dot products.
+ finish = len(self.vertices)
+ '''
+ which = None
+ occur1 = None
+ occur2 = None
+ if finish == 3 and len(self.edges) == 2 :
+ print("\n***ERROR*** only two edges should be three")
+ # return
+ occur1 = [self.vertices.index(self.edges[0].a),self.vertices.index(self.edges[0].b)]
+ occur2 = [self.vertices.index(self.edges[1].a),self.vertices.index(self.edges[1].b)]
+ #occur2 = [self.edges[1].a.index, self.edges[1].b.index]
+ twice = find_twice_vert(occur1,occur2)
+ occur1.remove(twice)
+ occur2.remove(twice)
+ #new_edge = edge(self.vertices[occur1[0]],self.vertices[occur2[0]])
+ #self.edges.append(new_edge)
+ '''
+ for i in range(finish):
+ current = self.vertices[i]
+ if i==finish-1:
+ next = self.vertices[0]
+ else:
+ next = self.vertices[i+1]
+ if i==0:
+ previous = self.vertices[-1]
+ else:
+ previous = self.vertices[i-1]
+ corner=[current] #PKHG new for each vertex = current
+ #corner = current
+ rightedge = None
+ leftedge = None
+ teller = -1
+ for edge in self.edges:
+ # if finish == 3 and len(self.edges) == 2 and i == 2:
+ # return
+ teller += 1
+ currentinfo = (current, edge.a, edge.b, edge.a is current, edge.b is current)
+ #next and previous are vertex with respect to ith vertex
+ if edge.a is current or edge.b is current: ## does this edge contain our current vert
+ if edge.a is current:
+ if edge.b is next:
+ rightedge = edge
+ rightvect = edge.vect
+ if edge.b is previous:
+ leftedge = edge
+ leftvect = edge.vect
+ elif edge.b is current:
+ if edge.a is next:
+ rightedge = edge
+ rightvect = edge.vectb
+ if edge.a is previous:
+ leftedge = edge
+ leftvect = edge.vectb
+ corner.append(rightedge)
+ corner.append(leftedge)
+ if rightedge and leftedge:
+ '''
+ if rightedge:
+ print("rightedge",rightedge.index)
+ if leftedge:
+ print( "leftedge",leftedge.index)
+ print("corner",corner)
+ #'''
+ dotty = self.dotproduct(rightvect,leftvect)
+ corner.append(dotty)
+ self.corners.append(corner)
+
+
+ def findnormal(self):
+ one = self.corners[1][2]
+ two = self.corners[1][1]
+ if one.a is self.corners[1][0]:
+ one = one.vect
+ elif one.b is self.corners[1][0]:
+ one = one.vectb
+ if two.a is self.corners[1][0]:
+ two = two.vect
+ elif two.b is self.corners[1][0]:
+ two = two.vectb
+ self.normal = crossp(one,two).docrossproduct()
+ self.normal.findlength()
+ self.normal.normalize()
+
+ def dospokes(self):
+#PKHG_OK_24-11 print("\n============vefm L375==============dbg, dospokes called corners =", self.corners[:])
+ for corner in self.corners:
+ vert = corner[0]
+ right = corner[1]
+ left = corner[2]
+ if right.a is vert:
+ one = vertex(right.vect.vector)
+ elif right.b is vert:
+ one = vertex(right.vectb.vector)
+ if left.a is vert:
+ two = vertex(left.vect.vector)
+ elif left.b is vert:
+ two = vertex(left.vectb.vector)
+
+ one.normalize()
+ two.normalize()
+ spoke = one+two
+ spoke.normalize()
+ self.spokes.append(spoke)
+
+ def artspokes(self):
+ centre = average(self.vertices).centroid()
+ for point in self.vertices:
+ newedge = edge(point,centre)
+ spokes.append(newedge)
+
+class mesh:
+ def __init__(self , name="GD_mesh"):
+ self.name = name #pkhg test phase at least ;-)
+ self.verts=[]
+ self.edges=[]
+ self.faces=[]
+ self.edgeflag = 0
+ self.faceflag = 0
+ self.vertexflag = 0
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+ self.boundaryflag = 0
+ self.vertnormalflag = 0
+ self.edgenormalflag = 0
+ self.facenormalflag = 0
+ #found in geodesic.py ??? needed for test here!
+ self.a45 = pi * 0.25
+ self.a90 = pi * 0.5
+ self.a180 = pi
+ self.a270 = pi * 1.5
+ self.a360 = pi * 2
+
+
+ def power(self,a,b): ## Returns a power, including negative numbers
+ result = sgn(a)*(abs(a)**b)
+ return result
+
+ def sign(self,d): ## Works out the sign of a number.
+ return sgn(d)
+
+ def ellipsecomp(self,efactor,theta):
+ if theta==self.a90:
+ result = self.a90
+ elif theta==self.a180:
+ result = self.a180
+ elif theta==self.a270:
+ result = self.a270
+ elif theta==self.a360:
+ result = 0.0
+ else:
+ result = atan(tan(theta)/efactor**0.5)
+ if result<0.0:
+ if theta>self.a180:
+ result = result+self.a180
+ elif theta<self.a180:
+ result = result+self.a180
+ ## Fishy - check this.
+ if result>0.0:
+ if theta>self.a180:
+ result = result+self.a180
+ elif theta<self.a180:
+ result = result
+ return result
+
+ def connectivity(self):
+ self.dovertedge()
+ self.dovertface()
+ self.dofaceedge()
+ self.boundary()
+
+ def superell(self,n1,uv,turn):
+ t1 = sin(uv+turn)
+ t1 = abs(t1)
+ t1 = t1**n1
+ t2 = cos(uv+turn)
+ t2 = abs(t2)
+ t2 = t2**n1
+ r = self.power(1.0/(t1+t2),(1.0/n1))
+ return r
+
+#PKHG changed according to http://de.wikipedia.org/wiki/Superformel
+#a and b a semi-diameter
+ def superform(self,m,n1,n2,n3,uv,a,b,twist):
+ t1 = cos(m*(uv+twist)*.25) / a
+ t1 = abs(t1)
+ t1 = t1**n2
+ t2 = sin(m*(uv+twist)*.25) / b
+ t2 = abs(t2)
+ t2 = t2**n3
+ r = self.power(1.0/(t1+t2),n1)
+ return r
+
+ def dovertedge(self):
+ if not self.vertedgeflag:
+ for vert in self.verts:
+ vert.edges = []
+ for currentedge in self.edges:
+ currentedge.a.edges.append(currentedge)
+ currentedge.b.edges.append(currentedge)
+ self.vertedgeflag = 1
+
+ def dovertface(self):
+ if not self.vertfaceflag:
+ for vert in self.verts:
+ vert.faces = []
+ for face in self.faces:
+ for vert in face.vertices:
+ vert.faces.append(face)
+ self.vertfaceflag = 1
+
+ def dofaceedge(self):
+ self.dovertedge() ## just in case they haven't been done
+ self.dovertface() ##
+ if not self.faceedgeflag:
+ for edge in self.edges:
+ edge.faces=[]
+ for face in self.faces:
+ face.edges = []
+ for face in self.faces:
+ finish = len(face.vertices)
+ for i in range(finish):
+ current = face.vertices[i]
+ if i == finish-1:
+ next = face.vertices[0]
+ else:
+ next = face.vertices[i+1]
+ for edge in current.edges:
+ if edge.a is current or edge.b is current:
+ if edge.b is next or edge.a is next:
+ edge.faces.append(face)
+ face.edges.append(edge)
+ self.faceedgeflag = 1
+
+ def boundary(self):
+ if not self.boundaryflag:
+ for edge in self.edges:
+ if len(edge.faces) < 2:
+ edge.boundary = 1
+ edge.faces[0].boundary = 1
+ edge.a.boundary = 1
+ edge.b.boundary = 1
+
+## The functions below turn the basic triangular faces into
+## hexagonal faces, creating the buckyball effect.
+#PKHG seems to work only for meshes with tri's ;-) ??!!
+ def hexify(self):
+ self.hexverts=[]
+ self.hexedges=[]
+ self.hexfaces=[]
+ #PKHG renumbering the index of the verts
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ #PKHG renumbering the index of the edges
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ #PKHG self=> dovertedge, dovertface, dofaceedge, boundary()
+ self.connectivity()
+ hexvert_counter = 0
+ for edge in self.edges:
+# print("21-11 >>>>>>>>>>>>>>dbg hexify L552")
+# breakpoint(locals(),True)
+ self.hexshorten(edge,hexvert_counter)
+ hexvert_counter += 2 #PKHG two new vertices done
+#PKHG 21-11 print("21-11 <<<<<<<<<<<<<<< na hexshorten L557", hexvert_counter)
+#PKHG 21-11 breakpoint(locals(),True)
+
+ for face in self.faces:
+ self.makehexfaces(face)
+
+ for vert in self.verts:
+ vert.clockwise()
+ self.hexvertface(vert)
+ self.verts = self.hexverts
+ self.edges = self.hexedges
+ self.faces = self.hexfaces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+#PKHG_DBG print("\n ==========================self hexified I hope")
+ #breakpoint(locals(),True)
+
+ def hexshorten(self,currentedge, hexvert_counter):
+ third = vertex(currentedge.vect/3.0)
+ newvert1 = vertex(currentedge.a.vector)
+ newvert2 = vertex(currentedge.b.vector)
+ newvert1 = newvert1 + third
+ newvert1.index = hexvert_counter
+ newvert2 = newvert2 - third
+ newvert2.index = hexvert_counter + 1 #PKHG caller adjusts +=2
+ newedge = edge(newvert1,newvert2)
+ newedge.index = currentedge.index
+ self.hexverts.append(newvert1)
+ self.hexverts.append(newvert2)
+ self.hexedges.append(newedge)
+
+ def makehexfaces(self,currentface):
+ vertices=[]
+ currentface.docorners()
+ for corner in currentface.corners:
+ vert = corner[0]
+ rightedge = corner[1]
+ leftedge = corner[2]
+ lid = leftedge.index
+ rid = rightedge.index
+
+ if leftedge.a is vert:
+ vertices.append(self.hexedges[lid].a)
+ elif leftedge.b is vert:
+ vertices.append(self.hexedges[lid].b)
+
+ if rightedge.a is vert:
+ vertices.append(self.hexedges[rid].a)
+ elif rightedge.b is vert:
+ vertices.append(self.hexedges[rid].b)
+
+ newface = face(vertices)
+ newedge1 = edge(vertices[0],vertices[1])
+ newedge2 = edge(vertices[2],vertices[3])
+ newedge3 = edge(vertices[4],vertices[5])
+ self.hexfaces.append(newface)
+ self.hexedges.append(newedge1)
+ self.hexedges.append(newedge2)
+ self.hexedges.append(newedge3)
+
+ def hexvertface(self,vert):
+ vertices=[]
+ for edge in vert.edges:
+ eid = edge.index
+ if edge.a is vert:
+ vertices.append(self.hexedges[eid].a)
+ elif edge.b is vert:
+ vertices.append(self.hexedges[eid].b)
+ newface = face(vertices)
+ self.hexfaces.append(newface)
+
+ def starify(self):
+ self.starverts=[]
+ self.staredges=[]
+ self.starfaces=[]
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ self.connectivity()
+ star_vert_counter = 0
+ for currentedge in self.edges:
+ newvert = average([currentedge.a,currentedge.b]).centroid()
+ newvert.index = star_vert_counter
+ star_vert_counter += 1
+ self.starverts.append(newvert)
+ star_face_counter = 0
+ star_edge_counter = 0
+ for currentface in self.faces:
+ currentface.docorners()
+ vertices=[]
+ for corner in currentface.corners:
+ vert = self.starverts[corner[1].index]
+# vert.index = star_vert_counter
+# star_vert_counter += 1
+ vertices.append(vert)
+ newface = face(vertices)
+ newface.index = star_face_counter
+ star_face_counter += 1
+ newedge1 = edge(vertices[0],vertices[1])
+ newedge1.index = star_edge_counter
+ newedge2 = edge(vertices[1],vertices[2])
+ newedge2.index = star_edge_counter + 1
+ newedge3 = edge(vertices[2],vertices[0])
+ newedge3.index = star_edge_counter + 2
+ star_edge_counter += 3
+ self.starfaces.append(newface)
+ self.staredges.append(newedge1)
+ self.staredges.append(newedge2)
+ self.staredges.append(newedge3)
+ for vert in self.verts:
+ vertices=[]
+ vert.clockwise()
+ for currentedge in vert.edges:
+ eid = currentedge.index
+ vertices.append(self.starverts[eid])
+ newface = face(vertices)
+ newface.index = star_face_counter
+ star_face_counter += 1
+ self.starfaces.append(newface)
+ self.verts = self.starverts
+ self.edges = self.staredges
+ self.faces = self.starfaces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+ def class2(self):
+ self.class2verts=[] #PKHG_??? used?
+ self.class2edges=[] #PKHG_??? used?
+ self.class2faces=[]
+
+ newvertstart = len(self.verts)
+ newedgestart = len(self.edges)
+ counter_verts = len(self.verts) #PKHG
+# for i in range(len(self.verts)):
+ for i in range(counter_verts):
+ self.verts[i].index = i
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ for i in range(len(self.faces)):
+ self.faces[i].index = i
+ self.connectivity()
+ for currentface in self.faces:
+ currentface.docorners()
+ newvert = average(currentface.vertices).centroid()
+ newvert.index = counter_verts
+#PKHG_??? 20-11
+ counter_verts += 1
+ self.verts.append(newvert)
+ newedge1 = edge(currentface.vertices[0],newvert)
+ newedge2 = edge(currentface.vertices[1],newvert)
+ newedge3 = edge(currentface.vertices[2],newvert)
+ self.edges.append(newedge1)
+ self.edges.append(newedge2)
+ self.edges.append(newedge3)
+ for currentedge in range(newedgestart):
+ self.edges[currentedge].a = self.verts[self.edges[currentedge].faces[0].index+newvertstart]
+ self.edges[currentedge].b = self.verts[self.edges[currentedge].faces[1].index+newvertstart]
+ self.edges[currentedge].findvect()
+ #breakpoint(locals(),True)
+ for currentvert in range(newvertstart):
+ vert = self.verts[currentvert]
+ vertices=[]
+ vert.clockwise()
+ for currentface in vert.faces:
+ eid = currentface.index
+#PKHG_OK print(">>>>eid = ", eid,newvertstart + eid)
+ vertices.append(self.verts[newvertstart + eid])
+ #print("21-11 L710 currentvert is=", currentvert)
+ #breakpoint(locals(),True)
+ for i in range(len(vertices)):
+ if i == len(vertices) - 1:
+ next = vertices[0]
+ else:
+ next = vertices[i+1]
+ #print("21-11 L710 i is=", i)
+ #breakpoint(locals(),True)
+ newface = face([vert,vertices[i],next])
+ self.class2faces.append(newface)
+ #self.verts = self.class2verts
+ #self.edges = self.class2edges
+ self.faces = self.class2faces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+ def dual(self):
+ self.dualverts=[]
+# self.dualedges=[]
+ self.dualfaces=[]
+#PKHG 21-11 dual problem?!
+ counter_verts = len(self.verts)
+ for i in range(counter_verts):
+ self.verts[i].index = i
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ for i in range(len(self.faces)):
+ self.faces[i].index = i
+ self.connectivity()
+ counter_verts = 0
+ for currentface in self.faces:
+ currentface.docorners()
+ newvert = average(currentface.vertices).centroid()
+ newvert.index = counter_verts #PKHG needed in >= 2.59
+ counter_verts += 1
+ self.dualverts.append(newvert)
+ for vert in self.verts:
+ vertices=[]
+ vert.clockwise()
+ for currentface in vert.faces:
+ eid = currentface.index
+ vertices.append(self.dualverts[eid])
+ newface = face(vertices)
+ self.dualfaces.append(newface)
+ for currentedge in self.edges:
+ currentedge.a = self.dualverts[currentedge.faces[0].index]
+ currentedge.b = self.dualverts[currentedge.faces[1].index]
+ self.verts = self.dualverts
+# self.edges = self.staredges
+ self.faces = self.dualfaces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+class facetype(mesh):
+ def __init__(self,basegeodesic,parameters,width,height,relative):
+ mesh.__init__(self)
+ self.detatch = parameters[0]
+ self.endtype = parameters[1]
+ self.coords = parameters[2]
+ self.base = basegeodesic
+ self.relative = relative
+ self.width = width
+
+ if not self.relative:
+ newwidth = self.findrelative()
+ self.width = width*newwidth
+ self.height = height
+ self.base.connectivity()
+ for coord in self.coords:
+ coord[0]=coord[0]*self.width
+ coord[1]=coord[1]*self.height
+ if not self.base.facenormalflag:
+ for currentface in self.base.faces:
+ # print("face normal ",currentface.normal)
+ currentface.docorners()
+ currentface.findnormal()
+ # print("face normal ",currentface.normal.x,currentface.normal.y,currentface.normal.z)
+ self.base.facenormalflag = 1
+ if self.endtype==4 and not self.base.vertnormalflag:
+ for currentvert in self.base.verts:
+ currentvert.findnormal()
+ self.base.vertnormalflag = 1
+ self.createfaces()
+
+ def findrelative(self):
+ centre = average(self.base.faces[0].vertices).centroid()
+ edgelist=[]
+ for point in self.base.faces[0].vertices:
+ newedge = edge(centre,point)
+ edgelist.append(newedge)
+ length = 0
+ for edg in edgelist:
+ extra = edg.vect.length
+ length = length+extra
+ # print("length",length,"extra",extra)
+ length = length/len(edgelist)
+ # print("find relative",length)
+ return length
+
+ def createfaces(self):
+ if not self.detatch:
+ for point in self.base.verts:
+ self.verts.append(point)
+ if self.endtype==4:
+ self.createghostverts()
+ for currentface in self.base.faces:
+ self.doface(currentface)
+
+ def createghostverts(self):
+ self.ghoststart = len(self.verts)
+ for vert in self.base.verts:
+ newvert = vert + (vert.normal * self.coords[-1][1])
+ self.verts.append(newvert)
+
+ def doface(self,candidate):
+ grid=[]
+ candidate.dospokes()
+ # print("Candidate normal",candidate.normal.x,candidate.normal.y,candidate.normal.z)
+ if not self.detatch:
+ line=[]
+ for vert in candidate.vertices:
+ line.append(vert)
+ grid.append(line)
+ else:
+ line=[]
+ for point in candidate.vertices:
+ newvert = vertex(point.vector)
+ self.verts.append(newvert)
+ line.append(newvert)
+ grid.append(line)
+ finish = len(self.coords)
+ if self.endtype==1 or self.endtype==4:
+ finish = finish-1
+ for i in range(finish):
+ up = candidate.normal*self.coords[i][1]
+ line=[]
+ for j in range(len(candidate.vertices)):
+ dotfac = candidate.corners[j][3]*0.5
+ vec=(candidate.spokes[j]*(self.coords[i][0]/sin(dotfac))) #self.coords[i][0])#(self.coords[i][0]/sin(dotfac)))#+up
+ newvert = candidate.vertices[j]+vec+up
+ line.append(newvert)
+ self.verts.append(newvert)
+ grid.append(line)
+ if self.endtype==4:
+ line=[]
+ for i in range(len(candidate.vertices)):
+ vert = self.verts[candidate.vertices[i].index+self.ghoststart]
+ line.append(vert)
+ # self.verts.append(vert)
+ grid.append(line)
+ for line in grid:
+ line.append(line[0])
+ if self.endtype==3:
+ grid.append(grid[0])
+ for i in range(len(grid)-1):
+ for j in range(len(grid[i])-1):
+ one = grid[i][j]
+ two = grid[i][j+1]
+ three = grid[i+1][j+1]
+ four = grid[i+1][j]
+ newface = face([one, two, three, four])
+ self.faces.append(newface)
+ if self.endtype==2:
+ finalfaceverts = grid[-1]
+ newface = face(finalfaceverts[:-1])
+ self.faces.append(newface)
+ if self.endtype==1:
+ lastvert = average(candidate.vertices).centroid()
+ up = candidate.normal*self.coords[-1][1]
+ newvert = lastvert+up
+ self.verts.append(newvert)
+ ring = grid[-1]
+ for i in range(len(ring)-1):
+ newface = face([newvert,ring[i],ring[i+1]])
+ self.faces.append(newface)
+
+class importmesh(mesh):
+ def __init__(self,meshname,breakquadflag):
+ mesh.__init__(self)
+# print("mesh and breakquad",meshname,breakquadflag)
+# impmesh = NMesh.GetRawFromObject(meshname)
+ impmesh = bpy.data.objects[meshname]
+ copied_mesh = None
+ if breakquadflag:
+ name = impmesh.name
+#PKHG???needed???NO 3-11-2011 impmesh.name = "Original_" + name
+ impmesh.name = name
+#PKHG TODO use a copy? no not necessary bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'}, TRANSFORM_OT_translate={"value":(0, 0,0}))
+#PKHG TODO use a copy? copied_mesh = bpy.context.active_object
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.quads_convert_to_tris()
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ for v in impmesh.data.vertices:
+ vert = vertex(v.co)
+ vert.index = v.index
+ self.verts.append(vert)
+#PKHG verts is now a list of vertex, so to say a copy of the Vectors
+
+#PKHG edges
+ for e in impmesh.data.edges:
+ tmp = []
+ for vert in e.vertices:
+ a = self.verts[vert]
+ tmp.append(a)
+ newedge = edge(tmp[0],tmp[1])
+ newedge.index = e.index
+ self.edges.append(newedge)
+#PKHG faces with out bmesh replace next line polygons by faces
+ for f in impmesh.data.polygons:
+ temp=[]
+ for vert in f.vertices: #PKHG a list! of indices
+ a = self.verts[vert] #PKHG verts contains already vertex objects
+ temp.append(a)
+ newface = face(temp)
+ newface.index = f.index #indexcount
+ self.faces.append(newface)
+ self.dovertedge()
+ self.dovertface()
+ self.temp=[]
+
+ for i in range(len(self.verts)):
+ self.temp.append([])
+ self.verts[i].index = i
+ for i in range(len(self.verts)):
+ target = self.surroundingverts(self.verts[i])
+ for j in range(len(target)): ## go through those verts
+ temptarg = self.temp[target[j].index]
+ flag = 0 ## set a flag up
+
+ for k in range(len(temptarg)): ## go through temp list for each of those verts
+
+ if temptarg[k]==i: ## if we find a match to the current vert...
+ flag = 1 ## raise the flag
+
+ if flag==0: ## if there is no flag after all that...
+ self.temp[target[j].index].append(i) ## add current vert to temp list of this surrounding vert
+ self.temp[i].append(target[j].index) ## add this surrounding vert to the current temp list
+ newedge = edge(self.verts[i],self.verts[target[j].index])
+ self.edges.append(newedge) ## add the newly found edge to the edges list
+
+ for edg in self.edges:
+ edg.findvect()
+ self.vertedgeflag = 0
+ self.vertedgeflag = 0
+ self.connectivity()
+#PKHG_DBG_OK print("\n======= mesh imported")
+
+ def surroundingverts(self,vert):
+ """ Find the verts surrounding vert"""
+ surround=[] ## list to be filled and returned
+ for faces in vert.faces: ## loop through faces attached to vert
+ finish = len(faces.vertices)
+ for i in range(finish):
+ if i==finish-1:
+ next = faces.vertices[0]
+ else:
+ next = faces.vertices[i+1]
+ if vert == faces.vertices[i]:
+ surround.append(next)
+ return surround
+
+ def breakquad(self,quad_face):
+ """ turn quads into triangles"""
+ distance1 = quad_face.vertices[0]-quad_face.vertices[2]
+ distance2 = quad_face.vertices[1]-quad_face.vertices[3]
+ distance1.findlength()
+ distance2.findlength()
+ if abs(distance1.length)<abs(distance2.length):
+ self.faces[quad_face.index]=face([quad_face.vertices[0],quad_face.vertices[1],quad_face.vertices[2]])
+ self.faces.append(face([quad_face.vertices[0],quad_face.vertices[2],quad_face.vertices[3]]))
+ else:
+ self.faces[quad_face.index]=face([quad_face.vertices[0],quad_face.vertices[1],quad_face.vertices[3]])
+ self.faces.append(face([quad_face.vertices[1],quad_face.vertices[2],quad_face.vertices[3]]))
+
+
+class strut(mesh):
+ def __init__(self,base,struttype,width,height,length,widthtog,heighttog,lengthtog,meshname,stretchflag,lift):
+ mesh.__init__(self)
+ ## put in strut prep stuff here
+ if struttype==None:
+ return
+ total = 0
+ divvy = len(base.faces[0].edges)
+ for lengf in base.faces[0].edges:
+ lengf.vect.findlength()
+ total = total+lengf.vect.length
+ yardstick = total/divvy
+ if widthtog:
+ self.width = width
+ else:
+ self.width = width * yardstick
+ if heighttog:
+ self.height = height
+ else:
+ self.height = height*yardstick
+ if lengthtog:
+ self.shrink = length
+ else:
+ self.shrink = length * yardstick
+ if not base.facenormalflag:
+ for currentface in base.faces:
+ currentface.docorners()
+ currentface.findnormal()
+ base.facenormalflag = 1
+ for edj in base.edges:
+ edj.findnormal()
+ side = edge(edj.a,edj.b)
+ edj.unit = side.vect
+ edj.unit.normalize()
+ edj.cross = crossp(edj.normal,edj.unit).docrossproduct()
+ template = importmesh(meshname,0)
+ maxx = 0
+ minx = 0
+ for vert in template.verts:
+# if vert.x>maxx:
+ if vert.vector.x > maxx:
+# maxx = vert.x
+ maxx = vert.vector.x
+# if vert.x<minx:
+ if vert.vector.x < minx:
+# minx = vert.x
+ minx = vert.vector.x
+ for edj in base.edges:
+ start = len(self.verts)
+ centre = average([edj.a,edj.b]).centroid()
+ split = edj.vect.length/2
+ #PKHG no division by zero!!
+ tmp = 1.0
+ if maxx != minx:
+ tmp = 1.0/(maxx - minx)
+# dubbl = edj.vect.length/(maxx-minx)
+ dubbl = edj.vect.length * tmp
+ #PKHG end no division by zero!!
+ diffplus = split-maxx
+ diffminus=-split-minx
+ for point in template.verts:
+# ay=(edj.normal*point.z*self.height)+(edj.normal*lift)
+ ay=(edj.normal * point.vector.z * self.height) + (edj.normal * lift)
+# ce = edj.cross * point.y * self.width
+ ce = edj.cross * point.vector.y * self.width
+ if stretchflag:
+# be = edj.unit*self.shrink*dubbl*point.x
+ be = edj.unit * self.shrink * dubbl * point.vector.x
+ else:
+# if point.x > 0.0:
+ if point.vector.x > 0.0:
+# be = edj.unit * self.shrink * (point.x + diffplus)
+ be = edj.unit * self.shrink * (point.vector.x + diffplus)
+# elif point.x < 0.0:
+ elif point.vector.x < 0.0:
+# be = edj.unit * self.shrink * (point.x + diffminus)
+ be = edj.unit * self.shrink * (point.vector.x + diffminus)
+# elif point.x == 0.0:
+ elif point.vector.x == 0.0:
+# be = edj.unit * self.shrink * point.x
+ be = edj.unit * self.shrink * point.vector.x
+ de = ay + be + ce
+ newvert = centre + de
+ self.verts.append(newvert)
+ for edjy in template.edges:
+ one = edjy.a.index+start
+ two = edjy.b.index+start
+ newedge = edge(self.verts[one],self.verts[two])
+ self.edges.append(newedge)
+ for facey in template.faces:
+ faceverts=[]
+ for verty in facey.vertices:
+ index = verty.index+start
+ faceverts.append(self.verts[index])
+ newface = face(faceverts)
+ self.faces.append(newface)
+ self.vertedgeflag = 0
+ self.vertedgeflag = 0
+ self.connectivity()
+
+class hub(mesh):
+ def __init__(self,base,hubtype,width,height,length,widthtog,heighttog,lengthtog,meshname):
+ mesh.__init__(self)
+ self.width = 1.0
+ self.height = 1.0
+ self.shrink = 1.0
+ ## put in strut prep stuff here
+ if hubtype==None:
+ return
+ total = 0
+ divvy = len(base.faces[0].edges)
+ for lengf in base.verts[0].edges:
+ lengf.vect.findlength()
+ total = total+lengf.vect.length
+ yardstick = total / divvy
+ if widthtog:
+ self.width = width
+ else:
+ self.width = width * yardstick
+ if heighttog:
+ self.height = height
+ else:
+ self.height = height * yardstick
+ if lengthtog:
+ self.shrink = length
+ else:
+ self.shrink = length * yardstick
+
+ if not base.facenormalflag:
+ for currentface in base.faces:
+ currentface.docorners()
+ currentface.findnormal()
+ base.facenormalflag = 1
+#PKHG_2411 breakpoint(locals(),True) #PKHG_DBG 24-11 reason ERROR**** findnormal has no faces
+
+
+ for apex in base.verts:
+ apex.findnormal()
+ side = edge(apex.edges[0].a,apex.edges[0].b)
+ apex.unit = side.vect #PKHG is Vector: b -a
+ apex.unit.normalize()
+ apex.cross = crossp(apex.normal,apex.unit).docrossproduct()
+ apex.unit = crossp(apex.cross,apex.normal).docrossproduct()
+
+ template = importmesh(meshname,0)
+ for apex in base.verts:
+ start = len(self.verts)
+ centre = apex
+ for point in template.verts:
+ ay = apex.normal * point.vector.z * self.height
+ ce = apex.cross * point.vector.y * self.width
+ be = apex.unit * point.vector.x * self.shrink
+ de = ay+be+ce
+ newvert = centre+de
+ self.verts.append(newvert)
+ for edjy in template.edges:
+ one = edjy.a.index+start
+ two = edjy.b.index+start
+ newedge = edge(self.verts[one],self.verts[two])
+ self.edges.append(newedge)
+ for facey in template.faces:
+ faceverts=[]
+ for verty in facey.vertices:
+ index = verty.index+start
+ faceverts.append(self.verts[index])
+ newface = face(faceverts)
+ self.faces.append(newface)
+ self.vertedgeflag = 0
+ self.vertedgeflag = 0
+ self.connectivity()
+
+#???PKHG TODO Nmesh used yet wrong!
+def finalfill(source,target):
+ if source == target: #PKHG: otherewise >infinite< loop
+ print("\n***WARNING*** vefm_259.finalfill L1148 source == target empty mesh used")
+ target = mesh() #
+#PKHG_??? maybe renumverting and checkkin faces wiht >=4 5 vertices?
+ count = 0
+#PKHG_OK print("\n>>>>>>>>20-11 DBG vefm_259 in finalfill L1152, len(source.verts) =",len(source.verts))
+ for point in source.verts:
+# newvert = NMesh.Vert(point.x,point.y,point.z)
+ newvert = vertex(point.vector)
+#PKHG_??? needed???
+ newvert.index = count
+ target.verts.append(newvert)
+ point.index = count #PKHG_INFO source renumbered too!
+#PKHG_OK print("test gelijk",newvert.vector == point.vector)
+ count += 1 #count+1
+
+ #PKHG indices of the vertex in faceyvertices are renumbered!
+#PKHG_OK print("\n>>>>>>>>20-11 DBG vefm_259 in finalfill L1163, len(source.faces) =",len(source.faces))
+ for facey in source.faces:
+ row = len(facey.vertices)
+ if row >= 5:
+#PKHG does not take the good vectors??? newvert = average(facey.vertices).centroid()
+ tmp = Vector()
+ for el in facey.vertices:
+ tmp = tmp + target.verts[el.index].vector
+ tmp = tmp / row
+ centre = vertex(tmp) #does not work here!==> average(facey.vertices).centroid()
+ centre.index = count #PKHG_??? give it a good index
+ count += 1
+#PKHG_DBG 21-11
+ #breakpoint(locals(),True)
+
+ target.verts.append(centre)
+ for i in range(row):
+ if i == row - 1:
+ a = target.verts[facey.vertices[-1].index]
+ b = target.verts[facey.vertices[0].index]
+ else:
+ a = target.verts[facey.vertices[i].index]
+ b = target.verts[facey.vertices[i+1].index]
+ target.faces.append([a,b,centre])
+ else:
+ f = []
+#PKHG_DBG 21-11
+# print("\n-----++++ L1217 dbg final dual", facey )
+#PKHG_DBG 21-11
+# breakpoint(locals(),True)
+
+ for j in range(len(facey.vertices)):
+ a = facey.vertices[j]
+#PKHG_NOTNEEDED tmp = a.index
+ f.append(target.verts[a.index])
+ target.faces.append(f)
+
diff --git a/release/scripts/addons_contrib/gpencil_retopo/__init__.py b/release/scripts/addons_contrib/gpencil_retopo/__init__.py
new file mode 100644
index 0000000..6a26782
--- /dev/null
+++ b/release/scripts/addons_contrib/gpencil_retopo/__init__.py
@@ -0,0 +1,111 @@
+# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+
+bl_info = {
+ "name": "Grease Pencil Retopology",
+ "author": "Campbell Barton, Bart Crouch",
+ "version": (1, 0, 0),
+ "blender": (2, 57, 0),
+ "location": "View3D > Properties > Grease Pencil",
+ "warning": "",
+ "description": "Use Grease Pencil to retopologise a mesh.",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+
+import bpy
+
+
+# retopo operator
+class Retopo(bpy.types.Operator):
+ bl_idname = "mesh.gp_retopo"
+ bl_label = "Retopo"
+ bl_description = "Convert Grease Pencil drawings to a mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ precision = bpy.props.IntProperty(name="Precision",
+ description="Lower values result in more removed doubles and "
+ "smoother less precise results",
+ default=40,
+ min=2,
+ soft_max=100)
+
+ @classmethod
+ def poll(cls, context):
+ return context.object
+
+ def execute(self, context):
+ from . import retopo
+ scene, gp = retopo.initialise(context)
+ if not gp:
+ self.report({'WARNING'}, "No grease pencil data found")
+ return {'CANCELLED'}
+
+ obj_new = retopo.calculate(gp, self.precision)
+
+ bpy.ops.object.select_all(action='DESELECT')
+ scene.objects.active = obj_new
+ obj_new.select = True
+
+ # nasty, recalc normals
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.mesh.normals_make_consistent(inside=False)
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ return {'FINISHED'}
+
+
+# draw function for integration in panels
+def panel_func(self, context):
+ self.layout.operator("mesh.gp_retopo")
+
+
+# define classes and panels for registration
+classes = [Retopo]
+panels = [bpy.types.VIEW3D_PT_tools_objectmode,
+ bpy.types.VIEW3D_PT_tools_meshedit,
+ bpy.types.VIEW3D_PT_tools_curveedit,
+ bpy.types.VIEW3D_PT_tools_surfaceedit,
+ bpy.types.VIEW3D_PT_tools_armatureedit,
+ bpy.types.VIEW3D_PT_tools_mballedit,
+ bpy.types.VIEW3D_PT_tools_latticeedit,
+ bpy.types.VIEW3D_PT_tools_posemode]
+
+
+# registering and menu integration
+def register():
+ for c in classes:
+ bpy.utils.register_class(c)
+ for panel in panels:
+ panel.append(panel_func)
+
+
+# unregistering and removing menus
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+ for panel in panels:
+ panel.remove(panel_func)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/gpencil_retopo/retopo.py b/release/scripts/addons_contrib/gpencil_retopo/retopo.py
new file mode 100644
index 0000000..b164bf4
--- /dev/null
+++ b/release/scripts/addons_contrib/gpencil_retopo/retopo.py
@@ -0,0 +1,522 @@
+# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from math import radians
+from mathutils.geometry import intersect_point_line, intersect_line_line
+
+
+# gather initial data and prepare for retopologising
+def initialise(context):
+ scene = context.scene
+ obj = context.object
+
+ gp = None
+ if obj:
+ gp = obj.grease_pencil
+ if not gp:
+ gp = scene.grease_pencil
+
+ if gp:
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ return(scene, gp)
+
+
+def get_hub(co, _hubs, EPS_SPLINE):
+
+ if 1:
+ for hub in _hubs.values():
+ if (hub.co - co).length < EPS_SPLINE:
+ return hub
+
+ key = co.to_tuple(3)
+ hub = _hubs[key] = Hub(co, key, len(_hubs))
+ return hub
+ else:
+ pass
+
+ '''
+ key = co.to_tuple(3)
+ try:
+ return _hubs[key]
+ except:
+ hub = _hubs[key] = Hub(co, key, len(_hubs))
+ return hub
+ '''
+
+
+class Hub(object):
+ __slots__ = "co", "key", "index", "links"
+
+ def __init__(self, co, key, index):
+ self.co = co.copy()
+ self.key = key
+ self.index = index
+ self.links = []
+
+ def get_weight(self):
+ f = 0.0
+
+ for hub_other in self.links:
+ f += (self.co - hub_other.co).length
+
+ def replace(self, other):
+ for hub in self.links:
+ try:
+ hub.links.remove(self)
+ except:
+ pass
+ if other not in hub.links:
+ hub.links.append(other)
+
+ def dist(self, other):
+ return (self.co - other.co).length
+
+ def calc_faces(self, hub_ls):
+ faces = []
+ # first tris
+ for l_a in self.links:
+ for l_b in l_a.links:
+ if l_b is not self and l_b in self.links:
+ # will give duplicates
+ faces.append((self.index, l_a.index, l_b.index))
+
+ # now quads, check which links share 2 different verts directly
+ def validate_quad(face):
+ if len(set(face)) != len(face):
+ return False
+ if hub_ls[face[0]] in hub_ls[face[2]].links:
+ return False
+ if hub_ls[face[2]] in hub_ls[face[0]].links:
+ return False
+
+ if hub_ls[face[1]] in hub_ls[face[3]].links:
+ return False
+ if hub_ls[face[3]] in hub_ls[face[1]].links:
+ return False
+
+ return True
+
+ for i, l_a in enumerate(self.links):
+ links_a = {l.index for l in l_a.links}
+ for j in range(i):
+ l_b = self.links[j]
+
+ links_b = {l.index for l in l_b.links}
+
+ isect = links_a.intersection(links_b)
+ if len(isect) == 2:
+ isect = list(isect)
+
+ # check there are no diagonal lines
+ face = (isect[0], l_a.index, isect[1], l_b.index)
+ if validate_quad(face):
+
+ faces.append(face)
+
+ return faces
+
+
+class BBox(object):
+ __slots__ = "xmin", "ymin", "zmin", "xmax", "ymax", "zmax"
+
+ def __init__(self):
+ self.xmin = self.ymin = self.zmin = 100000000.0
+ self.xmax = self.ymax = self.zmax = -100000000.0
+
+ @property
+ def xdim(self):
+ return self.xmax - self.xmin
+
+ @property
+ def ydim(self):
+ return self.ymax - self.ymin
+
+ @property
+ def zdim(self):
+ return self.zmax - self.zmin
+
+ def calc(self, points):
+ xmin = ymin = zmin = 100000000.0
+ xmax = ymax = zmax = -100000000.0
+
+ for pt in points:
+ x, y, z = pt
+ if x < xmin:
+ xmin = x
+ if y < ymin:
+ ymin = y
+ if z < zmin:
+ zmin = z
+
+ if x > xmax:
+ xmax = x
+ if y > ymax:
+ ymax = y
+ if z > zmax:
+ zmax = z
+
+ self.xmin, self.ymin, self.zmin = xmin, ymin, zmin
+ self.xmax, self.ymax, self.zmax = xmax, ymax, zmax
+
+ def xsect(self, other, margin=0.0):
+ if margin == 0.0:
+ if self.xmax < other.xmin:
+ return False
+ if self.ymax < other.ymin:
+ return False
+ if self.zmax < other.zmin:
+ return False
+
+ if self.xmin > other.xmax:
+ return False
+ if self.ymin > other.ymax:
+ return False
+ if self.zmin > other.zmax:
+ return False
+
+ else:
+ xmargin = ((self.xdim + other.xdim) / 2.0) * margin
+ ymargin = ((self.ydim + other.ydim) / 2.0) * margin
+ zmargin = ((self.zdim + other.zdim) / 2.0) * margin
+
+ if self.xmax < other.xmin - xmargin:
+ return False
+ if self.ymax < other.ymin - ymargin:
+ return False
+ if self.zmax < other.zmin - zmargin:
+ return False
+
+ if self.xmin > other.xmax + xmargin:
+ return False
+ if self.ymin > other.ymax + ymargin:
+ return False
+ if self.zmin > other.zmax + zmargin:
+ return False
+ return True
+
+ def __iadd__(self, other):
+ self.xmin = min(self.xmin, other.xmin)
+ self.ymin = min(self.ymin, other.ymin)
+ self.zmin = min(self.zmin, other.zmin)
+
+ self.xmax = max(self.xmax, other.xmax)
+ self.ymax = max(self.ymax, other.ymax)
+ self.zmax = max(self.zmax, other.zmax)
+ return self
+
+
+class Spline(object):
+ __slots__ = "points", "hubs", "closed", "length", "bb"
+
+ def __init__(self, points, precision):
+ self.points = points
+ self.hubs = []
+ self.calc_length()
+ self.closed = self.calc_closed(precision)
+ self.bb = BBox()
+ self.bb.calc(points)
+
+ def calc_length(self):
+ # calc length
+ f = 0.0
+ co_prev = self.points[0]
+ for co in self.points[1:]:
+ f += (co - co_prev).length
+ co_prev = co
+ self.length = f
+
+ def calc_closed(self, precision):
+ return (self.points[0] - self.points[-1]).length < (self.length / precision)
+
+ def link(self):
+ if len(self.hubs) < 2:
+ return
+
+ edges = list(set([i for i, hub in self.hubs]))
+ edges.sort()
+
+ edges_order = {}
+ for i in edges:
+ edges_order[i] = []
+
+ # self.hubs.sort()
+ for i, hub in self.hubs:
+ edges_order[i].append(hub)
+
+ hubs_order = []
+ for i in edges:
+ ls = edges_order[i]
+ edge_start = self.points[i]
+ ls.sort(key=lambda hub: (hub.co - edge_start).length)
+ hubs_order.extend(ls)
+
+ # Now we have the order, connect the hubs
+ hub_prev = hubs_order[0]
+
+ for hub in hubs_order[1:]:
+ hub.links.append(hub_prev)
+ hub_prev.links.append(hub)
+ hub_prev = hub
+
+ if self.closed:
+ hubs_order[0].links.append(hubs_order[-1])
+ hubs_order[-1].links.append(hubs_order[0])
+
+
+def get_points(stroke):
+ return [point.co.copy() for point in stroke.points]
+
+
+def get_splines(gp, precision):
+ l = gp.layers.active
+ if l:
+ frame = l.active_frame
+ return [Spline(get_points(stroke), precision) for stroke in frame.strokes if len(stroke.points) > 1]
+ else:
+ return []
+
+
+def xsect_spline(sp_a, sp_b, _hubs, precision):
+ pt_a_prev = pt_b_prev = None
+ EPS_SPLINE = min(sp_a.length, sp_b.length) / precision
+ pt_a_prev = sp_a.points[0]
+ for a, pt_a in enumerate(sp_a.points[1:]):
+ pt_b_prev = sp_b.points[0]
+ for b, pt_b in enumerate(sp_b.points[1:]):
+
+ # Now we have 2 edges
+ # print(pt_a, pt_a_prev, pt_b, pt_b_prev)
+ xsect = intersect_line_line(pt_a, pt_a_prev, pt_b, pt_b_prev)
+ if xsect is not None:
+ if (xsect[0] - xsect[1]).length <= EPS_SPLINE:
+ f = intersect_point_line(xsect[1], pt_a, pt_a_prev)[1]
+ # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
+ # for some reason doesnt work so well, same below
+ if f >= 0.0 and f <= 1.0:
+ f = intersect_point_line(xsect[0], pt_b, pt_b_prev)[1]
+ # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
+ if f >= 0.0 and f <= 1.0:
+ # This wont happen often
+ co = xsect[0].lerp(xsect[1], 0.5)
+ hub = get_hub(co, _hubs, EPS_SPLINE)
+
+ sp_a.hubs.append((a, hub))
+ sp_b.hubs.append((b, hub))
+
+ pt_b_prev = pt_b
+
+ pt_a_prev = pt_a
+
+
+def connect_splines(splines, precision):
+ HASH_PREC = 8
+ ANG_LIMIT = radians(25.0) # limit for joining splines into 1
+
+ def sort_pair(a, b):
+ if a < b:
+ return a, b
+ else:
+ return b, a
+
+ #def test_join(p1a, p1b, p2a, p2b, length_average):
+ def test_join(s1, s2, dir1, dir2, length_average):
+ if dir1 is False:
+ p1a = s1.points[0]
+ p1b = s1.points[1]
+ else:
+ p1a = s1.points[-1]
+ p1b = s1.points[-2]
+
+ if dir2 is False:
+ p2a = s2.points[0]
+ p2b = s2.points[1]
+ else:
+ p2a = s2.points[-1]
+ p2b = s2.points[-2]
+
+ v1 = p1a - p1b
+ v2 = p2b - p2a
+
+ if v1.angle(v2, ANG_LIMIT) >= ANG_LIMIT:
+ return False
+
+ # trim s2, allow overlapping line.
+ v2_test_1 = p2b - p2a
+ if dir2 is False:
+ i = 2
+ while (p2b - p1a).length < (p2a - p1a).length and i < len(s2.points):
+ p2a = p2b
+ p2b = s2.points[i]
+ i += 1
+ else:
+ i = -3
+ while (p2b - p1a).length < (p2a - p1a).length and -i <= len(s2.points):
+ p2a = p2b
+ p2b = s2.points[i]
+ i -= 1
+
+ # when trimming did we we turn a corner?
+ v2_test_2 = p2b - p2a
+ if v2_test_1.angle(v2_test_2, ANG_LIMIT) >= ANG_LIMIT:
+ return False
+ del v2_test_1
+ del v2_test_2
+ # end trimming
+
+ # compare length between tips
+ if (p1a - p2a).length > (length_average / precision):
+ return False
+
+ # print("joining!")
+ return True
+
+ # lazy, hash the points that have been compared.
+ comparisons = set()
+
+ do_join = True
+ while do_join:
+ do_join = False
+ for i, s1 in enumerate(splines):
+ key1a = s1.points[0].to_tuple(HASH_PREC)
+ key1b = s1.points[-1].to_tuple(HASH_PREC)
+
+ for j, s2 in enumerate(splines):
+ if s1 is s2:
+ continue
+
+ length_average = min(s1.length, s2.length)
+
+ key2a = s2.points[0].to_tuple(HASH_PREC)
+ key2b = s2.points[-1].to_tuple(HASH_PREC)
+
+ # there are 4 ways this may be joined
+ key_pair = sort_pair(key1a, key2a)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, False, False, length_average):
+ s1.points[:0] = reversed(s2.points)
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ key_pair = sort_pair(key1a, key2b)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, False, True, length_average):
+ s1.points[:0] = s2.points
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ key_pair = sort_pair(key1b, key2b)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, True, True, length_average):
+ s1.points += list(reversed(s2.points))
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ key_pair = sort_pair(key1b, key2a)
+ if key_pair not in comparisons:
+ comparisons.add(key_pair)
+ if test_join(s1, s2, True, False, length_average):
+ s1.points += s2.points
+ s1.bb += s2.bb
+ s1.calc_length()
+ del splines[j]
+ do_join = True
+ break
+
+ if do_join:
+ break
+
+
+def calculate(gp, precision):
+ # note, this precision is for closed lines, it could be a different arg.
+ splines = get_splines(gp, precision)
+
+ # spline endpoints may be co-linear, join these into single splines
+ connect_splines(splines, precision)
+
+ _hubs = {}
+
+ for i, sp in enumerate(splines):
+ for j, sp_other in enumerate(splines):
+ if j <= i:
+ continue
+
+ if sp.bb.xsect(sp_other.bb, margin=0.1):
+ xsect_spline(sp, sp_other, _hubs, precision)
+
+ for sp in splines:
+ sp.link()
+
+ # remove these
+ hubs_ls = [hub for hub in _hubs.values() if hub.index != -1]
+
+ _hubs.clear()
+ _hubs = None
+
+ for i, hub in enumerate(hubs_ls):
+ hub.index = i
+
+ # Now we have connected hubs, write all edges!
+ def order(i1, i2):
+ if i1 > i2:
+ return i2, i1
+ return i1, i2
+
+ edges = {}
+
+ for hub in hubs_ls:
+ i1 = hub.index
+ for hub_other in hub.links:
+ i2 = hub_other.index
+ edges[order(i1, i2)] = None
+
+ verts = []
+ edges = edges.keys()
+ faces = []
+
+ for hub in hubs_ls:
+ verts.append(hub.co)
+ faces.extend(hub.calc_faces(hubs_ls))
+
+ # remove double faces
+ faces = dict([(tuple(sorted(f)), f) for f in faces]).values()
+
+ mesh = bpy.data.meshes.new("Retopo")
+ mesh.from_pydata(verts, [], faces)
+
+ scene = bpy.context.scene
+ mesh.update()
+ obj_new = bpy.data.objects.new(name="Retopo", object_data=mesh)
+ scene.objects.link(obj_new)
+
+ return obj_new
diff --git a/release/scripts/addons_contrib/io_atomblend_utilities/__init__.py b/release/scripts/addons_contrib/io_atomblend_utilities/__init__.py
new file mode 100644
index 0000000..49a7fac
--- /dev/null
+++ b/release/scripts/addons_contrib/io_atomblend_utilities/__init__.py
@@ -0,0 +1,286 @@
+# ##### 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 LICENSE BLOCK #####
+
+#
+#
+# Authors : Clemens Barth (Blendphys at root-1.de), ...
+#
+# Homepage(Wiki) : http://development.root-1.de/Atomic_Blender.php
+#
+# Start of project : 2011-12-01 by Clemens Barth
+# First publication in Blender : 2012-11-03
+# Last modified : 2013-01-08
+#
+# Acknowledgements
+# ================
+#
+# Blender: ideasman, meta_androcto, truman, kilon, CoDEmanX, dairin0d, PKHG,
+# Valter, ...
+# Other: Frank Palmino
+#
+
+bl_info = {
+ "name": "Atomic Blender - Utilities",
+ "description": "Utilities for manipulating atom structures",
+ "author": "Clemens Barth",
+ "version": (0, 6),
+ "blender": (2, 60, 0),
+ "location": "Panel: View 3D - Tools",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/"
+ "Py/Scripts/Import-Export/PDB",
+ "tracker_url": "http://projects.blender.org/tracker/"
+ "index.php?func=detail&aid=33071&group_id=153&atid=467",
+ "category": "Import-Export"
+}
+
+import bpy
+from bpy.types import Operator, Panel
+from bpy.props import (StringProperty,
+ EnumProperty,
+ FloatProperty)
+
+from . import io_atomblend_utilities
+
+# -----------------------------------------------------------------------------
+# GUI
+
+# The panel.
+class PreparePanel(Panel):
+ bl_label = "Atomic Blender Utilities"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOL_PROPS"
+
+ def draw(self, context):
+ layout = self.layout
+ scn = context.scene.atom_blend
+
+ row = layout.row()
+ box = layout.box()
+ row = box.row()
+ row.label(text="Custom data file")
+ row = box.row()
+ col = row.column()
+ col.prop(scn, "datafile")
+ col.operator("atom_blend.datafile_apply")
+ row = box.row()
+ row.operator("atom_blend.button_distance")
+ row.prop(scn, "distance")
+ row = layout.row()
+ row.label(text="Choice of atom radii")
+ box = layout.box()
+ row = box.row()
+ row.label(text="All changes concern:")
+ row = box.row()
+ row.prop(scn, "radius_how")
+ row = box.row()
+ row.label(text="1. Change type of radii")
+ row = box.row()
+ row.prop(scn, "radius_type")
+ row = box.row()
+ row.active = (scn.radius_type == '3')
+ row.prop(scn, "radius_type_ionic")
+ row = box.row()
+ row.label(text="2. Change atom radii in pm")
+ row = box.row()
+ row.prop(scn, "radius_pm_name")
+ row = box.row()
+ row.prop(scn, "radius_pm")
+ row = box.row()
+ row.label(text="3. Change atom radii by scale")
+ row = box.row()
+ col = row.column()
+ col.prop(scn, "radius_all")
+ col = row.column(align=True)
+ col.operator( "atom_blend.radius_all_bigger" )
+ col.operator( "atom_blend.radius_all_smaller" )
+
+ layout.separator()
+ row = box.row()
+ row.active = (bpy.context.mode == 'EDIT_MESH')
+ row.operator( "atom_blend.separate_atom" )
+
+
+# The properties of buttons etc. in the panel.
+class PanelProperties(bpy.types.PropertyGroup):
+
+ def Callback_radius_type(self, context):
+ scn = bpy.context.scene.atom_blend
+ io_atomblend_utilities.choose_objects("radius_type",
+ scn.radius_how,
+ None,
+ None,
+ scn.radius_type,
+ scn.radius_type_ionic)
+ def Callback_radius_pm(self, context):
+ scn = bpy.context.scene.atom_blend
+ io_atomblend_utilities.choose_objects("radius_pm",
+ scn.radius_how,
+ None,
+ [scn.radius_pm_name,
+ scn.radius_pm],
+ None,
+ None)
+
+ datafile = StringProperty(
+ name = "", description="Path to your custom data file",
+ maxlen = 256, default = "", subtype='FILE_PATH')
+ XYZ_file = StringProperty(
+ name = "Path to file", default="",
+ description = "Path of the XYZ file")
+ number_atoms = StringProperty(name="",
+ default="Number", description = "This output shows "
+ "the number of atoms which have been loaded")
+ distance = StringProperty(
+ name="", default="Distance (A)",
+ description="Distance of 2 objects in Angstrom")
+ radius_how = EnumProperty(
+ name="",
+ description="Which objects shall be modified?",
+ items=(('ALL_ACTIVE',"all active objects", "in the current layer"),
+ ('ALL_IN_LAYER',"all"," in active layer(s)")),
+ default='ALL_ACTIVE',)
+ radius_type = EnumProperty(
+ name="Type of radius",
+ description="Which type of atom radii?",
+ items=(('0',"predefined", "Use pre-defined radii"),
+ ('1',"atomic", "Use atomic radii"),
+ ('2',"van der Waals","Use van der Waals radii"),
+ ('3',"ionic radii", "Use ionic radii")),
+ default='0',update=Callback_radius_type)
+ radius_type_ionic = EnumProperty(
+ name="Charge state",
+ description="Charge state of the ions if existing.",
+ items=(('0',"-4", "Charge state -4"),
+ ('1',"-3", "Charge state -3"),
+ ('2',"-2", "Charge state -2"),
+ ('3',"-1", "Charge state -1"),
+ ('5',"+1", "Charge state +1"),
+ ('6',"+2", "Charge state +2"),
+ ('7',"+3", "Charge state +3"),
+ ('8',"+4", "Charge state +4"),
+ ('9',"+5", "Charge state +5"),
+ ('10',"+6", "Charge state +6"),
+ ('11',"+7", "Charge state +7")),
+ default='3',update=Callback_radius_type)
+ radius_pm_name = StringProperty(
+ name="", default="Atom name",
+ description="Put in the name of the atom (e.g. Hydrogen)")
+ radius_pm = FloatProperty(
+ name="", default=100.0, min=0.0,
+ description="Put in the radius of the atom (in pm)",
+ update=Callback_radius_pm)
+ radius_all = FloatProperty(
+ name="Scale", default = 1.05, min=1.0, max=5.0,
+ description="Put in the scale factor")
+
+
+
+# Button loading a custom data file
+class DatafileApply(Operator):
+ bl_idname = "atom_blend.datafile_apply"
+ bl_label = "Apply"
+ bl_description = "Use color and radii values stored in the custom file"
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_blend
+
+ if scn.datafile == "":
+ return {'FINISHED'}
+
+ io_atomblend_utilities.custom_datafile(scn.datafile)
+ io_atomblend_utilities.custom_datafile_change_atom_props()
+
+ return {'FINISHED'}
+
+
+# Button for separating a single atom from a structure
+class SeparateAtom(Operator):
+ bl_idname = "atom_blend.separate_atom"
+ bl_label = "Separate atoms"
+ bl_description = ("Separate atoms you have selected. "
+ "You have to be in the 'Edit Mode'")
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_blend
+
+ io_atomblend_utilities.separate_atoms(scn)
+
+ return {'FINISHED'}
+
+
+# Button for measuring the distance of the active objects
+class DistanceButton(Operator):
+ bl_idname = "atom_blend.button_distance"
+ bl_label = "Measure ..."
+ bl_description = "Measure the distance between two objects"
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_blend
+ dist = io_atomblend_utilities.distance()
+
+ # Put the distance into the string of the output field.
+ scn.distance = dist
+ return {'FINISHED'}
+
+
+# Button for increasing the radii of all atoms
+class RadiusAllBiggerButton(Operator):
+ bl_idname = "atom_blend.radius_all_bigger"
+ bl_label = "Bigger ..."
+ bl_description = "Increase the radii of the atoms"
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_blend
+ io_atomblend_utilities.choose_objects("radius_all",
+ scn.radius_how,
+ scn.radius_all,
+ None,
+ None)
+ return {'FINISHED'}
+
+
+# Button for decreasing the radii of all atoms
+class RadiusAllSmallerButton(Operator):
+ bl_idname = "atom_blend.radius_all_smaller"
+ bl_label = "Smaller ..."
+ bl_description = "Decrease the radii of the atoms"
+
+ def execute(self, context):
+ scn = bpy.context.scene.atom_blend
+ io_atomblend_utilities.choose_objects("radius_all",
+ scn.radius_how,
+ 1.0/scn.radius_all,
+ None,
+ None)
+ return {'FINISHED'}
+
+
+def register():
+ io_atomblend_utilities.read_elements()
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.atom_blend = bpy.props.PointerProperty(type=
+ PanelProperties)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+
+ register()
diff --git a/release/scripts/addons_contrib/io_atomblend_utilities/io_atomblend_utilities.py b/release/scripts/addons_contrib/io_atomblend_utilities/io_atomblend_utilities.py
new file mode 100644
index 0000000..277338e
--- /dev/null
+++ b/release/scripts/addons_contrib/io_atomblend_utilities/io_atomblend_utilities.py
@@ -0,0 +1,487 @@
+# ##### 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 LICENSE BLOCK #####
+
+import os
+import bpy
+import bmesh
+
+# -----------------------------------------------------------------------------
+# Atom and element data
+
+
+# This is a list that contains some data of all possible elements. The structure
+# is as follows:
+#
+# 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means
+#
+# No., name, short name, color, radius (used), radius (covalent), radius (atomic),
+#
+# charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
+# charge states for any atom are listed, if existing.
+# The list is fixed and cannot be changed ... (see below)
+
+ELEMENTS_DEFAULT = (
+( 1, "Hydrogen", "H", ( 1.0, 1.0, 1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
+( 2, "Helium", "He", ( 0.85, 1.0, 1.0), 0.93, 0.93, 0.49 ),
+( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ),
+( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ),
+( 5, "Boron", "B", ( 1.0, 0.70, 0.70), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ),
+( 6, "Carbon", "C", ( 0.56, 0.56, 0.56), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ),
+( 7, "Nitrogen", "N", ( 0.18, 0.31, 0.97), 0.75, 0.75, 0.75 , -3 , 1.71 , 1 , 0.25 , 3 , 0.16 , 5 , 0.13 ),
+( 8, "Oxygen", "O", ( 1.0, 0.05, 0.05), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 , 1 , 0.22 , 6 , 0.09 ),
+( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ),
+(10, "Neon", "Ne", ( 0.70, 0.89, 0.96), 0.71, 0.71, 0.51 , 1 , 1.12 ),
+(11, "Sodium", "Na", ( 0.67, 0.36, 0.94), 1.54, 1.54, 2.23 , 1 , 0.97 ),
+(12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ),
+(13, "Aluminium", "Al", ( 0.74, 0.65, 0.65), 1.18, 1.18, 1.82 , 3 , 0.51 ),
+(14, "Silicon", "Si", ( 0.94, 0.78, 0.62), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 , 1 , 0.65 , 4 , 0.42 ),
+(15, "Phosphorus", "P", ( 1.0, 0.50, 0.0), 1.06, 1.06, 1.23 , -3 , 2.12 , 3 , 0.44 , 5 , 0.35 ),
+(16, "Sulfur", "S", ( 1.0, 1.0, 0.18), 1.02, 1.02, 1.09 , -2 , 1.84 , 2 , 2.19 , 4 , 0.37 , 6 , 0.30 ),
+(17, "Chlorine", "Cl", ( 0.12, 0.94, 0.12), 0.99, 0.99, 0.97 , -1 , 1.81 , 5 , 0.34 , 7 , 0.27 ),
+(18, "Argon", "Ar", ( 0.50, 0.81, 0.89), 0.98, 0.98, 0.88 , 1 , 1.54 ),
+(19, "Potassium", "K", ( 0.56, 0.25, 0.83), 2.03, 2.03, 2.77 , 1 , 0.81 ),
+(20, "Calcium", "Ca", ( 0.23, 1.0, 0.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ),
+(21, "Scandium", "Sc", ( 0.90, 0.90, 0.90), 1.44, 1.44, 2.09 , 3 , 0.73 ),
+(22, "Titanium", "Ti", ( 0.74, 0.76, 0.78), 1.32, 1.32, 2.00 , 1 , 0.96 , 2 , 0.94 , 3 , 0.76 , 4 , 0.68 ),
+(23, "Vanadium", "V", ( 0.65, 0.65, 0.67), 1.22, 1.22, 1.92 , 2 , 0.88 , 3 , 0.74 , 4 , 0.63 , 5 , 0.59 ),
+(24, "Chromium", "Cr", ( 0.54, 0.6, 0.78), 1.18, 1.18, 1.85 , 1 , 0.81 , 2 , 0.89 , 3 , 0.63 , 6 , 0.52 ),
+(25, "Manganese", "Mn", ( 0.61, 0.47, 0.78), 1.17, 1.17, 1.79 , 2 , 0.80 , 3 , 0.66 , 4 , 0.60 , 7 , 0.46 ),
+(26, "Iron", "Fe", ( 0.87, 0.4, 0.2), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ),
+(27, "Cobalt", "Co", ( 0.94, 0.56, 0.62), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ),
+(28, "Nickel", "Ni", ( 0.31, 0.81, 0.31), 1.15, 1.15, 1.62 , 2 , 0.69 ),
+(29, "Copper", "Cu", ( 0.78, 0.50, 0.2), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ),
+(30, "Zinc", "Zn", ( 0.49, 0.50, 0.69), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ),
+(31, "Gallium", "Ga", ( 0.76, 0.56, 0.56), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ),
+(32, "Germanium", "Ge", ( 0.4, 0.56, 0.56), 1.22, 1.22, 1.52 , -4 , 2.72 , 2 , 0.73 , 4 , 0.53 ),
+(33, "Arsenic", "As", ( 0.74, 0.50, 0.89), 1.20, 1.20, 1.33 , -3 , 2.22 , 3 , 0.58 , 5 , 0.46 ),
+(34, "Selenium", "Se", ( 1.0, 0.63, 0.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 , 1 , 0.66 , 4 , 0.50 , 6 , 0.42 ),
+(35, "Bromine", "Br", ( 0.65, 0.16, 0.16), 1.14, 1.14, 1.12 , -1 , 1.96 , 5 , 0.47 , 7 , 0.39 ),
+(36, "Krypton", "Kr", ( 0.36, 0.72, 0.81), 1.31, 1.31, 1.24 ),
+(37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69), 2.16, 2.16, 2.98 , 1 , 1.47 ),
+(38, "Strontium", "Sr", ( 0.0, 1.0, 0.0), 1.91, 1.91, 2.45 , 2 , 1.12 ),
+(39, "Yttrium", "Y", ( 0.58, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ),
+(40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ),
+(41, "Niobium", "Nb", ( 0.45, 0.76, 0.78), 1.34, 1.34, 2.08 , 1 , 1.00 , 4 , 0.74 , 5 , 0.69 ),
+(42, "Molybdenum", "Mo", ( 0.32, 0.70, 0.70), 1.30, 1.30, 2.01 , 1 , 0.93 , 4 , 0.70 , 6 , 0.62 ),
+(43, "Technetium", "Tc", ( 0.23, 0.61, 0.61), 1.27, 1.27, 1.95 , 7 , 0.97 ),
+(44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56), 1.25, 1.25, 1.89 , 4 , 0.67 ),
+(45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54), 1.25, 1.25, 1.83 , 3 , 0.68 ),
+(46, "Palladium", "Pd", ( 0.0, 0.41, 0.52), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ),
+(47, "Silver", "Ag", ( 0.75, 0.75, 0.75), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ),
+(48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ),
+(49, "Indium", "In", ( 0.65, 0.45, 0.45), 1.44, 1.44, 2.00 , 3 , 0.81 ),
+(50, "Tin", "Sn", ( 0.4, 0.50, 0.50), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 , 2 , 0.93 , 4 , 0.71 ),
+(51, "Antimony", "Sb", ( 0.61, 0.38, 0.70), 1.40, 1.40, 1.53 , -3 , 2.45 , 3 , 0.76 , 5 , 0.62 ),
+(52, "Tellurium", "Te", ( 0.83, 0.47, 0.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 , 1 , 0.82 , 4 , 0.70 , 6 , 0.56 ),
+(53, "Iodine", "I", ( 0.58, 0.0, 0.58), 1.33, 1.33, 1.32 , -1 , 2.20 , 5 , 0.62 , 7 , 0.50 ),
+(54, "Xenon", "Xe", ( 0.25, 0.61, 0.69), 1.31, 1.31, 1.24 ),
+(55, "Caesium", "Cs", ( 0.34, 0.09, 0.56), 2.35, 2.35, 3.35 , 1 , 1.67 ),
+(56, "Barium", "Ba", ( 0.0, 0.78, 0.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ),
+(57, "Lanthanum", "La", ( 0.43, 0.83, 1.0), 1.69, 1.69, 2.74 , 1 , 1.39 , 3 , 1.06 ),
+(58, "Cerium", "Ce", ( 1.0, 1.0, 0.78), 1.65, 1.65, 2.70 , 1 , 1.27 , 3 , 1.03 , 4 , 0.92 ),
+(59, "Praseodymium", "Pr", ( 0.85, 1.0, 0.78), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ),
+(60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78), 1.64, 1.64, 2.64 , 3 , 0.99 ),
+(61, "Promethium", "Pm", ( 0.63, 1.0, 0.78), 1.63, 1.63, 2.62 , 3 , 0.97 ),
+(62, "Samarium", "Sm", ( 0.56, 1.0, 0.78), 1.62, 1.62, 2.59 , 3 , 0.96 ),
+(63, "Europium", "Eu", ( 0.38, 1.0, 0.78), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ),
+(64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78), 1.61, 1.61, 2.54 , 3 , 0.93 ),
+(65, "Terbium", "Tb", ( 0.18, 1.0, 0.78), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ),
+(66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78), 1.59, 1.59, 2.49 , 3 , 0.90 ),
+(67, "Holmium", "Ho", ( 0.0, 1.0, 0.61), 1.58, 1.58, 2.47 , 3 , 0.89 ),
+(68, "Erbium", "Er", ( 0.0, 0.90, 0.45), 1.57, 1.57, 2.45 , 3 , 0.88 ),
+(69, "Thulium", "Tm", ( 0.0, 0.83, 0.32), 1.56, 1.56, 2.42 , 3 , 0.87 ),
+(70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ),
+(71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14), 1.56, 1.56, 2.25 , 3 , 0.85 ),
+(72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ),
+(73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ),
+(74, "Tungsten", "W", ( 0.12, 0.58, 0.83), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ),
+(75, "Rhenium", "Re", ( 0.14, 0.49, 0.67), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ),
+(76, "Osmium", "Os", ( 0.14, 0.4, 0.58), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ),
+(77, "Iridium", "Ir", ( 0.09, 0.32, 0.52), 1.27, 1.27, 1.87 , 4 , 0.68 ),
+(78, "Platinium", "Pt", ( 0.81, 0.81, 0.87), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ),
+(79, "Gold", "Au", ( 1.0, 0.81, 0.13), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ),
+(80, "Mercury", "Hg", ( 0.72, 0.72, 0.81), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ),
+(81, "Thallium", "Tl", ( 0.65, 0.32, 0.30), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ),
+(82, "Lead", "Pb", ( 0.34, 0.34, 0.38), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ),
+(83, "Bismuth", "Bi", ( 0.61, 0.30, 0.70), 1.46, 1.46, 1.63 , 1 , 0.98 , 3 , 0.96 , 5 , 0.74 ),
+(84, "Polonium", "Po", ( 0.67, 0.36, 0.0), 1.46, 1.46, 1.53 , 6 , 0.67 ),
+(85, "Astatine", "At", ( 0.45, 0.30, 0.27), 1.45, 1.45, 1.43 , -3 , 2.22 , 3 , 0.85 , 5 , 0.46 ),
+(86, "Radon", "Rn", ( 0.25, 0.50, 0.58), 1.00, 1.00, 1.34 ),
+(87, "Francium", "Fr", ( 0.25, 0.0, 0.4), 1.00, 1.00, 1.00 , 1 , 1.80 ),
+(88, "Radium", "Ra", ( 0.0, 0.49, 0.0), 1.00, 1.00, 1.00 , 2 , 1.43 ),
+(89, "Actinium", "Ac", ( 0.43, 0.67, 0.98), 1.00, 1.00, 1.00 , 3 , 1.18 ),
+(90, "Thorium", "Th", ( 0.0, 0.72, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ),
+(91, "Protactinium", "Pa", ( 0.0, 0.63, 1.0), 1.00, 1.00, 1.00 , 3 , 1.13 , 4 , 0.98 , 5 , 0.89 ),
+(92, "Uranium", "U", ( 0.0, 0.56, 1.0), 1.42, 1.42, 1.00 , 4 , 0.97 , 6 , 0.80 ),
+(93, "Neptunium", "Np", ( 0.0, 0.50, 1.0), 1.00, 1.00, 1.00 , 3 , 1.10 , 4 , 0.95 , 7 , 0.71 ),
+(94, "Plutonium", "Pu", ( 0.0, 0.41, 1.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ),
+(95, "Americium", "Am", ( 0.32, 0.36, 0.94), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ),
+(96, "Curium", "Cm", ( 0.47, 0.36, 0.89), 1.00, 1.00, 1.00 ),
+(97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89), 1.00, 1.00, 1.00 ),
+(98, "Californium", "Cf", ( 0.63, 0.21, 0.83), 1.00, 1.00, 1.00 ),
+(99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83), 1.00, 1.00, 1.00 ),
+(100, "Fermium", "Fm", ( 0.70, 0.12, 0.72), 1.00, 1.00, 1.00 ),
+(101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65), 1.00, 1.00, 1.00 ),
+(102, "Nobelium", "No", ( 0.74, 0.05, 0.52), 1.00, 1.00, 1.00 ),
+(103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4), 1.00, 1.00, 1.00 ),
+(104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00),
+(105, "Default", "Default", ( 1.0, 1.0, 1.0), 1.00, 1.00, 1.00),
+(106, "Stick", "Stick", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00),
+)
+
+# The list 'ELEMENTS' contains all data of the elements and will be used during
+# runtime. The list will be initialized with the fixed
+# data from above via the class below (ElementProp). One fixed list (above),
+# which cannot be changed, and a list of classes with same data (ELEMENTS) exist.
+# The list 'ELEMENTS' can be modified by e.g. loading a separate custom
+# data file.
+ELEMENTS = []
+
+# This is the class, which stores the properties for one element.
+class ElementProp(object):
+ __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic')
+ def __init__(self, number, name, short_name, color, radii, radii_ionic):
+ self.number = number
+ self.name = name
+ self.short_name = short_name
+ self.color = color
+ self.radii = radii
+ self.radii_ionic = radii_ionic
+
+
+# This function measures the distance between two objects (atoms),
+# which are active.
+def distance():
+
+ # In the 'Edit mode'
+ if bpy.context.mode == 'EDIT_MESH':
+
+ obj = bpy.context.edit_object
+ bm = bmesh.from_edit_mesh(obj.data)
+ locations = []
+
+ for v in bm.verts:
+ if v.select:
+ locations.append(obj.matrix_world * v.co)
+
+ if len(locations) > 1:
+ location1 = locations[0]
+ location2 = locations[1]
+ else:
+ return "N.A"
+ # In the object mode
+ else:
+
+ if len(bpy.context.selected_bases) > 1:
+ location1 = bpy.context.selected_objects[0].location
+ location2 = bpy.context.selected_objects[1].location
+ else:
+ return "N.A."
+
+ dv = location2 - location1
+ dist = str(dv.length)
+ pos = str.find(dist, ".")
+ dist = dist[:pos+4]
+ dist = dist + " A"
+
+ return dist
+
+
+def choose_objects(how,
+ who,
+ radius_all,
+ radius_pm,
+ radius_type,
+ radius_type_ionic):
+
+ if who == "ALL_IN_LAYER":
+
+ # Determine all selected layers.
+ layers = []
+ for i, layer in enumerate(bpy.context.scene.layers):
+ if layer == True:
+ layers.append(i)
+
+ # Put all objects, which are in the layers, into a list.
+ change_objects = []
+ for obj in bpy.context.scene.objects:
+ for layer in layers:
+ if obj.layers[layer] == True:
+ change_objects.append(obj)
+
+ # Consider all objects, which are in the list 'change_objects'.
+ for obj in change_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type in {'SURFACE', 'MESH', 'META'}:
+ modify_objects(how,
+ obj.children[0],
+ radius_all,
+ radius_pm,
+ radius_type,
+ radius_type_ionic)
+ else:
+ if obj.type in {'SURFACE', 'MESH', 'META'}:
+ modify_objects(how,
+ obj,
+ radius_all,
+ radius_pm,
+ radius_type,
+ radius_type_ionic)
+ if who == "ALL_ACTIVE":
+ for obj in bpy.context.selected_objects:
+ if len(obj.children) != 0:
+ if obj.children[0].type in {'SURFACE', 'MESH', 'META'}:
+ modify_objects(how,
+ obj.children[0],
+ radius_all,
+ radius_pm,
+ radius_type,
+ radius_type_ionic)
+ else:
+ if obj.type in {'SURFACE', 'MESH', 'META'}:
+ modify_objects(how,
+ obj,
+ radius_all,
+ radius_pm,
+ radius_type,
+ radius_type_ionic)
+
+
+
+# Modifying the radii in picometer of a specific type of atom
+def modify_objects(how,
+ obj,
+ radius_all,
+ radius_pm,
+ radius_type,
+ radius_type_ionic):
+
+ # Radius pm
+ if how == "radius_pm":
+ if radius_pm[0] in obj.name:
+ obj.scale = (radius_pm[1]/100,) * 3
+
+ # Radius all
+ if how == "radius_all":
+ obj.scale *= radius_all
+
+ # Radius type
+ if how == "radius_type":
+ for element in ELEMENTS:
+ if element.name in obj.name:
+ # For ionic radii
+ if radius_type == '3':
+ charge_states = element.radii_ionic[::2]
+ charge_radii = element.radii_ionic[1::2]
+ charge_state_chosen = int(radius_type_ionic) - 4
+
+ find = (lambda searchList, elem:
+ [[i for i, x in enumerate(searchList) if x == e]
+ for e in elem])
+ index = find(charge_states,[charge_state_chosen])[0]
+
+ # Is there a charge state?
+ if index != []:
+ #print(element.name, index[0], charge_radii[index[0]])
+ obj.scale = (charge_radii[index[0]],) * 3
+
+ # For atomic and van der Waals radii.
+ else:
+ obj.scale = (element.radii[int(radius_type)],) * 3
+
+
+# Initialization of the list 'ELEMENTS'.
+def read_elements():
+
+ del ELEMENTS[:]
+
+ for item in ELEMENTS_DEFAULT:
+
+ # All three radii into a list
+ radii = [item[4],item[5],item[6]]
+ # The handling of the ionic radii will be done later. So far, it is an
+ # empty list.
+ radii_ionic = item[7:]
+
+ li = ElementProp(item[0],item[1],item[2],item[3],
+ radii,radii_ionic)
+ ELEMENTS.append(li)
+
+
+# Changing color and radii by using the list of elements.
+def custom_datafile_change_atom_props():
+
+ for obj in bpy.context.selected_objects:
+ if len(obj.children) != 0:
+ child = obj.children[0]
+ if child.type in {'SURFACE', 'MESH', 'META'}:
+ for element in ELEMENTS:
+ if element.name in obj.name:
+ child.scale = (element.radii[0],) * 3
+ child.active_material.diffuse_color = element.color
+ else:
+ if obj.type in {'SURFACE', 'MESH', 'META'}:
+ for element in ELEMENTS:
+ if element.name in obj.name:
+ obj.scale = (element.radii[0],) * 3
+ obj.active_material.diffuse_color = element.color
+
+
+# Reading a custom data file.
+def custom_datafile(path_datafile):
+
+ if path_datafile == "":
+ return False
+
+ path_datafile = bpy.path.abspath(path_datafile)
+
+ if os.path.isfile(path_datafile) == False:
+ return False
+
+ # The whole list gets deleted! We build it new.
+ del ELEMENTS[:]
+
+ # Read the data file, which contains all data
+ # (atom name, radii, colors, etc.)
+ data_file_p = open(path_datafile, "r")
+
+ for line in data_file_p:
+
+ if "Atom" in line:
+
+ line = data_file_p.readline()
+ # Number
+ line = data_file_p.readline()
+ number = line[19:-1]
+ # Name
+ line = data_file_p.readline()
+ name = line[19:-1]
+ # Short name
+ line = data_file_p.readline()
+ short_name = line[19:-1]
+ # Color
+ line = data_file_p.readline()
+ color_value = line[19:-1].split(',')
+ color = [float(color_value[0]),
+ float(color_value[1]),
+ float(color_value[2])]
+ # Used radius
+ line = data_file_p.readline()
+ radius_used = float(line[19:-1])
+ # Atomic radius
+ line = data_file_p.readline()
+ radius_atomic = float(line[19:-1])
+ # Van der Waals radius
+ line = data_file_p.readline()
+ radius_vdW = float(line[19:-1])
+ radii = [radius_used,radius_atomic,radius_vdW]
+ radii_ionic = []
+
+ element = ElementProp(number,name,short_name,color,
+ radii, radii_ionic)
+
+ ELEMENTS.append(element)
+
+ data_file_p.close()
+
+ return True
+
+
+# Separating atoms from a dupliverts strucutre.
+def separate_atoms(scn):
+
+ # Get first all important properties from the atoms, which the user
+ # has chosen: location, color, scale
+ obj = bpy.context.edit_object
+
+ # Do nothing if it is not a dupliverts structure.
+ if not obj.dupli_type == "VERTS":
+ return {'FINISHED'}
+
+ bm = bmesh.from_edit_mesh(obj.data)
+
+ locations = []
+
+ for v in bm.verts:
+ if v.select:
+ locations.append(obj.matrix_world * v.co)
+
+ bm.free()
+ del(bm)
+
+ name = obj.name
+ scale = obj.children[0].scale
+ material = obj.children[0].active_material
+
+ # Separate the vertex from the main mesh and create a new mesh.
+ bpy.ops.mesh.separate()
+ new_object = bpy.context.scene.objects[0]
+ # And now, switch to the OBJECT mode such that we can ...
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+ # ... delete the new mesh including the separated vertex
+ bpy.ops.object.select_all(action='DESELECT')
+ new_object.select = True
+ bpy.ops.object.delete()
+
+ # Create new atoms/vacancies at the position of the old atoms
+ current_layers=bpy.context.scene.layers
+
+ # For all selected positions do:
+ for location in locations:
+ # For any ball do ...
+ if "Vacancy" not in name:
+ # NURBS ball
+ if obj.children[0].type == "SURFACE":
+ bpy.ops.surface.primitive_nurbs_surface_sphere_add(
+ view_align=False, enter_editmode=False,
+ location=location,
+ rotation=(0.0, 0.0, 0.0),
+ layers=current_layers)
+ # Mesh ball
+ elif obj.children[0].type == "MESH":
+ bpy.ops.mesh.primitive_uv_sphere_add(
+ segments=32,
+ ring_count=32,
+ #segments=scn.mesh_azimuth,
+ #ring_count=scn.mesh_zenith,
+ size=1, view_align=False, enter_editmode=False,
+ location=location,
+ rotation=(0, 0, 0),
+ layers=current_layers)
+ # Metaball
+ elif obj.children[0].type == "META":
+ bpy.ops.object.metaball_add(type='BALL', view_align=False,
+ enter_editmode=False, location=location,
+ rotation=(0, 0, 0), layers=current_layers)
+ # If it is a vacancy create a cube ...
+ else:
+ bpy.ops.mesh.primitive_cube_add(
+ view_align=False, enter_editmode=False,
+ location=location,
+ rotation=(0.0, 0.0, 0.0),
+ layers=current_layers)
+
+ new_atom = bpy.context.scene.objects.active
+ # Scale, material and name it.
+ new_atom.scale = scale
+ new_atom.active_material = material
+ new_atom.name = name + "_sep"
+ new_atom.select = True
+
+ bpy.context.scene.objects.active = obj
+ #bpy.ops.object.select_all(action='DESELECT')
diff --git a/release/scripts/addons_contrib/io_directx_bel/README b/release/scripts/addons_contrib/io_directx_bel/README
new file mode 100644
index 0000000..2867827
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/README
@@ -0,0 +1,266 @@
+a DirectX importer addon for Blender 2.6
+
+first goals :
+
+. to import anything from an .x file.
+ obviously verts, faces but uv, armatures, weights, normals...
+. import .x in binary format too
+
+horizon :
+. export to .x or mod/co-maintain the existing x exporter.
+. this project is also a prototype for a 'Blender Exchange Layer' project.
+ BEL would be a common layer logically located between an importer/exporter
+ addon and the blender data format, that would allow :
+ . to provide a common set of methods to retrieve/inject objects in Blender
+ . to provide a common set of transformation and selection tools between an
+ import/export script and Blender datas (rotate, rescale, filters...)
+ . to provide a common set of parsing helpers for new io addons
+
+PLY won't be used unfortunately (it's way too slow as far as I tested)
+
+
+TO TEST THE SCRIPT :
+ . copy the 'io_directx_bel' in /scripts/addons or addons_contrib
+ . start blender
+ . enable then addon in user prefs > addons
+ . run the script with file > import > directX
+
+25/01/12 0.18
+ . code rewrite according to api bmesh changes (me.polygon and uv layers essentially)
+ . implemented foreachset() call for uv import (faster)
+
+25/01/12 0.17
+ . faster, 60% faster in some case : various loops improvements, infile templates parsing disabled by default
+ saw another bottleneck about data chunks as string but will wait for binary support for better point of view.
+ . interface cosmetics
+
+23/01/12 rc 0.16
+. committed to svn (and littleneo git as usual)
+. corrected a bug about referenced token parenting
+. corrected a bug about non parented meshes
+. armatures/empties importation enabled by default
+. last run importer options are saved in a 'last_run' preset,
+ so it can be replayed or saved under another name once a
+ particular .x profile has been defined
+. tagged script for 2.6.1
+
+12/01/12 rc 0.15 :)
+. name conversion changed from 5 to 4 digits
+. matname, imagename and texturename fixes :
+. a path test is made at image import time with any existing data images,
+ so a same file cant be loaded twice wathever the naming method, / or \, rel or abs etc
+ (bel.material.new() and after line 835)
+. image and texture names should be ok now (tested with : incrediblylongname.x)
+. materials are replaced accordingly in existing objs when using the 'replace' naming method
+. fyi, the Dx exporter has the following inconveniences :
+ . split linked faces into individual faces
+ . inversed uvmapping (y axis) ?
+ -> see testfiles/blender_x_export/incrediblylongname.x
+
+29 and 31/12/11
+. Cosmetics, code cleaning and optimizations
+. bpy.ops.object.select_name methods replaced with
+ ob.select = True
+ bpy.context.scene.objects.active = ob
+. corrected a big bug about tokens info appending in dXtree()
+. new bpyname() method in bel module. removed bel.common
+
+26/12/11
+. armature import and bone max. length option
+
+23/11/11
+. contrib candidate :)
+. solved some naming cases, added bel methods.
+. added experimental option about parenting (no armature yet just empties, when needed)
+. a bit faster
+. added some test files (empty parenting, armature etc)
+
+22/11/11
+campbell feedback (cont):
+. added naming methods as options (default is blender name inc. if name exists)
+ me and ob remove() should be ok with special cases (empties, mesh with multi-users)
+. improved ui
+
+
+21/11/11
+campbell feedback :
+. converted immutables to tuples : templates_x.py and some other vars.
+ http://stackoverflow.com/questions/3340539/why-tuple-is-faster-than-list
+. dprint() (console debug) removed, replaced by a inloop tests (a bit faster)
+ I'd like to keep it for now for easier debug (eg user feedbacks with 'processing' option)
+
+19/11/11
+. object parenting support. parsing the x tree from roots using import_dxtree()
+ actually faster than before
+
+16/11/11
+. weight group import
+. improved ui a bit and console logs
+. x matrices to blender ones conversion
+
+14/11/11
+. global matrix options
+. added messy code about binary (not working)
+
+11/11/11
+. import materials and textures (basics) : uv and image mapped (multitex mode)
+ and material created with tex slot if any. alpha should be ok.. ?
+. added a smooth options
+. better tolerance with faulty .x (upper/lower case of template names)
+. token names length from x to blender conversion should be ok also (long name cases)
+. corrected a parser pointer error after one array parsing case.
+. added more templates (for mat and tex support)
+. removed texture files from repo in testfile (tex does not match meshes )
+ added some other x files for further tests in binary and compressed format
+ ( http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/test/models/X/ )
+
+08/11/11
+. turned into an addon (fork from obj import so unused functions atm)
+ enable it in addon, then file > import > directx
+. splitted directx parser (io_directx_bel folder) and bel draft
+ the bel folder is intended to be located in /scripts/modules (shared components)
+ but it's ok in scripts/addons too (tbd)
+ bel folder (will) includes anything related to blender data helper (read/write)
+. corrected duplicated quotes for x string type
+
+07/11/11
+. uv import
+. generic directx token parser. templates items are used to read datas of any token type
+ a bit slower but cool since it should support non strict standard directx files
+ virtually it can retrieve everything from now supposing the template is know
+ by default or given in the file. calls are now like :
+ nbslots, mats = readToken('MeshMaterialList001') or
+ uv = readToken('uv001') or
+ nVerts, verts, nFaces, faces = readToken('Hydralisk_backbone1') etc
+. removed the specific mesh parser the 'rigid' file is the last before mutation to
+ generic parser. a bit faster but harder to make evolve or adapt. keep it as a faster
+ strict 'branch'
+. added some default templates
+ goals / wip :
+ . to compare template declaration in file and default one.
+ so either use the default one (strict) or the .x one (could differ)
+ . use by the generic data parser to avoid a parser for each kind of token
+. cleaner code (grouping methods, function names, docs etc)
+ functions separated from calls
+ renamed token dict as tokens etc
+. added tweaks at the beginning of the file :
+ chunksize = 1024 # size of file streams red in a row
+ quickmode = False # this to only find meshes (no parenting, no other tokens than Mesh ones)
+ showtree = False # display the entire token tree in the console
+ showtemplate = True # display template datas found in file
+. added a patch for malformed datas of vertices (meshFaces) :
+ # patch for malformed datas not completely clear yet ( I guess
+ # there's bunch of us when looking at meshface syntax in .x files) :
+ # when array members are like 3;v0,v1,v2;,
+ # and not like 3;v0;v1;v2;, depending on template declarations.
+ # http://paulbourke.net/dataformats/directx/#xfilefrm_Use_of_commas
+. the script now generates linked faces (was not my fault !)
+ > it seems Dx always separate each face :
+ so it defines (vert * linked faces) verts for one needed vert
+ the readvertices loop now remove duplicates at source
+ it uses a verts lookup list to redirect vert id defined in faces
+
+06/11/11
+. vertices and faces imported from each test files
+. added some info to test yourself in README
+. switched to binary for .x as text to retrieve eol (pointer bugs). should be ok whatever it's win, mac or unix text format,
+ also works with mixed eol.
+ it seems python 3.1 can't return a 'line' when data.realine() when read mode is 'rb' (U default and universal ? really ? ;) )
+ when file has mac eol (\r)
+ -> read(1024) in binary, decode, and replace any \r with \n. yes, it doubles lines for windows and lines value is wrong for now
+ -> but the used pointer value is always ok now whatever the file format and still way faster than a data.tell()
+ see CRCF folder to compare output wispwind.x by format.
+. files are still splitted into chunks (1024 B) and readable as lines
+. references : added 'user' fields when token is used. users store a reference with their childs but with a '*' tag at chr0.
+ the tree reflects the changes
+. now read anything and add it to the 'tree'. this includes unknow tokens.
+. references are recognized. by reference I mean fields like { cube0 } rather than an inline frame cube0 {
+ declaration.
+ I don't know if one item can be referenced several time or referenced before declaration
+ should be.. waiting for a case. for now only one 'parent' token, messages will show up
+ multi references to one token if cases arise.
+. more permissive syntax : 'frame spam{', 'frame spam egg{', 'frame spam egg {'..
+. comments are recognized (inlines ones not done yet, since still no useful data red :) )
+. header is red
+. found other .x test files here :
+ http://www.xbdev.net/3dformats/x/xfileformat.php
+ created from 3ds max
+. added .x files in repo. line 70 and following to switch.
+. some token comes with no names, add a noname<00000> to them
+. console gives line number (more useful than char position I guess)
+
+
+05/11/11 day 0 :
+
+. made some disapointing test with ply (from a speed point of view, else it looks really cool)
+. made my own parser
+. nothing imported for now, it's more about self-eduction to .x and concept
+. but it reads the .x structure and can gather some info
+
+resource gathered :
+
+http://paulbourke.net/dataformats/directx/
+http://www.informikon.com/various/the-simplest-skeletal-animation-possible.html
+http://msdn.microsoft.com/en-us/library/windows/desktop/bb173011%28v=VS.85%29.aspx
+http://www.toymaker.info/Games/index.html
+
+
+
+step 1 : read main structure :
+
+ read main token names (any 'template', any 'frame', any 'mesh')
+ stores names in a token directory :
+ token['template'] for templates :
+ token['template'][templatename]
+ token['template'][templatename]['pointer'] (int) chr position in .x file (tell() like*)
+ token['template'][templatename]['line'] (int) line number in .x file
+ token['frame'] for frame and mesh type :
+ token['template'][frame or mesh name]
+ token['template'][frame or mesh name]['pointer'] (int) chr position in .x file (tell() like*)
+ token['template'][frame or mesh name]['line'] (int) line number in .x file
+ token['template'][frame or mesh name]['type'] (str) 'ob/bone' or 'mesh'
+ token['template'][frame or mesh name]['parent'] (str) frame parent of current item
+ token['template'][frame or mesh name]['childs'] (str list) list of child frame or mesh names
+ token['template'][frame or mesh name]['matrix'] (int) for now chr position of FrameTransformMatrix
+
+at the end of step 1 the script prints a tree of these datas
+
+step 2 : read template definitions :
+
+ for each template in dict, populate definitions in it.
+ it creates new fields in each token['template'][templatename]
+ according to values found in .x :
+ token['template'][templatename]['uuid'] (str) <universally unique identifier>
+ token['template'][templatename]['members']['name'] (str) member name
+ token['template'][templatename]['members']['type'] (str) DWORD,FLOAT etc keywords or template name
+ token['template'][templatename]['restriction'] (str) 'open' , 'closed' , or the specidied (restricted) value
+
+that's all for now.
+
+idea would be to allow 2 steps importation and random access to file :
+
+ . first the file is quickly parsed. we only retrieve main info, nothing about verts, faces etc
+ info like number of mats, textures, objects/mesh/bone trees
+ for now : 150000 lines in 5 secs for step 1
+ . then user select what to import
+ . then the script retrieve selected datas according to selection, using the 'pointer' value
+ to seek() to the needed data, then grab/parse/translate in something usable.
+ . template are used at this point to know how to parse a specific part (adaptive parser)
+
+ so far this looks fast.
+
+tested on windows. can be important because of eol and the code I wrote to compute pointer value.
+(data.tell() is slow)
+only one .x file tested, header is : xof 0303txt 0032 (windows \r\n eol)
+
+don't know a lot about .x format :
+
+uuid :
+ are the member/restriction always the same for a same uuid/template ?
+ template name can vary for a same uuid ?
+syntax :
+ blank lines IN a stream of a {} section, after ; ?
+ comments // and # IN a stream of data ?
+ '{' and '<something>' and '}' on the same line or '{' '}' are always unique ?
+
+
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/__init__.py b/release/scripts/addons_contrib/io_directx_bel/__init__.py
new file mode 100644
index 0000000..a2b5687
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/__init__.py
@@ -0,0 +1,296 @@
+# Blender directX importer
+bl_info = {
+ "name": "DirectX Importer",
+ "description": "Import directX Model Format (.x)",
+ "author": "Littleneo (Jerome Mahieux)",
+ "version": (0, 18),
+ "blender": (2, 63, 0),
+ "api": 42615,
+ "location": "File > Import > DirectX (.x)",
+ "warning": "",
+ "wiki_url": "https://github.com/littleneo/directX_blender/wiki",
+ "tracker_url": "https://github.com/littleneo/directX_blender/issues",
+ "category": "Import-Export",
+ "dependencies": ""
+}
+
+if "bpy" in locals():
+ import imp
+ if "import_x" in locals():
+ imp.reload(import_x)
+ #if "export_x" in locals():
+ # imp.reload(export_x)
+
+
+import bpy
+from bpy.props import (BoolProperty,
+ FloatProperty,
+ StringProperty,
+ EnumProperty,
+ )
+from bpy_extras.io_utils import (ExportHelper,
+ ImportHelper,
+ path_reference_mode,
+ axis_conversion,
+ )
+try : import bel
+except : import io_directx_bel.bel
+
+class ImportX(bpy.types.Operator, ImportHelper):
+ '''Load a Direct x File'''
+ bl_idname = "import_scene.x"
+ bl_label = "Import X"
+ bl_options = {'PRESET', 'UNDO'}
+
+ filename_ext = ".x"
+ filter_glob = StringProperty(
+ default="*.x",
+ options={'HIDDEN'},
+ )
+ show_tree = BoolProperty(
+ name="Show x tokens tree",
+ description="display relationships between x items in the console",
+ default=False,
+ )
+ show_templates = BoolProperty(
+ name="Show x templates",
+ description="display templates defined in the .x file",
+ default=False,
+ )
+ show_geninfo = BoolProperty(
+ name="Show processing",
+ description="display details for each imported thing",
+ default=False,
+ )
+
+ quickmode = BoolProperty(
+ name="Quick mode",
+ description="only retrieve mesh basics",
+ default=False,
+ )
+
+ parented = BoolProperty(
+ name="Object Relationships",
+ description="import armatures, empties, rebuild parent-childs relations",
+ default=True,
+ )
+
+ bone_maxlength = FloatProperty(
+ name="Bone length",
+ description="Bones max length",
+ min=0.1, max=10.0,
+ soft_min=0.1, soft_max=10.0,
+ default=1.0,
+ )
+
+ chunksize = EnumProperty(
+ name="Chunksize",
+ items=(('0', "all", ""),
+ ('4096', "4KB", ""),
+ ('2048', "2KB", ""),
+ ('1024', "1KB", ""),
+ ),
+ default='2048',
+ description="number of bytes red in a row",
+ )
+ naming_method = EnumProperty(
+ name="Naming method",
+ items=(('0', "increment name if exists", "blender default"),
+ ('1', "use existing", "this only append new elements"),
+ ('2', "rename existing", "names are forced"),
+ ('3', "replace existing", ""),
+ ),
+ default='0',
+ description="behaviour when a name already exists in Blender Data",
+ )
+ use_ngons = BoolProperty(
+ name="NGons",
+ description="Import faces with more then 4 verts as fgons",
+ default=True,
+ )
+ use_edges = BoolProperty(
+ name="Lines",
+ description="Import lines and faces with 2 verts as edge",
+ default=True,
+ )
+ use_smooth_groups = BoolProperty(
+ name="Smooth Groups",
+ description="Surround smooth groups by sharp edges",
+ default=True,
+ )
+
+ use_split_objects = BoolProperty(
+ name="Object",
+ description="Import OBJ Objects into Blender Objects",
+ default=True,
+ )
+ use_split_groups = BoolProperty(
+ name="Group",
+ description="Import OBJ Groups into Blender Objects",
+ default=True,
+ )
+
+ use_groups_as_vgroups = BoolProperty(
+ name="Poly Groups",
+ description="Import OBJ groups as vertex groups",
+ default=False,
+ )
+
+ use_image_search = BoolProperty(
+ name="Image Search",
+ description="Search subdirs for any assosiated images " \
+ "(Warning, may be slow)",
+ default=True,
+ )
+
+ split_mode = EnumProperty(
+ name="Split",
+ items=(('ON', "Split", "Split geometry, omits unused verts"),
+ ('OFF', "Keep Vert Order", "Keep vertex order from file"),
+ ),
+ )
+
+ global_clamp_size = FloatProperty(
+ name="Clamp Scale",
+ description="Clamp the size to this maximum (Zero to Disable)",
+ min=0.0, max=1000.0,
+ soft_min=0.0, soft_max=1000.0,
+ default=0.0,
+ )
+
+ axis_forward = EnumProperty(
+ name="Forward",
+ items=(('X', "Left (x)", ""),
+ ('Y', "Same (y)", ""),
+ ('Z', "Bottom (z)", ""),
+ ('-X', "Right (-x)", ""),
+ ('-Y', "Back (-y)", ""),
+ ('-Z', "Up (-z)", ""),
+ ),
+ default='-Z',
+ )
+
+ axis_up = EnumProperty(
+ name="Up",
+ items=(('X', "Right (x)", ""),
+ ('Y', "Back (y)", ""),
+ ('Z', "Same (z)", ""),
+ ('-X', "Left (-x)", ""),
+ ('-Y', "Front (-y)", ""),
+ ('-Z', "Bottom (-z)", ""),
+ ),
+ default='Y',
+ )
+
+ def execute(self, context):
+ from . import import_x
+ if self.split_mode == 'OFF':
+ self.use_split_objects = False
+ self.use_split_groups = False
+ else:
+ self.use_groups_as_vgroups = False
+
+ keywords = self.as_keywords(ignore=("axis_forward",
+ "axis_up",
+ "filter_glob",
+ "split_mode",
+ ))
+
+ keywords["naming_method"] = int(self.naming_method)
+
+ global_matrix = axis_conversion(from_forward=self.axis_forward,
+ from_up=self.axis_up,
+ ).to_4x4()
+ keywords["global_matrix"] = global_matrix
+
+
+ bel.fs.saveOptions(self,'import_scene.x', self.as_keywords(ignore=(
+ "filter_glob",
+ "filepath",
+ )))
+ return import_x.load(self, context, **keywords)
+
+ def draw(self, context):
+ layout = self.layout
+
+ # import box
+ box = layout.box()
+ col = box.column(align=True)
+ col.label('Import Options :')
+ col.prop(self, "chunksize")
+ col.prop(self, "use_smooth_groups")
+ actif = not(self.quickmode)
+ row = col.row()
+ row.enabled = actif
+ row.prop(self, "parented")
+ if self.parented :
+ row = col.row()
+ row.enabled = actif
+ row.prop(self, "bone_maxlength")
+ col.prop(self, "quickmode")
+
+ # source orientation box
+ box = layout.box()
+ col = box.column(align=True)
+ col.label('Source Orientation :')
+ col.prop(self, "axis_forward")
+ col.prop(self, "axis_up")
+
+ # naming methods box
+ box = layout.box()
+ col = box.column(align=True)
+ col.label('Naming Method :')
+ col.props_enum(self,"naming_method")
+
+ # info/debug box
+ box = layout.box()
+ col = box.column(align=True)
+ col.label('Info / Debug :')
+ col.prop(self, "show_tree")
+ col.prop(self, "show_templates")
+ col.prop(self, "show_geninfo")
+
+ #row = layout.row(align=True)
+ #row.prop(self, "use_ngons")
+ #row.prop(self, "use_edges")
+
+ '''
+ box = layout.box()
+ row = box.row()
+ row.prop(self, "split_mode", expand=True)
+
+ row = box.row()
+ if self.split_mode == 'ON':
+ row.label(text="Split by:")
+ row.prop(self, "use_split_objects")
+ row.prop(self, "use_split_groups")
+ else:
+ row.prop(self, "use_groups_as_vgroups")
+
+ row = layout.split(percentage=0.67)
+ row.prop(self, "global_clamp_size")
+
+ layout.prop(self, "use_image_search")
+ '''
+
+def menu_func_import(self, context):
+ self.layout.operator(ImportX.bl_idname, text="DirectX (.x)")
+
+#def menu_func_export(self, context):
+# self.layout.operator(ExportX.bl_idname, text="DirectX (.x)")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+ #bpy.types.INFO_MT_file_export.append(menu_func_export)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+ #bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py b/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py
new file mode 100644
index 0000000..fcc6a5c
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/__init__.py
@@ -0,0 +1,23 @@
+# set a given name to a unique
+# blender data name in its collection
+def bpyname(name,collection,limit=63,suffix=4) :
+ name = name[:limit-suffix]
+ tpl = '%s.%.'+str(suffix)+'d'
+ bname = name
+ id = 0
+ while bname in collection :
+ id += 1
+ bname = tpl%(name,id)
+ return bname
+
+## check if there's nested lists in a list. used by functions that need
+# list(s) of vertices/faces/edges etc as input
+# @param lst a list of vector or a list of list of vectors
+# @returns always nested list(s)
+# a boolean True if was nested, False if was not
+def nested(lst) :
+ try :
+ t = lst[0][0][0]
+ return lst, True
+ except :
+ return [lst], False
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/fs.py b/release/scripts/addons_contrib/io_directx_bel/bel/fs.py
new file mode 100644
index 0000000..18e2b2c
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/fs.py
@@ -0,0 +1,73 @@
+# v0.1
+import bpy
+from os import path as os_path, listdir as os_listdir
+from bpy import path as bpy_path
+
+# cross platform paths (since ms conform to / path ;) )
+# maybe add utf8 replace to old ascii blender builtin
+# // can be omitted for relative
+def clean(path) :
+ path = path.strip().replace('\\','/')
+ if ('/') not in path : path = '//'+path
+ return path
+
+## test for existence of a file or a dir
+def exist(path) :
+ if isfile(path) or isdir(path) : return True
+ return False
+
+## test for existence of a file
+def isfile(path) :
+ if os_path.isfile(path) : return True
+ # could be blender relative
+ path = bpy_path.abspath(path)
+ if os_path.isfile(path) : return True
+ return False
+
+## test for existence of a dir
+def isdir(path) :
+ if os_path.isdir(path) : return True
+ # could be blender relative
+ path = bpy_path.abspath(path)
+ if os_path.isdir(path) : return True
+ return False
+
+## returns a list of every absolute filepath
+# to each file within the 'ext' extensions
+# from a folder and its subfolders
+def scanDir(path,ext='all') :
+ files = []
+ fields = os_listdir(path)
+ if ext != 'all' and type(ext) != list : ext = [ext]
+ for item in fields :
+ if os_path.isfile(path + '/' + item) and (ext == 'all' or item.split('.')[-1] in ext) :
+ #print(' file %s'%item)
+ files.append(path + '/' + item)
+ elif os_path.isdir(path + '/' + item) :
+ print('folder %s/%s :'%(path,item))
+ files.extend(scanDir(path + '/' + item))
+ return files
+
+def saveOptions(op,operator_name, tokens, filename='last_run'):
+ #print(op.as_keywords())
+ #print(dir(op))
+ target_path = os_path.join("operator", operator_name)
+ target_path = os_path.join("presets", target_path)
+ target_path = bpy.utils.user_resource('SCRIPTS',target_path,create=True)
+ if target_path:
+ filepath = os_path.join(target_path, filename) + ".py"
+ file_preset = open(filepath, 'w')
+ file_preset.write("import bpy\nop = bpy.context.active_operator\n\n")
+ properties_blacklist = bpy.types.Operator.bl_rna.properties.keys()
+ for key, value in tokens.items() :
+ if key not in properties_blacklist :
+ # convert thin wrapped sequences to simple lists to repr()
+ try:
+ value = value[:]
+ except:
+ pass
+
+ file_preset.write("op.%s = %r\n" % (key, value))
+
+ file_preset.close()
+
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/image.py b/release/scripts/addons_contrib/io_directx_bel/bel/image.py
new file mode 100644
index 0000000..74f45b2
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/image.py
@@ -0,0 +1,259 @@
+import bpy
+import bpy.path
+
+from . import __init__ as bel
+from . import fs
+
+debuglevel = 0
+
+def dprint(str,l=2) :
+ if l <= debuglevel :
+ print(str)
+
+# create or retrieve a bdata image
+# given its path
+def new(path, name=False, relative = True) :
+ path = fs.clean(path)
+ # check file
+ if fs.isfile(path) == False :
+ dprint('Texture image not found')
+ return False
+
+ if relative :
+ try :
+ path = bpy.path.relpath(path)
+ path = fs.clean(path)
+ except :
+ print('cant turn path into relative one (.blend and img path drive letters ?) ')
+
+ # retrieve paths to image file from existing image slot
+ # returns img if paths match
+ for img in bpy.data.images :
+ if img.filepath != '' :
+ if bpy.path.abspath(path) == bpy.path.abspath(fs.clean(img.filepath)) :
+ return img
+
+ # create a unique name in image slot
+ if name == False :
+ name = bpy.path.basename(path)
+ name = bel.bpyname(name,bpy.data.images.keys())
+
+ # finally :
+ img = bpy.data.images.load(filepath=path)
+ img.name = name
+ return img
+
+
+def applyShader(mat,config) :
+
+ # matslot.link = 'DATA'
+ #mat = bpy.data.materials['Female_Body']
+
+ texslot = mat.texture_slots[0]
+ tex = texslot.texture
+ img = tex.image
+
+ #config = shaders[shadername]
+ alpha = True if 'alpha' in config else False
+
+ ## MAT
+
+ mat.type = 'SURFACE'
+ # diffuse
+ mat.diffuse_color = Color((0.6, 0.6, 0.6))
+ mat.diffuse_intensity = 0.8
+ mat.diffuse_shader = 'LAMBERT'
+ mat.use_diffuse_ramp = False
+
+ # specular
+ mat.specular_color = Color((1.0, 1.0, 1.0))
+ mat.specular_intensity = 0.25
+ mat.specular_shader = 'COOKTORR'
+ mat.use_specular_ramp = False
+ mat.specular_hardness = 1.0
+
+ # shading
+ mat.emit = 0.0
+ mat.ambient = 0.5
+ mat.translucency = 0.0
+ mat.use_shadeless = False
+ mat.use_tangent_shading = False
+ mat.use_cubic = False
+
+ # transparency
+ mat.use_transparency = alpha
+ mat.transparency_method = 'Z_TRANSPARENCY'
+ mat.alpha = not(alpha)
+ mat.specular_alpha = not(alpha)
+ mat.raytrace_transparency.fresnel = 0.0
+ mat.raytrace_transparency.fresnel_factor = 1.25
+
+ # mirror
+ mat.raytrace_mirror.use = False
+
+ # subsurface_scattering
+ mat.subsurface_scattering.use
+
+ # strand
+ # options
+ # shadow
+ mat.use_shadows = True
+ mat.use_transparent_shadows = True
+ mat.use_cast_shadows_only = False
+ mat.shadow_cast_alpha = 1.0
+ mat.use_only_shadow = False
+ mat.shadow_only_type = 'SHADOW_ONLY_OLD'
+ mat.use_cast_buffer_shadows = True
+ mat.shadow_buffer_bias = 0.0
+ mat.use_ray_shadow_bias = True
+ mat.shadow_ray_bias = 0.0
+ mat.use_cast_approximate = True
+
+ # TEXTURE SLOT 0
+
+ # diffuse
+ texslot.diffuse_factor = 1.0
+ texslot.use_map_diffuse = True
+ texslot.diffuse_color_factor = 1.0
+ texslot.use_map_color_diffuse = True
+ texslot.alpha_factor = 1.0
+ texslot.use_map_alpha = alpha
+ texslot.translucency_factor = 0.0
+ texslot.use_map_translucency = False
+
+ # specular
+ texslot.specular_factor = 0.3
+ texslot.use_map_specular = True
+ texslot.specular_color_factor = 1.0
+ texslot.use_map_color_spec = True
+ texslot.hardness_factor = 0.1
+ texslot.use_map_hardness = True
+
+ # shading
+ texslot.ambient_factor = 0.0
+ texslot.use_map_ambient = False
+ texslot.emit_factor = 0.1
+ texslot.use_map_emit = True
+ texslot.mirror_factor = 0.0
+ texslot.use_map_mirror = False
+ texslot.raymir_factor = 0.0
+ texslot.use_map_raymir = False
+
+ # geometry
+ texslot.normal_factor = 0.0
+ texslot.use_map_normal = False
+ texslot.warp_factor = 0.1
+ texslot.use_map_warp = False
+ texslot.displacement_factor = 0.0
+ texslot.use_map_displacement = False
+
+ texslot.blend_type = 'MIX'
+ texslot.invert = False
+ texslot.use_rgb_to_intensity = False
+ texslot.color = Color((1.0, 0.0, 1.0)) # default
+ texslot.use_stencil = False
+ texslot.default_value = 1.0
+
+ # TEXTURE
+ tex.use_alpha = alpha
+ tex.use_preview_alpha = alpha
+
+def BSshader(nodes,pointer) :
+ tkm = bpy.context.scene.tkm
+ typ, nodename = pointer.split(' ')
+ RenderShader = nodes[typ][nodename]
+ name = BSname(nodename,RenderShader['Object.Name'])
+ if name in bpy.data.materials :
+ mat = bpy.data.materials[name]
+ else :
+ mat = bpy.data.materials.new(name=name)
+ # Unused
+ DepthWriteEnable = RenderShader['DepthWriteEnable'] if 'DepthWriteEnable' in RenderShader else False # an integer
+ ShaderTransparency = RenderShader['MultiDrawLayer'] if 'MultiDrawLayer' in RenderShader else False # an integer
+ LightEnable = RenderShader['LightEnable'] if 'LightEnable' in RenderShader else False # an integer
+
+ ShaderPhong = BSnode(nodes,RenderShader['Surface'])
+ #print('mat : %s'%ShaderPhong['Material'])
+ RenderMaterial = BSnode(nodes,ShaderPhong['Material'])
+ DiffuseColor = RenderMaterial['DiffuseColor'] if 'DiffuseColor' in RenderMaterial else False
+ SpecularColor = RenderMaterial['SpecularColor'] if 'SpecularColor' in RenderMaterial else False
+ AmbientColor = RenderMaterial['AmbientColor'] if 'AmbientColor' in RenderMaterial else False
+ EmissionColor = RenderMaterial['Shininess'] if 'EmissionColor' in RenderMaterial else False
+ Shininess = RenderMaterial['Shininess'] if 'Shininess' in RenderMaterial else False
+ Transparency = RenderMaterial['Transparency'] if 'Transparency' in RenderMaterial else False
+ for key in RenderMaterial.keys() :
+ if key not in ['DiffuseColor','SpecularColor','AmbientColor','EmissionColor','Shininess','Transparency'] :
+ print('NEW RENDERMATERIAL PROP ! : %s'%key)
+
+ #print(AmbientColor)
+ if DiffuseColor : mat.diffuse_color = Color(DiffuseColor) #[0][0],DiffuseColor[0][1],DiffuseColor[0][2])
+ if SpecularColor : mat.specular_color = Color(SpecularColor)#[0][0],SpecularColor[0][1],SpecularColor[0][2])
+ if AmbientColor : mat.ambient = AmbientColor[0] # source value is a vector3f with x=y=z
+ if EmissionColor : mat.emit = EmissionColor[0] # source value is a vector3f with x=y=z
+ #if Shininess : mat.
+ #alpha is a boolean, whereas Transparency is a float or False
+ if Transparency :
+ mat.use_transparency = True
+ mat.transparency_method = 'Z_TRANSPARENCY'
+ mat.alpha = Transparency
+ mat.specular_alpha = 0
+ alpha = True
+ else : alpha = False
+ texinfluence = False
+ if 'Color' in ShaderPhong :
+ ShaderTexture = BSnode(nodes,ShaderPhong['Color'])
+ texinfluence = 'Color'
+ if 'Reflection' in ShaderPhong :
+ ShaderTexture = BSnode(nodes,ShaderPhong['Reflection'])
+ texinfluence = 'Reflection'
+ if texinfluence == False :
+ print('neither color nor refl. in ShaderPhong %s'%RenderShader['Surface'])
+ print('other props are : %s'%ShaderPhong.keys())
+ return mat
+
+ ShaderTextureName = ShaderTexture['Object.Name']
+
+ Texture2D = BSnode(nodes,ShaderTexture['Texture'])
+ Texture2DName = Texture2D['Object.Name']
+
+ FileObject = BSnode(nodes,Texture2D['Texture.FileObject'])
+ imgpath = FileObject['FileName']
+ imgname = imgpath.split('/')[-1]
+ imgpath = tkm.path_archives+'/Images/Q=Tex032M/'+imgpath
+
+ if imgname not in bpy.data.images :
+ if os.path.isfile(imgpath+'.png') : ext = '.png'
+ elif os.path.isfile(imgpath+'.jp2') : ext = '.jp2'
+ else :
+ print('Texture image not found ! %s'%Texture2D['Texture.FileObject'])
+ print('path : %s.png or .jp2 '%imgpath)
+ return mat
+ img = bpy.data.images.load(filepath=imgpath+ext)
+ img.name = imgname
+ else : img = bpy.data.images[imgname]
+
+ '''
+ texslot = mat.texture_slots[0]
+ mat.texture_slots[0]
+ tex = texslot.texture
+ tex.type = 'IMAGE'
+ img = tex.image
+ img.name
+ '''
+ #img = bpy.data.images.new(name='imgname',width=640, height=512)
+
+ if ShaderTextureName not in bpy.data.textures :
+ tex = bpy.data.textures.new(name=ShaderTextureName,type='IMAGE')
+ tex.image = img
+ tex.use_alpha = alpha
+ tex.use_preview_alpha = alpha
+ else : tex = bpy.data.textures[ShaderTextureName]
+
+ texslot = mat.texture_slots.create(index=0)
+ texslot.texture = tex
+ texslot.texture_coords = 'UV'
+ texslot.uv_layer = 'UV0'
+ texslot.use_map_alpha = alpha
+ texslot.alpha_factor = 1.0
+
+ return mat
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/material.py b/release/scripts/addons_contrib/io_directx_bel/bel/material.py
new file mode 100644
index 0000000..d39f32c
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/material.py
@@ -0,0 +1,32 @@
+import bpy
+
+'''
+given name < 21
+if material name exists :
+naming_method = 0 blender default (increment name)
+naming_method = 1 do nothing, abort creation and use existing
+naming_method = 2 create new, rename existing,
+naming_method = 3 create new, replace existing
+'''
+
+def new(name, naming_method=0) :
+ if name not in bpy.data.materials or naming_method == 0:
+ return bpy.data.materials.new(name=name)
+
+ elif naming_method == 1 :
+ return bpy.data.materials[name]
+
+ mat = bpy.data.materials.new(name=name)
+
+ if naming_method == 2 :
+ mat.name = name
+ return mat
+
+ # naming_method = 3 : replace
+ prevmat = bpy.data.materials[name]
+ for ob in bpy.data.objects :
+ for matslot in ob.material_slots :
+ if matslot.material == prevmat :
+ matslot.material = mat
+ bpy.data.materials.remove(prevmat)
+ return mat
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py b/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py
new file mode 100644
index 0000000..eee416c
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/mesh.py
@@ -0,0 +1,208 @@
+##\file
+# raw extract quick cleaning from blended cities2.6 project. thanks to myself for cooperation, but what a messy code we have here.
+import bpy
+import mathutils
+from mathutils import *
+
+from . import uv as buv
+from . import ob as bob
+
+debuglevel = 0
+'''
+wip.. naming behaviour previous to any data
+name exist ?
+no : create
+yes :
+ naming_method = 0 blender default (increment name)
+ naming_method = 1 do nothing, abort creation and use existing
+ naming_method = 2 create new, rename existing,
+ naming_method = 3 create new, remove existing
+
+for now, and mesh data, 0 2 or 3
+'''
+
+## material listed in matslots must exist before creation of material slots
+
+def write(obname,name,
+ verts=[], edges=[], faces=[],
+ matslots=[], mats=[], uvs=[],
+ groupnames=[], vindices=[], vweights=[],
+ smooth=False,
+ naming_method = 0,
+ ) :
+
+
+ obj = bpy.data.objects[obname] if obname in bpy.data.objects else False
+ me = bpy.data.meshes[name] if name in bpy.data.meshes else False
+
+ #print(naming_method,type(obj),type(me))
+ #print(obj,me)
+ #print()
+ if naming_method == 1 and me and obj and obj.data == me :
+ #print('%s and %s exist, reuse'%(obj.name,me.name))
+ return obj
+
+ if naming_method == 3 :
+ if obj :
+ #print('remove ob %s'%obj.name)
+ bob.remove(obj,False)
+ if me :
+ #print('remove me %s'%me.name)
+ bob.removeData(me)
+
+
+ me = bpy.data.meshes.new(name)
+ if naming_method == 2 : me.name = name
+
+ me.from_pydata(verts, edges, faces)
+ me.update()
+
+ if smooth : shadesmooth(me)
+
+ # material slots
+ matimage=[]
+ if len(matslots) > 0 :
+ for matname in matslots :
+ '''
+ if matname not in bpy.data.materials :
+ mat = bpy.data.materials.new(name=matname)
+ mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
+ mat.use_fake_user = True
+ warn.append('Created missing material : %s'%matname)
+ else :
+ '''
+ mat = bpy.data.materials[matname]
+ me.materials.append(mat)
+ texslot_nb = len(mat.texture_slots)
+ if texslot_nb :
+ texslot = mat.texture_slots[0]
+ if type(texslot) != type(None) :
+ tex = texslot.texture
+ if tex.type == 'IMAGE' :
+ img = tex.image
+ if type(img) != type(None) :
+ matimage.append(img)
+ continue
+ matimage.append(False)
+
+ # uvs
+ if len(uvs) > 0 :
+ #buv.write(me, uvs, matimage)
+ buv.flatwrite(me, uvs)
+
+ # map a material to each face
+ if len(mats) > 0 :
+ for fi,f in enumerate(me.polygons) :
+ f.material_index = mats[fi]
+
+ obj = bpy.data.objects.new(name=obname, object_data=me)
+ if naming_method != 0 :
+ obj.name = obname
+
+ '''
+ else :
+ ob = bpy.data.objects[name]
+ ob.data = me
+ if naming_method == 2 : ob.name =
+ ob.parent = None
+ ob.matrix_local = Matrix()
+ print(' reuse object %s'%ob.name)
+ '''
+
+ # vertexgroups
+ if len(groupnames) > 0 :
+ for gpi, groupname in enumerate(groupnames) :
+ weightsadd(obj, groupname, vindices[gpi], vweights[gpi])
+
+ # scene link check
+ if obj.name not in bpy.context.scene.objects.keys() :
+ bpy.context.scene.objects.link(obj)
+
+ return obj
+
+def shadesmooth(me,lst=True) :
+ if type(lst) == list :
+ for fi in lst :
+ me.polygons[fi].use_smooth = True
+ else :
+ for fi,face in enumerate(me.polygons) :
+ face.use_smooth = True
+
+def shadeflat(me,lst=True) :
+ if type(lst) == list :
+ for fi in lst :
+ me.polygons[fi].use_smooth = False
+ else :
+ for fi,face in enumerate(me.polygons) :
+ face.use_smooth = False
+
+def weightsadd(ob, groupname, vindices, vweights=False) :
+ if vweights == False : vweights = [1.0 for i in range(len(vindices))]
+ elif type(vweights) == float : vweights = [vweights for i in range(len(vindices))]
+ group = ob.vertex_groups.new(groupname)
+ for vi,v in enumerate(vindices) :
+ group.add([v], vweights[vi], 'REPLACE')
+
+def matToString(mat) :
+ #print('*** %s %s'%(mat,type(mat)))
+ return str(mat).replace('\n ','')[6:]
+
+def stringToMat(string) :
+ return Matrix(eval(string))
+
+
+def objectBuild(elm, verts, edges=[], faces=[], matslots=[], mats=[], uvs=[] ) :
+ #print('build element %s (%s)'%(elm,elm.className()))
+ dprint('object build',2)
+ city = bpy.context.scene.city
+ # apply current scale
+ verts = metersToBu(verts)
+
+ if type(elm) != str :
+ obname = elm.objectName()
+ if obname == 'not built' :
+ obname = elm.name
+ else : obname= elm
+
+ obnew = createMeshObject(obname, True, verts, edges, faces, matslots, mats, uvs)
+ #elm.asElement().pointer = str(ob.as_pointer())
+ if type(elm) != str :
+ if elm.className() == 'outlines' :
+ obnew.lock_scale[2] = True
+ if elm.parent :
+ obnew.parent = elm.Parent().object()
+ else :
+ #otl = elm.asOutline()
+ #ob.parent = otl.object()
+ objectLock(obnew,True)
+ #ob.matrix_local = Matrix() # not used
+ #ob.matrix_world = Matrix() # world
+ return obnew
+
+def dprint(str,l=2) :
+ if l <= debuglevel :
+ print(str)
+
+
+def materialsCheck(bld) :
+ if hasattr(bld,'materialslots') == False :
+ #print(bld.__class__.__name__)
+ builderclass = eval('bpy.types.%s'%(bld.__class__.__name__))
+ builderclass.materialslots=[bld.className()]
+
+ matslots = bld.materialslots
+ if len(matslots) > 0 :
+ for matname in matslots :
+ if matname not in bpy.data.materials :
+ mat = bpy.data.materials.new(name=matname)
+ mat.use_fake_user = True
+ if hasattr(bld,'mat_%s'%(matname)) :
+ method = 'defined by builder'
+ matdef = eval('bld.mat_%s'%(matname))
+ mat.diffuse_color = matdef['diffuse_color']
+ else :
+ method = 'random'
+ mat.diffuse_color=( random.uniform(0.0,1.0),random.uniform(0.0,1.0),random.uniform(0.0,1.0))
+ dprint('Created missing material %s (%s)'%(matname,method),2)
+
+
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/ob.py b/release/scripts/addons_contrib/io_directx_bel/bel/ob.py
new file mode 100644
index 0000000..486bced
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/ob.py
@@ -0,0 +1,116 @@
+import bpy
+from bpy.types import Mesh, PointLamp, SpotLamp, HemiLamp, AreaLamp, SunLamp, Camera, TextCurve, MetaBall, Lattice, Armature
+
+
+def new(name,datatype,naming_method):
+ if name in bpy.data.objects and naming_method :
+ ob = bpy.data.objects[name]
+ if naming_method == 1 :
+ ob.parent = None
+ ob.user_clear()
+ elif naming_method == 2 :
+ ob = bpy.data.objects.new(name,datatype)
+ ob.name = name
+ elif naming_method == 3 :
+ bpy.context.scene.objects.unlink(ob)
+ ob.user_clear()
+ bpy.data.objects.remove(ob)
+ ob = bpy.data.objects.new(name,datatype)
+ else :
+ ob = bpy.data.objects.new(name,datatype)
+ if ob.name not in bpy.context.scene.objects.keys() :
+ bpy.context.scene.objects.link(ob)
+ return ob
+
+## returns an object or a list of objects
+# @param ob 'all', 'active', 'selected', <object>, 'objectname'
+# @return a list of objects or an empty list
+def get(ob) :
+ if type(ob) == str :
+ if ob == 'all' : return bpy.context.scene.objects
+ elif ob == 'active' : return [bpy.context.active_object] if bpy.context.active_object != None else []
+ elif ob == 'selected' : return bpy.context.selected_objects
+ else :
+ try : return [bpy.data.objects[ob]]
+ except : return []
+ return [ob]
+
+
+## remove an object from blender internal
+def remove(ob,with_data=True) :
+ objs = get(ob)
+ #if objs :
+ # if type(objs) == bpy.types.Object : objs = [objs]
+ for ob in objs :
+ data = ob.data
+ #and_data=False
+ # never wipe data before unlink the ex-user object of the scene else crash (2.58 3 770 2)
+ # if there's more than one user for this data, never wipeOutData. will be done with the last user
+ # if in the list
+ and_data = with_data
+ try :
+ if data.users > 1 :
+ and_data=False
+ except :
+ and_data=False # empties
+
+ # odd (pre 2.60) :
+ # ob=bpy.data.objects[ob.name]
+ # if the ob (board) argument comes from bpy.data.groups['aGroup'].objects,
+ # bpy.data.groups['board'].objects['board'].users_scene
+ ob.name = '_dead'
+ for sc in ob.users_scene :
+ sc.objects.unlink(ob)
+
+ #try :
+ #print(' removing object %s...'%(ob.name)),
+ bpy.data.objects.remove(ob)
+ #print(' done.')
+ #except :
+ # print('removing failed, but renamed %s and unlinked'%ob.name)
+
+ # never wipe data before unlink the ex-user object of the scene else crash (2.58 3 770 2)
+ if and_data :
+ wipeOutData(data)
+
+
+## remove an object data from blender internal
+## or rename it _dead if there's still users
+def removeData(data) :
+ #print('%s has %s user(s) !'%(data.name,data.users))
+
+ if data.users <= 0 :
+
+ #data.user_clear()
+ data_type = type(data)
+
+ # mesh
+ if data_type == Mesh :
+ bpy.data.meshes.remove(data)
+ # lamp
+ elif data_type in [ PointLamp, SpotLamp, HemiLamp, AreaLamp, SunLamp ] :
+ bpy.data.lamps.remove(data)
+ # camera
+ elif data_type == Camera :
+ bpy.data.cameras.remove(data)
+ # Text, Curve
+ elif data_type in [ Curve, TextCurve ] :
+ bpy.data.curves.remove(data)
+ # metaball
+ elif data_type == MetaBall :
+ bpy.data.metaballs.remove(data)
+ # lattice
+ elif data_type == Lattice :
+ bpy.data.lattices.remove(data)
+ # armature
+ elif data_type == Armature :
+ bpy.data.armatures.remove(data)
+ else :
+ print(' data still here : forgot %s type'%type(data))
+ #except :
+ # empty, field
+ # print('%s has no user_clear attribute ? (%s).'%(data.name,type(data)))
+ else :
+ #print(' not done, %s has %s user'%(data.name,data.users))
+ data.name = '_dead'
+
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/bel/uv.py b/release/scripts/addons_contrib/io_directx_bel/bel/uv.py
new file mode 100644
index 0000000..2827819
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/bel/uv.py
@@ -0,0 +1,109 @@
+from mathutils import Vector
+from .__init__ import *
+from time import clock
+
+# uvs :
+#
+def write(me, uvs, matimage = False) :
+ t = clock()
+ uvs, nest = nested(uvs)
+ newuvs = []
+ # uvi : uvlayer id uvlist : uv coordinates list
+ for uvi, uvlist in enumerate(uvs) :
+
+ uv = me.uv_textures.new()
+ uv.name = 'UV%s'%uvi
+
+ uvlayer = me.uv_layers[-1].data
+
+ for uvfi, uvface in enumerate(uvlist) :
+ #uv.data[uvfi].use_twoside = True # 2.60 changes mat ways
+ mslotid = me.polygons[uvfi].material_index
+ #mat = mesh.materials[mslotid]
+ if matimage :
+ if matimage[mslotid] :
+ img = matimage[mslotid]
+ uv.data[uvfi].image=img
+
+ vi = 0
+ for fi in me.polygons[uvfi].loop_indices :
+ uvlayer[fi].uv = Vector((uvface[vi],uvface[vi+1]))
+ vi += 2
+
+ newuvs.append(uv)
+ print('uvs in ',clock() - t)
+ if nest : return newuvs
+ return newuvs[0]
+
+## WAY faster
+def flatwrite(me, uvs, matimage = False) :
+ #t = clock()
+ newuvs = []
+ #print('uv funcinput : %s'%(len(uvs)))
+ # uvi : uvlayer id uvlist : uv coordinates list
+ for uvi, uvlist in enumerate(uvs) :
+ #print('uvlist input : %s'%(len(uvlist)))
+ #print(uvlist[0:5])
+ uv = me.uv_textures.new()
+ uv.name = 'UV%s'%uvi
+ uvlayer = me.uv_layers[-1].data
+ # flatuv = awaited uvlist length
+ #flatuv = list( range(len(uvlayer) * 2) )
+ #print('uvlist need : %s'%(len(flatuv)))
+ uvlayer.foreach_set('uv',uvlist)
+
+ newuvs.append(uv)
+ #print('uvs in ',clock() - t)
+ return newuvs
+
+# face are squared or rectangular,
+# any orientation
+# vert order width then height 01 and 23 = x 12 and 03 = y
+# normal default when face has been built
+def row(vertices,faces,normals=True) :
+ uvs = []
+ for face in faces :
+ v0 = vertices[face[0]]
+ v1 = vertices[face[1]]
+ v2 = vertices[face[-1]]
+ print(v0,v1)
+ lx = (v1 - v0).length
+ ly = (v2 - v0).length
+ # init uv
+ if len(uvs) == 0 :
+ x = 0
+ y = 0
+ elif normals :
+ x = uvs[-1][2]
+ y = uvs[-1][3]
+ else :
+ x = uvs[-1][0]
+ y = uvs[-1][1]
+ if normals : uvs.append([x,y,x+lx,y,x+lx,y+ly,x,y+ly])
+ else : uvs.append([x+lx,y,x,y,x,y+ly,x+lx,y+ly])
+ return uvs
+
+## convert UV given as verts location to blender format
+# eg : [ [v0x,v0y] , [vnx , vny] ... ] -> [ [ v1x,v1y,v0x,v0y,v4x,v4y] ... ]
+# found in directx
+def asVertsLocation(verts2d, faces) :
+ t = clock()
+ uv = []
+ for f in faces :
+ uvface = []
+ for vi in f :
+ uvface.extend(verts2d[vi])
+ uv.append(uvface)
+ print('uvs convert in ',clock() - t)
+ return uv
+
+## Dx to flat
+#eg : [ [v0x,v0y] ,[v1x,v1y] , [vnx , vny] ] -> [ v0x,v0y,v1x,v1y,vnx,vny ]
+def asFlatList(uvlist,faces) :
+ #t = clock()
+ uv = []
+ for f in faces :
+ for vi in f :
+ uv.extend(uvlist[vi])
+ #print('uvs convert in %s len : %s'%(str(clock() - t),len(uv)))
+ return uv
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/import_x.py b/release/scripts/addons_contrib/io_directx_bel/import_x.py
new file mode 100644
index 0000000..f96dc7e
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/import_x.py
@@ -0,0 +1,971 @@
+# Blender directX importer
+# version baby
+
+# litterature explaining the parser directions :
+
+# I don't want to load the whole file as it can be huge : go chunks
+# also I want random access to 3d datas to import pieces, not always everything
+# so step1 is a whole file fast parsing, retrieving tokens name and building en empty internal dict
+# with only pointers and no 3d datas.
+# step 2 is to call any token by their names and retrieve the 3d datas thanks to pointers stored in dicts
+# between step 1 and step 2 a script ui should be provided to select, transform etc before import.
+# > I need to know the pointer position of tokens but data.tell() is slow
+# a += pointer computed from line length is way faster. so I need eol -> rb mode
+# and readline() is ok in binary mode 'rb' with \r\n (win) \n (unix) but not \r mac..
+# 2chrs for windows, 1 for mac and lunix > win eol \r\n becomes \n\n (add a line)
+# mac eol \r becomes \n so win lines info are wrong
+# this also allows support for wrong files format (mixed \r and \r\n)
+# for now it only works for text format, but the used methods will be independant of the container type.
+
+# TEST FILES
+# http://assimp.svn.sourceforge.net/viewvc/assimp/trunk/test/models/X/
+
+
+import os
+import re
+import struct, binascii
+import time
+
+import bpy
+import mathutils as bmat
+from mathutils import Vector, Matrix
+
+try :
+ import bel
+ import bel.mesh
+ import bel.image
+ import bel.uv
+ import bel.material
+ import bel.ob
+ import bel.fs
+except :
+ import io_directx_bel.bel as bel
+ from .bel import mesh,image,uv,material,ob,fs
+
+from .templates_x import *
+
+'''
+# just a temp hack to reload bel everytime
+import imp
+imp.reload(bel)
+imp.reload(bel.fs)
+imp.reload(bel.image)
+imp.reload(bel.material)
+imp.reload(bel.mesh)
+imp.reload(bel.ob)
+imp.reload(bel.uv)
+'''
+
+###################################################
+
+def load(operator, context, filepath,
+ global_clamp_size=0.0,
+ show_tree=False,
+ show_templates=False,
+ show_geninfo=False,
+ quickmode=False,
+ parented=False,
+ bone_maxlength=1.0,
+ chunksize=False,
+ naming_method=0,
+ use_ngons=True,
+ use_edges=True,
+ use_smooth_groups=True,
+ use_split_objects=True,
+ use_split_groups=True,
+ use_groups_as_vgroups=False,
+ use_image_search=True,
+ global_matrix=None,
+ ):
+
+
+ if quickmode :
+ parented = False
+
+ bone_minlength = bone_maxlength / 100.0
+
+ #global templates, tokens
+ rootTokens = []
+ namelookup = {}
+ imgnamelookup = {}
+ chunksize = int(chunksize)
+ reserved_type = (
+ 'dword',
+ 'float',
+ 'string'
+ )
+
+ '''
+ 'array',
+ 'Matrix4x4',
+ 'Vector',
+ '''
+ '''
+ with * : defined in dXdata
+
+ WORD 16 bits
+ * DWORD 32 bits
+ * FLOAT IEEE float
+ DOUBLE 64 bits
+ CHAR 8 bits
+ UCHAR 8 bits
+ BYTE 8 bits
+ * STRING NULL-terminated string
+ CSTRING Formatted C-string (currently unsupported)
+ UNICODE UNICODE string (currently unsupported)
+
+BINARY FORMAT
+# TOKENS in little-endian WORDs
+#define TOKEN_NAME 1
+#define TOKEN_STRING 2
+#define TOKEN_INTEGER 3
+#define TOKEN_GUID 5
+#define TOKEN_INTEGER_LIST 6
+#define TOKEN_FLOAT_LIST 7
+#define TOKEN_OBRACE 10
+#define TOKEN_CBRACE 11
+#define TOKEN_OPAREN 12
+#define TOKEN_CPAREN 13
+#define TOKEN_OBRACKET 14
+#define TOKEN_CBRACKET 15
+#define TOKEN_OANGLE 16
+#define TOKEN_CANGLE 17
+#define TOKEN_DOT 18
+#define TOKEN_COMMA 19
+#define TOKEN_SEMICOLON 20
+#define TOKEN_TEMPLATE 31
+#define TOKEN_WORD 40
+#define TOKEN_DWORD 41
+#define TOKEN_FLOAT 42
+#define TOKEN_DOUBLE 43
+#define TOKEN_CHAR 44
+#define TOKEN_UCHAR 45
+#define TOKEN_SWORD 46
+#define TOKEN_SDWORD 47
+#define TOKEN_VOID 48
+#define TOKEN_LPSTR 49
+#define TOKEN_UNICODE 50
+#define TOKEN_CSTRING 51
+#define TOKEN_ARRAY 52
+
+ '''
+
+ # COMMON REGEX
+ space = '[\ \t]{1,}' # at least one space / tab
+ space0 = '[\ \t]{0,}' # zero or more space / tab
+
+ # DIRECTX REGEX TOKENS
+ r_template = r'template' + space + '[\w]*' + space0 + '\{'
+ if quickmode :
+ r_sectionname = r'Mesh' + space + '[\W-]*'
+ else :
+ r_sectionname = r'[\w]*' + space + '[\w-]*' + space0 + '\{'
+ r_refsectionname = r'\{' + space0 + '[\w-]*' + space0 + '\}'
+ r_endsection = r'\{|\}'
+
+ # dX comments
+ r_ignore = r'#|//'
+
+ #r_frame = r'Frame' + space + '[\w]*'
+ #r_matrix = r'FrameTransformMatrix' + space + '\{[\s\d.,-]*'
+ #r_mesh = r'Mesh' + space + '[\W]*'
+
+ ###################
+ ## STEP 1 FUNCTIONS
+ ###################
+
+ ## HEADER
+ # returns header values or False if directx reco tag is missing
+ # assuming there's never comment header and that xof if the 1st
+ # string of the file
+ '''
+ they look like xof 0303txt 0032
+ 4 Magic Number (required) "xof "
+ 2 Minor Version 03
+ 2 Major Version 02
+ 4 Format Type (required)
+ "txt " Text File
+ "bin " Binary File
+ "tzip" MSZip Compressed Text File
+ "bzip" MSZip Compressed Binary File
+ 4 Float Accuracy "0032" 32 bit or "0064" 64 bit
+ '''
+ def dXheader(data) :
+ l = data.read(4)
+ if l != b'xof ' :
+ print ('no header found !')
+ data.seek(0)
+ return False
+ minor = data.read(2).decode()
+ major = data.read(2).decode()
+ format = data.read(4).decode().strip()
+ accuracy = int(data.read(4).decode())
+ data.seek(0)
+ return ( minor, major, format, accuracy )
+
+
+ ##
+ def dXtree(data,quickmode = False) :
+ tokens = {}
+ templates = {}
+ tokentypes = {}
+ c = 0
+ lvl = 0
+ tree = ['']
+ ptr = 0
+ eol = 0
+ trunkated = False
+ previouslvl = False
+ while True :
+ #for l in data.readlines() :
+ lines, trunkated = nextFileChunk(data,trunkated)
+ if lines == None : break
+ for l in lines :
+
+ # compute pointer position
+ ptr += eol
+ c += 1
+ eol = len(l) + 1
+ #print(c,data.tell(),ptr+eol)
+ #if l != '' : print('***',l)
+ #if l == '' : break
+ l = l.strip()
+
+ # remove blank and comment lines
+ if l == '' or re.match(r_ignore,l) :
+ continue
+
+ # one line token cases level switch
+ if previouslvl :
+ lvl -= 1
+ previouslvl = False
+
+ #print('%s lines in %.2f\''%(c,time.clock()-t),end='\r')
+ #print(c,len(l)+1,ptr,data.tell())
+ if '{' in l :
+ lvl += 1
+ if '}' in l : previouslvl = True #; print('got one line token : \n%s'%l)
+ elif '}' in l :
+ lvl -= 1
+ #print(c,lvl,tree)
+
+ if quickmode == False :
+ ## look for templates
+ if re.match(r_template,l) :
+ tname = l.split(' ')[1]
+ templates[tname] = {'pointer' : ptr, 'line' : c}
+ continue
+
+ ## look for {references}
+ if re.match(r_refsectionname,l) :
+ refname = namelookup[ l[1:-1].strip() ]
+ #print('FOUND reference to %s in %s at line %s (level %s)'%(refname,tree[lvl-1],c,lvl))
+ #tree = tree[0:lvl]
+ parent = tree[lvl-1]
+ # tag it as a reference, since it's not exactly a child.
+ # put it in childs since order can matter in sub tokens declaration
+ tokens[parent]['childs'].append('*'+refname)
+ if refname not in tokens :
+ print('reference to %s done before its declaration (line %s)\ncreated dummy'%(refname,c))
+ tokens[refname] = {}
+ if 'user' not in tokens[refname] : tokens[refname]['users'] = [parent]
+ else : tokens[refname]['users'].append(parent)
+ continue
+
+ ## look for any token or only Mesh token in quickmode
+ if re.match(r_sectionname,l) :
+ tokenname = getName(l,tokens)
+ #print('FOUND %s %s %s %s'%(tokenname,c,lvl,tree))
+ #print('pointer %s %s'%(data.tell(),ptr))
+ if lvl == 1 : rootTokens.append(tokenname)
+ typ = l.split(' ')[0].strip().lower()
+ tree = tree[0:lvl]
+ if typ not in tokentypes : tokentypes[typ] = [tokenname]
+ else : tokentypes[typ].append(tokenname)
+ parent = tree[-1]
+ if tokenname in tokens :
+ tokens[tokenname]['pointer'] = ptr
+ tokens[tokenname]['line'] = c
+ tokens[tokenname]['parent'] = parent
+ tokens[tokenname]['childs'] = []
+ tokens[tokenname]['type'] = typ
+
+ else : tokens[tokenname] = {'pointer': ptr,
+ 'line' : c,
+ 'parent' : parent,
+ 'childs' : [],
+ 'users' : [],
+ 'type' : typ
+ }
+ tree.append(tokenname)
+ if lvl > 1 and quickmode == False :
+ tokens[parent]['childs'].append(tokenname)
+
+ return tokens, templates, tokentypes
+
+ ## returns file binary chunks
+ def nextFileChunk(data,trunkated=False,chunksize=1024) :
+ if chunksize == 0 : chunk = data.read()
+ else : chunk = data.read(chunksize)
+ if format == 'txt' :
+ lines = chunk.decode('utf-8', errors='ignore')
+ #if stream : return lines.replace('\r','').replace('\n','')
+ lines = lines.replace('\r','\n').split('\n')
+ if trunkated : lines[0] = trunkated + lines[0]
+ if len(lines) == 1 :
+ if lines[0] == '' : return None, None
+ return lines, False
+ return lines, lines.pop()
+ # wip, todo for binaries
+ else :
+ print(chunk)
+ for word in range(0,len(chunk)) :
+ w = chunk[word:word+4]
+ print(word,w,struct.unpack("<l", w),binascii.unhexlify(w))
+
+
+ # name unnamed tokens, watchout for x duplicate
+ # for blender, referenced token in x should be named and unique..
+ def getName(l,tokens) :
+ xnam = l.split(' ')[1].strip()
+
+ #if xnam[0] == '{' : xnam = ''
+ if xnam and xnam[-1] == '{' : xnam = xnam[:-1]
+
+ name = xnam
+ if len(name) == 0 : name = l.split(' ')[0].strip()
+
+ namelookup[xnam] = bel.bpyname(name,tokens,4)
+
+ return namelookup[xnam]
+
+
+ ###################
+ ## STEP 2 FUNCTIONS
+ ###################
+ # once the internal dict is populated the functions below can be used
+
+ ## from a list of tokens, displays every child, users and references
+ '''
+ walk_dxtree( [ 'Mesh01', 'Mesh02' ] ) # for particular pieces
+ walk_dxtree(tokens.keys()) for the whole tree
+ '''
+ def walk_dXtree(field,lvl=0,tab='') :
+ for fi, tokenname in enumerate(field) :
+ if lvl > 0 or tokens[tokenname]['parent'] == '' :
+ if tokenname not in tokens :
+ tokenname = tokenname[1:]
+ ref = 'ref: '
+ else : ref = False
+
+ frame_type = tokens[tokenname]['type']
+ line = ('{:7}'.format(tokens[tokenname]['line']))
+ log = ' %s%s (%s)'%( ref if ref else '', tokenname, frame_type )
+ print('%s.%s%s'%(line, tab, log))
+ if fi == len(field) - 1 : tab = tab[:-3] + ' '
+
+ if ref == False :
+ for user in tokens[tokenname]['users'] :
+ print('%s.%s |__ user: %s'%(line, tab.replace('_',' '), user))
+ walk_dXtree(tokens[tokenname]['childs'],lvl+1,tab.replace('_',' ')+' |__')
+
+ if fi == len(field) - 1 and len(tokens[tokenname]['childs']) == 0 :
+ print('%s.%s'%(line,tab))
+
+ ## remove eol, comments, spaces from a raw block of datas
+ def cleanBlock(block) :
+ while '//' in block :
+ s = block.index('//')
+ e = block.index('\n',s+1)
+ block = block[0:s] + block[e:]
+ while '#' in block :
+ s = block.index('#')
+ e = block.index('\n',s+1)
+ block = block[0:s] + block[e:]
+ block = block.replace('\n','').replace(' ','').replace('\t ','')
+ return block
+
+ def readToken(tokenname) :
+ token = tokens[tokenname]
+ datatype = token['type'].lower()
+ if datatype in templates : tpl = templates[datatype]
+ elif datatype in defaultTemplates : tpl = defaultTemplates[datatype]
+ else :
+ print("can't find any template to read %s (type : %s)"%(tokenname,datatype))
+ return False
+ #print('> use template %s'%datatype)
+ block = readBlock(data,token)
+ ptr = 0
+ #return dXtemplateData(tpl,block)
+ fields, ptr = dXtemplateData(tpl,block)
+ if datatype in templatesConvert :
+ fields = eval( templatesConvert[datatype] )
+ return fields
+
+ def dXtemplateData(tpl,block,ptr=0) :
+ #print('dxTPL',block[ptr])
+ pack = []
+ for member in tpl['members'] :
+ #print(member)
+ dataname = member[-1]
+ datatype = member[0].lower()
+ if datatype == 'array' :
+ datatype = member[1].lower()
+ s = dataname.index('[') + 1
+ e = dataname.index(']')
+ #print(dataname[s:e])
+ length = eval(dataname[s:e])
+ #print("array %s type %s length defined by '%s' : %s"%(dataname[:s-1],datatype,dataname[s:e],length))
+ dataname = dataname[:s-1]
+ datavalue, ptr = dXarray(block, datatype, length, ptr)
+ #print('back to %s'%(dataname))
+ else :
+ length = 1
+ datavalue, ptr = dXdata(block, datatype, length, ptr)
+
+ #if len(str(datavalue)) > 50 : dispvalue = str(datavalue[0:25]) + ' [...] ' + str(datavalue[-25:])
+ #else : dispvalue = str(datavalue)
+ #print('%s : %s %s'%(dataname,dispvalue,type(datavalue)))
+ exec('%s = datavalue'%(dataname))
+ pack.append( datavalue )
+ return pack, ptr + 1
+
+ def dXdata(block,datatype,length,s=0,eof=';') :
+ #print('dxDTA',block[s])
+ # at last, the data we need
+ # should be a ';' but one meet ',' often, like in meshface
+ if datatype == 'dword' :
+ e = block.index(';',s+1)
+ try : field = int(block[s:e])
+ except :
+ e = block.index(',',s+1)
+ field = int(block[s:e])
+ return field, e+1
+ elif datatype == 'float' :
+ e = block.index(eof,s+1)
+ return float(block[s:e]), e+1
+ elif datatype == 'string' :
+ e = block.index(eof,s+1)
+ return str(block[s+1:e-1]) , e+1
+ else :
+ if datatype in templates : tpl = templates[datatype]
+ elif datatype in defaultTemplates : tpl = defaultTemplates[datatype]
+ else :
+ print("can't find any template for type : %s"%(datatype))
+ return False
+ #print('> use template %s'%datatype)
+ fields, ptr = dXtemplateData(tpl,block,s)
+ if datatype in templatesConvert :
+ fields = eval( templatesConvert[datatype] )
+ return fields, ptr
+
+ def dXarray(block, datatype, length, s=0) :
+ #print('dxARR',block[s])
+ lst = []
+ if datatype in reserved_type :
+ eoi=','
+ for i in range(length) :
+ if i+1 == length : eoi = ';'
+ datavalue, s = dXdata(block,datatype,1,s,eoi)
+ lst.append( datavalue )
+
+ else :
+ eoi = ';,'
+ for i in range(length) :
+ if i+1 == length : eoi = ';;'
+ #print(eoi)
+ e = block.index(eoi,s)
+ #except : print(block,s) ; popo()
+ datavalue, na = dXdata(block[s:e+1],datatype,1)
+ lst.append( datavalue )
+ s = e + 2
+ return lst, s
+
+ ###################################################
+
+ ## populate a template with its datas
+ # this make them available in the internal dict. should be used in step 2 for unknown data type at least
+ def readTemplate(data,tpl_name,display=False) :
+ ptr = templates[tpl_name]['pointer']
+ line = templates[tpl_name]['line']
+ #print('> %s at line %s (chr %s)'%(tpl_name,line,ptr))
+ data.seek(ptr)
+ block = ''
+ trunkated = False
+ go = True
+ while go :
+ lines, trunkated = nextFileChunk(data,trunkated,chunksize) # stream ?
+ if lines == None :
+ break
+ for l in lines :
+ #l = data.readline().decode().strip()
+ block += l.strip()
+ if '}' in l :
+ go = False
+ break
+
+ uuid = re.search(r'<.+>',block).group()
+ templates[tpl_name]['uuid'] = uuid.lower()
+ templates[tpl_name]['members'] = []
+ templates[tpl_name]['restriction'] = 'closed'
+
+ members = re.search(r'>.+',block).group()[1:-1].split(';')
+ for member in members :
+ if member == '' : continue
+ if member[0] == '[' :
+ templates[tpl_name]['restriction'] = member
+ continue
+ templates[tpl_name]['members'].append( member.split(' ') )
+
+ if display :
+ print('\ntemplate %s :'%tpl_name)
+ for k,v in templates[tpl_name].items() :
+ if k != 'members' :
+ print(' %s : %s'%(k,v))
+ else :
+ for member in v :
+ print(' %s'%str(member)[1:-1].replace(',',' ').replace("'",''))
+
+ if tpl_name in defaultTemplates :
+ defaultTemplates[tpl_name]['line'] = templates[tpl_name]['line']
+ defaultTemplates[tpl_name]['pointer'] = templates[tpl_name]['pointer']
+ if defaultTemplates[tpl_name] != templates[tpl_name] :
+ print('! DIFFERS FROM BUILTIN TEMPLATE :')
+ print('raw template %s :'%tpl_name)
+ print(templates[tpl_name])
+ print('raw default template %s :'%tpl_name)
+ print(defaultTemplates[tpl_name])
+ #for k,v in defaultTemplates[tpl_name].items() :
+ # if k != 'members' :
+ # print(' %s : %s'%(k,v))
+ # else :
+ # for member in v :
+ # print(' %s'%str(member)[1:-1].replace(',',' ').replace("'",''))
+ else :
+ print('MATCHES BUILTIN TEMPLATE')
+
+
+ ## read any kind of token data block
+ # by default the block is cleaned from inline comment space etc to allow data parsing
+ # useclean = False (retrieve all bytes) if you need to compute a file byte pointer
+ # to mimic the file.tell() function and use it with file.seek()
+ def readBlock(data,token, clean=True) :
+ ptr = token['pointer']
+ data.seek(ptr)
+ block = ''
+ #lvl = 0
+ trunkated = False
+ go = True
+ while go :
+ lines, trunkated = nextFileChunk(data,trunkated,chunksize)
+ if lines == None : break
+ for l in lines :
+ #eol = len(l) + 1
+ l = l.strip()
+ #c += 1
+ block += l+'\n'
+ if re.match(r_endsection,l) :
+ go = False
+ break
+ s = block.index('{') + 1
+ e = block.index('}')
+ block = block[s:e]
+ if clean : block = cleanBlock(block)
+ return block
+
+ def getChilds(tokenname) :
+ childs = []
+ # '*' in childname means it's a reference. always perform this test
+ # when using the childs field
+ for childname in tokens[tokenname]['childs'] :
+ if childname[0] == '*' : childname = childname[1:]
+ childs.append( childname )
+ return childs
+
+ # the input nested list of [bonename, matrix, [child0,child1..]] is given by import_dXtree()
+ def buildArm(armdata, child,lvl=0,parent_matrix=False) :
+
+ bonename, bonemat, bonechilds = child
+
+ if lvl == 0 :
+ armname = armdata
+ armdata = bpy.data.armatures.new(name=armname)
+ arm = bpy.data.objects.new(armname,armdata)
+ bpy.context.scene.objects.link(arm)
+ arm.select = True
+ bpy.context.scene.objects.active = arm
+ bpy.ops.object.mode_set(mode='EDIT')
+ parent_matrix = Matrix()
+
+ bone = armdata.edit_bones.new(name=bonename)
+ bonematW = parent_matrix * bonemat
+ bone.head = bonematW.to_translation()
+ #bone.roll.. ?
+ bone_length = bone_maxlength
+ for bonechild in bonechilds :
+ bonechild = buildArm(armdata,bonechild,lvl+1,bonematW)
+ bonechild.parent = bone
+ bone_length = min((bonechild.head - bone.head).length, bone_length)
+ bone.tail = bonematW * Vector((0,bone_length,0))
+ if lvl == 0 :
+ bpy.ops.object.mode_set(mode='OBJECT')
+ return arm
+ return bone
+
+ def import_dXtree(field,lvl=0) :
+ tab = ' '*lvl*2
+ if field == [] :
+ if show_geninfo : print('%s>> no childs, return False'%(tab))
+ return False
+ ob = False
+ mat = False
+ is_root = False
+ frames = []
+ obs = []
+
+ parentname = tokens[field[0]]['parent']
+ if show_geninfo : print('%s>>childs in frame %s :'%(tab,parentname))
+
+ for tokenname in field :
+
+ tokentype = tokens[tokenname]['type']
+
+ # frames can contain more than one mesh
+ if tokentype == 'mesh' :
+ # object and mesh naming :
+ # if parent frame has several meshes : obname = meshname = mesh token name,
+ # if parent frame has only one mesh : obname = parent frame name, meshname = mesh token name.
+ if parentname :
+ meshcount = 0
+ for child in getChilds(parentname) :
+ if tokens[child]['type'] == 'mesh' :
+ meshcount += 1
+ if meshcount == 2 :
+ parentname = tokenname
+ break
+ else : parentname = tokenname
+
+ ob = getMesh(parentname,tokenname)
+ obs.append(ob)
+
+ if show_geninfo : print('%smesh : %s'%(tab,tokenname))
+
+ # frames contain one matrix (empty or bone)
+ elif tokentype == 'frametransformmatrix' :
+ [mat] = readToken(tokenname)
+ if show_geninfo : print('%smatrix : %s'%(tab,tokenname))
+
+ # frames can contain 0 or more frames
+ elif tokentype == 'frame' :
+ frames.append(tokenname)
+ if show_geninfo : print('%sframe : %s'%(tab,tokenname))
+
+ # matrix is used for mesh transform if some mesh(es) exist(s)
+ if ob :
+ is_root = True
+ if mat == False :
+ mat = Matrix()
+ if show_geninfo : print('%smesh token without matrix, set it to default\n%splease report in bug tracker if you read this !'%(tab,tab))
+ if parentname == '' :
+ mat = mat * global_matrix
+ if len(obs) == 1 :
+ ob.matrix_world = mat
+ else :
+ ob = bel.ob.new(parentname, None, naming_method)
+ ob.matrix_world = mat
+ for child in obs :
+ child.parent = ob
+
+ # matrix only, store it as a list as we don't know if
+ # it's a bone or an empty yet
+ elif mat :
+ ob = [parentname, mat,[]]
+
+ # nothing case ?
+ else :
+ ob = [parentname, Matrix() * global_matrix,[]]
+ if show_geninfo : print('%snothing here'%(tab))
+
+ childs = []
+
+ for tokenname in frames :
+ if show_geninfo : print('%s<Begin %s :'%(tab,tokenname))
+
+ # child is either False, empty, object, or a list or undefined name matrices hierarchy
+ child = import_dXtree(getChilds(tokenname),lvl+1)
+ if child and type(child) != list :
+ is_root = True
+ childs.append( [tokenname, child] )
+ if show_geninfo : print('%sEnd %s>'%(tab,tokenname))
+
+ if is_root and parentname != '' :
+
+ if show_geninfo : print('%send of tree a this point'%(tab))
+ if type(ob) == list :
+ mat = ob[1]
+ ob = bel.ob.new(parentname, None, naming_method)
+ ob.matrix_world = mat
+
+ for tokenname, child in childs :
+ if show_geninfo : print('%sbegin2 %s>'%(tab,tokenname))
+ # returned a list of object(s) or matrice(s)
+ if child :
+
+ # current frame is an object or an empty, we parent this frame to it
+ #if eot or (ob and ( type(ob.data) == type(None) or type(ob.data) == bpy.types.Mesh ) ) :
+ if is_root :
+ # this branch is an armature, convert it
+ if type(child) == list :
+ if show_geninfo : print('%sconvert to armature %s'%(tab,tokenname))
+ child = buildArm(tokenname, child)
+
+ # parent the obj/empty/arm to current
+ # or apply the global user defined matrix to the object root
+ if parentname != '' :
+ child.parent = ob
+ else :
+ child.matrix_world = global_matrix
+
+ # returned a list of parented matrices. append it in childs list
+ elif type(child[0]) == str :
+ ob[2].append(child)
+
+ # child is an empty or a mesh, so current frame is an empty, not an armature
+ elif ob and ( type(child.data) == type(None) or type(child.data) == bpy.types.Mesh ) :
+ #print(' child data type: %s'%type(child.data))
+ child.parent = ob
+ #print('%s parented to %s'%(child.name,ob.name))
+
+ # returned False
+ else :
+ if show_geninfo : print('%sreturned %s, nothing'%(tab,child))
+
+ #print('>> %s return %s'%(field,ob))
+ return ob# if ob else False
+
+ # build from mesh token type
+ def getMesh(obname,tokenname,debug = False):
+
+ if debug : print('\nmesh name : %s'%tokenname)
+
+ verts = []
+ edges = []
+ faces = []
+ matslots = []
+ facemats = []
+ uvs = []
+ groupnames = []
+ groupindices = []
+ groupweights = []
+
+ nVerts, verts, nFaces, faces = readToken(tokenname)
+
+ if debug :
+ print('verts : %s %s\nfaces : %s %s'%(nVerts, len(verts),nFaces, len(faces)))
+
+ #for childname in token['childs'] :
+ for childname in getChilds(tokenname) :
+
+ tokentype = tokens[childname]['type']
+
+ # UV
+ if tokentype == 'meshtexturecoords' :
+ uv = readToken(childname)
+ #uv = bel.uv.asVertsLocation(uv, faces)
+ uv = bel.uv.asFlatList(uv, faces)
+ uvs.append(uv)
+
+ if debug : print('uv : %s'%(len(uv)))
+
+ # MATERIALS
+ elif tokentype == 'meshmateriallist' :
+ nbslots, facemats = readToken(childname)
+
+ if debug : print('facemats : %s'%(len(facemats)))
+
+ # mat can exist but with no datas so we prepare the mat slot
+ # with dummy ones
+ for slot in range(nbslots) :
+ matslots.append('dXnoname%s'%slot )
+
+ # length does not match (could be tuned more, need more cases)
+ if len(facemats) != len(faces) :
+ facemats = [ facemats[0] for i in faces ]
+
+ # seek for materials then textures if any mapped in this mesh.
+ # no type test, only one option type in token meshmateriallist : 'Material'
+ for slotid, matname in enumerate(getChilds(childname)) :
+
+ # rename dummy mats with the right name
+ matslots[slotid] = matname
+
+ # blender material creation (need tuning)
+ mat = bel.material.new(matname,naming_method)
+ matslots[slotid] = mat.name
+
+ if naming_method != 1 :
+ #print('matname : %s'%matname)
+ (diffuse_color,alpha), power, specCol, emitCol = readToken(matname)
+ #if debug : print(diffuse_color,alpha, power, specCol, emitCol)
+ mat.diffuse_color = diffuse_color
+ mat.diffuse_intensity = power
+ mat.specular_color = specCol
+ # dX emit don't use diffuse color but is a color itself
+ # convert it to a kind of intensity
+ mat.emit = (emitCol[0] + emitCol[1] + emitCol[2] ) / 3
+
+ if alpha != 1.0 :
+ mat.use_transparency = True
+ mat.transparency_method = 'Z_TRANSPARENCY'
+ mat.alpha = alpha
+ mat.specular_alpha = 0
+ transp = True
+ else : transp = False
+
+ # texture
+ # only 'TextureFilename' can be here, no type test
+ # textures have no name in .x so we build
+ # image and texture names from the image file name
+ # bdata texture slot name = bdata image name
+ btexnames = []
+ for texname in getChilds(matname) :
+
+ # create/rename/reuse etc corresponding data image
+ # (returns False if not found)
+ [filename] = readToken(texname)
+ img = bel.image.new(path+'/'+filename)
+
+ if img == False :
+ imgname = 'not_found'
+ else :
+ imgname = img.name
+
+ #print('texname : %s'%texname)
+ #print('filename : %s'%filename)
+ #print('btex/img name : %s'%imgname)
+
+ # associated texture (no naming check.. maybe tune more)
+ # tex and texslot are created even if img not found
+ if imgname in bpy.data.textures and ( img == False or bpy.data.textures[imgname].image == img ) :
+ tex = bpy.data.textures[imgname]
+ else :
+ tex = bpy.data.textures.new(name=imgname,type='IMAGE')
+ if img : tex.image = img
+
+ tex.use_alpha = transp
+ tex.use_preview_alpha = transp
+
+ # then create texture slot
+ texslot = mat.texture_slots.create(index=0)
+ texslot.texture = tex
+ texslot.texture_coords = 'UV'
+ texslot.uv_layer = 'UV0'
+ texslot.use_map_alpha = transp
+ texslot.alpha_factor = alpha
+
+ # create remaining dummy mat
+ for slotid, matname in enumerate(matslots) :
+ if matname not in bpy.data.materials :
+ mat = bel.material.new(matname,naming_method)
+ matslots[slotid] = mat.name
+
+ if debug : print('matslots : %s'%matslots)
+
+ # VERTICES GROUPS/WEIGHTS
+ elif tokentype == 'skinweights' :
+ groupname, nverts, vindices, vweights, mat = readToken(childname)
+ groupname = namelookup[groupname]
+ if debug :
+ print('vgroup : %s (%s/%s verts) %s'%(groupname,len(vindices),len(vweights),'bone' if groupname in tokens else ''))
+
+ #if debug : print('matrix : %s\n%s'%(type(mat),mat))
+
+ groupnames.append(groupname)
+ groupindices.append(vindices)
+ groupweights.append(vweights)
+
+ ob = bel.mesh.write(obname,tokenname,
+ verts, edges, faces,
+ matslots, facemats, uvs,
+ groupnames, groupindices, groupweights,
+ use_smooth_groups,
+ naming_method)
+
+ return ob
+
+ ## here we go
+
+ file = os.path.basename(filepath)
+
+ print('\nimporting %s...'%file)
+ start = time.clock()
+ path = os.path.dirname(filepath)
+ filepath = os.fsencode(filepath)
+ data = open(filepath,'rb')
+ header = dXheader(data)
+
+ if global_matrix is None:
+ global_matrix = mathutils.Matrix()
+
+ if header :
+ minor, major, format, accuracy = header
+
+ if show_geninfo :
+ print('\n%s directX header'%file)
+ print(' minor : %s'%(minor))
+ print(' major : %s'%(major))
+ print(' format : %s'%(format))
+ print(' floats are %s bits'%(accuracy))
+
+ if format in [ 'txt' ] : #, 'bin' ] :
+
+ ## FILE READ : STEP 1 : STRUCTURE
+ if show_geninfo : print('\nBuilding internal .x tree')
+ t = time.clock()
+ tokens, templates, tokentypes = dXtree(data,quickmode)
+ readstruct_time = time.clock()-t
+ if show_geninfo : print('builded tree in %.2f\''%(readstruct_time)) # ,end='\r')
+
+ ## populate templates with datas
+ for tplname in templates :
+ readTemplate(data,tplname,show_templates)
+
+ ## DATA TREE CHECK
+ if show_tree :
+ print('\nDirectX Data Tree :\n')
+ walk_dXtree(tokens.keys())
+
+ ## DATA IMPORTATION
+ if show_geninfo :
+ #print(tokens)
+ print('Root frames :\n %s'%rootTokens)
+ if parented :
+ import_dXtree(rootTokens)
+ else :
+ for tokenname in tokentypes['mesh'] :
+ obname = tokens[tokenname]['parent']
+ # object and mesh naming :
+ # if parent frame has several meshes : obname = meshname = mesh token name,
+ # if parent frame has only one mesh : obname = parent frame name, meshname = mesh token name.
+ if obname :
+ meshcount = 0
+ for child in getChilds(obname) :
+ if tokens[child]['type'] == 'mesh' :
+ meshcount += 1
+ if meshcount == 2 :
+ obname = tokenname
+ break
+ else : obname = tokenname
+
+ ob = getMesh(obname,tokenname,show_geninfo)
+ ob.matrix_world = global_matrix
+
+ print('done in %.2f\''%(time.clock()-start)) # ,end='\r')
+
+ else :
+ print('only .x files in text format are currently supported')
+ print('please share your file to make the importer evolve')
+
+
+ return {'FINISHED'}
+
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/io_directx_bel/templates_x.py b/release/scripts/addons_contrib/io_directx_bel/templates_x.py
new file mode 100644
index 0000000..7b51e0c
--- /dev/null
+++ b/release/scripts/addons_contrib/io_directx_bel/templates_x.py
@@ -0,0 +1,162 @@
+# dx 'strict' templates
+# lower() since some apps does not respect it,
+# and to keep the 'as it should be' syntax
+
+defaultTemplates={}
+templatesConvert={}
+
+# mesh template
+defaultTemplates['Mesh'.lower()] = {
+ 'uuid' : '<3d82ab44-62da-11cf-ab39-0020af71e433>',
+ 'restriction' : '[...]',
+ 'members' : (
+ ('dword', 'nVertices'),
+ ('array', 'vector', 'vertices[nVertices]'),
+ ('dword', 'nFaces'),
+ ('array', 'MeshFace', 'faces[nFaces]'),
+ )
+}
+
+defaultTemplates['FrameTransformMatrix'.lower()] = {
+ 'uuid' : '<f6f23f41-7686-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('matrix4x4', 'frameMatrix'),
+ )
+}
+
+templatesConvert['matrix4x4'] = 'Matrix( [fields[0][0:4], fields[0][4:8] , fields[0][8:12] , fields[0][12:16]] )'
+defaultTemplates['matrix4x4'.lower()] = {
+ 'uuid' : '<f6f23f45-7686-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('array', 'float', 'matrix[16]'),
+ )
+}
+
+#returns [ [vid0,vid1,vid2], [vid1,vid2,vid3,vid4] .. ]
+templatesConvert['meshface'] = 'fields[1]'
+defaultTemplates['MeshFace'.lower()] = {
+ 'uuid' : '<3d82ab5f-62da-11cf-ab39-0020af71e433>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('dword', 'nFaceVertexIndices'),
+ ('array', 'dword', 'faceVertexIndices[nFaceVertexIndices]')
+ )
+}
+
+defaultTemplates['vector'.lower()] = {
+ 'uuid' : '<3d82ab5e-62da-11cf-ab39-0020af71e433>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('float', 'x'),
+ ('float', 'y'),
+ ('float', 'z')
+ )
+}
+
+defaultTemplates['Coords2d'.lower()] = {
+ 'uuid' : '<f6f23f44-7686-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('float', 'u'),
+ ('float', 'v')
+ )
+}
+
+# returns [ uvAsVertsLocation ]
+templatesConvert['meshtexturecoords'] = 'fields[1]'
+defaultTemplates['MeshTextureCoords'.lower()] = {
+ 'uuid' : '<f6f23f40-7686-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('dword', 'nTextureCoords'),
+ ('array', 'Coords2d', 'textureCoords[nTextureCoords]')
+ )
+}
+
+defaultTemplates['meshnormals'.lower()] = {
+ 'uuid' : '<f6f23f43-7686-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('dword', 'nNormals'),
+ ('array', 'vector', 'normals[nNormals]'),
+ ('dword', 'nFaceNormals'),
+ ('array', 'MeshFace', 'faceNormals[nFaceNormals]')
+ )
+}
+
+# returns [ nMaterials, [ materialindex of each face ] ]
+templatesConvert['meshmateriallist'] = '[fields[0],fields[2]]'
+defaultTemplates['MeshMaterialList'.lower()] = {
+ 'uuid' : '<f6f23f42-7686-11cf-8f52-0040333594a3>',
+ 'restriction' : '[Material]',
+ 'members' : (
+ ('dword', 'nMaterials'),
+ ('dword', 'nFaceIndexes'),
+ ('array', 'dword', 'faceIndexes[nFaceIndexes]')
+ )
+}
+
+defaultTemplates['Material'.lower()] = {
+ 'uuid' : '<3d82ab4d-62da-11cf-ab39-0020af71e433>',
+ 'restriction' : '[...]',
+ 'members' : (
+ ('colorrgba', 'faceColor'),
+ ('float', 'power'),
+ ('colorrgb', 'specularColor'),
+ ('colorrgb', 'emissiveColor')
+ )
+}
+
+templatesConvert['colorrgba'] = 'fields[:3],fields[3]'
+defaultTemplates['colorrgba'.lower()] = {
+ 'uuid' : '<35ff44e0-6c7c-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('float', 'red'),
+ ('float', 'green'),
+ ('float', 'blue'),
+ ('float', 'alpha')
+ )
+}
+
+defaultTemplates['colorrgb'.lower()] = {
+ 'uuid' : '<d3e16e81-7835-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('float', 'red'),
+ ('float', 'green'),
+ ('float', 'blue')
+ )
+}
+
+defaultTemplates['TextureFilename'.lower()] = {
+ 'uuid' : '<a42790e1-7810-11cf-8f52-0040333594a3>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('string', 'filename'),
+ )
+}
+
+defaultTemplates['SkinWeights'.lower()] = {
+ 'uuid' : '<6f0d123b-bad2-4167-a0d0-80224f25fabb>',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('string', 'transformNodeName'),
+ ('dword', 'nWeights'),
+ ('array', 'dword', 'vertexIndices[nWeights]'),
+ ('array', 'float', 'weights[nWeights]'),
+ ('matrix4x4', 'matrixOffset')
+ )
+}
+
+defaultTemplates['XSkinMeshHeader'.lower()] = {
+ 'uuid' : '3cf169ce-ff7c-44ab-93c0-f78f62d172e2',
+ 'restriction' : 'closed',
+ 'members' : (
+ ('word', 'nMaxSkinWeightsPerVertex'),
+ ('word', 'nMaxSkinWeightsPerFace'),
+ ('word', 'nBones')
+ )
+}
diff --git a/release/scripts/addons_contrib/io_export_marmalade.py b/release/scripts/addons_contrib/io_export_marmalade.py
new file mode 100644
index 0000000..401efe7
--- /dev/null
+++ b/release/scripts/addons_contrib/io_export_marmalade.py
@@ -0,0 +1,1474 @@
+# ***** 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 3 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, see <http://www.gnu.org/licenses/>.
+# All rights reserved.
+# ***** GPL LICENSE BLOCK *****
+
+# Marmalade SDK is not responsible in any case of the following code.
+# This Blender add-on is freely shared for the Blender and Marmalade user communities.
+
+
+bl_info = {
+ "name": "Marmalade Cross-platform Apps (.group)",
+ "author": "Benoit Muller",
+ "version": (0, 6, 2),
+ "blender": (2, 63, 0),
+ "location": "File > Export > Marmalade cross-platform Apps (.group)",
+ "description": "Export Marmalade Format files (.group)",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Import-Export/Marmalade_Exporter",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "",
+ "category": "Import-Export"}
+
+import os
+import shutil
+from math import radians
+
+import bpy
+from mathutils import Matrix
+
+import mathutils
+import math
+
+import datetime
+
+import subprocess
+
+
+#Container for the exporter settings
+class MarmaladeExporterSettings:
+
+ def __init__(self,
+ context,
+ FilePath,
+ CoordinateSystem=1,
+ FlipNormals=False,
+ ApplyModifiers=False,
+ Scale=100,
+ AnimFPS=30,
+ ExportVertexColors=True,
+ ExportMaterialColors=True,
+ ExportTextures=True,
+ CopyTextureFiles=True,
+ ExportArmatures=False,
+ ExportAnimationFrames=0,
+ ExportAnimationActions=0,
+ ExportMode=1,
+ MergeModes=0,
+ Verbose=False):
+ self.context = context
+ self.FilePath = FilePath
+ self.CoordinateSystem = int(CoordinateSystem)
+ self.FlipNormals = FlipNormals
+ self.ApplyModifiers = ApplyModifiers
+ self.Scale = Scale
+ self.AnimFPS = AnimFPS
+ self.ExportVertexColors = ExportVertexColors
+ self.ExportMaterialColors = ExportMaterialColors
+ self.ExportTextures = ExportTextures
+ self.CopyTextureFiles = CopyTextureFiles
+ self.ExportArmatures = ExportArmatures
+ self.ExportAnimationFrames = int(ExportAnimationFrames)
+ self.ExportAnimationActions = int(ExportAnimationActions)
+ self.ExportMode = int(ExportMode)
+ self.MergeModes = int(MergeModes)
+ self.Verbose = Verbose
+ self.WarningList = []
+
+
+def ExportMadeWithMarmaladeGroup(Config):
+ print("----------\nExporting to {}".format(Config.FilePath))
+ if Config.Verbose:
+ print("Opening File...")
+ Config.File = open(Config.FilePath, "w")
+
+ if Config.Verbose:
+ print("Done")
+
+ if Config.Verbose:
+ print("writing group header")
+
+ Config.File.write('// Marmalade group file exported from : %s\n' % bpy.data.filepath)
+ Config.File.write('// Exported %s\n' % str(datetime.datetime.now()))
+ Config.File.write("CIwResGroup\n{\n\tname \"%s\"\n" % bpy.path.display_name_from_filepath(Config.FilePath))
+
+ if Config.Verbose:
+ print("Generating Object list for export... (Root parents only)")
+ if Config.ExportMode == 1:
+ Config.ExportList = [Object for Object in Config.context.scene.objects
+ if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}
+ and Object.parent is None]
+ else:
+ ExportList = [Object for Object in Config.context.selected_objects
+ if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}]
+ Config.ExportList = [Object for Object in ExportList
+ if Object.parent not in ExportList]
+ if Config.Verbose:
+ print(" List: {}\nDone".format(Config.ExportList))
+
+ if Config.Verbose:
+ print("Setting up...")
+
+ if Config.ExportAnimationFrames:
+ if Config.Verbose:
+ print(bpy.context.scene)
+ print(bpy.context.scene.frame_current)
+ CurrentFrame = bpy.context.scene.frame_current
+ if Config.Verbose:
+ print("Done")
+
+ Config.ObjectList = []
+ if Config.Verbose:
+ print("Writing Objects...")
+ WriteObjects(Config, Config.ExportList)
+ if Config.Verbose:
+ print("Done")
+
+ if Config.Verbose:
+ print("Objects Exported: {}".format(Config.ExportList))
+
+ if Config.ExportAnimationFrames:
+ if Config.Verbose:
+ print("Writing Animation...")
+ WriteKeyedAnimationSet(Config, bpy.context.scene)
+ bpy.context.scene.frame_current = CurrentFrame
+ if Config.Verbose:
+ print("Done")
+ Config.File.write("}\n")
+ CloseFile(Config)
+ print("Finished")
+
+
+def GetObjectChildren(Parent):
+ return [Object for Object in Parent.children
+ if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}]
+
+
+#Returns the file path of first image texture from Material.
+def GetMaterialTextureFullPath(Config, Material):
+ if Material:
+ #Create a list of Textures that have type "IMAGE"
+ ImageTextures = [Material.texture_slots[TextureSlot].texture for TextureSlot in Material.texture_slots.keys() if Material.texture_slots[TextureSlot].texture.type == "IMAGE"]
+ #Refine a new list with only image textures that have a file source
+ TexImages = [Texture.image for Texture in ImageTextures if getattr(Texture.image, "source", "") == "FILE"]
+ ImageFiles = [Texture.image.filepath for Texture in ImageTextures if getattr(Texture.image, "source", "") == "FILE"]
+ if TexImages:
+ filepath = TexImages[0].filepath
+ if TexImages[0].packed_file:
+ TexImages[0].unpack()
+ if not os.path.exists(filepath):
+ #try relative path to the blend file
+ filepath = os.path.dirname(bpy.data.filepath) + filepath
+ #Marmalade doesn't like jpeg/tif so try to convert in png on the fly
+ if (TexImages[0].file_format == 'JPEG' or TexImages[0].file_format == 'TIFF') and os.path.exists(filepath):
+ marmaladeConvert = os.path.expandvars("%S3E_DIR%\\..\\tools\\ImageMagick\\win32\\convert.exe")
+ if (os.path.exists(marmaladeConvert)):
+ srcImagefilepath = filepath
+ filepath = os.path.splitext(filepath)[0] + '.png'
+ if Config.Verbose:
+ print(" /!\\ Converting Texture %s in PNG: %s{}..." % (TexImages[0].file_format, filepath))
+ print('"%s" "%s" "%s"' % (marmaladeConvert, srcImagefilepath, filepath))
+ subprocess.call([marmaladeConvert, srcImagefilepath, filepath])
+ return filepath
+ return None
+
+
+def WriteObjects(Config, ObjectList, geoFile=None, mtlFile=None, GeoModel=None, bChildObjects=False):
+ Config.ObjectList += ObjectList
+
+ if bChildObjects == False and Config.MergeModes > 0:
+ if geoFile == None:
+ #we merge objects, so use name of group file for the name of Geo
+ geoFile, mtlFile = CreateGeoMtlFiles(Config, bpy.path.display_name_from_filepath(Config.FilePath))
+ GeoModel = CGeoModel(bpy.path.display_name_from_filepath(Config.FilePath))
+
+ for Object in ObjectList:
+ if Config.Verbose:
+ print(" Writing Object: {}...".format(Object.name))
+
+ if Config.ExportArmatures and Object.type == "ARMATURE":
+ Armature = Object.data
+ ParentList = [Bone for Bone in Armature.bones if Bone.parent is None]
+ if Config.Verbose:
+ print(" Writing Armature Bones...")
+ #Create the skel file
+ skelfullname = os.path.dirname(Config.FilePath) + os.sep + "models" + os.sep + "%s.skel" % (StripName(Object.name))
+ ensure_dir(skelfullname)
+ if Config.Verbose:
+ print(" Creating skel file %s" % (skelfullname))
+
+ skelFile = open(skelfullname, "w")
+ skelFile.write('// skel file exported from : %r\n' % os.path.basename(bpy.data.filepath))
+ skelFile.write("CIwAnimSkel\n")
+ skelFile.write("{\n")
+ skelFile.write("\tnumBones %d\n" % (len(Armature.bones)))
+ Config.File.write("\t\".\models\%s.skel\"\n" % (StripName(Object.name)))
+
+ WriteArmatureParentRootBones(Config, Object, ParentList, skelFile)
+
+ skelFile.write("}\n")
+ skelFile.close()
+ if Config.Verbose:
+ print(" Done")
+
+ ChildList = GetObjectChildren(Object)
+ if Config.ExportMode == 2: # Selected Objects Only
+ ChildList = [Child for Child in ChildList
+ if Child in Config.context.selected_objects]
+ if Config.Verbose:
+ print(" Writing Children...")
+ WriteObjects(Config, ChildList, geoFile, mtlFile, GeoModel, True)
+ if Config.Verbose:
+ print(" Done Writing Children")
+
+ if Object.type == "MESH":
+ if Config.Verbose:
+ print(" Generating Mesh...")
+ if Config.ApplyModifiers:
+ if Config.ExportArmatures:
+ #Create a copy of the object and remove all armature modifiers so an unshaped
+ #mesh can be created from it.
+ Object2 = Object.copy()
+ for Modifier in [Modifier for Modifier in Object2.modifiers if Modifier.type == "ARMATURE"]:
+ Object2.modifiers.remove(Modifier)
+ Mesh = Object2.to_mesh(bpy.context.scene, True, "PREVIEW")
+ else:
+ Mesh = Object.to_mesh(bpy.context.scene, True, "PREVIEW")
+ else:
+ Mesh = Object.to_mesh(bpy.context.scene, False, "PREVIEW")
+ if Config.Verbose:
+ print(" Done")
+ print(" Writing Mesh...")
+
+ # Flip ZY axis (Blender Z up: Marmalade: Y up) ans Scale appropriately
+ X_ROT = mathutils.Matrix.Rotation(-math.pi / 2, 4, 'X')
+
+ if Config.MergeModes == 0:
+ # No merge, so all objects are exported in MODEL SPACE and not in world space
+ # Calculate Scale of the Export
+ meshScale = Object.matrix_world.to_scale() # Export is working, even if user doesn't have use apply scale in Edit mode.
+
+ scalematrix = Matrix()
+ scalematrix[0][0] = meshScale.x * Config.Scale
+ scalematrix[1][1] = meshScale.y * Config.Scale
+ scalematrix[2][2] = meshScale.z * Config.Scale
+
+ meshRot = Object.matrix_world.to_quaternion() # Export is working, even if user doesn't have use apply Rotation in Edit mode.
+ Mesh.transform(X_ROT * meshRot.to_matrix().to_4x4() * scalematrix)
+ else:
+ # In Merge mode, we need to keep relative postion of each objects, so we export in WORLD SPACE
+ SCALE_MAT = mathutils.Matrix.Scale(Config.Scale, 4)
+ Mesh.transform(SCALE_MAT * X_ROT * Object.matrix_world)
+
+ # manage merge options
+
+ if Config.MergeModes == 0:
+ #one geo per Object, so use name of Object for the Geo file
+ geoFile, mtlFile = CreateGeoMtlFiles(Config, StripName(Object.name))
+ GeoModel = CGeoModel(StripName(Object.name))
+
+ # Write the Mesh in the Geo file
+ WriteMesh(Config, Object, Mesh, geoFile, mtlFile, GeoModel)
+
+ if Config.MergeModes == 0:
+ # no merge so finalize the file, and discard the file and geo class
+ FinalizeGeoMtlFiles(Config, geoFile, mtlFile)
+ geoFile = None
+ mtlFile = None
+ GeoModel = None
+ elif Config.MergeModes == 1:
+ # merge in one Mesh, so keep the Geo class and prepare to change object
+ GeoModel.NewObject()
+ elif Config.MergeModes == 2:
+ # merge several Meshes in one file: so clear the mesh data that we just written in the file,
+ # but keep Materials info that need to be merged across objects
+ GeoModel.ClearAllExceptMaterials()
+
+ if Config.Verbose:
+ print(" Done")
+
+ if Config.ApplyModifiers and Config.ExportArmatures:
+ bpy.data.objects.remove(Object2)
+ bpy.data.meshes.remove(Mesh)
+
+ if Config.Verbose:
+ print(" Done Writing Object: {}".format(Object.name))
+
+ if bChildObjects == False:
+ # we have finish to do all objects
+ if GeoModel:
+ if Config.MergeModes == 1:
+ # we have Merges all objects in one Mesh, so time to write this big mesh in the file
+ GeoModel.PrintGeoMesh(geoFile)
+ # time to write skinfile if any
+ if len(GeoModel.useBonesDict) > 0:
+ # some mesh was not modified by the armature. so we must skinned the merged mesh.
+ # So unskinned vertices from unarmatured meshes, are assigned to the root bone of the armature
+ for i in range(0, len(GeoModel.vList)):
+ if not i in GeoModel.skinnedVertices:
+ GeoModel.skinnedVertices.append(i)
+ useBonesKey = pow(2, GeoModel.armatureRootBoneIndex)
+ vertexGroupIndices = list((GeoModel.armatureRootBoneIndex,))
+ if useBonesKey not in GeoModel.useBonesDict:
+ GeoModel.mapVertexGroupNames[GeoModel.armatureRootBoneIndex] = StripBoneName(GeoModel.armatureRootBone.name)
+ VertexList = []
+ VertexList.append("\t\tvertWeights { %d, 1.0}" % i)
+ GeoModel.useBonesDict[useBonesKey] = (vertexGroupIndices, VertexList)
+ else:
+ pair_ListGroupIndices_ListAssignedVertices = GeoModel.useBonesDict[useBonesKey]
+ pair_ListGroupIndices_ListAssignedVertices[1].append("\t\tvertWeights { %d, 1.0}" % i)
+ GeoModel.useBonesDict[useBonesKey] = pair_ListGroupIndices_ListAssignedVertices
+ # now generates the skin file
+ PrintSkinWeights(Config, GeoModel.armatureObjectName, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, GeoModel.name)
+ if Config.MergeModes > 0:
+ WriteMeshMaterialsForGeoModel(Config, mtlFile, GeoModel)
+ FinalizeGeoMtlFiles(Config, geoFile, mtlFile)
+ geoFile = None
+ mtlFile = None
+ GeoModel = None
+
+
+def CreateGeoMtlFiles(Config, Name):
+ #Create the geo file
+ geofullname = os.path.dirname(Config.FilePath) + os.sep + "models" + os.sep + "%s.geo" % Name
+ ensure_dir(geofullname)
+ if Config.Verbose:
+ print(" Creating geo file %s" % (geofullname))
+ geoFile = open(geofullname, "w")
+ geoFile.write('// geo file exported from : %r\n' % os.path.basename(bpy.data.filepath))
+ geoFile.write("CIwModel\n")
+ geoFile.write("{\n")
+ geoFile.write("\tname \"%s\"\n" % Name)
+ # add it to the group
+ Config.File.write("\t\".\models\%s.geo\"\n" % Name)
+
+ # Create the mtl file
+ mtlfullname = os.path.dirname(Config.FilePath) + os.sep + "models" + os.sep + "%s.mtl" % Name
+ ensure_dir(mtlfullname)
+ if Config.Verbose:
+ print(" Creating mtl file %s" % (mtlfullname))
+ mtlFile = open(mtlfullname, "w")
+ mtlFile.write('// mtl file exported from : %r\n' % os.path.basename(bpy.data.filepath))
+ return geoFile, mtlFile
+
+
+def FinalizeGeoMtlFiles(Config, geoFile, mtlFile):
+ if Config.Verbose:
+ print(" Closing geo file")
+ geoFile.write("}\n")
+ geoFile.close()
+ if Config.Verbose:
+ print(" Closing mtl file")
+ mtlFile.close()
+
+
+def WriteMesh(Config, Object, Mesh, geoFile=None, mtlFile=None, GeoModel=None):
+ if geoFile == None or mtlFile == None:
+ print (" ERROR not geo file arguments in WriteMesh method")
+ return
+
+ if GeoModel == None:
+ print (" ERROR not GeoModel arguments in WriteMesh method")
+ return
+
+ BuildOptimizedGeo(Config, Object, Mesh, GeoModel)
+ if Config.MergeModes == 0 or Config.MergeModes == 2:
+ #if we don't merge, or if we write several meshes into one file ... write the mesh everytime we do an object
+ GeoModel.PrintGeoMesh(geoFile)
+
+ if Config.Verbose:
+ print(" Done\n Writing Mesh Materials...")
+
+ if Config.MergeModes == 0:
+ #No merge, so we can diretly write the Mtl file associated to this object
+ WriteMeshMaterialsForGeoModel(Config, mtlFile, GeoModel)
+
+ if Config.Verbose:
+ print(" Done")
+
+ if Config.ExportArmatures:
+ if Config.Verbose:
+ print(" Writing Mesh Weights...")
+ WriteMeshSkinWeightsForGeoModel(Config, Object, Mesh, GeoModel)
+ if Config.Verbose:
+ print(" Done")
+
+
+###### optimized version fo Export, can be used also to merge several object in one single geo File ######
+
+# CGeoModel
+# -> List Vertices
+# -> List Normales
+# -> List uv 0
+# -> List uv 1
+# -> List Vertex Colors
+# -> List Materials
+# -> Material name
+# -> Blender Material Object
+# -> List Tris -> Stream Indices v,vn,uv0,uv1,vc
+# -> List Quads -> Stream Indices v,vn,uv0,uv1,vc
+
+
+#############
+#Store one Point of a Quad or Tri in marmalade geo format: //index-list is: { <int> <int> <int> <int> <int> } //v,vn,uv0,uv1,vc
+#############
+class CGeoIndexList:
+ __slots__ = "v", "vn", "uv0", "uv1", "vc"
+
+ def __init__(self, v, vn, uv0, uv1, vc):
+ self.v = v
+ self.vn = vn
+ self.uv0 = uv0
+ self.uv1 = uv1
+ self.vc = vc
+
+
+#############
+#Store a Quad or a Tri in marmalade geo format : 3 or 4 CIndexList depending it is a Tri or a Quad
+#############
+class CGeoPoly:
+ __slots__ = "pointsList",
+
+ def __init__(self):
+ self.pointsList = []
+
+ def AddPoint(self, v, vn, uv0, uv1, vc):
+ self.pointsList.append( CGeoIndexList(v, vn, uv0, uv1, vc))
+
+ def PointsCount(self):
+ return len(self.pointsList)
+
+ def PrintPoly(self, geoFile):
+ if len(self.pointsList) == 3:
+ geoFile.write("\t\t\t\tt ")
+ if len(self.pointsList) == 4:
+ geoFile.write("\t\t\t\tq ")
+ for point in self.pointsList:
+ geoFile.write(" {%d, %d, %d, %d, %d}" % (point.v, point.vn, point.uv0, point.uv1, point.vc))
+ geoFile.write("\n")
+
+
+#############
+#Store all the poly (tri or quad) assigned to a Material in marmalade geo format
+#############
+class CGeoMaterialPolys:
+ __slots__ = "name", "material", "quadList", "triList", "currentPoly"
+
+ def __init__(self, name, material=None):
+ self.name = name
+ self.material = material
+ self.quadList = []
+ self.triList = []
+ self.currentPoly = None
+
+ def BeginPoly(self):
+ self.currentPoly = CGeoPoly()
+
+ def AddPoint(self, v, vn, uv0, uv1, vc):
+ self.currentPoly.AddPoint(v, vn, uv0, uv1, vc)
+
+ def EndPoly(self):
+ if (self.currentPoly.PointsCount() == 3):
+ self.triList.append(self.currentPoly)
+ if (self.currentPoly.PointsCount() == 4):
+ self.quadList.append(self.currentPoly)
+ self.currentPoly = None
+
+ def ClearPolys(self):
+ self.quadList = []
+ self.triList = []
+ self.currentPoly = None
+
+ def PrintMaterialPolys(self, geoFile):
+ geoFile.write("\t\tCSurface\n")
+ geoFile.write("\t\t{\n")
+ geoFile.write("\t\t\tmaterial \"%s\"\n" % self.name)
+ if self.triList:
+ geoFile.write("\t\t\tCTris\n")
+ geoFile.write("\t\t\t{\n")
+ geoFile.write("\t\t\t\tnumTris %d\n" % (len(self.triList)))
+ for poly in self.triList:
+ poly.PrintPoly(geoFile)
+ geoFile.write("\t\t\t}\n")
+
+ if self.quadList:
+ geoFile.write("\t\t\tCQuads\n")
+ geoFile.write("\t\t\t{\n")
+ geoFile.write("\t\t\t\tnumQuads %d\n" % (len(self.quadList)))
+ for poly in self.quadList:
+ poly.PrintPoly(geoFile)
+ geoFile.write("\t\t\t}\n")
+ geoFile.write("\t\t}\n")
+
+
+#############
+#Store all the information on a Model/Mesh (vertices, normal, certcies color, uv0, uv1, TRI, QUAD) in marmalade geo format
+#############
+class CGeoModel:
+ __slots__ = ("name", "MaterialsDict", "vList", "vnList", "vcList", "uv0List", "uv1List",
+ "currentMaterialPolys", "vbaseIndex","vnbaseIndex", "uv0baseIndex", "uv1baseIndex",
+ "armatureObjectName", "useBonesDict", "mapVertexGroupNames", "armatureRootBone", "armatureRootBoneIndex", "skinnedVertices")
+
+ def __init__(self, name):
+ self.name = name
+ self.MaterialsDict = {}
+ self.vList = []
+ self.vnList = []
+ self.vcList = []
+ self.uv0List = []
+ self.uv1List = []
+ self.currentMaterialPolys = None
+ #used xx baseIndex are used when merging several blender objects into one Mesh in the geo file (internal offset)
+ self.vbaseIndex = 0
+ self.vnbaseIndex = 0
+ self.uv0baseIndex = 0
+ self.uv1baseIndex = 0
+
+ # Store some information for skin management , when we merge several object in one big mesh (MergeModes 1)
+ # can only work if in the object list only one is rigged with an armature... and if it is located in 0,0,0
+ self.armatureObjectName = ""
+ #useBonesKey : bit field, where each bit is a VertexGroup.Index): Sum(2^VertGroupIndex).
+ #useBonesDict[useBonesKey] = tuple(VertexGroups.group, list(Vertex))
+ self.useBonesDict = {}
+ self.mapVertexGroupNames = {}
+ self.armatureRootBone = None
+ self.armatureRootBoneIndex = 0
+ self.skinnedVertices = []
+
+
+
+ def AddVertex(self, vertex):
+ self.vList.append(vertex.copy())
+
+ def AddVertexNormal(self, vertexN):
+ self.vnList.append(vertexN.copy())
+
+ # add a uv coordiantes and return the current Index in the stream (index is local to the object, when we merge several object into a one Mesh)
+ def AddVertexUV0(self, u, v):
+ self.uv0List.append((u, v))
+ return len(self.uv0List) - 1 - self.uv0baseIndex
+
+ def AddVertexUV1(self, u, v):
+ self.uv1List.append((u, v))
+ return len(self.uv1List) - 1 - self.uv1baseIndex
+
+ # add a vertexcolor if it doesn't already exist and return the current Index in the stream (index is global to all objects, when we merge several object into a one Mesh)
+ def AddVertexColor(self, r, g, b, a):
+ for i in range(0, len(self.vcList)):
+ col = self.vcList[i]
+ if col[0] == r and col[1] == g and col[2] == b and col[3] == a:
+ return i
+
+ self.vcList.append((r, g, b, a))
+ return len(self.vcList)-1
+
+ def BeginPoly(self, MaterialName, material=None):
+ if MaterialName not in self.MaterialsDict:
+ self.currentMaterialPolys = CGeoMaterialPolys(MaterialName, material)
+ else:
+ self.currentMaterialPolys = self.MaterialsDict[MaterialName]
+ self.currentMaterialPolys.BeginPoly()
+
+ def AddPoint(self, v, vn, uv0, uv1, vc):
+ if v != -1:
+ v += self.vbaseIndex
+ if vn != -1:
+ vn += self.vnbaseIndex
+ if uv0 != -1:
+ uv0 += self.uv0baseIndex
+ if uv1 != -1:
+ uv1 += self.uv1baseIndex
+
+ self.currentMaterialPolys.AddPoint(v, vn, uv0, uv1, vc)
+
+ def EndPoly(self):
+ self.currentMaterialPolys.EndPoly()
+ self.MaterialsDict[self.currentMaterialPolys.name] = self.currentMaterialPolys
+ self.currentMaterialPolys = None
+
+ def NewObject(self):
+ #used in Merge mode 1: allows to merge several blender objects into one Mesh.
+ self.vbaseIndex = len(self.vList)
+ self.vnbaseIndex = len(self.vnList)
+ self.uv0baseIndex = len(self.uv0List)
+ self.uv1baseIndex = len(self.uv1List)
+
+ def ClearAllExceptMaterials(self):
+ #used in Merge mode 2: one geo with several mesh
+ self.vList = []
+ self.vnList = []
+ self.vcList = []
+ self.uv0List = []
+ self.uv1List = []
+ self.currentMaterialPolys = None
+ self.vbaseIndex = 0
+ self.vnbaseIndex = 0
+ self.uv0baseIndex = 0
+ self.uv1baseIndex = 0
+ for GeoMaterialPolys in self.MaterialsDict.values():
+ GeoMaterialPolys.ClearPolys()
+ self.useBonesDict = {}
+ self.mapVertexGroupNames = {}
+ self.armatureObjectName = ""
+ self.armatureRootBone = None
+ self.armatureRootBoneIndex = 0
+ self.skinnedVertices = []
+
+ def PrintGeoMesh(self, geoFile):
+ geoFile.write("\tCMesh\n")
+ geoFile.write("\t{\n")
+ geoFile.write("\t\tname \"%s\"\n" % (StripName(self.name)))
+
+ if self.vList:
+ geoFile.write("\t\tCVerts\n")
+ geoFile.write("\t\t{\n")
+ geoFile.write("\t\t\tnumVerts %d\n" % len(self.vList))
+ for vertex in self.vList:
+ geoFile.write("\t\t\tv { %.9f, %.9f, %.9f }\n" % (vertex[0], vertex[1], vertex[2]))
+ geoFile.write("\t\t}\n")
+
+ if self.vnList:
+ geoFile.write("\t\tCVertNorms\n")
+ geoFile.write("\t\t{\n")
+ geoFile.write("\t\t\tnumVertNorms %d\n" % len(self.vnList))
+ for vertexn in self.vnList:
+ geoFile.write("\t\t\tvn { %.9f, %.9f, %.9f }\n" % (vertexn[0], vertexn[1], vertexn[2]))
+ geoFile.write("\t\t}\n")
+
+ if self.vcList:
+ geoFile.write("\t\tCVertCols\n")
+ geoFile.write("\t\t{\n")
+ geoFile.write("\t\t\tnumVertCols %d\n" % len(self.vcList))
+ for color in self.vcList:
+ geoFile.write("\t\t\tcol { %.6f, %.6f, %.6f, %.6f }\n" % (color[0], color[1], color[2], color[3])) #alpha is not supported on blender for vertex colors
+ geoFile.write("\t\t}\n")
+
+ if self.uv0List:
+ geoFile.write("\t\tCUVs\n")
+ geoFile.write("\t\t{\n")
+ geoFile.write("\t\t\tsetID 0\n")
+ geoFile.write("\t\t\tnumUVs %d\n" % len(self.uv0List))
+ for uv in self.uv0List:
+ geoFile.write("\t\t\tuv { %.9f, %.9f }\n" % (uv[0], uv[1]))
+ geoFile.write("\t\t}\n")
+
+ if self.uv1List:
+ geoFile.write("\t\tCUVs\n")
+ geoFile.write("\t\t{\n")
+ geoFile.write("\t\t\tsetID 1\n")
+ geoFile.write("\t\t\tnumUVs %d\n" % len(self.uv1List))
+ for uv in self.uv1List:
+ geoFile.write("\t\t\tuv { %.9f, %.9f }\n" % (uv[0], uv[1]))
+ geoFile.write("\t\t}\n")
+
+ for GeoMaterialPolys in self.MaterialsDict.values():
+ GeoMaterialPolys.PrintMaterialPolys(geoFile)
+ geoFile.write("\t}\n")
+
+ def GetMaterialList(self):
+ return list(self.MaterialsDict.keys())
+
+ def GetMaterialByName(self, name):
+ if name in self.MaterialsDict:
+ return self.MaterialsDict[name].material
+ else:
+ return None
+
+
+
+#############
+# iterates faces, vertices ... and store the information in the GeoModel container
+def BuildOptimizedGeo(Config, Object, Mesh, GeoModel):
+ if GeoModel == None:
+ GeoModel = CGeoModel(filename, Object.name)
+
+ #Ensure tessfaces data are here
+ Mesh.update (calc_tessface=True)
+
+ #Store Vertex stream, and Normal stream (use directly the order from blender collection
+ for Vertex in Mesh.vertices:
+ GeoModel.AddVertex(Vertex.co)
+ Normal = Vertex.normal
+ if Config.FlipNormals:
+ Normal = -Normal
+ GeoModel.AddVertexNormal(Normal)
+ #Check if some colors have been defined
+ vertexColors = None
+ if Config.ExportVertexColors and (len(Mesh.vertex_colors) > 0):
+ vertexColors = Mesh.tessface_vertex_colors[0].data
+
+ #Check if some uv coordinates have been defined
+ UVCoordinates = None
+ if Config.ExportTextures and (len(Mesh.uv_textures) > 0):
+ for UV in Mesh.tessface_uv_textures:
+ if UV.active_render:
+ UVCoordinates = UV.data
+ break
+
+ #Iterate on Faces and Store the poly (quad or tri) and the associate colors,UVs
+ for Face in Mesh.tessfaces:
+ # stream for vertex (we use the same for normal)
+ Vertices = list(Face.vertices)
+ if Config.CoordinateSystem == 1:
+ Vertices = Vertices[::-1]
+ # stream for vertex colors
+ if vertexColors:
+ MeshColor = vertexColors[Face.index]
+ if len(Vertices) == 3:
+ FaceColors = list((MeshColor.color1, MeshColor.color2, MeshColor.color3))
+ else:
+ FaceColors = list((MeshColor.color1, MeshColor.color2, MeshColor.color3, MeshColor.color4))
+ if Config.CoordinateSystem == 1:
+ FaceColors = FaceColors[::-1]
+ colorIndex = []
+ for color in FaceColors:
+ index = GeoModel.AddVertexColor(color[0], color[1], color[2], 1) #rgba => no alpha on vertex color in Blender so use 1
+ colorIndex.append(index)
+ else:
+ colorIndex = list((-1,-1,-1,-1))
+
+ # stream for UV0 coordinates
+ if UVCoordinates:
+ uvFace = UVCoordinates[Face.index]
+ uvVertices = []
+ for uvVertex in uvFace.uv:
+ uvVertices.append(tuple(uvVertex))
+ if Config.CoordinateSystem == 1:
+ uvVertices = uvVertices[::-1]
+ uv0Index = []
+ for uvVertex in uvVertices:
+ index = GeoModel.AddVertexUV0(uvVertex[0], 1 - uvVertex[1])
+ uv0Index.append(index)
+ else:
+ uv0Index = list((-1, -1, -1, -1))
+
+ # stream for UV1 coordinates
+ uv1Index = list((-1, -1, -1, -1))
+
+ mat = None
+ # find the associated material
+ if Face.material_index < len(Mesh.materials):
+ mat = Mesh.materials[Face.material_index]
+ if mat:
+ matName = mat.name
+ else:
+ matName = "NoMaterialAssigned" # There is no material assigned in blender !!!, exporter have generated a default one
+
+ # now on the material, generates the tri/quad in v,vn,uv0,uv1,vc stream index
+ GeoModel.BeginPoly(matName, mat)
+
+ for i in range(0, len(Vertices)):
+ GeoModel.AddPoint(Vertices[i], Vertices[i], uv0Index[i], uv1Index[i], colorIndex[i])
+
+ GeoModel.EndPoly()
+
+
+
+#############
+# Get the list of Material in use by the CGeoModel
+def WriteMeshMaterialsForGeoModel(Config, mtlFile, GeoModel):
+ for matName in GeoModel.GetMaterialList():
+ Material = GeoModel.GetMaterialByName(matName)
+ WriteMaterial(Config, mtlFile, Material)
+
+
+def WriteMaterial(Config, mtlFile, Material=None):
+ mtlFile.write("CIwMaterial\n")
+ mtlFile.write("{\n")
+ if Material:
+ mtlFile.write("\tname \"%s\"\n" % Material.name)
+
+ if Config.ExportMaterialColors:
+ #if bpy.context.scene.world:
+ # MatAmbientColor = Material.ambient * bpy.context.scene.world.ambient_color
+ MatAmbientColor = Material.ambient * Material.diffuse_color
+ mtlFile.write("\tcolAmbient {%.2f,%.2f,%.2f,%.2f} \n" % (min(255, MatAmbientColor[0] * 255), min(255, MatAmbientColor[1] * 255), min(255, MatAmbientColor[2] * 255), min(255, Material.alpha * 255)))
+ MatDiffuseColor = 255 * Material.diffuse_intensity * Material.diffuse_color
+ MatDiffuseColor = min((255, 255, 255)[:],MatDiffuseColor[:])
+ mtlFile.write("\tcolDiffuse {%.2f,%.2f,%.2f} \n" % (MatDiffuseColor[:]))
+ MatSpecularColor = 255 * Material.specular_intensity * Material.specular_color
+ MatSpecularColor = min((255, 255, 255)[:],MatSpecularColor[:])
+ mtlFile.write("\tcolSpecular {%.2f,%.2f,%.2f} \n" % (MatSpecularColor[:]))
+ # EmitColor = Material.emit * Material.diffuse_color
+ # mtlFile.write("\tcolEmissive {%.2f,%.2f,%.2f} \n" % (EmitColor* 255)[:])
+ else:
+ mtlFile.write("\tname \"NoMaterialAssigned\" // There is no material assigned in blender !!!, exporter have generated a default one\n")
+
+ #Copy texture
+ if Config.ExportTextures:
+ Texture = GetMaterialTextureFullPath(Config, Material)
+ if Texture:
+ mtlFile.write("\ttexture0 .\\textures\\%s\n" % (bpy.path.basename(Texture)))
+
+ if Config.CopyTextureFiles:
+ if not os.path.exists(Texture):
+ #try relative path to the blend file
+ Texture = os.path.dirname(bpy.data.filepath) + Texture
+ if os.path.exists(Texture):
+ textureDest = os.path.dirname(Config.FilePath) + os.sep + "models" + os.sep + "textures" + os.sep + ("%s" % bpy.path.basename(Texture))
+ ensure_dir(textureDest)
+ if Config.Verbose:
+ print(" Copying the texture file %s ---> %s" % (Texture, textureDest))
+ shutil.copy(Texture, textureDest)
+ else:
+ if Config.Verbose:
+ print(" CANNOT Copy texture file (not found) %s" % (Texture))
+ mtlFile.write("}\n")
+
+def GetFirstRootBone(ArmatureObject):
+ ArmatureBones = ArmatureObject.data.bones
+ ParentBoneList = [Bone for Bone in ArmatureBones if Bone.parent is None]
+ if ParentBoneList:
+ return ParentBoneList[0]
+ return None
+
+
+def GetVertexGroupFromBone(Object, Bone):
+ if Bone:
+ vertexGroupList = [VertexGroup for VertexGroup in Object.vertex_groups if VertexGroup.name == Bone.name]
+ if vertexGroupList:
+ return vertexGroupList[0]
+ return None
+
+
+def GetBoneListNames(Bones):
+ boneList = []
+ for Bone in Bones:
+ boneList.append(Bone.name)
+ boneList += GetBoneListNames(Bone.children)
+ return boneList
+
+
+def FindUniqueIndexForRootBone(Object, RootVertexGroup):
+ if RootVertexGroup:
+ return RootVertexGroup.index
+ else:
+ #If there is not VertexGroup associated to the root bone name, we don't have a vertex index.
+ #so use the next available free index
+ return len(Object.vertex_groups)
+
+
+def WriteMeshSkinWeightsForGeoModel(Config, Object, Mesh, GeoModel):
+ ArmatureList = [Modifier for Modifier in Object.modifiers if Modifier.type == "ARMATURE"]
+ if ArmatureList:
+ ArmatureObject = ArmatureList[0].object
+ if ArmatureObject is None:
+ return
+ RootBone = GetFirstRootBone(ArmatureObject)
+ RootVertexGroup = GetVertexGroupFromBone(Object, RootBone)
+ BoneNames = GetBoneListNames(ArmatureObject.data.bones)
+
+ GeoModel.armatureObjectName = StripName(ArmatureObject.name)
+ if RootBone:
+ GeoModel.armatureRootBone = RootBone
+ GeoModel.armatureRootBoneIndex = FindUniqueIndexForRootBone(Object, RootVertexGroup)
+
+ # Marmalade need to declare a vertex per list of affected bones
+ # so first we have to get all the combinations of affected bones that exist in the mesh
+ # to build thoses groups, we build a unique key (like a bit field, where each bit is a VertexGroup.Index): Sum(2^VertGroupIndex)... so we have a unique Number per combinations
+
+ for Vertex in Mesh.vertices:
+ VertexIndex = Vertex.index + GeoModel.vbaseIndex
+ AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup, BoneNames)
+ GeoModel.skinnedVertices.append(VertexIndex)
+
+ if Config.MergeModes != 1:
+ # write skin file directly
+ PrintSkinWeights(Config, GeoModel.armatureObjectName, GeoModel.useBonesDict, GeoModel.mapVertexGroupNames, StripName(Object.name))
+
+
+def PrintSkinWeights(Config, ArmatureObjectName, useBonesDict, mapVertexGroupNames, GeoName):
+ #Create the skin file
+ skinfullname = os.path.dirname(Config.FilePath) + os.sep + "models" + os.sep + "%s.skin" % GeoName
+ ensure_dir(skinfullname)
+ if Config.Verbose:
+ print(" Creating skin file %s" % (skinfullname))
+ skinFile = open(skinfullname, "w")
+ skinFile.write('// skin file exported from : %r\n' % os.path.basename(bpy.data.filepath))
+ skinFile.write("CIwAnimSkin\n")
+ skinFile.write("{\n")
+ skinFile.write("\tskeleton \"%s\"\n" % ArmatureObjectName)
+ skinFile.write("\tmodel \"%s\"\n" % GeoName)
+
+ # now we have Bones grouped in the dictionary , along with the associated influenced vertex weighting
+ # So simply iterate the dictionary
+ Config.File.write("\t\".\models\%s.skin\"\n" % GeoName)
+ for pair_ListGroupIndices_ListAssignedVertices in useBonesDict.values():
+ skinFile.write("\tCIwAnimSkinSet\n")
+ skinFile.write("\t{\n")
+ skinFile.write("\t\tuseBones {")
+ for vertexGroupIndex in pair_ListGroupIndices_ListAssignedVertices[0]:
+ skinFile.write(" %s" % mapVertexGroupNames[vertexGroupIndex])
+ skinFile.write(" }\n")
+ skinFile.write("\t\tnumVerts %d\n" % len(pair_ListGroupIndices_ListAssignedVertices[1]))
+ for VertexWeightString in pair_ListGroupIndices_ListAssignedVertices[1]:
+ skinFile.write(VertexWeightString)
+ skinFile.write("\t}\n")
+
+ skinFile.write("}\n")
+ skinFile.close()
+
+
+def AddVertexToDicionarySkinWeights(Config, Object, Mesh, Vertex, useBonesDict, mapVertexGroupNames, VertexIndex, RootBone, RootVertexGroup, BoneNames):
+ #build useBones
+ useBonesKey = 0
+ vertexGroupIndices = []
+ weightTotal = 0.0
+ if (len(Vertex.groups)) > 4:
+ print ("ERROR Vertex %d is influenced by more than 4 bones\n" % (VertexIndex))
+ for VertexGroup in Vertex.groups:
+ if (VertexGroup.weight > 0):
+ groupName = Object.vertex_groups[VertexGroup.group].name
+ if groupName in BoneNames:
+ mapVertexGroupNames[VertexGroup.group] = StripBoneName(groupName)
+ if (len(vertexGroupIndices))<4: #ignore if more 4 bones are influencing the vertex
+ useBonesKey = useBonesKey + pow(2, VertexGroup.group)
+ vertexGroupIndices.append(VertexGroup.group)
+ weightTotal = weightTotal + VertexGroup.weight
+ if (weightTotal == 0):
+ bWeightTotZero = True #avoid divide by zero later on
+ if (RootBone):
+ if Config.Verbose:
+ print(" Warning Weight is ZERO for vertex %d => Add it to the root bone" % (VertexIndex))
+ RootBoneGroupIndex = FindUniqueIndexForRootBone(Object, RootVertexGroup)
+ mapVertexGroupNames[RootBoneGroupIndex] = StripBoneName(RootBone.name)
+ useBonesKey = pow(2, RootBoneGroupIndex)
+ vertexGroupIndices = list((RootBoneGroupIndex,))
+
+ weightTotal = 1
+ else:
+ bWeightTotZero = False
+
+ if len(vertexGroupIndices) > 0:
+ vertexGroupIndices.sort();
+
+ #build the vertex weight string: vertex indices, followed by influence weight for each bone
+ VertexWeightString = "\t\tvertWeights { %d" % (VertexIndex)
+ for vertexGroupIndex in vertexGroupIndices:
+ #get the weight of this specific VertexGroup (aka bone)
+ boneWeight = 1
+ for VertexGroup in Vertex.groups:
+ if VertexGroup.group == vertexGroupIndex:
+ boneWeight = VertexGroup.weight
+ #calculate the influence of this bone compared to the total of weighting applied to this Vertex
+ if not bWeightTotZero:
+ VertexWeightString += ", %.7f" % (boneWeight / weightTotal)
+ else:
+ VertexWeightString += ", %.7f" % (1.0 / len(vertexGroupIndices))
+ VertexWeightString += "}"
+ if bWeightTotZero:
+ VertexWeightString += " // total weight was zero in blender , export assign it to the RootBone with weight 1."
+ if (len(Vertex.groups)) > 4:
+ VertexWeightString += " // vertex is associated to more than 4 bones in blender !! skip some bone association (was associated to %d bones)." % (len(Vertex.groups))
+ VertexWeightString += "\n"
+
+ #store in dictionnary information
+ if useBonesKey not in useBonesDict:
+ VertexList = []
+ VertexList.append(VertexWeightString)
+ useBonesDict[useBonesKey] = (vertexGroupIndices, VertexList)
+ else:
+ pair_ListGroupIndices_ListAssignedVertices = useBonesDict[useBonesKey]
+ pair_ListGroupIndices_ListAssignedVertices[1].append(VertexWeightString)
+ useBonesDict[useBonesKey] = pair_ListGroupIndices_ListAssignedVertices
+ else:
+ print ("ERROR Vertex %d is not skinned (it doesn't belong to any vertex group\n" % (VertexIndex))
+
+
+
+############# ARMATURE: Bone export, and Bone animation export
+
+
+def WriteArmatureParentRootBones(Config, Object, RootBonesList, skelFile):
+
+ if len(RootBonesList) > 1:
+ print(" /!\\ WARNING ,Marmelade need only one ROOT bone per armature, there is %d root bones " % len(RootBonesList))
+ print(RootBonesList)
+
+ PoseBones = Object.pose.bones
+ for Bone in RootBonesList:
+ if Config.Verbose:
+ print(" Writing Root Bone: {}...".format(Bone.name))
+
+ PoseBone = PoseBones[Bone.name]
+ WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True)
+ if Config.Verbose:
+ print(" Done")
+ WriteArmatureChildBones(Config, Object, Bone.children, skelFile)
+
+
+def WriteArmatureChildBones(Config, Object, BonesList, skelFile):
+ PoseBones = Object.pose.bones
+ for Bone in BonesList:
+ if Config.Verbose:
+ print(" Writing Child Bone: {}...".format(Bone.name))
+ PoseBone = PoseBones[Bone.name]
+ WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, skelFile, True)
+ if Config.Verbose:
+ print(" Done")
+
+ WriteArmatureChildBones(Config, Object, Bone.children, skelFile)
+
+
+def WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, File, isRestPoseNotAnimPose):
+ # Compute armature scale :
+ # Many others exporter require sthe user to do Apply Scale in Object Mode to have 1,1,1 scale and so that anim data are correctly scaled
+ # Here we retreive the Scale of the Armture Object.matrix_world.to_scale() and we use it to scale the bones :-)
+ # So new Blender user should not complain about bad animation export if they forgot to apply the Scale to 1,1,1
+
+ armScale = Object.matrix_world.to_scale()
+ armRot = Object.matrix_world.to_quaternion()
+ if isRestPoseNotAnimPose:
+ #skel file, bone header
+ File.write("\tCIwAnimBone\n")
+ File.write("\t{\n")
+ File.write("\t\tname \"%s\"\n" % StripBoneName(Bone.name))
+ #get bone local matrix for rest pose
+ if Bone.parent:
+ File.write("\t\tparent \"%s\"\n" % StripBoneName(Bone.parent.name))
+ localmat = Bone.parent.matrix_local.inverted() * Bone.matrix_local
+ else:
+ localmat = Bone.matrix_local
+ else:
+ #anim file, bone header
+ File.write("\t\t\n")
+ File.write("\t\tbone \"%s\" \n" % StripBoneName(Bone.name))
+ localmat = PoseBone.matrix
+ #get bone local matrix for current anim pose
+ if Bone.parent:
+ ParentPoseBone = PoseBones[Bone.parent.name]
+ localmat = ParentPoseBone.matrix.inverted() * PoseBone.matrix
+ else:
+ localmat = PoseBone.matrix
+
+ if not Bone.parent:
+ #Flip Y Z axes (only on root bone, other bones are local to root bones, so no need to rotate)
+ X_ROT = mathutils.Matrix.Rotation(-math.pi / 2, 4, 'X')
+ if Config.MergeModes > 0:
+ # Merge mode is in world coordinates and not in model coordinates: so apply the world coordinate on the rootbone
+ localmat = X_ROT * Object.matrix_world * localmat
+ armScale.x = armScale.y = armScale.z = 1
+ else:
+ localmat= X_ROT * armRot.to_matrix().to_4x4() * localmat #apply the armature rotation on the root bone
+
+
+ loc = localmat.to_translation()
+ quat = localmat.to_quaternion()
+
+ #Scale the bone
+ loc.x *= (armScale.x * Config.Scale)
+ loc.y *= (armScale.y * Config.Scale)
+ loc.z *= (armScale.z * Config.Scale)
+
+ File.write("\t\tpos { %.9f, %.9f, %.9f }\n" % (loc[0], loc[1], loc[2]))
+ File.write("\t\trot { %.9f, %.9f, %.9f, %.9f }\n" % (quat.w, quat.x, quat.y, quat.z))
+
+ if isRestPoseNotAnimPose:
+ File.write("\t}\n")
+
+
+def WriteKeyedAnimationSet(Config, Scene):
+ for Object in [Object for Object in Config.ObjectList if Object.animation_data]:
+ if Config.Verbose:
+ print(" Writing Animation Data for Object: {}".format(Object.name))
+ actions = []
+ if Config.ExportAnimationActions == 0 and Object.animation_data.action:
+ actions.append(Object.animation_data.action)
+ else:
+ actions = bpy.data.actions[:]
+ DefaultAction = Object.animation_data.action
+
+ for Action in actions:
+ if Config.ExportAnimationActions == 0:
+ animFileName = StripName(Object.name)
+ else:
+ Object.animation_data.action = Action
+ animFileName = "%s_%s" % (StripName(Object.name),StripName(Action.name))
+
+ #Object animated (aka single bone object)
+ #build key frame time list
+
+ keyframeTimes = set()
+ if Config.ExportAnimationFrames == 1:
+ # Exports only key frames
+ for FCurve in Action.fcurves:
+ for Keyframe in FCurve.keyframe_points:
+ if Keyframe.co[0] < Scene.frame_start:
+ keyframeTimes.add(Scene.frame_start)
+ elif Keyframe.co[0] > Scene.frame_end:
+ keyframeTimes.add(Scene.frame_end)
+ else:
+ keyframeTimes.add(int(Keyframe.co[0]))
+ else:
+ # Exports all frames
+ keyframeTimes.update(range(Scene.frame_start, Scene.frame_end + 1, 1))
+ keyframeTimes = list(keyframeTimes)
+ keyframeTimes.sort()
+ if len(keyframeTimes):
+ #Create the anim file for offset animation (or single bone animation
+ animfullname = os.path.dirname(Config.FilePath) + os.sep + "anims" + os.sep + "%s_offset.anim" % animFileName
+ #not yet supported
+ """
+ ## ensure_dir(animfullname)
+ ## if Config.Verbose:
+ ## print(" Creating anim file (single bone animation) %s" % (animfullname))
+ ## animFile = open(animfullname, "w")
+ ## animFile.write('// anim file exported from : %r\n' % os.path.basename(bpy.data.filepath))
+ ## animFile.write("CIwAnim\n")
+ ## animFile.write("{\n")
+ ## animFile.write("\tent \"%s\"\n" % (StripName(Object.name)))
+ ## animFile.write("\tskeleton \"SingleBone\"\n")
+ ## animFile.write("\t\t\n")
+ ##
+ ## Config.File.write("\t\".\\anims\\%s_offset.anim\"\n" % animFileName))
+ ##
+ ## for KeyframeTime in keyframeTimes:
+ ## #Scene.frame_set(KeyframeTime)
+ ## animFile.write("\tCIwAnimKeyFrame\n")
+ ## animFile.write("\t{\n")
+ ## animFile.write("\t\ttime %.2f // frame num %d \n" % (KeyframeTime/Config.AnimFPS, KeyframeTime))
+ ## animFile.write("\t\t\n")
+ ## animFile.write("\t\tbone \"SingleBone\" \n")
+ ## #postion
+ ## posx = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "location" and FCurve.array_index == 0: posx = FCurve.evaluate(KeyframeTime)
+ ## posy = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "location" and FCurve.array_index == 1: posy = FCurve.evaluate(KeyframeTime)
+ ## posz = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "location" and FCurve.array_index == 2: posz = FCurve.evaluate(KeyframeTime)
+ ## animFile.write("\t\tpos {%.9f,%.9f,%.9f}\n" % (posx, posy, posz))
+ ## #rotation
+ ## rot = Euler()
+ ## rot[0] = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "rotation_euler" and FCurve.array_index == 1: rot[0] = FCurve.evaluate(KeyframeTime)
+ ## rot[1] = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "rotation_euler" and FCurve.array_index == 2: rot[1] = FCurve.evaluate(KeyframeTime)
+ ## rot[2] = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "rotation_euler" and FCurve.array_index == 3: rot[2] = FCurve.evaluate(KeyframeTime)
+ ## rot = rot.to_quaternion()
+ ## animFile.write("\t\trot {%.9f,%.9f,%.9f,%.9f}\n" % (rot[0], rot[1], rot[2], rot[3]))
+ ## #scale
+ ## scalex = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "scale" and FCurve.array_index == 0: scalex = FCurve.evaluate(KeyframeTime)
+ ## scaley = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "scale" and FCurve.array_index == 1: scaley = FCurve.evaluate(KeyframeTime)
+ ## scalez = 0
+ ## for FCurve in Action.fcurves:
+ ## if FCurve.data_path == "scale" and FCurve.array_index == 2: scalez = FCurve.evaluate(KeyframeTime)
+ ## animFile.write("\t\t//scale {%.9f,%.9f,%.9f}\n" % (scalex, scaley, scalez))
+ ## #keyframe done
+ ## animFile.write("\t}\n")
+ ## animFile.write("}\n")
+ ## animFile.close()
+ """
+ else:
+ if Config.Verbose:
+ print(" Object %s has no useable animation data." % (StripName(Object.name)))
+
+ if Config.ExportArmatures and Object.type == "ARMATURE":
+ if Config.Verbose:
+ print(" Writing Armature Bone Animation Data...\n")
+ PoseBones = Object.pose.bones
+ Bones = Object.data.bones
+ #riged bones animated
+ #build key frame time list
+ keyframeTimes = set()
+ if Config.ExportAnimationFrames == 1:
+ # Exports only key frames
+ for FCurve in Action.fcurves:
+ for Keyframe in FCurve.keyframe_points:
+ if Keyframe.co[0] < Scene.frame_start:
+ keyframeTimes.add(Scene.frame_start)
+ elif Keyframe.co[0] > Scene.frame_end:
+ keyframeTimes.add(Scene.frame_end)
+ else:
+ keyframeTimes.add(int(Keyframe.co[0]))
+ else:
+ # Exports all frame
+ keyframeTimes.update(range(Scene.frame_start, Scene.frame_end + 1, 1))
+
+ keyframeTimes = list(keyframeTimes)
+ keyframeTimes.sort()
+ if Config.Verbose:
+ print("Exporting frames: ")
+ print(keyframeTimes)
+ if (Scene.frame_preview_end > Scene.frame_end):
+ print(" WARNING: END Frame of animation in UI preview is Higher than the Scene Frame end:\n Scene.frame_end %d versus Scene.frame_preview_end %d.\n"
+ % (Scene.frame_end, Scene.frame_preview_end))
+ print(" => You might need to change the Scene End Frame, to match the current UI preview frame end...\n=> if you don't want to miss end of animation.\n")
+
+ if len(keyframeTimes):
+ #Create the anim file
+ animfullname = os.path.dirname(Config.FilePath) + os.sep + "anims" + os.sep + "%s.anim" % animFileName
+ ensure_dir(animfullname)
+ if Config.Verbose:
+ print(" Creating anim file (bones animation) %s\n" % (animfullname))
+ print(" Frame count %d \n" % (len(keyframeTimes)))
+ animFile = open(animfullname, "w")
+ animFile.write('// anim file exported from : %r\n' % os.path.basename(bpy.data.filepath))
+ animFile.write("CIwAnim\n")
+ animFile.write("{\n")
+ animFile.write("\tskeleton \"%s\"\n" % (StripName(Object.name)))
+ animFile.write("\t\t\n")
+
+ Config.File.write("\t\".\\anims\\%s.anim\"\n" % animFileName)
+
+ for KeyframeTime in keyframeTimes:
+ if Config.Verbose:
+ print(" Writing Frame %d:" % KeyframeTime)
+ animFile.write("\tCIwAnimKeyFrame\n")
+ animFile.write("\t{\n")
+ animFile.write("\t\ttime %.2f // frame num %d \n" % (KeyframeTime / Config.AnimFPS, KeyframeTime))
+ #for every frame write bones positions
+ Scene.frame_set(KeyframeTime)
+ for PoseBone in PoseBones:
+ if Config.Verbose:
+ print(" Writing Bone: {}...".format(PoseBone.name))
+ animFile.write("\t\t\n")
+
+ Bone = Bones[PoseBone.name]
+ WriteBonePosition(Config, Object, Bone, PoseBones, PoseBone, animFile, False)
+ #keyframe done
+ animFile.write("\t}\n")
+ animFile.write("}\n")
+ animFile.close()
+ else:
+ if Config.Verbose:
+ print(" Object %s has no useable animation data." % (StripName(Object.name)))
+ if Config.ExportAnimationActions == 1:
+ #set back the original default animation
+ Object.animation_data.action = DefaultAction
+ if Config.Verbose:
+ print(" Done") #Done with Object
+
+
+
+
+################## Utilities
+
+def StripBoneName(name):
+ return name.replace(" ", "")
+
+
+def StripName(Name):
+
+ def ReplaceSet(String, OldSet, NewChar):
+ for OldChar in OldSet:
+ String = String.replace(OldChar, NewChar)
+ return String
+
+ import string
+
+ NewName = ReplaceSet(Name, string.punctuation + " ", "_")
+ return NewName
+
+
+def ensure_dir(f):
+ d = os.path.dirname(f)
+ if not os.path.exists(d):
+ os.makedirs(d)
+
+
+def CloseFile(Config):
+ if Config.Verbose:
+ print("Closing File...")
+ Config.File.close()
+ if Config.Verbose:
+ print("Done")
+
+
+CoordinateSystems = (
+ ("1", "Left-Handed", ""),
+ ("2", "Right-Handed", ""),
+ )
+
+
+AnimationFrameModes = (
+ ("0", "None", ""),
+ ("1", "Keyframes Only", ""),
+ ("2", "Full Animation", ""),
+ )
+
+AnimationActions = (
+ ("0", "Default Animation", ""),
+ ("1", "All Animations", ""),
+ )
+
+ExportModes = (
+ ("1", "All Objects", ""),
+ ("2", "Selected Objects", ""),
+ )
+
+MergeModes = (
+ ("0", "None", ""),
+ ("1", "Merge in one big Mesh", ""),
+ ("2", "Merge in unique Geo File containing several meshes", ""),
+ )
+
+
+from bpy.props import StringProperty, EnumProperty, BoolProperty, IntProperty
+
+
+class MarmaladeExporter(bpy.types.Operator):
+ """Export to the Marmalade model format (.group)"""
+
+ bl_idname = "export.marmalade"
+ bl_label = "Export Marmalade"
+
+ filepath = StringProperty(subtype='FILE_PATH')
+ #Export Mode
+ ExportMode = EnumProperty(
+ name="Export",
+ description="Select which objects to export. Only Mesh, Empty, " \
+ "and Armature objects will be exported",
+ items=ExportModes,
+ default="1")
+
+ MergeModes = EnumProperty(
+ name="Merge",
+ description="Select if objects should be merged in one Geo File (it can be usefull if a scene is done by several cube/forms)." \
+ "Do not merge rigged character that have an armature.",
+ items=MergeModes,
+ default="0")
+
+ #General Options
+ Scale = IntProperty(
+ name="Scale Percent",
+ description="Scale percentage applied for export",
+ default=100, min=1, max=1000)
+
+ FlipNormals = BoolProperty(
+ name="Flip Normals",
+ description="",
+ default=False)
+ ApplyModifiers = BoolProperty(
+ name="Apply Modifiers",
+ description="Apply object modifiers before export",
+ default=False)
+ ExportVertexColors = BoolProperty(
+ name="Export Vertices Colors",
+ description="Export colors set on vertices, if any",
+ default=True)
+ ExportMaterialColors = BoolProperty(
+ name="Export Material Colors",
+ description="Ambient color is exported on the Material",
+ default=True)
+ ExportTextures = BoolProperty(
+ name="Export Textures and UVs",
+ description="Exports UVs and Reference external image files to be used by the model",
+ default=True)
+ CopyTextureFiles = BoolProperty(
+ name="Copy Textures Files",
+ description="Copy referenced Textures files in the models\\textures directory",
+ default=True)
+ ExportArmatures = BoolProperty(
+ name="Export Armatures",
+ description="Export the bones of any armatures to deform meshes",
+ default=True)
+ ExportAnimationFrames = EnumProperty(
+ name="Animations Frames",
+ description="Select the type of animations to export. Only object " \
+ "and armature bone animations can be exported. Keyframes exports only the keyed frames" \
+ "Full Animation exports every frames, None disables animationq export. ",
+ items=AnimationFrameModes,
+ default="1")
+ ExportAnimationActions = EnumProperty(
+ name="Animations Actions",
+ description="By default only the Default Animation Action assoiated to an armature is exported." \
+ "However if you have defined several animations on the same armature,"\
+ "you can select to export all animations. You can see the list of animation actions in the DopeSheet window.",
+ items=AnimationActions,
+ default="0")
+ AnimFPS = IntProperty(
+ name="Animation FPS",
+ description="Frame rate used to export animation in seconds (can be used to artficially slow down the exported animation, or to speed up it",
+ default=30, min=1, max=300)
+
+ #Advance Options
+ CoordinateSystem = EnumProperty(
+ name="System",
+ description="Select a coordinate system to export to",
+ items=CoordinateSystems,
+ default="1")
+
+ Verbose = BoolProperty(
+ name="Verbose",
+ description="Run the exporter in debug mode. Check the console for output",
+ default=True)
+
+ def execute(self, context):
+ #Append .group
+ FilePath = bpy.path.ensure_ext(self.filepath, ".group")
+
+ Config = MarmaladeExporterSettings(context,
+ FilePath,
+ CoordinateSystem=self.CoordinateSystem,
+ FlipNormals=self.FlipNormals,
+ ApplyModifiers=self.ApplyModifiers,
+ Scale=self.Scale,
+ AnimFPS=self.AnimFPS,
+ ExportVertexColors=self.ExportVertexColors,
+ ExportMaterialColors=self.ExportMaterialColors,
+ ExportTextures=self.ExportTextures,
+ CopyTextureFiles=self.CopyTextureFiles,
+ ExportArmatures=self.ExportArmatures,
+ ExportAnimationFrames=self.ExportAnimationFrames,
+ ExportAnimationActions=self.ExportAnimationActions,
+ ExportMode=self.ExportMode,
+ MergeModes=self.MergeModes,
+ Verbose=self.Verbose)
+
+ # Exit edit mode before exporting, so current object states are exported properly.
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ ExportMadeWithMarmaladeGroup(Config)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ if not self.filepath:
+ self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".group")
+ WindowManager = context.window_manager
+ WindowManager.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+
+def menu_func(self, context):
+ self.layout.operator(MarmaladeExporter.bl_idname, text="Marmalade cross-platform Apps (.group)")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_file_export.append(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_file_export.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_export_md3.py b/release/scripts/addons_contrib/io_export_md3.py
new file mode 100644
index 0000000..328cbc9
--- /dev/null
+++ b/release/scripts/addons_contrib/io_export_md3.py
@@ -0,0 +1,694 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Quake Model 3 (.md3)",
+ "author": "Xembie",
+ "version": (0, 7),
+ "blender": (2, 53, 0),
+ "location": "File > Export",
+ "description": "Save a Quake Model 3 File)",
+ "warning": "", # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=23160",
+ "category": "Import-Export"}
+
+
+import bpy,struct,math,os
+
+MAX_QPATH = 64
+
+MD3_IDENT = "IDP3"
+MD3_VERSION = 15
+MD3_MAX_TAGS = 16
+MD3_MAX_SURFACES = 32
+MD3_MAX_FRAMES = 1024
+MD3_MAX_SHADERS = 256
+MD3_MAX_VERTICES = 4096
+MD3_MAX_TRIANGLES = 8192
+MD3_XYZ_SCALE = 64.0
+
+class md3Vert:
+ xyz = []
+ normal = 0
+ binaryFormat = "<3hH"
+
+ def __init__(self):
+ self.xyz = [0.0, 0.0, 0.0]
+ self.normal = 0
+
+ def GetSize(self):
+ return struct.calcsize(self.binaryFormat)
+
+ # copied from PhaethonH <phaethon at linux.ucla.edu> md3.py
+ def Decode(self, latlng):
+ lat = (latlng >> 8) & 0xFF;
+ lng = (latlng) & 0xFF;
+ lat *= math.pi / 128;
+ lng *= math.pi / 128;
+ x = math.cos(lat) * math.sin(lng)
+ y = math.sin(lat) * math.sin(lng)
+ z = math.cos(lng)
+ retval = [ x, y, z ]
+ return retval
+
+ # copied from PhaethonH <phaethon at linux.ucla.edu> md3.py
+ def Encode(self, normal):
+ x = normal[0]
+ y = normal[1]
+ z = normal[2]
+ # normalize
+ l = math.sqrt((x*x) + (y*y) + (z*z))
+ if l == 0:
+ return 0
+ x = x/l
+ y = y/l
+ z = z/l
+
+ if (x == 0.0) & (y == 0.0) :
+ if z > 0.0:
+ return 0
+ else:
+ return (128 << 8)
+
+ lng = math.acos(z) * 255 / (2 * math.pi)
+ lat = math.atan2(y, x) * 255 / (2 * math.pi)
+ retval = ((int(lat) & 0xFF) << 8) | (int(lng) & 0xFF)
+ return retval
+
+ def Save(self, file):
+ tmpData = [0] * 4
+ tmpData[0] = int(self.xyz[0] * MD3_XYZ_SCALE)
+ tmpData[1] = int(self.xyz[1] * MD3_XYZ_SCALE)
+ tmpData[2] = int(self.xyz[2] * MD3_XYZ_SCALE)
+ tmpData[3] = self.normal
+ data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1], tmpData[2], tmpData[3])
+ file.write(data)
+
+class md3TexCoord:
+ u = 0.0
+ v = 0.0
+
+ binaryFormat = "<2f"
+
+ def __init__(self):
+ self.u = 0.0
+ self.v = 0.0
+
+ def GetSize(self):
+ return struct.calcsize(self.binaryFormat)
+
+ def Save(self, file):
+ tmpData = [0] * 2
+ tmpData[0] = self.u
+ tmpData[1] = 1.0 - self.v
+ data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1])
+ file.write(data)
+
+class md3Triangle:
+ indexes = []
+
+ binaryFormat = "<3i"
+
+ def __init__(self):
+ self.indexes = [ 0, 0, 0 ]
+
+ def GetSize(self):
+ return struct.calcsize(self.binaryFormat)
+
+ def Save(self, file):
+ tmpData = [0] * 3
+ tmpData[0] = self.indexes[0]
+ tmpData[1] = self.indexes[2] # reverse
+ tmpData[2] = self.indexes[1] # reverse
+ data = struct.pack(self.binaryFormat,tmpData[0], tmpData[1], tmpData[2])
+ file.write(data)
+
+class md3Shader:
+ name = ""
+ index = 0
+
+ binaryFormat = "<%dsi" % MAX_QPATH
+
+ def __init__(self):
+ self.name = ""
+ self.index = 0
+
+ def GetSize(self):
+ return struct.calcsize(self.binaryFormat)
+
+ def Save(self, file):
+ tmpData = [0] * 2
+ tmpData[0] = self.name
+ tmpData[1] = self.index
+ data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1])
+ file.write(data)
+
+class md3Surface:
+ ident = ""
+ name = ""
+ flags = 0
+ numFrames = 0
+ numShaders = 0
+ numVerts = 0
+ numTriangles = 0
+ ofsTriangles = 0
+ ofsShaders = 0
+ ofsUV = 0
+ ofsVerts = 0
+ ofsEnd = 0
+ shaders = []
+ triangles = []
+ uv = []
+ verts = []
+
+ binaryFormat = "<4s%ds10i" % MAX_QPATH # 1 int, name, then 10 ints
+
+ def __init__(self):
+ self.ident = ""
+ self.name = ""
+ self.flags = 0
+ self.numFrames = 0
+ self.numShaders = 0
+ self.numVerts = 0
+ self.numTriangles = 0
+ self.ofsTriangles = 0
+ self.ofsShaders = 0
+ self.ofsUV = 0
+ self.ofsVerts = 0
+ self.ofsEnd
+ self.shaders = []
+ self.triangles = []
+ self.uv = []
+ self.verts = []
+
+ def GetSize(self):
+ sz = struct.calcsize(self.binaryFormat)
+ self.ofsTriangles = sz
+ for t in self.triangles:
+ sz += t.GetSize()
+ self.ofsShaders = sz
+ for s in self.shaders:
+ sz += s.GetSize()
+ self.ofsUV = sz
+ for u in self.uv:
+ sz += u.GetSize()
+ self.ofsVerts = sz
+ for v in self.verts:
+ sz += v.GetSize()
+ self.ofsEnd = sz
+ return self.ofsEnd
+
+ def Save(self, file):
+ self.GetSize()
+ tmpData = [0] * 12
+ tmpData[0] = self.ident
+ tmpData[1] = self.name
+ tmpData[2] = self.flags
+ tmpData[3] = self.numFrames
+ tmpData[4] = self.numShaders
+ tmpData[5] = self.numVerts
+ tmpData[6] = self.numTriangles
+ tmpData[7] = self.ofsTriangles
+ tmpData[8] = self.ofsShaders
+ tmpData[9] = self.ofsUV
+ tmpData[10] = self.ofsVerts
+ tmpData[11] = self.ofsEnd
+ data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7],tmpData[8],tmpData[9],tmpData[10],tmpData[11])
+ file.write(data)
+
+ # write the tri data
+ for t in self.triangles:
+ t.Save(file)
+
+ # save the shader coordinates
+ for s in self.shaders:
+ s.Save(file)
+
+ # save the uv info
+ for u in self.uv:
+ u.Save(file)
+
+ # save the verts
+ for v in self.verts:
+ v.Save(file)
+
+class md3Tag:
+ name = ""
+ origin = []
+ axis = []
+
+ binaryFormat="<%ds3f9f" % MAX_QPATH
+
+ def __init__(self):
+ self.name = ""
+ self.origin = [0, 0, 0]
+ self.axis = [0, 0, 0, 0, 0, 0, 0, 0, 0]
+
+ def GetSize(self):
+ return struct.calcsize(self.binaryFormat)
+
+ def Save(self, file):
+ tmpData = [0] * 13
+ tmpData[0] = self.name
+ tmpData[1] = float(self.origin[0])
+ tmpData[2] = float(self.origin[1])
+ tmpData[3] = float(self.origin[2])
+ tmpData[4] = float(self.axis[0])
+ tmpData[5] = float(self.axis[1])
+ tmpData[6] = float(self.axis[2])
+ tmpData[7] = float(self.axis[3])
+ tmpData[8] = float(self.axis[4])
+ tmpData[9] = float(self.axis[5])
+ tmpData[10] = float(self.axis[6])
+ tmpData[11] = float(self.axis[7])
+ tmpData[12] = float(self.axis[8])
+ data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6], tmpData[7], tmpData[8], tmpData[9], tmpData[10], tmpData[11], tmpData[12])
+ file.write(data)
+
+class md3Frame:
+ mins = 0
+ maxs = 0
+ localOrigin = 0
+ radius = 0.0
+ name = ""
+
+ binaryFormat="<3f3f3ff16s"
+
+ def __init__(self):
+ self.mins = [0, 0, 0]
+ self.maxs = [0, 0, 0]
+ self.localOrigin = [0, 0, 0]
+ self.radius = 0.0
+ self.name = ""
+
+ def GetSize(self):
+ return struct.calcsize(self.binaryFormat)
+
+ def Save(self, file):
+ tmpData = [0] * 11
+ tmpData[0] = self.mins[0]
+ tmpData[1] = self.mins[1]
+ tmpData[2] = self.mins[2]
+ tmpData[3] = self.maxs[0]
+ tmpData[4] = self.maxs[1]
+ tmpData[5] = self.maxs[2]
+ tmpData[6] = self.localOrigin[0]
+ tmpData[7] = self.localOrigin[1]
+ tmpData[8] = self.localOrigin[2]
+ tmpData[9] = self.radius
+ tmpData[10] = self.name
+ data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7], tmpData[8], tmpData[9], tmpData[10])
+ file.write(data)
+
+class md3Object:
+ # header structure
+ ident = "" # this is used to identify the file (must be IDP3)
+ version = 0 # the version number of the file (Must be 15)
+ name = ""
+ flags = 0
+ numFrames = 0
+ numTags = 0
+ numSurfaces = 0
+ numSkins = 0
+ ofsFrames = 0
+ ofsTags = 0
+ ofsSurfaces = 0
+ ofsEnd = 0
+ frames = []
+ tags = []
+ surfaces = []
+
+ binaryFormat="<4si%ds9i" % MAX_QPATH # little-endian (<), 17 integers (17i)
+
+ def __init__(self):
+ self.ident = 0
+ self.version = 0
+ self.name = ""
+ self.flags = 0
+ self.numFrames = 0
+ self.numTags = 0
+ self.numSurfaces = 0
+ self.numSkins = 0
+ self.ofsFrames = 0
+ self.ofsTags = 0
+ self.ofsSurfaces = 0
+ self.ofsEnd = 0
+ self.frames = []
+ self.tags = []
+ self.surfaces = []
+
+ def GetSize(self):
+ self.ofsFrames = struct.calcsize(self.binaryFormat)
+ self.ofsTags = self.ofsFrames
+ for f in self.frames:
+ self.ofsTags += f.GetSize()
+ self.ofsSurfaces += self.ofsTags
+ for t in self.tags:
+ self.ofsSurfaces += t.GetSize()
+ self.ofsEnd = self.ofsSurfaces
+ for s in self.surfaces:
+ self.ofsEnd += s.GetSize()
+ return self.ofsEnd
+
+ def Save(self, file):
+ self.GetSize()
+ tmpData = [0] * 12
+ tmpData[0] = self.ident
+ tmpData[1] = self.version
+ tmpData[2] = self.name
+ tmpData[3] = self.flags
+ tmpData[4] = self.numFrames
+ tmpData[5] = self.numTags
+ tmpData[6] = self.numSurfaces
+ tmpData[7] = self.numSkins
+ tmpData[8] = self.ofsFrames
+ tmpData[9] = self.ofsTags
+ tmpData[10] = self.ofsSurfaces
+ tmpData[11] = self.ofsEnd
+
+ data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7], tmpData[8], tmpData[9], tmpData[10], tmpData[11])
+ file.write(data)
+
+ for f in self.frames:
+ f.Save(file)
+
+ for t in self.tags:
+ t.Save(file)
+
+ for s in self.surfaces:
+ s.Save(file)
+
+
+def message(log,msg):
+ if log:
+ log.write(msg + "\n")
+ else:
+ print(msg)
+
+class md3Settings:
+ def __init__(self,
+ savepath,
+ name,
+ logpath,
+ overwrite=True,
+ dumpall=False,
+ ignoreuvs=False,
+ scale=1.0,
+ offsetx=0.0,
+ offsety=0.0,
+ offsetz=0.0):
+ self.savepath = savepath
+ self.name = name
+ self.logpath = logpath
+ self.overwrite = overwrite
+ self.dumpall = dumpall
+ self.ignoreuvs = ignoreuvs
+ self.scale = scale
+ self.offsetx = offsetx
+ self.offsety = offsety
+ self.offsetz = offsetz
+
+def print_md3(log,md3,dumpall):
+ message(log,"Header Information")
+ message(log,"Ident: " + str(md3.ident))
+ message(log,"Version: " + str(md3.version))
+ message(log,"Name: " + md3.name)
+ message(log,"Flags: " + str(md3.flags))
+ message(log,"Number of Frames: " + str(md3.numFrames))
+ message(log,"Number of Tags: " + str(md3.numTags))
+ message(log,"Number of Surfaces: " + str(md3.numSurfaces))
+ message(log,"Number of Skins: " + str(md3.numSkins))
+ message(log,"Offset Frames: " + str(md3.ofsFrames))
+ message(log,"Offset Tags: " + str(md3.ofsTags))
+ message(log,"Offset Surfaces: " + str(md3.ofsSurfaces))
+ message(log,"Offset end: " + str(md3.ofsEnd))
+ if dumpall:
+ message(log,"Frames:")
+ for f in md3.frames:
+ message(log," Mins: " + str(f.mins[0]) + " " + str(f.mins[1]) + " " + str(f.mins[2]))
+ message(log," Maxs: " + str(f.maxs[0]) + " " + str(f.maxs[1]) + " " + str(f.maxs[2]))
+ message(log," Origin(local): " + str(f.localOrigin[0]) + " " + str(f.localOrigin[1]) + " " + str(f.localOrigin[2]))
+ message(log," Radius: " + str(f.radius))
+ message(log," Name: " + f.name)
+
+ message(log,"Tags:")
+ for t in md3.tags:
+ message(log," Name: " + t.name)
+ message(log," Origin: " + str(t.origin[0]) + " " + str(t.origin[1]) + " " + str(t.origin[2]))
+ message(log," Axis[0]: " + str(t.axis[0]) + " " + str(t.axis[1]) + " " + str(t.axis[2]))
+ message(log," Axis[1]: " + str(t.axis[3]) + " " + str(t.axis[4]) + " " + str(t.axis[5]))
+ message(log," Axis[2]: " + str(t.axis[6]) + " " + str(t.axis[7]) + " " + str(t.axis[8]))
+
+ message(log,"Surfaces:")
+ for s in md3.surfaces:
+ message(log," Ident: " + s.ident)
+ message(log," Name: " + s.name)
+ message(log," Flags: " + str(s.flags))
+ message(log," # of Frames: " + str(s.numFrames))
+ message(log," # of Shaders: " + str(s.numShaders))
+ message(log," # of Verts: " + str(s.numVerts))
+ message(log," # of Triangles: " + str(s.numTriangles))
+ message(log," Offset Triangles: " + str(s.ofsTriangles))
+ message(log," Offset UVs: " + str(s.ofsUV))
+ message(log," Offset Verts: " + str(s.ofsVerts))
+ message(log," Offset End: " + str(s.ofsEnd))
+ message(log," Shaders:")
+ for shader in s.shaders:
+ message(log," Name: " + shader.name)
+ message(log," Index: " + str(shader.index))
+ message(log," Triangles:")
+ for tri in s.triangles:
+ message(log," Indexes: " + str(tri.indexes[0]) + " " + str(tri.indexes[1]) + " " + str(tri.indexes[2]))
+ message(log," UVs:")
+ for uv in s.uv:
+ message(log," U: " + str(uv.u))
+ message(log," V: " + str(uv.v))
+ message(log," Verts:")
+ for vert in s.verts:
+ message(log," XYZ: " + str(vert.xyz[0]) + " " + str(vert.xyz[1]) + " " + str(vert.xyz[2]))
+ message(log," Normal: " + str(vert.normal))
+
+ shader_count = 0
+ vert_count = 0
+ tri_count = 0
+ for surface in md3.surfaces:
+ shader_count += surface.numShaders
+ tri_count += surface.numTriangles
+ vert_count += surface.numVerts
+
+ if md3.numTags >= MD3_MAX_TAGS:
+ message(log,"!Warning: Tag limit reached! " + str(md3.numTags))
+ if md3.numSurfaces >= MD3_MAX_SURFACES:
+ message(log,"!Warning: Surface limit reached! " + str(md3.numSurfaces))
+ if md3.numFrames >= MD3_MAX_FRAMES:
+ message(log,"!Warning: Frame limit reached! " + str(md3.numFrames))
+ if shader_count >= MD3_MAX_SHADERS:
+ message(log,"!Warning: Shader limit reached! " + str(shader_count))
+ if vert_count >= MD3_MAX_VERTICES:
+ message(log,"!Warning: Vertex limit reached! " + str(vert_count))
+ if tri_count >= MD3_MAX_TRIANGLES:
+ message(log,"!Warning: Triangle limit reached! " + str(tri_count))
+
+def save_md3(settings):
+ if settings.logpath:
+ if settings.overwrite:
+ log = open(settings.logpath,"w")
+ else:
+ log = open(settings.logpath,"a")
+ else:
+ log = 0
+ message(log,"##########Exporting MD3##########")
+ bpy.ops.object.mode_set(mode='OBJECT')
+ md3 = md3Object()
+ md3.ident = MD3_IDENT
+ md3.version = MD3_VERSION
+ md3.name = settings.name
+ md3.numFrames = (bpy.context.scene.frame_end + 1) - bpy.context.scene.frame_start
+
+ for obj in bpy.context.selected_objects:
+ if obj.type == 'MESH':
+ nsurface = md3Surface()
+ nsurface.name = obj.name
+ nsurface.ident = MD3_IDENT
+
+ vertlist = []
+
+ for f,face in enumerate(obj.data.faces):
+ ntri = md3Triangle()
+ if len(face.verts) != 3:
+ message(log,"Found a nontriangle face in object " + obj.name)
+ continue
+
+ for v,vert_index in enumerate(face.verts):
+ uv_u = round(obj.data.active_uv_texture.data[f].uv[v][0],5)
+ uv_v = round(obj.data.active_uv_texture.data[f].uv[v][1],5)
+
+ match = 0
+ match_index = 0
+ for i,vi in enumerate(vertlist):
+ if vi == vert_index:
+ if settings.ignoreuvs:
+ match = 1#there is a uv match for all
+ match_index = i
+ else:
+ if nsurface.uv[i].u == uv_u and nsurface.uv[i].v == uv_v:
+ match = 1
+ match_index = i
+
+ if match == 0:
+ vertlist.append(vert_index)
+ ntri.indexes[v] = nsurface.numVerts
+ ntex = md3TexCoord()
+ ntex.u = uv_u
+ ntex.v = uv_v
+ nsurface.uv.append(ntex)
+ nsurface.numVerts += 1
+ else:
+ ntri.indexes[v] = match_index
+ nsurface.triangles.append(ntri)
+ nsurface.numTriangles += 1
+
+ if obj.data.active_uv_texture:
+ nshader = md3Shader()
+ nshader.name = obj.data.active_uv_texture.name
+ nshader.index = nsurface.numShaders
+ nsurface.shaders.append(nshader)
+ nsurface.numShaders += 1
+ if nsurface.numShaders < 1: #we should add a blank as a placeholder
+ nshader = md3Shader()
+ nshader.name = "NULL"
+ nsurface.shaders.append(nshader)
+ nsurface.numShaders += 1
+
+ for frame in range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1):
+ bpy.context.scene.set_frame(frame)
+ fobj = obj.create_mesh(bpy.context.scene,True,'PREVIEW')
+ fobj.calc_normals()
+ nframe = md3Frame()
+ nframe.name = str(frame)
+ for vi in vertlist:
+ vert = fobj.verts[vi]
+ nvert = md3Vert()
+ nvert.xyz = vert.co * obj.matrix_world
+ nvert.xyz[0] = (round(nvert.xyz[0] + obj.matrix_world[3][0],5) * settings.scale) + settings.offsetx
+ nvert.xyz[1] = (round(nvert.xyz[1] + obj.matrix_world[3][1],5) * settings.scale) + settings.offsety
+ nvert.xyz[2] = (round(nvert.xyz[2] + obj.matrix_world[3][2],5) * settings.scale) + settings.offsetz
+ nvert.normal = nvert.Encode(vert.normal)
+ for i in range(0,3):
+ nframe.mins[i] = min(nframe.mins[i],nvert.xyz[i])
+ nframe.maxs[i] = max(nframe.maxs[i],nvert.xyz[i])
+ minlength = math.sqrt(math.pow(nframe.mins[0],2) + math.pow(nframe.mins[1],2) + math.pow(nframe.mins[2],2))
+ maxlength = math.sqrt(math.pow(nframe.maxs[0],2) + math.pow(nframe.maxs[1],2) + math.pow(nframe.maxs[2],2))
+ nframe.radius = round(max(minlength,maxlength),5)
+ nsurface.verts.append(nvert)
+ md3.frames.append(nframe)
+ nsurface.numFrames += 1
+ bpy.data.meshes.remove(fobj)
+ md3.surfaces.append(nsurface)
+ md3.numSurfaces += 1
+
+ elif obj.type == 'EMPTY':
+ md3.numTags += 1
+ for frame in range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1):
+ bpy.context.scene.set_frame(frame)
+ ntag = md3Tag()
+ ntag.origin[0] = (round(obj.matrix_world[3][0] * settings.scale,5)) + settings.offsetx
+ ntag.origin[1] = (round(obj.matrix_world[3][1] * settings.scale,5)) + settings.offsety
+ ntag.origin[2] = (round(obj.matrix_world[3][2] * settings.scale,5)) + settings.offsetz
+ ntag.axis[0] = obj.matrix_world[0][0]
+ ntag.axis[1] = obj.matrix_world[0][1]
+ ntag.axis[2] = obj.matrix_world[0][2]
+ ntag.axis[3] = obj.matrix_world[1][0]
+ ntag.axis[4] = obj.matrix_world[1][1]
+ ntag.axis[5] = obj.matrix_world[1][2]
+ ntag.axis[6] = obj.matrix_world[2][0]
+ ntag.axis[7] = obj.matrix_world[2][1]
+ ntag.axis[8] = obj.matrix_world[2][2]
+ md3.tags.append(ntag)
+
+ if md3.numSurfaces < 1:
+ message(log,"Select a mesh to export!")
+ if log:
+ log.close()
+ return
+
+ file = open(settings.savepath, "wb")
+ md3.Save(file)
+ print_md3(log,md3,settings.dumpall)
+ file.close()
+
+ message(log,"MD3: " + settings.name + " saved to " + settings.savepath)
+ if log:
+ print("Logged to",settings.logpath)
+ log.close()
+
+from bpy.props import *
+class ExportMD3(bpy.types.Operator):
+ """Export to Quake Model 3 (.md3)"""
+ bl_idname = "export.md3"
+ bl_label = 'Export MD3'
+
+ filepath = StringProperty(subtype = 'FILE_PATH',name="File Path", description="Filepath for exporting", maxlen= 1024, default= "")
+ md3name = StringProperty(name="MD3 Name", description="MD3 header name / skin path (64 bytes)",maxlen=64,default="")
+ md3log = StringProperty(name="MD3 Log", description="MD3 log file path",maxlen=1024,default="export_md3.log")
+ md3overwritelog = BoolProperty(name="Overwrite log", description="Overwrite log (off == append)", default=True)
+ md3dumpall = BoolProperty(name="Dump all", description="Dump all data for md3 to log",default=False)
+ md3ignoreuvs = BoolProperty(name="Ignore UVs", description="Ignores uv influence on mesh generation. Use if uv map not made.",default=False)
+ md3scale = FloatProperty(name="Scale", description="Scale all objects from world origin (0,0,0)",default=1.0,precision=5)
+ md3offsetx = FloatProperty(name="Offset X", description="Transition scene along x axis",default=0.0,precision=5)
+ md3offsety = FloatProperty(name="Offset Y", description="Transition scene along y axis",default=0.0,precision=5)
+ md3offsetz = FloatProperty(name="Offset Z", description="Transition scene along z axis",default=0.0,precision=5)
+
+ def execute(self, context):
+ settings = md3Settings(savepath = self.properties.filepath,
+ name = self.properties.md3name,
+ logpath = self.properties.md3log,
+ overwrite = self.properties.md3overwritelog,
+ dumpall = self.properties.md3dumpall,
+ ignoreuvs = self.properties.md3ignoreuvs,
+ scale = self.properties.md3scale,
+ offsetx = self.properties.md3offsetx,
+ offsety = self.properties.md3offsety,
+ offsetz = self.properties.md3offsetz)
+ save_md3(settings)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None
+
+def menu_func(self, context):
+ newpath = os.path.splitext(bpy.context.blend_data.filepath)[0] + ".md3"
+ self.layout.operator(ExportMD3.bl_idname, text="Quake Model 3 (.md3)").filepath = newpath
+
+def register():
+ bpy.types.INFO_MT_file_export.append(menu_func)
+
+def unregister():
+ bpy.types.INFO_MT_file_export.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_import_BrushSet.py b/release/scripts/addons_contrib/io_import_BrushSet.py
new file mode 100644
index 0000000..f73ecc8
--- /dev/null
+++ b/release/scripts/addons_contrib/io_import_BrushSet.py
@@ -0,0 +1,144 @@
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# ----------------------------------------------------------------------------#
+
+"""
+todo:
+- add file selection for single and multiple files
+
+changelog:
+ "version": (1,1,4),
+ filename will be used as texture name (still limited by stringlength)
+
+
+ "version": (1,1,3),
+ fixed operator and registration
+ added tracker and wiki url\
+
+version": (1,1,2)
+ replaced image.new() with image.load()
+ changed addon category
+ removed some unused/old code
+
+version":1.11:
+ added type arg to texture.new() [L48]
+ cleared default filename
+"""
+
+# ----------------------------------------------------------------------------#
+
+import bpy
+import os
+from bpy.props import *
+
+#addon description
+bl_info = {
+ "name": "import BrushSet",
+ "author": "Daniel Grauer",
+ "version": (1, 1, 5),
+ "blender": (2, 56, 0),
+ "category": "Import-Export",
+ "location": "File > Import > BrushSet",
+ "description": "imports all image files from a folder",
+ "warning": '', # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/BrushSet",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25702&group_id=153&atid=467",
+ }
+
+print(" ")
+print("*------------------------------------------------------------------------------*")
+print("* initializing BrushSet import *")
+print("*------------------------------------------------------------------------------*")
+print(" ")
+
+#extension filter (alternative use mimetypes)
+ext_list = ['jpg',
+ 'bmp',
+ 'iris',
+ 'png',
+ 'jpeg',
+ 'targa',
+ 'tga'];
+
+def LoadBrushSet(filepath, filename):
+ for file in os.listdir(filepath):
+ path = (filepath + file)
+ #get folder name
+ (f1, f2) = os.path.split(filepath)
+ (f3, foldername) = os.path.split(f1)
+
+ texturename = foldername # file "texture" foldername
+
+ #filter ext_list
+ if file.split('.')[-1].lower() in ext_list:
+ #create new texture
+ texture = bpy.data.textures.new(texturename, 'IMAGE') #watch it, string limit 21 ?!
+
+ #create new image
+ image = bpy.data.images.load(path)
+ image.source = "FILE"
+ image.filepath = path
+ bpy.data.textures[texture.name].image = image
+
+ print("imported: " + file)
+ print("Brush Set imported!")
+
+# ----------------------------------------------------------------------------#
+
+class BrushSetImporter(bpy.types.Operator):
+ """Load Brush Set"""
+ bl_idname = "import_image.brushset"
+ bl_label = "Import BrushSet"
+
+ filename = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE')
+ filepath = StringProperty(name="File Name", description="filepath", default="", maxlen=1024, options={'ANIMATABLE'}, subtype='NONE')
+
+ def execute(self, context):
+ LoadBrushSet(self.properties.filepath, self.properties.filename)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+# ----------------------------------------------------------------------------#
+
+def menu_func(self, context):
+ #clear the default name for import
+ default_name = ""
+
+ self.layout.operator(BrushSetImporter.bl_idname, text="Brush Set").filename = default_name
+
+# ----------------------------------------------------------------------------#
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_file_import.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_file_import.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
+
+print(" ")
+print("*------------------------------------------------------------------------------*")
+print(" ")
diff --git a/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py b/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py
new file mode 100644
index 0000000..98c5d1b
--- /dev/null
+++ b/release/scripts/addons_contrib/io_import_LRO_Lola_MGS_Mola_img.py
@@ -0,0 +1,640 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "LRO Lola & MGS Mola img Importer",
+ "author": "Valter Battioli (ValterVB)",
+ "version": (1, 1, 8),
+ "blender": (2, 58, 0),
+ "location": "3D window > Tool Shelf",
+ "description": "Import DTM from LRO Lola and MGS Mola",
+ "warning": "May consume a lot of memory",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Import-Export/NASA_IMG_Importer",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=25462",
+ "category": "Import-Export"}
+
+
+#***********************************************************************
+#ver. 0.0.1: -First version
+#ver. 0.0.2: -Add check on path and file
+# -Check on selected coordinates more complete
+#ver. 1.1.0: -Optimized for less memory
+#ver. 1.1.1: -Correct bug for real value of the High (bad error).
+# now it's less artistic, bat more real Always possible use
+# the old formula. check Magnify (x4)
+# -Correct the bug for directory with dot in the name
+# -Add some warning and more information
+# -Add slider for the scale and info on it
+#ver. 1.1.2: -Word correction
+# -Correct the problem for Unix (Upper lower case)
+# If the Ext of the file selected from user is upper
+# than the second file is Upper and Viceversa.
+# (I can't verify because i have Win)
+#ver. 1.1.3: -Little fix for previous fix on upper/lower case
+#ver. 1.1.4: -Fix for recent API changes. Thanks to Filiciss.
+# -Some code cleaning (PEP8)
+#ver. 1.1.5: -Fix for recent API changes. Thanks to Filiciss.
+#ver. 1.1.6: -Fix for API changes, and restore Scale factor
+#ver. 1.1.7: -Fix for API changes. Move some code out of draw
+#ver. 1.1.8: -Add a reset button
+#************************************************************************
+
+import bpy
+import os.path
+import math
+import array
+import mathutils
+from mathutils import *
+
+TO_RAD = math.pi / 180 # From degrees to radians
+
+# turning off relative path - it causes an error if it was true
+if bpy.context.user_preferences.filepaths.use_relative_paths == True:
+ bpy.context.user_preferences.filepaths.use_relative_paths = False
+
+
+# A very simple "bridge" tool.
+# Connects two equally long vertex rows with faces.
+# Returns a list of the new faces (list of lists)
+#
+# vertIdx1 ... First vertex list (list of vertex indices).
+# vertIdx2 ... Second vertex list (list of vertex indices).
+# closed ... Creates a loop (first & last are closed).
+# flipped ... Invert the normal of the face(s).
+#
+# Note: You can set vertIdx1 to a single vertex index to create a fan/star
+# of faces.
+# Note: If both vertex idx list are the same length they have to have at
+# least 2 vertices.
+def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
+ faces = []
+
+ if not vertIdx1 or not vertIdx2:
+ return None
+
+ if len(vertIdx1) < 2 and len(vertIdx2) < 2:
+ return None
+
+ fan = False
+ if (len(vertIdx1) != len(vertIdx2)):
+ if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
+ fan = True
+ else:
+ return None
+
+ total = len(vertIdx2)
+
+ if closed:
+ # Bridge the start with the end.
+ if flipped:
+ face = [
+ vertIdx1[0],
+ vertIdx2[0],
+ vertIdx2[total - 1]]
+ if not fan:
+ face.append(vertIdx1[total - 1])
+ faces.append(face)
+
+ else:
+ face = [vertIdx2[0], vertIdx1[0]]
+ if not fan:
+ face.append(vertIdx1[total - 1])
+ face.append(vertIdx2[total - 1])
+ faces.append(face)
+
+ # Bridge the rest of the faces.
+ for num in range(total - 1):
+ if flipped:
+ if fan:
+ face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
+ else:
+ face = [vertIdx2[num], vertIdx1[num],
+ vertIdx1[num + 1], vertIdx2[num + 1]]
+ faces.append(face)
+ else:
+ if fan:
+ face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
+ else:
+ face = [vertIdx1[num], vertIdx2[num],
+ vertIdx2[num + 1], vertIdx1[num + 1]]
+ faces.append(face)
+ return faces
+
+
+#Utility Function ********************************************************
+#
+#Input: Latitude Output: Number of the line (1 to n)
+def LatToLine(Latitude):
+ tmpLines = round((MAXIMUM_LATITUDE - Latitude) * MAP_RESOLUTION + 1.0)
+ if tmpLines > LINES:
+ tmpLines = LINES
+ return tmpLines
+
+
+#Input: Number of the line (1 to n) Output: Latitude
+def LineToLat(Line):
+ if MAP_RESOLUTION == 0:
+ return 0
+ else:
+ return float(MAXIMUM_LATITUDE - (Line - 1) / MAP_RESOLUTION)
+
+
+#Input: Longitude Output: Number of the point (1 to n)
+def LongToPoint(Longitude):
+ tmpPoints = round((Longitude - WESTERNMOST_LONGITUDE) *
+ MAP_RESOLUTION + 1.0)
+ if tmpPoints > LINE_SAMPLES:
+ tmpPoints = LINE_SAMPLES
+ return tmpPoints
+
+
+#Input: Number of the Point (1 to n) Output: Longitude
+def PointToLong(Point):
+ if MAP_RESOLUTION == 0:
+ return 0
+ else:
+ return float(WESTERNMOST_LONGITUDE + (Point - 1) / MAP_RESOLUTION)
+
+
+#Input: Latitude Output: Neareast real Latitude on grid
+def RealLat(Latitude):
+ return float(LineToLat(LatToLine(Latitude)))
+
+
+#Input: Longitude Output: Neareast real Longitude on grid
+def RealLong(Longitude):
+ return float(PointToLong(LongToPoint(Longitude)))
+#**************************************************************************
+
+
+def MakeMaterialMars(obj):
+ #Copied from io_convert_image_to_mesh_img
+ mat = bpy.data.materials.new("Mars")
+ mat.diffuse_shader = 'MINNAERT'
+ mat.diffuse_color = (0.426, 0.213, 0.136)
+ mat.darkness = 0.8
+
+ mat.specular_shader = 'WARDISO'
+ mat.specular_color = (1.000, 0.242, 0.010)
+ mat.specular_intensity = 0.010
+ mat.specular_slope = 0.100
+ obj.data.materials.append(mat)
+
+
+def MakeMaterialMoon(obj):
+ #Same as Mars Material, but i have canged the color
+ mat = bpy.data.materials.new("Moon")
+ mat.diffuse_shader = 'MINNAERT'
+ mat.diffuse_color = (0.426, 0.426, 0.426)
+ mat.darkness = 0.8
+
+ mat.specular_shader = 'WARDISO'
+ mat.specular_color = (0.6, 0.6, 0.6)
+ mat.specular_intensity = 0.010
+ mat.specular_slope = 0.100
+ obj.data.materials.append(mat)
+
+
+#Read the LBL file
+def ReadLabel(FileName):
+ global FileAndPath
+ global LINES, LINE_SAMPLES, SAMPLE_TYPE, SAMPLE_BITS, UNIT, MAP_RESOLUTION
+ global MAXIMUM_LATITUDE, MINIMUM_LATITUDE, WESTERNMOST_LONGITUDE
+ global EASTERNMOST_LONGITUDE, SCALING_FACTOR, OFFSET, RadiusUM, TARGET_NAME
+ global Message
+
+ if FileName == '':
+ return
+ LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
+ MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
+ WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
+ OFFSET = SCALING_FACTOR = 0.0
+ SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
+
+ FileAndPath = FileName
+ FileAndExt = os.path.splitext(FileAndPath)
+ try:
+ #Check for UNIX that is case sensitive
+ #If the Ext of the file selected from user is Upper, than the second
+ #file is Upper and Viceversa
+ if FileAndExt[1].isupper():
+ f = open(FileAndExt[0] + ".LBL", 'r') # Open the label file
+ else:
+ f = open(FileAndExt[0] + ".lbl", 'r') # Open the label file
+ Message = ""
+ except:
+ Message = "FILE LBL NOT AVAILABLE OR YOU HAVEN'T SELECTED A FILE"
+ return
+
+ block = ""
+ OFFSET = 0
+ for line in f:
+ tmp = line.split("=")
+ if tmp[0].strip() == "OBJECT" and tmp[1].strip() == "IMAGE":
+ block = "IMAGE"
+ elif tmp[0].strip() == "OBJECT" and tmp[1].strip() == "IMAGE_MAP_PROJECTION":
+ block = "IMAGE_MAP_PROJECTION"
+ elif tmp[0].strip() == "END_OBJECT" and tmp[1].strip() == "IMAGE":
+ block = ""
+ elif tmp[0].strip() == "END_OBJECT" and tmp[1].strip() == "IMAGE_MAP_PROJECTION":
+ block = ""
+ elif tmp[0].strip() == "TARGET_NAME":
+ block = ""
+ TARGET_NAME = tmp[1].strip()
+ if block == "IMAGE":
+ if line.find("LINES") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ LINES = int(tmp[1].strip())
+ elif line.find("LINE_SAMPLES") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ LINE_SAMPLES = int(tmp[1].strip())
+ elif line.find("UNIT") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ UNIT = tmp[1].strip()
+ elif line.find("SAMPLE_TYPE") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ SAMPLE_TYPE = tmp[1].strip()
+ elif line.find("SAMPLE_BITS") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ SAMPLE_BITS = int(tmp[1].strip())
+ elif line.find("SCALING_FACTOR") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ SCALING_FACTOR = float(tmp[0].replace(" ", ""))
+ elif line.find("OFFSET") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ if tmp[0].find("OFFSET") != -1 and len(tmp) > 1:
+ tmp = tmp[1].split("<")
+ tmp[0] = tmp[0].replace(".", "")
+ OFFSET = float(tmp[0].replace(" ", ""))
+ elif block == "IMAGE_MAP_PROJECTION":
+ if line.find("A_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ A_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
+ RadiusUM = tmp[1].rstrip().replace(">", "")
+ elif line.find("B_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ B_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
+ elif line.find("C_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ C_AXIS_RADIUS = float(tmp[0].replace(" ", ""))
+ elif line.find("MAXIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ MAXIMUM_LATITUDE = float(tmp[0].replace(" ", ""))
+ elif line.find("MINIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ MINIMUM_LATITUDE = float(tmp[0].replace(" ", ""))
+ elif line.find("WESTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ WESTERNMOST_LONGITUDE = float(tmp[0].replace(" ", ""))
+ elif line.find("EASTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ EASTERNMOST_LONGITUDE = float(tmp[0].replace(" ", ""))
+ elif line.find("MAP_RESOLUTION") != -1 and not(line.startswith("/*")):
+ tmp = line.split("=")
+ tmp = tmp[1].split("<")
+ MAP_RESOLUTION = float(tmp[0].replace(" ", ""))
+ f.close
+ MAXIMUM_LATITUDE = MAXIMUM_LATITUDE - 1 / MAP_RESOLUTION / 2
+ MINIMUM_LATITUDE = MINIMUM_LATITUDE + 1 / MAP_RESOLUTION / 2
+ WESTERNMOST_LONGITUDE = WESTERNMOST_LONGITUDE + 1 / MAP_RESOLUTION / 2
+ EASTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE - 1 / MAP_RESOLUTION / 2
+ if OFFSET == 0: # When OFFSET isn't available I use the medium of the radius
+ OFFSET = (A_AXIS_RADIUS + B_AXIS_RADIUS + C_AXIS_RADIUS) / 3
+ else:
+ OFFSET = OFFSET / 1000 # Convert m to Km
+ if SCALING_FACTOR == 0:
+ SCALING_FACTOR = 1.0 # When isn'tavailable I set it to 1
+
+
+def update_fpath(self, context):
+ global start_up
+ start_up=False
+ ReadLabel(bpy.context.scene.fpath)
+ if Message != "":
+ start_up=True
+ else:
+ typ = bpy.types.Scene
+ var = bpy.props
+ typ.FromLat = var.FloatProperty(description="From Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE), precision=3, default=0.0)
+ typ.ToLat = var.FloatProperty(description="To Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE), precision=3)
+ typ.FromLong = var.FloatProperty(description="From Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE), precision=3)
+ typ.ToLong = var.FloatProperty(description="To Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE), precision=3)
+ typ.Scale = var.IntProperty(description="Scale", min=1, max=100, default=1)
+ typ.Magnify = var.BoolProperty(description="Magnify", default=False)
+
+
+#Import the data and draw the planet
+class Import(bpy.types.Operator):
+ bl_idname = 'import.lro_and_mgs'
+ bl_label = 'Start Import'
+ bl_description = 'Import the data'
+
+ def execute(self, context):
+ From_Lat = RealLat(bpy.context.scene.FromLat)
+ To_Lat = RealLat(bpy.context.scene.ToLat)
+ From_Long = RealLong(bpy.context.scene.FromLong)
+ To_Long = RealLong(bpy.context.scene.ToLong)
+ BlenderScale = bpy.context.scene.Scale
+ Exag = bpy.context.scene.Magnify
+ Vertex = [] # Vertex array
+ Faces = [] # Faces arrays
+ FirstRow = []
+ SecondRow = []
+ print('*** Start create vertex ***')
+ FileAndPath = bpy.context.scene.fpath
+ FileAndExt = os.path.splitext(FileAndPath)
+ #Check for UNIX that is case sensitive
+ #If the Ext of the file selected from user is Upper, than the second file is Upper and Viceversa
+ if FileAndExt[1].isupper():
+ FileName = FileAndExt[0] + ".IMG"
+ else:
+ FileName = FileAndExt[0] + ".img"
+ f = open(FileName, 'rb')
+ f.seek(int((int(LatToLine(From_Lat)) - 1) * (LINE_SAMPLES * (SAMPLE_BITS / 8))), 1) # Skip the first n line of point
+ SkipFirstPoint = int((LongToPoint(From_Long) - 1) * (SAMPLE_BITS / 8)) # Nunmber of points to skip
+ PointsToRead = (LongToPoint(To_Long) - LongToPoint(From_Long) + 1) * (int(SAMPLE_BITS) / 8) # Number of points to be read
+ SkipLastPoint = (LINE_SAMPLES * (SAMPLE_BITS / 8)) - PointsToRead - SkipFirstPoint # Nunmber of points to skip
+ LatToRead = From_Lat
+ while (LatToRead >= To_Lat):
+ f.seek(SkipFirstPoint, 1) # Skip the first n point
+ Altitudes = f.read(int(PointsToRead)) # Read all the point
+ Altitudes = array.array("h", Altitudes) # Change to Array of signed short
+ if SAMPLE_TYPE == "MSB_INTEGER":
+ Altitudes.byteswap() # Change from MSB (big endian) to LSB (little endian)
+ LongToRead = From_Long
+ PointToRead = 0
+ while (LongToRead <= To_Long):
+ if Exag:
+ tmpRadius = (Altitudes[PointToRead] / SCALING_FACTOR / 1000 + OFFSET) / BlenderScale # Old formula (High*4)
+ else:
+ tmpRadius = ((Altitudes[PointToRead] * SCALING_FACTOR) / 1000 + OFFSET) / BlenderScale # Correct scale
+ CurrentRadius = tmpRadius * (math.cos(LatToRead * TO_RAD))
+ X = CurrentRadius * (math.sin(LongToRead * TO_RAD))
+ Y = tmpRadius * math.sin(LatToRead * TO_RAD)
+ Z = CurrentRadius * math.cos(LongToRead * TO_RAD)
+ Vertex.append(Vector((float(X), float(Y), float(Z))))
+ LongToRead += (1 / MAP_RESOLUTION)
+ PointToRead += 1
+ f.seek(int(SkipLastPoint), 1)
+ LatToRead -= (1 / MAP_RESOLUTION)
+ f.close
+ del Altitudes
+ print('*** End create Vertex ***')
+
+ print('*** Start create faces ***')
+ LinesToRead = int(LatToLine(To_Lat) - LatToLine(From_Lat) + 1) # Number of the lines to read
+ PointsToRead = int(LongToPoint(To_Long) - LongToPoint(From_Long) + 1) # Number of the points to read
+ for Point in range(0, PointsToRead):
+ FirstRow.append(Point)
+ SecondRow.append(Point + PointsToRead)
+ if int(PointsToRead) == LINE_SAMPLES:
+ FaceTemp = createFaces(FirstRow, SecondRow, closed=True, flipped=True)
+ else:
+ FaceTemp = createFaces(FirstRow, SecondRow, closed=False, flipped=True)
+ Faces.extend(FaceTemp)
+
+ FaceTemp = []
+ for Line in range(1, (LinesToRead - 1)):
+ FirstRow = SecondRow
+ SecondRow = []
+ FacesTemp = []
+ for Point in range(0, PointsToRead):
+ SecondRow.append(Point + (Line + 1) * PointsToRead)
+ if int(PointsToRead) == LINE_SAMPLES:
+ FaceTemp = createFaces(FirstRow, SecondRow, closed=True, flipped=True)
+ else:
+ FaceTemp = createFaces(FirstRow, SecondRow, closed=False, flipped=True)
+ Faces.extend(FaceTemp)
+ del FaceTemp
+ print('*** End create faces ***')
+
+ print ('*** Start draw ***')
+ mesh = bpy.data.meshes.new(TARGET_NAME)
+ mesh.from_pydata(Vertex, [], Faces)
+ del Faces
+ del Vertex
+ mesh.update()
+ ob_new = bpy.data.objects.new(TARGET_NAME, mesh)
+ ob_new.data = mesh
+ scene = bpy.context.scene
+ scene.objects.link(ob_new)
+ scene.objects.active = ob_new
+ ob_new.select = True
+ print ('*** End draw ***')
+ print('*** Start Smooth ***')
+ bpy.ops.object.shade_smooth()
+ print('*** End Smooth ***')
+ if TARGET_NAME == "MOON":
+ MakeMaterialMoon(ob_new)
+ elif TARGET_NAME == "MARS":
+ MakeMaterialMars(ob_new)
+ print('*** FINISHED ***')
+ return {'FINISHED'}
+
+
+# User inteface
+class Img_Importer(bpy.types.Panel):
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOL_PROPS"
+ bl_label = "LRO Lola & MGS Mola IMG Importer"
+
+ def __init__(self):
+ typ = bpy.types.Scene
+ var = bpy.props
+
+ def draw(self, context):
+ layout = self.layout
+ if start_up:
+ layout.prop(context.scene, "fpath")
+ col = layout.column()
+ split = col.split(align=True)
+ if Message != "":
+ split.label("Message: " + Message)
+ else:
+ col = layout.column()
+ split = col.split(align=True)
+ split.label("Minimum Latitude: " + str(MINIMUM_LATITUDE) + " deg")
+ split.label("Maximum Latitude: " + str(MAXIMUM_LATITUDE) + " deg")
+
+ split = col.split(align=True)
+ split.label("Westernmost Longitude: " + str(WESTERNMOST_LONGITUDE) + " deg")
+ split.label("Easternmost Longitude: " + str(EASTERNMOST_LONGITUDE) + " deg")
+
+ split = col.split(align=True)
+ split.label("Lines: " + str(LINES))
+ split.label("Line samples: " + str(LINE_SAMPLES))
+
+ split = col.split(align=True)
+ split.label("Sample type: " + str(SAMPLE_TYPE))
+ split.label("Sample bits: " + str(SAMPLE_BITS))
+
+ split = col.split(align=True)
+ split.label("Unit: " + UNIT)
+ split.label("Map resolution: " + str(MAP_RESOLUTION) + " pix/deg")
+
+ split = col.split(align=True)
+ split.label("Radius: " + str(OFFSET) + " " + RadiusUM)
+ split.label("Scale: " + str(SCALING_FACTOR))
+
+ split = col.split(align=True)
+ split.label("Target: ")
+ split.label(TARGET_NAME)
+
+ col = layout.column()
+ split = col.split(align=True)
+ split.prop(context.scene, "FromLat", "Northernmost Lat.")
+ split.prop(context.scene, "ToLat", "Southernmost Lat.")
+ if bpy.context.scene.FromLat < bpy.context.scene.ToLat:
+ col = layout.column()
+ split = col.split(align=True)
+ split.label("Warning: Northernmost must be greater than Southernmost")
+
+ col = layout.column()
+ split = col.split(align=True)
+ split.prop(context.scene, "FromLong", "Westernmost Long.")
+ split.prop(context.scene, "ToLong", "Easternmost Long.")
+ if bpy.context.scene.FromLong > bpy.context.scene.ToLong:
+ col = layout.column()
+ split = col.split(align=True)
+ split.label("Warning: Easternmost must be greater than Westernmost")
+
+ col = layout.column()
+ split = col.split(align=True)
+ split.prop(context.scene, "Scale", "Scale")
+ split.prop(context.scene, "Magnify", "Magnify (x4)")
+ if bpy.context.scene.fpath != "":
+ col = layout.column()
+ split = col.split(align=True)
+ split.label("1 Blender unit = " + str(bpy.context.scene.Scale) + RadiusUM)
+
+ if Message != "":
+ col = layout.column()
+ split = col.split(align=True)
+ split.label("Message: " + Message)
+
+ if bpy.context.scene.fpath.upper().endswith(("IMG", "LBL")): # Check if is selected the correct file
+ VertNumbers = (((RealLat(bpy.context.scene.FromLat) - RealLat(bpy.context.scene.ToLat)) * MAP_RESOLUTION) + 1) * ((RealLong(bpy.context.scene.ToLong) - RealLong(bpy.context.scene.FromLong)) * MAP_RESOLUTION + 1)
+ else:
+ VertNumbers = 0
+ #If I have 4 or plus vertex and at least 2 row and at least 2 point, I can import
+ if VertNumbers > 3 and (RealLat(bpy.context.scene.FromLat) > RealLat(bpy.context.scene.ToLat)) and (RealLong(bpy.context.scene.FromLong) < RealLong(bpy.context.scene.ToLong)): # If I have 4 or plus vertex I can import
+ split = col.split(align=True)
+ split.label("Map resolution on the equator: ")
+ split.label(str(2 * math.pi * OFFSET / 360 / MAP_RESOLUTION) + " " + RadiusUM + "/pix")
+ col = layout.column()
+ split = col.split(align=True)
+ split.label("Real Northernmost Lat.: " + str(RealLat(bpy.context.scene.FromLat)) + " deg")
+ split.label("Real Southernmost Long.: " + str(RealLat(bpy.context.scene.ToLat)) + " deg")
+ split = col.split(align=True)
+ split.label("Real Westernmost Long.: " + str(RealLong(bpy.context.scene.FromLong)) + " deg")
+ split.label("Real Easternmost Long.: " + str(RealLong(bpy.context.scene.ToLong)) + "deg")
+ split = col.split(align=True)
+ split.label("Numbers of vertex to be imported: " + str(int(VertNumbers)))
+ col.separator()
+ col.operator('import.lro_and_mgs', text='Import')
+ col.separator()
+ col.operator('import.reset', text='Reset')
+
+
+#Reset the UI
+class Reset(bpy.types.Operator):
+ bl_idname = 'import.reset'
+ bl_label = 'Start Import'
+
+ def execute(self, context):
+ clear_properties()
+ return {'FINISHED'}
+
+
+def initialize():
+ global MAXIMUM_LATITUDE, MINIMUM_LATITUDE
+ global WESTERNMOST_LONGITUDE, EASTERNMOST_LONGITUDE
+ global LINES, LINE_SAMPLES, SAMPLE_BITS, MAP_RESOLUTION
+ global OFFSET, SCALING_FACTOR
+ global SAMPLE_TYPE, UNIT, TARGET_NAME, RadiusUM, Message
+ global start_up
+
+ LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
+ MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
+ WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
+ OFFSET = SCALING_FACTOR = 0.0
+ SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
+ start_up=True
+
+ bpy.types.Scene.fpath = bpy.props.StringProperty(
+ name="Import File ",
+ description="Select your img file",
+ subtype="FILE_PATH",
+ default="",
+ update=update_fpath)
+
+def clear_properties():
+ # can happen on reload
+ if bpy.context.scene is None:
+ return
+ global MAXIMUM_LATITUDE, MINIMUM_LATITUDE
+ global WESTERNMOST_LONGITUDE, EASTERNMOST_LONGITUDE
+ global LINES, LINE_SAMPLES, SAMPLE_BITS, MAP_RESOLUTION
+ global OFFSET, SCALING_FACTOR
+ global SAMPLE_TYPE, UNIT, TARGET_NAME, RadiusUM, Message
+ global start_up
+
+ LINES = LINE_SAMPLES = SAMPLE_BITS = MAP_RESOLUTION = 0
+ MAXIMUM_LATITUDE = MINIMUM_LATITUDE = 0.0
+ WESTERNMOST_LONGITUDE = EASTERNMOST_LONGITUDE = 0.0
+ OFFSET = SCALING_FACTOR = 0.0
+ SAMPLE_TYPE = UNIT = TARGET_NAME = RadiusUM = Message = ""
+ start_up=True
+
+ props = ["FromLat", "ToLat", "FromLong", "ToLong", "Scale", "Magnify", "fpath"]
+ for p in props:
+ if p in bpy.types.Scene.bl_rna.properties:
+ exec("del bpy.types.Scene." + p)
+ if p in bpy.context.scene:
+ del bpy.context.scene[p]
+ bpy.types.Scene.fpath = bpy.props.StringProperty(
+ name="Import File ",
+ description="Select your img file",
+ subtype="FILE_PATH",
+ default="",
+ update=update_fpath)
+
+
+# registering the script
+def register():
+ initialize()
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ clear_properties()
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_import_fbx.py b/release/scripts/addons_contrib/io_import_fbx.py
new file mode 100644
index 0000000..e2c5dfb
--- /dev/null
+++ b/release/scripts/addons_contrib/io_import_fbx.py
@@ -0,0 +1,510 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Import: Autodesk FBX",
+ "author": "Campbell Barton",
+ "version": (0, 0, 1),
+ "blender": (2, 56, 0),
+ "location": "File > Import ",
+ "description": "This script is WIP and not intended for general use yet!",
+ "warning": "Work in progress",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Import-Export"}
+
+
+def parse_fbx(path, fbx_data):
+ DEBUG = False
+
+ f = open(path, "rU", encoding="utf-8")
+ lines = f.readlines()
+
+ # remove comments and \n
+ lines = [l[:-1].rstrip() for l in lines if not l.lstrip().startswith(";")]
+
+ # remove whitespace
+ lines = [l for l in lines if l]
+
+ # remove multiline float lists
+ def unmultiline(i):
+ lines[i - 1] = lines[i - 1] + lines.pop(i).lstrip()
+
+ # Multiline floats, used for verts and matricies, this is harderto read so detect and make into 1 line.
+ i = 0
+ while i < len(lines):
+ l = lines[i].strip()
+ if l.startswith(","):
+ unmultiline(i)
+ i -= 1
+ try:
+ float(l.split(",", 1)[0])
+ unmultiline(i)
+ i -= 1
+ except:
+ pass
+
+ i += 1
+
+ CONTAINER = [None]
+
+ def is_int(val):
+ try:
+ CONTAINER[0] = int(val)
+ return True
+ except:
+ return False
+
+ def is_int_array(val):
+ try:
+ CONTAINER[0] = tuple([int(v) for v in val.split(",")])
+ return True
+ except:
+ return False
+
+ def is_float(val):
+ try:
+ CONTAINER[0] = float(val)
+ return True
+ except:
+ return False
+
+ def is_float_array(val):
+ try:
+ CONTAINER[0] = tuple([float(v) for v in val.split(",")])
+ return True
+ except:
+ return False
+
+ def read_fbx(i, ls):
+ if DEBUG:
+ print("LINE:", lines[i])
+
+ tag, val = lines[i].split(":", 1)
+ tag = tag.lstrip()
+ val = val.strip()
+
+ if val == "":
+ ls.append((tag, None, None))
+ if val.endswith("{"):
+ name = val[:-1].strip() # remove the trailing {
+ if name == "":
+ name = None
+
+ sub_ls = []
+ ls.append((tag, name, sub_ls))
+
+ i += 1
+ while lines[i].strip() != "}":
+ i = read_fbx(i, sub_ls)
+
+ elif val.startswith('"') and val.endswith('"'):
+ ls.append((tag, None, val[1:-1])) # remove quotes
+ elif is_int(val):
+ ls.append((tag, None, CONTAINER[0]))
+ elif is_float(val):
+ ls.append((tag, None, CONTAINER[0]))
+ elif is_int_array(val):
+ ls.append((tag, None, CONTAINER[0]))
+ elif is_float_array(val):
+ ls.append((tag, None, CONTAINER[0]))
+ elif tag == 'Property':
+ ptag, ptype, punknown, pval = val.split(",", 3)
+ ptag = ptag.strip().strip("\"")
+ ptype = ptype.strip().strip("\"")
+ punknown = punknown.strip().strip("\"")
+ pval = pval.strip()
+
+ if val.startswith('"') and val.endswith('"'):
+ pval = pval[1:-1]
+ elif is_int(pval):
+ pval = CONTAINER[0]
+ elif is_float(pval):
+ pval = CONTAINER[0]
+ elif is_int_array(pval):
+ pval = CONTAINER[0]
+ elif is_float_array(pval):
+ pval = CONTAINER[0]
+
+ ls.append((tag, None, (ptag, ptype, punknown, pval)))
+ else:
+ # IGNORING ('Property', None, '"Lcl Scaling", "Lcl Scaling", "A+",1.000000000000000,1.000000000000000,1.000000000000000')
+ print("\tParser Skipping:", (tag, None, val))
+
+ # name = .lstrip()[0]
+ if DEBUG:
+ print("TAG:", tag)
+ print("VAL:", val)
+ return i + 1
+
+ i = 0
+ while i < len(lines):
+ i = read_fbx(i, fbx_data)
+
+
+def parse_connections(fbx_data):
+ c = {}
+ for tag, name, value in fbx_data:
+ type, child, parent = [i.strip() for i in value.replace('"', '').split(',')]
+ if type == "OO":
+ parent = parent.replace('Model::', '').replace('Material::', '')
+ child = child.replace('Model::', '').replace('Material::', '')
+
+ c[child] = parent
+
+ return c
+
+# Blender code starts here:
+import bpy
+
+
+def import_fbx(path):
+ import math
+ import mathutils
+
+ mtx_x90 = mathutils.Matrix.Rotation(math.pi / 2.0, 3, 'X')
+
+ fbx_data = []
+ objects = {}
+ materials = {}
+ parse_fbx(path, fbx_data)
+ # Now lets get in the mesh data for fun.
+
+ def tag_get_iter(data, tag):
+ for tag_iter, name, value in data:
+ if tag_iter == tag:
+ yield (name, value)
+
+ def tag_get_single(data, tag):
+ for tag_iter, name, value in data:
+ if tag_iter == tag:
+ return (name, value)
+ return (None, None)
+
+ def tag_get_prop(data, prop):
+ for tag_iter, name, value in data:
+ if tag_iter == "Property":
+ if value[0] == prop:
+ return value[3]
+ return None
+
+ scene = bpy.context.scene
+
+ connections = parse_connections(tag_get_single(fbx_data, "Connections")[1])
+
+ for tag1, name1, value1 in fbx_data:
+ if tag1 == "Objects":
+ for tag2, name2, value2 in value1:
+ if tag2 == "Model":
+ '''
+ print("")
+ print(tag2)
+ print(name2)
+ print(value2)
+ '''
+
+ # check we import an object
+ obj = None
+
+ # "Model::MyCamera", "Camera" --> MyCamera
+ fbx_name = name2.split(',')[0].strip()[1:-1].split("::", 1)[-1]
+ # we dont parse this part properly
+ # the name2 can be somtrhing like
+ # Model "Model::kimiko", "Mesh"
+ if name2.endswith(" \"Mesh\""):
+
+ verts = tag_get_single(value2, "Vertices")[1]
+ faces = tag_get_single(value2, "PolygonVertexIndex")[1]
+ edges = tag_get_single(value2, "Edges")[1]
+
+ # convert odd fbx verts and faces to a blender mesh.
+ if verts and faces:
+ me = bpy.data.meshes.new(name=fbx_name)
+ # get a list of floats as triples
+ blen_verts = [verts[i - 3:i] for i in range(3, len(verts) + 3, 3)]
+
+ # get weirdo face indices and proper edge indexs
+ # edge_points Collects faces index, first and last verts.
+
+ face = []
+ edge_points = {}
+ blen_faces = [face]
+ blen_faces_edges = [] # faces that have a length of 2
+ blen_poly_mapping = {}
+ poly_idx = 0
+
+ for idx, f in enumerate(faces):
+
+ if f < 0:
+ face.append(f ^ -1)
+ edge_points[idx] = [face[-1], face[0]]
+ face = []
+
+ if len(blen_faces[-1]) == 2:
+ blen_faces_edges.append(blen_faces.pop())
+ else:
+ blen_poly_mapping[poly_idx] = len(blen_faces) - 1
+
+ blen_faces.append(face)
+ poly_idx += 1
+ else:
+ face.append(f)
+
+ edge_final = []
+
+ if len(faces) == 2: # Special case if there is only one edge in scene.
+ edge1 = faces[0]
+ if edge1 < 0:
+ edge1 ^= -1
+ edge2 = faces[1]
+ if edge2 < 0:
+ edge2 ^= -1
+ edge_final.append((edge1, edge2))
+
+ else: # More than one edges
+ for idx, e in enumerate(edges):
+
+ if faces[e] < 0: # If this is the faces last point, use edge_points to create edge between last and first points of face
+ edge1 = edge_points[e][0]
+ edge2 = edge_points[e][1]
+ else:
+ edge1 = faces[e]
+ edge2 = faces[e + 1]
+ if edge2 < 0:
+ edge2 ^= -1
+
+ edge_final.append((edge1, edge2))
+
+ if not blen_faces[-1]:
+ del blen_faces[-1]
+
+ me.from_pydata(blen_verts, edge_final, blen_faces)
+ me.update()
+
+ # Handle smoothing
+ for i in tag_get_iter(value2, "LayerElementSmoothing"):
+ i = i[1]
+ type = tag_get_single(i, "MappingInformationType")[1]
+
+ if type == "ByPolygon":
+ smooth_faces = tag_get_single(i, "Smoothing")[1]
+
+ for idx, val in enumerate(smooth_faces):
+ new_idx = blen_poly_mapping.get(idx)
+ if new_idx is not None:
+ me.faces[new_idx].use_smooth = val
+ elif type == "ByEdge":
+ smooth_edges = tag_get_single(i, "Smoothing")[1]
+
+ for idx, ed in enumerate(me.edges):
+ ed.use_edge_sharp = smooth_edges[idx]
+ else:
+ print("WARNING: %s, unsupported smoothing type: %s" % (fbx_name, type))
+
+ # Handle edge weighting
+ for i in tag_get_iter(value2, "LayerElementEdgeCrease"):
+ i = i[1]
+ type = tag_get_single(i, "MappingInformationType")[1]
+
+ if type == "ByPolygon":
+ crease_faces = tag_get_single(i, "Smoothing")[1]
+
+ for idx, f in enumerate(me.faces):
+ poly_idx = blen_poly_mapping.get(idx)
+ if poly_idx is not None:
+ f.use_smooth = crease_faces[idx]
+ elif type == "ByEdge":
+ crease_edges = tag_get_single(i, "EdgeCrease")[1]
+
+ for idx, ed in enumerate(me.edges):
+ ed.crease = crease_edges[idx]
+ else:
+ print("WARNING: %s, unsupported smoothing type: %s" % (fbx_name, type))
+
+ # Create the Uv-sets
+ for i in tag_get_iter(value2, "LayerElementUV"):
+ i = i[1]
+ uv_in = 0
+ uv_face = []
+ uv_name = tag_get_single(i, "Name")[1]
+ print(uv_name)
+ uv_verts = tag_get_single(i, "UV")[1]
+ uv_index = tag_get_single(i, "UVIndex")[1]
+
+ if(uv_verts):
+ blen_uv_verts = [uv_verts[i - 2:i] for i in range(2, len(uv_verts) + 2, 2)]
+
+ for ind, uv_i in enumerate(uv_index):
+ if(uv_i == -1):
+ uv_face.append([-0.1, -0.1])
+ else:
+ uv_face.append(blen_uv_verts[uv_i])
+ uv_in += 1
+
+ me.uv_textures.new(uv_name)
+ uv_layer = me.uv_textures[-1].data
+ uv_counter = 0
+ if uv_layer:
+ for fi, uv in enumerate(uv_layer):
+ if(len(me.faces[fi].vertices) == 4):
+ uv.uv1 = uv_face[uv_counter]
+ uv.uv2 = uv_face[uv_counter + 1]
+ uv.uv3 = uv_face[uv_counter + 2]
+ uv.uv4 = uv_face[uv_counter + 3]
+ uv_counter += 4
+ else:
+ uv.uv1 = uv_face[uv_counter]
+ uv.uv2 = uv_face[uv_counter + 1]
+ uv.uv3 = uv_face[uv_counter + 2]
+ uv_counter += 3
+
+ obj = bpy.data.objects.new(fbx_name, me)
+ base = scene.objects.link(obj)
+
+ elif name2.endswith(" \"Camera\""):
+
+ camera = bpy.data.cameras.new(name=fbx_name)
+
+ props = tag_get_single(value2, "Properties60")[1]
+ camera.angle = math.radians(tag_get_prop(props, "FieldOfView"))
+
+ obj = bpy.data.objects.new(fbx_name, camera)
+ base = scene.objects.link(obj)
+
+ elif name2.endswith(" \"Light\""):
+
+ light = bpy.data.lamps.new(name=fbx_name)
+
+ props = tag_get_single(value2, "Properties60")[1]
+
+ # Lamp types
+ light_types = {0: 'POINT', 1: 'SUN', 2: 'SPOT'}
+
+ light.type = light_types[tag_get_prop(props, "LightType")]
+ light.energy = max(tag_get_prop(props, "Intensity") / 100.0, 0)
+ light.color = tag_get_prop(props, "Color")
+ light.distance = tag_get_prop(props, "DecayStart")
+
+ if light.type == 'SPOT':
+ light.spot_size = math.rad(tag_get_prop(props, "Cone angle"))
+
+ # Todo: shadows
+
+ obj = bpy.data.objects.new(fbx_name, light)
+ base = scene.objects.link(obj)
+
+ if obj:
+ # Update our object dict
+ objects[fbx_name] = obj
+
+ # Take care of parenting (we assume the parent has already been processed)
+ parent = connections.get(fbx_name)
+ if parent and parent != "Scene" and not parent.startswith("DisplayLayer"):
+ obj.parent = objects[parent]
+ parent = obj.parent
+ else:
+ parent = None
+
+ # apply transformation
+ props = tag_get_single(value2, "Properties60")[1]
+
+ loc = tag_get_prop(props, "Lcl Translation")
+ rot = tag_get_prop(props, "Lcl Rotation")
+ sca = tag_get_prop(props, "Lcl Scaling")
+
+ # Convert rotation
+ rot_mat = mathutils.Euler([math.radians(i) for i in rot]).to_matrix()
+ if parent:
+ rot_mat = parent.matrix_world.to_3x3().inverted() * rot_mat
+
+ obj.location = loc
+ obj.rotation_euler = rot_mat.to_euler()[:]
+ obj.scale = sca
+
+ elif tag2 == "Material":
+
+ # "Material::MyMaterial", "" --> MyMaterial
+ fbx_name = name2.split(',')[0].strip()[1:-1].split("::", 1)[-1]
+
+ mat = bpy.data.materials.new(name=fbx_name)
+
+ props = tag_get_single(value2, "Properties60")[1]
+
+ # We always use Lambert diffuse shader for now
+ mat.diffuse_shader = 'LAMBERT'
+
+ mat.diffuse_color = tag_get_prop(props, "DiffuseColor")
+ mat.diffuse_intensity = tag_get_prop(props, "DiffuseFactor")
+ mat.alpha = 1 - tag_get_prop(props, "TransparencyFactor")
+ mat.specular_color = tag_get_prop(props, "SpecularColor")
+ mat.specular_intensity = tag_get_prop(props, "SpecularFactor") * 2.0
+ mat.specular_hardness = (tag_get_prop(props, "Shininess") * 5.10) + 1
+ mat.ambient = tag_get_prop(props, "AmbientFactor")
+
+ # Update material dict
+ materials[fbx_name] = mat
+
+ # Map to an object (we assume models are done before materials)
+ obj = connections.get(fbx_name)
+ if obj:
+ obj = objects[obj]
+ obj.data.materials.append(mat)
+
+ return {'FINISHED'}
+
+
+# Operator
+from bpy.props import StringProperty
+from bpy_extras.io_utils import ImportHelper
+
+
+class ImportFBX(bpy.types.Operator, ImportHelper):
+ """"""
+ bl_idname = "import_scene.fbx"
+ bl_label = "Import FBX"
+
+ filename_ext = ".fbx"
+ filter_glob = StringProperty(default="*.fbx", options={'HIDDEN'})
+
+ def execute(self, context):
+ return import_fbx(self.filepath)
+
+
+# Registering / Unregister
+def menu_func(self, context):
+ self.layout.operator(ImportFBX.bl_idname, icon='PLUGIN')
+
+
+def register():
+ bpy.utils.register_class(ImportFBX)
+ bpy.types.INFO_MT_file_import.append(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_class(ImportFBX)
+ bpy.types.INFO_MT_file_import.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
+
+
+if __name__ == "__main__":
+ import_fbx("/test.fbx")
diff --git a/release/scripts/addons_contrib/io_import_lipSync_Importer.py b/release/scripts/addons_contrib/io_import_lipSync_Importer.py
new file mode 100644
index 0000000..9626790
--- /dev/null
+++ b/release/scripts/addons_contrib/io_import_lipSync_Importer.py
@@ -0,0 +1,478 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "LipSync Importer & Blinker",
+ "author": "Yousef Harfoush - bat3a ;)",
+ "version": (0, 5, 1),
+ "blender": (2, 65, 0),
+ "location": "3D window > Tool Shelf",
+ "description": "Plot Moho (Papagayo, Jlipsync, Yolo) file to frames and adds automatic blinking",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/Py/Scripts/Import-Export/Lipsync Importer",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=24080&group_id=153&atid=468",
+ "category": "Import-Export"}
+
+
+import bpy, re
+from random import random
+from bpy.props import *
+from bpy.props import IntProperty, FloatProperty, StringProperty
+
+global lastPhoneme
+lastPhoneme="nothing"
+
+# add blinking
+def blinker():
+
+ scn = bpy.context.scene
+ obj = bpy.context.object
+
+ if scn.regMenuTypes.enumBlinkTypes == '0':
+ modifier = 0
+ elif scn.regMenuTypes.enumBlinkTypes == '1':
+ modifier = scn.blinkMod
+
+ #creating keys with blinkNm count
+ for y in range(scn.blinkNm):
+ frame = y * scn.blinkSp + int(random()*modifier)
+ createShapekey('blink', frame)
+
+# -----------code contributed by dalai felinto adds armature support modified by me-------------------
+
+bone_keys = {
+"AI": ('location', 0),
+"E": ('location', 1),
+"FV": ('location', 2),
+"L": ('rotation_euler', 0),
+"MBP": ('rotation_euler', 1),
+"O": ('rotation_euler', 2),
+"U": ('scale', 0),
+"WQ": ('scale', 1),
+"etc": ('scale', 2),
+"rest": ('ik_stretch', -1)
+}
+
+def lipsyncerBone():
+ # reading imported file & creating keys
+ object = bpy.context.object
+ scene = bpy.context.scene
+ bone = bpy.context.active_pose_bone
+
+ resetBoneScale(bone)
+
+ f=open(scene.fpath) # importing file
+ f.readline() # reading the 1st line that we don"t need
+
+ for line in f:
+ # removing new lines
+ lsta = re.split("\n+", line)
+
+ # building a list of frames & shapes indexes
+ lst = re.split(":? ", lsta[0])# making a list of a frame & number
+ frame = int(lst[0])
+
+ for key,attribute in bone_keys.items():
+ if lst[1] == key:
+ createBoneKeys(key, bone, attribute, frame)
+
+def resetBoneScale(bone):
+ # set the attributes used by papagayo to 0.0
+ for attribute,index in bone_keys.values():
+ if index != -1:
+ #bone.location[0] = 0.0
+ exec("bone.%s[%d] = %f" % (attribute, index, 0.0))
+ else:
+ exec("bone.%s = %f" % (attribute, 0.0))
+
+def addBoneKey(bone, data_path, index=-1, value=None, frame=0, group=""):
+ # set a value and keyframe for the bone
+ # it assumes the 'bone' variable was defined before
+ # and it's the current selected bone
+ frame=bpy.context.scene.frame_current
+ if value != None:
+ if index != -1:
+ # bone.location[0] = 0.0
+ exec("bone.%s[%d] = %f" % (data_path, index, value))
+ else:
+ exec("bone.%s = %f" % (data_path, value))
+
+ # bone.keyframe_insert("location", 0, 10.0, "Lipsync")
+ exec('bone.keyframe_insert("%s", %d, %f, "%s")' % (data_path, index, frame, group))
+
+# creating keys with offset and eases for a phonem @ the Skframe
+def createBoneKeys(phoneme, bone, attribute, frame):
+ global lastPhoneme
+
+ scene = bpy.context.scene
+ object = bpy.context.object
+
+ offst = scene.offset # offset value
+ skVlu = scene.skscale # shape key value
+
+ #in case of Papagayo format
+ if scene.regMenuTypes.enumFileTypes == '0' :
+ frmIn = scene.easeIn # ease in value
+ frmOut = scene.easeOut # ease out value
+ hldIn = scene.holdGap # holding time value
+
+ #in case of Jlipsync format or Yolo
+ elif scene.regMenuTypes.enumFileTypes == '1' :
+ frmIn = 1
+ frmOut = 1
+ hldIn = 0
+
+ # inserting the In key only when phonem change or when blinking
+ if lastPhoneme!=phoneme or eval(scene.regMenuTypes.enumModeTypes) == 1:
+ addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame-frmIn, "Lipsync")
+
+ addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame, "Lipsync")
+ addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame+hldIn, "Lipsync")
+ addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame+hldIn+frmOut, "Lipsync")
+
+ lastPhoneme=phoneme
+
+# -------------------------------------------------------------------------------
+
+# reading imported file & creating keys
+def lipsyncer():
+
+ obj = bpy.context.object
+ scn = bpy.context.scene
+
+ f=open(scn.fpath) # importing file
+ f.readline() # reading the 1st line that we don"t need
+
+ for line in f:
+
+ # removing new lines
+ lsta = re.split("\n+", line)
+
+ # building a list of frames & shapes indexes
+ lst = re.split(":? ", lsta[0])# making a list of a frame & number
+ frame = int(lst[0])
+
+ for key in obj.data.shape_keys.key_blocks:
+ if lst[1] == key.name:
+ createShapekey(key.name, frame)
+
+# creating keys with offset and eases for a phonem @ the frame
+def createShapekey(phoneme, frame):
+
+ global lastPhoneme
+
+ scn = bpy.context.scene
+ obj = bpy.context.object
+ objSK = obj.data.shape_keys
+
+ offst = scn.offset # offset value
+ skVlu = scn.skscale # shape key value
+
+ #in case of Papagayo format
+ if scn.regMenuTypes.enumFileTypes == '0' :
+ frmIn = scn.easeIn # ease in value
+ frmOut = scn.easeOut # ease out value
+ hldIn = scn.holdGap # holding time value
+
+ #in case of Jlipsync format or Yolo
+ elif scn.regMenuTypes.enumFileTypes == '1' :
+ frmIn = 1
+ frmOut = 1
+ hldIn = 0
+
+ # inserting the In key only when phonem change or when blinking
+ if lastPhoneme!=phoneme or eval(scn.regMenuTypes.enumModeTypes) == 1:
+ objSK.key_blocks[phoneme].value=0.0
+ objSK.key_blocks[phoneme].keyframe_insert("value",
+ -1, offst+frame-frmIn, "Lipsync")
+
+ objSK.key_blocks[phoneme].value=skVlu
+ objSK.key_blocks[phoneme].keyframe_insert("value",
+ -1, offst+frame, "Lipsync")
+
+ objSK.key_blocks[phoneme].value=skVlu
+ objSK.key_blocks[phoneme].keyframe_insert("value",
+ -1, offst+frame+hldIn, "Lipsync")
+
+ objSK.key_blocks[phoneme].value=0.0
+ objSK.key_blocks[phoneme].keyframe_insert("value",
+ -1, offst+frame+hldIn+frmOut, "Lipsync")
+
+ lastPhoneme = phoneme
+
+# lipsyncer operation start
+class btn_lipsyncer(bpy.types.Operator):
+ bl_idname = 'lipsync.go'
+ bl_label = 'Start Processing'
+ bl_description = 'Plots the voice file keys to timeline'
+
+ def execute(self, context):
+
+ scn = context.scene
+ obj = context.active_object
+
+ # testing if object is valid
+ if obj!=None:
+ if obj.type=="MESH":
+ if obj.data.shape_keys!=None:
+ if scn.fpath!='': lipsyncer()
+ else: print ("select a Moho file")
+ else: print("No shape keys")
+
+ elif obj.type=="ARMATURE":
+ if 1:#XXX add prop test
+ if scn.fpath!='': lipsyncerBone()
+ else: print ("select a Moho file")
+ else: print("Create Pose properties")
+
+ else: print ("Object is not a mesh ot bone")
+ else: print ("Select object")
+ return {'FINISHED'}
+
+# blinker operation start
+class btn_blinker(bpy.types.Operator):
+ bl_idname = 'blink.go'
+ bl_label = 'Start Processing'
+ bl_description = 'Add blinks at random or specifice frames'
+
+ def execute(self, context):
+
+ scn = context.scene
+ obj = context.object
+
+ # testing if object is valid
+ if obj!=None:
+ if obj.type=="MESH":
+ if obj.data.shape_keys!=None:
+ for key in obj.data.shape_keys.key_blocks:
+ if key.name=='blink':
+ blinker()
+ #return
+ else: print("No shape keys")
+ else: print ("Object is not a mesh ot bone")
+ else: print ("Select object")
+ return {'FINISHED'}
+
+
+#defining custom enumeratos
+class menuTypes(bpy.types.PropertyGroup):
+
+ enumFileTypes = EnumProperty(items =(('0', 'Papagayo', ''),
+ ('1', 'Jlipsync Or Yolo', '')
+ #,('2', 'Retarget', '')
+ ),
+ name = 'Choose FileType',
+ default = '0')
+
+ enumBlinkTypes = EnumProperty(items =(('0', 'Specific', ''),
+ ('1', 'Random','')),
+ name = 'Choose BlinkType',
+ default = '0')
+
+ enumModeTypes = EnumProperty(items =(('0', 'Lipsyncer',''),
+ ('1', 'Blinker','')),
+ name = 'Choose Mode',
+ default = '0')
+
+# drawing the user interface
+class LipSyncBoneUI(bpy.types.Panel):
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "UI"
+ bl_label = "Phonemes"
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column()
+
+ bone = bpy.context.active_pose_bone
+
+ #showing the current object type
+ if bone: #and if scn.regMenuTypes.enumModeTypes == '0':
+ col.prop(bone, "location", index=0, text="AI")
+ col.prop(bone, "location", index=1, text="E")
+ col.prop(bone, "location", index=2, text="FV")
+ if bpy.context.scene.unit_settings.system_rotation == 'RADIANS':
+ col.prop(bone, "rotation_euler", index=0, text="L")
+ col.prop(bone, "rotation_euler", index=1, text="MBP")
+ col.prop(bone, "rotation_euler", index=2, text="O")
+ else:
+ row=col.row()
+ row.prop(bone, "rotation_euler", index=0, text="L")
+ row.label(text=str("%4.2f" % (bone.rotation_euler.x)))
+ row=col.row()
+ row.prop(bone, "rotation_euler", index=1, text="MBP")
+ row.label(text=str("%4.2f" % (bone.rotation_euler.y)))
+ row=col.row()
+ row.prop(bone, "rotation_euler", index=2, text="O")
+ row.label(text=str("%4.2f" % (bone.rotation_euler.z)))
+ col.prop(bone, "scale", index=0, text="U")
+ col.prop(bone, "scale", index=1, text="WQ")
+ col.prop(bone, "scale", index=2, text="etc")
+ else:
+ layout.label(text="No good bone is selected")
+
+# drawing the user interface
+class LipSyncUI(bpy.types.Panel):
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOL_PROPS"
+ bl_label = "LipSync Importer & Blinker"
+
+ newType= bpy.types.Scene
+
+ newType.fpath = StringProperty(name="Import File ", description="Select your voice file", subtype="FILE_PATH")
+ newType.skscale = FloatProperty(description="Smoothing shape key values", min=0.1, max=1.0, default=0.8)
+ newType.offset = IntProperty(description="Offset your frames", default=0)
+
+ newType.easeIn = IntProperty(description="Smoothing In curve", min=1, default=3)
+ newType.easeOut = IntProperty(description="Smoothing Out curve", min=1, default=3)
+ newType.holdGap = IntProperty(description="Holding for slow keys", min=0, default=0)
+
+ newType.blinkSp = IntProperty(description="Space between blinks", min=1, default=100)
+ newType.blinkNm = IntProperty(description="Number of blinks", min=1, default=10)
+
+ newType.blinkMod = IntProperty(description="Randomzing keyframe placment", min=1, default=10)
+
+ def draw(self, context):
+
+ obj = bpy.context.active_object
+ scn = bpy.context.scene
+
+ layout = self.layout
+ col = layout.column()
+
+ # showing the current object type
+ if obj != None:
+ if obj.type == "MESH":
+ split = col.split(align=True)
+ split.label(text="The active object is: ", icon="OBJECT_DATA")
+ split.label(obj.name, icon="EDITMODE_HLT")
+ elif obj.type == "ARMATURE": # bone needs to be selected
+ if obj.mode == "POSE": # mode needs to be pose
+ split = col.split(align=True)
+ split.label(text="The active object is: ", icon="ARMATURE_DATA")
+ split.label(obj.name, icon="EDITMODE_HLT")
+ else:
+ col.label(text="You need to select Pose mode!", icon="OBJECT_DATA")
+ else:
+ col.label(text="The active object is not a Mesh or Armature!", icon="OBJECT_DATA")
+ else:
+ layout.label(text="No object is selected", icon="OBJECT_DATA")
+
+ col.row().prop(scn.regMenuTypes, 'enumModeTypes')
+ col.separator()
+
+ # the lipsyncer panel
+ if scn.regMenuTypes.enumModeTypes == '0':
+ # choose the file format
+ col.row().prop(scn.regMenuTypes, 'enumFileTypes', text = ' ', expand = True)
+
+ # Papagayo panel
+ if scn.regMenuTypes.enumFileTypes == '0':
+ col.prop(context.scene, "fpath")
+ split = col.split(align=True)
+ split.label("Key Value :")
+ split.prop(context.scene, "skscale")
+ split = col.split(align=True)
+ split.label("Frame Offset :")
+ split.prop(context.scene, "offset")
+ split = col.split(align=True)
+ split.prop(context.scene, "easeIn", "Ease In")
+ split.prop(context.scene, "holdGap", "Hold Gap")
+ split.prop(context.scene, "easeOut", "Ease Out")
+
+ col.operator('lipsync.go', text='Plot Keys to the Timeline')
+
+ # Jlipsync & Yolo panel
+ elif scn.regMenuTypes.enumFileTypes == '1':
+ col.prop(context.scene, "fpath")
+ split = col.split(align=True)
+ split.label("Key Value :")
+ split.prop(context.scene, "skscale")
+ split = col.split(align=True)
+ split.label("Frame Offset :")
+ split.prop(context.scene, "offset")
+
+ col.operator('lipsync.go', text='Plot Keys to the Timeline')
+
+ # the blinker panel
+ elif scn.regMenuTypes.enumModeTypes == '1':
+ # choose blink type
+ col.row().prop(scn.regMenuTypes, 'enumBlinkTypes', text = ' ', expand = True)
+
+ # specific panel
+ if scn.regMenuTypes.enumBlinkTypes == '0':
+ split = col.split(align=True)
+ split.label("Key Value :")
+ split.prop(context.scene, "skscale")
+ split = col.split(align=True)
+ split.label("Frame Offset :")
+ split.prop(context.scene, "offset")
+ split = col.split(align=True)
+ split.prop(context.scene, "easeIn", "Ease In")
+ split.prop(context.scene, "holdGap", "Hold Gap")
+ split.prop(context.scene, "easeOut", "Ease Out")
+ col.prop(context.scene, "blinkSp", "Spacing")
+ col.prop(context.scene, "blinkNm", "Times")
+ col.operator('blink.go', text='Add Keys to the Timeline')
+
+ # Random panel
+ elif scn.regMenuTypes.enumBlinkTypes == '1':
+ split = col.split(align=True)
+ split.label("Key Value :")
+ split.prop(context.scene, "skscale")
+ split = col.split(align=True)
+ split.label("Frame Start :")
+ split.prop(context.scene, "offset")
+ split = col.split(align=True)
+ split.prop(context.scene, "easeIn", "Ease In")
+ split.prop(context.scene, "holdGap", "Hold Gap")
+ split.prop(context.scene, "easeOut", "Ease Out")
+ split = col.split(align=True)
+ split.prop(context.scene, "blinkSp", "Spacing")
+ split.prop(context.scene, "blinkMod", "Random Modifier")
+ col.prop(context.scene, "blinkNm", "Times")
+ col.operator('blink.go', text='Add Keys to the Timeline')
+
+
+# clearing vars
+def clear_properties():
+
+ # can happen on reload
+ if bpy.context.scene is None:
+ return
+
+ props = ["fpath", "skscale", "offset", "easeIn", "easeOut", "holdGap", "blinkSp", "blinkNm", "blinkMod"]
+ for p in props:
+ if p in bpy.types.Scene.bl_rna.properties:
+ exec("del bpy.types.Scene."+p)
+ if p in bpy.context.scene:
+ del bpy.context.scene[p]
+
+# registering the script
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.regMenuTypes = PointerProperty(type = menuTypes)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ del bpy.context.scene.regMenuTypes
+
+ clear_properties()
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_import_sound_to_anim.py b/release/scripts/addons_contrib/io_import_sound_to_anim.py
new file mode 100644
index 0000000..4a05656
--- /dev/null
+++ b/release/scripts/addons_contrib/io_import_sound_to_anim.py
@@ -0,0 +1,1930 @@
+#!/usr/bin/python3
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+# ***** 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 3 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, see <http://www.gnu.org/licenses/>.
+# All rights reserved.
+# ***** GPL LICENSE BLOCK *****
+
+bl_info = {
+ "name": "Import: Sound to Animation",
+ "author": "Vlassius",
+ "version": (0, 70),
+ "blender": (2, 64, 0),
+ "api": 52100,
+ "location": "Select a object -> go to the Object tab -> Import Movement From Wav File",
+ "description": "Extract movement from sound file. See the Object Panel at the end.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/Import_Movement_From_Audio_File",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=23565&group_id=153&atid=467",
+ "category": "Import-Export"}
+
+"""
+-- Extract movement from sound file, to help in animation - import script --<br>
+
+- NOTES:
+- This script takes a wav file and get sound "movement" to help you in sync the movement to words in the wave file. <br>
+- Supported Audio: .wav (wave) 8 bits and 16 bits - mono and multichanel file<br>
+- At least Blender 2.64.9 is necessary to run this program.
+- Curitiba - Brasil
+
+
+-v 0.70Beta-
+ Included: SmartRender - Render just the frames that has changes
+ Included: Options to check SmartRender for Blender Internal Render Engine:LocRotScale, Material, Transp, Mirror
+ Included: User can Cancel all functions with CANCEL button- Extensive Code and flux change (bugs expected)
+ Included: User can Cancel all functions with ESC
+ Inclused: User friendly messages into UI while running (its no more necessary to look at terminal window to most users)
+ Cleanup: Non Stardard Chars in coments
+ To Do: Decrease overhead of timer loops
+ To Do: Try to implement Smart Render for Cycles
+
+-v 0.60Beta-
+ Included: Option to use just the beat from the audio sound
+ Included: Option to exclude the beat from the audio sound
+ Included: More or less sensibility options when using the beat
+ Included: Audio Channel Select option
+
+-v 0.50Beta-
+ Included: Auto Adjust Audio Sensity option
+ Included: 8 bits .wav file support
+ Recalibrated: Manual audio sense 1
+ Cosmetic: Many changes in panel and terminal window info
+ Corrected: Tracker_url
+ Corrected: a few bytes in Memory Leaks
+ work around: memory leak in function: bpy.ops.transform.rotate
+ work around: memory leak in function: bpy.ops.anim.keyframe_insert
+
+-v 0.22Beta-
+ Included:
+ Camera Rotation
+ Empty Location-Rotation-Scale
+
+-v 0.21Beta-
+ Changed just the meta informations like version and wiki page.
+
+-v 0.20 Beta-
+ New Panel
+
+-v 0.1.5 Beta-
+ Change in API-> Properties
+ Included the button "Get FPS from Scene" due to a problem to get it in the start
+ Return to Frame 1 after import
+ Filter .wav type file (by batFINGER)
+
+-v 0.1.4 Beta-
+ If choose negative in rotation, auto check the rotation negative to Bones
+ change in register() unregister():
+
+-v 0.1.3 Beta-
+ File Cleanup
+ Change to bl_info.
+ Cosmetic Changes.
+ Minor change in API in how to define buttons.
+ Adjust in otimization.
+
+-v 0.1.2 Beta
+change in API- Update function bpy.ops.anim.keyframe_insert_menu
+
+-v 0.1.1 Beta
+change in API- Update property of window_manager.fileselect_add
+
+-v 0.1.0 Beta
+new - Added support to LAMP object
+new - improved flow to import
+new - check the type of object before show options
+bug - option max. and min. values
+change- Updated scene properties for changes in property API.
+ See http://lists.blender.org/pipermail/bf-committers/2010-September/028654.html
+new flow: 1) Process the sound file 2) Show Button to import key frames
+
+- v0.0.4 ALPHA
+new - Added destructive optimizer option - LostLestSignificativeDigit lost/total -> 10/255 default
+new - Visual Graph to samples
+new - Option to just process audio file and do not import - this is to help adjust the audio values
+new - Get and show automatically the FPS (in proper field) information taking the information from scene
+bug- Display sensitivity +1
+bug - Corrected location of the script in description
+
+- v0.0.3
+Main change: Corrected to work INSIDE dir /install/linux2/2.53/scripts/addons
+Corrected position of label "Rotation Negative"
+Added correct way to deal with paths in Python os.path.join - os.path.normpath
+
+- v0.0.2
+Corrected initial error (Register() function)
+Corrected some labels R. S. L.
+Turned off "object field" for now
+Changed target default to Z location
+
+- v0.0.1
+Initial version
+
+Credit to:
+Vlassius
+
+- http://vlassius.com.br
+- vlassius at vlassius.com.br
+- Curitiba - Brasil
+
+"""
+
+import bpy
+from bpy.props import *
+#from io_utils import ImportHelper
+import wave
+
+#para deixar global
+def _Interna_Globals(BytesDadosTotProcess, context):
+ global array
+ global arrayAutoSense
+
+ array= bytearray(BytesDadosTotProcess) # cria array
+ arrayAutoSense= bytearray((BytesDadosTotProcess)*2) # cria array para AutoAudioSense
+ context.scene.imp_sound_to_anim.bArrayCriado=True
+
+#
+#==================================================================================================
+# BLENDER UI Panel
+#==================================================================================================
+#
+class VIEW3D_PT_CustomMenuPanel(bpy.types.Panel):
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "object"
+ bl_label = "Import Movement From Wav File"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ b=bpy.context.active_object.type=='EMPTY' or bpy.context.active_object.type=='ARMATURE' or \
+ bpy.context.active_object.type=='MESH' or \
+ bpy.context.active_object.type=='CAMERA' or \
+ bpy.context.active_object.type=='LAMP'
+ if not b:
+ row=layout.row()
+ row.label(text="The Selected Object is: type \"" + bpy.context.active_object.type + \
+ "\", and it is not supported.")
+ row=layout.row()
+ row.label(text="Supported Object are Type: Armature, Mesh, Camera and Lamp")
+ row=layout.row()
+ else:
+ #print(context.scene.imp_sound_to_anim.bTypeImport)
+ if context.scene.imp_sound_to_anim.bTypeImport == 0:
+ #mount panel to Direct animation
+ row=layout.row()
+ layout.operator("import.sound_animation_botao_udirect")
+
+ # monta as telas quando está rodando
+ elif context.scene.imp_sound_to_anim.Working!="": #its running
+ row=layout.row()
+ row=layout.row()
+
+ if context.scene.imp_sound_to_anim.Working== "CheckSmartRender":
+ #context.scene.imp_sound_to_anim.Info_check_smartrender=
+ row=layout.row()
+ row.label(text="Checking for Smart Render...")
+ row=layout.row()
+ row.label(text=context.scene.imp_sound_to_anim.Info_check_smartrender)
+ row=layout.row()
+
+ elif context.scene.imp_sound_to_anim.Working== "SmartRender":
+ #context.scene.imp_sound_to_anim.Info_check_smartrender=
+ row=layout.row()
+ row.label(text="Processing Smart Render...")
+ row=layout.row()
+ row.label(text=context.scene.imp_sound_to_anim.Info_check_smartrender)
+ row=layout.row()
+
+ elif context.scene.imp_sound_to_anim.Working== "ProcessaSom":
+ #context.scene.imp_sound_to_anim.Info_Import=
+ row=layout.row()
+ row.label(text="Processing Sound File...")
+ row=layout.row()
+ row.label(text=context.scene.imp_sound_to_anim.Info_Import)
+
+ elif context.scene.imp_sound_to_anim.Working== "wavimport":
+ #context.scene.imp_sound_to_anim.Info_Import=
+ row=layout.row()
+ row.label(text="Importing Keys...")
+ row=layout.row()
+ row.label(text=context.scene.imp_sound_to_anim.Info_Import)
+ row=layout.row()
+
+ # botao cancel
+ layout.operator(OBJECT_OT_Botao_Cancel.bl_idname)
+ row=layout.row()
+
+ elif context.scene.imp_sound_to_anim.bTypeImport == 1:
+ row=layout.row()
+ row.label(text="1)Click button \"Process Wav\",")
+ row=layout.row()
+ row.label(text="2)Click Button \"Import Key Frames\",")
+ row=layout.row()
+ row.label(text="Run the animation (alt A) and Enjoy!")
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"action_auto_audio_sense")
+ row=layout.row()
+ if context.scene.imp_sound_to_anim.action_auto_audio_sense == 0: # se auto audio sense desligado
+ row.prop(context.scene.imp_sound_to_anim,"audio_sense")
+ row=layout.row()
+
+ else: #somente se autosense ligado
+ if context.scene.imp_sound_to_anim.remove_beat == 0 :
+ row.prop(context.scene.imp_sound_to_anim,"use_just_beat")
+
+ if context.scene.imp_sound_to_anim.use_just_beat == 0:
+ row.prop(context.scene.imp_sound_to_anim,"remove_beat")
+
+ if context.scene.imp_sound_to_anim.use_just_beat or context.scene.imp_sound_to_anim.remove_beat:
+ if not context.scene.imp_sound_to_anim.beat_less_sensible and not context.scene.imp_sound_to_anim.beat_more_sensible:
+ row=layout.row()
+ if context.scene.imp_sound_to_anim.beat_less_sensible ==0:
+ row.prop(context.scene.imp_sound_to_anim,"beat_more_sensible")
+
+ if context.scene.imp_sound_to_anim.beat_more_sensible ==0:
+ row.prop(context.scene.imp_sound_to_anim,"beat_less_sensible")
+
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"action_per_second")
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"action_escale")
+
+ #row=layout.row()
+ row.label(text="Result from 0 to " + str(round(255/context.scene.imp_sound_to_anim.action_escale,4)) + "")
+
+ row=layout.row()
+ row.label(text="Property to Change:")
+ row.prop(context.scene.imp_sound_to_anim,"import_type")
+
+ #coluna
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"import_where1")
+ row.prop(context.scene.imp_sound_to_anim,"import_where2")
+ row.prop(context.scene.imp_sound_to_anim,"import_where3")
+
+ row=layout.row()
+ row.label(text='Optional Configurations:')
+ row=layout.row()
+
+ row.prop(context.scene.imp_sound_to_anim,"frames_per_second")
+ row=layout.row()
+ #coluna
+ column= layout.column()
+ split=column.split(percentage=0.5)
+ col=split.column()
+
+ row=col.row()
+ row.prop(context.scene.imp_sound_to_anim,"frames_initial")
+
+ row=col.row()
+ row.prop(context.scene.imp_sound_to_anim,"action_min_value")
+
+ col=split.column()
+
+ row=col.row()
+ row.prop(context.scene.imp_sound_to_anim,"optimization_destructive")
+
+ row=col.row()
+ row.prop(context.scene.imp_sound_to_anim,"action_max_value")
+
+ row=layout.row()
+
+ row.prop(context.scene.imp_sound_to_anim,"action_offset_x")
+ row.prop(context.scene.imp_sound_to_anim,"action_offset_y")
+ row.prop(context.scene.imp_sound_to_anim,"action_offset_z")
+
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"audio_channel_select")
+ row.prop(context.scene.imp_sound_to_anim,"action_valor_igual")
+
+ #operator button
+ #OBJECT_OT_Botao_Go => Botao_GO
+ row=layout.row()
+ layout.operator(OBJECT_OT_Botao_Go.bl_idname)
+
+ row=layout.row()
+ row.label(text=context.scene.imp_sound_to_anim.Info_Import)
+
+ # preciso garantir a existencia do array porque o Blender salva no arquivo como existente sem o array existir
+ try:
+ array
+ except NameError:
+ nada=0 #dummy
+ else:
+ if context.scene.imp_sound_to_anim.bArrayCriado:
+ layout.operator(OBJECT_OT_Botao_Import.bl_idname)
+ row=layout.row()
+
+ #Layout SmartRender, somente para Blender_render
+ if bpy.context.scene.render.engine == "BLENDER_RENDER":
+ row=layout.row()
+ row.label(text="----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------")
+ row=layout.row()
+ if context.scene.imp_sound_to_anim.Info_check_smartrender!= "":
+ row=layout.row()
+ row.label(text=context.scene.imp_sound_to_anim.Info_check_smartrender)
+
+ row=layout.row()
+ row.operator(OBJECT_OT_Botao_Check_SmartRender.bl_idname)
+ if context.scene.imp_sound_to_anim.Info_check_smartrender!= "":
+ row.operator(OBJECT_OT_Botao_SmartRender.bl_idname)
+
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"check_smartrender_loc_rot_sc")
+ row.prop(context.scene.imp_sound_to_anim,"check_smartrender_material_basic")
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"check_smartrender_material_transparence")
+ row.prop(context.scene.imp_sound_to_anim,"check_smartrender_material_mirror")
+
+ #-----------------------------
+ #Use Driver
+ #-----------------------------
+ if context.scene.imp_sound_to_anim.bTypeImport == 2:
+
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"audio_sense")
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"frames_per_second")
+ row=layout.row()
+ row.prop(context.scene.imp_sound_to_anim,"action_per_second")
+ row=layout.row()
+ layout.operator(ImportWavFile.bl_idname)
+
+
+#
+#==================================================================================================
+# BLENDER UI PropertyGroup
+#==================================================================================================
+#
+class ImpSoundtoAnim(bpy.types.PropertyGroup):
+
+ #Array created
+ bArrayCriado = IntProperty(name="",
+ description="Avisa que rodou process de som",
+ default=0)
+
+ #Script Running
+ Working = StringProperty(name="",
+ description="Script esta trabalhando",
+ maxlen= 1024,
+ default="")
+
+ #Nome do objeto
+ Info_Import = StringProperty(name="",
+ description="Info about Import",
+ maxlen= 1024,
+ default= "")#this set the initial text
+
+ #Mensagem Smart Render
+ Info_check_smartrender = StringProperty(name="",
+ description="Smart Render Message",
+ maxlen= 1024,
+ default= "")#this set the initial text
+
+ #iAudioSensib=0 #sensibilidade volume do audio 0 a 5. Quanto maior, mais sensibilidade
+ audio_sense = IntProperty(name="Audio Sens",
+ description="Audio Sensibility.",
+ min=1,
+ max=6,
+ step=1,
+ default= 1)
+
+ #iFramesPorSeg=15 #Frames por segundo para key frame
+ #fps= (bpy.types.Scene) bpy.context.scene.render.fps
+ frames_per_second = IntProperty(name="#Frames/s",
+ description="Frames you want per second. Better match your set up in Blender scene.",
+ min=1,
+ max=120,
+ step=1)
+
+ #iMovPorSeg=1 #Sensibilidade de movimento. 3= 3 movimentos por segundo
+ action_per_second = IntProperty(name="Act/s",
+ description="Actions per second. From 1 to #Frames/s",
+ min=1,
+ max=120,
+ step=1,
+ default= 4)#this set the initial text
+
+ #iDivScala=200
+ #scala do valor do movimento. [se =1 - 0 a 255 ] [se=255 - 0,00000 a 1,00000] [se=1000 - 0 a 0.255]
+ action_escale = IntProperty(name="Scale",
+ description="Scale the result values. See the text at right side of the field",
+ min=1,
+ max=99999,
+ step=100,
+ default= 100)#this set the initial text
+
+ #iMaxValue=255
+ action_max_value = IntProperty(name="Clip Max",
+ description="Set the max value (clip higher values).",
+ min=1,
+ max=255,
+ step=1,
+ default= 255)#this set the initial text
+
+ #iMinValue=0
+ action_min_value = IntProperty(name="Clip Min",
+ description="Set the min value. (clip lower values)",
+ min=0,
+ max=255,
+ step=1,
+ default= 0)#this set the initial text
+
+ #iStartFrame=0#
+ frames_initial = IntProperty(name="Frame Ini",
+ description="Where to start to put the computed values.",
+ min=0,
+ max=999999999,
+ step=1,
+ default= 0)
+
+ audio_channel_select = IntProperty(name="Audio Channel",
+ description="Choose the audio channel to use",
+ min=1,
+ max=10,
+ step=1,
+ default= 1)
+
+ action_offset_x = FloatProperty(name="XOffset",
+ description="Offset X Values",
+ min=-999999,
+ max=999999,
+ step=1,
+ default= 0)
+
+ action_offset_y = FloatProperty(name="YOffset",
+ description="Offset Y Values",
+ min=-999999,
+ max=999999,
+ step=1,
+ default= 0)
+
+ action_offset_z = FloatProperty(name="ZOffset",
+ description="Offset Z Values",
+ min=-999999,
+ max=999999,
+ step=1,
+ default= 0)
+
+ import_type= EnumProperty(items=(('imp_t_Scale', "Scale", "Apply to Scale"),
+ ('imp_t_Rotation', "Rotation", "Apply to Rotation"),
+ ('imp_t_Location', "Location", "Apply to Location")
+ ),
+ name="",
+ description= "Property to Import Values",
+ default='imp_t_Location')
+
+ import_where1= EnumProperty(items=(('imp_w_-z', "-z", "Apply to -z"),
+ ('imp_w_-y', "-y", "Apply to -y"),
+ ('imp_w_-x', "-x", "Apply to -x"),
+ ('imp_w_z', "z", "Apply to z"),
+ ('imp_w_y', "y", "Apply to y"),
+ ('imp_w_x', "x", "Apply to x")
+ ),
+ name="",
+ description= "Where to Import",
+ default='imp_w_z')
+
+ import_where2= EnumProperty(items=(('imp_w_none', "None", ""),
+ ('imp_w_-z', "-z", "Apply to -z"),
+ ('imp_w_-y', "-y", "Apply to -y"),
+ ('imp_w_-x', "-x", "Apply to -x"),
+ ('imp_w_z', "z", "Apply to z"),
+ ('imp_w_y', "y", "Apply to y"),
+ ('imp_w_x', "x", "Apply to x")
+ ),
+ name="",
+ description= "Where to Import",
+ default='imp_w_none')
+
+ import_where3= EnumProperty(items=(('imp_w_none', "None", ""),
+ ('imp_w_-z', "-z", "Apply to -z"),
+ ('imp_w_-y', "-y", "Apply to -y"),
+ ('imp_w_-x', "-x", "Apply to -x"),
+ ('imp_w_z', "z", "Apply to z"),
+ ('imp_w_y', "y", "Apply to y"),
+ ('imp_w_x', "x", "Apply to x")
+ ),
+ name="",
+ description= "Where to Import",
+ default='imp_w_none')
+
+
+ #========== Propriedades boolean =============#
+
+ # INVERTIDO!!! bNaoValorIgual=True # nao deixa repetir valores INVERTIDO!!!
+ action_valor_igual = BoolProperty(name="Hard Transition",
+ description="Use to movements like a mouth, to a arm movement, maybe you will not use this.",
+ default=1)
+
+ action_auto_audio_sense = BoolProperty(name="Auto Audio Sensitivity",
+ description="Try to discover best audio scale. ",
+ default=1)
+
+ use_just_beat=BoolProperty(name="Just Use The Beat",
+ description="Try to use just the beat to extract movement.",
+ default=0)
+
+ remove_beat=BoolProperty(name="Remove The Beat",
+ description="Try to remove the beat to extract movement.",
+ default=0)
+
+ beat_more_sensible=BoolProperty(name="More Sensible",
+ description="Try To be more sensible about the beat.",
+ default=0)
+
+ beat_less_sensible=BoolProperty(name="Less Sensible",
+ description="Try to be less sensible about the beat.",
+ default=0)
+
+ check_smartrender_loc_rot_sc=BoolProperty(name="Loc Rot Scale",
+ description="Find changes in Location, Rotation and Scale Frame by Frame.",
+ default=1)
+
+ check_smartrender_material_basic=BoolProperty(name="Basic Material",
+ description="Find changes in basic material settings Frame by Frame.",
+ default=1)
+
+ check_smartrender_material_transparence=BoolProperty(name="Material Transparence",
+ description="Find changes in material transparence settings Frame by Frame.",
+ default=0)
+
+ check_smartrender_material_mirror=BoolProperty(name="Material Mirror",
+ description="Find changes in material mirror settings Frame by Frame.",
+ default=0)
+
+ timer_reset_func=BoolProperty(name="Reset Counters",
+ description="Reset Counters after stop",
+ default=0)
+
+ cancel_button_hit=BoolProperty(name="Cancel Hit",
+ description="Cancel Hit",
+ default=0)
+
+ # Optimization
+ optimization_destructive = IntProperty(name="Optimization",
+ description="Hi value = Hi optimization -> Hi loss of information.",
+ min=0,
+ max=254,
+ step=10,
+ default= 10)
+
+ # import as driver or direct NOT IN USE!!
+ # not defined
+ # Direct=1
+ # Driver=2
+ bTypeImport = IntProperty(name="",
+ description="Import Direct or Driver",
+ default=0)
+
+ # globais do dialog open wave
+ filter_glob = StringProperty(default="*.wav", options={'HIDDEN'})
+ path = StringProperty(name="File Path", description="Filepath used for importing the WAV file", \
+ maxlen= 1024, default= "")
+ filename = StringProperty(name="File Name", description="Name of the file")
+ directory = StringProperty(name="Directory", description="Directory of the file")
+
+from bpy.props import *
+
+def WavFileImport(self, context):
+ self.layout.operator(ImportWavFile.bl_idname, text="Import a wav file", icon='PLUGIN')
+
+
+#
+#==================================================================================================
+# Use Direct
+#==================================================================================================
+#
+class OBJECT_OT_Botao_uDirect(bpy.types.Operator):
+ '''Import as Direct Animation'''
+ bl_idname = "import.sound_animation_botao_udirect"
+ bl_label = "Direct to a Property"
+
+ def execute(self, context):
+ context.scene.imp_sound_to_anim.bTypeImport= 1
+ if context.scene.imp_sound_to_anim.frames_per_second == 0:
+ context.scene.imp_sound_to_anim.frames_per_second= bpy.context.scene.render.fps
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+#
+#==================================================================================================
+# Button - Import
+#==================================================================================================
+#
+class OBJECT_OT_Botao_Import(bpy.types.Operator):
+ '''Import Key Frames to Blender'''
+ bl_idname = "import.sound_animation_botao_import"
+ bl_label = "Import Key Frames"
+
+ RunFrom=0
+ iSumImportFrames=0
+ iSumOptimizerP1=0
+ iSumOptimizerP2=0
+ iSumOptimizerP3=0
+
+ def wavimport(context, loop):
+ obi=OBJECT_OT_Botao_Import
+
+ # para de entrar no timer
+ context.scene.imp_sound_to_anim.Working=""
+ #reseta contadores caso seja pedido
+ if context.scene.imp_sound_to_anim.timer_reset_func:
+ obi.RunFrom=0
+ obi.iSumOptimizerP1=0
+ obi.iSumOptimizerP2=0
+ obi.iSumOptimizerP3=0
+ obi.iSumImportFrames=0
+ context.scene.imp_sound_to_anim.timer_reset_func=False
+
+ #limita o loop se estiver no fim
+ tot=len(array)-1
+ if obi.RunFrom+loop > tot:
+ loop= tot - obi.RunFrom
+
+ #scala do valor do movimento. [se =1 - 0 a 255 ] [se=255 - 0,00000 a 1,00000] [se=1000 - 0 a 0.255]
+ iDivScala= int(context.scene.imp_sound_to_anim.action_escale)
+
+ # nao deixa repetir valores
+ bNaoValorIgual=True
+ if context.scene.imp_sound_to_anim.action_valor_igual: bNaoValorIgual= False
+
+ # inicia no inicio pedido pelo usuario mais ponteiro RunFrom
+ iStartFrame= int(context.scene.imp_sound_to_anim.frames_initial) + obi.RunFrom
+
+ iMaxValue= context.scene.imp_sound_to_anim.action_max_value
+ iMinValue= context.scene.imp_sound_to_anim.action_min_value
+
+ bEscala=bRotacao=bEixo=False
+ if context.scene.imp_sound_to_anim.import_type=='imp_t_Scale':
+ bEscala=True;
+
+ if context.scene.imp_sound_to_anim.import_type=='imp_t_Rotation':
+ bRotacao=True;
+
+ if context.scene.imp_sound_to_anim.import_type=='imp_t_Location':
+ bEixo=True;
+
+ # atencao, nao eh boolean
+ iEixoXneg= iEixoYneg= iEixoZneg=1
+ # atencao, nao eh boolean
+ iRotationNeg=1
+ # atencao, nao eh boolean
+ iEscalaYneg= iEscalaZneg= iEscalaXneg=1
+ bEixoX=bEixoY=bEixoZ=bEscalaX=bEscalaY=bEscalaZ=bRotationX=bRotationY=bRotationZ=False
+
+ # LOCAL 1
+ if context.scene.imp_sound_to_anim.import_where1== 'imp_w_x':
+ bEixoX=True
+ bEscalaX=True
+ bRotationX=True
+
+ if context.scene.imp_sound_to_anim.import_where1== 'imp_w_y':
+ bEixoY=True
+ bEscalaY=True
+ bRotationY=True
+
+ if context.scene.imp_sound_to_anim.import_where1== 'imp_w_z':
+ bEixoZ=True
+ bEscalaZ=True
+ bRotationZ=True
+
+ if context.scene.imp_sound_to_anim.import_where1== 'imp_w_-x':
+ bEixoX=True
+ bEscalaX=True
+ bRotationX=True
+ iEixoXneg=-1
+ iEscalaXneg=-1
+ iRotationNeg=-1
+
+ if context.scene.imp_sound_to_anim.import_where1== 'imp_w_-y':
+ bEixoY=True
+ bEscalaY=True
+ bRotationY=True
+ iEixoYneg=-1
+ iRotationNeg=-1
+ iEscalaYneg=-1
+
+ if context.scene.imp_sound_to_anim.import_where1== 'imp_w_-z':
+ bEixoZ=True
+ bEscalaZ=True
+ bRotationZ=True
+ iEixoZneg=-1
+ iRotationNeg=-1
+ iEscalaZneg=-1
+
+
+ # LOCAL 2
+ if context.scene.imp_sound_to_anim.import_where2== 'imp_w_x':
+ bEixoX=True
+ bEscalaX=True
+ bRotationX=True
+
+ if context.scene.imp_sound_to_anim.import_where2== 'imp_w_y':
+ bEixoY=True
+ bEscalaY=True
+ bRotationY=True
+
+ if context.scene.imp_sound_to_anim.import_where2== 'imp_w_z':
+ bEixoZ=True
+ bEscalaZ=True
+ bRotationZ=True
+
+ if context.scene.imp_sound_to_anim.import_where2== 'imp_w_-x':
+ bEixoX=True
+ bEscalaX=True
+ bRotationX=True
+ iEixoXneg=-1
+ iEscalaXneg=-1
+ iRotationNeg=-1
+
+ if context.scene.imp_sound_to_anim.import_where2== 'imp_w_-y':
+ bEixoY=True
+ bEscalaY=True
+ bRotationY=True
+ iEixoYneg=-1
+ iRotationNeg=-1
+ iEscalaYneg=-1
+
+ if context.scene.imp_sound_to_anim.import_where2== 'imp_w_-z':
+ bEixoZ=True
+ bEscalaZ=True
+ bRotationZ=True
+ iEixoZneg=-1
+ iRotationNeg=-1
+ iEscalaZneg=-1
+
+
+ # LOCAL 3
+ if context.scene.imp_sound_to_anim.import_where3== 'imp_w_x':
+ bEixoX=True
+ bEscalaX=True
+ bRotationX=True
+
+ if context.scene.imp_sound_to_anim.import_where3== 'imp_w_y':
+ bEixoY=True
+ bEscalaY=True
+ bRotationY=True
+
+ if context.scene.imp_sound_to_anim.import_where3== 'imp_w_z':
+ bEixoZ=True
+ bEscalaZ=True
+ bRotationZ=True
+
+ if context.scene.imp_sound_to_anim.import_where3== 'imp_w_-x':
+ bEixoX=True
+ bEscalaX=True
+ bRotationX=True
+ iEixoXneg=-1
+ iEscalaXneg=-1
+ iRotationNeg=-1
+
+ if context.scene.imp_sound_to_anim.import_where3== 'imp_w_-y':
+ bEixoY=True
+ bEscalaY=True
+ bRotationY=True
+ iEixoYneg=-1
+ iRotationNeg=-1
+ iEscalaYneg=-1
+
+ if context.scene.imp_sound_to_anim.import_where3== 'imp_w_-z':
+ bEixoZ=True
+ bEscalaZ=True
+ bRotationZ=True
+ iEixoZneg=-1
+ iRotationNeg=-1
+ iEscalaZneg=-1
+
+ iMinBaseX=iMinScaleBaseX=context.scene.imp_sound_to_anim.action_offset_x
+ iMinBaseY=iMinScaleBaseY=context.scene.imp_sound_to_anim.action_offset_y
+ iMinBaseZ=iMinScaleBaseZ=context.scene.imp_sound_to_anim.action_offset_z
+
+ #escala inicia com 1 e nao com zero
+ iRotationAxisBaseX=context.scene.imp_sound_to_anim.action_offset_x +1
+ iRotationAxisBaseY=context.scene.imp_sound_to_anim.action_offset_y +1
+ iRotationAxisBaseZ=context.scene.imp_sound_to_anim.action_offset_z +1
+
+ #Added destructive optimizer option - LostLestSignificativeDigit lost/total
+ iDestructiveOptimizer=context.scene.imp_sound_to_anim.optimization_destructive
+
+ #limita ou nao o valor - velocidade
+ bLimitValue=False
+
+ if iMinValue<0: iMinValue=0
+ if iMaxValue>255: iMaxValue=255
+ if iMinValue>255: iMinValue=255
+ if iMaxValue<0: iMaxValue=0
+ if iMinValue!= 0: bLimitValue= True
+ if iMaxValue!= 255: bLimitValue= True
+
+ if obi.RunFrom==0:
+ print('')
+ print("================================================================")
+ from time import strftime
+ print(strftime("Start Import: %H:%M:%S"))
+ print("================================================================")
+ print('')
+
+ ilocationXAnt=0
+ ilocationYAnt=0
+ ilocationZAnt=0
+ iscaleXAnt=0
+ iscaleYAnt=0
+ iscaleZAnt=0
+ iRotateValAnt=0
+
+ # variavel global _Interna_Globals
+ if context.scene.imp_sound_to_anim.bArrayCriado:
+ for i in range(loop):
+ ival=array[i+obi.RunFrom]/iDivScala
+ #valor pequeno demais, vai dar zero na hora de aplicar
+ if ival < 0.001:
+ array[i+obi.RunFrom]=0
+ ival=0
+
+ # to increase performance and legibility
+ arrayI= array[i+obi.RunFrom]
+ arrayIP1= array[i+1+obi.RunFrom]
+ arrayIL1= array[i-1+obi.RunFrom]
+
+ # opcao de NAO colocar valores iguais sequenciais
+ if i>0 and bNaoValorIgual and arrayIL1== arrayI:
+ print("Importing Blender Frame: "+str(i+obi.RunFrom+1)+"\tof "+str(len(array)-1) + \
+ "\t(skipped by optimizer)")
+ obi.iSumOptimizerP3+=1
+ else:
+ # otimizacao - nao preciso mais que 2 valores iguais.
+ # pular key frame intermediario - Ex b, a, -, -, -, a
+ # tambem otimiza pelo otimizador com perda
+ # valor atual == anterior e posterior -> pula
+ if i>0 and i< len(array)-1 and abs(arrayI - arrayIL1)<=iDestructiveOptimizer and \
+ abs(arrayI - arrayIP1)<=iDestructiveOptimizer:
+ print("Importing Blender Frame: "+str(i+obi.RunFrom+1)+"\tof "+str(len(array)-1) + \
+ "\t(skipped by optimizer)")
+ if iDestructiveOptimizer>0 and arrayI != arrayIL1 or arrayI != arrayIP1:
+ obi.iSumOptimizerP1+=1
+ else: obi.iSumOptimizerP2+=1
+ else:
+ if bLimitValue:
+ if arrayI > iMaxValue: array[i+obi.RunFrom]=iMaxValue
+ if arrayI < iMinValue: array[i+obi.RunFrom]=iMinValue
+
+ ival=array[i+obi.RunFrom]/iDivScala
+ #passa para float com somente 3 digitos caso seja float
+ m_ival=ival*1000
+ if int(m_ival) != m_ival:
+ ival= int(m_ival)
+ ival = ival /1000
+
+ bpy.context.scene.frame_current = i+iStartFrame
+
+ #precisa fazer objeto ativo
+ if bpy.context.active_object.type=='MESH' or bpy.context.active_object.type=='CAMERA' or \
+ bpy.context.active_object.type=='EMPTY':
+ if bEixo:
+ if bEixoX: bpy.context.active_object.location.x = ival*iEixoXneg+iMinBaseX
+ if bEixoY: bpy.context.active_object.location.y = ival*iEixoYneg+iMinBaseY
+ if bEixoZ: bpy.context.active_object.location.z = ival*iEixoZneg+iMinBaseZ
+
+ if bEscala:
+ if bEscalaX: bpy.context.active_object.scale.x = ival*iEscalaXneg+iMinScaleBaseX
+ if bEscalaY: bpy.context.active_object.scale.y = ival*iEscalaYneg+iMinScaleBaseY
+ if bEscalaZ: bpy.context.active_object.scale.z = ival*iEscalaZneg+iMinScaleBaseZ
+
+ # 'ARMATURE' or ('MESH' and bRotacao) or ('CAMERA' and bRotacao) or 'LAMP' or 'EMPTY' and bRotacao)
+ if bpy.context.active_object.type=='ARMATURE' or (bpy.context.active_object.type=='MESH' and bRotacao) or \
+ (bpy.context.active_object.type=='CAMERA' and bRotacao) or \
+ bpy.context.active_object.type=='LAMP' or \
+ (bpy.context.active_object.type=='EMPTY' and bRotacao):
+
+ #=========== BONE ===========#
+ if bpy.context.active_object.type=='ARMATURE': #precisa ser objeto ativo. Nao achei como passar para editmode
+ if bpy.context.mode!= 'POSE': #posemode
+ bpy.ops.object.posemode_toggle()
+
+ #============= ALL ===========#
+ if bEixo:
+ if ilocationXAnt!=0 or ilocationYAnt!=0 or ilocationZAnt!=0:
+
+ bpy.ops.transform.translate(value=(ilocationXAnt*-1, ilocationYAnt*-1, \
+ ilocationZAnt*-1), constraint_axis=(bEixoX, bEixoY,bEixoZ), \
+ constraint_orientation='GLOBAL', mirror=False, \
+ proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
+ proportional_size=1, snap=False, \
+ snap_target='CLOSEST', snap_point=(0, 0, 0), \
+ snap_align=False, snap_normal=(0, 0, 0), \
+ release_confirm=False)
+
+ ilocationX=ilocationY=ilocationZ=0
+ if bEixoX: ilocationX = ival*iEixoXneg+iMinBaseX
+ if bEixoY: ilocationY = ival*iEixoYneg+iMinBaseY
+ if bEixoZ: ilocationZ = ival*iEixoZneg+iMinBaseZ
+
+ bpy.ops.transform.translate(value=(ilocationX, ilocationY, \
+ ilocationZ), constraint_axis=(bEixoX, bEixoY,bEixoZ), \
+ constraint_orientation='GLOBAL', mirror=False, \
+ proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
+ proportional_size=1, snap=False, \
+ snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, \
+ snap_normal=(0, 0, 0), release_confirm=False)
+ ilocationXAnt= ilocationX
+ ilocationYAnt= ilocationY
+ ilocationZAnt= ilocationZ
+
+ if bEscala:
+ if iscaleXAnt!=0 or iscaleYAnt!=0 or iscaleZAnt!=0:
+ tmpscaleXAnt=0
+ tmpscaleYAnt=0
+ tmpscaleZAnt=0
+ if iscaleXAnt: tmpscaleXAnt=1/iscaleXAnt
+ if iscaleYAnt: tmpscaleYAnt=1/iscaleYAnt
+ if iscaleZAnt: tmpscaleZAnt=1/iscaleZAnt
+
+ bpy.ops.transform.resize(value=(tmpscaleXAnt, tmpscaleYAnt, \
+ tmpscaleZAnt ), constraint_axis=(False, False, False), \
+ constraint_orientation='GLOBAL', mirror=False, \
+ proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
+ proportional_size=1, snap=False, snap_target='CLOSEST', \
+ snap_point=(0, 0, 0), snap_align=False, \
+ snap_normal=(0, 0, 0), release_confirm=False)
+
+ iscaleX=iscaleY=iscaleZ=0
+ if bEscalaX: iscaleX = ival*iEscalaXneg+iMinScaleBaseX
+ if bEscalaY: iscaleY = ival*iEscalaYneg+iMinScaleBaseY
+ if bEscalaZ: iscaleZ = ival*iEscalaZneg+iMinScaleBaseZ
+
+ bpy.ops.transform.resize(value=(iscaleX, iscaleY, \
+ iscaleZ), constraint_axis=(False, False, False), \
+ constraint_orientation='GLOBAL', mirror=False, \
+ proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
+ proportional_size=1, snap=False, \
+ snap_target='CLOSEST', snap_point=(0, 0, 0), \
+ snap_align=False, snap_normal=(0, 0, 0), \
+ release_confirm=False)
+ iscaleXAnt= iscaleX
+ iscaleYAnt= iscaleY
+ iscaleZAnt= iscaleZ
+
+ if bRotacao:
+ if iRotateValAnt!=0:
+ bpy.context.active_object.rotation_euler= ((iRotateValAnt*-1)+ iRotationAxisBaseX) *bRotationX , \
+ ((iRotateValAnt*-1)+ iRotationAxisBaseY) *bRotationY , \
+ ((iRotateValAnt*-1)+ iRotationAxisBaseZ) *bRotationZ
+
+ bpy.context.active_object.rotation_euler= ((ival*iRotationNeg)+ iRotationAxisBaseX) * bRotationX, \
+ ((ival*iRotationNeg)+ iRotationAxisBaseY) * bRotationY, \
+ ((ival*iRotationNeg)+ iRotationAxisBaseZ) * bRotationZ
+ iRotateValAnt= ival*iRotationNeg
+
+ ob = bpy.context.active_object
+
+ if bEixo:
+ ob.keyframe_insert(data_path="location")
+
+ if bRotacao:
+ ob.keyframe_insert(data_path="rotation_euler")
+
+ if bEscala:
+ ob.keyframe_insert(data_path="scale")
+
+ print("Importing Blender Frame: "+str(i+obi.RunFrom+1)+"\tof "+str(len(array)-1) + "\tValue: "+ str(ival))
+
+ obi.iSumImportFrames+=1
+ # Fim do ELSE otimizador
+ # Fim bNaoValorIgual
+
+ if obi.RunFrom>= tot:
+ bpy.context.scene.frame_current = 1
+ context.scene.imp_sound_to_anim.Info_Import="Done. Imported " + str(obi.iSumImportFrames) + " Frames"
+ from time import strftime
+ print('')
+ print("================================================================")
+ print("Imported: " +str(obi.iSumImportFrames) + " Key Frames")
+ print("Optimizer Pass 1 prepared to optimize: " +str(obi.iSumOptimizerP1) + " blocks of Frames")
+ print("Optimizer Pass 2 has optimized: " +str(obi.iSumOptimizerP2) + " Frames")
+ print("Optimizer Pass 3 has optimized: " +str(obi.iSumOptimizerP3) + " Frames")
+ print("Optimizer has optimized: " +str(obi.iSumOptimizerP1 + obi.iSumOptimizerP2 + obi.iSumOptimizerP3) + " Frames")
+ print(strftime("End Import: %H:%M:%S - by Vlassius"))
+ print("================================================================")
+ print('')
+ obi.RunFrom=0
+ obi.iSumImportFrames=0
+ obi.iSumOptimizerP1=0
+ obi.iSumOptimizerP2=0
+ obi.iSumOptimizerP3=0
+ return obi.RunFrom
+ else:
+ obi.RunFrom+= loop
+ context.scene.imp_sound_to_anim.Info_Import="Processing Frame " + str(obi.RunFrom+loop) + \
+ " of " + str(tot-1) + " Frames"
+ return obi.RunFrom
+
+
+ def execute(self, context):
+ #wavimport(context)
+ #return{'FINISHED'}
+ context.scene.imp_sound_to_anim.Working= "wavimport"
+ bpy.ops.wm.modal_timer_operator()
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+
+
+#
+#==================================================================================================
+# Button - Sound Process
+#==================================================================================================
+#
+class OBJECT_OT_Botao_Go(bpy.types.Operator):
+ ''''''
+ bl_idname = "import.sound_animation_botao_go"
+ # change in API
+ bl_description = "Process a .wav file, take movement from the sound and import to the scene as Key"
+ bl_label = "Process Wav"
+
+ filter_glob = StringProperty(default="*.wav", options={'HIDDEN'})
+ path = StringProperty(name="File Path", description="Filepath used for importing the WAV file", \
+ maxlen= 1024, default= "")
+ filename = StringProperty(name="File Name", description="Name of the file")
+ directory = StringProperty(name="Directory", description="Directory of the file")
+
+ RunFrom=0
+ Wave_read=0
+ MaxAudio=0
+
+
+ def SoundConv(File, DivSens, Sensibil, Resol, context, bAutoSense, bRemoveBeat, bUseBeat, bMoreSensible, \
+ bLessSensible, AudioChannel, loop):
+ obg= OBJECT_OT_Botao_Go
+ #reseta contadores caso seja pedido
+ if context.scene.imp_sound_to_anim.timer_reset_func:
+ obc.RunFrom=0
+ Wave_read=0
+ MaxAudio=0
+ context.scene.imp_sound_to_anim.timer_reset_func=False
+
+ #abre arquivo se primeira rodada
+ if obg.RunFrom==0:
+ try:
+ obg.Wave_read= wave.open(File, 'rb')
+ except IOError as e:
+ print("File Open Error: ", e)
+ return False
+
+ NumCh= obg.Wave_read.getnchannels()
+ SampW= obg.Wave_read.getsampwidth() # 8, 16, 24 32 bits
+ FrameR= obg.Wave_read.getframerate()
+ NumFr= obg.Wave_read.getnframes()
+ ChkCompr= obg.Wave_read.getcomptype()
+
+ if ChkCompr != "NONE":
+ print('Sorry, this compressed Format is NOT Supported ', ChkCompr)
+ context.scene.imp_sound_to_anim.Info_Import= "Sorry, this compressed Format is NOT Supported "
+ return False
+
+ if SampW > 2:
+ context.scene.imp_sound_to_anim.Info_Import= "Sorry, supported .wav files 8 and 16 bits only"
+ print('Sorry, supported .wav files 8 and 16 bits only')
+ return False
+
+ context.scene.imp_sound_to_anim.Info_Import=""
+
+ # controla numero do canal
+ if AudioChannel > NumCh:
+ if obg.RunFrom==0:
+ print("Channel number " + str(AudioChannel) + " is selected but this audio file has just " + \
+ str(NumCh) + " channels, so selecting channel " \
+ + str(NumCh) + "!")
+ AudioChannel = NumCh
+
+ # apenas para por na tela
+ tmpAudioChannel= AudioChannel
+
+ #used in index sum to find the channe, adjust to first byte sample index
+ AudioChannel -= 1
+
+ # se dois canais, AudioChannel=4 porque sao 4 bytes
+ if SampW ==2: AudioChannel*=2
+
+ # usado para achar contorno da onda - achando picos
+ # numero de audio frames para cada video frame
+ BytesResol= int(FrameR/Resol)
+
+ # com 8 bits/S - razao Sample/s por resolucao
+ # tamanho do array
+ BytesDadosTotProcess= NumFr // BytesResol
+
+ if obg.RunFrom==0: # primeira rodada
+ # inicia array
+ _Interna_Globals(BytesDadosTotProcess, context)
+ print('')
+ print("================================================================")
+ from time import strftime
+ print(strftime("Go! %H:%M:%S"))
+ print("================================================================")
+ print('')
+ print('Total Audio Time: \t ' + str(NumFr//FrameR) + 's (' + str(NumFr//FrameR//60) + 'min)')
+ print('Total # Interactions: \t', BytesDadosTotProcess)
+ print('Total Audio Frames: \t', NumFr)
+ print('Frames/s: \t\t ' + str(FrameR))
+ print('# Chanels in File: \t', NumCh)
+ print('Channel to use:\t\t', tmpAudioChannel)
+ print('Bit/Sample/Chanel: \t ' + str(SampW*8))
+ print('# Frames/Act: \t\t', DivSens)
+
+ if bAutoSense==0:
+ print('Audio Sensitivity: \t', Sensibil+1)
+ else:
+ print('Using Auto Audio Sentivity. This is pass 1 of 2.')
+
+ print('')
+ print ("Sample->[value]\tAudio Frame # \t\t[Graph Value]")
+
+ if obg.RunFrom==0 and bAutoSense!=0:
+ Sensibil=0 # if auto sense, Sensibil must be zero here
+ obg.MaxAudio=0 # valor maximo de audio encontrado
+
+ # verifica limite total do audio
+ looptot= int(BytesDadosTotProcess // DivSens)
+ if obg.RunFrom+loop > looptot:
+ loop= looptot-obg.RunFrom
+
+ j=0 # usado de indice
+ # laco total leitura bytes
+ # armazena dado de pico
+ for jj in range(loop):
+ # caso de 2 canais (esterio)
+ # uso apenas 2 bytes em 16 bits, ie, apenas canal esquerdo
+ # [0] e [1] para CH L
+ # [2] e [3] para CH R and so on
+ # mono:1 byte to 8 bits, 2 bytes to 16 bits
+ # sterio: 2 byte to 8 bits, 4 bytes to 16 bits
+ ValorPico=0
+ # leio o numero de frames de audio para cada frame de video, valor em torno de 1000
+ for i in range(BytesResol):
+ #loop exterior copia DivSens frames a cada frame calculado
+ frame = obg.Wave_read.readframes(DivSens)
+
+ if len(frame)==0: break
+
+ if bAutoSense==0: # AutoAudioSense Desligado
+ if SampW ==1:
+ if Sensibil ==5:
+ frame0= frame[AudioChannel] << 6 & 255
+
+ elif Sensibil ==4:
+ frame0= frame[AudioChannel] << 5 & 255
+
+ elif Sensibil ==3:
+ frame0= frame[AudioChannel] << 4 & 255
+
+ elif Sensibil ==2:
+ frame0= frame[AudioChannel] << 3 & 255
+
+ elif Sensibil ==1:
+ frame0= frame[AudioChannel] << 2 & 255
+
+ elif Sensibil ==0:
+ frame0= frame[AudioChannel]
+
+ if frame0> ValorPico:
+ ValorPico= frame0
+
+ if SampW ==2: # frame[0] baixa frame[1] ALTA BIT 1 TEM SINAL!
+ if frame[1+AudioChannel] <127: # se bit1 =0, usa o valor - se bit1=1 quer dizer numero negativo
+ if Sensibil ==0:
+ frame0= frame[1+AudioChannel]
+
+ elif Sensibil ==4:
+ frame0= ((frame[AudioChannel] & 0b11111100) >> 2) | ((frame[1+AudioChannel] & 0b00000011) << 6)
+
+ elif Sensibil ==3:
+ frame0= ((frame[AudioChannel] & 0b11110000) >> 4) | ((frame[1+AudioChannel] & 0b00001111) << 4)
+
+ elif Sensibil ==2:
+ frame0= ((frame[AudioChannel] & 0b11100000) >> 5) | ((frame[1+AudioChannel] & 0b00011111) << 3)
+
+ elif Sensibil ==1:
+ frame0= ((frame[AudioChannel] & 0b11000000) >> 6) | ((frame[1+AudioChannel] & 0b00111111) << 2)
+
+ elif Sensibil ==5:
+ frame0=frame[AudioChannel]
+
+ if frame0 > ValorPico:
+ ValorPico= frame0
+
+ else: # AutoAudioSense Ligado
+ if SampW ==1:
+ if frame[AudioChannel]> obg.MaxAudio:
+ obg.MaxAudio = frame[AudioChannel]
+
+ if frame[AudioChannel]> ValorPico:
+ ValorPico=frame[AudioChannel]
+
+ if SampW ==2:
+ if frame[1+AudioChannel] < 127:
+ tmpValorPico= frame[1+AudioChannel] << 8
+ tmpValorPico+= frame[AudioChannel]
+
+ if tmpValorPico > obg.MaxAudio:
+ obg.MaxAudio = tmpValorPico
+
+ if tmpValorPico > ValorPico:
+ ValorPico= tmpValorPico
+
+ if bAutoSense==0: #autoaudiosense desligado
+ # repito o valor de frames por actions (OTIMIZAR)
+ for ii in range(DivSens):
+ array[j+obg.RunFrom]=ValorPico # valor de pico encontrado
+ j +=1 # incrementa indice prox local
+ else:
+ idx=obg.RunFrom*2 # porque sao dois bytes
+ arrayAutoSense[j+idx]= (ValorPico & 0b0000000011111111) #copia valores baixos
+ arrayAutoSense[j+1+idx]= (ValorPico & 0b1111111100000000) >> 8 #copia valores altos
+ j+=2
+
+ if bAutoSense==0: #autoaudiosense desligado
+ igraph= ValorPico//10
+ else:
+ if SampW ==2:
+ igraph= ValorPico//1261
+
+ else:
+ igraph= ValorPico//10
+
+ stgraph="["
+ for iii in range(igraph):
+ stgraph+="+"
+
+ for iiii in range(26-igraph):
+ stgraph+=" "
+ stgraph+="]"
+
+ print ("Sample-> " + str(ValorPico) + "\tAudio Frame # " + str(jj+obg.RunFrom) + " of " + str(looptot-1) + "\t"+ stgraph)
+
+ # acabou primeira fase roda toda de uma vez
+ if obg.RunFrom+loop == looptot:
+ if bAutoSense==1:
+ print("")
+ print("================================================================")
+ print('Calculating Auto Audio Sentivity, pass 2 of 2.')
+ print("================================================================")
+
+ # caso usar batida, procurar por valores proximos do maximo e zerar restante.
+ # caso retirar batida, zerar valores proximos do maximo
+ UseMinim=0
+ UseMax=0
+
+ if bUseBeat==1:
+ print("Trying to use just the beat.")
+ UseMinim= obg.MaxAudio*0.8
+ if bMoreSensible:
+ UseMinim= obg.MaxAudio*0.7
+ elif bLessSensible:
+ UseMinim= obg.MaxAudio*0.9
+
+ if bRemoveBeat==1:
+ print("Trying to exclude the beat.")
+ UseMax= obg.MaxAudio*0.7
+ if bMoreSensible:
+ UseMax= obg.MaxAudio*0.8
+ elif bLessSensible:
+ UseMax= obg.MaxAudio*0.7
+
+ print("")
+ # para transformar 15 bits em 8 calibrando valor maximo -> fazer regra de 3
+ # obg.MaxAudio -> 255
+ # outros valores => valor calibrado= (255 * Valor) / obg.MaxAudio
+ scale= 255/obg.MaxAudio
+
+ j=0
+ jj=0
+ print ("Sample->[value]\tAudio Frame # \t\t[Graph Value]")
+
+ for i in range(BytesDadosTotProcess // DivSens):
+
+ ValorOriginal= arrayAutoSense[j+1] << 8
+ ValorOriginal+= arrayAutoSense[j]
+
+ if bUseBeat==1:
+ if ValorOriginal < UseMinim:
+ ValorOriginal = 0
+
+ elif bRemoveBeat==1:
+ if ValorOriginal > UseMax:
+ ValorOriginal = 0
+
+ ValorOriginal= ((round(ValorOriginal * scale)) & 0b11111111) #aplica a escala
+
+ for ii in range(DivSens):
+ array[jj] = ValorOriginal
+ jj += 1 # se autoaudiosense, o array tem dois bytes para cada valor
+
+ j+=2
+ igraph= round(array[jj-1]/10)
+ stgraph="["
+ for iii in range(igraph):
+ stgraph+="+"
+
+ for iiii in range(26-igraph):
+ stgraph+=" "
+ stgraph+="]"
+ print ("Sample-> " + str(array[jj-1]) + "\tAudio Frame # " + str(i) + " of " + str(looptot-1) + "\t"+ stgraph)
+
+ #limpa array tmp
+ del arrayAutoSense[:]
+
+ # mensagens finais
+ context.scene.imp_sound_to_anim.Info_Import= "Click \"Import Key frames\" to begin import" #this set the initial text
+
+ print("================================================================")
+ from time import strftime
+ print(strftime("End Process: %H:%M:%S"))
+ print("================================================================")
+
+ try:
+ obg.Wave_read.close()
+ except:
+ print('File Close Error')
+
+ obg.RunFrom=0
+ return obg.RunFrom # acabou tudo
+
+ else:#ainda nao acabou o arquivo todo if RunFrom+loop = looptot:
+ context.scene.imp_sound_to_anim.Info_Import="Processing " + str(obg.RunFrom) + " of " + str(looptot) +" Audio Frames"
+ # force update info text in UI
+ bpy.context.scene.frame_current= bpy.context.scene.frame_current
+ obg.RunFrom+=loop
+ return obg.RunFrom
+
+
+
+
+ def ProcessaSom(context, loop):
+ obg= OBJECT_OT_Botao_Go
+ # para de entrar o timer
+ context.scene.imp_sound_to_anim.Working=""
+ #reseta contadores caso seja pedido
+ if context.scene.imp_sound_to_anim.timer_reset_func:
+ obg.RunFrom=0
+ context.scene.imp_sound_to_anim.timer_reset_func=False
+
+ import os
+ f= os.path.join(context.scene.imp_sound_to_anim.directory, context.scene.imp_sound_to_anim.filename)
+ f= os.path.normpath(f)
+
+ if obg.RunFrom==0:
+ print ("")
+ print ("")
+ print ("Selected file = ",f)
+ checktype = f.split('\\')[-1].split('.')[1]
+ if checktype.upper() != 'WAV':
+ print ("ERROR!! Selected file = ", f)
+ print ("ERROR!! Its not a .wav file")
+ return
+
+ #sensibilidade volume do audio 0 a 5. Quanto maior, mais sensibilidade
+ iAudioSensib= int(context.scene.imp_sound_to_anim.audio_sense)-1
+ if iAudioSensib <0: iAudioSensib=0
+ elif iAudioSensib>5: iAudioSensib=5
+
+ #act/s nao pode se maior que frames/s
+ if context.scene.imp_sound_to_anim.action_per_second > context.scene.imp_sound_to_anim.frames_per_second:
+ context.scene.imp_sound_to_anim.action_per_second = context.scene.imp_sound_to_anim.frames_per_second
+
+ #Frames por segundo para key frame
+ iFramesPorSeg= int(context.scene.imp_sound_to_anim.frames_per_second)
+
+ #Sensibilidade de movimento. 3= 3 movimentos por segundo
+ iMovPorSeg= int(context.scene.imp_sound_to_anim.action_per_second)
+
+ #iDivMovPorSeg Padrao - taxa 4/s ou a cada 0,25s => iFramesPorSeg/iDivMovPorSeg= ~0.25
+ for i in range(iFramesPorSeg):
+ iDivMovPorSeg=iFramesPorSeg/(i+1)
+ if iFramesPorSeg/iDivMovPorSeg >=iMovPorSeg:
+ break
+
+ bRemoveBeat= context.scene.imp_sound_to_anim.remove_beat
+ bUseBeat= context.scene.imp_sound_to_anim.use_just_beat
+ bLessSensible= context.scene.imp_sound_to_anim.beat_less_sensible
+ bMoreSensible= context.scene.imp_sound_to_anim.beat_more_sensible
+ AudioChannel= context.scene.imp_sound_to_anim.audio_channel_select
+
+ # chama funcao de converter som, retorna preenchendo _Interna_Globals.array
+ index= OBJECT_OT_Botao_Go.SoundConv(f, int(iDivMovPorSeg), iAudioSensib, iFramesPorSeg, context, \
+ context.scene.imp_sound_to_anim.action_auto_audio_sense, bRemoveBeat, \
+ bUseBeat, bMoreSensible, bLessSensible, AudioChannel, loop)
+ return index
+
+
+ def execute(self, context):
+
+ # copia dados dialof open wave
+ context.scene.imp_sound_to_anim.filter_glob= self.filter_glob
+ context.scene.imp_sound_to_anim.path = self.path
+ context.scene.imp_sound_to_anim.filename = self.filename
+ context.scene.imp_sound_to_anim.directory = self.directory
+
+ context.scene.imp_sound_to_anim.Working= "ProcessaSom"
+ bpy.ops.wm.modal_timer_operator()
+ #ProcessaSom(context)
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ #need to set a path so so we can get the file name and path
+ wm = context.window_manager
+ wm.fileselect_add(self)
+
+ return {'RUNNING_MODAL'}
+
+
+#
+#==================================================================================================
+# Button - Check Smart Render
+#==================================================================================================
+#
+class OBJECT_OT_Botao_Check_SmartRender(bpy.types.Operator):
+ '''Check for Reduction'''
+ bl_idname = "import.sound_animation_botao_check_smartrender"
+ bl_label = "Check Smart Render"
+
+ RunFrom=0
+ Frames_Renderizar=0
+ Frames_Pular=0
+
+ def CheckSmartRender(context, loop):
+ obc= OBJECT_OT_Botao_Check_SmartRender
+
+ #reseta contadores caso seja pedido
+ if context.scene.imp_sound_to_anim.timer_reset_func:
+ obc.RunFrom=0
+ obc.Frames_Pular=0
+ obc.Frames_Renderizar=0
+ context.scene.imp_sound_to_anim.timer_reset_func=False
+
+ if obc.RunFrom==0:
+ if loop !=1: # loop==1 quando estou chamando de dentro da funcao render
+ print("")
+ print("================================================================")
+ print('Running Check Smart Render...')
+
+ #garante ao menos locrotscale ligado
+ if context.scene.imp_sound_to_anim.check_smartrender_loc_rot_sc==False and \
+ context.scene.imp_sound_to_anim.check_smartrender_material_basic==False and \
+ context.scene.imp_sound_to_anim.check_smartrender_material_transparence==False and \
+ context.scene.imp_sound_to_anim.check_smartrender_material_mirror==False:
+ context.scene.imp_sound_to_anim.check_smartrender_loc_rot_sc=True
+
+ chkLocRotSc= context.scene.imp_sound_to_anim.check_smartrender_loc_rot_sc
+ chkMatBas= context.scene.imp_sound_to_anim.check_smartrender_material_basic
+ chkMatTransp= context.scene.imp_sound_to_anim.check_smartrender_material_transparence
+ chkMatMirror= context.scene.imp_sound_to_anim.check_smartrender_material_mirror
+
+ ToRender=[]
+ origloop=loop
+ from copy import copy
+ RunMax= bpy.context.scene.frame_end - bpy.context.scene.frame_start+1
+ if obc.RunFrom+loop > RunMax:
+ loop= RunMax-obc.RunFrom
+ if loop<=0: #acabou
+ if origloop !=1: # loop==1 quando estou chamando de dentro da funcao render
+ print("")
+ print("Frames to copy: " + str(obc.Frames_Pular) + " Frames to really render= " + str(obc.Frames_Renderizar))
+ print("================================================================")
+ print("")
+ obc.RunFrom=0
+ obc.Frames_Pular=0
+ obc.Frames_Renderizar=0
+ return (ToRender, obc.RunFrom)
+
+ #move para o primeiro frame a renderizar
+ #RunFrom inicia em zero - frames inicia em 1
+ bpy.context.scene.frame_current = obc.RunFrom+bpy.context.scene.frame_start
+
+ for k in range(loop):
+ if obc.RunFrom==0 and k==0: #primeiro sempre renderiza
+ ToRender.append(bpy.context.scene.frame_current)
+ obc.Frames_Renderizar+=1
+ bpy.context.scene.frame_set(bpy.context.scene.frame_current + 1)
+ else:
+ if origloop !=1: # loop==1 quando estou chamando de dentro da funcao render
+ import sys
+ sys.stdout.write("\rChecking Frame "+str(bpy.context.scene.frame_current) + " ")
+ sys.stdout.flush()
+ #buffer de todos os objetos
+ a=[]
+ for obj in bpy.data.objects:
+ if chkLocRotSc:
+ # loc rot scale
+ a.append(copy(obj.location))
+ a.append(copy(obj.rotation_euler))
+ a.append(copy(obj.scale))
+ if hasattr(obj.data, 'materials') and obj.data.materials.keys()!=[] :
+ if bpy.context.scene.render.engine == "BLENDER_RENDER":
+ #pega somente primeiro material sempre
+ if chkMatBas:
+ # cores
+ a.append(copy(obj.data.materials[0].type))
+ a.append(copy(obj.data.materials[0].emit))
+ a.append(copy(obj.data.materials[0].diffuse_color))
+ a.append(copy(obj.data.materials[0].diffuse_intensity))
+ a.append(copy(obj.data.materials[0].specular_intensity))
+ a.append(copy(obj.data.materials[0].specular_color))
+ a.append(copy(obj.data.materials[0].alpha))
+ a.append(copy(obj.data.materials[0].diffuse_shader))
+ a.append(copy(obj.data.materials[0].specular_shader))
+ a.append(copy(obj.data.materials[0].specular_hardness))
+
+ if chkMatTransp:
+ # transp
+ a.append(copy(obj.data.materials[0].transparency_method))
+ a.append(copy(obj.data.materials[0].specular_alpha))
+ a.append(copy(obj.data.materials[0].raytrace_transparency.fresnel))
+ a.append(copy(obj.data.materials[0].raytrace_transparency.ior))
+ a.append(copy(obj.data.materials[0].raytrace_transparency.filter))
+ a.append(copy(obj.data.materials[0].raytrace_transparency.depth))
+ a.append(copy(obj.data.materials[0].translucency))
+ a.append(copy(obj.data.materials[0].specular_alpha))
+
+ if chkMatMirror:
+ #mirror
+ a.append(copy(obj.data.materials[0].raytrace_mirror.reflect_factor))
+ a.append(copy(obj.data.materials[0].raytrace_mirror.fresnel))
+ a.append(copy(obj.data.materials[0].raytrace_mirror.fresnel_factor))
+ a.append(copy(obj.data.materials[0].mirror_color))
+ a.append(copy(obj.data.materials[0].raytrace_mirror.depth))
+ a.append(copy(obj.data.materials[0].raytrace_mirror.gloss_factor))
+
+ # tenho todos os objetos em a[]
+ # incrementar um frame e checar se eh igual
+ bpy.context.scene.frame_set(bpy.context.scene.frame_current + 1)
+
+ j=0
+ dif=0
+ for obj in bpy.data.objects:
+ if chkLocRotSc:
+ if a[j]!= obj.location or a[j+1]!= obj.rotation_euler or a[j+2]!= obj.scale:
+ dif=1
+ #break
+ j+=3
+
+ if hasattr(obj.data, 'materials') and obj.data.materials.keys()!=[] :
+ if bpy.context.scene.render.engine == "BLENDER_RENDER":
+ if chkMatBas:
+ # cores
+ if a[j]!= obj.data.materials[0].type or a[j+1]!= obj.data.materials[0].emit or \
+ a[j+2]!= obj.data.materials[0].diffuse_color or \
+ a[j+3]!= obj.data.materials[0].diffuse_intensity or \
+ a[j+4]!= obj.data.materials[0].specular_intensity or \
+ a[j+5]!= obj.data.materials[0].specular_color or \
+ a[j+6]!= obj.data.materials[0].alpha or \
+ a[j+7]!= obj.data.materials[0].diffuse_shader or \
+ a[j+8]!= obj.data.materials[0].specular_shader or \
+ a[j+9]!= obj.data.materials[0].specular_hardness:
+ dif=1
+ print("mat")
+ j+= 10 # ajusta ponteiro j
+ if chkMatTransp: j+=8
+ if chkMatMirror: j+=6
+ break
+ j+=10
+
+ if chkMatTransp:
+ #transp
+ if a[j]!= obj.data.materials[0].transparency_method or a[j+1]!= obj.data.materials[0].specular_alpha or \
+ a[j+2]!= obj.data.materials[0].raytrace_transparency.fresnel or \
+ a[j+3]!= obj.data.materials[0].raytrace_transparency.ior or \
+ a[j+4]!= obj.data.materials[0].raytrace_transparency.filter or \
+ a[j+5]!= obj.data.materials[0].raytrace_transparency.depth or \
+ a[j+6]!= obj.data.materials[0].translucency or \
+ a[j+7]!= obj.data.materials[0].specular_alpha:
+ dif=1
+ j+= 8 # ajusta ponteiro j
+ if chkMatMirror: j+=6
+
+ break
+ j+=8
+
+ if chkMatMirror:
+ #mirror
+ if a[j]!= obj.data.materials[0].raytrace_mirror.reflect_factor or a[j+1]!= obj.data.materials[0].raytrace_mirror.fresnel or \
+ a[j+2]!= obj.data.materials[0].raytrace_mirror.fresnel_factor or \
+ a[j+3]!= obj.data.materials[0].mirror_color or \
+ a[j+4]!= obj.data.materials[0].raytrace_mirror.depth or \
+ a[j+5]!= obj.data.materials[0].raytrace_mirror.gloss_factor:
+ dif=1
+ j+= 6 # ajusta ponteiro j
+ break
+ j+=6
+ # finaliza
+ if dif==0:
+ obc.Frames_Pular+=1
+ else:
+ obc.Frames_Renderizar+=1
+ ToRender.append(bpy.context.scene.frame_current)
+
+ del a
+ # para nao sair do index - nunca chega nesse frame
+ ToRender.append(bpy.context.scene.frame_end+1)
+
+ if obc.RunFrom+loop < RunMax:
+ context.scene.imp_sound_to_anim.Info_check_smartrender= "["+str(obc.RunFrom+loop) + "/" + \
+ str(RunMax) + "] Frames to Render= " + str(obc.Frames_Renderizar) + \
+ " -> Reduction " + str(round((obc.Frames_Pular/RunMax)*100,1)) + "%"
+ else:
+ context.scene.imp_sound_to_anim.Info_check_smartrender= "Frames to Render= " + str(obc.Frames_Renderizar) + \
+ " -> Reduction " + str(round((obc.Frames_Pular/RunMax)*100,1)) + "%"
+
+ #incrementa indice
+ obc.RunFrom+= loop
+ return (ToRender, obc.RunFrom)
+
+ def execute(self, context):
+ context.scene.imp_sound_to_anim.Working= "CheckSmartRender"
+ #context.scene.imp_sound_to_anim.timer_reset_func=True
+ bpy.ops.wm.modal_timer_operator()
+ #CheckSmartRender(context)
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+
+#
+#==================================================================================================
+# Button - Smart Render
+#==================================================================================================
+#
+class OBJECT_OT_Botao_SmartRender(bpy.types.Operator):
+ '''Render Only Modified Frames and Copy the Others'''
+ bl_idname = "import.sound_animation_smart_render"
+ bl_label = "Smart Render"
+
+ BaseRenderToCopy=0
+
+ def SmartRender(context):
+ obs=OBJECT_OT_Botao_SmartRender
+
+ index=0
+ pad=4
+ #calcula zero pad
+ if bpy.context.scene.frame_end //1000000 > 0: #default 999999 1000000//1000000=1
+ pad=7
+ elif bpy.context.scene.frame_end //100000 > 0: #default 99999 100000//100000=1
+ pad=6
+ elif bpy.context.scene.frame_end //10000 > 0: #default 9999 10000//10000=1
+ pad=5
+
+ #bpy.data.images['Render Result'].file_format ='PNG'
+ bpy.context.scene.render.image_settings.file_format = 'PNG'
+
+ #info dos arquivos
+ path= bpy.context.scene.render.filepath
+
+ import shutil
+
+ tot=bpy.context.scene.frame_end - bpy.context.scene.frame_start+1
+ i=0
+ # checa apenas 1 frame o indice é interno em ChackSmartRender
+ r= OBJECT_OT_Botao_Check_SmartRender.CheckSmartRender(context, 1)
+ ToRender= r[0] # tem numero do frame se for para renderizar
+ index= r[1]
+
+ #copia frame atual #se o frame ja não foi renderizado
+ if (obs.BaseRenderToCopy!=(index+bpy.context.scene.frame_start-1)) and index > 1: #index!=1 and index !=0:
+ print("Copying: " + str(obs.BaseRenderToCopy) + "-> " + str(index+bpy.context.scene.frame_start-1) + \
+ " To " + path + str(index+bpy.context.scene.frame_start-1).zfill(pad) + ".png")
+ shutil.copy2(path + str(obs.BaseRenderToCopy).zfill(pad) + ".png", path + \
+ str(index+bpy.context.scene.frame_start-1).zfill(pad) + ".png")
+
+ if ToRender.__len__()>1: #renderizar 1 item em ToRender nao renderiza, (sempre vem com no minimo 1)
+ if index==1:
+ print("================================================================")
+ from time import strftime
+ print(strftime("Running Smart Render: %H:%M:%S"))
+ print("================================================================")
+ BaseRenderToCopy=0
+
+ if ToRender[0] <= bpy.context.scene.frame_end:
+ #renderiza proximo frame
+ print("Rendering-> " + str(ToRender[0]))
+ obs.BaseRenderToCopy= ToRender[0]
+ bpy.ops.render.render(animation=False, write_still=False)
+ bpy.data.images['Render Result'].save_render(filepath=path + str(ToRender[0]).zfill(pad) + ".png")
+ i+=1
+
+ if index==tot:
+ print("================================================================")
+ from time import strftime
+ print(strftime("Finish Render: %H:%M:%S"))
+ print("================================================================")
+ print(".")
+
+ if index==tot+1:
+ obs.BaseRenderToCopy=0
+ return 0
+
+ return index
+
+
+ def execute(self, context):
+ # se for CYCLES, nao funciona com timer, preciso rodar direto
+ context.scene.imp_sound_to_anim.Working= "SmartRender"
+ bpy.ops.wm.modal_timer_operator()
+ #SmartRender(context)
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+
+
+#
+#==================================================================================================
+# Button - Cancel
+#==================================================================================================
+#
+class OBJECT_OT_Botao_Cancel(bpy.types.Operator):
+ '''Cancel Actual Operation'''
+ bl_idname = "import.sound_animation_botao_cancel"
+ bl_label = "CANCEL"
+
+ def execute(self, context):
+ context.scene.imp_sound_to_anim.cancel_button_hit=True
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+
+#
+#==================================================================================================
+# TIMER - controla a execucao das funcoes
+# Responsavel por rodar em partes usando o timer e possibilitando
+# o cancelamento e textos informativos
+#==================================================================================================
+#
+class ModalTimerOperator(bpy.types.Operator):
+ """Internal Script Control"""
+ bl_idname = "wm.modal_timer_operator"
+ bl_label = "Internal Script Control"
+
+ _timer = None
+ Running= False
+
+ def CheckRunStop(self, context, func, index):
+ # forca update do UI
+ bpy.context.scene.frame_set(bpy.context.scene.frame_current)
+ if index!=0:
+ #configura timer para a funcao
+ context.scene.imp_sound_to_anim.Working= func
+ self.Running=True
+ return {'PASS_THROUGH'}
+ else: # posso desligar o timer e modal
+ if self._timer!= None:
+ context.window_manager.event_timer_remove(self._timer)
+ self._timer= None
+ return {'FINISHED'}
+
+
+ def modal(self, context, event):
+ if event.type == 'ESC'and self.Running:
+ print("-- ESC Pressed --")
+ self.cancel(context)
+ context.scene.imp_sound_to_anim.Working=""
+ self.Running=False
+ #reseta contadores
+ context.scene.imp_sound_to_anim.timer_reset_func=True
+ # forca update do UI
+ bpy.context.scene.frame_set(bpy.context.scene.frame_current)
+ return {'CANCELLED'}
+
+ if event.type == 'TIMER':
+ #print("timer")
+ #CheckSmartRender
+ if context.scene.imp_sound_to_anim.Working== "CheckSmartRender":
+ self.parar(context)
+ #5= frames para rodar antes de voltar [1]= indice de posicao atual
+ index= OBJECT_OT_Botao_Check_SmartRender.CheckSmartRender(context, 5)[1]
+ return self.CheckRunStop(context, "CheckSmartRender", index)
+
+ #SmartRender
+ elif context.scene.imp_sound_to_anim.Working== "SmartRender":
+ self.parar(context)
+ #render/copia 1 e volta index>=0 indice posicao atual
+ index= OBJECT_OT_Botao_SmartRender.SmartRender(context)
+ return self.CheckRunStop(context, "SmartRender", index)
+
+ #ProcessaSom
+ elif context.scene.imp_sound_to_anim.Working== "ProcessaSom":
+ self.parar(context)
+ # loop = numero de frames de audio index=0 se terminou ou >0 se não acabou
+ index= OBJECT_OT_Botao_Go.ProcessaSom(context, 50)
+ return self.CheckRunStop(context, "ProcessaSom", index)
+
+ #wavimport(context)
+ elif context.scene.imp_sound_to_anim.Working== "wavimport":
+ self.parar(context)
+ # 5= numero de frames to import por timer
+ index=OBJECT_OT_Botao_Import.wavimport(context, 50)
+ return self.CheckRunStop(context, "wavimport", index)
+
+ #passa por aqui quando as funcoes estao sendo executadas mas
+ #configuradas para nao entrar porque context.scene.imp_sound_to_anim.Working== ""
+ return {'PASS_THROUGH'}
+
+ # reseta e para tudo botao CANCEL pressionado
+ if context.scene.imp_sound_to_anim.cancel_button_hit==True:
+ context.scene.imp_sound_to_anim.Working=""
+ #pede reset contadores
+ context.scene.imp_sound_to_anim.timer_reset_func=True
+ if self._timer!= None:
+ context.window_manager.event_timer_remove(self._timer)
+ self._timer= None
+ print("-- Cancel Pressed --")
+ context.scene.imp_sound_to_anim.cancel_button_hit=False
+ return {'FINISHED'}
+
+ #print("modal")
+
+ # se o timer esta ativado, continua, (senao termina).
+ # desligar a chamada ao modal se caso chegar aqui (nao deveria)
+ if self._timer!= None:
+ return{'PASS_THROUGH'}
+ else:
+ return {'FINISHED'}
+
+ def execute(self, context):
+ if self._timer==None:
+ self._timer = context.window_manager.event_timer_add(0.2, context.window)
+ context.window_manager.modal_handler_add(self)
+ #para deixar rodar sem deligar o timer
+ context.scene.imp_sound_to_anim.timer_desligar=False
+ self.Running=True
+ return {'RUNNING_MODAL'}
+
+ def cancel(self, context):
+ if self._timer!= None:
+ context.window_manager.event_timer_remove(self._timer)
+ self._timer= None
+ return {'CANCELLED'}
+
+ def parar(self, context):
+ if self.Running:
+ context.scene.imp_sound_to_anim.Working=""
+ self.Running=False
+
+
+
+#
+#==================================================================================================
+# Register - Unregister - MAIN
+#==================================================================================================
+#
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.imp_sound_to_anim = PointerProperty(type=ImpSoundtoAnim, name="Import: Sound to Animation", description="Extract movement from sound file. See the Object Panel at the end.")
+ bpy.types.INFO_MT_file_import.append(WavFileImport)
+
+def unregister():
+
+ try:
+ bpy.utils.unregister_module(__name__)
+ except:
+ pass
+
+ try:
+ bpy.types.INFO_MT_file_import.remove(WavFileImport)
+ except:
+ pass
+
+
+
+if __name__ == "__main__":
+ register()
+
+
+
+
diff --git a/release/scripts/addons_contrib/io_import_voodoo_camera.py b/release/scripts/addons_contrib/io_import_voodoo_camera.py
new file mode 100644
index 0000000..3a45982
--- /dev/null
+++ b/release/scripts/addons_contrib/io_import_voodoo_camera.py
@@ -0,0 +1,331 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Import Voodoo camera",
+ "author": "Fazekas Laszlo",
+ "version": (0, 8),
+ "blender": (2, 63, 0),
+ "location": "File > Import > Voodoo camera",
+ "description": "Imports a Blender (2.4x or 2.5x) Python script from the Voodoo (version 1.1 or 1.2) camera tracker software.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Import-Export/Voodoo_camera",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=22510",
+ "category": "Import-Export"}
+
+"""
+This script loads a Blender Python script from the Voodoo camera
+tracker program into Blender 2.5x+.
+
+It processes the script as a text file and not as a Python executable
+because of the incompatible Python APIs of Blender 2.4x/2.5x/2.6x.
+"""
+
+import bpy
+from bpy.props import *
+import mathutils
+import os
+import string
+import math
+
+def voodoo_import(infile,ld_cam,ld_points):
+
+ checktype = os.path.splitext(infile)[1]
+
+ if checktype.upper() != '.PY':
+ print ("Selected file: ",infile)
+ raise IOError("The selected input file is not a *.py file")
+ return
+
+ print ("--------------------------------------------------")
+ print ("Importing Voodoo file: ", infile)
+
+ file = open(infile,'rU')
+ scene = bpy.context.scene
+ initfr = scene.frame_current
+ b24= True
+ voodoo_import.frwas= False
+
+ dummy = bpy.data.objects.new('voodoo_scene', None)
+ dummy.location = (0.0, 0.0, 0.0)
+ dummy.rotation_euler = ( -3.141593/2, 0.0, 0.0)
+ dummy.scale = (0.2, 0.2, 0.2)
+ scene.objects.link(dummy)
+
+ if ld_cam:
+ data = bpy.data.cameras.new('voodoo_render_cam')
+ data.lens_unit= 'DEGREES'
+ vcam = bpy.data.objects.new('voodoo_render_cam', data)
+ vcam.location = (0.0, 0.0, 0.0)
+ vcam.rotation_euler = (0.0, 0.0, 0.0)
+ vcam.scale = (1.0, 1.0, 1.0)
+ data.lens = 35.0
+ data.shift_x = 0.0
+ data.shift_y = 0.0
+ data.dof_distance = 0.0
+ data.clip_start = 0.1
+ data.clip_end = 1000.0
+ data.draw_size = 0.5
+ scene.objects.link(vcam)
+ vcam.parent = dummy
+
+ if ld_points:
+ data = bpy.data.meshes.new('voodoo_FP3D_cloud')
+ mesh = bpy.data.objects.new('voodoo_FP3D_cloud', data)
+ mesh.location = (0.0, 0.0, 0.0)
+ # before 6.3
+ # mesh.rotation_euler = (3.141593/2, 0.0, 0.0)
+ # mesh.scale = (5.0, 5.0, 5.0)
+ mesh.rotation_euler = (0.0, 0.0, 0.0)
+ mesh.scale = (1.0, 1.0, 1.0)
+ scene.objects.link(mesh)
+ mesh.parent = dummy
+
+ verts = []
+
+ def stri(s):
+ try:
+ ret= int(s,10)
+
+ except ValueError :
+ ret= -1
+
+ return ret
+
+ def process_line(line):
+ lineSplit = line.split()
+
+ if (len(lineSplit) < 1): return
+
+ if (line[0] == '#'): return
+
+ if b24:
+
+ # Blender 2.4x mode
+ # process camera commands
+
+ if ld_cam:
+ if (line[0] == 'c' and line[1] != 'r'):
+ pos= line.find('.lens')
+
+ if (pos != -1):
+ fr = stri(lineSplit[0][1:pos])
+
+ if (fr >= 0):
+ scene.frame_current = fr
+ vcam.data.lens= float(lineSplit[2])
+ vcam.data.keyframe_insert('lens')
+ return
+
+ if (line[0] == 'o'):
+ pos= line.find('.setMatrix')
+
+ if (pos != -1):
+ fr = stri(lineSplit[0][1:pos])
+
+ if (fr >= 0):
+ scene.frame_current = fr
+ # for up to 2.55
+ # vcam.matrix_world = eval('mathutils.' + line.rstrip()[pos+21:-1])
+ # for 2.56, from Michael (Meikel) Oetjen
+ # vcam.matrix_world = eval('mathutils.Matrix(' + line.rstrip()[pos+28:-2].replace('[','(',4).replace(']',')',4) + ')')
+ # for 2.57
+ # vcam.matrix_world = eval('mathutils.Matrix([' + line.rstrip()[pos+28:-2] + '])')
+ # for 2.63
+ vcam.matrix_world = eval('(' + line.rstrip()[pos+27:-1] + ')')
+ vcam.keyframe_insert('location')
+ vcam.keyframe_insert('scale')
+ vcam.keyframe_insert('rotation_euler')
+ return
+
+ # process mesh commands
+
+ if ld_points:
+ if (line[0] == 'v'):
+ pos= line.find('NMesh.Vert')
+
+ if (pos != -1):
+ verts.append(eval(line[pos+10:]))
+
+ return
+
+ # Blender 2.5x mode
+ # process camera commands
+
+ if ld_cam:
+ pos= line.find('set_frame')
+
+ if (pos == -1):
+ pos= line.find('frame_set')
+
+ if (pos == -1):
+ pos= lineSplit[0].find('frame_current')
+
+ if (pos != -1):
+ fr= stri(lineSplit[2])
+
+ if (fr >= 0):
+ scene.frame_current = fr
+ voodoo_import.frwas= True
+
+ return
+
+ if (pos != -1):
+ fr= stri(line[pos+10:-2])
+
+ if (fr >= 0):
+ scene.frame_current = fr
+ voodoo_import.frwas= True
+ return
+
+ if voodoo_import.frwas:
+
+ pos= line.find('data.lens')
+
+ if (pos != -1):
+ vcam.data.lens= float(lineSplit[2])
+ vcam.data.keyframe_insert('lens')
+ return
+
+ pos= line.find('.Matrix')
+
+ if (pos != -1):
+
+ # for up to 2.55
+ # vcam.matrix_world = eval('mathutils' + line[pos:])
+
+ # for 2.56
+ # if (line[pos+8] == '['):
+ # # from Michael (Meikel) Oetjen
+ # vcam.matrix_world = eval('mathutils.Matrix((' + line.rstrip()[pos+9:-1].replace('[','(',3).replace(']',')',4) + ')')
+ # else:
+ # vcam.matrix_world = eval('mathutils' + line[pos:])
+
+ # for 2.57
+ # vcam.matrix_world = eval('mathutils.Matrix([' + line.rstrip()[pos+8:-1] + '])')
+
+ # for 2.63
+ vcam.matrix_world = eval('(' + line.rstrip()[pos+7:] + ')')
+ return
+
+ pos= line.find('.matrix_world')
+
+ if (pos != -1):
+ vcam.matrix_world = eval(line.rstrip()[line.find('=')+1:])
+ return
+
+ pos= line.find('.location')
+
+ if (pos != -1):
+ vcam.location = eval(line[line.find('=')+1:])
+ return
+
+ pos= line.find('.rotation_euler')
+
+ if (pos != -1):
+ vcam.rotation_euler = eval(line[line.find('=')+1:])
+ return
+
+ pos= line.find('.data.keyframe_insert')
+
+ if (pos != -1):
+ vcam.data.keyframe_insert(eval(line[pos+22:-2]))
+ return
+
+ pos= line.find('.keyframe_insert')
+
+ if (pos != -1):
+ vcam.keyframe_insert(eval(line[pos+17:-2]))
+ return
+
+ # process mesh commands
+
+ if ld_points:
+ pos= line.find('.append')
+
+ if (pos != -1):
+ verts.append(eval(line[pos+8:-2]))
+
+ #read lines
+
+ for line in file.readlines():
+
+ if (b24 and (line.find('import') != -1) and (line.find('bpy') != -1)):
+ b24= False
+
+ process_line(line)
+
+ scene.frame_set(initfr)
+
+ if ld_points:
+ mesh.data.from_pydata(verts, [], [])
+
+ mesh.data.update()
+
+
+# Operator
+class ImportVoodooCamera(bpy.types.Operator):
+ """"""
+ bl_idname = "import.voodoo_camera"
+ bl_label = "Import Voodoo camera"
+ bl_description = "Load a Blender export script from the Voodoo motion tracker"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ filepath = StringProperty(name="File Path",
+ description="Filepath used for processing the script",
+ maxlen= 1024,default= "")
+
+ # filter_python = BoolProperty(name="Filter python",
+ # description="",default=True,options={'HIDDEN'})
+
+ load_camera = BoolProperty(name="Load camera",
+ description="Load the camera",
+ default=True)
+ load_points = BoolProperty(name="Load points",
+ description="Load the FP3D point cloud",
+ default=True)
+
+ def execute(self, context):
+ voodoo_import(self.filepath,self.load_camera,self.load_points)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+
+# Registering / Unregister
+def menu_func(self, context):
+ self.layout.operator(ImportVoodooCamera.bl_idname, text="Voodoo camera", icon='PLUGIN')
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_file_import.append(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_file_import.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_mesh_gwyddion/__init__.py b/release/scripts/addons_contrib/io_mesh_gwyddion/__init__.py
new file mode 100644
index 0000000..1cb6fa9
--- /dev/null
+++ b/release/scripts/addons_contrib/io_mesh_gwyddion/__init__.py
@@ -0,0 +1,184 @@
+# ##### 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 LICENSE BLOCK #####
+
+#
+#
+# Authors : Clemens Barth (Blendphys at root-1.de), ...
+#
+# Homepage : http://development.root-1.de/Atomic_Blender.php
+#
+# Start of project : 2012-11-12 by Clemens Barth
+# First publication in Blender : 2012-11-19
+# Last modified : 2012-11-19
+#
+# Acknowledgements
+# ================
+#
+# Other: Frank Palmino
+#
+
+bl_info = {
+ "name": "Atomic Blender - Gwyddion",
+ "description": "Loading Gwyddion Atomic Force Microscopy images",
+ "author": "Clemens Barth",
+ "version": (0, 1),
+ "blender": (2, 60, 0),
+ "location": "File -> Import -> Gwyddion (.gwy)",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Import-Export/Gwyddion",
+ "tracker_url": "http://projects.blender.org/tracker/"
+ "index.php?func=detail&aid=33236&group_id=153&atid=469",
+ "category": "Import-Export"
+}
+
+import bpy
+from bpy.types import Operator
+from bpy_extras.io_utils import ImportHelper
+from bpy.props import (BoolProperty,
+ StringProperty,
+ EnumProperty,
+ FloatProperty)
+
+from . import import_gwyddion
+
+# -----------------------------------------------------------------------------
+# GUI
+
+# This is the class for the file dialog of the importer.
+class ImportGwyddion(Operator, ImportHelper):
+ bl_idname = "import_mesh.gwy"
+ bl_label = "Import Gwyddion (*.gwy)"
+ bl_options = {'PRESET', 'UNDO'}
+
+ filename_ext = ".gwy"
+ filter_glob = StringProperty(default="*.gwy", options={'HIDDEN'},)
+
+ use_camera = BoolProperty(
+ name="Camera", default=False,
+ description="Do you need a camera?")
+ use_lamp = BoolProperty(
+ name="Lamp", default=False,
+ description = "Do you need a lamp?")
+ use_smooth = BoolProperty(
+ name="Smooth image data", default=False,
+ description = "Smooth the images")
+ scale_size = FloatProperty (
+ name = "Scale xy", default=0.5,
+ description = "Scale the lateral size")
+ scale_height = FloatProperty (
+ name = "Scale h", default=3.0,
+ description = "Scale the height")
+ use_all_channels = BoolProperty(
+ name="All channels", default=False,
+ description = "Load all images")
+ use_c1 = BoolProperty(
+ name="1", default=True,
+ description = "Channel 1")
+ use_c2 = BoolProperty(
+ name="2", default=False,
+ description = "Channel 2")
+ use_c3 = BoolProperty(
+ name="3", default=False,
+ description = "Channel 3")
+ use_c4 = BoolProperty(
+ name="4", default=False,
+ description = "Channel 4")
+ use_c5 = BoolProperty(
+ name="5", default=False,
+ description = "Channel 5")
+ use_c6 = BoolProperty(
+ name="6", default=False,
+ description = "Channel 6")
+ use_c7 = BoolProperty(
+ name="7", default=False,
+ description = "Channel 7")
+ use_c8 = BoolProperty(
+ name="8", default=False,
+ description = "Channel 8")
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row.prop(self, "use_camera")
+ row.prop(self, "use_lamp")
+ row = layout.row()
+ row.prop(self, "use_smooth")
+ row = layout.row()
+ row.prop(self, "scale_size")
+ row.prop(self, "scale_height")
+ row = layout.row()
+ row.label(text="Channels")
+ row.prop(self, "use_all_channels")
+ row = layout.row()
+ row.prop(self, "use_c1")
+ row.prop(self, "use_c2")
+ row.prop(self, "use_c3")
+ row.prop(self, "use_c4")
+ row = layout.row()
+ row.prop(self, "use_c5")
+ row.prop(self, "use_c6")
+ row.prop(self, "use_c7")
+ row.prop(self, "use_c8")
+
+ if self.use_all_channels:
+ self.use_c1, self.use_c2, self.use_c3, self.use_c4, \
+ self.use_c5, self.use_c6, self.use_c7, self.use_c8 \
+ = True, True, True, True, True, True, True, True
+
+ def execute(self, context):
+ # This is in order to solve this strange 'relative path' thing.
+ filepath_par = bpy.path.abspath(self.filepath)
+
+ channels = [self.use_c1, self.use_c2, self.use_c3, self.use_c4,
+ self.use_c5, self.use_c6, self.use_c7, self.use_c8]
+
+ # Execute main routine
+ #print("passed - 1")
+ images, AFMdata = import_gwyddion.load_gwyddion_images(filepath_par,
+ channels)
+
+ #print("passed - 3")
+ import_gwyddion.create_mesh(images,
+ AFMdata,
+ self.use_smooth,
+ self.scale_size,
+ self.scale_height,
+ self.use_camera,
+ self.use_lamp)
+ #print("passed - 4")
+
+ return {'FINISHED'}
+
+
+# The entry into the menu 'file -> import'
+def menu_func_import(self, context):
+ self.layout.operator(ImportGwyddion.bl_idname, text="Gwyddion (.gwy)")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+
+if __name__ == "__main__":
+
+ register()
diff --git a/release/scripts/addons_contrib/io_mesh_gwyddion/import_gwyddion.py b/release/scripts/addons_contrib/io_mesh_gwyddion/import_gwyddion.py
new file mode 100644
index 0000000..896a3f3
--- /dev/null
+++ b/release/scripts/addons_contrib/io_mesh_gwyddion/import_gwyddion.py
@@ -0,0 +1,309 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+import os
+import re
+from math import pi, sqrt
+from mathutils import Vector, Matrix
+import struct
+
+# All data for the images. Basically, each variable is a list with a length,
+# which equals the number of images.
+# Some of the variables are still not used. However, I keep them for purposes
+# in future.
+class AFMData(object):
+ def __init__(self, date, x_size, y_size, x_pixel, y_pixel, x_off, y_off,
+ voltage, feedback, gain, speed, amplitude, angle, datfile,
+ channel, unit, z_factor, spec_x_unit, spec_x_label, spec_y_unit,
+ spec_y_label, spec_y_factor, spec_points, spec_feedback,
+ spec_acquisition, spec_delay):
+ self.date = date
+ self.x_size = x_size
+ self.y_size = y_size
+ self.x_pixel = x_pixel
+ self.y_pixel = y_pixel
+ self.x_off = x_off
+ self.y_off = y_off
+ self.voltage = voltage
+ self.feedback = feedback
+ self.gain = gain
+ self.speed = speed
+ self.amplitude = amplitude
+ self.angle = angle
+ self.datfile = datfile
+ self.channel = channel
+ self.unit = unit
+ self.z_factor = z_factor
+ self.spec_x_unit = spec_x_unit
+ self.spec_x_label = spec_x_label
+ self.spec_y_unit = spec_y_unit
+ self.spec_y_label = spec_y_label
+ self.spec_y_factor = spec_y_factor
+ self.spec_points = spec_points
+ self.spec_feedback = spec_feedback
+ self.spec_acquisition = spec_acquisition
+ self.spec_delay = spec_delay
+
+
+# For loading the Gwyddion images. I basically have followed rules described
+# here: http://gwyddion.net/documentation/user-guide-en/gwyfile-format.html
+def load_gwyddion_images(data_file, channels):
+
+ if not os.path.isfile(data_file):
+ return False
+
+ AFMdata = AFMData([],[],[],[],[],[],[],
+ [],[],[],[],[],[],[],
+ [],[],[],[],[],[],[],
+ [],[],[],[],[])
+ AFMdata.datfile = data_file
+
+ datafile = open(data_file, 'rb')
+ data = datafile.read()
+ datafile.close()
+
+ # Search the title of each image
+ for a in list(re.finditer(b"data/title\x00", data)):
+
+ pos = a.start()
+ channel_number = int(data[pos-2:pos-1])
+
+ if channels[channel_number] == False:
+ continue
+
+ pos1 = data[pos:].find(b"\x00") + pos + len("\x00") + 1
+ pos2 = data[pos1:].find(b"\x00") + pos1
+
+ channel_name = data[pos1:pos2].decode("utf-8")
+
+ AFMdata.channel.append([channel_number, channel_name])
+
+ # Search important parameters and finally the image data.
+ images = []
+ for a in list(re.finditer(b"/data\x00", data)):
+
+ pos = a.start()
+
+ channel_number = int(data[pos-1:pos])
+
+ if channels[channel_number] == False:
+ continue
+
+ # Find the image size in pixel (x direction)
+ pos1 = data[pos:].find(b"xres") + pos+len("xres")
+ size_x_pixel = struct.unpack("i",data[pos1+2:pos1+4+2])[0]
+
+ # ... the image size in pixel (y direction)
+ pos1 = data[pos:].find(b"yres") + pos+len("yres")
+ size_y_pixel = struct.unpack("i",data[pos1+2:pos1+4+2])[0]
+
+ # ... the real image size (x direction)
+ pos1 = data[pos:].find(b"xreal") + pos+len("xreal")
+ size_x_real = struct.unpack("d",data[pos1+2:pos1+8+2])[0]
+
+ # ... the real image size (y direction)
+ pos1 = data[pos:].find(b"yreal") + pos+len("yreal")
+ size_y_real = struct.unpack("d",data[pos1+2:pos1+8+2])[0]
+
+ # If it is a z image, multiply with 10^9 nm
+ factor = 1.0
+ pos1 = data[pos:].find(b"si_unit_z") + pos
+ unit = data[pos1+34:pos1+36].decode("utf-8")
+ if "m" in unit:
+ factor = 1000000000.0
+
+ # Now, find the image data and store it
+ pos1 = data[pos:].find(b"\x00data\x00") + pos + len("\x00data\x00") + 5
+
+ image = []
+ for i in range(size_y_pixel):
+ line = []
+ for j in range(size_x_pixel):
+ # The '8' is for the double values
+ k = pos1 + (i*size_x_pixel+j) * 8
+ l = pos1 + (i*size_x_pixel+j+1) * 8
+ line.append(struct.unpack("d",data[k:l])[0]*factor)
+ image.append(line)
+
+ images.append(image)
+
+ # Note all parameters of the image.
+ AFMdata.x_pixel.append(int(size_x_pixel))
+ AFMdata.y_pixel.append(int(size_y_pixel))
+ AFMdata.x_size.append(size_x_real * 1000000000.0)
+ AFMdata.y_size.append(size_y_real * 1000000000.0)
+
+ return (images, AFMdata)
+
+# Routine to create the mesh and finally the image
+def create_mesh(data_list,
+ AFMdata,
+ use_smooth,
+ scale_size,
+ scale_height,
+ use_camera,
+ use_lamp):
+ # This is for the image name.
+ path_list = AFMdata.datfile.strip('/').split('/')
+
+ number_img = len(data_list)
+ image_x_offset_gap = 10.0 * scale_size
+ image_x_all = sum(AFMdata.x_size)*scale_size
+ image_x_offset = -(image_x_all+image_x_offset_gap*(number_img-1)) / 2.0
+
+ # For each image do:
+ for k, data in enumerate(data_list):
+
+ size_x = AFMdata.x_pixel[k]
+ size_y = AFMdata.y_pixel[k]
+
+ image_scale = AFMdata.x_size[k] / float(AFMdata.x_pixel[k])
+ image_scale = image_scale * scale_size
+ image_x_size = AFMdata.x_size[k] * scale_size
+ image_x_offset += image_x_size / 2.0
+
+ image_name = path_list[-1] + "_" + AFMdata.channel[k][1]
+
+ data_mesh = []
+ data_faces = []
+
+ #print("passed - create_mesh ---- 1")
+
+ for i, line in enumerate(data):
+ for j, pixel in enumerate(line):
+
+ # The vertices
+ data_mesh.append(Vector((float(i) * image_scale,
+ float(j) * image_scale,
+ float(pixel)*scale_height)))
+
+ # The faces
+ if i < size_y-1 and j < size_x-1:
+ data_faces.append( [size_x*i+j , size_x*(i+1)+j,
+ size_x*(i+1)+j+1, size_x*i+j+1 ])
+
+ #print("passed - create_mesh ---- 2")
+
+ # Build the mesh
+ surface_mesh = bpy.data.meshes.new("Mesh")
+ surface_mesh.from_pydata(data_mesh, [], data_faces)
+ surface_mesh.update()
+ surface = bpy.data.objects.new(image_name, surface_mesh)
+ bpy.context.scene.objects.link(surface)
+ bpy.ops.object.select_all(action='DESELECT')
+ surface.select = True
+
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+ # sum((v.co for v in mesh.vertices), Vector()) / len(mesh.vertices)
+
+ if use_smooth:
+ for polygon in surface.data.polygons:
+ polygon.use_smooth = True
+
+ surface.location = Vector((0.0, image_x_offset, 0.0))
+ image_x_offset += image_x_size / 2.0 + image_x_offset_gap
+
+ #print("passed - create_mesh ---- 3")
+
+
+
+ object_center_vec = Vector((0.0,0.0,0.0))
+ object_size = (sum(AFMdata.x_size) * scale_size
+ +image_x_offset_gap * (len(data_list)-1))
+
+ # ------------------------------------------------------------------------
+ # CAMERA AND LAMP
+ camera_factor = 20.0
+
+ # If chosen a camera is put into the scene.
+ if use_camera == True:
+
+ # Assume that the object is put into the global origin. Then, the
+ # camera is moved in x and z direction, not in y. The object has its
+ # size at distance sqrt(object_size) from the origin. So, move the
+ # camera by this distance times a factor of camera_factor in x and z.
+ # Then add x, y and z of the origin of the object.
+ object_camera_vec = Vector((sqrt(object_size) * camera_factor,
+ 0.0,
+ sqrt(object_size) * camera_factor))
+ camera_xyz_vec = object_center_vec + object_camera_vec
+
+ # Create the camera
+ current_layers=bpy.context.scene.layers
+ camera_data = bpy.data.cameras.new("A_camera")
+ camera_data.lens = 45
+ camera_data.clip_end = 50000.0
+ camera = bpy.data.objects.new("A_camera", camera_data)
+ camera.location = camera_xyz_vec
+ camera.layers = current_layers
+ bpy.context.scene.objects.link(camera)
+
+ # Here the camera is rotated such it looks towards the center of
+ # the object. The [0.0, 0.0, 1.0] vector along the z axis
+ z_axis_vec = Vector((0.0, 0.0, 1.0))
+ # The angle between the last two vectors
+ angle = object_camera_vec.angle(z_axis_vec, 0)
+ # The cross-product of z_axis_vec and object_camera_vec
+ axis_vec = z_axis_vec.cross(object_camera_vec)
+ # Rotate 'axis_vec' by 'angle' and convert this to euler parameters.
+ # 4 is the size of the matrix.
+ camera.rotation_euler = Matrix.Rotation(angle, 4, axis_vec).to_euler()
+
+ # Rotate the camera around its axis by 90° such that we have a nice
+ # camera position and view onto the object.
+ bpy.ops.object.select_all(action='DESELECT')
+ camera.select = True
+ bpy.ops.transform.rotate(value=(90.0*2*pi/360.0),
+ axis=object_camera_vec,
+ constraint_axis=(False, False, False),
+ constraint_orientation='GLOBAL',
+ mirror=False, proportional='DISABLED',
+ proportional_edit_falloff='SMOOTH',
+ proportional_size=1, snap=False,
+ snap_target='CLOSEST', snap_point=(0, 0, 0),
+ snap_align=False, snap_normal=(0, 0, 0),
+ release_confirm=False)
+
+ # Here a lamp is put into the scene, if chosen.
+ if use_lamp == True:
+
+ # This is the distance from the object measured in terms of %
+ # of the camera distance. It is set onto 50% (1/2) distance.
+ lamp_dl = sqrt(object_size) * 15 * 0.5
+ # This is a factor to which extend the lamp shall go to the right
+ # (from the camera point of view).
+ lamp_dy_right = lamp_dl * (3.0/4.0)
+
+ # Create x, y and z for the lamp.
+ object_lamp_vec = Vector((lamp_dl,lamp_dy_right,lamp_dl))
+ lamp_xyz_vec = object_center_vec + object_lamp_vec
+
+ # Create the lamp
+ current_layers=bpy.context.scene.layers
+ lamp_data = bpy.data.lamps.new(name="A_lamp", type="POINT")
+ lamp_data.distance = 5000.0
+ lamp_data.energy = 3.0
+ lamp_data.shadow_method = 'RAY_SHADOW'
+ lamp = bpy.data.objects.new("A_lamp", lamp_data)
+ lamp.location = lamp_xyz_vec
+ lamp.layers = current_layers
+ bpy.context.scene.objects.link(lamp)
+
+ bpy.context.scene.world.light_settings.use_ambient_occlusion = True
+ bpy.context.scene.world.light_settings.ao_factor = 0.1
diff --git a/release/scripts/addons_contrib/io_mesh_xyz/__init__.py b/release/scripts/addons_contrib/io_mesh_xyz/__init__.py
new file mode 100644
index 0000000..e425d89
--- /dev/null
+++ b/release/scripts/addons_contrib/io_mesh_xyz/__init__.py
@@ -0,0 +1,250 @@
+# ##### 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 LICENSE BLOCK #####
+
+#
+#
+# Authors : Clemens Barth (Blendphys at root-1.de), ...
+#
+# Homepage(Wiki) : http://development.root-1.de/Atomic_Blender.php
+#
+# Start of project : 2011-12-01 by Clemens Barth
+# First publication in Blender : 2011-12-18
+# Last modified : 2012-11-10
+#
+# Acknowledgements
+# ================
+#
+# Blender: ideasman, meta_androcto, truman, kilon, CoDEmanX, dairin0d, PKHG,
+# Valter, ...
+# Other: Frank Palmino
+#
+
+bl_info = {
+ "name": "Atomic Blender - XYZ",
+ "description": "Import/export of atoms described in .xyz files",
+ "author": "Clemens Barth",
+ "version": (1, 0),
+ "blender": (2, 60, 0),
+ "location": "File -> Import -> XYZ (.xyz)",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/"
+ "Import-Export/XYZ",
+ "tracker_url": "http://projects.blender.org/tracker/"
+ "index.php?func=detail&aid=29646&group_id=153&atid=468",
+ "category": "Import-Export"
+}
+
+import bpy
+from bpy.types import Operator
+from bpy_extras.io_utils import ImportHelper, ExportHelper
+from bpy.props import (StringProperty,
+ BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty)
+
+from . import import_xyz
+from . import export_xyz
+
+# -----------------------------------------------------------------------------
+# GUI
+
+
+# This is the class for the file dialog.
+class ImportXYZ(Operator, ImportHelper):
+ bl_idname = "import_mesh.xyz"
+ bl_label = "Import XYZ (*.xyz)"
+ bl_options = {'PRESET', 'UNDO'}
+
+ filename_ext = ".xyz"
+ filter_glob = StringProperty(default="*.xyz", options={'HIDDEN'},)
+
+ use_camera = BoolProperty(
+ name="Camera", default=False,
+ description="Do you need a camera?")
+ use_lamp = BoolProperty(
+ name="Lamp", default=False,
+ description = "Do you need a lamp?")
+ ball = EnumProperty(
+ name="Type of ball",
+ description="Choose ball",
+ items=(('0', "NURBS", "NURBS balls"),
+ ('1', "Mesh" , "Mesh balls"),
+ ('2', "Meta" , "Metaballs")),
+ default='0',)
+ mesh_azimuth = IntProperty(
+ name = "Azimuth", default=32, min=1,
+ description = "Number of sectors (azimuth)")
+ mesh_zenith = IntProperty(
+ name = "Zenith", default=32, min=1,
+ description = "Number of sectors (zenith)")
+ scale_ballradius = FloatProperty(
+ name = "Balls", default=1.0, min=0.0001,
+ description = "Scale factor for all atom radii")
+ scale_distances = FloatProperty (
+ name = "Distances", default=1.0, min=0.0001,
+ description = "Scale factor for all distances")
+ atomradius = EnumProperty(
+ name="Type of radius",
+ description="Choose type of atom radius",
+ items=(('0', "Pre-defined", "Use pre-defined radius"),
+ ('1', "Atomic", "Use atomic radius"),
+ ('2', "van der Waals", "Use van der Waals radius")),
+ default='0',)
+ use_center = BoolProperty(
+ name = "Object to origin (first frames)", default=False,
+ description = "Put the object into the global origin, the first frame only")
+ use_center_all = BoolProperty(
+ name = "Object to origin (all frames)", default=True,
+ description = "Put the object into the global origin, all frames")
+ datafile = StringProperty(
+ name = "", description="Path to your custom data file",
+ maxlen = 256, default = "", subtype='FILE_PATH')
+ use_frames = BoolProperty(
+ name = "Load all frames?", default=False,
+ description = "Do you want to load all frames?")
+ skip_frames = IntProperty(
+ name="", default=0, min=0,
+ description="Number of frames you want to skip.")
+ images_per_key = IntProperty(
+ name="", default=1, min=1,
+ description="Choose the number of images between 2 keys.")
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row.prop(self, "use_camera")
+ row.prop(self, "use_lamp")
+ row = layout.row()
+ col = row.column()
+ col.prop(self, "ball")
+ row = layout.row()
+ row.active = (self.ball == "1")
+ col = row.column(align=True)
+ col.prop(self, "mesh_azimuth")
+ col.prop(self, "mesh_zenith")
+ row = layout.row()
+ col = row.column()
+ col.label(text="Scaling factors")
+ col = row.column(align=True)
+ col.prop(self, "scale_ballradius")
+ col.prop(self, "scale_distances")
+ row = layout.row()
+ row.prop(self, "use_center")
+ row = layout.row()
+ row.prop(self, "use_center_all")
+ row = layout.row()
+ row.prop(self, "atomradius")
+
+ row = layout.row()
+ row.prop(self, "use_frames")
+ row = layout.row()
+ row.active = self.use_frames
+ col = row.column()
+ col.label(text="Skip frames")
+ col = row.column()
+ col.prop(self, "skip_frames")
+ row = layout.row()
+ row.active = self.use_frames
+ col = row.column()
+ col.label(text="Frames/key")
+ col = row.column()
+ col.prop(self, "images_per_key")
+
+ def execute(self, context):
+
+ del import_xyz.ALL_FRAMES[:]
+ del import_xyz.ELEMENTS[:]
+ del import_xyz.STRUCTURE[:]
+
+ # This is to determine the path.
+ filepath_xyz = bpy.path.abspath(self.filepath)
+
+ # Execute main routine
+ import_xyz.import_xyz(
+ self.ball,
+ self.mesh_azimuth,
+ self.mesh_zenith,
+ self.scale_ballradius,
+ self.atomradius,
+ self.scale_distances,
+ self.use_center,
+ self.use_center_all,
+ self.use_camera,
+ self.use_lamp,
+ filepath_xyz)
+
+ # Load frames
+ if len(import_xyz.ALL_FRAMES) > 1 and self.use_frames:
+
+ import_xyz.build_frames(self.images_per_key,
+ self.skip_frames)
+
+ return {'FINISHED'}
+
+
+# This is the class for the file dialog of the exporter.
+class ExportXYZ(Operator, ExportHelper):
+ bl_idname = "export_mesh.xyz"
+ bl_label = "Export XYZ (*.xyz)"
+ filename_ext = ".xyz"
+
+ filter_glob = StringProperty(
+ default="*.xyz", options={'HIDDEN'},)
+
+ atom_xyz_export_type = EnumProperty(
+ name="Type of Objects",
+ description="Choose type of objects",
+ items=(('0', "All", "Export all active objects"),
+ ('1', "Elements", "Export only those active objects which have"
+ " a proper element name")),
+ default='1',)
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row.prop(self, "atom_xyz_export_type")
+
+ def execute(self, context):
+ export_xyz.export_xyz(self.atom_xyz_export_type,
+ bpy.path.abspath(self.filepath))
+
+ return {'FINISHED'}
+
+
+# The entry into the menu 'file -> import'
+def menu_func(self, context):
+ self.layout.operator(ImportXYZ.bl_idname, text="XYZ (.xyz)")
+
+# The entry into the menu 'file -> export'
+def menu_func_export(self, context):
+ self.layout.operator(ExportXYZ.bl_idname, text="XYZ (.xyz)")
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_file_import.append(menu_func)
+ bpy.types.INFO_MT_file_export.append(menu_func_export)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_file_import.remove(menu_func)
+ bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
+if __name__ == "__main__":
+
+ register()
diff --git a/release/scripts/addons/io_mesh_pdb/atom_info.dat b/release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat
similarity index 100%
copy from release/scripts/addons/io_mesh_pdb/atom_info.dat
copy to release/scripts/addons_contrib/io_mesh_xyz/atom_info.dat
diff --git a/release/scripts/addons_contrib/io_mesh_xyz/export_xyz.py b/release/scripts/addons_contrib/io_mesh_xyz/export_xyz.py
new file mode 100644
index 0000000..093d6e9
--- /dev/null
+++ b/release/scripts/addons_contrib/io_mesh_xyz/export_xyz.py
@@ -0,0 +1,85 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+from . import import_xyz
+
+
+class AtomsExport(object):
+ __slots__ = ('element', 'location')
+ def __init__(self, element, location):
+ self.element = element
+ self.location = location
+
+
+def export_xyz(obj_type, filepath_xyz):
+
+ list_atoms = []
+ counter = 0
+ for obj in bpy.context.selected_objects:
+
+ if "Stick" in obj.name:
+ continue
+
+ if obj.type not in {'MESH', 'SURFACE', 'META'}:
+ continue
+
+ name = ""
+ for element in import_xyz.ELEMENTS_DEFAULT:
+ if element[1] in obj.name:
+ if element[2] == "Vac":
+ name = "X"
+ else:
+ name = element[2]
+
+ if name == "":
+ if obj_type == "0":
+ name = "?"
+ else:
+ continue
+
+ if len(obj.children) != 0:
+ for vertex in obj.data.vertices:
+ location = obj.matrix_world*vertex.co
+ list_atoms.append(AtomsExport(name, location))
+ counter += 1
+ else:
+ if not obj.parent:
+ location = obj.location
+ list_atoms.append(AtomsExport(name, location))
+ counter += 1
+
+ xyz_file_p = open(filepath_xyz, "w")
+ xyz_file_p.write("%d\n" % counter)
+ xyz_file_p.write("This XYZ file has been created with Blender "
+ "and the addon Atomic Blender - XYZ. "
+ "For more details see: wiki.blender.org/index.php/"
+ "Extensions:2.6/Py/Scripts/Import-Export/XYZ\n")
+
+ for i, atom in enumerate(list_atoms):
+ string = "%3s%15.5f%15.5f%15.5f\n" % (
+ atom.element,
+ atom.location[0],
+ atom.location[1],
+ atom.location[2])
+ xyz_file_p.write(string)
+
+ xyz_file_p.close()
+
+ return True
+
diff --git a/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py b/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py
new file mode 100644
index 0000000..9a575f2
--- /dev/null
+++ b/release/scripts/addons_contrib/io_mesh_xyz/import_xyz.py
@@ -0,0 +1,739 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+from math import pi, sqrt
+from mathutils import Vector, Matrix
+
+# -----------------------------------------------------------------------------
+# Atom and element data
+
+
+# This is a list that contains some data of all possible elements. The structure
+# is as follows:
+#
+# 1, "Hydrogen", "H", [0.0,0.0,1.0], 0.32, 0.32, 0.32 , -1 , 1.54 means
+#
+# No., name, short name, color, radius (used), radius (covalent), radius (atomic),
+#
+# charge state 1, radius (ionic) 1, charge state 2, radius (ionic) 2, ... all
+# charge states for any atom are listed, if existing.
+# The list is fixed and cannot be changed ... (see below)
+
+ELEMENTS_DEFAULT = (
+( 1, "Hydrogen", "H", ( 1.0, 1.0, 1.0), 0.32, 0.32, 0.79 , -1 , 1.54 ),
+( 2, "Helium", "He", ( 0.85, 1.0, 1.0), 0.93, 0.93, 0.49 ),
+( 3, "Lithium", "Li", ( 0.8, 0.50, 1.0), 1.23, 1.23, 2.05 , 1 , 0.68 ),
+( 4, "Beryllium", "Be", ( 0.76, 1.0, 0.0), 0.90, 0.90, 1.40 , 1 , 0.44 , 2 , 0.35 ),
+( 5, "Boron", "B", ( 1.0, 0.70, 0.70), 0.82, 0.82, 1.17 , 1 , 0.35 , 3 , 0.23 ),
+( 6, "Carbon", "C", ( 0.56, 0.56, 0.56), 0.77, 0.77, 0.91 , -4 , 2.60 , 4 , 0.16 ),
+( 7, "Nitrogen", "N", ( 0.18, 0.31, 0.97), 0.75, 0.75, 0.75 , -3 , 1.71 , 1 , 0.25 , 3 , 0.16 , 5 , 0.13 ),
+( 8, "Oxygen", "O", ( 1.0, 0.05, 0.05), 0.73, 0.73, 0.65 , -2 , 1.32 , -1 , 1.76 , 1 , 0.22 , 6 , 0.09 ),
+( 9, "Fluorine", "F", ( 0.56, 0.87, 0.31), 0.72, 0.72, 0.57 , -1 , 1.33 , 7 , 0.08 ),
+(10, "Neon", "Ne", ( 0.70, 0.89, 0.96), 0.71, 0.71, 0.51 , 1 , 1.12 ),
+(11, "Sodium", "Na", ( 0.67, 0.36, 0.94), 1.54, 1.54, 2.23 , 1 , 0.97 ),
+(12, "Magnesium", "Mg", ( 0.54, 1.0, 0.0), 1.36, 1.36, 1.72 , 1 , 0.82 , 2 , 0.66 ),
+(13, "Aluminium", "Al", ( 0.74, 0.65, 0.65), 1.18, 1.18, 1.82 , 3 , 0.51 ),
+(14, "Silicon", "Si", ( 0.94, 0.78, 0.62), 1.11, 1.11, 1.46 , -4 , 2.71 , -1 , 3.84 , 1 , 0.65 , 4 , 0.42 ),
+(15, "Phosphorus", "P", ( 1.0, 0.50, 0.0), 1.06, 1.06, 1.23 , -3 , 2.12 , 3 , 0.44 , 5 , 0.35 ),
+(16, "Sulfur", "S", ( 1.0, 1.0, 0.18), 1.02, 1.02, 1.09 , -2 , 1.84 , 2 , 2.19 , 4 , 0.37 , 6 , 0.30 ),
+(17, "Chlorine", "Cl", ( 0.12, 0.94, 0.12), 0.99, 0.99, 0.97 , -1 , 1.81 , 5 , 0.34 , 7 , 0.27 ),
+(18, "Argon", "Ar", ( 0.50, 0.81, 0.89), 0.98, 0.98, 0.88 , 1 , 1.54 ),
+(19, "Potassium", "K", ( 0.56, 0.25, 0.83), 2.03, 2.03, 2.77 , 1 , 0.81 ),
+(20, "Calcium", "Ca", ( 0.23, 1.0, 0.0), 1.74, 1.74, 2.23 , 1 , 1.18 , 2 , 0.99 ),
+(21, "Scandium", "Sc", ( 0.90, 0.90, 0.90), 1.44, 1.44, 2.09 , 3 , 0.73 ),
+(22, "Titanium", "Ti", ( 0.74, 0.76, 0.78), 1.32, 1.32, 2.00 , 1 , 0.96 , 2 , 0.94 , 3 , 0.76 , 4 , 0.68 ),
+(23, "Vanadium", "V", ( 0.65, 0.65, 0.67), 1.22, 1.22, 1.92 , 2 , 0.88 , 3 , 0.74 , 4 , 0.63 , 5 , 0.59 ),
+(24, "Chromium", "Cr", ( 0.54, 0.6, 0.78), 1.18, 1.18, 1.85 , 1 , 0.81 , 2 , 0.89 , 3 , 0.63 , 6 , 0.52 ),
+(25, "Manganese", "Mn", ( 0.61, 0.47, 0.78), 1.17, 1.17, 1.79 , 2 , 0.80 , 3 , 0.66 , 4 , 0.60 , 7 , 0.46 ),
+(26, "Iron", "Fe", ( 0.87, 0.4, 0.2), 1.17, 1.17, 1.72 , 2 , 0.74 , 3 , 0.64 ),
+(27, "Cobalt", "Co", ( 0.94, 0.56, 0.62), 1.16, 1.16, 1.67 , 2 , 0.72 , 3 , 0.63 ),
+(28, "Nickel", "Ni", ( 0.31, 0.81, 0.31), 1.15, 1.15, 1.62 , 2 , 0.69 ),
+(29, "Copper", "Cu", ( 0.78, 0.50, 0.2), 1.17, 1.17, 1.57 , 1 , 0.96 , 2 , 0.72 ),
+(30, "Zinc", "Zn", ( 0.49, 0.50, 0.69), 1.25, 1.25, 1.53 , 1 , 0.88 , 2 , 0.74 ),
+(31, "Gallium", "Ga", ( 0.76, 0.56, 0.56), 1.26, 1.26, 1.81 , 1 , 0.81 , 3 , 0.62 ),
+(32, "Germanium", "Ge", ( 0.4, 0.56, 0.56), 1.22, 1.22, 1.52 , -4 , 2.72 , 2 , 0.73 , 4 , 0.53 ),
+(33, "Arsenic", "As", ( 0.74, 0.50, 0.89), 1.20, 1.20, 1.33 , -3 , 2.22 , 3 , 0.58 , 5 , 0.46 ),
+(34, "Selenium", "Se", ( 1.0, 0.63, 0.0), 1.16, 1.16, 1.22 , -2 , 1.91 , -1 , 2.32 , 1 , 0.66 , 4 , 0.50 , 6 , 0.42 ),
+(35, "Bromine", "Br", ( 0.65, 0.16, 0.16), 1.14, 1.14, 1.12 , -1 , 1.96 , 5 , 0.47 , 7 , 0.39 ),
+(36, "Krypton", "Kr", ( 0.36, 0.72, 0.81), 1.31, 1.31, 1.24 ),
+(37, "Rubidium", "Rb", ( 0.43, 0.18, 0.69), 2.16, 2.16, 2.98 , 1 , 1.47 ),
+(38, "Strontium", "Sr", ( 0.0, 1.0, 0.0), 1.91, 1.91, 2.45 , 2 , 1.12 ),
+(39, "Yttrium", "Y", ( 0.58, 1.0, 1.0), 1.62, 1.62, 2.27 , 3 , 0.89 ),
+(40, "Zirconium", "Zr", ( 0.58, 0.87, 0.87), 1.45, 1.45, 2.16 , 1 , 1.09 , 4 , 0.79 ),
+(41, "Niobium", "Nb", ( 0.45, 0.76, 0.78), 1.34, 1.34, 2.08 , 1 , 1.00 , 4 , 0.74 , 5 , 0.69 ),
+(42, "Molybdenum", "Mo", ( 0.32, 0.70, 0.70), 1.30, 1.30, 2.01 , 1 , 0.93 , 4 , 0.70 , 6 , 0.62 ),
+(43, "Technetium", "Tc", ( 0.23, 0.61, 0.61), 1.27, 1.27, 1.95 , 7 , 0.97 ),
+(44, "Ruthenium", "Ru", ( 0.14, 0.56, 0.56), 1.25, 1.25, 1.89 , 4 , 0.67 ),
+(45, "Rhodium", "Rh", ( 0.03, 0.49, 0.54), 1.25, 1.25, 1.83 , 3 , 0.68 ),
+(46, "Palladium", "Pd", ( 0.0, 0.41, 0.52), 1.28, 1.28, 1.79 , 2 , 0.80 , 4 , 0.65 ),
+(47, "Silver", "Ag", ( 0.75, 0.75, 0.75), 1.34, 1.34, 1.75 , 1 , 1.26 , 2 , 0.89 ),
+(48, "Cadmium", "Cd", ( 1.0, 0.85, 0.56), 1.48, 1.48, 1.71 , 1 , 1.14 , 2 , 0.97 ),
+(49, "Indium", "In", ( 0.65, 0.45, 0.45), 1.44, 1.44, 2.00 , 3 , 0.81 ),
+(50, "Tin", "Sn", ( 0.4, 0.50, 0.50), 1.41, 1.41, 1.72 , -4 , 2.94 , -1 , 3.70 , 2 , 0.93 , 4 , 0.71 ),
+(51, "Antimony", "Sb", ( 0.61, 0.38, 0.70), 1.40, 1.40, 1.53 , -3 , 2.45 , 3 , 0.76 , 5 , 0.62 ),
+(52, "Tellurium", "Te", ( 0.83, 0.47, 0.0), 1.36, 1.36, 1.42 , -2 , 2.11 , -1 , 2.50 , 1 , 0.82 , 4 , 0.70 , 6 , 0.56 ),
+(53, "Iodine", "I", ( 0.58, 0.0, 0.58), 1.33, 1.33, 1.32 , -1 , 2.20 , 5 , 0.62 , 7 , 0.50 ),
+(54, "Xenon", "Xe", ( 0.25, 0.61, 0.69), 1.31, 1.31, 1.24 ),
+(55, "Caesium", "Cs", ( 0.34, 0.09, 0.56), 2.35, 2.35, 3.35 , 1 , 1.67 ),
+(56, "Barium", "Ba", ( 0.0, 0.78, 0.0), 1.98, 1.98, 2.78 , 1 , 1.53 , 2 , 1.34 ),
+(57, "Lanthanum", "La", ( 0.43, 0.83, 1.0), 1.69, 1.69, 2.74 , 1 , 1.39 , 3 , 1.06 ),
+(58, "Cerium", "Ce", ( 1.0, 1.0, 0.78), 1.65, 1.65, 2.70 , 1 , 1.27 , 3 , 1.03 , 4 , 0.92 ),
+(59, "Praseodymium", "Pr", ( 0.85, 1.0, 0.78), 1.65, 1.65, 2.67 , 3 , 1.01 , 4 , 0.90 ),
+(60, "Neodymium", "Nd", ( 0.78, 1.0, 0.78), 1.64, 1.64, 2.64 , 3 , 0.99 ),
+(61, "Promethium", "Pm", ( 0.63, 1.0, 0.78), 1.63, 1.63, 2.62 , 3 , 0.97 ),
+(62, "Samarium", "Sm", ( 0.56, 1.0, 0.78), 1.62, 1.62, 2.59 , 3 , 0.96 ),
+(63, "Europium", "Eu", ( 0.38, 1.0, 0.78), 1.85, 1.85, 2.56 , 2 , 1.09 , 3 , 0.95 ),
+(64, "Gadolinium", "Gd", ( 0.27, 1.0, 0.78), 1.61, 1.61, 2.54 , 3 , 0.93 ),
+(65, "Terbium", "Tb", ( 0.18, 1.0, 0.78), 1.59, 1.59, 2.51 , 3 , 0.92 , 4 , 0.84 ),
+(66, "Dysprosium", "Dy", ( 0.12, 1.0, 0.78), 1.59, 1.59, 2.49 , 3 , 0.90 ),
+(67, "Holmium", "Ho", ( 0.0, 1.0, 0.61), 1.58, 1.58, 2.47 , 3 , 0.89 ),
+(68, "Erbium", "Er", ( 0.0, 0.90, 0.45), 1.57, 1.57, 2.45 , 3 , 0.88 ),
+(69, "Thulium", "Tm", ( 0.0, 0.83, 0.32), 1.56, 1.56, 2.42 , 3 , 0.87 ),
+(70, "Ytterbium", "Yb", ( 0.0, 0.74, 0.21), 1.74, 1.74, 2.40 , 2 , 0.93 , 3 , 0.85 ),
+(71, "Lutetium", "Lu", ( 0.0, 0.67, 0.14), 1.56, 1.56, 2.25 , 3 , 0.85 ),
+(72, "Hafnium", "Hf", ( 0.30, 0.76, 1.0), 1.44, 1.44, 2.16 , 4 , 0.78 ),
+(73, "Tantalum", "Ta", ( 0.30, 0.65, 1.0), 1.34, 1.34, 2.09 , 5 , 0.68 ),
+(74, "Tungsten", "W", ( 0.12, 0.58, 0.83), 1.30, 1.30, 2.02 , 4 , 0.70 , 6 , 0.62 ),
+(75, "Rhenium", "Re", ( 0.14, 0.49, 0.67), 1.28, 1.28, 1.97 , 4 , 0.72 , 7 , 0.56 ),
+(76, "Osmium", "Os", ( 0.14, 0.4, 0.58), 1.26, 1.26, 1.92 , 4 , 0.88 , 6 , 0.69 ),
+(77, "Iridium", "Ir", ( 0.09, 0.32, 0.52), 1.27, 1.27, 1.87 , 4 , 0.68 ),
+(78, "Platinium", "Pt", ( 0.81, 0.81, 0.87), 1.30, 1.30, 1.83 , 2 , 0.80 , 4 , 0.65 ),
+(79, "Gold", "Au", ( 1.0, 0.81, 0.13), 1.34, 1.34, 1.79 , 1 , 1.37 , 3 , 0.85 ),
+(80, "Mercury", "Hg", ( 0.72, 0.72, 0.81), 1.49, 1.49, 1.76 , 1 , 1.27 , 2 , 1.10 ),
+(81, "Thallium", "Tl", ( 0.65, 0.32, 0.30), 1.48, 1.48, 2.08 , 1 , 1.47 , 3 , 0.95 ),
+(82, "Lead", "Pb", ( 0.34, 0.34, 0.38), 1.47, 1.47, 1.81 , 2 , 1.20 , 4 , 0.84 ),
+(83, "Bismuth", "Bi", ( 0.61, 0.30, 0.70), 1.46, 1.46, 1.63 , 1 , 0.98 , 3 , 0.96 , 5 , 0.74 ),
+(84, "Polonium", "Po", ( 0.67, 0.36, 0.0), 1.46, 1.46, 1.53 , 6 , 0.67 ),
+(85, "Astatine", "At", ( 0.45, 0.30, 0.27), 1.45, 1.45, 1.43 , -3 , 2.22 , 3 , 0.85 , 5 , 0.46 ),
+(86, "Radon", "Rn", ( 0.25, 0.50, 0.58), 1.00, 1.00, 1.34 ),
+(87, "Francium", "Fr", ( 0.25, 0.0, 0.4), 1.00, 1.00, 1.00 , 1 , 1.80 ),
+(88, "Radium", "Ra", ( 0.0, 0.49, 0.0), 1.00, 1.00, 1.00 , 2 , 1.43 ),
+(89, "Actinium", "Ac", ( 0.43, 0.67, 0.98), 1.00, 1.00, 1.00 , 3 , 1.18 ),
+(90, "Thorium", "Th", ( 0.0, 0.72, 1.0), 1.65, 1.65, 1.00 , 4 , 1.02 ),
+(91, "Protactinium", "Pa", ( 0.0, 0.63, 1.0), 1.00, 1.00, 1.00 , 3 , 1.13 , 4 , 0.98 , 5 , 0.89 ),
+(92, "Uranium", "U", ( 0.0, 0.56, 1.0), 1.42, 1.42, 1.00 , 4 , 0.97 , 6 , 0.80 ),
+(93, "Neptunium", "Np", ( 0.0, 0.50, 1.0), 1.00, 1.00, 1.00 , 3 , 1.10 , 4 , 0.95 , 7 , 0.71 ),
+(94, "Plutonium", "Pu", ( 0.0, 0.41, 1.0), 1.00, 1.00, 1.00 , 3 , 1.08 , 4 , 0.93 ),
+(95, "Americium", "Am", ( 0.32, 0.36, 0.94), 1.00, 1.00, 1.00 , 3 , 1.07 , 4 , 0.92 ),
+(96, "Curium", "Cm", ( 0.47, 0.36, 0.89), 1.00, 1.00, 1.00 ),
+(97, "Berkelium", "Bk", ( 0.54, 0.30, 0.89), 1.00, 1.00, 1.00 ),
+(98, "Californium", "Cf", ( 0.63, 0.21, 0.83), 1.00, 1.00, 1.00 ),
+(99, "Einsteinium", "Es", ( 0.70, 0.12, 0.83), 1.00, 1.00, 1.00 ),
+(100, "Fermium", "Fm", ( 0.70, 0.12, 0.72), 1.00, 1.00, 1.00 ),
+(101, "Mendelevium", "Md", ( 0.70, 0.05, 0.65), 1.00, 1.00, 1.00 ),
+(102, "Nobelium", "No", ( 0.74, 0.05, 0.52), 1.00, 1.00, 1.00 ),
+(103, "Lawrencium", "Lr", ( 0.78, 0.0, 0.4), 1.00, 1.00, 1.00 ),
+(104, "Vacancy", "Vac", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00),
+(105, "Default", "Default", ( 1.0, 1.0, 1.0), 1.00, 1.00, 1.00),
+(106, "Stick", "Stick", ( 0.5, 0.5, 0.5), 1.00, 1.00, 1.00),
+)
+
+# This list here contains all data of the elements and will be used during
+# runtime. It is a list of classes.
+# During executing Atomic Blender, the list will be initialized with the fixed
+# data from above via the class structure below (ElementProp). We
+# have then one fixed list (above), which will never be changed, and a list of
+# classes with same data. The latter can be modified via loading a separate
+# custom data file for instance.
+ELEMENTS = []
+
+# This is the list, which contains all atoms of all frames! Each item is a
+# list which contains the atoms of a single frame. It is a list of
+# 'AtomProp'.
+ALL_FRAMES = []
+
+# A list of ALL balls which are put into the scene
+STRUCTURE = []
+
+
+# This is the class, which stores the properties for one element.
+class ElementProp(object):
+ __slots__ = ('number', 'name', 'short_name', 'color', 'radii', 'radii_ionic')
+ def __init__(self, number, name, short_name, color, radii, radii_ionic):
+ self.number = number
+ self.name = name
+ self.short_name = short_name
+ self.color = color
+ self.radii = radii
+ self.radii_ionic = radii_ionic
+
+# This is the class, which stores the properties of one atom.
+class AtomProp(object):
+ __slots__ = ('element', 'name', 'location', 'radius', 'color', 'material')
+ def __init__(self, element, name, location, radius, color, material):
+ self.element = element
+ self.name = name
+ self.location = location
+ self.radius = radius
+ self.color = color
+ self.material = material
+
+
+# -----------------------------------------------------------------------------
+# Some basic routines
+
+def read_elements():
+
+ del ELEMENTS[:]
+
+ for item in ELEMENTS_DEFAULT:
+
+ # All three radii into a list
+ radii = [item[4],item[5],item[6]]
+ # The handling of the ionic radii will be done later. So far, it is an
+ # empty list.
+ radii_ionic = []
+
+ li = ElementProp(item[0],item[1],item[2],item[3],
+ radii,radii_ionic)
+ ELEMENTS.append(li)
+
+
+# filepath_pdb: path to pdb file
+# radiustype : '0' default
+# '1' atomic radii
+# '2' van der Waals
+def read_xyz_file(filepath_xyz,radiustype):
+
+ number_frames = 0
+ total_number_atoms = 0
+
+ # Open the file ...
+ filepath_xyz_p = open(filepath_xyz, "r")
+
+ #Go through the whole file.
+ FLAG = False
+ for line in filepath_xyz_p:
+
+ # ... the loop is broken here (EOF) ...
+ if line == "":
+ continue
+
+ split_list = line.rsplit()
+
+ if len(split_list) == 1:
+ number_atoms = int(split_list[0])
+ FLAG = True
+
+ if FLAG == True:
+
+ line = filepath_xyz_p.readline()
+ line = line.rstrip()
+
+ all_atoms= []
+ for i in range(number_atoms):
+
+
+ # This is a guarantee that only the total number of atoms of the
+ # first frame is used. Condition is, so far, that the number of
+ # atoms in a xyz file is constant. However, sometimes the number
+ # may increase (or decrease). If it decreases, the addon crashes.
+ # If it increases, only the tot number of atoms of the first frame
+ # is used.
+ # By time, I will allow varying atom numbers ... but this takes
+ # some time ...
+ if number_frames != 0:
+ if i >= total_number_atoms:
+ break
+
+
+ line = filepath_xyz_p.readline()
+ line = line.rstrip()
+ split_list = line.rsplit()
+ short_name = str(split_list[0])
+
+ # Go through all elements and find the element of the current atom.
+ FLAG_FOUND = False
+ for element in ELEMENTS:
+ if str.upper(short_name) == str.upper(element.short_name):
+ # Give the atom its proper name, color and radius:
+ name = element.name
+ # int(radiustype) => type of radius:
+ # pre-defined (0), atomic (1) or van der Waals (2)
+ radius = float(element.radii[int(radiustype)])
+ color = element.color
+ FLAG_FOUND = True
+ break
+
+ # Is it a vacancy or an 'unknown atom' ?
+ if FLAG_FOUND == False:
+ # Give this atom also a name. If it is an 'X' then it is a
+ # vacancy. Otherwise ...
+ if "X" in short_name:
+ short_name = "VAC"
+ name = "Vacancy"
+ radius = float(ELEMENTS[-3].radii[int(radiustype)])
+ color = ELEMENTS[-3].color
+ # ... take what is written in the xyz file. These are somewhat
+ # unknown atoms. This should never happen, the element list is
+ # almost complete. However, we do this due to security reasons.
+ else:
+ name = str.upper(short_name)
+ radius = float(ELEMENTS[-2].radii[int(radiustype)])
+ color = ELEMENTS[-2].color
+
+ x = float(split_list[1])
+ y = float(split_list[2])
+ z = float(split_list[3])
+
+ location = Vector((x,y,z))
+
+ all_atoms.append([short_name, name, location, radius, color])
+
+ # We note here all elements. This needs to be done only once.
+ if number_frames == 0:
+
+ # This is a guarantee that only the total number of atoms of the
+ # first frame is used. Condition is, so far, that the number of
+ # atoms in a xyz file is constant. However, sometimes the number
+ # may increase (or decrease). If it decreases, the addon crashes.
+ # If it increases, only the tot number of atoms of the first frame
+ # is used.
+ # By time, I will allow varying atom numbers ... but this takes
+ # some time ...
+ total_number_atoms = number_atoms
+
+
+ elements = []
+ for atom in all_atoms:
+ FLAG_FOUND = False
+ for element in elements:
+ # If the atom name is already in the list,
+ # FLAG on 'True'.
+ if element == atom[1]:
+ FLAG_FOUND = True
+ break
+ # No name in the current list has been found? => New entry.
+ if FLAG_FOUND == False:
+ # Stored are: Atom label (e.g. 'Na'), the corresponding
+ # atom name (e.g. 'Sodium') and its color.
+ elements.append(atom[1])
+
+ # Sort the atoms: create lists of atoms of one type
+ structure = []
+ for element in elements:
+ atoms_one_type = []
+ for atom in all_atoms:
+ if atom[1] == element:
+ atoms_one_type.append(AtomProp(atom[0],
+ atom[1],
+ atom[2],
+ atom[3],
+ atom[4],[]))
+ structure.append(atoms_one_type)
+
+ ALL_FRAMES.append(structure)
+ number_frames += 1
+ FLAG = False
+
+ filepath_xyz_p.close()
+
+ return total_number_atoms
+
+
+# -----------------------------------------------------------------------------
+# The main routine
+
+def import_xyz(Ball_type,
+ Ball_azimuth,
+ Ball_zenith,
+ Ball_radius_factor,
+ radiustype,
+ Ball_distance_factor,
+ put_to_center,
+ put_to_center_all,
+ use_camera,
+ use_lamp,
+ filepath_xyz):
+
+ # List of materials
+ atom_material_list = []
+
+ # ------------------------------------------------------------------------
+ # INITIALIZE THE ELEMENT LIST
+
+ read_elements()
+
+ # ------------------------------------------------------------------------
+ # READING DATA OF ATOMS
+
+ Number_of_total_atoms = read_xyz_file(filepath_xyz,
+ radiustype)
+
+ # We show the atoms of the first frame.
+ first_frame = ALL_FRAMES[0]
+
+ # ------------------------------------------------------------------------
+ # MATERIAL PROPERTIES FOR ATOMS
+
+ # Create first a new list of materials for each type of atom
+ # (e.g. hydrogen)
+ for atoms_of_one_type in first_frame:
+ # Take the first atom
+ atom = atoms_of_one_type[0]
+ material = bpy.data.materials.new(atom.name)
+ material.name = atom.name
+ material.diffuse_color = atom.color
+ atom_material_list.append(material)
+
+ # Now, we go through all atoms and give them a material. For all atoms ...
+ for atoms_of_one_type in first_frame:
+ for atom in atoms_of_one_type:
+ # ... and all materials ...
+ for material in atom_material_list:
+ # ... select the correct material for the current atom via
+ # comparison of names ...
+ if atom.name in material.name:
+ # ... and give the atom its material properties.
+ # However, before we check if it is a vacancy
+ # The vacancy is represented by a transparent cube.
+ if atom.name == "Vacancy":
+ material.transparency_method = 'Z_TRANSPARENCY'
+ material.alpha = 1.3
+ material.raytrace_transparency.fresnel = 1.6
+ material.raytrace_transparency.fresnel_factor = 1.6
+ material.use_transparency = True
+ # The atom gets its properties.
+ atom.material = material
+
+ # ------------------------------------------------------------------------
+ # TRANSLATION OF THE STRUCTURE TO THE ORIGIN
+
+ # It may happen that the structure in a XYZ file already has an offset
+
+
+ # If chosen, the structure is put into the center of the scene
+ # (only the first frame).
+ if put_to_center == True and put_to_center_all == False:
+
+ sum_vec = Vector((0.0,0.0,0.0))
+
+ # Sum of all atom coordinates
+ for atoms_of_one_type in first_frame:
+ sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec)
+
+ # Then the average is taken
+ sum_vec = sum_vec / Number_of_total_atoms
+
+ # After, for each atom the center of gravity is substracted
+ for atoms_of_one_type in first_frame:
+ for atom in atoms_of_one_type:
+ atom.location -= sum_vec
+
+ # If chosen, the structure is put into the center of the scene
+ # (all frames).
+ if put_to_center_all == True:
+
+ # For all frames
+ for frame in ALL_FRAMES:
+
+ sum_vec = Vector((0.0,0.0,0.0))
+
+ # Sum of all atom coordinates
+ for (i, atoms_of_one_type) in enumerate(frame):
+
+ # This is a guarantee that only the total number of atoms of the
+ # first frame is used. Condition is, so far, that the number of
+ # atoms in a xyz file is constant. However, sometimes the number
+ # may increase (or decrease). If it decreases, the addon crashes.
+ # If it increases, only the tot number of atoms of the first frame
+ # is used.
+ # By time, I will allow varying atom numbers ... but this takes
+ # some time ...
+ if i >= Number_of_total_atoms:
+ break
+
+ sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec)
+
+ # Then the average is taken
+ sum_vec = sum_vec / Number_of_total_atoms
+
+ # After, for each atom the center of gravity is substracted
+ for atoms_of_one_type in frame:
+ for atom in atoms_of_one_type:
+ atom.location -= sum_vec
+
+
+ # ------------------------------------------------------------------------
+ # SCALING
+
+ # Take all atoms and adjust their radii and scale the distances.
+ for atoms_of_one_type in first_frame:
+ for atom in atoms_of_one_type:
+ atom.location *= Ball_distance_factor
+
+ # ------------------------------------------------------------------------
+ # DETERMINATION OF SOME GEOMETRIC PROPERTIES
+
+ # In the following, some geometric properties of the whole object are
+ # determined: center, size, etc.
+ sum_vec = Vector((0.0,0.0,0.0))
+
+ # First the center is determined. All coordinates are summed up ...
+ for atoms_of_one_type in first_frame:
+ sum_vec = sum([atom.location for atom in atoms_of_one_type], sum_vec)
+
+ # ... and the average is taken. This gives the center of the object.
+ object_center_vec = sum_vec / Number_of_total_atoms
+
+ # Now, we determine the size.The farthest atom from the object center is
+ # taken as a measure. The size is used to place well the camera and light
+ # into the scene.
+
+ object_size_vec = []
+ for atoms_of_one_type in first_frame:
+ object_size_vec += [atom.location - object_center_vec for atom in atoms_of_one_type]
+
+ object_size = 0.0
+ object_size = max(object_size_vec).length
+
+ # ------------------------------------------------------------------------
+ # CAMERA AND LAMP
+ camera_factor = 20.0
+
+ # If chosen a camera is put into the scene.
+ if use_camera == True:
+
+ # Assume that the object is put into the global origin. Then, the
+ # camera is moved in x and z direction, not in y. The object has its
+ # size at distance sqrt(object_size) from the origin. So, move the
+ # camera by this distance times a factor of camera_factor in x and z.
+ # Then add x, y and z of the origin of the object.
+ object_camera_vec = Vector((sqrt(object_size) * camera_factor,
+ 0.0,
+ sqrt(object_size) * camera_factor))
+ camera_xyz_vec = object_center_vec + object_camera_vec
+
+ # Create the camera
+ current_layers=bpy.context.scene.layers
+ camera_data = bpy.data.cameras.new("A_camera")
+ camera_data.lens = 45
+ camera_data.clip_end = 500.0
+ camera = bpy.data.objects.new("A_camera", camera_data)
+ camera.location = camera_xyz_vec
+ camera.layers = current_layers
+ bpy.context.scene.objects.link(camera)
+
+ # Here the camera is rotated such it looks towards the center of
+ # the object. The [0.0, 0.0, 1.0] vector along the z axis
+ z_axis_vec = Vector((0.0, 0.0, 1.0))
+ # The angle between the last two vectors
+ angle = object_camera_vec.angle(z_axis_vec, 0)
+ # The cross-product of z_axis_vec and object_camera_vec
+ axis_vec = z_axis_vec.cross(object_camera_vec)
+ # Rotate 'axis_vec' by 'angle' and convert this to euler parameters.
+ # 4 is the size of the matrix.
+ camera.rotation_euler = Matrix.Rotation(angle, 4, axis_vec).to_euler()
+
+ # Rotate the camera around its axis by 90° such that we have a nice
+ # camera position and view onto the object.
+ bpy.ops.object.select_all(action='DESELECT')
+ camera.select = True
+ bpy.ops.transform.rotate(value=(90.0*2*pi/360.0),
+ axis=object_camera_vec,
+ constraint_axis=(False, False, False),
+ constraint_orientation='GLOBAL',
+ mirror=False, proportional='DISABLED',
+ proportional_edit_falloff='SMOOTH',
+ proportional_size=1, snap=False,
+ snap_target='CLOSEST', snap_point=(0, 0, 0),
+ snap_align=False, snap_normal=(0, 0, 0),
+ release_confirm=False)
+
+ # Here a lamp is put into the scene, if chosen.
+ if use_lamp == True:
+
+ # This is the distance from the object measured in terms of %
+ # of the camera distance. It is set onto 50% (1/2) distance.
+ lamp_dl = sqrt(object_size) * 15 * 0.5
+ # This is a factor to which extend the lamp shall go to the right
+ # (from the camera point of view).
+ lamp_dy_right = lamp_dl * (3.0/4.0)
+
+ # Create x, y and z for the lamp.
+ object_lamp_vec = Vector((lamp_dl,lamp_dy_right,lamp_dl))
+ lamp_xyz_vec = object_center_vec + object_lamp_vec
+
+ # Create the lamp
+ current_layers=bpy.context.scene.layers
+ lamp_data = bpy.data.lamps.new(name="A_lamp", type="POINT")
+ lamp_data.distance = 500.0
+ lamp_data.energy = 3.0
+ lamp_data.shadow_method = 'RAY_SHADOW'
+ lamp = bpy.data.objects.new("A_lamp", lamp_data)
+ lamp.location = lamp_xyz_vec
+ lamp.layers = current_layers
+ bpy.context.scene.objects.link(lamp)
+
+ bpy.context.scene.world.light_settings.use_ambient_occlusion = True
+ bpy.context.scene.world.light_settings.ao_factor = 0.2
+
+
+ # ------------------------------------------------------------------------
+ # DRAWING THE ATOMS
+
+ bpy.ops.object.select_all(action='DESELECT')
+
+ # For each list of atoms of ONE type (e.g. Hydrogen)
+ for atoms_of_one_type in first_frame:
+
+ # Create first the vertices composed of the coordinates of all
+ # atoms of one type
+ atom_vertices = []
+ for atom in atoms_of_one_type:
+ # In fact, the object is created in the World's origin.
+ # This is why 'object_center_vec' is substracted. At the end
+ # the whole object is translated back to 'object_center_vec'.
+ atom_vertices.append( atom.location - object_center_vec )
+
+ # Build the mesh
+ atom_mesh = bpy.data.meshes.new("Mesh_"+atom.name)
+ atom_mesh.from_pydata(atom_vertices, [], [])
+ atom_mesh.update()
+ new_atom_mesh = bpy.data.objects.new(atom.name, atom_mesh)
+ bpy.context.scene.objects.link(new_atom_mesh)
+
+ # Now, build a representative sphere (atom)
+ current_layers=bpy.context.scene.layers
+
+ if atom.name == "Vacancy":
+ bpy.ops.mesh.primitive_cube_add(
+ view_align=False, enter_editmode=False,
+ location=(0.0, 0.0, 0.0),
+ rotation=(0.0, 0.0, 0.0),
+ layers=current_layers)
+ else:
+ # NURBS balls
+ if Ball_type == "0":
+ bpy.ops.surface.primitive_nurbs_surface_sphere_add(
+ view_align=False, enter_editmode=False,
+ location=(0,0,0), rotation=(0.0, 0.0, 0.0),
+ layers=current_layers)
+ # UV balls
+ elif Ball_type == "1":
+ bpy.ops.mesh.primitive_uv_sphere_add(
+ segments=Ball_azimuth, ring_count=Ball_zenith,
+ size=1, view_align=False, enter_editmode=False,
+ location=(0,0,0), rotation=(0, 0, 0),
+ layers=current_layers)
+ # Meta balls
+ elif Ball_type == "2":
+ bpy.ops.object.metaball_add(type='BALL', view_align=False,
+ enter_editmode=False, location=(0, 0, 0),
+ rotation=(0, 0, 0), layers=current_layers)
+
+ ball = bpy.context.scene.objects.active
+ ball.scale = (atom.radius*Ball_radius_factor,) * 3
+
+ if atom.name == "Vacancy":
+ ball.name = "Cube_"+atom.name
+ else:
+ ball.name = "Ball (NURBS)_"+atom.name
+ ball.active_material = atom.material
+ ball.parent = new_atom_mesh
+ new_atom_mesh.dupli_type = 'VERTS'
+ # The object is back translated to 'object_center_vec'.
+ new_atom_mesh.location = object_center_vec
+ STRUCTURE.append(new_atom_mesh)
+
+ # ------------------------------------------------------------------------
+ # SELECT ALL LOADED OBJECTS
+
+ bpy.ops.object.select_all(action='DESELECT')
+ obj = None
+ for obj in STRUCTURE:
+ obj.select = True
+ # activate the last selected object (perhaps another should be active?)
+ if obj:
+ bpy.context.scene.objects.active = obj
+
+
+
+def build_frames(frame_delta, frame_skip):
+
+ scn = bpy.context.scene
+
+ # Introduce the basis for all elements that appear in the structure.
+ for element in STRUCTURE:
+
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.context.scene.objects.active = element
+ element.select = True
+ bpy.ops.object.shape_key_add(True)
+
+ frame_skip += 1
+
+ # Introduce the keys and reference the atom positions for each key.
+ i = 0
+ for j, frame in enumerate(ALL_FRAMES):
+
+ if j % frame_skip == 0:
+
+ for elements_frame, elements_structure in zip(frame,STRUCTURE):
+
+ key = elements_structure.shape_key_add()
+
+ for atom_frame, atom_structure in zip(elements_frame, key.data):
+
+ atom_structure.co = (atom_frame.location
+ - elements_structure.location)
+
+ key.name = atom_frame.name + "_frame_" + str(i)
+
+ i += 1
+
+ num_frames = i
+
+ scn.frame_start = 0
+ scn.frame_end = frame_delta * num_frames
+
+ # Manage the values of the keys
+ for element in STRUCTURE:
+
+ scn.frame_current = 0
+
+ element.data.shape_keys.key_blocks[1].value = 1.0
+ element.data.shape_keys.key_blocks[2].value = 0.0
+ element.data.shape_keys.key_blocks[1].keyframe_insert("value")
+ element.data.shape_keys.key_blocks[2].keyframe_insert("value")
+
+ scn.frame_current += frame_delta
+
+ number = 0
+
+ for number in range(num_frames)[2:]:#-1]:
+
+ element.data.shape_keys.key_blocks[number-1].value = 0.0
+ element.data.shape_keys.key_blocks[number].value = 1.0
+ element.data.shape_keys.key_blocks[number+1].value = 0.0
+ element.data.shape_keys.key_blocks[number-1].keyframe_insert("value")
+ element.data.shape_keys.key_blocks[number].keyframe_insert("value")
+ element.data.shape_keys.key_blocks[number+1].keyframe_insert("value")
+
+ scn.frame_current += frame_delta
+
+ number += 1
+
+ element.data.shape_keys.key_blocks[number].value = 1.0
+ element.data.shape_keys.key_blocks[number-1].value = 0.0
+ element.data.shape_keys.key_blocks[number].keyframe_insert("value")
+ element.data.shape_keys.key_blocks[number-1].keyframe_insert("value")
+
+
+
diff --git a/release/scripts/addons_contrib/io_points_pcd/__init__.py b/release/scripts/addons_contrib/io_points_pcd/__init__.py
new file mode 100644
index 0000000..30736c5
--- /dev/null
+++ b/release/scripts/addons_contrib/io_points_pcd/__init__.py
@@ -0,0 +1,102 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "PCD",
+ "author": "Aurel Wildfellner",
+ "version": (0, 1),
+ "blender": (2, 57, 0),
+ "location": "File > Import-Export > Point Cloud Data",
+ "description": "Imports and Exports PCD (Point Cloud Data) files. PCD files are the default format used by pcl (Point Cloud Library).",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+# "support": 'OFFICAL',
+ "category": "Import-Export"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(pcd_utils)
+else:
+ from . import pcd_utils
+
+import itertools
+import os
+
+
+import bpy
+from bpy.props import *
+from bpy_extras.io_utils import ExportHelper, ImportHelper
+
+
+class ImportPCD(bpy.types.Operator, ImportHelper):
+ """Load PCD (Point Cloud Data) files"""
+ bl_idname = "import_points.stl"
+ bl_label = "Import PCD"
+
+ filename_ext = ".pcd"
+
+ filter_glob = StringProperty(default="*.pcd", options={'HIDDEN'})
+
+ files = CollectionProperty(name="File Path",
+ description="File path used for importing "
+ "the PCD file",
+ type=bpy.types.OperatorFileListElement)
+
+ directory = StringProperty(subtype='DIR_PATH')
+
+ def execute(self, context):
+ paths = [os.path.join(self.directory, name.name) for name in self.files]
+ if not paths:
+ paths.append(self.filepath)
+
+ for path in paths:
+ pcd_utils.import_pcd(path)
+
+ return {'FINISHED'}
+
+
+
+
+def menu_func_import(self, context):
+ self.layout.operator(ImportPCD.bl_idname, text="Point Cloud Data (.pcd)").filepath = "*.pcd"
+
+
+def menu_func_export(self, context):
+ #self.layout.operator(ExportPLY.bl_idname, text="Point Cloud Data (.pcd)")
+ pass
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+ bpy.types.INFO_MT_file_export.append(menu_func_export)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+ bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/io_points_pcd/pcd_utils.py b/release/scripts/addons_contrib/io_points_pcd/pcd_utils.py
new file mode 100644
index 0000000..9f2a79e
--- /dev/null
+++ b/release/scripts/addons_contrib/io_points_pcd/pcd_utils.py
@@ -0,0 +1,55 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+
+from . import pcdparser
+
+
+def create_and_link_mesh(name, points):
+ """
+ Create a blender mesh and object called name from a list of
+ *points* and link it in the current scene.
+ """
+
+ mesh = bpy.data.meshes.new(name)
+ mesh.from_pydata(points, [], [])
+
+ # update mesh to allow proper display
+ mesh.validate()
+ mesh.update()
+
+ scene = bpy.context.scene
+
+ obj = bpy.data.objects.new(name, mesh)
+ scene.objects.link(obj)
+ obj.select = True
+
+
+def import_pcd(filepath, name="new_pointcloud"):
+ parser = pcdparser.PCDParser.factory(filepath, pcdparser.PointXYZ)
+ parser.parseFile()
+ points = parser.getPoints()
+
+ blender_points = []
+ for point in points:
+ blender_points.append((point.x, point.y, point.z))
+
+ create_and_link_mesh(name, blender_points)
+
+
diff --git a/release/scripts/addons_contrib/io_points_pcd/pcdparser.py b/release/scripts/addons_contrib/io_points_pcd/pcdparser.py
new file mode 100644
index 0000000..8c543c4
--- /dev/null
+++ b/release/scripts/addons_contrib/io_points_pcd/pcdparser.py
@@ -0,0 +1,338 @@
+# ##### 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 LICENSE BLOCK #####
+
+
+import struct
+
+
+def encodeASCIILine(line):
+ return line.decode(encoding='ASCII')
+
+
+
+class Point:
+
+ def __init__(self):
+ pass
+
+
+ def setField(self, fieldname, values):
+ pass
+
+
+
+
+class PointXYZ(Point):
+
+ x = 0
+ y = 0
+ z = 0
+
+ def __init__(self):
+ super().__init__()
+
+
+ def setField(self, fieldname, values):
+ value = values[0]
+ if fieldname == 'x':
+ self.x = value
+ elif fieldname == 'y':
+ self.y = value
+ elif fieldname == 'z':
+ self.z = value
+
+
+
+
+class PCDParser:
+
+ filepath = ''
+ file = None
+
+ points = []
+ PointClass = None
+
+ headerEnd = False
+
+
+ @staticmethod
+ def factory(filepath, PointClass):
+ version = 'NO_VERSION_NUMBER'
+ with open(filepath, 'rb') as f:
+ for b in f:
+ line = encodeASCIILine(b)
+ line_split = line.split()
+ if line_split[0] == 'VERSION' and len(line_split) > 1:
+ version = line_split[1]
+ break
+
+ if version == ".7" or version == "0.7":
+ return PCDParser_v0_7(filepath, PointClass)
+ else:
+ return None
+
+
+ def __init__(self, filepath, PointClass):
+ self.filepath = filepath
+ self.PointClass = PointClass
+
+ self.file = None
+ self.headerEnd = False
+ self.points = []
+
+
+ def parserWarning(self, msg):
+ print("[WARNING] ", msg)
+
+
+ def rmComment(self, line):
+ return line[:line.find('#')]
+
+
+ def parseFile(self):
+ with open(self.filepath, 'rb') as self.file:
+ self.parseHeader()
+ self.parsePoints()
+
+
+ def parseHeader(self):
+ for b in self.file:
+ line = encodeASCIILine(b)
+ line = self.rmComment(line)
+
+ split = line.split()
+ if len(split) > 0:
+ self.parseHeaderLine(split)
+
+ if self.headerEnd:
+ self.finalizeHeader()
+ break
+
+
+ def parseHeaderLine(self, split):
+ keyword = split[0]
+ self.parserWarning("Uknown header Keyword '" + keyword + "' gets ignored")
+
+
+ def finalizeHeader(self):
+ pass
+
+
+ def parsePoints(self):
+ pass
+
+
+ def getPoints(self):
+ return self.points
+
+
+ def version(self):
+ return 'NO_VERSION_NUMBER'
+
+
+
+
+class PCDParser_v0_7(PCDParser):
+
+ fields = []
+
+ def __init__(self, filepath, PointClass):
+ super().__init__(filepath, PointClass)
+ self.fields = []
+
+
+ def version(self):
+ return '.7'
+
+
+ def parseHeaderLine(self, split):
+ keyword = split[0]
+ if keyword == 'VERSION':
+ self.parseVERSION(split[1:])
+ elif keyword == 'FIELDS':
+ self.parseFIELDS(split[1:])
+ elif keyword == 'SIZE':
+ self.parseSIZE(split[1:])
+ elif keyword == 'TYPE':
+ self.parseTYPE(split[1:])
+ elif keyword == 'COUNT':
+ self.parseCOUNT(split[1:])
+ elif keyword == 'WIDTH':
+ self.parseWIDTH(split[1:])
+ elif keyword == 'HEIGHT':
+ self.parseHEIGHT(split[1:])
+ elif keyword == 'POINTS':
+ self.parsePOINTS(split[1:])
+ elif keyword == 'DATA':
+ self.parseDATA(split[1:])
+ else:
+ super().parseHeaderLine(split)
+
+
+ def parseVERSION(self, split):
+ pass
+
+
+ def parseFIELDS(self, split):
+ print("SPLIT FIELDS:", split)
+ for field in split:
+ self.fields.append([field, None, None, None])
+ print("FIELDS, after parsing:", self.fields)
+
+
+ def parseSIZE(self, split):
+ for i, size in enumerate(split):
+ self.fields[i][1] = int(size)
+
+
+ def parseTYPE(self, split):
+ for i, type in enumerate(split):
+ self.fields[i][2] = type
+
+
+ def parseCOUNT(self, split):
+ for i, count in enumerate(split):
+ self.fields[i][3] = int(count)
+
+
+ def parseWIDTH(self, split):
+ self.width = int(split[0])
+
+
+ def parseHEIGHT(self, split):
+ self.height = int(split[0])
+
+
+ def parsePOINTS(self, split):
+ pass
+
+
+ def parseDATA(self, split):
+ if split[0] == "ascii":
+ self.datatype = 'ASCII'
+ elif split[0] == "binary":
+ self.datatype = 'BINARY'
+ self.headerEnd = True
+
+
+ def finalizeHeader(self):
+ self.numPoints = self.width * self.height
+ print("FIELDS - finalized", self.fields)
+
+
+ def parsePoints(self):
+ if self.datatype == 'ASCII':
+ self.parseASCII()
+ elif self.datatype == 'BINARY':
+ self.parseBINARY()
+
+
+ def parseASCII(self):
+ parsedPoints = 0
+ while parsedPoints < self.numPoints:
+
+ try:
+ b = self.file.readline()
+ line = encodeASCIILine(b)
+ except:
+ self.parserError("Unexpected end of data")
+ return
+ line = self.rmComment(line)
+ split = line.split()
+
+ if (len(split) == 0):
+ continue
+ else:
+ parsedPoints += 1
+
+ point = self.PointClass()
+
+ for field in self.fields:
+ fieldname = field[0]
+ fieldtype = field[2]
+ fieldcount = field[3]
+
+ values = []
+ for i in range(fieldcount):
+ vs = split.pop(0)
+ if fieldtype == 'F':
+ values.append(float(vs))
+ elif fieldtype in ['U', 'I']:
+ values.append(int(vs))
+
+ point.setField(fieldname, values)
+
+ self.points.append(point)
+
+
+ def parseBINARY(self):
+ for pointi in range(self.numPoints):
+ point = self.PointClass()
+
+ for field in self.fields:
+ fieldname = field[0]
+ fieldsize = field[1]
+ fieldtype = field[2]
+ fieldcount = field[3]
+
+ values = []
+ for i in range(fieldcount):
+
+ fs = None
+ if fieldtype == 'F':
+ if fieldsize == 4: #float
+ fs = '<f'
+ elif fieldsize == 8: #double
+ fs = '<d'
+ elif fieldtype == 'U':
+ if fieldsize == 1: #unsinged char
+ fs = '<B'
+ elif fieldsize == 2: #unsinged short
+ fs = '<H'
+ elif fieldsize == 4: #unsinged int
+ fs = '<I'
+ elif fieldtype == 'I':
+ if fieldsize == 1: #char
+ fs = '<c'
+ elif fieldsize == 2: #short
+ fs = '<h'
+ elif fieldsize == 4: #signed int
+ fs = '<i'
+
+ raw = self.file.read(fieldsize)
+ if (fs):
+ data = struct.unpack(fs, raw)
+ values.append(data[0])
+
+ point.setField(fieldname, values)
+
+ self.points.append(point)
+
+
+
+
+def test():
+ parser = PCDParser.factory('test.pcd', PointXYZ)
+ if parser:
+ parser.parseFile()
+ points = parser.getPoints()
+ for point in points:
+ print(point.x, point.y, point.z)
+ else:
+ print("Can't create parser for this file")
+
diff --git a/release/scripts/addons_contrib/io_points_pcd/test.pcd b/release/scripts/addons_contrib/io_points_pcd/test.pcd
new file mode 100644
index 0000000..79ec41d
--- /dev/null
+++ b/release/scripts/addons_contrib/io_points_pcd/test.pcd
@@ -0,0 +1,224 @@
+# .PCD v.7 - Point Cloud Data file format
+VERSION .7
+FIELDS x y z rgb
+SIZE 4 4 4 4
+TYPE F F F F
+COUNT 1 1 1 1
+WIDTH 213
+HEIGHT 1
+VIEWPOINT 0 0 0 1 0 0 0
+POINTS 213
+DATA ascii
+0.93773 0.33763 0 4.2108e+06
+0.90805 0.35641 0 4.2108e+06
+0.81915 0.32 0 4.2108e+06
+0.97192 0.278 0 4.2108e+06
+0.944 0.29474 0 4.2108e+06
+0.98111 0.24247 0 4.2108e+06
+0.93655 0.26143 0 4.2108e+06
+0.91631 0.27442 0 4.2108e+06
+0.81921 0.29315 0 4.2108e+06
+0.90701 0.24109 0 4.2108e+06
+0.83239 0.23398 0 4.2108e+06
+0.99185 0.2116 0 4.2108e+06
+0.89264 0.21174 0 4.2108e+06
+0.85082 0.21212 0 4.2108e+06
+0.81044 0.32222 0 4.2108e+06
+0.74459 0.32192 0 4.2108e+06
+0.69927 0.32278 0 4.2108e+06
+0.8102 0.29315 0 4.2108e+06
+0.75504 0.29765 0 4.2108e+06
+0.8102 0.24399 0 4.2108e+06
+0.74995 0.24723 0 4.2108e+06
+0.68049 0.29768 0 4.2108e+06
+0.66509 0.29002 0 4.2108e+06
+0.69441 0.2526 0 4.2108e+06
+0.62807 0.22187 0 4.2108e+06
+0.58706 0.32199 0 4.2108e+06
+0.52125 0.31955 0 4.2108e+06
+0.49351 0.32282 0 4.2108e+06
+0.44313 0.32169 0 4.2108e+06
+0.58678 0.2929 0 4.2108e+06
+0.53436 0.29164 0 4.2108e+06
+0.59308 0.24134 0 4.2108e+06
+0.5357 0.2444 0 4.2108e+06
+0.50043 0.31235 0 4.2108e+06
+0.44107 0.29711 0 4.2108e+06
+0.50727 0.22193 0 4.2108e+06
+0.43957 0.23976 0 4.2108e+06
+0.8105 0.21112 0 4.2108e+06
+0.73555 0.2114 0 4.2108e+06
+0.69907 0.21082 0 4.2108e+06
+0.63327 0.21154 0 4.2108e+06
+0.59165 0.21201 0 4.2108e+06
+0.52477 0.21491 0 4.2108e+06
+0.49375 0.21006 0 4.2108e+06
+0.4384 0.19632 0 4.2108e+06
+0.43425 0.16052 0 4.2108e+06
+0.3787 0.32173 0 4.2108e+06
+0.33444 0.3216 0 4.2108e+06
+0.23815 0.32199 0 4.808e+06
+0.3788 0.29315 0 4.2108e+06
+0.33058 0.31073 0 4.2108e+06
+0.3788 0.24399 0 4.2108e+06
+0.30249 0.29189 0 4.2108e+06
+0.23492 0.29446 0 4.808e+06
+0.29465 0.24399 0 4.2108e+06
+0.23514 0.24172 0 4.808e+06
+0.18836 0.32277 0 4.808e+06
+0.15992 0.32176 0 4.808e+06
+0.08642 0.32181 0 4.808e+06
+0.039994 0.32283 0 4.808e+06
+0.20039 0.31211 0 4.808e+06
+0.1417 0.29506 0 4.808e+06
+0.20921 0.22332 0 4.808e+06
+0.13884 0.24227 0 4.808e+06
+0.085123 0.29441 0 4.808e+06
+0.048446 0.31279 0 4.808e+06
+0.086957 0.24399 0 4.808e+06
+0.3788 0.21189 0 4.2108e+06
+0.29465 0.19323 0 4.2108e+06
+0.23755 0.19348 0 4.808e+06
+0.29463 0.16054 0 4.2108e+06
+0.23776 0.16054 0 4.808e+06
+0.19016 0.21038 0 4.808e+06
+0.15704 0.21245 0 4.808e+06
+0.08678 0.21169 0 4.808e+06
+0.012746 0.32168 0 4.808e+06
+-0.075715 0.32095 0 4.808e+06
+-0.10622 0.32304 0 4.808e+06
+-0.16391 0.32118 0 4.808e+06
+0.00088411 0.29487 0 4.808e+06
+-0.057568 0.29457 0 4.808e+06
+-0.0034333 0.24399 0 4.808e+06
+-0.055185 0.24185 0 4.808e+06
+-0.10983 0.31352 0 4.808e+06
+-0.15082 0.29453 0 4.808e+06
+-0.11534 0.22049 0 4.808e+06
+-0.15155 0.24381 0 4.808e+06
+-0.1912 0.32173 0 4.808e+06
+-0.281 0.3185 0 4.808e+06
+-0.30791 0.32307 0 4.808e+06
+-0.33854 0.32148 0 4.808e+06
+-0.21248 0.29805 0 4.808e+06
+-0.26372 0.29905 0 4.808e+06
+-0.22562 0.24399 0 4.808e+06
+-0.25035 0.2371 0 4.808e+06
+-0.29941 0.31191 0 4.808e+06
+-0.35845 0.2954 0 4.808e+06
+-0.29231 0.22236 0 4.808e+06
+-0.36101 0.24172 0 4.808e+06
+-0.0034393 0.21129 0 4.808e+06
+-0.07306 0.21304 0 4.808e+06
+-0.10579 0.2099 0 4.808e+06
+-0.13642 0.21411 0 4.808e+06
+-0.22562 0.19323 0 4.808e+06
+-0.24439 0.19799 0 4.808e+06
+-0.22591 0.16041 0 4.808e+06
+-0.23466 0.16082 0 4.808e+06
+-0.3077 0.20998 0 4.808e+06
+-0.3413 0.21239 0 4.808e+06
+-0.40551 0.32178 0 4.2108e+06
+-0.50568 0.3218 0 4.2108e+06
+-0.41732 0.30844 0 4.2108e+06
+-0.44237 0.28859 0 4.2108e+06
+-0.41591 0.22004 0 4.2108e+06
+-0.44803 0.24236 0 4.2108e+06
+-0.50623 0.29315 0 4.2108e+06
+-0.50916 0.24296 0 4.2108e+06
+-0.57019 0.22334 0 4.2108e+06
+-0.59611 0.32199 0 4.2108e+06
+-0.65104 0.32199 0 4.2108e+06
+-0.72566 0.32129 0 4.2108e+06
+-0.75538 0.32301 0 4.2108e+06
+-0.59653 0.29315 0 4.2108e+06
+-0.65063 0.29315 0 4.2108e+06
+-0.59478 0.24245 0 4.2108e+06
+-0.65063 0.24399 0 4.2108e+06
+-0.70618 0.29525 0 4.2108e+06
+-0.76203 0.31284 0 4.2108e+06
+-0.70302 0.24183 0 4.2108e+06
+-0.77062 0.22133 0 4.2108e+06
+-0.41545 0.21099 0 4.2108e+06
+-0.45004 0.19812 0 4.2108e+06
+-0.4475 0.1673 0 4.2108e+06
+-0.52031 0.21236 0 4.2108e+06
+-0.55182 0.21045 0 4.2108e+06
+-0.5965 0.21131 0 4.2108e+06
+-0.65064 0.2113 0 4.2108e+06
+-0.72216 0.21286 0 4.2108e+06
+-0.7556 0.20987 0 4.2108e+06
+-0.78343 0.31973 0 4.2108e+06
+-0.87572 0.32111 0 4.2108e+06
+-0.90519 0.32263 0 4.2108e+06
+-0.95526 0.34127 0 4.2108e+06
+-0.79774 0.29271 0 4.2108e+06
+-0.85618 0.29497 0 4.2108e+06
+-0.79975 0.24326 0 4.2108e+06
+-0.8521 0.24246 0 4.2108e+06
+-0.91157 0.31224 0 4.2108e+06
+-0.95031 0.29572 0 4.2108e+06
+-0.92223 0.2213 0 4.2108e+06
+-0.94979 0.24354 0 4.2108e+06
+-0.78641 0.21505 0 4.2108e+06
+-0.87094 0.21237 0 4.2108e+06
+-0.90637 0.20934 0 4.2108e+06
+-0.93777 0.21481 0 4.2108e+06
+0.22244 -0.0296 0 4.808e+06
+0.2704 -0.078167 0 4.808e+06
+0.24416 -0.056883 0 4.808e+06
+0.27311 -0.10653 0 4.808e+06
+0.26172 -0.10653 0 4.808e+06
+0.2704 -0.1349 0 4.808e+06
+0.24428 -0.15599 0 4.808e+06
+0.19017 -0.025297 0 4.808e+06
+0.14248 -0.02428 0 4.808e+06
+0.19815 -0.037432 0 4.808e+06
+0.14248 -0.03515 0 4.808e+06
+0.093313 -0.02428 0 4.808e+06
+0.044144 -0.02428 0 4.808e+06
+0.093313 -0.03515 0 4.808e+06
+0.044144 -0.03515 0 4.808e+06
+0.21156 -0.17357 0 4.808e+06
+0.029114 -0.12594 0 4.2108e+06
+0.036583 -0.15619 0 4.2108e+06
+0.22446 -0.20514 0 4.808e+06
+0.2208 -0.2369 0 4.808e+06
+0.2129 -0.208 0 4.808e+06
+0.19316 -0.25672 0 4.808e+06
+0.14497 -0.27484 0 4.808e+06
+0.030167 -0.18748 0 4.2108e+06
+0.1021 -0.27453 0 4.808e+06
+0.1689 -0.2831 0 4.808e+06
+0.13875 -0.28647 0 4.808e+06
+0.086993 -0.29568 0 4.808e+06
+0.044924 -0.3154 0 4.808e+06
+-0.0066125 -0.02428 0 4.808e+06
+-0.057362 -0.02428 0 4.808e+06
+-0.0066125 -0.03515 0 4.808e+06
+-0.057362 -0.03515 0 4.808e+06
+-0.10653 -0.02428 0 4.808e+06
+-0.15266 -0.025282 0 4.808e+06
+-0.10653 -0.03515 0 4.808e+06
+-0.16036 -0.037257 0 4.808e+06
+0.0083286 -0.1259 0 4.2108e+06
+0.0007442 -0.15603 0 4.2108e+06
+-0.1741 -0.17381 0 4.808e+06
+-0.18502 -0.02954 0 4.808e+06
+-0.20707 -0.056403 0 4.808e+06
+-0.23348 -0.07764 0 4.808e+06
+-0.2244 -0.10653 0 4.808e+06
+-0.23604 -0.10652 0 4.808e+06
+-0.20734 -0.15641 0 4.808e+06
+-0.23348 -0.13542 0 4.808e+06
+0.0061083 -0.18729 0 4.2108e+06
+-0.066235 -0.27472 0 4.808e+06
+-0.17577 -0.20789 0 4.808e+06
+-0.10861 -0.27494 0 4.808e+06
+-0.15584 -0.25716 0 4.808e+06
+-0.0075775 -0.31546 0 4.808e+06
+-0.050817 -0.29595 0 4.808e+06
+-0.10306 -0.28653 0 4.808e+06
+-0.1319 -0.2831 0 4.808e+06
+-0.18716 -0.20571 0 4.808e+06
+-0.18369 -0.23729 0 4.808e+06
diff --git a/release/scripts/addons_contrib/io_scene_cod/__init__.py b/release/scripts/addons_contrib/io_scene_cod/__init__.py
new file mode 100644
index 0000000..1cab6f0
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_cod/__init__.py
@@ -0,0 +1,475 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Blender-CoD: Blender Add-On for Call of Duty modding
+Version: alpha 3
+
+Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
+
+http://code.google.com/p/blender-cod/
+
+TODO
+- UI for xmodel and xanim import (planned for alpha 4/5)
+
+"""
+
+bl_info = {
+ "name": "Blender-CoD - Add-On for Call of Duty modding (alpha 3)",
+ "author": "CoDEmanX, Flybynyt",
+ "version": (0, 3, 5),
+ "blender": (2, 62, 0),
+ "location": "File > Import | File > Export",
+ "description": "Export models to *.XMODEL_EXPORT and animations to *.XANIM_EXPORT",
+ "warning": "Alpha version, please report any bugs!",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/Call_of_Duty_IO",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=30482",
+ "support": "TESTING",
+ "category": "Import-Export"
+}
+
+# To support reload properly, try to access a package var, if it's there, reload everything
+if "bpy" in locals():
+ import imp
+ if "import_xmodel" in locals():
+ imp.reload(import_xmodel)
+ if "export_xmodel" in locals():
+ imp.reload(export_xmodel)
+ if "import_xanim" in locals():
+ imp.reload(import_xanim)
+ if "export_xanim" in locals():
+ imp.reload(export_xanim)
+
+import bpy
+from bpy.props import BoolProperty, IntProperty, FloatProperty, StringProperty, EnumProperty
+import bpy_extras.io_utils
+from bpy_extras.io_utils import ExportHelper, ImportHelper
+import time
+
+# Planned for alpha 4/5
+class ImportXmodel(bpy.types.Operator, ImportHelper):
+ """Load a CoD XMODEL_EXPORT File"""
+ bl_idname = "import_scene.xmodel"
+ bl_label = "Import XMODEL_EXPORT"
+ bl_options = {'PRESET'}
+
+ filename_ext = ".XMODEL_EXPORT"
+ filter_glob = StringProperty(default="*.XMODEL_EXPORT", options={'HIDDEN'})
+
+ #use_meshes = BoolProperty(name="Meshes", description="Import meshes", default=True)
+ #use_armature = BoolProperty(name="Armature", description="Import Armature", default=True)
+ #use_bind_armature = BoolProperty(name="Bind Meshes to Armature", description="Parent imported meshes to armature", default=True)
+
+ #use_split_objects = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default=True)
+ #use_split_groups = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default=True)
+
+ #use_image_search = BoolProperty(name="Image Search", description="Search subdirs for any associated images (Warning, may be slow)", default=True)
+
+ def execute(self, context):
+ from . import import_xmodel
+ start_time = time.clock()
+ result = import_xmodel.load(self, context, **self.as_keywords(ignore=("filter_glob", "check_existing")))
+
+ if not result:
+ self.report({'INFO'}, "Import finished in %.4f sec." % (time.clock() - start_time))
+ return {'FINISHED'}
+ else:
+ self.report({'ERROR'}, result)
+ return {'CANCELLED'}
+
+ """
+ def draw(self, context):
+ layout = self.layout
+
+ col = layout.column()
+ col.prop(self, "use_meshes")
+ col.prop(self, "use_armature")
+
+ row = layout.row()
+ row.active = self.use_meshes and self.use_armature
+ row.prop(self, "use_bind_armature")
+ """
+
+ @classmethod
+ def poll(self, context):
+ return (context.scene is not None)
+
+class ImportXanim(bpy.types.Operator, ImportHelper):
+ """Load a CoD XANIM_EXPORT File"""
+ bl_idname = "import_scene.xanim"
+ bl_label = "Import XANIM_EXPORT"
+ bl_options = {'PRESET'}
+
+ filename_ext = ".XANIM_EXPORT"
+ filter_glob = StringProperty(default="*.XANIM_EXPORT;*.NT_EXPORT", options={'HIDDEN'})
+
+ def execute(self, context):
+ # print("Selected: " + context.active_object.name)
+ from . import import_xanim
+
+ return import_xanim.load(self, context, **self.as_keywords(ignore=("filter_glob",)))
+
+class ExportXmodel(bpy.types.Operator, ExportHelper):
+ """Save a CoD XMODEL_EXPORT File"""
+
+ bl_idname = "export_scene.xmodel"
+ bl_label = 'Export XMODEL_EXPORT'
+ bl_options = {'PRESET'}
+
+ filename_ext = ".XMODEL_EXPORT"
+ filter_glob = StringProperty(default="*.XMODEL_EXPORT", options={'HIDDEN'})
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ use_version = EnumProperty(
+ name="Format Version",
+ description="XMODEL_EXPORT format version for export",
+ items=(('5', "Version 5", "vCoD, CoD:UO"),
+ ('6', "Version 6", "CoD2, CoD4, CoD5, CoD7")),
+ default='6',
+ )
+
+ use_selection = BoolProperty(
+ name="Selection only",
+ description="Export selected meshes only (object or weight paint mode)",
+ default=False
+ )
+
+ use_vertex_colors = BoolProperty(
+ name="Vertex colors",
+ description="Export vertex colors (if disabled, white color will be used)",
+ default=True
+ )
+
+ use_vertex_colors_alpha = BoolProperty(
+ name="As alpha",
+ description="Turn RGB vertex colors into grayscale (average value) and use it as alpha transparency. White is 1 (opaque), black 0 (invisible)",
+ default=False
+ )
+
+ use_apply_modifiers = BoolProperty(
+ name="Apply Modifiers",
+ description="Apply all mesh modifiers except Armature (preview resolution)",
+ default=True
+ )
+
+ use_armature = BoolProperty(
+ name="Armature",
+ description="Export bones (if disabled, only a 'tag_origin' bone will be written)",
+ default=True
+ )
+
+ use_vertex_cleanup = BoolProperty(
+ name="Clean up vertices",
+ description="Try this if you have problems converting to xmodel. Skips vertices which aren't used by any face and updates references.",
+ default=False
+ )
+
+ use_armature_pose = BoolProperty(
+ name="Pose animation to models",
+ description="Export meshes with Armature modifier applied as a series of XMODEL_EXPORT files",
+ default=False
+ )
+
+ use_frame_start = IntProperty(
+ name="Start",
+ description="First frame to export",
+ default=1,
+ min=0
+ )
+
+ use_frame_end = IntProperty(
+ name="End",
+ description="Last frame to export",
+ default=250,
+ min=0
+ )
+
+ use_weight_min = BoolProperty(
+ name="Minimum bone weight",
+ description="Try this if you get 'too small weight' errors when converting",
+ default=False,
+ )
+
+ use_weight_min_threshold = FloatProperty(
+ name="Threshold",
+ description="Smallest allowed weight (minimum value)",
+ default=0.010097,
+ min=0.0,
+ max=1.0,
+ precision=6
+ )
+
+ def execute(self, context):
+ from . import export_xmodel
+ start_time = time.clock()
+ result = export_xmodel.save(self, context, **self.as_keywords(ignore=("filter_glob", "check_existing")))
+
+ if not result:
+ self.report({'INFO'}, "Export finished in %.4f sec." % (time.clock() - start_time))
+ return {'FINISHED'}
+ else:
+ self.report({'ERROR'}, result)
+ return {'CANCELLED'}
+
+ # Extend ExportHelper invoke function to support dynamic default values
+ def invoke(self, context, event):
+
+ #self.use_frame_start = context.scene.frame_start
+ self.use_frame_start = context.scene.frame_current
+
+ #self.use_frame_end = context.scene.frame_end
+ self.use_frame_end = context.scene.frame_current
+
+ return super().invoke(context, event)
+
+ def draw(self, context):
+ layout = self.layout
+
+ row = layout.row(align=True)
+ row.prop(self, "use_version", expand=True)
+
+ # Calculate number of selected mesh objects
+ if context.mode in {'OBJECT', 'PAINT_WEIGHT'}:
+ meshes_selected = len([m for m in bpy.data.objects if m.type == 'MESH' and m.select])
+ else:
+ meshes_selected = 0
+
+ col = layout.column(align=True)
+ col.prop(self, "use_selection", "Selection only (%i meshes)" % meshes_selected)
+ col.enabled = bool(meshes_selected)
+
+ col = layout.column(align=True)
+ col.prop(self, "use_apply_modifiers")
+
+ col = layout.column(align=True)
+ col.enabled = not self.use_armature_pose
+ if self.use_armature and self.use_armature_pose:
+ col.prop(self, "use_armature", "Armature (disabled)")
+ else:
+ col.prop(self, "use_armature")
+
+ if self.use_version == '6':
+
+ row = layout.row(align=True)
+ row.prop(self, "use_vertex_colors")
+
+ sub = row.split()
+ sub.active = self.use_vertex_colors
+ sub.prop(self, "use_vertex_colors_alpha")
+
+ col = layout.column(align=True)
+ col.label("Advanced:")
+
+ col = layout.column(align=True)
+ col.prop(self, "use_vertex_cleanup")
+
+ box = layout.box()
+
+ col = box.column(align=True)
+ col.prop(self, "use_armature_pose")
+
+ sub = box.column()
+ sub.active = self.use_armature_pose
+ sub.label(text="Frame range: (%i frames)" % (abs(self.use_frame_end - self.use_frame_start) + 1))
+
+ row = sub.row(align=True)
+ row.prop(self, "use_frame_start")
+ row.prop(self, "use_frame_end")
+
+ box = layout.box()
+
+ col = box.column(align=True)
+ col.prop(self, "use_weight_min")
+
+ sub = box.column()
+ sub.enabled = self.use_weight_min
+ sub.prop(self, "use_weight_min_threshold")
+
+ @classmethod
+ def poll(self, context):
+ return (context.scene is not None)
+
+class ExportXanim(bpy.types.Operator, ExportHelper):
+ """Save a XMODEL_XANIM File"""
+
+ bl_idname = "export_scene.xanim"
+ bl_label = 'Export XANIM_EXPORT'
+ bl_options = {'PRESET'}
+
+ filename_ext = ".XANIM_EXPORT"
+ filter_glob = StringProperty(default="*.XANIM_EXPORT", options={'HIDDEN'})
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ use_selection = BoolProperty(
+ name="Selection only",
+ description="Export selected bones only (pose mode)",
+ default=False
+ )
+
+ use_framerate = IntProperty(
+ name="Framerate",
+ description="Set frames per second for export, 30 fps is commonly used.",
+ default=24,
+ min=1,
+ max=100
+ )
+
+ use_frame_start = IntProperty(
+ name="Start",
+ description="First frame to export",
+ default=1,
+ min=0
+ )
+
+ use_frame_end = IntProperty(
+ name="End",
+ description="Last frame to export",
+ default=250,
+ min=0
+ )
+
+ use_notetrack = BoolProperty(
+ name="Notetrack",
+ description="Export timeline markers as notetrack nodes",
+ default=True
+ )
+
+ use_notetrack_format = EnumProperty(
+ name="Notetrack format",
+ description="Notetrack format to use. Always set 'CoD 7' for Black Ops, even if not using notetrack!",
+ items=(('5', "CoD 5", "Separate NT_EXPORT notetrack file for 'World at War'"),
+ ('7', "CoD 7", "Separate NT_EXPORT notetrack file for 'Black Ops'"),
+ ('1', "all other", "Inline notetrack data for all CoD versions except WaW and BO")),
+ default='1',
+ )
+
+ def execute(self, context):
+ from . import export_xanim
+ start_time = time.clock()
+ result = export_xanim.save(self, context, **self.as_keywords(ignore=("filter_glob", "check_existing")))
+
+ if not result:
+ self.report({'INFO'}, "Export finished in %.4f sec." % (time.clock() - start_time))
+ return {'FINISHED'}
+ else:
+ self.report({'ERROR'}, result)
+ return {'CANCELLED'}
+
+ # Extend ExportHelper invoke function to support dynamic default values
+ def invoke(self, context, event):
+
+ self.use_frame_start = context.scene.frame_start
+ self.use_frame_end = context.scene.frame_end
+ self.use_framerate = round(context.scene.render.fps / context.scene.render.fps_base)
+
+ return super().invoke(context, event)
+
+ def draw(self, context):
+
+ layout = self.layout
+
+ bones_selected = 0
+ armature = None
+
+ # Take the first armature
+ for ob in bpy.data.objects:
+ if ob.type == 'ARMATURE' and len(ob.data.bones) > 0:
+ armature = ob.data
+
+ # Calculate number of selected bones if in pose-mode
+ if context.mode == 'POSE':
+ bones_selected = len([b for b in armature.bones if b.select])
+
+ # Prepare info string
+ armature_info = "%s (%i bones)" % (ob.name, len(armature.bones))
+ break
+ else:
+ armature_info = "Not found!"
+
+ if armature:
+ icon = 'NONE'
+ else:
+ icon = 'ERROR'
+
+ col = layout.column(align=True)
+ col.label("Armature: %s" % armature_info, icon)
+
+ col = layout.column(align=True)
+ col.prop(self, "use_selection", "Selection only (%i bones)" % bones_selected)
+ col.enabled = bool(bones_selected)
+
+ layout.label(text="Frame range: (%i frames)" % (abs(self.use_frame_end - self.use_frame_start) + 1))
+
+ row = layout.row(align=True)
+ row.prop(self, "use_frame_start")
+ row.prop(self, "use_frame_end")
+
+ col = layout.column(align=True)
+ col.prop(self, "use_framerate")
+
+ # Calculate number of markers in export range
+ frame_min = min(self.use_frame_start, self.use_frame_end)
+ frame_max = max(self.use_frame_start, self.use_frame_end)
+ num_markers = len([m for m in context.scene.timeline_markers if frame_max >= m.frame >= frame_min])
+
+ col = layout.column(align=True)
+ col.prop(self, "use_notetrack", text="Notetrack (%i nodes)" % num_markers)
+
+ col = layout.column(align=True)
+ col.prop(self, "use_notetrack_format", expand=True)
+
+ @classmethod
+ def poll(self, context):
+ return (context.scene is not None)
+
+def menu_func_xmodel_import(self, context):
+ self.layout.operator(ImportXmodel.bl_idname, text="CoD Xmodel (.XMODEL_EXPORT)")
+"""
+def menu_func_xanim_import(self, context):
+ self.layout.operator(ImportXanim.bl_idname, text="CoD Xanim (.XANIM_EXPORT)")
+"""
+def menu_func_xmodel_export(self, context):
+ self.layout.operator(ExportXmodel.bl_idname, text="CoD Xmodel (.XMODEL_EXPORT)")
+
+def menu_func_xanim_export(self, context):
+ self.layout.operator(ExportXanim.bl_idname, text="CoD Xanim (.XANIM_EXPORT)")
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_file_import.append(menu_func_xmodel_import)
+ #bpy.types.INFO_MT_file_import.append(menu_func_xanim_import)
+ bpy.types.INFO_MT_file_export.append(menu_func_xmodel_export)
+ bpy.types.INFO_MT_file_export.append(menu_func_xanim_export)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_file_import.remove(menu_func_xmodel_import)
+ #bpy.types.INFO_MT_file_import.remove(menu_func_xanim_import)
+ bpy.types.INFO_MT_file_export.remove(menu_func_xmodel_export)
+ bpy.types.INFO_MT_file_export.remove(menu_func_xanim_export)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_scene_cod/export_xanim.py b/release/scripts/addons_contrib/io_scene_cod/export_xanim.py
new file mode 100644
index 0000000..c3d00fc
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_cod/export_xanim.py
@@ -0,0 +1,231 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Blender-CoD: Blender Add-On for Call of Duty modding
+Version: alpha 3
+
+Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
+
+http://code.google.com/p/blender-cod/
+
+TODO
+- Test pose matrix exports, global or local?
+
+"""
+
+import bpy
+from datetime import datetime
+
+def save(self, context, filepath="",
+ use_selection=False,
+ use_framerate=24,
+ use_frame_start=1,
+ use_frame_end=250,
+ use_notetrack=True,
+ use_notetrack_format='1'):
+
+ armature = None
+ last_frame_current = context.scene.frame_current
+
+ # There's no context object right after object deletion, need to set one
+ if context.object:
+ last_mode = context.object.mode
+ else:
+ last_mode = 'OBJECT'
+
+ if bpy.data.objects:
+ context.scene.objects.active = bpy.data.objects[0]
+ else:
+ return "Nothing to export."
+
+ # HACK: Force an update, so that bone tree is properly sorted for hierarchy table export
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ # Check input objects, don't move this above hack!
+ for ob in bpy.data.objects:
+
+ # Take the first armature
+ if ob.type == 'ARMATURE' and len(ob.data.bones) > 0:
+ armature = ob
+ break
+ else:
+ return "No armature to export."
+
+ # Get the wanted bones
+ if use_selection:
+ bones = [b for b in armature.data.bones if b.select]
+ else:
+ bones = armature.data.bones
+
+ # Get armature matrix once for later global coords/matrices calculation per frame
+ a_matrix = armature.matrix_world
+
+ # There's valid data for export, create output file
+ try:
+ file = open(filepath, "w")
+ except IOError:
+ return "Could not open file for writing:\n%s" % filepath
+
+ # write the header
+ file.write("// XANIM_EXPORT file in CoD animation v3 format created with Blender v%s\n" \
+ % bpy.app.version_string)
+ file.write("// Source file: %s\n" % filepath)
+ file.write("// Export time: %s\n\n" % datetime.now().strftime("%d-%b-%Y %H:%M:%S"))
+ file.write("ANIMATION\n")
+ file.write("VERSION 3\n\n")
+
+ file.write("NUMPARTS %i\n" % len(bones))
+
+ # Write bone table
+ for i_bone, bone in enumerate(bones):
+ file.write("PART %i \"%s\"\n" % (i_bone, bone.name))
+
+ # Exporter shall use Blender's framerate (render settings, used as playback speed)
+ # Note: Time remapping not taken into account
+ file.write("\nFRAMERATE %i\n" % use_framerate)
+
+ file.write("NUMFRAMES %i\n\n" % (abs(use_frame_start - use_frame_end) + 1))
+
+ # If start frame greater than end frame, export animation reversed
+ if use_frame_start < use_frame_end:
+ frame_order = 1
+ frame_min = use_frame_start
+ frame_max = use_frame_end
+ else:
+ frame_order = -1
+ frame_min = use_frame_end
+ frame_max = use_frame_start
+
+ for i_frame, frame in enumerate(range(use_frame_start,
+ use_frame_end + frame_order,
+ frame_order),
+ frame_min):
+
+ file.write("FRAME %i\n" % i_frame)
+
+ # Set frame directly
+ context.scene.frame_set(frame)
+
+ # Get PoseBones for that frame
+ if use_selection:
+ bones = [b for b in armature.pose.bones if b.bone.select]
+ else:
+ bones = armature.pose.bones
+
+ # Write bone orientations
+ for i_bone, bone in enumerate(bones):
+
+ # Skip bone if 'Selection only' is enabled and bone not selected
+ if use_selection and not bone.bone.select: # It's actually posebone.bone!
+ continue
+
+ file.write("PART %i\n" % i_bone)
+
+
+ """ Doesn't seem to be right... or maybe it is? root can't have rotation, it rather sets the global orientation
+ if bone.parent is None:
+ file.write("OFFSET 0.000000 0.000000 0.000000\n")
+ file.write("SCALE 1.000000 1.000000 1.000000\n")
+ file.write("X 1.000000, 0.000000, 0.000000\n")
+ file.write("Y 0.000000, 1.000000, 0.000000\n")
+ file.write("Z 0.000000, 0.000000, 1.000000\n\n")
+ else:
+ """
+
+ b_tail = a_matrix * bone.tail
+ file.write("OFFSET %.6f %.6f %.6f\n" % (b_tail[0], b_tail[1], b_tail[2]))
+ file.write("SCALE 1.000000 1.000000 1.000000\n") # Is this even supported by CoD?
+
+ file.write("X %.6f %.6f %.6f\n" % (bone.matrix[0][0], bone.matrix[1][0], bone.matrix[2][0]))
+ file.write("Y %.6f %.6f %.6f\n" % (bone.matrix[0][1], bone.matrix[1][1], bone.matrix[2][1]))
+ file.write("Z %.6f %.6f %.6f\n\n" % (bone.matrix[0][2], bone.matrix[1][2], bone.matrix[2][2]))
+
+ """
+ # Is a local matrix used (above) or a global?
+ # Rest pose bone roll shouldn't matter if local is used... o_O
+ # Note: Converting to xanim delta doesn't allow bone moves (only root?)
+ b_matrix = a_matrix * bone.matrix
+ file.write("X %.6f %.6f %.6f\n" % (b_matrix[0][0], b_matrix[1][0], b_matrix[2][0]))
+ file.write("Y %.6f %.6f %.6f\n" % (b_matrix[0][1], b_matrix[1][1], b_matrix[2][1]))
+ file.write("Z %.6f %.6f %.6f\n" % (b_matrix[0][2], b_matrix[1][2], b_matrix[2][2]))
+ """
+
+ # Blender timeline markers to notetrack nodes
+ markers = []
+ for m in context.scene.timeline_markers:
+ if frame_max >= m.frame >= frame_min:
+ markers.append([m.frame, m.name])
+ markers = sorted(markers)
+
+ # Cache marker string
+ marker_string = "NUMKEYS %i\n" % len(markers)
+
+ for m in markers:
+ marker_string += "FRAME %i \"%s\"\n" % (m[0], m[1])
+
+ # Write notetrack data
+ if use_notetrack_format == '7':
+ # Always 0 for CoD7, no matter if there are markers or not!
+ file.write("NUMKEYS 0\n")
+ else:
+ file.write("NOTETRACKS\n\n")
+
+ for i_bone, bone in enumerate(bones):
+
+ file.write("PART %i\n" % (i_bone))
+
+ if i_bone == 0 and use_notetrack and use_notetrack_format == '1' and len(markers) > 0:
+
+ file.write("NUMTRACKS 1\n\n")
+ file.write("NOTETRACK 0\n")
+ file.write(marker_string)
+ file.write("\n")
+
+ else:
+ file.write("NUMTRACKS 0\n\n")
+
+ # Close to flush buffers!
+ file.close()
+
+ if use_notetrack and use_notetrack_format in {'5', '7'}:
+
+ import os.path
+ filepath = os.path.splitext(filepath)[0] + ".NT_EXPORT"
+
+ try:
+ file = open(filepath, "w")
+ except IOError:
+ return "Could not open file for writing:\n%s" % filepath
+
+ if use_notetrack_format == '7':
+ file.write("FIRSTFRAME %i\n" % use_frame_start)
+ file.write("NUMFRAMES %i\n" % (abs(use_frame_end - use_frame_start) + 1))
+ file.write(marker_string)
+
+ file.close()
+
+ # Set frame_current and mode back
+ context.scene.frame_set(last_frame_current)
+ bpy.ops.object.mode_set(mode=last_mode, toggle=False)
+
+ # Quit with no errors
+ return
diff --git a/release/scripts/addons_contrib/io_scene_cod/export_xmodel.py b/release/scripts/addons_contrib/io_scene_cod/export_xmodel.py
new file mode 100644
index 0000000..72874c2
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_cod/export_xmodel.py
@@ -0,0 +1,732 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Blender-CoD: Blender Add-On for Call of Duty modding
+Version: alpha 3
+
+Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
+
+http://code.google.com/p/blender-cod/
+
+"""
+
+import bpy
+import os
+from datetime import datetime
+
+def save(self, context, filepath="",
+ use_version='6',
+ use_selection=False,
+ use_apply_modifiers=True,
+ use_armature=True,
+ use_vertex_colors=True,
+ use_vertex_colors_alpha=False,
+ use_vertex_cleanup=False,
+ use_armature_pose=False,
+ use_frame_start=1,
+ use_frame_end=250,
+ use_weight_min=False,
+ use_weight_min_threshold=0.010097):
+
+ # There's no context object right after object deletion, need to set one
+ if context.object:
+ last_mode = context.object.mode
+ else:
+ last_mode = 'OBJECT'
+
+ for ob in bpy.data.objects:
+ if ob.type == 'MESH':
+ context.scene.objects.active = ob
+ break
+ else:
+ return "No mesh to export."
+
+ # HACK: Force an update, so that bone tree is properly sorted for hierarchy table export
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ # Remember frame to set it back after export
+ last_frame_current = context.scene.frame_current
+
+ # Disable Armature for Pose animation export, bone.tail_local not available for PoseBones
+ if use_armature and use_armature_pose:
+ use_armature = False
+
+ # Don't iterate for a single frame
+ if not use_armature_pose or (use_armature_pose and use_frame_start == use_frame_end):
+ context.scene.frame_set(use_frame_start)
+
+ result = _write(self, context, filepath,
+ use_version,
+ use_selection,
+ use_apply_modifiers,
+ use_armature,
+ use_vertex_colors,
+ use_vertex_colors_alpha,
+ use_vertex_cleanup,
+ use_armature_pose,
+ use_weight_min,
+ use_weight_min_threshold)
+ else:
+
+ if use_frame_start < use_frame_end:
+ frame_order = 1
+ frame_min = use_frame_start
+ frame_max = use_frame_end
+ else:
+ frame_order = -1
+ frame_min = use_frame_end
+ frame_max = use_frame_start
+
+ # String length of highest frame number for filename padding
+ frame_strlen = len(str(frame_max))
+
+ filepath_split = os.path.splitext(filepath)
+
+ for i_frame, frame in enumerate(range(use_frame_start,
+ use_frame_end + frame_order,
+ frame_order
+ ),
+ frame_min):
+
+ # Set frame for export
+ # Don't do it directly to frame_current, as to_mesh() won't use updated frame!
+ context.scene.frame_set(frame)
+
+ # Generate filename including padded frame number
+ filepath_frame = "%s_%.*i%s" % (filepath_split[0], frame_strlen, i_frame, filepath_split[1])
+
+ result = _write(self, context, filepath_frame,
+ use_version,
+ use_selection,
+ use_apply_modifiers,
+ use_armature,
+ use_vertex_colors,
+ use_vertex_colors_alpha,
+ use_vertex_cleanup,
+ use_armature_pose,
+ use_weight_min,
+ use_weight_min_threshold
+ )
+
+ # Quit iteration on error
+ if result:
+ context.scene.frame_set(last_frame_current)
+ return result
+
+ # Set frame back
+ context.scene.frame_set(last_frame_current)
+
+ # Set mode back
+ bpy.ops.object.mode_set(mode=last_mode, toggle=False)
+
+ # Handle possible error result of single frame export
+ return result
+
+def _write(self, context, filepath,
+ use_version,
+ use_selection,
+ use_apply_modifiers,
+ use_armature,
+ use_vertex_colors,
+ use_vertex_colors_alpha,
+ use_vertex_cleanup,
+ use_armature_pose,
+ use_weight_min,
+ use_weight_min_threshold):
+
+ num_verts = 0
+ num_verts_unique = 0
+ verts_unique = []
+ num_faces = 0
+ meshes = []
+ meshes_matrix = []
+ meshes_vgroup = []
+ objects = []
+ armature = None
+ bone_mapping = {}
+ materials = []
+
+ ob_count = 0
+ v_count = 0
+
+ # Check input objects, count them and convert mesh objects
+ for ob in bpy.data.objects:
+
+ # Take the first armature
+ if ob.type == 'ARMATURE' and use_armature and armature is None and len(ob.data.bones) > 0:
+ armature = ob
+ continue
+
+ if ob.type != 'MESH':
+ continue
+
+ # Skip meshes, which are unselected
+ if use_selection and not ob.select:
+ continue
+
+ # Set up modifiers whether to apply deformation or not
+ mod_states = []
+ for mod in ob.modifiers:
+ mod_states.append(mod.show_viewport)
+ if mod.type == 'ARMATURE':
+ mod.show_viewport = mod.show_viewport and use_armature_pose
+ else:
+ mod.show_viewport = mod.show_viewport and use_apply_modifiers
+
+ # to_mesh() applies enabled modifiers only
+ mesh = ob.to_mesh(scene=context.scene, apply_modifiers=True, settings='PREVIEW')
+
+ # Restore modifier settings
+ for i, mod in enumerate(ob.modifiers):
+ mod.show_viewport = mod_states[i]
+
+ # Skip invalid meshes
+ if len(mesh.vertices) < 3:
+ _skip_notice(ob.name, mesh.name, "Less than 3 vertices")
+ continue
+ if len(mesh.tessfaces) < 1:
+ _skip_notice(ob.name, mesh.name, "No faces")
+ continue
+ if len(ob.material_slots) < 1:
+ _skip_notice(ob.name, mesh.name, "No material")
+ continue
+ if not mesh.tessface_uv_textures:
+ _skip_notice(ob.name, mesh.name, "No UV texture, not unwrapped?")
+ continue
+
+ meshes.append(mesh)
+ meshes_matrix.append(ob.matrix_world)
+
+ if ob.vertex_groups:
+ meshes_vgroup.append(ob.vertex_groups)
+ else:
+ meshes_vgroup.append(None)
+
+ if use_vertex_cleanup:
+
+ # Retrieve verts which belong to a face
+ verts = []
+ for f in mesh.tessfaces:
+ for v in f.vertices:
+ verts.append(v)
+
+ # Uniquify & sort
+ keys = {}
+ for e in verts:
+ keys[e] = 1
+ verts = list(keys.keys())
+
+ else:
+ verts = [v.index for v in mesh.vertices]
+
+ # Store vert sets, aligned to mesh objects
+ verts_unique.append(verts)
+
+ # As len(mesh.vertices) doesn't take unused verts into account, already count here
+ num_verts_unique += len(verts)
+
+ # Take quads into account!
+ for f in mesh.tessfaces:
+ if len(f.vertices) == 3:
+ num_faces += 1
+ else:
+ num_faces += 2
+
+ objects.append(ob.name)
+
+ if (num_verts or num_faces or len(objects)) == 0:
+ return "Nothing to export.\n" \
+ "Meshes must have at least:\n" \
+ " 3 vertices\n" \
+ " 1 face\n" \
+ " 1 material\n" \
+ " UV mapping"
+
+ # There's valid data for export, create output file
+ try:
+ file = open(filepath, "w")
+ except IOError:
+ return "Could not open file for writing:\n%s" % filepath
+
+ # Write header
+ file.write("// XMODEL_EXPORT file in CoD model v%i format created with Blender v%s\n" \
+ % (int(use_version), bpy.app.version_string))
+
+ file.write("// Source file: %s\n" % bpy.data.filepath)
+ file.write("// Export time: %s\n\n" % datetime.now().strftime("%d-%b-%Y %H:%M:%S"))
+
+ if use_armature_pose:
+ file.write("// Posed model of frame %i\n\n" % bpy.context.scene.frame_current)
+
+ if use_weight_min:
+ file.write("// Minimum bone weight: %f\n\n" % use_weight_min_threshold)
+
+ file.write("MODEL\n")
+ file.write("VERSION %i\n" % int(use_version))
+
+ # Write armature data
+ if armature is None:
+
+ # Default rig
+ file.write("\nNUMBONES 1\n")
+ file.write("BONE 0 -1 \"tag_origin\"\n")
+
+ file.write("\nBONE 0\n")
+
+ if use_version == '5':
+ file.write("OFFSET 0.000000 0.000000 0.000000\n")
+ file.write("SCALE 1.000000 1.000000 1.000000\n")
+ file.write("X 1.000000 0.000000 0.000000\n")
+ file.write("Y 0.000000 1.000000 0.000000\n")
+ file.write("Z 0.000000 0.000000 1.000000\n")
+ else:
+ # Model format v6 has commas
+ file.write("OFFSET 0.000000, 0.000000, 0.000000\n")
+ file.write("SCALE 1.000000, 1.000000, 1.000000\n")
+ file.write("X 1.000000, 0.000000, 0.000000\n")
+ file.write("Y 0.000000, 1.000000, 0.000000\n")
+ file.write("Z 0.000000, 0.000000, 1.000000\n")
+
+ else:
+
+ # Either use posed armature bones for animation to model sequence export
+ if use_armature_pose:
+ bones = armature.pose.bones
+ # Or armature bones in rest pose for regular rigged models
+ else:
+ bones = armature.data.bones
+
+ file.write("\nNUMBONES %i\n" % len(bones))
+
+ # Get the armature object's orientation
+ a_matrix = armature.matrix_world
+
+ # Check for multiple roots, armature should have exactly one
+ roots = 0
+ for bone in bones:
+ if not bone.parent:
+ roots += 1
+ if roots != 1:
+ warning_string = "Warning: %i root bones found in armature object '%s'\n" \
+ % (roots, armature.name)
+ print(warning_string)
+ file.write("// %s" % warning_string)
+
+ # Look up table for bone indices
+ bone_table = [b.name for b in bones]
+
+ # Write bone hierarchy table and create bone_mapping array for later use (vertex weights)
+ for i, bone in enumerate(bones):
+
+ if bone.parent:
+ try:
+ bone_parent_index = bone_table.index(bone.parent.name)
+ except (ValueError):
+ bone_parent_index = 0
+ file.write("// Warning: \"%s\" not found in bone table, binding to root...\n"
+ % bone.parent.name)
+ else:
+ bone_parent_index = -1
+
+ file.write("BONE %i %i \"%s\"\n" % (i, bone_parent_index, bone.name))
+ bone_mapping[bone.name] = i
+
+ # Write bone orientations
+ for i, bone in enumerate(bones):
+ file.write("\nBONE %i\n" % i)
+
+ # Using local tail for proper coordinates
+ b_tail = a_matrix * bone.tail_local
+
+ # TODO: Fix calculation/error: pose animation will use posebones, but they don't have tail_local!
+
+ # TODO: Fix rotation matrix calculation, calculation seems to be wrong...
+ #b_matrix = bone.matrix_local * a_matrix
+ #b_matrix = bone.matrix * a_matrix * bones[0].matrix.inverted()
+ #from mathutils import Matrix
+
+ # Is this the way to go? Or will it fix the root only, but mess up all other roll angles?
+ if i == 0:
+ b_matrix = ((1,0,0),(0,1,0),(0,0,1))
+ else:
+ b_matrix = a_matrix * bone.matrix_local
+ #from mathutils import Matrix
+ #b_matrix = bone.matrix_local * a_matrix * Matrix(((1,-0,0),(0,0,-1),(-0,1,0)))
+
+ if use_version == '5':
+ file.write("OFFSET %.6f %.6f %.6f\n" % (b_tail[0], b_tail[1], b_tail[2]))
+ file.write("SCALE 1.000000 1.000000 1.000000\n") # Is this even supported by CoD?
+ file.write("X %.6f %.6f %.6f\n" % (b_matrix[0][0], b_matrix[1][0], b_matrix[2][0]))
+ file.write("Y %.6f %.6f %.6f\n" % (b_matrix[0][1], b_matrix[1][1], b_matrix[2][1]))
+ file.write("Z %.6f %.6f %.6f\n" % (b_matrix[0][2], b_matrix[1][2], b_matrix[2][2]))
+ else:
+ file.write("OFFSET %.6f, %.6f, %.6f\n" % (b_tail[0], b_tail[1], b_tail[2]))
+ file.write("SCALE 1.000000, 1.000000, 1.000000\n")
+ file.write("X %.6f, %.6f, %.6f\n" % (b_matrix[0][0], b_matrix[1][0], b_matrix[2][0]))
+ file.write("Y %.6f, %.6f, %.6f\n" % (b_matrix[0][1], b_matrix[1][1], b_matrix[2][1]))
+ file.write("Z %.6f, %.6f, %.6f\n" % (b_matrix[0][2], b_matrix[1][2], b_matrix[2][2]))
+
+ # Write vertex data
+ file.write("\nNUMVERTS %i\n" % num_verts_unique)
+
+ for i, me in enumerate(meshes):
+
+ # Get the right object matrix for mesh
+ mesh_matrix = meshes_matrix[i]
+
+ # Get bone influences per vertex
+ if armature is not None and meshes_vgroup[i] is not None:
+
+ groupNames, vWeightList = meshNormalizedWeights(meshes_vgroup[i],
+ me,
+ use_weight_min,
+ use_weight_min_threshold
+ )
+ # Get bones by vertex_group names, bind to root if can't find one
+ groupIndices = [bone_mapping.get(g, -1) for g in groupNames]
+
+ weight_group_list = []
+ for weights in vWeightList:
+ weight_group_list.append(sorted(zip(weights, groupIndices), reverse=True))
+
+ # Use uniquified vert sets and count the verts
+ for i_vert, vert in enumerate(verts_unique[i]):
+ v = me.vertices[vert]
+
+ # Calculate global coords
+ x = mesh_matrix[0][0] * v.co[0] + \
+ mesh_matrix[0][1] * v.co[1] + \
+ mesh_matrix[0][2] * v.co[2] + \
+ mesh_matrix[0][3]
+
+ y = mesh_matrix[1][0] * v.co[0] + \
+ mesh_matrix[1][1] * v.co[1] + \
+ mesh_matrix[1][2] * v.co[2] + \
+ mesh_matrix[1][3]
+
+ z = mesh_matrix[2][0] * v.co[0] + \
+ mesh_matrix[2][1] * v.co[1] + \
+ mesh_matrix[2][2] * v.co[2] + \
+ mesh_matrix[2][3]
+
+ #print("%.6f %.6f %.6f single calced xyz\n%.6f %.6f %.6f mat mult" % (x, y, z, ))
+
+ file.write("VERT %i\n" % (i_vert + v_count))
+
+ if use_version == '5':
+ file.write("OFFSET %.6f %.6f %.6f\n" % (x, y, z))
+ else:
+ file.write("OFFSET %.6f, %.6f, %.6f\n" % (x, y, z))
+
+ # Write bone influences
+ if armature is None or meshes_vgroup[i] is None:
+ file.write("BONES 1\n")
+ file.write("BONE 0 1.000000\n\n")
+ else:
+ cache = ""
+ c_bones = 0
+
+ for weight, bone_index in weight_group_list[v.index]:
+ if (use_weight_min and round(weight, 6) < use_weight_min_threshold) or \
+ (not use_weight_min and round(weight, 6) == 0):
+ # No (more) bones with enough weight, totalweight of 0 would lead to error
+ break
+ cache += "BONE %i %.6f\n" % (bone_index, weight)
+ c_bones += 1
+
+ if c_bones == 0:
+ warning_string = "Warning: No bone influence found for vertex %i, binding to bone %i\n" \
+ % (v.index, bone_index)
+ print(warning_string)
+ file.write("// %s" % warning_string)
+ file.write("BONES 1\n")
+ file.write("BONE %i 0.000001\n\n" % bone_index) # HACK: Is a minimum weight a good idea?
+ else:
+ file.write("BONES %i\n%s\n" % (c_bones, cache))
+
+ v_count += len(verts_unique[i]);
+
+ # TODO: Find a better way to keep track of the vertex index?
+ v_count = 0
+
+ # Prepare material array
+ for me in meshes:
+ for f in me.tessfaces:
+ try:
+ mat = me.materials[f.material_index]
+ except (IndexError):
+ # Mesh has no material with this index
+ # Note: material_index is never None (will be 0 instead)
+ continue
+ else:
+ if mat not in materials:
+ materials.append(mat)
+
+ # Write face data
+ file.write("\nNUMFACES %i\n" % num_faces)
+
+ for i_me, me in enumerate(meshes):
+
+ #file.write("// Verts:\n%s\n" % list(enumerate(verts_unique[i_me])))
+
+ for f in me.tessfaces:
+
+ try:
+ mat = me.materials[f.material_index]
+
+ except (IndexError):
+ mat_index = 0
+
+ warning_string = "Warning: Assigned material with index %i not found, falling back to first\n" \
+ % f.material_index
+ print(warning_string)
+ file.write("// %s" % warning_string)
+
+ else:
+ try:
+ mat_index = materials.index(mat)
+
+ except (ValueError):
+ mat_index = 0
+
+ warning_string = "Warning: Material \"%s\" not mapped, falling back to first\n" \
+ % mat.name
+ print(warning_string)
+ file.write("// %s" % warning_string)
+
+ # Support for vertex colors
+ if me.tessface_vertex_colors:
+ col = me.tessface_vertex_colors.active.data[f.index]
+
+ # Automatic triangulation support
+ f_v_orig = [v for v in enumerate(f.vertices)]
+
+ if len(f_v_orig) == 3:
+ f_v_iter = (f_v_orig[2], f_v_orig[1], f_v_orig[0]), # HACK: trailing comma to force a tuple
+ else:
+ f_v_iter = (f_v_orig[2], f_v_orig[1], f_v_orig[0]), (f_v_orig[3], f_v_orig[2], f_v_orig[0])
+
+ for iter in f_v_iter:
+
+ # TODO: Test material# export (v5 correct?)
+ if use_version == '5':
+ file.write("TRI %i %i 0 1\n" % (ob_count, mat_index))
+ else:
+ file.write("TRI %i %i 0 0\n" % (ob_count, mat_index))
+
+ for vi, v in iter:
+
+ no = me.vertices[v].normal # Invert? Orientation seems to have no effect...
+
+ uv = me.tessface_uv_textures.active
+ uv1 = uv.data[f.index].uv[vi][0]
+ uv2 = 1 - uv.data[f.index].uv[vi][1] # Flip!
+
+ #if 0 > uv1 > 1
+ # TODO: Warn if accidentally tiling ( uv <0 or >1 )
+
+ # Remap vert indices used by face
+ if use_vertex_cleanup:
+ vert_new = verts_unique[i_me].index(v) + v_count
+ #file.write("// %i (%i) --> %i\n" % (v+v_count, v, vert_new))
+ else:
+ vert_new = v + v_count
+
+ if use_version == '5':
+ file.write("VERT %i %.6f %.6f %.6f %.6f %.6f\n" \
+ % (vert_new, uv1, uv2, no[0], no[1], no[2]))
+ else:
+ file.write("VERT %i\n" % vert_new)
+ file.write("NORMAL %.6f %.6f %.6f\n" % (no[0], no[1], no[2]))
+
+ if me.tessface_vertex_colors and use_vertex_colors:
+
+ if vi == 0:
+ c = col.color1
+ elif vi == 1:
+ c = col.color2
+ elif vi == 2:
+ c = col.color3
+ else:
+ c = col.color4
+
+ if use_vertex_colors_alpha:
+
+ # Turn RGB into grayscale (luminance conversion)
+ c_lum = c[0] * 0.3 + c[1] * 0.59 + c[2] * 0.11
+ file.write("COLOR 1.000000 1.000000 1.000000 %.6f\n" % c_lum)
+ else:
+ file.write("COLOR %.6f %.6f %.6f 1.000000\n" % (c[0], c[1], c[2]))
+
+ else:
+ file.write("COLOR 1.000000 1.000000 1.000000 1.000000\n")
+
+ file.write("UV 1 %.6f %.6f\n" % (uv1, uv2))
+
+ # Note: Face types (tris/quads) have nothing to do with vert indices!
+ if use_vertex_cleanup:
+ v_count += len(verts_unique[i_me])
+ else:
+ v_count += len(me.vertices)
+
+ ob_count += 1
+
+ # Write object data
+ file.write("\nNUMOBJECTS %i\n" % len(objects))
+
+ for i_ob, ob in enumerate(objects):
+ file.write("OBJECT %i \"%s\"\n" % (i_ob, ob))
+
+ # Static material string
+ material_string = ("COLOR 0.000000 0.000000 0.000000 1.000000\n"
+ "TRANSPARENCY 0.000000 0.000000 0.000000 1.000000\n"
+ "AMBIENTCOLOR 0.000000 0.000000 0.000000 1.000000\n"
+ "INCANDESCENCE 0.000000 0.000000 0.000000 1.000000\n"
+ "COEFFS 0.800000 0.000000\n"
+ "GLOW 0.000000 0\n"
+ "REFRACTIVE 6 1.000000\n"
+ "SPECULARCOLOR -1.000000 -1.000000 -1.000000 1.000000\n"
+ "REFLECTIVECOLOR -1.000000 -1.000000 -1.000000 1.000000\n"
+ "REFLECTIVE -1 -1.000000\n"
+ "BLINN -1.000000 -1.000000\n"
+ "PHONG -1.000000\n\n"
+ )
+
+ if len(materials) > 0:
+ file.write("\nNUMMATERIALS %i\n" % len(materials))
+
+ for i_mat, mat in enumerate(materials):
+
+ try:
+ for i_ts, ts in enumerate(mat.texture_slots):
+
+ # Skip empty slots and disabled textures
+ if not ts or not mat.use_textures[i_ts]:
+ continue
+
+ # Image type and Color map? If yes, add to material array and index
+ if ts.texture.type == 'IMAGE' and ts.use_map_color_diffuse:
+
+ # Pick filename of the first color map
+ imagepath = ts.texture.image.filepath
+ imagename = os.path.split(imagepath)[1]
+ if len(imagename) == 0:
+ imagename = "untitled"
+ break
+ else:
+ raise(ValueError)
+
+ except:
+ imagename = "no color diffuse map found"
+
+ # Material can be assigned and None
+ if mat:
+ mat_name = mat.name
+ mat_shader = mat.diffuse_shader.capitalize()
+ else:
+ mat_name = "None"
+ mat_shader = "Lambert"
+
+ if use_version == '5':
+ file.write("MATERIAL %i \"%s\"\n" % (i_mat, imagename))
+ # or is it mat.name at filename?
+ else:
+ file.write("MATERIAL %i \"%s\" \"%s\" \"%s\"\n" % (
+ i_mat,
+ mat_name,
+ mat_shader,
+ imagename
+ ))
+ file.write(material_string)
+ else:
+ # Write a default material
+ # Should never happen, nothing to export / mesh without material exceptions already caught
+ file.write("\nNUMMATERIALS 1\n")
+ if use_version == '5':
+ file.write("MATERIAL 0 \"default.tga\"\n")
+ else:
+ file.write("MATERIAL 0 \"$default\" \"Lambert\" \"untitled\"\n")
+ file.write(material_string)
+
+ # Close to flush buffers!
+ file.close()
+
+ # Remove meshes, which were made by to_mesh()
+ for mesh in meshes:
+ mesh.user_clear()
+ bpy.data.meshes.remove(mesh)
+
+ # Quit with no errors
+ return
+
+# Taken from export_fbx.py by Campbell Barton
+# Modified to accept vertex_groups directly instead of mesh object
+def BPyMesh_meshWeight2List(vgroup, me):
+
+ """ Takes a mesh and return its group names and a list of lists, one list per vertex.
+ aligning the each vert list with the group names, each list contains float value for the weight.
+ These 2 lists can be modified and then used with list2MeshWeight to apply the changes.
+ """
+
+ # Clear the vert group.
+ groupNames = [g.name for g in vgroup]
+ len_groupNames = len(groupNames)
+
+ if not len_groupNames:
+ # no verts? return a vert aligned empty list
+ #return [[] for i in range(len(me.vertices))], []
+ return [], []
+
+ else:
+ vWeightList = [[0.0] * len_groupNames for i in range(len(me.vertices))]
+
+ for i, v in enumerate(me.vertices):
+ for g in v.groups:
+ # possible weights are out of range
+ index = g.group
+ if index < len_groupNames:
+ vWeightList[i][index] = g.weight
+
+ return groupNames, vWeightList
+
+def meshNormalizedWeights(vgroup, me, weight_min, weight_min_threshold):
+
+ groupNames, vWeightList = BPyMesh_meshWeight2List(vgroup, me)
+
+ if not groupNames:
+ return [], []
+
+ for vWeights in vWeightList:
+ tot = 0.0
+ for w in vWeights:
+ if weight_min and w < weight_min_threshold:
+ w = 0.0
+ tot += w
+
+ if tot:
+ for j, w in enumerate(vWeights):
+ vWeights[j] = w / tot
+
+ return groupNames, vWeightList
+
+def _skip_notice(ob_name, mesh_name, notice):
+ print("\nSkipped object \"%s\" (mesh \"%s\"): %s" % (ob_name, mesh_name, notice))
diff --git a/release/scripts/addons_contrib/io_scene_cod/import_xanim.py b/release/scripts/addons_contrib/io_scene_cod/import_xanim.py
new file mode 100644
index 0000000..4d79034
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_cod/import_xanim.py
@@ -0,0 +1,38 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Blender-CoD: Blender Add-On for Call of Duty modding
+Version: alpha 3
+
+Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
+
+http://code.google.com/p/blender-cod/
+
+TODO
+- Implement xanim import (apply anim data to the armature of a loaded model)
+
+"""
+
+def load(self, context, **keywords):
+
+ #filepath = os.fsencode(filepath)
+
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/io_scene_cod/import_xmodel.py b/release/scripts/addons_contrib/io_scene_cod/import_xmodel.py
new file mode 100644
index 0000000..6f862e0
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_cod/import_xmodel.py
@@ -0,0 +1,392 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Blender-CoD: Blender Add-On for Call of Duty modding
+Version: alpha 3
+
+Copyright (c) 2011 CoDEmanX, Flybynyt -- blender-cod at online.de
+
+http://code.google.com/p/blender-cod/
+
+NOTES
+- Code is in early state of development and work in progress!
+- Importing rigs from XMODEL_EXPORT v6 works, but the code is really messy.
+
+TODO
+- Implement full xmodel import
+
+"""
+
+import os
+import bpy
+from mathutils import *
+import math
+#from mathutils.geometry import tesselate_polygon
+#from io_utils import load_image, unpack_list, unpack_face_list
+
+def round_matrix_3x3(mat, precision=6):
+ return Matrix(((round(mat[0][0],precision), round(mat[0][1],precision), round(mat[0][2],precision)),
+ (round(mat[1][0],precision), round(mat[1][1],precision), round(mat[1][2],precision)),
+ (round(mat[2][0],precision), round(mat[2][1],precision), round(mat[2][2],precision))))
+
+def load(self, context, filepath=""):
+
+ filepath = os.fsencode(filepath)
+
+ test_0 = []
+ test_1 = []
+ test_2 = []
+ test_3 = []
+
+ state = 0
+
+ # placeholders
+ vec0 = Vector((0.0, 0.0, 0.0))
+ mat0 = Matrix(((0.0, 0.0, 0.0),(0.0, 0.0, 0.0),(0.0, 0.0, 0.0)))
+
+ numbones = 0
+ numbones_i = 0
+ bone_i = 0
+ bone_table = []
+ numverts = 0
+ vert_i = 0
+ vert_table = [] # allocate table? [0]*numverts
+ face_i = 0
+ face_tmp = []
+ face_table = []
+ bones_influencing_num = 0
+ bones_influencing_i = 0
+ numfaces = 0
+
+ print("\nImporting %s" % filepath)
+
+ try:
+ file = open(filepath, "r")
+ except IOError:
+ return "Could not open file for reading:\n%s" % filepath
+
+ for line in file:
+ line = line.strip()
+ line_split = line.split()
+
+ # Skip empty and comment lines
+ if not line or line[0] == "/":
+ continue
+
+ elif state == 0 and line_split[0] == "MODEL":
+ state = 1
+
+ elif state == 1 and line_split[0] == "VERSION":
+ if line_split[1] != "6":
+ error_string = "Unsupported version: %s" % line_split[1]
+ print("\n%s" % error_string)
+ return error_string
+ state = 2
+
+ elif state == 2 and line_split[0] == "NUMBONES":
+ numbones = int(line_split[1])
+ state = 3
+
+ elif state == 3 and line_split[0] == "BONE":
+ if numbones_i != int(line_split[1]):
+ error_string = "Unexpected bone number: %s (expected %i)" % (line_split[1], numbones_i)
+ print("\n%s" % error_string)
+ return error_string
+ bone_table.append((line_split[3][1:-1], int(line_split[2]), vec0, mat0))
+ test_0.append(line_split[3][1:-1])
+ test_1.append(int(line_split[2]))
+ if numbones_i >= numbones-1:
+ state = 4
+ else:
+ numbones_i += 1
+
+ elif state == 4 and line_split[0] == "BONE":
+ bone_num = int(line_split[1])
+ if bone_i != bone_num:
+ error_string = "Unexpected bone number: %s (expected %i)" % (line_split[1], bone_i)
+ print("\n%s" % error_string)
+ return error_string
+ state = 5
+
+ elif state == 5 and line_split[0] == "OFFSET":
+ # remove commas - line_split[#][:-1] would also work, but isn't as save
+ line_split = line.replace(",", "").split()
+
+ # should we check for len(line_split) to ensure we got enough elements?
+ # Note: we can't assign a new vector to tuple object, we need to change each value
+
+ bone_table[bone_i][2].xyz = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+ #print("\nPROBLEMATIC: %s" % bone_table[bone_i][2])
+ #NO ERROR HERE, but for some reason the whole table will contain the same vectors
+ #bone_table[bone_i][2][0] = float(line_split[1])
+ #bone_table[bone_i][2][1] = float(line_split[2])
+ #bone_table[bone_i][2][2] = float(line_split[3])
+ test_2.append(Vector((float(line_split[1]),float(line_split[2]),float(line_split[3]))))
+
+ state = 6
+
+ elif state == 6 and line_split[0] == "SCALE":
+ # always 1.000000?! no processing so far...
+ state = 7
+
+ elif state == 7 and line_split[0] == "X":
+ line_split = line.replace(",", "").split()
+ bone_table[bone_i][3][0] = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+
+ """ Use something like this:
+ bone.align_roll(targetmatrix[2])
+ roll = roll%360 #nicer to have it 0-359.99...
+ """
+ m_col = []
+ m_col.append((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+
+ state = 8
+
+ elif state == 8 and line_split[0] == "Y":
+ line_split = line.replace(",", "").split()
+ bone_table[bone_i][3][1] = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+
+ m_col.append((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+
+ state = 9
+
+ elif state == 9 and line_split[0] == "Z":
+ line_split = line.replace(",", "").split()
+ vec_roll = Vector((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+ ##bone_table[bone_i][3][2] = vec_roll
+ #print("bone_table: %s" % bone_table[bone_i][3][2])
+
+ m_col.append((float(line_split[1]), float(line_split[2]), float(line_split[3])))
+
+ #test_3.append(Vector(vec_roll))
+
+ test_3.append(m_col)
+ #print("test_3: %s\n\n" % test_3[:])
+
+ if bone_i >= numbones-1:
+ state = 10
+ else:
+ #print("\n---> Increasing bone: %3i" % bone_i)
+ #print("\t" + str(bone_table[bone_i][3]))
+ #print("\t" + str(bone_table[bone_i][0]))
+ bone_i += 1
+ state = 4
+
+ elif state == 10 and line_split[0] == "NUMVERTS":
+ numverts = int(line_split[1])
+ state = 11
+
+ elif state == 11 and line_split[0] == "VERT":
+ vert_num = int(line_split[1])
+ if vert_i != vert_num:
+ error_string = "Unexpected vertex number: %s (expected %i)" % (line_split[1], vert_i)
+ print("\n%s" % error_string)
+ return error_string
+ vert_i += 1
+ state = 12
+
+ elif state == 12 and line_split[0] == "OFFSET":
+ line_split = line.replace(",", "").split()
+ vert_table.append(Vector((float(line_split[1]), float(line_split[2]), float(line_split[3]))))
+ state = 13
+
+ elif state == 13 and line_split[0] == "BONES":
+ # TODO: process
+ bones_influencing_num = int(line_split[1])
+ state= 14
+
+ elif state == 14 and line_split[0] == "BONE":
+ # TODO: add bones to vert_table
+ if bones_influencing_i >= bones_influencing_num-1:
+ if vert_i >= numverts:
+ state = 15
+ else:
+ state = 11
+ else:
+ bones_influencing_i += 1
+ #state = 14
+
+ elif state == 15 and line_split[0] == "NUMFACES":
+ numfaces = int(line_split[1])
+ state = 16
+
+ elif state == 16: #and line_split[0] == "TRI":
+ #face_i += 1
+ face_tmp = []
+ state = 17
+
+ elif (state == 17 or state == 21 or state == 25) and line_split[0] == "VERT":
+ #print("face_tmp length: %i" % len(face_tmp))
+ face_tmp.append(int(line_split[1]))
+ state += 1
+
+ elif (state == 18 or state == 22 or state == 26) and line_split[0] == "NORMAL":
+ state += 1
+
+ elif (state == 19 or state == 23 or state == 27) and line_split[0] == "COLOR":
+ state += 1
+
+ elif (state == 20 or state == 24 or state == 28) and line_split[0] == "UV":
+ state += 1
+
+ elif state == 29:
+
+ #print("Adding face: %s\n%i faces so far (of %i)\n" % (str(face_tmp), face_i, numfaces))
+ face_table.append(face_tmp)
+ if (face_i >= numfaces - 1):
+ state = 30
+ else:
+ face_i += 1
+ face_tmp = []
+ state = 17
+
+ elif state > 15 and state < 30 and line_split[0] == "NUMOBJECTS":
+ print("Bad numfaces, terminated loop\n")
+ state = 30
+
+ elif state == 30:
+ print("Adding mesh!")
+ me = bpy.data.meshes.new("pymesh")
+ me.from_pydata(vert_table, [], face_table)
+ me.update()
+ ob = bpy.data.objects.new("Py-Mesh", me)
+ bpy.context.scene.objects.link(ob)
+
+ state = 31
+
+ else: #elif state == 16:
+ #UNDONE
+ print("eh? state is %i line: %s" % (state, line))
+ pass
+
+ #print("\nCurrent state=" + str(state) + "\nLine:" + line)
+
+ #print("\n" + str(list(bone_table)) + "\n\n" + str(list(vert_table)))
+
+ #createRig(context, "Armature", Vector((0,0,0)), bone_table)
+
+ name = "Armature"
+ origin = Vector((0,0,0))
+ boneTable = bone_table
+
+ # If no context object, an object was deleted and mode is 'OBJECT' for sure
+ if context.object: #and context.mode is not 'OBJECT':
+
+ # Change mode, 'cause modes like POSE will lead to incorrect context poll
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Create armature and object
+ bpy.ops.object.add(
+ type='ARMATURE',
+ enter_editmode=True,
+ location=origin)
+ ob = bpy.context.object
+ ob.show_x_ray = True
+ ob.name = name
+ amt = ob.data
+ amt.name = name + "Amt"
+ #amt.show_axes = True
+
+ # Create bones
+ bpy.ops.object.mode_set(mode='EDIT')
+ #for (bname, pname, vector, matrix) in boneTable:
+ #i = 0
+ for (t0, t1, t2, t3) in zip(test_0, test_1, test_2, test_3):
+
+ t3 = Matrix(t3)
+
+ bone = amt.edit_bones.new(t0)
+ if t1 != -1:
+ parent = amt.edit_bones[t1]
+ bone.parent = parent
+ bone.head = parent.tail
+
+ bone.align_roll((parent.matrix.to_3x3()*t3)[2])
+ #local_mat = parent.matrix.to_3x3() * t3()
+ #bone.align_roll(local_mat[2])
+ from math import degrees
+ print("t3[2]: %s\nroll: %f\n---------" % (t3.col[2], degrees(bone.roll)))
+ #bone.roll = math.radians(180 - math.degrees(bone.roll))
+ #print("###\nalign_roll: %s\nroll: %.2f\ntest_3:%s" % (t3, math.degrees(bone.roll), list(test_3)))
+ bone.use_connect = True
+ else:
+ bone.head = (0,0,0)
+ rot = Matrix.Translation((0,0,0)) # identity matrix
+ bone.align_roll(t3[2])
+ bone.use_connect = False
+ bone.tail = t2
+
+ file.close()
+
+"""
+def createRig(context, name, origin, boneTable):
+
+ # If no context object, an object was deleted and mode is 'OBJECT' for sure
+ if context.object: #and context.mode is not 'OBJECT':
+
+ # Change mode, 'cause modes like POSE will lead to incorrect context poll
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Create armature and object
+ bpy.ops.object.add(
+ type='ARMATURE',
+ enter_editmode=True,
+ location=origin)
+ ob = bpy.context.object
+ ob.show_x_ray = True
+ ob.name = name
+ amt = ob.data
+ amt.name = name + "Amt"
+ #amt.show_axes = True
+
+ # Create bones
+ bpy.ops.object.mode_set(mode='EDIT')
+ #for (bname, pname, vector, matrix) in boneTable:
+ #i = 0
+ for i in range(len(test_0)):
+ t0 = test_0[i]
+ t1 = test_1[i]
+ t2 = test_2[i]
+ t3 = test_3[i]
+
+ bone = amt.edit_bones.new(t0)
+ if t1 != -1:
+ parent = amt.edit_bones[t1]
+ bone.parent = parent
+ bone.head = parent.tail
+ bone.use_connect = True
+ bone.align_roll(t3)
+ #print("align_roll: %s\nroll: %.2f" % (t3, math.degrees(bone.roll)))
+ #(trans, rot, scale) = parent.matrix.decompose()
+ else:
+ bone.head = (0,0,0)
+ rot = Matrix.Translation((0,0,0)) # identity matrix
+ bone.use_connect = False
+ #bone.tail = Vector(vector) * rot + bone.head
+ bone.tail = t2
+ #bone.tail = boneTable[i][2] #passing boneTable as parameter seems to break it :(
+ #i += 1
+
+ #outfile.write("\n%s" % str(boneTable))
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ return ob
+"""
diff --git a/release/scripts/addons_contrib/io_scene_m3/__init__.py b/release/scripts/addons_contrib/io_scene_m3/__init__.py
new file mode 100644
index 0000000..1d2785b
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_m3/__init__.py
@@ -0,0 +1,97 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ 'name': 'Import Blizzard M3 format (.m3)',
+ 'author': 'Cory Perry',
+ 'version': (0, 2, 1),
+ "blender": (2, 57, 0),
+ 'location': 'File > Import > Blizzard M3 (.m3)',
+ 'description': 'Imports the Blizzard M3 format (.m3)',
+ 'warning': 'Broken',
+ 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/'\
+ 'Import-Export/M3_Import',
+ 'tracker_url': 'http://projects.blender.org/tracker/index.php?'\
+ 'func=detail&aid=24017',
+ 'category': 'Import-Export'}
+
+
+# To support reload properly, try to access a package var, if it's there,
+# reload everything
+if "bpy" in locals():
+ import imp
+ if 'import_m3' in locals():
+ imp.reload(import_m3)
+# if 'export_m3' in locals():
+# imp.reload(export_m3)
+
+import time
+import datetime
+import bpy
+from bpy.props import StringProperty, BoolProperty
+from bpy_extras.io_utils import ImportHelper
+
+
+class ImportM3(bpy.types.Operator, ImportHelper):
+ """Import from M3 file format (.m3)"""
+ bl_idname = 'import_scene.blizzard_m3'
+ bl_label = 'Import M3'
+ bl_options = {'UNDO'}
+
+ filename_ext = '.m3'
+ filter_glob = StringProperty(default='*.m3', options={'HIDDEN'})
+
+ use_image_search = BoolProperty(name='Image Search',
+ description='Search subdirectories for any associated'\
+ 'images', default=True)
+
+ def execute(self, context):
+ from . import import_m3
+ print('Importing file', self.filepath)
+ t = time.mktime(datetime.datetime.now().timetuple())
+ with open(self.filepath, 'rb') as file:
+ import_m3.read(file, context, self)
+ t = time.mktime(datetime.datetime.now().timetuple()) - t
+ print('Finished importing in', t, 'seconds')
+ return {'FINISHED'}
+
+
+def menu_func_import(self, context):
+ self.layout.operator(ImportM3.bl_idname, text='Blizzard M3 (.m3)')
+
+
+#def menu_func_export(self, context):
+# self.layout.operator(ExportM3.bl_idname, text='Blizzard M3 (.m3)')
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+# bpy.types.INFO_MT_file_export.append(menu_func_export)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+# bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/io_scene_m3/import_m3.py b/release/scripts/addons_contrib/io_scene_m3/import_m3.py
new file mode 100644
index 0000000..f22a089
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_m3/import_m3.py
@@ -0,0 +1,365 @@
+# ##### 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 LICENSE BLOCK #####
+
+__author__ = "Cory Perry (muraj)"
+__version__ = "0.2.1"
+__bpydoc__ = """\
+This script imports m3 format files to Blender.
+
+The m3 file format, used by Blizzard in several games, is based around the
+mdx and m2 file format. Thanks to the efforts of Volcore, madyavic and the
+people working on libm3, the file format has been reversed engineered
+enough to make this script possible (Thanks guys!).
+
+This script currently imports the following:<br>
+ - Geometry data (vertices, faces, submeshes [in vertex groups])
+ - Model Textures (currently only the first material is supported)
+
+ Blender supports the DDS file format and needs the image in the same
+ directory. This script will notify you of any missing textures.
+
+TODO:<br>
+ - Documentation & clean up
+ - Full MD34 and MD33 testing (possibly batch importing for a testing suite)
+ - Import *ALL* materials and bind accordingly (currently supports diffuse,
+ specular, and normal.
+ - Adjust vertices to bind pose (import IREF matrices)
+ - Import Bone data
+ - Import Animation data
+
+Usage:<br>
+ Execute this script from the "File->Import" menu and choose a m3 file to
+open.
+
+Notes:<br>
+ Known issue with Thor.m3, seems to add a lot of unecessary verts.
+ Generates the standard verts and faces lists.
+"""
+
+import bpy
+import struct
+import os.path
+from bpy.props import *
+from bpy_extras.image_utils import load_image
+
+##################
+## Struct setup ##
+##################
+verFlag = False # Version flag (MD34 == True, MD33 == False)
+
+
+class ref:
+ fmt = 'LL'
+
+ def __init__(self, file):
+ global verFlag
+ if verFlag:
+ self.fmt += 'L' # Extra unknown...
+ _s = file.read(struct.calcsize(self.fmt))
+ self.entries, self.refid = struct.unpack(self.fmt, _s)[:2]
+
+ @classmethod
+ def size(cls):
+ global verFlag
+ return struct.calcsize(cls.fmt + ('L' if verFlag else ''))
+
+
+class animref:
+ fmt = 'HHL'
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ self.flags, self.animflags, self.animid = struct.unpack(self.fmt, _s)
+
+
+class Tag:
+ fmt = '4sLLL'
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ self.name, self.ofs, self.nTag, self.version = \
+ struct.unpack(self.fmt, _s)
+
+
+class matrix:
+ fmt = 'f' * 16
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ self.mat = struct.unpack(self.fmt, _s)
+
+
+class vect:
+ fmt = 'fff'
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ self.v = struct.unpack(self.fmt, _s)
+
+
+class vertex:
+ fmt = "4B4b4B%dH4B"
+ ver = {0x020000: 2, 0x060000: 4, 0x0A0000: 6, 0x120000: 8}
+
+ def __init__(self, file, flag):
+ self.pos = vect(file)
+ _fmt = self.fmt % (self.ver[flag])
+ _s = file.read(struct.calcsize(_fmt))
+ _s = struct.unpack(_fmt, _s)
+ self.boneWeight = _s[0:4]
+ self.boneIndex = _s[4:8]
+ self.normal = _s[8:12]
+ self.uv = _s[12:14]
+ self.tan = _s[-4:] # Skipping the middle ukn value if needed
+ self.boneWeight = [b / 255.0 for b in self.boneWeight]
+ self.normal = [x * 2.0 / 255.0 - 1.0 for x in self.normal]
+ self.tan = [x * 2.0 / 255.0 - 1.0 for x in self.tan]
+ self.uv = [x / 2046.0 for x in self.uv]
+ self.uv[1] = 1.0 - self.uv[1]
+
+ @classmethod
+ def size(cls, flag=0x020000):
+ return struct.calcsize('fff' + cls.fmt % (cls.ver[flag]))
+
+
+class quat:
+ fmt = 'ffff'
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ self.v = struct.unpack(self.fmt, _s)
+ #Quats are stored x,y,z,w - this fixes it
+ self.v = [self.v[-1], self.v[0], self.v[1], self.v[2]]
+
+
+class bone:
+
+ def __init__(self, file):
+ file.read(4) # ukn1
+ self.name = ref(file)
+ self.flag, self.parent, _ = struct.unpack('LhH', file.read(8))
+ self.posid = animref(file)
+ self.pos = vect(file)
+ file.read(4 * 4) # ukn
+ self.rotid = animref(file)
+ self.rot = quat(file)
+ file.read(4 * 5) # ukn
+ self.scaleid = animref(file)
+ self.scale = vect(file)
+ vect(file) # ukn
+ file.read(4 * 6) # ukn
+
+
+class div:
+
+ def __init__(self, file):
+ self.faces = ref(file)
+ self.regn = ref(file)
+ self.bat = ref(file)
+ self.msec = ref(file)
+ file.read(4) # ukn
+
+
+class regn:
+ fmt = 'L2H2L6H'
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ _ukn1, self.ofsVert, self.nVerts, self.ofsIndex, self.nIndex, \
+ self.boneCount, self.indBone, self.nBone = \
+ struct.unpack(self.fmt, _s)[:8]
+
+
+class mat:
+
+ def __init__(self, file):
+ self.name = ref(file)
+ file.read(4 * 10) # ukn
+ self.layers = [ref(file) for _ in range(13)]
+ file.read(4 * 15) # ukn
+
+
+class layr:
+
+ def __init__(self, file):
+ file.read(4)
+ self.name = ref(file)
+ #Rest not implemented.
+
+
+class hdr:
+ fmt = '4sLL'
+
+ def __init__(self, file):
+ _s = file.read(struct.calcsize(self.fmt))
+ self.magic, self.ofsTag, self.nTag = struct.unpack(self.fmt, _s)
+ self.MODLref = ref(file)
+
+
+class MODL:
+
+ def __init__(self, file, flag=20):
+ global verFlag
+ self.name = ref(file)
+ self.ver = struct.unpack('L', file.read(4))[0]
+ self.seqHdr = ref(file)
+ self.seqData = ref(file)
+ self.seqLookup = ref(file)
+ file.read(0x1C if verFlag else 0x14) # ukn1
+ self.bones = ref(file)
+ file.read(4) # ukn2
+ self.flags = struct.unpack('L', file.read(4))[0]
+ self.vert = ref(file)
+ self.views = ref(file)
+ self.boneLookup = ref(file)
+ self.extents = [vect(file), vect(file)]
+ self.radius = struct.unpack('f', file.read(4))[0]
+ if verFlag:
+ file.read(4) # ukn MD34 addition
+ if not verFlag:
+ if flag == 20:
+ file.read(0x2C)
+ else:
+ file.read(0x34)
+ else:
+ if flag == 20:
+ file.read(0x30)
+ else:
+ file.read(0x3C)
+ self.attach = ref(file)
+ file.read(5 * ref.size())
+ self.materialsLookup = ref(file)
+ self.materials = ref(file)
+ file.read(ref.size())
+ if not verFlag:
+ file.read(0x90)
+ else:
+ file.read(0xD8)
+ self.iref = ref(file)
+
+
+def read(file, context, op):
+ """Imports as an m3 file"""
+ global verFlag
+ h = hdr(file)
+ if h.magic[::-1] == b'MD34':
+ print('m3_import: !WARNING! MD34 files not full tested...')
+ verFlag = True
+ elif h.magic[::-1] == b'MD33':
+ verFlag = False
+ else:
+ raise Exception('m3_import: !ERROR! Not a valid or supported m3 file')
+ file.seek(h.ofsTag) # Jump to the Tag table
+ print('m3_import: !INFO! Reading TagTable...')
+ tagTable = [Tag(file) for _ in range(h.nTag)]
+ file.seek(tagTable[h.MODLref.refid].ofs)
+ m = MODL(file, tagTable[h.MODLref.refid].version)
+ if not m.flags & 0x20000:
+ raise Exception('m3_import: !ERROR! Model doesn\'t have any vertices')
+ print('m3_import: !INFO! Reading Vertices...')
+ vert_flags = m.flags & 0x1E0000 # Mask out the vertex version
+ file.seek(tagTable[m.views.refid].ofs)
+ d = div(file)
+ file.seek(tagTable[m.vert.refid].ofs)
+ verts = [vertex(file, vert_flags) \
+ for _ in range(tagTable[m.vert.refid].nTag // vertex.size(vert_flags))]
+ file.seek(tagTable[d.faces.refid].ofs)
+ print('m3_import: !INFO! Reading Faces...')
+ rawfaceTable = struct.unpack('H' * (tagTable[d.faces.refid].nTag), \
+ file.read(tagTable[d.faces.refid].nTag * 2))
+ faceTable = []
+ for i in range(1, len(rawfaceTable) + 1):
+ faceTable.append(rawfaceTable[i - 1])
+ if i % 3 == 0: # Add a zero for the fourth index to the face.
+ faceTable.append(0)
+ print("m3_import: !INFO! Read %d vertices and %d faces" \
+ % (len(verts), len(faceTable)))
+ print('m3_import: !INFO! Adding Geometry...')
+ mesh = bpy.data.meshes.new(os.path.basename(op.properties.filepath))
+ mobj = bpy.data.objects.new(os.path.basename(op.properties.filepath), mesh)
+ context.scene.objects.link(mobj)
+ v, n = [], []
+ for vert in verts: # "Flatten" the vertex array...
+ v.extend(vert.pos.v)
+ n.extend(vert.normal)
+ mesh.vertices.add(len(verts))
+ mesh.faces.add(len(rawfaceTable) // 3)
+ mesh.vertices.foreach_set('co', v)
+ mesh.vertices.foreach_set('normal', n)
+ mesh.faces.foreach_set('vertices_raw', faceTable)
+ uvtex = mesh.uv_textures.new()
+ for i, face in enumerate(mesh.faces):
+ uf = uvtex.data[i]
+ uf.uv1 = verts[faceTable[i * 4 + 0]].uv
+ uf.uv2 = verts[faceTable[i * 4 + 1]].uv
+ uf.uv3 = verts[faceTable[i * 4 + 2]].uv
+ uf.uv4 = (0, 0)
+ print('m3_import: !INFO! Importing materials...')
+ material = bpy.data.materials.new('Mat00')
+ mesh.materials.append(material)
+ file.seek(tagTable[m.materials.refid].ofs)
+ mm = mat(file)
+ tex_map = [('use_map_color_diffuse', 0), ('use_map_specular', 2),\
+ ('use_map_normal', 9)]
+ for map, i in tex_map:
+ file.seek(tagTable[mm.layers[i].refid].ofs)
+ nref = layr(file).name
+ file.seek(tagTable[nref.refid].ofs)
+ name = bytes.decode(file.read(nref.entries - 1))
+ name = os.path.basename(str(name))
+ tex = bpy.data.textures.new(name=name, type='IMAGE')
+ tex.image = load_image(name, os.path.dirname(op.filepath))
+ if tex.image != None:
+ print("m3_import: !INFO! Loaded %s" % (name))
+ else:
+ print("m3_import: !WARNING! Cannot find texture \"%s\"" % (name))
+ mtex = material.texture_slots.add()
+ mtex.texture = tex
+ mtex.texture_coords = 'UV'
+ if i == 9:
+ mtex.normal_factor = 0.1 # Just a guess, seems to look nice
+ mtex.use_map_color_diffuse = (i == 0)
+ setattr(mtex, map, True)
+
+
+class M3Importer(bpy.types.Operator):
+ """Import from M3 file format (.m3)"""
+ bl_idname = "import_mesh.blizzard_m3"
+ bl_label = 'Import M3'
+ bl_options = {'UNDO'}
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ filepath = StringProperty(
+ subtype='FILE_PATH',
+ )
+
+ def execute(self, context):
+ t = time.mktime(datetime.datetime.now().timetuple())
+ with open(self.properties.filepath, 'rb') as file:
+ print('Importing file', self.properties.filepath)
+ read(file, context, self)
+ t = time.mktime(datetime.datetime.now().timetuple()) - t
+ print('Finished importing in', t, 'seconds')
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.add_fileselect(self)
+ return {'RUNNING_MODAL'}
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/__init__.py b/release/scripts/addons_contrib/io_scene_ms3d/__init__.py
new file mode 100644
index 0000000..0519b97
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/__init__.py
@@ -0,0 +1,107 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ 'name': "MilkShape3D MS3D format (.ms3d)",
+ 'description': "Import / Export MilkShape3D MS3D files"\
+ " (conform with v1.8.4)",
+ 'author': "Alexander Nussbaumer",
+ 'version': (0, 91, 0),
+ 'blender': (2, 65, 0),
+ 'location': "File > Import & File > Export",
+ 'warning': "",
+ 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Import-Export/MilkShape3D_MS3D",
+ 'tracker_url': "http://projects.blender.org/tracker/index.php"\
+ "?func=detail&aid=29404",
+ 'category': "Import-Export",
+ }
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+
+
+# To support reload properly, try to access a package var,
+# if it's there, reload everything
+if 'bpy' in locals():
+ import imp
+ if 'io_scene_ms3d.ms3d_ui' in locals():
+ imp.reload(io_scene_ms3d.ms3d_ui)
+else:
+ from io_scene_ms3d.ms3d_ui import (
+ Ms3dImportOperator,
+ Ms3dExportOperator,
+ )
+
+
+#import blender stuff
+from bpy.utils import (
+ register_module,
+ unregister_module,
+ )
+from bpy.types import (
+ INFO_MT_file_export,
+ INFO_MT_file_import,
+ )
+
+
+###############################################################################
+# registration
+def register():
+ ####################
+ # F8 - key
+ import imp
+ imp.reload(ms3d_ui)
+ # F8 - key
+ ####################
+
+ ms3d_ui.register()
+
+ register_module(__name__)
+ INFO_MT_file_export.append(Ms3dExportOperator.menu_func)
+ INFO_MT_file_import.append(Ms3dImportOperator.menu_func)
+
+
+def unregister():
+ ms3d_ui.unregister()
+
+ unregister_module(__name__)
+ INFO_MT_file_export.remove(Ms3dExportOperator.menu_func)
+ INFO_MT_file_import.remove(Ms3dImportOperator.menu_func)
+
+
+###############################################################################
+# global entry point
+if (__name__ == "__main__"):
+ register()
+
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py
new file mode 100644
index 0000000..5e82303
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_export.py
@@ -0,0 +1,862 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+
+
+#import python stuff
+import io
+from math import (
+ pi,
+ )
+from mathutils import (
+ Matrix,
+ )
+from os import (
+ path,
+ )
+from sys import (
+ exc_info,
+ )
+from time import (
+ time,
+ )
+
+
+# import io_scene_ms3d stuff
+from io_scene_ms3d.ms3d_strings import (
+ ms3d_str,
+ )
+from io_scene_ms3d.ms3d_spec import (
+ Ms3dSpec,
+ Ms3dModel,
+ Ms3dVertex,
+ Ms3dTriangle,
+ Ms3dGroup,
+ Ms3dMaterial,
+ Ms3dJoint,
+ Ms3dRotationKeyframe,
+ Ms3dTranslationKeyframe,
+ Ms3dCommentEx,
+ )
+from io_scene_ms3d.ms3d_utils import (
+ select_all,
+ enable_edit_mode,
+ pre_setup_environment,
+ post_setup_environment,
+ matrix_difference,
+ )
+from io_scene_ms3d.ms3d_ui import (
+ Ms3dUi,
+ Ms3dMaterialProperties,
+ Ms3dMaterialHelper,
+ )
+
+
+#import blender stuff
+from bpy import (
+ ops,
+ )
+import bmesh
+
+
+###############################################################################
+class Ms3dExporter():
+ """ Load a MilkShape3D MS3D File """
+
+ def __init__(self, options):
+ self.options = options
+ pass
+
+ # create a empty ms3d ms3d_model
+ # fill ms3d_model with blender content
+ # writer ms3d file
+ def write(self, blender_context):
+ """convert bender content to ms3d content and write it to file"""
+
+ t1 = time()
+ t2 = None
+
+ try:
+ # setup environment
+ pre_setup_environment(self, blender_context)
+
+ # create an empty ms3d template
+ ms3d_model = Ms3dModel()
+
+ # inject blender data to ms3d file
+ self.from_blender(blender_context, ms3d_model)
+
+ t2 = time()
+
+ #self.file = None
+ try:
+ # write ms3d file to disk
+ #self.file = io.FileIO(self.options.filepath, "wb")
+ with io.FileIO(self.options.filepath, "wb") as self.file:
+ ms3d_model.write(self.file)
+ self.file.flush()
+ self.file.close()
+ finally:
+ # close ms3d file
+ #if self.file is not None:
+ # self.file.close()
+ pass
+
+ # if option is set, this time will enlargs the io time
+ if self.options.verbose:
+ ms3d_model.print_internal()
+
+ post_setup_environment(self, blender_context)
+ # restore active object
+ blender_context.scene.objects.active = self.active_object
+
+ if ((not blender_context.scene.objects.active)
+ and (blender_context.selected_objects)):
+ blender_context.scene.objects.active \
+ = blender_context.selected_objects[0]
+
+ # restore pre operator undo state
+ blender_context.user_preferences.edit.use_global_undo = self.undo
+
+ is_valid, statistics = ms3d_model.is_valid()
+ print()
+ print("##########################################################")
+ print("Export from Blender to MS3D")
+ print(statistics)
+ print("##########################################################")
+
+ except Exception:
+ type, value, traceback = exc_info()
+ print("write - exception in try block\n type: '{0}'\n"
+ " value: '{1}'".format(type, value, traceback))
+
+ if t2 is None:
+ t2 = time()
+
+ raise
+
+ else:
+ pass
+
+ t3 = time()
+ print(ms3d_str['SUMMARY_EXPORT'].format(
+ (t3 - t1), (t2 - t1), (t3 - t2)))
+
+ return {"FINISHED"}
+
+
+ ###########################################################################
+ def from_blender(self, blender_context, ms3d_model):
+ blender_mesh_objects = []
+
+ source = (blender_context.active_object, )
+
+ for blender_object in source:
+ if blender_object and blender_object.type == 'MESH' \
+ and blender_object.is_visible(blender_context.scene):
+ blender_mesh_objects.append(blender_object)
+
+ blender_to_ms3d_bones = {}
+
+ self.create_animation(blender_context, ms3d_model, blender_mesh_objects, blender_to_ms3d_bones)
+ self.create_geometry(blender_context, ms3d_model, blender_mesh_objects,
+ blender_to_ms3d_bones)
+
+
+ ###########################################################################
+ def create_geometry(self, blender_context, ms3d_model, blender_mesh_objects, blender_to_ms3d_bones):
+ blender_scene = blender_context.scene
+
+ blender_to_ms3d_vertices = {}
+ blender_to_ms3d_triangles = {}
+ blender_to_ms3d_groups = {}
+ blender_to_ms3d_materials = {}
+
+ for blender_mesh_object in blender_mesh_objects:
+ blender_mesh = blender_mesh_object.data
+
+ ms3d_model._model_ex_object.joint_size = \
+ blender_mesh.ms3d.joint_size
+ ms3d_model._model_ex_object.alpha_ref = blender_mesh.ms3d.alpha_ref
+ ms3d_model._model_ex_object.transparency_mode = \
+ Ms3dUi.transparency_mode_to_ms3d(
+ blender_mesh.ms3d.transparency_mode)
+
+ ##########################
+ # prepare ms3d groups if available
+ # works only for exporting active object
+ ##EXPORT_ACTIVE_ONLY:
+ for ms3d_local_group_index, blender_ms3d_group in enumerate(
+ blender_mesh.ms3d.groups):
+ ms3d_group = Ms3dGroup()
+ ms3d_group.__index = len(ms3d_model._groups)
+ ms3d_group.name = blender_ms3d_group.name
+ ms3d_group.flags = Ms3dUi.flags_to_ms3d(blender_ms3d_group.flags)
+ if blender_ms3d_group.comment:
+ ms3d_group._comment_object = Ms3dCommentEx()
+ ms3d_group._comment_object.comment = \
+ blender_ms3d_group.comment
+ ms3d_group._comment_object.index = len(ms3d_model._groups)
+ ms3d_group.material_index = None # to mark as not setted
+ ms3d_model._groups.append(ms3d_group)
+ blender_to_ms3d_groups[blender_ms3d_group.id] = ms3d_group
+
+ ##########################
+ # i have to use BMesh, because there are several custom data stored.
+ # BMesh doesn't support quads_convert_to_tris()
+ # so, i use that very ugly way:
+ # create a complete copy of mesh and bend object data
+ # to be able to apply operations to it.
+
+ # temporary, create a full heavy copy of the model
+ # (object, mesh, modifiers)
+ blender_mesh_temp = blender_mesh_object.data.copy()
+ blender_mesh_object_temp = blender_mesh_object.copy()
+ blender_mesh_object_temp.data = blender_mesh_temp
+ blender_scene.objects.link(blender_mesh_object_temp)
+ blender_scene.objects.active = blender_mesh_object_temp
+
+ # apply transform
+ if self.options.apply_transform:
+ matrix_transform = blender_mesh_object_temp.matrix_local
+ else:
+ matrix_transform = Matrix()
+
+ # apply modifiers
+ for modifier in blender_mesh_object_temp.modifiers:
+ if self.options.apply_modifiers:
+ # disable only armature modifiers and only,
+ # when use_animation is enabled
+ if self.options.use_animation \
+ and modifier.type in {'ARMATURE', }:
+ modifier.show_viewport = False
+ modifier.show_render = False
+ else:
+ # disable all modifiers,
+ # to be able to add and apply triangulate modifier later
+ modifier.show_viewport = False
+ modifier.show_render = False
+
+ # convert to tris by using the triangulate modifier
+ blender_mesh_object_temp.modifiers.new("temp", 'TRIANGULATE')
+ blender_mesh_temp = blender_mesh_object_temp.to_mesh(
+ blender_scene,
+ True,
+ self.options.apply_modifiers_mode)
+
+ enable_edit_mode(True, blender_context)
+ bm = bmesh.new()
+ bm.from_mesh(blender_mesh_temp)
+
+ layer_texture = bm.faces.layers.tex.get(
+ ms3d_str['OBJECT_LAYER_TEXTURE'])
+ if layer_texture is None:
+ layer_texture = bm.faces.layers.tex.new(
+ ms3d_str['OBJECT_LAYER_TEXTURE'])
+
+ layer_smoothing_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+ if layer_smoothing_group is None:
+ layer_smoothing_group = bm.faces.layers.int.new(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+
+ layer_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+ if layer_group is None:
+ layer_group = bm.faces.layers.int.new(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+
+ layer_uv = bm.loops.layers.uv.get(ms3d_str['OBJECT_LAYER_UV'])
+ if layer_uv is None:
+ if bm.loops.layers.uv:
+ layer_uv = bm.loops.layers.uv[0]
+ else:
+ layer_uv = bm.loops.layers.uv.new(
+ ms3d_str['OBJECT_LAYER_UV'])
+
+ layer_deform = bm.verts.layers.deform.active
+
+ layer_extra = bm.verts.layers.int.get(ms3d_str['OBJECT_LAYER_EXTRA'])
+ if layer_extra is None:
+ layer_extra = bm.verts.layers.int.new(
+ ms3d_str['OBJECT_LAYER_EXTRA'])
+
+
+ ##########################
+ # handle vertices
+ for bmv in bm.verts:
+ item = blender_to_ms3d_vertices.get(bmv)
+ if item is None:
+ index = len(ms3d_model._vertices)
+ ms3d_vertex = Ms3dVertex()
+ ms3d_vertex.__index = index
+
+ ms3d_vertex._vertex = self.geometry_correction(
+ matrix_transform * bmv.co)
+
+ if self.options.use_animation and layer_deform:
+ blender_vertex_group_ids = bmv[layer_deform]
+ if blender_vertex_group_ids:
+ count = 0
+ bone_ids = []
+ weights = []
+ for blender_index, blender_weight \
+ in blender_vertex_group_ids.items():
+ ms3d_joint = blender_to_ms3d_bones.get(
+ blender_mesh_object_temp.vertex_groups[\
+ blender_index].name)
+ if ms3d_joint:
+ if count == 0:
+ ms3d_vertex.bone_id = ms3d_joint.__index
+ weights.append(
+ int(blender_weight * 100.0))
+ elif count == 1:
+ bone_ids.append(ms3d_joint.__index)
+ weights.append(
+ int(blender_weight * 100.0))
+ elif count == 2:
+ bone_ids.append(ms3d_joint.__index)
+ weights.append(
+ int(blender_weight * 100.0))
+ elif count == 3:
+ bone_ids.append(ms3d_joint.__index)
+ self.options.report(
+ {'WARNING', 'INFO'},
+ ms3d_str['WARNING_EXPORT_SKIP_WEIGHT'])
+ else:
+ # only first three weights will be supported / four bones
+ self.options.report(
+ {'WARNING', 'INFO'},
+ ms3d_str['WARNING_EXPORT_SKIP_WEIGHT_EX'])
+ break
+ count+= 1
+
+ while len(bone_ids) < 3:
+ bone_ids.append(Ms3dSpec.DEFAULT_VERTEX_BONE_ID)
+ while len(weights) < 3:
+ weights.append(0)
+
+ # normalize weights to 100
+ if self.options.normalize_weights:
+ weight_sum = 0
+ for weight in weights:
+ weight_sum += weight
+
+ if weight_sum > 100:
+ weight_normalize = 100 / weight_sum
+ else:
+ weight_normalize = 1
+
+ weight_sum = 100
+ for index, weight in enumerate(weights):
+ if index >= count-1:
+ weights[index] = weight_sum
+ break
+ normalized_weight = int(
+ weight * weight_normalize)
+ weight_sum -= normalized_weight
+ weights[index] = normalized_weight
+
+ ms3d_vertex._vertex_ex_object._bone_ids = \
+ tuple(bone_ids)
+ ms3d_vertex._vertex_ex_object._weights = \
+ tuple(weights)
+
+ if layer_extra:
+ #ms3d_vertex._vertex_ex_object.extra = bmv[layer_extra]
+ # bm.verts.layers.int does only support signed int32
+ # convert signed int32 to unsigned int32 (little-endian)
+ signed_int32 = bmv[layer_extra]
+ bytes_int32 = signed_int32.to_bytes(
+ 4, byteorder='little', signed=True)
+ unsigned_int32 = int.from_bytes(
+ bytes_int32, byteorder='little', signed=False)
+ ms3d_vertex._vertex_ex_object.extra = unsigned_int32
+
+ ms3d_model._vertices.append(ms3d_vertex)
+ blender_to_ms3d_vertices[bmv] = ms3d_vertex
+
+ ##########################
+ # handle faces / tris
+ for bmf in bm.faces:
+ item = blender_to_ms3d_triangles.get(bmf)
+ if item is None:
+ index = len(ms3d_model._triangles)
+ ms3d_triangle = Ms3dTriangle()
+ ms3d_triangle.__index = index
+ bmv0 = bmf.verts[0]
+ bmv1 = bmf.verts[1]
+ bmv2 = bmf.verts[2]
+ ms3d_vertex0 = blender_to_ms3d_vertices[bmv0]
+ ms3d_vertex1 = blender_to_ms3d_vertices[bmv1]
+ ms3d_vertex2 = blender_to_ms3d_vertices[bmv2]
+ ms3d_vertex0.reference_count += 1
+ ms3d_vertex1.reference_count += 1
+ ms3d_vertex2.reference_count += 1
+ ms3d_triangle._vertex_indices = (
+ ms3d_vertex0.__index,
+ ms3d_vertex1.__index,
+ ms3d_vertex2.__index,
+ )
+ ms3d_triangle._vertex_normals = (
+ self.geometry_correction(bmv0.normal),
+ self.geometry_correction(bmv1.normal),
+ self.geometry_correction(bmv2.normal),
+ )
+ ms3d_triangle._s = (
+ bmf.loops[0][layer_uv].uv.x,
+ bmf.loops[1][layer_uv].uv.x,
+ bmf.loops[2][layer_uv].uv.x,
+ )
+ ms3d_triangle._t = (
+ 1.0 - bmf.loops[0][layer_uv].uv.y,
+ 1.0 - bmf.loops[1][layer_uv].uv.y,
+ 1.0 - bmf.loops[2][layer_uv].uv.y,
+ )
+
+ ms3d_triangle.smoothing_group = bmf[layer_smoothing_group]
+ ms3d_model._triangles.append(ms3d_triangle)
+
+ ms3d_material = self.get_ms3d_material_add_if(
+ blender_mesh, ms3d_model,
+ blender_to_ms3d_materials, bmf.material_index)
+ ms3d_group = blender_to_ms3d_groups.get(bmf[layer_group])
+
+ ##EXPORT_ACTIVE_ONLY:
+ if ms3d_group is not None:
+ if ms3d_material is None:
+ ms3d_group.material_index = \
+ Ms3dSpec.DEFAULT_GROUP_MATERIAL_INDEX
+ else:
+ if ms3d_group.material_index is None:
+ ms3d_group.material_index = \
+ ms3d_material.__index
+ else:
+ if ms3d_group.material_index != \
+ ms3d_material.__index:
+ ms3d_group = \
+ self.get_ms3d_group_by_material_add_if(
+ ms3d_model, ms3d_material)
+ else:
+ if ms3d_material is not None:
+ ms3d_group = self.get_ms3d_group_by_material_add_if(
+ ms3d_model, ms3d_material)
+ else:
+ ms3d_group = self.get_ms3d_group_default_material_add_if(
+ ms3d_model)
+
+ if ms3d_group is not None:
+ ms3d_group._triangle_indices.append(
+ ms3d_triangle.__index)
+ ms3d_triangle.group_index = ms3d_group.__index
+
+ blender_to_ms3d_triangles[bmf] = ms3d_triangle
+
+ if bm is not None:
+ bm.free()
+
+ enable_edit_mode(False, blender_context)
+
+ ##########################
+ # remove the temporary data
+ blender_scene.objects.unlink(blender_mesh_object_temp)
+ if blender_mesh_temp is not None:
+ blender_mesh_temp.user_clear()
+ blender_context.blend_data.meshes.remove(blender_mesh_temp)
+ blender_mesh_temp = None
+ if blender_mesh_object_temp is not None:
+ blender_mesh_temp = blender_mesh_object_temp.data.user_clear()
+ blender_mesh_object_temp.user_clear()
+ blender_context.blend_data.objects.remove(
+ blender_mesh_object_temp)
+ if blender_mesh_temp is not None:
+ blender_mesh_temp.user_clear()
+ blender_context.blend_data.meshes.remove(blender_mesh_temp)
+
+
+ ###########################################################################
+ def create_animation(self, blender_context, ms3d_model,
+ blender_mesh_objects, blender_to_ms3d_bones):
+ ##########################
+ # setup scene
+ blender_scene = blender_context.scene
+
+ if not self.options.use_animation:
+ ms3d_model.animation_fps = 24
+ ms3d_model.number_total_frames = 1
+ ms3d_model.current_time = 0
+ return
+
+ frame_start = blender_scene.frame_start
+ frame_end = blender_scene.frame_end
+ frame_total = (frame_end - frame_start) + 1
+ frame_step = blender_scene.frame_step
+ frame_offset = 0
+
+ fps = blender_scene.render.fps * blender_scene.render.fps_base
+ time_base = 1.0 / fps
+
+ base_bone_correction = Matrix.Rotation(pi / 2, 4, 'Z')
+
+ for blender_mesh_object in blender_mesh_objects:
+ blender_bones = None
+ blender_action = None
+ blender_nla_tracks = None
+ for blender_modifier in blender_mesh_object.modifiers:
+ if blender_modifier.type == 'ARMATURE' \
+ and blender_modifier.object.pose:
+ blender_bones = blender_modifier.object.data.bones
+ blender_pose_bones = blender_modifier.object.pose.bones
+ if blender_modifier.object.animation_data:
+ blender_action = \
+ blender_modifier.object.animation_data.action
+ blender_nla_tracks = \
+ blender_modifier.object.animation_data.nla_tracks
+ break
+
+ if blender_bones is None \
+ and (blender_action is None and blender_nla_tracks is None):
+ continue
+
+ ##########################
+ # bones
+ blender_bones_ordered = []
+ self.build_blender_bone_dependency_order(
+ blender_bones, blender_bones_ordered)
+ for blender_bone_name in blender_bones_ordered:
+ blender_bone_oject = blender_bones[blender_bone_name]
+ ms3d_joint = Ms3dJoint()
+ ms3d_joint.__index = len(ms3d_model._joints)
+
+ blender_bone_ms3d = blender_bone_oject.ms3d
+ blender_bone = blender_bone_oject
+
+ ms3d_joint.flags = Ms3dUi.flags_to_ms3d(blender_bone_ms3d.flags)
+ if blender_bone_ms3d.comment:
+ ms3d_joint._comment_object = Ms3dCommentEx()
+ ms3d_joint._comment_object.comment = \
+ blender_bone_ms3d.comment
+ ms3d_joint._comment_object.index = ms3d_joint.__index
+
+ ms3d_joint.joint_ex_object._color = blender_bone_ms3d.color[:]
+
+ ms3d_joint.name = blender_bone.name
+
+ if blender_bone.parent:
+ ms3d_joint.parent_name = blender_bone.parent.name
+ ms3d_joint.__matrix = matrix_difference(
+ blender_bone.matrix_local,
+ blender_bone.parent.matrix_local)
+ else:
+ ms3d_joint.__matrix = base_bone_correction \
+ * blender_bone.matrix_local
+
+ mat = ms3d_joint.__matrix
+ loc = mat.to_translation()
+ rot = mat.to_euler('XZY')
+ ms3d_joint._position = self.joint_correction(loc)
+ ms3d_joint._rotation = self.joint_correction(rot)
+
+ ms3d_model._joints.append(ms3d_joint)
+ blender_to_ms3d_bones[blender_bone.name] = ms3d_joint
+
+ ##########################
+ # animation
+ frames = None
+ frames_location = set()
+ frames_rotation = set()
+ frames_scale = set()
+
+ if blender_action:
+ self.fill_keyframe_sets(
+ blender_action.fcurves,
+ frames_location, frames_rotation, frames_scale,
+ 0)
+
+ if blender_nla_tracks:
+ for nla_track in blender_nla_tracks:
+ if nla_track.mute:
+ continue
+ for strip in nla_track.strips:
+ if strip.mute:
+ continue
+ frame_correction = strip.frame_start \
+ - strip.action_frame_start
+ self.fill_keyframe_sets(
+ strip.action.fcurves,
+ frames_location, frames_rotation, frames_scale,
+ frame_correction)
+
+ frames = set(frames_location)
+ frames = frames.union(frames_rotation)
+ frames = frames.union(frames_scale)
+
+ if not self.options.shrink_to_keys:
+ frames = frames.intersection(range(
+ blender_scene.frame_start, blender_scene.frame_end + 1))
+
+ frames_sorted = list(frames)
+ frames_sorted.sort()
+
+ if self.options.shrink_to_keys and len(frames_sorted) >= 2:
+ frame_start = frames_sorted[0]
+ frame_end = frames_sorted[len(frames_sorted)-1]
+ frame_total = (frame_end - frame_start) + 1
+ frame_offset = frame_start - 1
+
+ if self.options.bake_each_frame:
+ frames_sorted = range(int(frame_start), int(frame_end + 1),
+ int(frame_step))
+
+ frame_temp = blender_scene.frame_current
+
+ for current_frame in frames_sorted:
+ blender_scene.frame_set(current_frame)
+
+ current_time = (current_frame - frame_offset) * time_base
+ for blender_bone_name in blender_bones_ordered:
+ blender_bone = blender_bones[blender_bone_name]
+ blender_pose_bone = blender_pose_bones[blender_bone_name]
+ ms3d_joint = blender_to_ms3d_bones[blender_bone_name]
+
+ m1 = blender_bone.matrix_local.inverted()
+ if blender_pose_bone.parent:
+ m2 = blender_pose_bone.parent.matrix_channel.inverted()
+ else:
+ m2 = Matrix()
+ m3 = blender_pose_bone.matrix.copy()
+ m = ((m1 * m2) * m3)
+ loc = m.to_translation()
+ rot = m.to_euler('XZY')
+
+ ms3d_joint.translation_key_frames.append(
+ Ms3dTranslationKeyframe(
+ current_time, self.joint_correction(loc)
+ )
+ )
+ ms3d_joint.rotation_key_frames.append(
+ Ms3dRotationKeyframe(
+ current_time, self.joint_correction(rot)
+ )
+ )
+
+ blender_scene.frame_set(frame_temp)
+
+ ms3d_model.animation_fps = fps
+ if ms3d_model.number_joints > 0:
+ ms3d_model.number_total_frames = int(frame_total)
+ ms3d_model.current_time = ((blender_scene.frame_current \
+ - blender_scene.frame_start) + 1) * time_base
+ else:
+ ms3d_model.number_total_frames = 1
+ ms3d_model.current_time = 0
+
+
+ ###########################################################################
+ def get_ms3d_group_default_material_add_if(self, ms3d_model):
+ markerName = "MaterialGroupDefault"
+ markerComment = "group without material"
+
+ for ms3d_group in ms3d_model._groups:
+ if ms3d_group.material_index == \
+ Ms3dSpec.DEFAULT_GROUP_MATERIAL_INDEX \
+ and ms3d_group.name == markerName \
+ and ms3d_group._comment_object \
+ and ms3d_group._comment_object.comment == markerComment:
+ return ms3d_group
+
+ ms3d_group = Ms3dGroup()
+ ms3d_group.__index = len(ms3d_model._groups)
+ ms3d_group.name = markerName
+ ms3d_group._comment_object = Ms3dCommentEx()
+ ms3d_group._comment_object.comment = markerComment
+ ms3d_group._comment_object.index = len(ms3d_model._groups)
+ ms3d_group.material_index = Ms3dSpec.DEFAULT_GROUP_MATERIAL_INDEX
+
+ ms3d_model._groups.append(ms3d_group)
+
+ return ms3d_group
+
+
+ ###########################################################################
+ def get_ms3d_group_by_material_add_if(self, ms3d_model, ms3d_material):
+ if ms3d_material.__index < 0 \
+ or ms3d_material.__index >= len(ms3d_model.materials):
+ return None
+
+ markerName = "MaterialGroup.{}".format(ms3d_material.__index)
+ markerComment = "MaterialGroup({})".format(ms3d_material.name)
+
+ for ms3d_group in ms3d_model._groups:
+ if ms3d_group.name == markerName \
+ and ms3d_group._comment_object \
+ and ms3d_group._comment_object.comment == markerComment:
+ return ms3d_group
+
+ ms3d_group = Ms3dGroup()
+ ms3d_group.__index = len(ms3d_model._groups)
+ ms3d_group.name = markerName
+ ms3d_group._comment_object = Ms3dCommentEx()
+ ms3d_group._comment_object.comment = markerComment
+ ms3d_group._comment_object.index = len(ms3d_model._groups)
+ ms3d_group.material_index = ms3d_material.__index
+
+ ms3d_model._groups.append(ms3d_group)
+
+ return ms3d_group
+
+
+ ###########################################################################
+ def get_ms3d_material_add_if(self, blender_mesh, ms3d_model,
+ blender_to_ms3d_materials, blender_index):
+ if blender_index < 0 or blender_index >= len(blender_mesh.materials):
+ return None
+
+ blender_material = blender_mesh.materials[blender_index]
+ ms3d_material = blender_to_ms3d_materials.get(blender_material)
+ if ms3d_material is None:
+ ms3d_material = Ms3dMaterial()
+ ms3d_material.__index = len(ms3d_model.materials)
+
+ blender_ms3d_material = blender_material.ms3d
+
+ if not self.options.use_blender_names \
+ and not self.options.use_blender_materials \
+ and blender_ms3d_material.name:
+ ms3d_material.name = blender_ms3d_material.name
+ else:
+ ms3d_material.name = blender_material.name
+
+ temp_material = None
+ if self.options.use_blender_materials:
+ temp_material = Ms3dMaterial()
+ Ms3dMaterialHelper.copy_from_blender(
+ None, None, temp_material, blender_material)
+ else:
+ temp_material = blender_ms3d_material
+
+ ms3d_material._ambient = temp_material.ambient[:]
+ ms3d_material._diffuse = temp_material.diffuse[:]
+ ms3d_material._specular = temp_material.specular[:]
+ ms3d_material._emissive = temp_material.emissive[:]
+ ms3d_material.shininess = temp_material.shininess
+ ms3d_material.transparency = temp_material.transparency
+ ms3d_material.texture = temp_material.texture
+ ms3d_material.alphamap = temp_material.alphamap
+
+ ms3d_material.mode = Ms3dUi.texture_mode_to_ms3d(
+ blender_ms3d_material.mode)
+ if blender_ms3d_material.comment:
+ ms3d_material._comment_object = Ms3dCommentEx()
+ ms3d_material._comment_object.comment = \
+ blender_ms3d_material.comment
+ ms3d_material._comment_object.index = ms3d_material.__index
+
+ ms3d_model.materials.append(ms3d_material)
+
+ blender_to_ms3d_materials[blender_material] = ms3d_material
+
+ return ms3d_material
+
+
+ ###########################################################################
+ def geometry_correction(self, value):
+ return (value[1], value[2], value[0])
+
+
+ ###########################################################################
+ def joint_correction(self, value):
+ return (-value[0], value[2], value[1])
+
+
+ ###########################################################################
+ def build_blender_bone_dependency_order(self, blender_bones,
+ blender_bones_ordered):
+ if not blender_bones:
+ return blender_bones_ordered
+
+ blender_bones_children = {None: []}
+ for blender_bone in blender_bones:
+ if blender_bone.parent:
+ blender_bone_children = blender_bones_children.get(
+ blender_bone.parent.name)
+ if blender_bone_children is None:
+ blender_bone_children = blender_bones_children[
+ blender_bone.parent.name] = []
+ else:
+ blender_bone_children = blender_bones_children[None]
+
+ blender_bone_children.append(blender_bone.name)
+
+ self.traverse_dependencies(
+ blender_bones_ordered,
+ blender_bones_children,
+ None)
+
+ return blender_bones_ordered
+
+
+ ###########################################################################
+ def traverse_dependencies(self, blender_bones_ordered,
+ blender_bones_children, key):
+ blender_bone_children = blender_bones_children.get(key)
+ if blender_bone_children:
+ for blender_bone_name in blender_bone_children:
+ blender_bones_ordered.append(blender_bone_name)
+ self.traverse_dependencies(
+ blender_bones_ordered,
+ blender_bones_children,
+ blender_bone_name)
+
+ ###########################################################################
+ def fill_keyframe_sets(self,
+ fcurves,
+ frames_location, frames_rotation, frames_scale,
+ frame_correction):
+ for fcurve in fcurves:
+ if fcurve.data_path.endswith(".location"):
+ frames = frames_location
+ elif fcurve.data_path.endswith(".rotation_euler"):
+ frames = frames_rotation
+ elif fcurve.data_path.endswith(".rotation_quaternion"):
+ frames = frames_rotation
+ elif fcurve.data_path.endswith(".scale"):
+ frames = frames_scale
+ else:
+ pass
+
+ for keyframe_point in fcurve.keyframe_points:
+ frames.add(int(keyframe_point.co[0] + frame_correction))
+
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py
new file mode 100644
index 0000000..3c01085
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_import.py
@@ -0,0 +1,945 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+
+
+#import python stuff
+import io
+from mathutils import (
+ Vector,
+ Matrix,
+ )
+from os import (
+ path,
+ )
+from sys import (
+ exc_info,
+ )
+from time import (
+ time,
+ )
+
+
+# import io_scene_ms3d stuff
+from io_scene_ms3d.ms3d_strings import (
+ ms3d_str,
+ )
+from io_scene_ms3d.ms3d_spec import (
+ Ms3dSpec,
+ Ms3dModel,
+ Ms3dVertexEx2,
+ Ms3dVertexEx3,
+ )
+from io_scene_ms3d.ms3d_utils import (
+ select_all,
+ enable_pose_mode,
+ enable_edit_mode,
+ pre_setup_environment,
+ post_setup_environment,
+ get_edge_split_modifier_add_if,
+ )
+from io_scene_ms3d.ms3d_ui import (
+ Ms3dUi,
+ )
+
+
+#import blender stuff
+from bpy import (
+ ops,
+ )
+import bmesh
+from bpy_extras.image_utils import (
+ load_image,
+ )
+
+
+###############################################################################
+class Ms3dImporter():
+ """ Load a MilkShape3D MS3D File """
+ def __init__(self, options):
+ self.options = options
+ pass
+
+ ###########################################################################
+ # create empty blender ms3d_model
+ # read ms3d file
+ # fill blender with ms3d_model content
+ def read(self, blender_context):
+ """ read ms3d file and convert ms3d content to bender content """
+
+ t1 = time()
+ t2 = None
+ self.has_textures = False
+
+ try:
+ # setup environment
+ pre_setup_environment(self, blender_context)
+
+ # create an empty ms3d template
+ ms3d_model = Ms3dModel(self.filepath_splitted[1])
+
+ #self.file = None
+ try:
+ # open ms3d file
+ #self.file = io.FileIO(self.options.filepath, 'rb')
+ with io.FileIO(self.options.filepath, 'rb') as self.file:
+ # read and inject ms3d data from disk to internal structure
+ ms3d_model.read(self.file)
+ self.file.close()
+ finally:
+ # close ms3d file
+ #if self.file is not None:
+ # self.file.close()
+ pass
+
+ # if option is set, this time will enlargs the io time
+ if self.options.verbose:
+ ms3d_model.print_internal()
+
+ t2 = time()
+
+ is_valid, statistics = ms3d_model.is_valid()
+
+ if is_valid:
+ # inject ms3d data to blender
+ self.to_blender(blender_context, ms3d_model)
+
+ blender_scene = blender_context.scene
+
+ # finalize/restore environment
+ blender_scene.update()
+
+ post_setup_environment(self, blender_context)
+
+ print()
+ print("##########################################################")
+ print("Import from MS3D to Blender")
+ print(statistics)
+ print("##########################################################")
+
+ except Exception:
+ type, value, traceback = exc_info()
+ print("read - exception in try block\n type: '{0}'\n"
+ " value: '{1}'".format(type, value, traceback))
+
+ if t2 is None:
+ t2 = time()
+
+ raise
+
+ else:
+ pass
+
+ t3 = time()
+ print(ms3d_str['SUMMARY_IMPORT'].format(
+ (t3 - t1), (t2 - t1), (t3 - t2)))
+
+ return {"FINISHED"}
+
+
+ ###########################################################################
+ def to_blender(self, blender_context, ms3d_model):
+ blender_mesh_object = self.create_geometry(blender_context, ms3d_model)
+ blender_armature_object = self.create_animation(
+ blender_context, ms3d_model, blender_mesh_object)
+
+ self.organize_objects(
+ blender_context, ms3d_model,
+ [blender_mesh_object, blender_armature_object])
+
+
+ ###########################################################################
+ def organize_objects(self, blender_context, ms3d_model, blender_objects):
+ ##########################
+ # blender_armature_object to blender_mesh_object
+ # that has bad side effects to the armature
+ # and causes cyclic dependecies
+ ###blender_armature_object.parent = blender_mesh_object
+ ###blender_mesh_object.parent = blender_armature_object
+
+ blender_scene = blender_context.scene
+
+ blender_group = blender_context.blend_data.groups.new(
+ "{}.g".format(ms3d_model.name))
+ blender_empty_object = blender_context.blend_data.objects.new(
+ "{}.e".format(ms3d_model.name), None)
+ blender_empty_object.location = blender_scene.cursor_location
+ blender_scene.objects.link(blender_empty_object)
+ blender_group.objects.link(blender_empty_object)
+
+ for blender_object in blender_objects:
+ if blender_object is not None:
+ blender_group.objects.link(blender_object)
+ blender_object.parent = blender_empty_object
+
+
+ ###########################################################################
+ def create_geometry(self, blender_context, ms3d_model):
+ ##########################
+ # blender stuff:
+ # create a blender Mesh
+ blender_mesh = blender_context.blend_data.meshes.new(
+ "{}.m".format(ms3d_model.name))
+ blender_mesh.ms3d.name = ms3d_model.name
+
+ ms3d_comment = ms3d_model.comment_object
+ if ms3d_comment is not None:
+ blender_mesh.ms3d.comment = ms3d_comment.comment
+ ms3d_model_ex = ms3d_model.model_ex_object
+ if ms3d_model_ex is not None:
+ blender_mesh.ms3d.joint_size = ms3d_model_ex.joint_size
+ blender_mesh.ms3d.alpha_ref = ms3d_model_ex.alpha_ref
+ blender_mesh.ms3d.transparency_mode \
+ = Ms3dUi.transparency_mode_from_ms3d(
+ ms3d_model_ex.transparency_mode)
+
+ ##########################
+ # blender stuff:
+ # link to blender object
+ blender_mesh_object = blender_context.blend_data.objects.new(
+ "{}.m".format(ms3d_model.name), blender_mesh)
+
+ ##########################
+ # blender stuff:
+ # create edge split modifire, to make sharp edges visible
+ blender_modifier = get_edge_split_modifier_add_if(blender_mesh_object)
+
+ ##########################
+ # blender stuff:
+ # link to blender scene
+ blender_scene = blender_context.scene
+ blender_scene.objects.link(blender_mesh_object)
+ #blender_mesh_object.location = blender_scene.cursor_location
+ enable_edit_mode(False, blender_context)
+ select_all(False)
+ blender_mesh_object.select = True
+ blender_scene.objects.active = blender_mesh_object
+
+ ##########################
+ # take this as active object after import
+ self.active_object = blender_mesh_object
+
+ ##########################
+ # blender stuff:
+ # create all (ms3d) groups
+ ms3d_to_blender_group_index = {}
+ blender_group_manager = blender_mesh.ms3d
+ for ms3d_group_index, ms3d_group in enumerate(ms3d_model.groups):
+ blender_group = blender_group_manager.create_group()
+ blender_group.name = ms3d_group.name
+ blender_group.flags = Ms3dUi.flags_from_ms3d(ms3d_group.flags)
+ blender_group.material_index = ms3d_group.material_index
+
+ ms3d_comment = ms3d_group.comment_object
+ if ms3d_comment is not None:
+ blender_group.comment = ms3d_comment.comment
+
+ # translation dictionary
+ ms3d_to_blender_group_index[ms3d_group_index] = blender_group.id
+
+ ####################################################
+ # begin BMesh stuff
+ #
+
+ ##########################
+ # BMesh stuff:
+ # create an empty BMesh
+ bm = bmesh.new()
+
+ ##########################
+ # BMesh stuff:
+ # create new Layers for custom data per "mesh face"
+ layer_texture = bm.faces.layers.tex.get(
+ ms3d_str['OBJECT_LAYER_TEXTURE'])
+ if layer_texture is None:
+ layer_texture = bm.faces.layers.tex.new(
+ ms3d_str['OBJECT_LAYER_TEXTURE'])
+
+ layer_smoothing_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+ if layer_smoothing_group is None:
+ layer_smoothing_group = bm.faces.layers.int.new(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+
+ layer_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+ if layer_group is None:
+ layer_group = bm.faces.layers.int.new(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+
+ ##########################
+ # BMesh stuff:
+ # create new Layers for custom data per "face vertex"
+ layer_uv = bm.loops.layers.uv.get(ms3d_str['OBJECT_LAYER_UV'])
+ if layer_uv is None:
+ layer_uv = bm.loops.layers.uv.new(ms3d_str['OBJECT_LAYER_UV'])
+
+ ##########################
+ # BMesh stuff:
+ # create new Layers for custom data per "vertex"
+ layer_extra = bm.verts.layers.int.get(ms3d_str['OBJECT_LAYER_EXTRA'])
+ if layer_extra is None:
+ layer_extra = bm.verts.layers.int.new(ms3d_str['OBJECT_LAYER_EXTRA'])
+
+ ##########################
+ # BMesh stuff:
+ # create all vertices
+ for ms3d_vertex_index, ms3d_vertex in enumerate(ms3d_model.vertices):
+ bmv = bm.verts.new(self.geometry_correction(ms3d_vertex.vertex))
+
+ if layer_extra and ms3d_vertex.vertex_ex_object and \
+ (isinstance(ms3d_vertex.vertex_ex_object, Ms3dVertexEx2) \
+ or isinstance(ms3d_vertex.vertex_ex_object, Ms3dVertexEx3)):
+
+ #bmv[layer_extra] = ms3d_vertex.vertex_ex_object.extra
+ # bm.verts.layers.int does only support signed int32
+ # convert unsigned int32 to signed int32 (little-endian)
+ unsigned_int32 = ms3d_vertex.vertex_ex_object.extra
+ bytes_int32 = unsigned_int32.to_bytes(
+ 4, byteorder='little', signed=False)
+ signed_int32 = int.from_bytes(
+ bytes_int32, byteorder='little', signed=True)
+ bmv[layer_extra] = signed_int32
+
+ ##########################
+ # blender stuff (uses BMesh stuff):
+ # create all materials / image textures
+ ms3d_to_blender_material = {}
+ for ms3d_material_index, ms3d_material in enumerate(
+ ms3d_model.materials):
+ blender_material = blender_context.blend_data.materials.new(
+ ms3d_material.name)
+
+ # custom datas
+ blender_material.ms3d.name = ms3d_material.name
+ blender_material.ms3d.ambient = ms3d_material.ambient
+ blender_material.ms3d.diffuse = ms3d_material.diffuse
+ blender_material.ms3d.specular = ms3d_material.specular
+ blender_material.ms3d.emissive = ms3d_material.emissive
+ blender_material.ms3d.shininess = ms3d_material.shininess
+ blender_material.ms3d.transparency = ms3d_material.transparency
+ blender_material.ms3d.mode = Ms3dUi.texture_mode_from_ms3d(
+ ms3d_material.mode)
+
+ if ms3d_material.texture:
+ blender_material.ms3d.texture = ms3d_material.texture
+
+ if ms3d_material.alphamap:
+ blender_material.ms3d.alphamap = ms3d_material.alphamap
+
+ ms3d_comment = ms3d_material.comment_object
+ if ms3d_comment is not None:
+ blender_material.ms3d.comment = ms3d_comment.comment
+
+ # blender datas
+ blender_material.ambient = (
+ (ms3d_material.ambient[0]
+ + ms3d_material.ambient[1]
+ + ms3d_material.ambient[2]) / 3.0)
+
+ blender_material.diffuse_color[0] = ms3d_material.diffuse[0]
+ blender_material.diffuse_color[1] = ms3d_material.diffuse[1]
+ blender_material.diffuse_color[2] = ms3d_material.diffuse[2]
+
+ blender_material.specular_color[0] = ms3d_material.specular[0]
+ blender_material.specular_color[1] = ms3d_material.specular[1]
+ blender_material.specular_color[2] = ms3d_material.specular[2]
+
+ blender_material.emit = (
+ (ms3d_material.emissive[0]
+ + ms3d_material.emissive[1]
+ + ms3d_material.emissive[2]) / 3.0)
+
+ blender_material.specular_hardness = ms3d_material.shininess * 4.0
+ blender_material.alpha = 1.0 - ms3d_material.transparency
+
+ # diffuse texture
+ if ms3d_material.texture:
+ dir_name_diffuse = self.filepath_splitted[0]
+ file_name_diffuse = path.split(ms3d_material.texture)[1]
+ blender_image_diffuse = load_image(
+ file_name_diffuse, dir_name_diffuse)
+ blender_texture_diffuse = \
+ blender_context.blend_data.textures.new(
+ name=file_name_diffuse, type='IMAGE')
+ blender_texture_diffuse.image = blender_image_diffuse
+ blender_texture_slot_diffuse \
+ = blender_material.texture_slots.add()
+ blender_texture_slot_diffuse.texture = blender_texture_diffuse
+ blender_texture_slot_diffuse.texture_coords = 'UV'
+ blender_texture_slot_diffuse.uv_layer = layer_uv.name
+ blender_texture_slot_diffuse.use_map_color_diffuse = True
+ blender_texture_slot_diffuse.use_map_alpha = False
+ if blender_image_diffuse is not None:
+ self.has_textures = True
+ else:
+ blender_image_diffuse = None
+
+ # alpha texture
+ if ms3d_material.alphamap:
+ dir_name_alpha = self.filepath_splitted[0]
+ file_name_alpha = path.split(ms3d_material.alphamap)[1]
+ blender_image_alpha = load_image(
+ file_name_alpha, dir_name_alpha)
+ blender_texture_alpha = blender_context.blend_data.textures.new(
+ name=file_name_alpha, type='IMAGE')
+ blender_texture_alpha.image = blender_image_alpha
+ blender_texture_slot_alpha \
+ = blender_material.texture_slots.add()
+ blender_texture_slot_alpha.texture = blender_texture_alpha
+ blender_texture_slot_alpha.texture_coords = 'UV'
+ blender_texture_slot_alpha.uv_layer = layer_uv.name
+ blender_texture_slot_alpha.use_map_color_diffuse = False
+ blender_texture_slot_alpha.use_map_alpha = True
+ blender_texture_slot_alpha.use_rgb_to_intensity = True
+ blender_material.alpha = 0
+ blender_material.specular_alpha = 0
+
+ # append blender material to blender mesh, to be linked to
+ blender_mesh.materials.append(blender_material)
+
+ # translation dictionary
+ ms3d_to_blender_material[ms3d_material_index] \
+ = blender_image_diffuse
+
+ ##########################
+ # BMesh stuff:
+ # create all triangles
+ length_verts = len(bm.verts)
+ vertex_extra_index = length_verts
+ blender_invalide_normal = Vector()
+ smoothing_group_blender_faces = {}
+ for ms3d_triangle_index, ms3d_triangle in enumerate(
+ ms3d_model.triangles):
+ bmv_list = []
+ bmf_normal = Vector()
+
+ for index, vert_index in enumerate(ms3d_triangle.vertex_indices):
+ if vert_index < 0 or vert_index >= length_verts:
+ continue
+ bmv = bm.verts[vert_index]
+
+ blender_normal = self.geometry_correction(
+ ms3d_triangle.vertex_normals[index])
+ if bmv.normal == blender_invalide_normal:
+ bmv.normal = blender_normal
+ elif bmv.normal != blender_normal \
+ and self.options.extended_normal_handling:
+ ## search for an already created extra vertex
+ bmv_new = None
+ for vert_index_candidat in range(
+ vertex_extra_index, length_verts):
+ bmv_candidat = bm.verts[vert_index_candidat]
+ if bmv_candidat.co == bmv.co \
+ and bmv_candidat.normal == blender_normal:
+ bmv_new = bmv_candidat
+ vert_index = vert_index_candidat
+ break
+
+ ## if not exists, create one in blender and ms3d as well
+ if bmv_new is None:
+ ms3d_model.vertices.append(
+ ms3d_model.vertices[vert_index])
+ bmv_new = bm.verts.new(bmv.co)
+ bmv_new.normal = blender_normal
+ bmv_new[layer_extra] = bmv[layer_extra]
+ vert_index = length_verts
+ length_verts += 1
+ self.options.report({'WARNING', 'INFO'},
+ ms3d_str['WARNING_IMPORT_EXTRA_VERTEX_NORMAL'].format(
+ bmv.normal, blender_normal))
+ bmv = bmv_new
+
+ if [[x] for x in bmv_list if x == bmv]:
+ self.options.report(
+ {'WARNING', 'INFO'},
+ ms3d_str['WARNING_IMPORT_SKIP_VERTEX_DOUBLE'].format(
+ ms3d_triangle_index))
+ continue
+ bmv_list.append(bmv)
+ bmf_normal += bmv.normal
+
+ if len(bmv_list) < 3:
+ self.options.report(
+ {'WARNING', 'INFO'},
+ ms3d_str['WARNING_IMPORT_SKIP_LESS_VERTICES'].format(
+ ms3d_triangle_index))
+ continue
+
+ bmf_normal.normalize()
+
+ bmf = bm.faces.get(bmv_list)
+ if bmf is not None:
+ self.options.report(
+ {'WARNING', 'INFO'},
+ ms3d_str['WARNING_IMPORT_SKIP_FACE_DOUBLE'].format(
+ ms3d_triangle_index))
+ continue
+
+ bmf = bm.faces.new(bmv_list)
+ bmf.normal = bmf_normal
+
+ # blender uv custom data per "face vertex"
+ bmf.loops[0][layer_uv].uv = Vector(
+ (ms3d_triangle.s[0], 1.0 - ms3d_triangle.t[0]))
+ bmf.loops[1][layer_uv].uv = Vector(
+ (ms3d_triangle.s[1], 1.0 - ms3d_triangle.t[1]))
+ bmf.loops[2][layer_uv].uv = Vector(
+ (ms3d_triangle.s[2], 1.0 - ms3d_triangle.t[2]))
+
+ # ms3d custom data per "mesh face"
+ bmf[layer_smoothing_group] = ms3d_triangle.smoothing_group
+
+ blender_group_id = ms3d_to_blender_group_index.get(
+ ms3d_triangle.group_index)
+ if blender_group_id is not None:
+ bmf[layer_group] = blender_group_id
+
+ if ms3d_triangle.group_index >= 0 \
+ and ms3d_triangle.group_index < len(ms3d_model.groups):
+ ms3d_material_index \
+ = ms3d_model.groups[ms3d_triangle.group_index].material_index
+ if ms3d_material_index != Ms3dSpec.NONE_GROUP_MATERIAL_INDEX:
+ bmf.material_index = ms3d_material_index
+ # apply diffuse texture image to face, to be visible in 3d view
+ bmf[layer_texture].image = ms3d_to_blender_material.get(
+ ms3d_material_index)
+
+ # helper dictionary for post-processing smoothing_groups
+ smoothing_group_blender_face = smoothing_group_blender_faces.get(
+ ms3d_triangle.smoothing_group)
+ if smoothing_group_blender_face is None:
+ smoothing_group_blender_face = []
+ smoothing_group_blender_faces[ms3d_triangle.smoothing_group] \
+ = smoothing_group_blender_face
+ smoothing_group_blender_face.append(bmf)
+
+ ##########################
+ # BMesh stuff:
+ # create all sharp edges for blender to make smoothing_groups visible
+ for ms3d_smoothing_group_index, blender_face_list \
+ in smoothing_group_blender_faces.items():
+ edge_dict = {}
+ for bmf in blender_face_list:
+ bmf.smooth = True
+ for bme in bmf.edges:
+ if edge_dict.get(bme) is None:
+ edge_dict[bme] = 0
+ else:
+ edge_dict[bme] += 1
+ bme.seam = (edge_dict[bme] == 0)
+ bme.smooth = (edge_dict[bme] != 0)
+
+ ##########################
+ # BMesh stuff:
+ # finally tranfer BMesh to Mesh
+ bm.to_mesh(blender_mesh)
+ bm.free()
+
+
+ #
+ # end BMesh stuff
+ ####################################################
+
+ blender_mesh.validate(self.options.verbose)
+
+ return blender_mesh_object
+
+
+ ###########################################################################
+ def create_animation(self, blender_context, ms3d_model, blender_mesh_object):
+ ##########################
+ # setup scene
+ blender_scene = blender_context.scene
+ blender_scene.render.fps = ms3d_model.animation_fps
+ if ms3d_model.animation_fps:
+ blender_scene.render.fps_base = (blender_scene.render.fps /
+ ms3d_model.animation_fps)
+
+ blender_scene.frame_start = 1
+ blender_scene.frame_end = (ms3d_model.number_total_frames
+ + blender_scene.frame_start) - 1
+ blender_scene.frame_current = (ms3d_model.current_time
+ * ms3d_model.animation_fps)
+
+ ##########################
+ if not ms3d_model.joints:
+ return
+
+ ##########################
+ ms3d_armature_name = "{}.a".format(ms3d_model.name)
+ ms3d_action_name = "{}.act".format(ms3d_model.name)
+
+ ##########################
+ # create new blender_armature_object
+ blender_armature = blender_context.blend_data.armatures.new(
+ ms3d_armature_name)
+ blender_armature.ms3d.name = ms3d_model.name
+ blender_armature.draw_type = 'STICK'
+ blender_armature.show_axes = True
+ blender_armature.use_auto_ik = True
+ blender_armature_object = blender_context.blend_data.objects.new(
+ ms3d_armature_name, blender_armature)
+ blender_scene.objects.link(blender_armature_object)
+ #blender_armature_object.location = blender_scene.cursor_location
+ blender_armature_object.show_x_ray = True
+
+ ##########################
+ # create new modifier
+ blender_modifier = blender_mesh_object.modifiers.new(
+ ms3d_armature_name, type='ARMATURE')
+ blender_modifier.show_expanded = False
+ blender_modifier.use_vertex_groups = True
+ blender_modifier.use_bone_envelopes = False
+ blender_modifier.object = blender_armature_object
+
+ ##########################
+ # prepare for vertex groups
+ ms3d_to_blender_vertex_groups = {}
+ for ms3d_vertex_index, ms3d_vertex in enumerate(ms3d_model.vertices):
+ # prepare for later use for blender vertex group
+ if ms3d_vertex.bone_id != Ms3dSpec.NONE_VERTEX_BONE_ID:
+ if ms3d_vertex.vertex_ex_object \
+ and ( \
+ ms3d_vertex.vertex_ex_object.bone_ids[0] != \
+ Ms3dSpec.NONE_VERTEX_BONE_ID \
+ or ms3d_vertex.vertex_ex_object.bone_ids[1] != \
+ Ms3dSpec.NONE_VERTEX_BONE_ID \
+ or ms3d_vertex.vertex_ex_object.bone_ids[2] != \
+ Ms3dSpec.NONE_VERTEX_BONE_ID \
+ ):
+ ms3d_vertex_group_ids_weights = []
+ ms3d_vertex_group_ids_weights.append(
+ (ms3d_vertex.bone_id,
+ float(ms3d_vertex.vertex_ex_object.weights[0] % 101) / 100.0,
+ ))
+ if ms3d_vertex.vertex_ex_object.bone_ids[0] != \
+ Ms3dSpec.NONE_VERTEX_BONE_ID:
+ ms3d_vertex_group_ids_weights.append(
+ (ms3d_vertex.vertex_ex_object.bone_ids[0],
+ float(ms3d_vertex.vertex_ex_object.weights[1] % 101) / 100.0
+ ))
+ if ms3d_vertex.vertex_ex_object.bone_ids[1] != \
+ Ms3dSpec.NONE_VERTEX_BONE_ID:
+ ms3d_vertex_group_ids_weights.append(
+ (ms3d_vertex.vertex_ex_object.bone_ids[1],
+ float(ms3d_vertex.vertex_ex_object.weights[2] % 101) / 100.0
+ ))
+ if ms3d_vertex.vertex_ex_object.bone_ids[2] != \
+ Ms3dSpec.NONE_VERTEX_BONE_ID:
+ ms3d_vertex_group_ids_weights.append(
+ (ms3d_vertex.vertex_ex_object.bone_ids[2],
+ 1.0 -
+ float((ms3d_vertex.vertex_ex_object.weights[0] % 101)
+ + (ms3d_vertex.vertex_ex_object.weights[1] % 101)
+ + (ms3d_vertex.vertex_ex_object.weights[2] % 101)) / 100.0
+ ))
+
+ else:
+ ms3d_vertex_group_ids_weights = [(ms3d_vertex.bone_id, 1.0), ]
+
+ for ms3d_vertex_group_id_weight in ms3d_vertex_group_ids_weights:
+ ms3d_vertex_group_id = ms3d_vertex_group_id_weight[0]
+ blender_vertex_weight = ms3d_vertex_group_id_weight[1]
+ blender_vertex_group = ms3d_to_blender_vertex_groups.get(
+ ms3d_vertex_group_id)
+ if blender_vertex_group is None:
+ ms3d_to_blender_vertex_groups[ms3d_vertex_group_id] \
+ = blender_vertex_group = []
+ blender_vertex_group.append((ms3d_vertex_index,
+ blender_vertex_weight))
+
+ ##########################
+ # blender stuff:
+ # create all vertex groups to be used for bones
+ for ms3d_bone_id, blender_vertex_index_weight_list \
+ in ms3d_to_blender_vertex_groups.items():
+ ms3d_name = ms3d_model.joints[ms3d_bone_id].name
+ blender_vertex_group = blender_mesh_object.vertex_groups.new(
+ ms3d_name)
+ for blender_vertex_id_weight in blender_vertex_index_weight_list:
+ blender_vertex_index = blender_vertex_id_weight[0]
+ blender_vertex_weight = blender_vertex_id_weight[1]
+ blender_vertex_group.add((blender_vertex_index, ),
+ blender_vertex_weight, 'ADD')
+
+ ##########################
+ # bring joints in the correct order
+ ms3d_joints_ordered = []
+ self.build_ms3d_joint_dependency_order(ms3d_model.joints,
+ ms3d_joints_ordered)
+
+ ##########################
+ # prepare joint data for later use
+ ms3d_joint_by_name = {}
+ for ms3d_joint in ms3d_joints_ordered:
+ item = ms3d_joint_by_name.get(ms3d_joint.name)
+ if item is None:
+ ms3d_joint.__children = []
+ ms3d_joint_by_name[ms3d_joint.name] = ms3d_joint
+
+ matrix_local_rot = (Matrix.Rotation(ms3d_joint.rotation[2], 4, 'Z')
+ * Matrix.Rotation(ms3d_joint.rotation[1], 4, 'Y')
+ ) * Matrix.Rotation(ms3d_joint.rotation[0], 4, 'X')
+ matrix_local = Matrix.Translation(Vector(ms3d_joint.position)
+ ) * matrix_local_rot
+
+ ms3d_joint.__matrix_local_rot = matrix_local_rot
+ ms3d_joint.__matrix_global_rot = matrix_local_rot
+ ms3d_joint.__matrix_local = matrix_local
+ ms3d_joint.__matrix_global = matrix_local
+
+ if ms3d_joint.parent_name:
+ ms3d_joint_parent = ms3d_joint_by_name.get(
+ ms3d_joint.parent_name)
+ if ms3d_joint_parent is not None:
+ ms3d_joint_parent.__children.append(ms3d_joint)
+
+ matrix_global = ms3d_joint_parent.__matrix_global \
+ * matrix_local
+ ms3d_joint.__matrix_global = matrix_global
+
+ matrix_global_rot = ms3d_joint_parent.__matrix_global_rot \
+ * matrix_local_rot
+ ms3d_joint.__matrix_global_rot = matrix_global_rot
+
+ ##########################
+ # ms3d_joint to blender_edit_bone
+ if ms3d_model.model_ex_object and not self.options.use_joint_size:
+ joint_length = ms3d_model.model_ex_object.joint_size
+ else:
+ joint_length = self.options.joint_size
+ if joint_length < 0.01:
+ joint_length = 0.01
+
+ blender_scene.objects.active = blender_armature_object
+ enable_edit_mode(True, blender_context)
+ for ms3d_joint in ms3d_joints_ordered:
+ blender_edit_bone = blender_armature.edit_bones.new(ms3d_joint.name)
+ blender_edit_bone.use_connect = False
+ blender_edit_bone.use_inherit_rotation = True
+ blender_edit_bone.use_inherit_scale = True
+ blender_edit_bone.use_local_location = True
+ blender_armature.edit_bones.active = blender_edit_bone
+
+ ms3d_joint = ms3d_joint_by_name[ms3d_joint.name]
+ ms3d_joint_vector = ms3d_joint.__matrix_global * Vector()
+
+ blender_edit_bone.head \
+ = self.geometry_correction(ms3d_joint_vector)
+
+ vector_tail_end_up = ms3d_joint.__matrix_global_rot * Vector((0,1,0))
+ vector_tail_end_dir = ms3d_joint.__matrix_global_rot * Vector((0,0,1))
+ vector_tail_end_up.normalize()
+ vector_tail_end_dir.normalize()
+ blender_edit_bone.tail = blender_edit_bone.head \
+ + self.geometry_correction(
+ vector_tail_end_dir * joint_length)
+ blender_edit_bone.align_roll(self.geometry_correction(
+ vector_tail_end_up))
+
+ if ms3d_joint.parent_name:
+ ms3d_joint_parent = ms3d_joint_by_name[ms3d_joint.parent_name]
+ blender_edit_bone_parent = ms3d_joint_parent.blender_edit_bone
+ blender_edit_bone.parent = blender_edit_bone_parent
+
+ ms3d_joint.blender_bone_name = blender_edit_bone.name
+ ms3d_joint.blender_edit_bone = blender_edit_bone
+ enable_edit_mode(False, blender_context)
+
+ if self.options.joint_to_bones:
+ enable_edit_mode(True, blender_context)
+ for ms3d_joint in ms3d_joints_ordered:
+ blender_edit_bone = blender_armature.edit_bones[ms3d_joint.name]
+ if blender_edit_bone.children:
+ new_length = 0.0
+ for child_bone in blender_edit_bone.children:
+ length = (child_bone.head - blender_edit_bone.head).length
+ if new_length <= 0 or length < new_length:
+ new_length = length
+ if new_length >= 0.01:
+ direction = blender_edit_bone.tail - blender_edit_bone.head
+ direction.normalize()
+ blender_edit_bone.tail = blender_edit_bone.head + (direction * new_length)
+ enable_edit_mode(False, blender_context)
+
+ ##########################
+ # post process bones
+ enable_edit_mode(False, blender_context)
+ for ms3d_joint_name, ms3d_joint in ms3d_joint_by_name.items():
+ blender_bone = blender_armature.bones.get(
+ ms3d_joint.blender_bone_name)
+ if blender_bone is None:
+ continue
+
+ blender_bone.ms3d.name = ms3d_joint.name
+ blender_bone.ms3d.flags = Ms3dUi.flags_from_ms3d(ms3d_joint.flags)
+
+ ms3d_joint_ex = ms3d_joint.joint_ex_object
+ if ms3d_joint_ex is not None:
+ blender_bone.ms3d.color = ms3d_joint_ex.color
+
+ ms3d_comment = ms3d_joint.comment_object
+ if ms3d_comment is not None:
+ blender_bone.ms3d.comment = ms3d_comment.comment
+
+ ##########################
+ if not self.options.use_animation:
+ return blender_armature_object
+
+
+ ##########################
+ # process pose bones
+ enable_pose_mode(True, blender_context)
+
+ blender_action = blender_context.blend_data.actions.new(ms3d_action_name)
+ if blender_armature_object.animation_data is None:
+ blender_armature_object.animation_data_create()
+ blender_armature_object.animation_data.action = blender_action
+
+ ##########################
+ # transition between keys may be incorrect
+ # because of the gimbal-lock problem!
+ # http://www.youtube.com/watch?v=zc8b2Jo7mno
+ # http://www.youtube.com/watch?v=rrUCBOlJdt4
+ # you can fix it manually by selecting the affected keyframes
+ # and allpy the following option to it:
+ # "Graph Editor -> Key -> Discontinuity (Euler) Filter"
+ # ==> "bpy.ops.graph.euler_filter()"
+ # but this option is only available for Euler rotation f-curves!
+ #
+ for ms3d_joint_name, ms3d_joint in ms3d_joint_by_name.items():
+ blender_pose_bone = blender_armature_object.pose.bones.get(
+ ms3d_joint.blender_bone_name)
+ if blender_pose_bone is None:
+ continue
+
+ data_path = blender_pose_bone.path_from_id('location')
+ fcurve_location_x = blender_action.fcurves.new(data_path, index=0)
+ fcurve_location_y = blender_action.fcurves.new(data_path, index=1)
+ fcurve_location_z = blender_action.fcurves.new(data_path, index=2)
+ for translation_key_frames in ms3d_joint.translation_key_frames:
+ frame = (translation_key_frames.time * ms3d_model.animation_fps)
+ matrix_local = Matrix.Translation(
+ Vector(translation_key_frames.position))
+ v = (matrix_local) * Vector()
+ fcurve_location_x.keyframe_points.insert(frame, -v[0])
+ fcurve_location_y.keyframe_points.insert(frame, v[2])
+ fcurve_location_z.keyframe_points.insert(frame, v[1])
+
+ if self.options.is_rotation_mode_quaternion:
+ blender_pose_bone.rotation_mode = 'QUATERNION'
+ data_path = blender_pose_bone.path_from_id("rotation_quaternion")
+ fcurve_rotation_w = blender_action.fcurves.new(data_path, index=0)
+ fcurve_rotation_x = blender_action.fcurves.new(data_path, index=1)
+ fcurve_rotation_y = blender_action.fcurves.new(data_path, index=2)
+ fcurve_rotation_z = blender_action.fcurves.new(data_path, index=3)
+ for rotation_key_frames in ms3d_joint.rotation_key_frames:
+ frame = (rotation_key_frames.time * ms3d_model.animation_fps)
+ matrix_local_rot = (
+ Matrix.Rotation(
+ rotation_key_frames.rotation[2], 4, 'Y')
+ * Matrix.Rotation(
+ rotation_key_frames.rotation[1], 4, 'Z')
+ ) * Matrix.Rotation(
+ -rotation_key_frames.rotation[0], 4, 'X')
+ q = (matrix_local_rot).to_quaternion()
+ fcurve_rotation_w.keyframe_points.insert(frame, q.w)
+ fcurve_rotation_x.keyframe_points.insert(frame, q.x)
+ fcurve_rotation_y.keyframe_points.insert(frame, q.y)
+ fcurve_rotation_z.keyframe_points.insert(frame, q.z)
+ else:
+ blender_pose_bone.rotation_mode = 'XZY'
+ data_path = blender_pose_bone.path_from_id("rotation_euler")
+ fcurve_rotation_x = blender_action.fcurves.new(data_path, index=0)
+ fcurve_rotation_y = blender_action.fcurves.new(data_path, index=1)
+ fcurve_rotation_z = blender_action.fcurves.new(data_path, index=2)
+ for rotation_key_frames in ms3d_joint.rotation_key_frames:
+ frame = (rotation_key_frames.time * ms3d_model.animation_fps)
+ fcurve_rotation_x.keyframe_points.insert(
+ frame, -rotation_key_frames.rotation[0])
+ fcurve_rotation_y.keyframe_points.insert(
+ frame, rotation_key_frames.rotation[2])
+ fcurve_rotation_z.keyframe_points.insert(
+ frame, rotation_key_frames.rotation[1])
+
+ enable_pose_mode(False, blender_context)
+
+ return blender_armature_object
+
+
+ ###########################################################################
+ def geometry_correction(self, value):
+ return Vector((value[2], value[0], value[1]))
+
+
+ ###########################################################################
+ def build_ms3d_joint_dependency_order(self, ms3d_joints, ms3d_joints_ordered):
+ ms3d_joints_children = {"": {}}
+ for ms3d_joint in ms3d_joints:
+ if ms3d_joint.parent_name:
+ ms3d_joint_children = ms3d_joints_children.get(
+ ms3d_joint.parent_name)
+ if ms3d_joint_children is None:
+ ms3d_joint_children = ms3d_joints_children[
+ ms3d_joint.parent_name] = {}
+ else:
+ ms3d_joint_children = ms3d_joints_children[""]
+
+ ms3d_joint_children[ms3d_joint.name] = ms3d_joint
+
+ self.traverse_dependencies(
+ ms3d_joints_ordered,
+ ms3d_joints_children,
+ "")
+
+
+ return ms3d_joints_ordered
+
+
+ ###########################################################################
+ def traverse_dependencies(self, ms3d_joints_ordered, ms3d_joints_children,
+ key):
+ ms3d_joint_children = ms3d_joints_children.get(key)
+ if ms3d_joint_children:
+ for item in ms3d_joint_children.items():
+ ms3d_joint_name = item[0]
+ ms3d_joint = item[1]
+ ms3d_joints_ordered.append(ms3d_joint)
+ self.traverse_dependencies(
+ ms3d_joints_ordered,
+ ms3d_joints_children,
+ ms3d_joint_name)
+
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py
new file mode 100644
index 0000000..177fd4f
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_spec.py
@@ -0,0 +1,2075 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+
+
+from struct import (
+ pack,
+ unpack,
+ )
+from sys import (
+ exc_info,
+ )
+from os import (
+ fstat,
+ )
+
+###############################################################################
+#
+# MilkShape 3D 1.8.5 File Format Specification
+#
+# all specifications were taken from SDK 1.8.5
+#
+# some additional specifications were taken from
+# MilkShape 3D Viewer v2.0 (Nov 06 2007) - msMesh.h
+#
+
+
+###############################################################################
+#
+# sizes
+#
+
+class Ms3dSpec:
+ ###########################################################################
+ #
+ # max values
+ #
+ MAX_VERTICES = 65534 # 0..65533; note: (65534???, 65535???)
+ MAX_TRIANGLES = 65534 # 0..65533; note: (65534???, 65535???)
+ MAX_GROUPS = 255 # 1..255; note: (0 default group)
+ MAX_MATERIALS = 128 # 0..127; note: (-1 no material)
+ MAX_JOINTS = 128 # 0..127; note: (-1 no joint)
+ MAX_SMOOTH_GROUP = 32 # 0..32; note: (0 no smoothing group)
+ MAX_TEXTURE_FILENAME_SIZE = 128
+
+ ###########################################################################
+ #
+ # flags
+ #
+ FLAG_NONE = 0
+ FLAG_SELECTED = 1
+ FLAG_HIDDEN = 2
+ FLAG_SELECTED2 = 4
+ FLAG_DIRTY = 8
+ FLAG_ISKEY = 16 # additional spec from [2]
+ FLAG_NEWLYCREATED = 32 # additional spec from [2]
+ FLAG_MARKED = 64 # additional spec from [2]
+
+ FLAG_TEXTURE_NONE = 0x00
+ FLAG_TEXTURE_COMBINE_ALPHA = 0x20
+ FLAG_TEXTURE_HAS_ALPHA = 0x40
+ FLAG_TEXTURE_SPHERE_MAP = 0x80
+
+ MODE_TRANSPARENCY_SIMPLE = 0
+ MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF = 1
+ MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES = 2
+
+
+ ###########################################################################
+ #
+ # values
+ #
+ HEADER = "MS3D000000"
+
+
+ ###########################################################################
+ #
+ # min, max, default values
+ #
+ NONE_VERTEX_BONE_ID = -1
+ NONE_GROUP_MATERIAL_INDEX = -1
+
+ DEFAULT_HEADER = HEADER
+ DEFAULT_HEADER_VERSION = 4
+ DEFAULT_VERTEX_BONE_ID = NONE_VERTEX_BONE_ID
+ DEFAULT_TRIANGLE_SMOOTHING_GROUP = 0
+ DEFAULT_TRIANGLE_GROUP = 0
+ DEFAULT_MATERIAL_MODE = FLAG_TEXTURE_NONE
+ DEFAULT_GROUP_MATERIAL_INDEX = NONE_GROUP_MATERIAL_INDEX
+ DEFAULT_MODEL_JOINT_SIZE = 1.0
+ DEFAULT_MODEL_TRANSPARENCY_MODE = MODE_TRANSPARENCY_SIMPLE
+ DEFAULT_MODEL_ANIMATION_FPS = 25.0
+ DEFAULT_MODEL_SUB_VERSION_COMMENTS = 1
+ DEFAULT_MODEL_SUB_VERSION_VERTEX_EXTRA = 2
+ DEFAULT_MODEL_SUB_VERSION_JOINT_EXTRA = 1
+ DEFAULT_MODEL_SUB_VERSION_MODEL_EXTRA = 1
+ DEFAULT_FLAGS = FLAG_NONE
+ MAX_MATERIAL_SHININESS = 128
+
+ # blender default / OpenGL default
+ DEFAULT_MATERIAL_AMBIENT = (0.2, 0.2, 0.2, 1.0)
+ DEFAULT_MATERIAL_DIFFUSE = (0.8, 0.8, 0.8, 1.0)
+ DEFAULT_MATERIAL_SPECULAR = (1.0, 1.0, 1.0, 1.0)
+ DEFAULT_MATERIAL_EMISSIVE = (0.0, 0.0, 0.0, 1.0)
+ DEFAULT_MATERIAL_SHININESS = 12.5
+
+ DEFAULT_JOINT_COLOR = (0.8, 0.8, 0.8)
+
+###############################################################################
+#
+# helper class for basic raw io
+#
+class EOF(BaseException):
+ pass
+
+class Ms3dIo:
+ # sizes for IO
+ SIZE_BYTE = 1
+ SIZE_SBYTE = 1
+ SIZE_WORD = 2
+ SIZE_DWORD = 4
+ SIZE_FLOAT = 4
+ LENGTH_ID = 10
+ LENGTH_NAME = 32
+ LENGTH_FILENAME = 128
+
+ PRECISION = 4
+
+ @staticmethod
+ def raise_on_eof(file):
+ """ pseudo end of file detection """
+ fd = file.fileno()
+ stat = fstat(fd)
+ if file.tell() >= stat.st_size:
+ raise EOF()
+
+ @staticmethod
+ def read_byte(file):
+ """ read a single byte from file """
+ value = unpack('<B', file.read(Ms3dIo.SIZE_BYTE))[0]
+ return value
+
+ @staticmethod
+ def write_byte(file, value):
+ """ write a single byte to file """
+ file.write(pack('<B', value))
+
+ @staticmethod
+ def read_sbyte(file):
+ """ read a single signed byte from file """
+ value = unpack('<b', file.read(Ms3dIo.SIZE_SBYTE))[0]
+ return value
+
+ @staticmethod
+ def write_sbyte(file, value):
+ """ write a single signed byte to file """
+ file.write(pack('<b', value))
+
+ @staticmethod
+ def read_word(file):
+ """ read a word from file """
+ value = unpack('<H', file.read(Ms3dIo.SIZE_WORD))[0]
+ return value
+
+ @staticmethod
+ def write_word(file, value):
+ """ write a word to file """
+ file.write(pack('<H', value))
+
+ @staticmethod
+ def read_dword(file):
+ """ read a double word from file """
+ value = unpack('<I', file.read(Ms3dIo.SIZE_DWORD))[0]
+ return value
+
+ @staticmethod
+ def write_dword(file, value):
+ """ write a double word to file """
+ file.write(pack('<I', value))
+
+ @staticmethod
+ def read_float(file):
+ """ read a float from file """
+ value = unpack('<f', file.read(Ms3dIo.SIZE_FLOAT))[0]
+ return value
+
+ @staticmethod
+ def write_float(file, value):
+ """ write a float to file """
+ file.write(pack('<f', value))
+
+ @staticmethod
+ def read_array(file, itemReader, count):
+ """ read an array[count] of objects from file, by using a itemReader """
+ value = []
+ for i in range(count):
+ itemValue = itemReader(file)
+ value.append(itemValue)
+ return tuple(value)
+
+ @staticmethod
+ def write_array(file, itemWriter, count, value):
+ """ write an array[count] of objects to file, by using a itemWriter """
+ for i in range(count):
+ itemValue = value[i]
+ itemWriter(file, itemValue)
+
+ @staticmethod
+ def read_array2(file, itemReader, count, count2):
+ """ read an array[count][count2] of objects from file,
+ by using a itemReader """
+ value = []
+ for i in range(count):
+ itemValue = Ms3dIo.read_array(file, itemReader, count2)
+ value.append(tuple(itemValue))
+ return value
+
+ @staticmethod
+ def write_array2(file, itemWriter, count, count2, value):
+ """ write an array[count][count2] of objects to file,
+ by using a itemWriter """
+ for i in range(count):
+ itemValue = value[i]
+ Ms3dIo.write_array(file, itemWriter, count2, itemValue)
+
+ @staticmethod
+ def read_string(file, length):
+ """ read a string of a specific length from file """
+ value = []
+ skip = False
+ for i in range(length):
+ raw = unpack('<b', file.read(Ms3dIo.SIZE_SBYTE))[0]
+ if (raw >= 32) & (raw <= 255):
+ pass
+ else:
+ if (raw == 0):
+ raw = 0
+ skip = True
+ else:
+ raw = 32
+
+ c = chr(raw)
+
+ if (not skip):
+ value.append(c)
+
+ finalValue = "".join(value)
+ return finalValue
+
+ @staticmethod
+ def write_string(file, length, value):
+ """ write a string of a specific length to file """
+ l = len(value)
+ for i in range(length):
+ if(i < l):
+ c = value[i]
+
+ if (isinstance(c, str)):
+ c = c[0]
+ raw = ord(c)
+ elif (isinstance(c, int)):
+ raw = c
+ else:
+ pass
+ else:
+ raw = 0
+
+ file.write(pack('<b', raw % 256))
+
+
+###############################################################################
+#
+# multi complex types
+#
+
+###############################################################################
+class Ms3dHeader:
+ """ Ms3dHeader """
+ __slots__ = (
+ 'id',
+ 'version',
+ )
+
+ def __init__(
+ self,
+ default_id=Ms3dSpec.DEFAULT_HEADER,
+ default_version=Ms3dSpec.DEFAULT_HEADER_VERSION
+ ):
+ self.id = default_id
+ self.version = default_version
+
+ def __repr__(self):
+ return "\n<id='{}', version={}>".format(
+ self.id,
+ self.version
+ )
+
+ def __hash__(self):
+ return hash(self.id) ^ hash(self.version)
+
+ def __eq__(self, other):
+ return ((self is not None) and (other is not None)
+ and (self.id == other.id)
+ and (self.version == other.version))
+
+ def read(self, file):
+ self.id = Ms3dIo.read_string(file, Ms3dIo.LENGTH_ID)
+ self.version = Ms3dIo.read_dword(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_ID, self.id)
+ Ms3dIo.write_dword(file, self.version)
+
+
+###############################################################################
+class Ms3dVertex:
+ """ Ms3dVertex """
+ """
+ __slots__ was taking out,
+ to be able to inject additional attributes during runtime
+ __slots__ = (
+ 'flags',
+ 'bone_id',
+ 'reference_count',
+ '_vertex',
+ '_vertex_ex_object', # Ms3dVertexEx
+ )
+ """
+
+ def __init__(
+ self,
+ default_flags=Ms3dSpec.DEFAULT_FLAGS,
+ default_vertex=(0.0, 0.0, 0.0),
+ default_bone_id=Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ default_reference_count=0,
+ default_vertex_ex_object=None, # Ms3dVertexEx
+ ):
+ self.flags = default_flags
+ self._vertex = default_vertex
+ self.bone_id = default_bone_id
+ self.reference_count = default_reference_count
+
+ if default_vertex_ex_object is None:
+ default_vertex_ex_object = Ms3dVertexEx2()
+ # Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_VERTEX_EXTRA = 2
+ self._vertex_ex_object = default_vertex_ex_object
+ # Ms3dVertexEx
+
+ def __repr__(self):
+ return "\n<flags={}, vertex=({:.{p}f}, {:.{p}f}, {:.{p}f}), bone_id={},"\
+ " reference_count={}>".format(
+ self.flags,
+ self._vertex[0],
+ self._vertex[1],
+ self._vertex[2],
+ self.bone_id,
+ self.reference_count,
+ p=Ms3dIo.PRECISION
+ )
+
+ def __hash__(self):
+ return (hash(self.vertex)
+ #^ hash(self.flags)
+ #^ hash(self.bone_id)
+ #^ hash(self.reference_count)
+ )
+
+ def __eq__(self, other):
+ return ((self.vertex == other.vertex)
+ #and (self.flags == other.flags)
+ #and (self.bone_id == other.bone_id)
+ #and (self.reference_count == other.reference_count)
+ )
+
+
+ @property
+ def vertex(self):
+ return self._vertex
+
+ @property
+ def vertex_ex_object(self):
+ return self._vertex_ex_object
+
+
+ def read(self, file):
+ self.flags = Ms3dIo.read_byte(file)
+ self._vertex = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ self.bone_id = Ms3dIo.read_sbyte(file)
+ self.reference_count = Ms3dIo.read_byte(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_byte(file, self.flags)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.vertex)
+ Ms3dIo.write_sbyte(file, self.bone_id)
+ Ms3dIo.write_byte(file, self.reference_count)
+
+
+###############################################################################
+class Ms3dTriangle:
+ """ Ms3dTriangle """
+ """
+ __slots__ was taking out,
+ to be able to inject additional attributes during runtime
+ __slots__ = (
+ 'flags',
+ 'smoothing_group',
+ 'group_index',
+ '_vertex_indices',
+ '_vertex_normals',
+ '_s',
+ '_t',
+ )
+ """
+
+ def __init__(
+ self,
+ default_flags=Ms3dSpec.DEFAULT_FLAGS,
+ default_vertex_indices=(0, 0, 0),
+ default_vertex_normals=(
+ (0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0)),
+ default_s=(0.0, 0.0, 0.0),
+ default_t=(0.0, 0.0, 0.0),
+ default_smoothing_group=Ms3dSpec.DEFAULT_TRIANGLE_SMOOTHING_GROUP,
+ default_group_index=Ms3dSpec.DEFAULT_TRIANGLE_GROUP
+ ):
+ self.flags = default_flags
+ self._vertex_indices = default_vertex_indices
+ self._vertex_normals = default_vertex_normals
+ self._s = default_s
+ self._t = default_t
+ self.smoothing_group = default_smoothing_group
+ self.group_index = default_group_index
+
+ def __repr__(self):
+ return "\n<flags={}, vertex_indices={}, vertex_normals=(({:.{p}f}, "\
+ "{:.{p}f}, {:.{p}f}), ({:.{p}f}, {:.{p}f}, {:.{p}f}), ({:.{p}f}, "\
+ "{:.{p}f}, {:.{p}f})), s=({:.{p}f}, {:.{p}f}, {:.{p}f}), "\
+ "t=({:.{p}f}, {:.{p}f}, {:.{p}f}), smoothing_group={}, "\
+ "group_index={}>".format(
+ self.flags,
+ self.vertex_indices,
+ self.vertex_normals[0][0],
+ self.vertex_normals[0][1],
+ self.vertex_normals[0][2],
+ self.vertex_normals[1][0],
+ self.vertex_normals[1][1],
+ self.vertex_normals[1][2],
+ self.vertex_normals[2][0],
+ self.vertex_normals[2][1],
+ self.vertex_normals[2][2],
+ self.s[0],
+ self.s[1],
+ self.s[2],
+ self.t[0],
+ self.t[1],
+ self.t[2],
+ self.smoothing_group,
+ self.group_index,
+ p=Ms3dIo.PRECISION
+ )
+
+
+ @property
+ def vertex_indices(self):
+ return self._vertex_indices
+
+ @property
+ def vertex_normals(self):
+ return self._vertex_normals
+
+ @property
+ def s(self):
+ return self._s
+
+ @property
+ def t(self):
+ return self._t
+
+
+ def read(self, file):
+ self.flags = Ms3dIo.read_word(file)
+ self._vertex_indices = Ms3dIo.read_array(file, Ms3dIo.read_word, 3)
+ self._vertex_normals = Ms3dIo.read_array2(file, Ms3dIo.read_float, 3, 3)
+ self._s = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ self._t = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ self.smoothing_group = Ms3dIo.read_byte(file)
+ self.group_index = Ms3dIo.read_byte(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_word(file, self.flags)
+ Ms3dIo.write_array(file, Ms3dIo.write_word, 3, self.vertex_indices)
+ Ms3dIo.write_array2(file, Ms3dIo.write_float, 3, 3, self.vertex_normals)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.s)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.t)
+ Ms3dIo.write_byte(file, self.smoothing_group)
+ Ms3dIo.write_byte(file, self.group_index)
+
+
+###############################################################################
+class Ms3dGroup:
+ """ Ms3dGroup """
+ """
+ __slots__ was taking out,
+ to be able to inject additional attributes during runtime
+ __slots__ = (
+ 'flags',
+ 'name',
+ 'material_index',
+ '_triangle_indices',
+ '_comment_object', # Ms3dComment
+ )
+ """
+
+ def __init__(
+ self,
+ default_flags=Ms3dSpec.DEFAULT_FLAGS,
+ default_name="",
+ default_triangle_indices=None,
+ default_material_index=Ms3dSpec.DEFAULT_GROUP_MATERIAL_INDEX,
+ default_comment_object=None, # Ms3dComment
+ ):
+ if (default_name is None):
+ default_name = ""
+
+ if (default_triangle_indices is None):
+ default_triangle_indices = []
+
+ self.flags = default_flags
+ self.name = default_name
+ self._triangle_indices = default_triangle_indices
+ self.material_index = default_material_index
+
+ if default_comment_object is None:
+ default_comment_object = Ms3dCommentEx()
+ self._comment_object = default_comment_object # Ms3dComment
+
+ def __repr__(self):
+ return "\n<flags={}, name='{}', number_triangles={},"\
+ " triangle_indices={}, material_index={}>".format(
+ self.flags,
+ self.name,
+ self.number_triangles,
+ self.triangle_indices,
+ self.material_index
+ )
+
+
+ @property
+ def number_triangles(self):
+ if self.triangle_indices is None:
+ return 0
+ return len(self.triangle_indices)
+
+ @property
+ def triangle_indices(self):
+ return self._triangle_indices
+
+ @property
+ def comment_object(self):
+ return self._comment_object
+
+
+ def read(self, file):
+ self.flags = Ms3dIo.read_byte(file)
+ self.name = Ms3dIo.read_string(file, Ms3dIo.LENGTH_NAME)
+ _number_triangles = Ms3dIo.read_word(file)
+ self._triangle_indices = Ms3dIo.read_array(
+ file, Ms3dIo.read_word, _number_triangles)
+ self.material_index = Ms3dIo.read_sbyte(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_byte(file, self.flags)
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_NAME, self.name)
+ Ms3dIo.write_word(file, self.number_triangles)
+ Ms3dIo.write_array(
+ file, Ms3dIo.write_word, self.number_triangles,
+ self.triangle_indices)
+ Ms3dIo.write_sbyte(file, self.material_index)
+
+
+###############################################################################
+class Ms3dMaterial:
+ """ Ms3dMaterial """
+ """
+ __slots__ was taking out,
+ to be able to inject additional attributes during runtime
+ __slots__ = (
+ 'name',
+ 'shininess',
+ 'transparency',
+ 'mode',
+ 'texture',
+ 'alphamap',
+ '_ambient',
+ '_diffuse',
+ '_specular',
+ '_emissive',
+ '_comment_object', # Ms3dComment
+ )
+ """
+
+ def __init__(
+ self,
+ default_name="",
+ default_ambient=list(Ms3dSpec.DEFAULT_MATERIAL_AMBIENT),
+ default_diffuse=list(Ms3dSpec.DEFAULT_MATERIAL_DIFFUSE),
+ default_specular=list(Ms3dSpec.DEFAULT_MATERIAL_SPECULAR),
+ default_emissive=list(Ms3dSpec.DEFAULT_MATERIAL_EMISSIVE),
+ default_shininess=Ms3dSpec.DEFAULT_MATERIAL_SHININESS,
+ default_transparency=0.0,
+ default_mode=Ms3dSpec.DEFAULT_MATERIAL_MODE,
+ default_texture="",
+ default_alphamap="",
+ default_comment_object=None, # Ms3dComment
+ ):
+ if (default_name is None):
+ default_name = ""
+
+ if (default_texture is None):
+ default_texture = ""
+
+ if (default_alphamap is None):
+ default_alphamap = ""
+
+ self.name = default_name
+ self._ambient = default_ambient
+ self._diffuse = default_diffuse
+ self._specular = default_specular
+ self._emissive = default_emissive
+ self.shininess = default_shininess
+ self.transparency = default_transparency
+ self.mode = default_mode
+ self.texture = default_texture
+ self.alphamap = default_alphamap
+
+ if default_comment_object is None:
+ default_comment_object = Ms3dCommentEx()
+ self._comment_object = default_comment_object # Ms3dComment
+
+ def __repr__(self):
+ return "\n<name='{}', ambient=({:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}), "\
+ "diffuse=({:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}), specular=("\
+ "{:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}), emissive=({:.{p}f}, "\
+ "{:.{p}f}, {:.{p}f}, {:.{p}f}), shininess={:.{p}f}, transparency="\
+ "{:.{p}f}, mode={}, texture='{}', alphamap='{}'>".format(
+ self.name,
+ self.ambient[0],
+ self.ambient[1],
+ self.ambient[2],
+ self.ambient[3],
+ self.diffuse[0],
+ self.diffuse[1],
+ self.diffuse[2],
+ self.diffuse[3],
+ self.specular[0],
+ self.specular[1],
+ self.specular[2],
+ self.specular[3],
+ self.emissive[0],
+ self.emissive[1],
+ self.emissive[2],
+ self.emissive[3],
+ self.shininess,
+ self.transparency,
+ self.mode,
+ self.texture,
+ self.alphamap,
+ p=Ms3dIo.PRECISION
+ )
+
+ def __hash__(self):
+ return (hash(self.name)
+
+ ^ hash(self.ambient)
+ ^ hash(self.diffuse)
+ ^ hash(self.specular)
+ ^ hash(self.emissive)
+
+ ^ hash(self.shininess)
+ ^ hash(self.transparency)
+ ^ hash(self.mode)
+
+ ^ hash(self.texture)
+ ^ hash(self.alphamap)
+ )
+
+ def __eq__(self, other):
+ return ((self.name == other.name)
+
+ and (self.ambient == other.ambient)
+ and (self.diffuse == other.diffuse)
+ and (self.specular == other.specular)
+ and (self.emissive == other.emissive)
+
+ and (self.shininess == other.shininess)
+ and (self.transparency == other.transparency)
+ and (self.mode == other.mode)
+
+ #and (self.texture == other.texture)
+ #and (self.alphamap == other.alphamap)
+ )
+
+
+ @property
+ def ambient(self):
+ return self._ambient
+
+ @property
+ def diffuse(self):
+ return self._diffuse
+
+ @property
+ def specular(self):
+ return self._specular
+
+ @property
+ def emissive(self):
+ return self._emissive
+
+ @property
+ def comment_object(self):
+ return self._comment_object
+
+
+ def read(self, file):
+ self.name = Ms3dIo.read_string(file, Ms3dIo.LENGTH_NAME)
+ self._ambient = Ms3dIo.read_array(file, Ms3dIo.read_float, 4)
+ self._diffuse = Ms3dIo.read_array(file, Ms3dIo.read_float, 4)
+ self._specular = Ms3dIo.read_array(file, Ms3dIo.read_float, 4)
+ self._emissive = Ms3dIo.read_array(file, Ms3dIo.read_float, 4)
+ self.shininess = Ms3dIo.read_float(file)
+ self.transparency = Ms3dIo.read_float(file)
+ self.mode = Ms3dIo.read_sbyte(file)
+ self.texture = Ms3dIo.read_string(file, Ms3dIo.LENGTH_FILENAME)
+ self.alphamap = Ms3dIo.read_string(file, Ms3dIo.LENGTH_FILENAME)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_NAME, self.name)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 4, self.ambient)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 4, self.diffuse)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 4, self.specular)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 4, self.emissive)
+ Ms3dIo.write_float(file, self.shininess)
+ Ms3dIo.write_float(file, self.transparency)
+ Ms3dIo.write_sbyte(file, self.mode)
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_FILENAME, self.texture)
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_FILENAME, self.alphamap)
+
+
+###############################################################################
+class Ms3dRotationKeyframe:
+ """ Ms3dRotationKeyframe """
+ __slots__ = (
+ 'time',
+ '_rotation',
+ )
+
+ def __init__(
+ self,
+ default_time=0.0,
+ default_rotation=(0.0, 0.0, 0.0)
+ ):
+ self.time = default_time
+ self._rotation = default_rotation
+
+ def __repr__(self):
+ return "\n<time={:.{p}f}, rotation=({:.{p}f}, {:.{p}f}, {:.{p}f})>".format(
+ self.time,
+ self.rotation[0],
+ self.rotation[1],
+ self.rotation[2],
+ p=Ms3dIo.PRECISION
+ )
+
+
+ @property
+ def rotation(self):
+ return self._rotation
+
+
+ def read(self, file):
+ self.time = Ms3dIo.read_float(file)
+ self._rotation = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_float(file, self.time)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.rotation)
+
+
+###############################################################################
+class Ms3dTranslationKeyframe:
+ """ Ms3dTranslationKeyframe """
+ __slots__ = (
+ 'time',
+ '_position',
+ )
+
+ def __init__(
+ self,
+ default_time=0.0,
+ default_position=(0.0, 0.0, 0.0)
+ ):
+ self.time = default_time
+ self._position = default_position
+
+ def __repr__(self):
+ return "\n<time={:.{p}f}, position=({:.{p}f}, {:.{p}f}, {:.{p}f})>".format(
+ self.time,
+ self.position[0],
+ self.position[1],
+ self.position[2],
+ p=Ms3dIo.PRECISION
+ )
+
+
+ @property
+ def position(self):
+ return self._position
+
+
+ def read(self, file):
+ self.time = Ms3dIo.read_float(file)
+ self._position = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_float(file, self.time)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.position)
+
+
+###############################################################################
+class Ms3dJoint:
+ """ Ms3dJoint """
+ """
+ __slots__ was taking out,
+ to be able to inject additional attributes during runtime
+ __slots__ = (
+ 'flags',
+ 'name',
+ 'parent_name',
+ '_rotation',
+ '_position',
+ '_rotation_keyframes',
+ '_translation_keyframes',
+ '_joint_ex_object', # Ms3dJointEx
+ '_comment_object', # Ms3dComment
+ )
+ """
+
+ def __init__(
+ self,
+ default_flags=Ms3dSpec.DEFAULT_FLAGS,
+ default_name="",
+ default_parent_name="",
+ default_rotation=(0.0, 0.0, 0.0),
+ default_position=(0.0, 0.0, 0.0),
+ default_rotation_keyframes=None,
+ default_translation_keyframes=None,
+ default_joint_ex_object=None, # Ms3dJointEx
+ default_comment_object=None, # Ms3dComment
+ ):
+ if (default_name is None):
+ default_name = ""
+
+ if (default_parent_name is None):
+ default_parent_name = ""
+
+ if (default_rotation_keyframes is None):
+ default_rotation_keyframes = [] #Ms3dRotationKeyframe()
+
+ if (default_translation_keyframes is None):
+ default_translation_keyframes = [] #Ms3dTranslationKeyframe()
+
+ self.flags = default_flags
+ self.name = default_name
+ self.parent_name = default_parent_name
+ self._rotation = default_rotation
+ self._position = default_position
+ self._rotation_keyframes = default_rotation_keyframes
+ self._translation_keyframes = default_translation_keyframes
+
+ if default_comment_object is None:
+ default_comment_object = Ms3dCommentEx()
+ self._comment_object = default_comment_object # Ms3dComment
+
+ if default_joint_ex_object is None:
+ default_joint_ex_object = Ms3dJointEx()
+ self._joint_ex_object = default_joint_ex_object # Ms3dJointEx
+
+ def __repr__(self):
+ return "\n<flags={}, name='{}', parent_name='{}', rotation=({:.{p}f}, "\
+ "{:.{p}f}, {:.{p}f}), position=({:.{p}f}, {:.{p}f}, {:.{p}f}), "\
+ "number_rotation_keyframes={}, number_translation_keyframes={},"\
+ " rotation_key_frames={}, translation_key_frames={}>".format(
+ self.flags,
+ self.name,
+ self.parent_name,
+ self.rotation[0],
+ self.rotation[1],
+ self.rotation[2],
+ self.position[0],
+ self.position[1],
+ self.position[2],
+ self.number_rotation_keyframes,
+ self.number_translation_keyframes,
+ self.rotation_key_frames,
+ self.translation_key_frames,
+ p=Ms3dIo.PRECISION
+ )
+
+
+ @property
+ def rotation(self):
+ return self._rotation
+
+ @property
+ def position(self):
+ return self._position
+
+ @property
+ def number_rotation_keyframes(self):
+ if self.rotation_key_frames is None:
+ return 0
+ return len(self.rotation_key_frames)
+
+ @property
+ def number_translation_keyframes(self):
+ if self.translation_key_frames is None:
+ return 0
+ return len(self.translation_key_frames)
+
+ @property
+ def rotation_key_frames(self):
+ return self._rotation_keyframes
+
+ @property
+ def translation_key_frames(self):
+ return self._translation_keyframes
+
+
+ @property
+ def joint_ex_object(self):
+ return self._joint_ex_object
+
+
+ @property
+ def comment_object(self):
+ return self._comment_object
+
+
+ def read(self, file):
+ self.flags = Ms3dIo.read_byte(file)
+ self.name = Ms3dIo.read_string(file, Ms3dIo.LENGTH_NAME)
+ self.parent_name = Ms3dIo.read_string(file, Ms3dIo.LENGTH_NAME)
+ self._rotation = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ self._position = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ _number_rotation_keyframes = Ms3dIo.read_word(file)
+ _number_translation_keyframes = Ms3dIo.read_word(file)
+ self._rotation_keyframes = []
+ for i in range(_number_rotation_keyframes):
+ self.rotation_key_frames.append(Ms3dRotationKeyframe().read(file))
+ self._translation_keyframes = []
+ for i in range(_number_translation_keyframes):
+ self.translation_key_frames.append(
+ Ms3dTranslationKeyframe().read(file))
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_byte(file, self.flags)
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_NAME, self.name)
+ Ms3dIo.write_string(file, Ms3dIo.LENGTH_NAME, self.parent_name)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.rotation)
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.position)
+ Ms3dIo.write_word(file, self.number_rotation_keyframes)
+ Ms3dIo.write_word(file, self.number_translation_keyframes)
+ for i in range(self.number_rotation_keyframes):
+ self.rotation_key_frames[i].write(file)
+ for i in range(self.number_translation_keyframes):
+ self.translation_key_frames[i].write(file)
+
+
+###############################################################################
+class Ms3dCommentEx:
+ """ Ms3dCommentEx """
+ __slots__ = (
+ 'index',
+ 'comment',
+ )
+
+ def __init__(
+ self,
+ default_index=0,
+ default_comment=""
+ ):
+ if (default_comment is None):
+ default_comment = ""
+
+ self.index = default_index
+ self.comment = default_comment
+
+ def __repr__(self):
+ return "\n<index={}, comment_length={}, comment='{}'>".format(
+ self.index,
+ self.comment_length,
+ self.comment
+ )
+
+
+ @property
+ def comment_length(self):
+ if self.comment is None:
+ return 0
+ return len(self.comment)
+
+
+ def read(self, file):
+ self.index = Ms3dIo.read_dword(file)
+ _comment_length = Ms3dIo.read_dword(file)
+ self.comment = Ms3dIo.read_string(file, _comment_length)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_dword(file, self.index)
+ Ms3dIo.write_dword(file, self.comment_length)
+ Ms3dIo.write_string(file, self.comment_length, self.comment)
+
+
+###############################################################################
+class Ms3dComment:
+ """ Ms3dComment """
+ __slots__ = (
+ 'comment',
+ )
+
+ def __init__(
+ self,
+ default_comment=""
+ ):
+ if (default_comment is None):
+ default_comment = ""
+
+ self.comment = default_comment
+
+ def __repr__(self):
+ return "\n<comment_length={}, comment='{}'>".format(
+ self.comment_length,
+ self.comment
+ )
+
+
+ @property
+ def comment_length(self):
+ if self.comment is None:
+ return 0
+ return len(self.comment)
+
+
+ def read(self, file):
+ _comment_length = Ms3dIo.read_dword(file)
+ self.comment = Ms3dIo.read_string(file, _comment_length)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_dword(file, self.comment_length)
+ Ms3dIo.write_string(file, self.comment_length, self.comment)
+
+
+###############################################################################
+class Ms3dVertexEx1:
+ """ Ms3dVertexEx1 """
+ __slots__ = (
+ '_bone_ids',
+ '_weights',
+ )
+
+ def __init__(
+ self,
+ default_bone_ids=(
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID),
+ default_weights=(100, 0, 0)
+ ):
+ self._bone_ids = default_bone_ids
+ self._weights = default_weights
+
+ def __repr__(self):
+ return "\n<bone_ids={}, weights={}>".format(
+ self.bone_ids,
+ self.weights
+ )
+
+
+ @property
+ def bone_ids(self):
+ return self._bone_ids
+
+ @property
+ def weights(self):
+ return self._weights
+
+
+ @property
+ def weight_bone_id(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights
+ return 100
+
+ @property
+ def weight_bone_id0(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights[0]
+ return 0
+
+ @property
+ def weight_bone_id1(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights[1]
+ return 0
+
+ @property
+ def weight_bone_id2(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return 100 - (self._weights[0] + self._weights[1] \
+ + self._weights[2])
+ return 0
+
+
+ def read(self, file):
+ self._bone_ids = Ms3dIo.read_array(file, Ms3dIo.read_sbyte, 3)
+ self._weights = Ms3dIo.read_array(file, Ms3dIo.read_byte, 3)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_array(file, Ms3dIo.write_sbyte, 3, self.bone_ids)
+ Ms3dIo.write_array(file, Ms3dIo.write_byte, 3, self.weights)
+
+
+###############################################################################
+class Ms3dVertexEx2:
+ """ Ms3dVertexEx2 """
+ __slots__ = (
+ 'extra',
+ '_bone_ids',
+ '_weights',
+ )
+
+ def __init__(
+ self,
+ default_bone_ids=(
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID),
+ default_weights=(100, 0, 0),
+ default_extra=0
+ ):
+ self._bone_ids = default_bone_ids
+ self._weights = default_weights
+ self.extra = default_extra
+
+ def __repr__(self):
+ return "\n<bone_ids={}, weights={}, extra={}>".format(
+ self.bone_ids,
+ self.weights,
+ self.extra
+ )
+
+
+ @property
+ def bone_ids(self):
+ return self._bone_ids
+
+ @property
+ def weights(self):
+ return self._weights
+
+
+ @property
+ def weight_bone_id(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights
+ return 100
+
+ @property
+ def weight_bone_id0(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights[0]
+ return 0
+
+ @property
+ def weight_bone_id1(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights[1]
+ return 0
+
+ @property
+ def weight_bone_id2(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return 100 - (self._weights[0] + self._weights[1] \
+ + self._weights[2])
+ return 0
+
+
+ def read(self, file):
+ self._bone_ids = Ms3dIo.read_array(file, Ms3dIo.read_sbyte, 3)
+ self._weights = Ms3dIo.read_array(file, Ms3dIo.read_byte, 3)
+ self.extra = Ms3dIo.read_dword(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_array(file, Ms3dIo.write_sbyte, 3, self.bone_ids)
+ Ms3dIo.write_array(file, Ms3dIo.write_byte, 3, self.weights)
+ Ms3dIo.write_dword(file, self.extra)
+
+
+###############################################################################
+class Ms3dVertexEx3:
+ """ Ms3dVertexEx3 """
+ #char bone_ids[3]; // index of joint or -1, if -1, then that weight is
+ # ignored, since subVersion 1
+ #byte weights[3]; // vertex weight ranging from 0 - 100, last weight is
+ # computed by 1.0 - sum(all weights), since subVersion 1
+ #// weight[0] is the weight for bone_id in Ms3dVertex
+ #// weight[1] is the weight for bone_ids[0]
+ #// weight[2] is the weight for bone_ids[1]
+ #// 1.0f - weight[0] - weight[1] - weight[2] is the weight for bone_ids[2]
+ #unsigned int extra; // vertex extra, which can be used as color or
+ # anything else, since subVersion 2
+ __slots__ = (
+ 'extra',
+ '_bone_ids',
+ '_weights',
+ )
+
+ def __init__(
+ self,
+ default_bone_ids=(
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID,
+ Ms3dSpec.DEFAULT_VERTEX_BONE_ID),
+ default_weights=(100, 0, 0),
+ default_extra=0
+ ):
+ self._bone_ids = default_bone_ids
+ self._weights = default_weights
+ self.extra = default_extra
+
+ def __repr__(self):
+ return "\n<bone_ids={}, weights={}, extra={}>".format(
+ self.bone_ids,
+ self.weights,
+ self.extra
+ )
+
+
+ @property
+ def bone_ids(self):
+ return self._bone_ids
+
+ @property
+ def weights(self):
+ return self._weights
+
+
+ @property
+ def weight_bone_id(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights
+ return 100
+
+ @property
+ def weight_bone_id0(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights[0]
+ return 0
+
+ @property
+ def weight_bone_id1(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return self._weights[1]
+ return 0
+
+ @property
+ def weight_bone_id2(self):
+ if self._weights[0] or self._weights[1] or self._weights[2]:
+ return 100 - (self._weights[0] + self._weights[1] \
+ + self._weights[2])
+ return 0
+
+
+ def read(self, file):
+ self._bone_ids = Ms3dIo.read_array(file, Ms3dIo.read_sbyte, 3)
+ self._weights = Ms3dIo.read_array(file, Ms3dIo.read_byte, 3)
+ self.extra = Ms3dIo.read_dword(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_array(file, Ms3dIo.write_sbyte, 3, self.bone_ids)
+ Ms3dIo.write_array(file, Ms3dIo.write_byte, 3, self.weights)
+ Ms3dIo.write_dword(file, self.extra)
+
+
+###############################################################################
+class Ms3dJointEx:
+ """ Ms3dJointEx """
+ __slots__ = (
+ '_color',
+ )
+
+ def __init__(
+ self,
+ default_color=Ms3dSpec.DEFAULT_JOINT_COLOR
+ ):
+ self._color = default_color
+
+ def __repr__(self):
+ return "\n<color=({:.{p}f}, {:.{p}f}, {:.{p}f})>".format(
+ self.color[0],
+ self.color[1],
+ self.color[2],
+ p=Ms3dIo.PRECISION
+ )
+
+
+ @property
+ def color(self):
+ return self._color
+
+
+ def read(self, file):
+ self._color = Ms3dIo.read_array(file, Ms3dIo.read_float, 3)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_array(file, Ms3dIo.write_float, 3, self.color)
+
+
+###############################################################################
+class Ms3dModelEx:
+ """ Ms3dModelEx """
+ __slots__ = (
+ 'joint_size',
+ 'transparency_mode',
+ 'alpha_ref',
+ )
+
+ def __init__(
+ self,
+ default_joint_size=Ms3dSpec.DEFAULT_MODEL_JOINT_SIZE,
+ default_transparency_mode\
+ =Ms3dSpec.DEFAULT_MODEL_TRANSPARENCY_MODE,
+ default_alpha_ref=0.0
+ ):
+ self.joint_size = default_joint_size
+ self.transparency_mode = default_transparency_mode
+ self.alpha_ref = default_alpha_ref
+
+ def __repr__(self):
+ return "\n<joint_size={:.{p}f}, transparency_mode={}, alpha_ref={:.{p}f}>".format(
+ self.joint_size,
+ self.transparency_mode,
+ self.alpha_ref,
+ p=Ms3dIo.PRECISION
+ )
+
+ def read(self, file):
+ self.joint_size = Ms3dIo.read_float(file)
+ self.transparency_mode = Ms3dIo.read_dword(file)
+ self.alpha_ref = Ms3dIo.read_float(file)
+ return self
+
+ def write(self, file):
+ Ms3dIo.write_float(file, self.joint_size)
+ Ms3dIo.write_dword(file, self.transparency_mode)
+ Ms3dIo.write_float(file, self.alpha_ref)
+
+
+###############################################################################
+#
+# file format
+#
+###############################################################################
+class Ms3dModel:
+ """ Ms3dModel """
+ __slot__ = (
+ 'header',
+ 'animation_fps',
+ 'current_time',
+ 'number_total_frames',
+ 'sub_version_comments',
+ 'sub_version_vertex_extra',
+ 'sub_version_joint_extra',
+ 'sub_version_model_extra',
+ 'name',
+ '_vertices',
+ '_triangles',
+ '_groups',
+ '_materials',
+ '_joints',
+ '_has_model_comment',
+ '_comment_object', # Ms3dComment
+ '_model_ex_object', # Ms3dModelEx
+ )
+
+ def __init__(
+ self,
+ default_name=""
+ ):
+ if (default_name is None):
+ default_name = ""
+
+ self.name = default_name
+
+ self.animation_fps = Ms3dSpec.DEFAULT_MODEL_ANIMATION_FPS
+ self.current_time = 0.0
+ self.number_total_frames = 0
+ self.sub_version_comments \
+ = Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_COMMENTS
+ self.sub_version_vertex_extra \
+ = Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_VERTEX_EXTRA
+ self.sub_version_joint_extra \
+ = Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_JOINT_EXTRA
+ self.sub_version_model_extra \
+ = Ms3dSpec.DEFAULT_MODEL_SUB_VERSION_MODEL_EXTRA
+
+ self._vertices = [] #Ms3dVertex()
+ self._triangles = [] #Ms3dTriangle()
+ self._groups = [] #Ms3dGroup()
+ self._materials = [] #Ms3dMaterial()
+ self._joints = [] #Ms3dJoint()
+
+ self.header = Ms3dHeader()
+ self._model_ex_object = Ms3dModelEx()
+ self._comment_object = None #Ms3dComment()
+
+
+ @property
+ def number_vertices(self):
+ if self.vertices is None:
+ return 0
+ return len(self.vertices)
+
+ @property
+ def vertices(self):
+ return self._vertices
+
+
+ @property
+ def number_triangles(self):
+ if self.triangles is None:
+ return 0
+ return len(self.triangles)
+
+ @property
+ def triangles(self):
+ return self._triangles
+
+
+ @property
+ def number_groups(self):
+ if self.groups is None:
+ return 0
+ return len(self.groups)
+
+ @property
+ def groups(self):
+ return self._groups
+
+
+ @property
+ def number_materials(self):
+ if self.materials is None:
+ return 0
+ return len(self.materials)
+
+ @property
+ def materials(self):
+ return self._materials
+
+
+ @property
+ def number_joints(self):
+ if self.joints is None:
+ return 0
+ return len(self.joints)
+
+ @property
+ def joints(self):
+ return self._joints
+
+
+ @property
+ def number_group_comments(self):
+ if self.groups is None:
+ return 0
+ number = 0
+ for item in self.groups:
+ if item.comment_object is not None and item.comment_object.comment:
+ number += 1
+ return number
+
+ @property
+ def group_comments(self):
+ if self.groups is None:
+ return None
+ items = []
+ for item in self.groups:
+ if item.comment_object is not None and item.comment_object.comment:
+ items.append(item)
+ return items
+
+
+ @property
+ def number_material_comments(self):
+ if self.materials is None:
+ return 0
+ number = 0
+ for item in self.materials:
+ if item.comment_object is not None and item.comment_object.comment:
+ number += 1
+ return number
+
+ @property
+ def material_comments(self):
+ if self.materials is None:
+ return None
+ items = []
+ for item in self.materials:
+ if item.comment_object is not None and item.comment_object.comment:
+ items.append(item)
+ return items
+
+
+ @property
+ def number_joint_comments(self):
+ if self.joints is None:
+ return 0
+ number = 0
+ for item in self.joints:
+ if item.comment_object is not None and item.comment_object.comment:
+ number += 1
+ return number
+
+ @property
+ def joint_comments(self):
+ if self.joints is None:
+ return None
+ items = []
+ for item in self.joints:
+ if item.comment_object is not None and item.comment_object.comment:
+ items.append(item)
+ return items
+
+
+ @property
+ def has_model_comment(self):
+ if self.comment_object is not None and self.comment_object.comment:
+ return 1
+ return 0
+
+ @property
+ def comment_object(self):
+ return self._comment_object
+
+
+ @property
+ def vertex_ex(self):
+ if not self.sub_version_vertex_extra:
+ return None
+ return [item.vertex_ex_object for item in self.vertices]
+
+ @property
+ def joint_ex(self):
+ if not self.sub_version_joint_extra:
+ return None
+ return [item.joint_ex_object for item in self.joints]
+
+ @property
+ def model_ex_object(self):
+ if not self.sub_version_model_extra:
+ return None
+ return self._model_ex_object
+
+
+ def print_internal(self):
+ print()
+ print("##############################################################")
+ print("## the internal data of Ms3dModel object...")
+ print("##")
+
+ print("header={}".format(self.header))
+
+ print("number_vertices={}".format(self.number_vertices))
+ print("vertices=[", end="")
+ if self.vertices:
+ for obj in self.vertices:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("number_triangles={}".format(self.number_triangles))
+ print("triangles=[", end="")
+ if self.triangles:
+ for obj in self.triangles:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("number_groups={}".format(self.number_groups))
+ print("groups=[", end="")
+ if self.groups:
+ for obj in self.groups:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("number_materials={}".format(self.number_materials))
+ print("materials=[", end="")
+ if self.materials:
+ for obj in self.materials:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("animation_fps={}".format(self.animation_fps))
+ print("current_time={}".format(self.current_time))
+ print("number_total_frames={}".format(self.number_total_frames))
+
+ print("number_joints={}".format(self.number_joints))
+ print("joints=[", end="")
+ if self.joints:
+ for obj in self.joints:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("sub_version_comments={}".format(self.sub_version_comments))
+
+ print("number_group_comments={}".format(self.number_group_comments))
+ print("group_comments=[", end="")
+ if self.group_comments:
+ for obj in self.group_comments:
+ print("{}".format(obj.comment_object), end="")
+ print("]")
+
+ print("number_material_comments={}".format(
+ self.number_material_comments))
+ print("material_comments=[", end="")
+ if self.material_comments:
+ for obj in self.material_comments:
+ print("{}".format(obj.comment_object), end="")
+ print("]")
+
+ print("number_joint_comments={}".format(self.number_joint_comments))
+ print("joint_comments=[", end="")
+ if self.joint_comments:
+ for obj in self.joint_comments:
+ print("{}".format(obj.comment_object), end="")
+ print("]")
+
+ print("has_model_comment={}".format(self.has_model_comment))
+ print("model_comment={}".format(self.comment_object))
+
+ print("sub_version_vertex_extra={}".format(
+ self.sub_version_vertex_extra))
+ print("vertex_ex=[", end="")
+ if self.vertex_ex:
+ for obj in self.vertex_ex:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("sub_version_joint_extra={}".format(
+ self.sub_version_joint_extra))
+ print("joint_ex=[", end="")
+ if self.joint_ex:
+ for obj in self.joint_ex:
+ print("{}".format(obj), end="")
+ print("]")
+
+ print("sub_version_model_extra={}".format(
+ self.sub_version_model_extra))
+ print("model_ex={}".format(self.model_ex_object))
+
+ print("##")
+ print("## ...end")
+ print("##############################################################")
+ print()
+
+
+ def read(self, file):
+ """
+ opens, reads and pars MS3D file.
+ add content to blender scene
+ """
+
+ self.header.read(file)
+ if (self.header != Ms3dHeader()):
+ print("\nwarning, invalid file header")
+
+ _number_vertices = Ms3dIo.read_word(file)
+ if (_number_vertices > Ms3dSpec.MAX_VERTICES):
+ print("\nwarning, invalid count: number_vertices: {}".format(
+ _number_vertices))
+ self._vertices = []
+ for i in range(_number_vertices):
+ self.vertices.append(Ms3dVertex().read(file))
+
+ _number_triangles = Ms3dIo.read_word(file)
+ if (_number_triangles > Ms3dSpec.MAX_TRIANGLES):
+ print("\nwarning, invalid count: number_triangles: {}".format(
+ _number_triangles))
+ self._triangles = []
+ for i in range(_number_triangles):
+ self.triangles.append(Ms3dTriangle().read(file))
+
+ _number_groups = Ms3dIo.read_word(file)
+ if (_number_groups > Ms3dSpec.MAX_GROUPS):
+ print("\nwarning, invalid count: number_groups: {}".format(
+ _number_groups))
+ self._groups = []
+ for i in range(_number_groups):
+ self.groups.append(Ms3dGroup().read(file))
+
+ _number_materials = Ms3dIo.read_word(file)
+ if (_number_materials > Ms3dSpec.MAX_MATERIALS):
+ print("\nwarning, invalid count: number_materials: {}".format(
+ _number_materials))
+ self._materials = []
+ for i in range(_number_materials):
+ self.materials.append(Ms3dMaterial().read(file))
+
+ self.animation_fps = Ms3dIo.read_float(file)
+ self.current_time = Ms3dIo.read_float(file)
+ self.number_total_frames = Ms3dIo.read_dword(file)
+
+ _progress = set()
+
+ try:
+ # optional data
+ # doesn't matter if doesn't existing.
+
+ Ms3dIo.raise_on_eof(file)
+
+ _number_joints = Ms3dIo.read_word(file)
+ _progress.add('NUMBER_JOINTS')
+ if (_number_joints > Ms3dSpec.MAX_JOINTS):
+ print("\nwarning, invalid count: number_joints: {}".format(
+ _number_joints))
+ self._joints = []
+ for i in range(_number_joints):
+ self.joints.append(Ms3dJoint().read(file))
+ _progress.add('JOINTS')
+
+ Ms3dIo.raise_on_eof(file)
+
+ self.sub_version_comments = Ms3dIo.read_dword(file)
+ _progress.add('SUB_VERSION_COMMENTS')
+ _number_group_comments = Ms3dIo.read_dword(file)
+ _progress.add('NUMBER_GROUP_COMMENTS')
+ if (_number_group_comments > Ms3dSpec.MAX_GROUPS):
+ print("\nwarning, invalid count:"\
+ " number_group_comments: {}".format(
+ _number_group_comments))
+ if _number_group_comments > _number_groups:
+ print("\nwarning, invalid count:"\
+ " number_group_comments: {}, number_groups: {}".format(
+ _number_group_comments, _number_groups))
+ for i in range(_number_group_comments):
+ item = Ms3dCommentEx().read(file)
+ if item.index >= 0 and item.index < _number_groups:
+ self.groups[item.index]._comment_object = item
+ else:
+ print("\nwarning, invalid index:"\
+ " group_index: {}, number_groups: {}".format(
+ item.index, _number_groups))
+ _progress.add('GROUP_COMMENTS')
+
+ _number_material_comments = Ms3dIo.read_dword(file)
+ _progress.add('NUMBER_MATERIAL_COMMENTS')
+ if (_number_material_comments > Ms3dSpec.MAX_MATERIALS):
+ print("\nwarning, invalid count:"\
+ " number_material_comments: {}".format(
+ _number_material_comments))
+ if _number_material_comments > _number_materials:
+ print("\nwarning, invalid count:"\
+ " number_material_comments:"\
+ " {}, number_materials: {}".format(
+ _number_material_comments, _number_materials))
+ for i in range(_number_material_comments):
+ item = Ms3dCommentEx().read(file)
+ if item.index >= 0 and item.index < _number_materials:
+ self.materials[item.index]._comment_object = item
+ else:
+ print("\nwarning, invalid index:"\
+ " material_index: {}, number_materials:"\
+ " {}".format(item.index, _number_materials))
+ _progress.add('MATERIAL_COMMENTS')
+
+ _number_joint_comments = Ms3dIo.read_dword(file)
+ _progress.add('NUMBER_JOINT_COMMENTS')
+ if (_number_joint_comments > Ms3dSpec.MAX_JOINTS):
+ print("\nwarning, invalid count:"\
+ " number_joint_comments: {}".format(
+ _number_joint_comments))
+ if _number_joint_comments > _number_joints:
+ print("\nwarning, invalid count:"\
+ " number_joint_comments: {}, number_joints: {}".format(
+ _number_joint_comments, _number_joints))
+ for i in range(_number_joint_comments):
+ item = Ms3dCommentEx().read(file)
+ if item.index >= 0 and item.index < _number_joints:
+ self.joints[item.index]._comment_object = item
+ else:
+ print("\nwarning, invalid index:"\
+ " joint_index: {}, number_joints: {}".format(
+ item.index, _number_joints))
+ _progress.add('JOINT_COMMENTS')
+
+ _has_model_comment = Ms3dIo.read_dword(file)
+ _progress.add('HAS_MODEL_COMMENTS')
+ if (_has_model_comment != 0):
+ self._comment_object = Ms3dComment().read(file)
+ else:
+ self._comment_object = None
+ _progress.add('MODEL_COMMENTS')
+
+ Ms3dIo.raise_on_eof(file)
+
+ self.sub_version_vertex_extra = Ms3dIo.read_dword(file)
+ _progress.add('SUB_VERSION_VERTEX_EXTRA')
+ if self.sub_version_vertex_extra > 0:
+ length = len(self.joints)
+ for i in range(_number_vertices):
+ if self.sub_version_vertex_extra == 1:
+ item = Ms3dVertexEx1()
+ elif self.sub_version_vertex_extra == 2:
+ item = Ms3dVertexEx2()
+ elif self.sub_version_vertex_extra == 3:
+ item = Ms3dVertexEx3()
+ else:
+ print("\nwarning, invalid version:"\
+ " sub_version_vertex_extra: {}".format(
+ sub_version_vertex_extra))
+ continue
+ self.vertices[i]._vertex_ex_object = item.read(file)
+ _progress.add('VERTEX_EXTRA')
+
+ Ms3dIo.raise_on_eof(file)
+
+ self.sub_version_joint_extra = Ms3dIo.read_dword(file)
+ _progress.add('SUB_VERSION_JOINT_EXTRA')
+ if self.sub_version_joint_extra > 0:
+ for i in range(_number_joints):
+ self.joints[i]._joint_ex_object = Ms3dJointEx().read(file)
+ _progress.add('JOINT_EXTRA')
+
+ Ms3dIo.raise_on_eof(file)
+
+ self.sub_version_model_extra = Ms3dIo.read_dword(file)
+ _progress.add('SUB_VERSION_MODEL_EXTRA')
+ if self.sub_version_model_extra > 0:
+ self._model_ex_object.read(file)
+ _progress.add('MODEL_EXTRA')
+
+ except EOF:
+ # reached end of optional data.
+ print("Ms3dModel.read - optional data read: {}".format(_progress))
+ pass
+
+ except Exception:
+ type, value, traceback = exc_info()
+ print("Ms3dModel.read - exception in optional try block,"
+ " _progress={0}\n type: '{1}'\n value: '{2}'".format(
+ _progress, type, value, traceback))
+
+ else:
+ pass
+
+ # try best to continue far as possible
+ if not 'JOINTS' in _progress:
+ _number_joints = 0
+ self._joints = []
+
+ if not 'GROUP_COMMENTS' in _progress:
+ self.sub_version_comments = 0
+ _number_group_comments = 0
+
+ if not 'MATERIAL_COMMENTS' in _progress:
+ _number_material_comments = 0
+
+ if not 'JOINT_COMMENTS' in _progress:
+ _number_joint_comments = 0
+
+ if not 'MODEL_COMMENTS' in _progress:
+ _has_model_comment = 0
+ self._comment_object = None # Ms3dComment()
+
+ if not 'VERTEX_EXTRA' in _progress:
+ self.sub_version_vertex_extra = 0
+
+ if not 'JOINT_EXTRA' in _progress:
+ self.sub_version_joint_extra = 0
+
+ if not 'MODEL_EXTRA' in _progress:
+ self.sub_version_model_extra = 0
+ self._model_ex_object = Ms3dModelEx()
+
+ return
+
+
+ def write(self, file):
+ """
+ add blender scene content to MS3D
+ creates, writes MS3D file.
+ """
+
+ self.header.write(file)
+
+ Ms3dIo.write_word(file, self.number_vertices)
+ for i in range(self.number_vertices):
+ self.vertices[i].write(file)
+
+ Ms3dIo.write_word(file, self.number_triangles)
+ for i in range(self.number_triangles):
+ self.triangles[i].write(file)
+
+ Ms3dIo.write_word(file, self.number_groups)
+ for i in range(self.number_groups):
+ self.groups[i].write(file)
+
+ Ms3dIo.write_word(file, self.number_materials)
+ for i in range(self.number_materials):
+ self.materials[i].write(file)
+
+ Ms3dIo.write_float(file, self.animation_fps)
+ Ms3dIo.write_float(file, self.current_time)
+ Ms3dIo.write_dword(file, self.number_total_frames)
+
+ try:
+ # optional part
+ # doesn't matter if it doesn't complete.
+ Ms3dIo.write_word(file, self.number_joints)
+ for i in range(self.number_joints):
+ self.joints[i].write(file)
+
+ Ms3dIo.write_dword(file, self.sub_version_comments)
+
+ Ms3dIo.write_dword(file, self.number_group_comments)
+ for i in range(self.number_group_comments):
+ self.group_comments[i].comment_object.write(file)
+
+ Ms3dIo.write_dword(file, self.number_material_comments)
+ for i in range(self.number_material_comments):
+ self.material_comments[i].comment_object.write(file)
+
+ Ms3dIo.write_dword(file, self.number_joint_comments)
+ for i in range(self.number_joint_comments):
+ self.joint_comments[i].comment_object.write(file)
+
+ Ms3dIo.write_dword(file, self.has_model_comment)
+ if (self.has_model_comment != 0):
+ self.comment_object.write(file)
+
+ Ms3dIo.write_dword(file, self.sub_version_vertex_extra)
+ if (self.sub_version_vertex_extra in {1, 2, 3}):
+ for i in range(self.number_vertices):
+ self.vertex_ex[i].write(file)
+
+ Ms3dIo.write_dword(file, self.sub_version_joint_extra)
+ for i in range(self.number_joints):
+ self.joint_ex[i].write(file)
+
+ Ms3dIo.write_dword(file, self.sub_version_model_extra)
+ self.model_ex_object.write(file)
+
+ except Exception:
+ type, value, traceback = exc_info()
+ print("Ms3dModel.write - exception in optional try block"
+ "\n type: '{0}'\n value: '{1}'".format(
+ type, value, traceback))
+ pass
+
+ else:
+ pass
+
+ return
+
+
+ def is_valid(self):
+ valid = True
+ result = []
+
+ format1 = "\n number of {0}: {1}"
+ format2 = " limit exceeded! (limit is {0})"
+
+ result.append("MS3D statistics:")
+ result.append(format1.format("vertices ........",
+ self.number_vertices))
+ if (self.number_vertices > Ms3dSpec.MAX_VERTICES):
+ result.append(format2.format(Ms3dSpec.MAX_VERTICES))
+ valid &= False
+
+ result.append(format1.format("triangles .......",
+ self.number_triangles))
+ if (self.number_triangles > Ms3dSpec.MAX_TRIANGLES):
+ result.append(format2.format(Ms3dSpec.MAX_TRIANGLES))
+ valid &= False
+
+ result.append(format1.format("groups ..........",
+ self.number_groups))
+ if (self.number_groups > Ms3dSpec.MAX_GROUPS):
+ result.append(format2.format(Ms3dSpec.MAX_GROUPS))
+ valid &= False
+
+ result.append(format1.format("materials .......",
+ self.number_materials))
+ if (self.number_materials > Ms3dSpec.MAX_MATERIALS):
+ result.append(format2.format(Ms3dSpec.MAX_MATERIALS))
+ valid &= False
+
+ result.append(format1.format("joints ..........",
+ self.number_joints))
+ if (self.number_joints > Ms3dSpec.MAX_JOINTS):
+ result.append(format2.format(Ms3dSpec.MAX_JOINTS))
+ valid &= False
+
+ result.append(format1.format("model comments ..",
+ self.has_model_comment))
+ result.append(format1.format("group comments ..",
+ self.number_group_comments))
+ result.append(format1.format("material comments",
+ self.number_material_comments))
+ result.append(format1.format("joint comments ..",
+ self.number_joint_comments))
+
+ #if (not valid):
+ # result.append("\n\nthe data may be corrupted.")
+
+ return (valid, ("".join(result)))
+
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_strings.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_strings.py
new file mode 100644
index 0000000..84a5a56
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_strings.py
@@ -0,0 +1,263 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+SEE_MS3D_DOC = "see MilkShape 3D documentation"
+
+ms3d_str = {
+ 'lang': "en-US",
+ 'RUNTIME_KEY': "Human friendly presentation",
+
+ ###############################
+ # blender key names
+ 'OBJECT_LAYER_EXTRA': "ms3d_extra_layer",
+ 'OBJECT_LAYER_GROUP': "ms3d_group_layer",
+ 'OBJECT_LAYER_SMOOTHING_GROUP': "ms3d_smoothing_group_layer",
+ 'OBJECT_MODIFIER_SMOOTHING_GROUP': "ms3d_smoothing_groups",
+ # for some reason after bm.to_mesh(..)
+ # the names of 'bm.loops.layers.uv' becomes to 'bm.faces.layers.tex'
+ # to bypass this issue, i give both the same name.
+ # 'OBJECT_LAYER_TEXTURE': "ms3d_texture_layer",
+ 'OBJECT_LAYER_TEXTURE': "ms3d_uv_layer",
+ 'OBJECT_LAYER_UV': "ms3d_uv_layer",
+
+ ###############################
+ # strings to be used with 'str().format()'
+ 'STRING_FORMAT_GROUP': "Group.{:03d}",
+ 'WARNING_IMPORT_SKIP_FACE_DOUBLE': "skipped face #{}:"\
+ " contains double faces with same vertices!",
+ 'WARNING_IMPORT_SKIP_LESS_VERTICES': "skipped face #{}:"\
+ " contains faces too less vertices!",
+ 'WARNING_IMPORT_SKIP_VERTEX_DOUBLE': "skipped face #{}:"\
+ " contains faces with double vertices!",
+ 'WARNING_IMPORT_EXTRA_VERTEX_NORMAL': "created extra vertex"\
+ " because of different normals #{} -> {}.",
+ 'SUMMARY_IMPORT': "elapsed time: {0:.4}s (media io:"\
+ " ~{1:.4}s, converter: ~{2:.4}s)",
+ 'SUMMARY_EXPORT': "elapsed time: {0:.4}s (converter:"\
+ " ~{1:.4}s, media io: ~{2:.4}s)",
+ 'WARNING_EXPORT_SKIP_WEIGHT' : "skipped weight",
+ 'WARNING_EXPORT_SKIP_WEIGHT_EX' : "skipped weight:"\
+ " limit exceeded",
+
+ ###############################
+ 'TEXT_OPERATOR': "MilkShape 3D (.ms3d)",
+ 'FILE_EXT': ".ms3d",
+ 'FILE_FILTER': "*.ms3d",
+ 'BL_DESCRIPTION_EXPORTER': "Export to a MilkShape 3D file format (.ms3d)",
+ 'BL_DESCRIPTION_IMPORTER': "Import from a MilkShape 3D file format (.ms3d)",
+ 'BL_LABEL_EXPORTER': "Export MS3D",
+ 'BL_LABEL_GROUP_OPERATOR': "MS3D - Group Collection Operator",
+ 'BL_LABEL_IMPORTER': "Import MS3D",
+ 'BL_LABEL_PANEL_SMOOTHING_GROUP': "MS3D - Smoothing Group",
+ 'BL_LABEL_SMOOTHING_GROUP_OPERATOR': "MS3D Set Smoothing Group"\
+ " Operator",
+ 'BL_LABEL_MATERIAL_OPERATOR' : "MS3D - Copy Material Operator",
+ 'ENUM_ADD_GROUP_1': "Add",
+ 'ENUM_ADD_GROUP_2': "adds an item",
+ 'ENUM_ASSIGN_1': "Assign",
+ 'ENUM_ASSIGN_2_GROUP': "assign selected faces to selected group",
+ 'ENUM_ASSIGN_2_SMOOTHING_GROUP': "assign all selected faces to"\
+ " selected smoothing group",
+ 'ENUM_DESELECT_1': "Deselect",
+ 'ENUM_DESELECT_2_GROUP': "deselects faces of selected group",
+ 'ENUM_DESELECT_2_SMOOTHING_GROUP': "deselects all faces of selected"\
+ " smoothing group",
+ 'ENUM_FLAG_DIRTY_1': "Dirty",
+ 'ENUM_FLAG_DIRTY_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_HIDDEN_1': "Hidden",
+ 'ENUM_FLAG_HIDDEN_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_ISKEY_1': "Is Key",
+ 'ENUM_FLAG_ISKEY_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_MARKED_1': "Marked",
+ 'ENUM_FLAG_MARKED_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_NEWLYCREATED_1': "Newly Created",
+ 'ENUM_FLAG_NEWLYCREATED_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_NONE_1': "None",
+ 'ENUM_FLAG_NONE_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_SELECTED_1': "Selected",
+ 'ENUM_FLAG_SELECTED_2': SEE_MS3D_DOC,
+ 'ENUM_FLAG_SELECTED2_1': "Selected Ex.",
+ 'ENUM_FLAG_SELECTED2_2': SEE_MS3D_DOC,
+ 'ENUM_REMOVE_1': "Remove",
+ 'ENUM_REMOVE_2_GROUP': "remove selected faces from selected group",
+ 'ENUM_REMOVE_GROUP_1': "Remove",
+ 'ENUM_REMOVE_GROUP_2': "removes an item",
+ 'ENUM_SELECT_1': "Select",
+ 'ENUM_SELECT_2_GROUP': "selects faces of selected group",
+ 'ENUM_SELECT_2_SMOOTHING_GROUP': "selects all faces of selected"\
+ " smoothing group",
+ 'LABEL_NAME_ANIMATION': "Animation Processing:",
+ 'LABEL_NAME_OBJECT': "World Processing:",
+ 'LABEL_NAME_OPTIONS': "Advanced Options:",
+ 'LABEL_NAME_PROCESSING': "Object Processing:",
+ 'LABEL_NAME_MODIFIER': "Modifier Processing:",
+ 'LABEL_PANEL_BUTTON_NONE': "None",
+ 'LABEL_PANEL_GROUPS': "MS3D - Groups",
+ 'LABEL_PANEL_JOINTS': "MS3D - Joint",
+ 'LABEL_PANEL_MATERIALS': "MS3D - Material",
+ 'LABEL_PANEL_MODEL': "MS3D - Model",
+ 'PROP_DESC_ALPHA_REF': "ms3d internal raw 'alpha_ref' of Model",
+ 'PROP_DESC_ALPHAMAP': "ms3d internal raw 'alphamap' file name of"\
+ " Material",
+ 'PROP_DESC_AMBIENT': "ms3d internal raw 'ambient' of Material",
+ 'PROP_DESC_USE_ANIMATION': "keyframes (rotations, positions)",
+ 'PROP_DESC_COLOR_JOINT': "ms3d internal raw 'color' of Joint",
+ 'PROP_DESC_COMMENT_GROUP': "ms3d internal raw 'comment' of Group",
+ 'PROP_DESC_COMMENT_JOINT': "ms3d internal raw 'comment' of Joint",
+ 'PROP_DESC_COMMENT_MATERIAL': "ms3d internal raw 'comment' of Material",
+ 'PROP_DESC_COMMENT_MODEL': "ms3d internal raw 'comment' of Model",
+ 'PROP_DESC_DIFFUSE': "ms3d internal raw 'diffuse' of Material",
+ 'PROP_DESC_EMISSIVE': "ms3d internal raw 'emissive' of Material",
+ 'PROP_DESC_FLAGS_GROUP': "ms3d internal raw 'flags' of Group",
+ 'PROP_DESC_FLAGS_JOINT': "ms3d internal raw 'flags' of Joint",
+ 'PROP_DESC_GROUP_NAME': "ms3d internal raw 'name' of Group",
+ 'PROP_DESC_JOINT_SIZE': "ms3d internal raw 'joint_size' of Model",
+ 'PROP_DESC_MODE_TEXTURE': "ms3d internal raw 'mode' of Material",
+ 'PROP_DESC_NAME_ARMATURE': "ms3d internal raw 'name' of Model (not used"\
+ " for export)",
+ 'PROP_DESC_NAME_JOINT': "ms3d internal raw 'name' of Joint",
+ 'PROP_DESC_NAME_MATERIAL': "ms3d internal raw 'name' of Material",
+ 'PROP_DESC_NAME_MODEL': "ms3d internal raw 'name' of Model (not used for export)",
+ 'PROP_DESC_SHININESS': "ms3d internal raw 'shininess' of Material",
+ 'PROP_DESC_SPECULAR': "ms3d internal raw 'specular' of Material",
+ 'PROP_DESC_TEXTURE': "ms3d internal raw 'texture' file name of"\
+ " Material",
+ 'PROP_DESC_TRANSPARENCY': "ms3d internal raw 'transparency' of"\
+ " Material",
+ 'PROP_DESC_TRANSPARENCY_MODE': "ms3d internal raw 'transparency_mode'"\
+ " of Model",
+ 'PROP_DESC_VERBOSE': "Run the converter in debug mode."\
+ " Check the console for output (Warning, may be very slow)",
+ 'PROP_FLAG_TEXTURE_COMBINE_ALPHA_1': "Combine Alpha",
+ 'PROP_FLAG_TEXTURE_COMBINE_ALPHA_2': SEE_MS3D_DOC,
+ 'PROP_FLAG_TEXTURE_HAS_ALPHA_1': "Has Alpha",
+ 'PROP_FLAG_TEXTURE_HAS_ALPHA_2': SEE_MS3D_DOC,
+ 'PROP_FLAG_TEXTURE_SPHERE_MAP_1': "Sphere Map",
+ 'PROP_FLAG_TEXTURE_SPHERE_MAP_2': SEE_MS3D_DOC,
+ 'PROP_MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF_1': "Depth"\
+ " Buffered with Alpha Ref",
+ 'PROP_MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF_2': SEE_MS3D_DOC,
+ 'PROP_MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES_1': "Depth Sorted"\
+ " Triangles",
+ 'PROP_MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES_2': SEE_MS3D_DOC,
+ 'PROP_MODE_TRANSPARENCY_SIMPLE_1': "Simple",
+ 'PROP_MODE_TRANSPARENCY_SIMPLE_2': SEE_MS3D_DOC,
+ 'PROP_NAME_ALPHA_REF': "Alpha Ref.",
+ 'PROP_NAME_ALPHAMAP': "Alphamap",
+ 'PROP_NAME_AMBIENT': "Ambient",
+ 'PROP_NAME_USE_ANIMATION': "Animation",
+ 'PROP_NAME_COLOR': "Color",
+ 'PROP_NAME_COMMENT': "Comment",
+ 'PROP_NAME_DIFFUSE': "Diffuse",
+ 'PROP_NAME_EMISSIVE': "Emissive",
+ 'PROP_NAME_FLAGS': "Flags",
+ 'PROP_NAME_JOINT_SIZE': "Joint Size",
+ 'PROP_NAME_MODE': "Mode",
+ 'PROP_NAME_NAME': "Name",
+ 'PROP_NAME_ACTIVE': "Active Mesh:",
+ 'PROP_NAME_SHININESS': "Shininess",
+ 'PROP_NAME_SPECULAR': "Specular",
+ 'PROP_NAME_TEXTURE': "Texture",
+ 'PROP_NAME_TRANSPARENCY': "Transparency",
+ 'PROP_NAME_TRANSPARENCY_MODE': "Transp. Mode",
+ 'PROP_NAME_VERBOSE': "Verbose",
+ 'PROP_SMOOTHING_GROUP_INDEX': "Smoothing group id",
+ 'PROP_NAME_ROTATION_MODE' : "Bone Rotation Mode",
+ 'PROP_DESC_ROTATION_MODE' : "set the preferred rotation mode of bones",
+ 'PROP_ITEM_ROTATION_MODE_EULER_1' : "Euler",
+ 'PROP_ITEM_ROTATION_MODE_EULER_2' : "use euler bone rotation"\
+ " (gimbal-lock can be fixed by using "\
+ "'Graph Editor -> Key -> Discontinuity (Euler) Filter')",
+ 'PROP_ITEM_ROTATION_MODE_QUATERNION_1' : "Quaternion",
+ 'PROP_ITEM_ROTATION_MODE_QUATERNION_2' : "use quaternion bone rotation"\
+ " (no gimbal-lock filter available!)",
+ 'PROP_NAME_USE_JOINT_SIZE': "Override Joint Size",
+ 'PROP_DESC_USE_JOINT_SIZE': "use value of 'Joint Size', the value of the"\
+ " ms3d file is ignored for representation.",
+ 'PROP_NAME_IMPORT_JOINT_SIZE': "Joint Size",
+ 'PROP_DESC_IMPORT_JOINT_SIZE': "size of the joint representation in"\
+ " blender",
+ 'BL_LABEL_SET_SCENE_TO_METRIC' : "Set Scene to 'Metric' [1 mm]",
+ 'BL_DESC_SET_SCENE_TO_METRIC' : "set Scene | Units to Metric"\
+ " (1 Unit = 1 mm),"\
+ " Display | Textured Solid,"\
+ " View | Clip (0.001 mm ... 1 km)",
+ 'PROP_NAME_NORMALIZE_WEIGHTS' : "Normalize Weights",
+ 'PROP_DESC_NORMALIZE_WEIGHTS' : "normalize weights to 100%,"\
+ " when its sum of weights is greater than 100%",
+ 'PROP_NAME_SHRINK_TO_KEYS' : "Shrink To Keys",
+ 'PROP_DESC_SHRINK_TO_KEYS' : "shrinks the animation to region from"\
+ " first keyframe to last keyframe",
+ 'PROP_NAME_BAKE_EACH_FRAME' : "Bake Each Frame As Key",
+ 'PROP_DESC_BAKE_EACH_FRAME' : "if enabled, to each frame there will be"\
+ " a key baked",
+ 'LABEL_NAME_JOINT_TO_BONES' : "works only with some models!",
+ 'PROP_NAME_JOINT_TO_BONES' : "Joints To Bones",
+ 'PROP_DESC_JOINT_TO_BONES' : "changes the length of the bones",
+ 'PROP_NAME_USE_BLENDER_NAMES' : "Use Blender Names Only",
+ 'PROP_DESC_USE_BLENDER_NAMES' : "use only blender names, ignores ms3d"\
+ " names (bone names will always be taken from blender)",
+ 'PROP_NAME_USE_BLENDER_MATERIALS' : "Use Blender Materials",
+ 'PROP_DESC_USE_BLENDER_MATERIALS' : "ignores ms3d material definition"\
+ " (you loose some information by choosing this option)",
+ 'ENUM_FROM_BLENDER_1' : "Copy From Blender",
+ 'ENUM_FROM_BLENDER_2' : "takes and copies all available values from"\
+ " blender",
+ 'ENUM_TO_BLENDER_1' : "Copy To Blender",
+ 'ENUM_TO_BLENDER_2' : "copies and puts all available values to blender",
+ 'PROP_NAME_EXTENDED_NORMAL_HANDLING': "Extended Normal Handling",
+ 'PROP_DESC_EXTENDED_NORMAL_HANDLING': "adds extra vertices if normals"\
+ " are different",
+ 'PROP_NAME_APPLY_TRANSFORM': "Apply Transform",
+ 'PROP_DESC_APPLY_TRANSFORM': "applies location, rotation and scale on"\
+ " export",
+ 'PROP_NAME_APPLY_MODIFIERS': "Apply Modifiers",
+ 'PROP_DESC_APPLY_MODIFIERS': "applies modifiers on export that are"\
+ " enabled (except of armature modifiers)",
+ 'PROP_NAME_APPLY_MODIFIERS_MODE': "Apply Mode",
+ 'PROP_DESC_APPLY_MODIFIERS_MODE': "apply modifier, if enabled in its"\
+ " mode",
+ 'PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW_1': "View",
+ 'PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW_2': "apply modifiers that are"\
+ " enabled in viewport",
+ 'PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER_1': "Render",
+ 'PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER_2': "apply modifiers that are"\
+ " enabled in renderer",
+
+ 'PROP_NAME_': "Name",
+ 'PROP_DESC_': "Description",
+ # ms3d_str['']
+ }
+
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_ui.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_ui.py
new file mode 100644
index 0000000..b3ed9db
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_ui.py
@@ -0,0 +1,1678 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+
+
+#import python stuff
+from random import (
+ randrange,
+ )
+
+
+# import io_scene_ms3d stuff
+from io_scene_ms3d.ms3d_strings import (
+ ms3d_str,
+ )
+from io_scene_ms3d.ms3d_spec import (
+ Ms3dSpec,
+ )
+from io_scene_ms3d.ms3d_utils import (
+ enable_edit_mode,
+ get_edge_split_modifier_add_if,
+ set_sence_to_metric,
+ )
+
+
+#import blender stuff
+from bmesh import (
+ from_edit_mesh,
+ )
+from bpy.utils import (
+ register_class,
+ unregister_class,
+ )
+from bpy_extras.io_utils import (
+ ExportHelper,
+ ImportHelper,
+ )
+from bpy.props import (
+ BoolProperty,
+ CollectionProperty,
+ EnumProperty,
+ FloatProperty,
+ FloatVectorProperty,
+ IntProperty,
+ StringProperty,
+ PointerProperty,
+ )
+from bpy.types import (
+ Operator,
+ PropertyGroup,
+ Panel,
+ Armature,
+ Bone,
+ Mesh,
+ Material,
+ Action,
+ Group,
+ )
+from bpy.app import (
+ debug,
+ )
+
+
+class Ms3dUi:
+ DEFAULT_VERBOSE = debug
+
+ ###########################################################################
+ FLAG_TEXTURE_COMBINE_ALPHA = 'COMBINE_ALPHA'
+ FLAG_TEXTURE_HAS_ALPHA = 'HAS_ALPHA'
+ FLAG_TEXTURE_SPHERE_MAP = 'SPHERE_MAP'
+
+ @staticmethod
+ def texture_mode_from_ms3d(ms3d_value):
+ ui_value = set()
+ if (ms3d_value & Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA) \
+ == Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA:
+ ui_value.add(Ms3dUi.FLAG_TEXTURE_COMBINE_ALPHA)
+ if (ms3d_value & Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA) \
+ == Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA:
+ ui_value.add(Ms3dUi.FLAG_TEXTURE_HAS_ALPHA)
+ if (ms3d_value & Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP) \
+ == Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP:
+ ui_value.add(Ms3dUi.FLAG_TEXTURE_SPHERE_MAP)
+ return ui_value
+
+ @staticmethod
+ def texture_mode_to_ms3d(ui_value):
+ ms3d_value = Ms3dSpec.FLAG_TEXTURE_NONE
+
+ if Ms3dUi.FLAG_TEXTURE_COMBINE_ALPHA in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA
+ if Ms3dUi.FLAG_TEXTURE_HAS_ALPHA in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA
+ if Ms3dUi.FLAG_TEXTURE_SPHERE_MAP in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP
+ return ms3d_value
+
+
+ MODE_TRANSPARENCY_SIMPLE = 'SIMPLE'
+ MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF \
+ = 'DEPTH_BUFFERED_WITH_ALPHA_REF'
+ MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES = 'DEPTH_SORTED_TRIANGLES'
+
+ @staticmethod
+ def transparency_mode_from_ms3d(ms3d_value):
+ if(ms3d_value == Ms3dSpec.MODE_TRANSPARENCY_SIMPLE):
+ return Ms3dUi.MODE_TRANSPARENCY_SIMPLE
+ elif(ms3d_value == \
+ Ms3dSpec.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF):
+ return Ms3dUi.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF
+ elif(ms3d_value == Ms3dSpec.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES):
+ return Ms3dUi.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES
+ return None
+
+ @staticmethod
+ def transparency_mode_to_ms3d(ui_value):
+ if(ui_value == Ms3dUi.MODE_TRANSPARENCY_SIMPLE):
+ return Ms3dSpec.MODE_TRANSPARENCY_SIMPLE
+ elif(ui_value == Ms3dUi.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF):
+ return Ms3dSpec.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF
+ elif(ui_value == Ms3dUi.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES):
+ return Ms3dSpec.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES
+ return None
+
+
+ FLAG_NONE = 'NONE'
+ FLAG_SELECTED = 'SELECTED'
+ FLAG_HIDDEN = 'HIDDEN'
+ FLAG_SELECTED2 = 'SELECTED2'
+ FLAG_DIRTY = 'DIRTY'
+ FLAG_ISKEY = 'ISKEY'
+ FLAG_NEWLYCREATED = 'NEWLYCREATED'
+ FLAG_MARKED = 'MARKED'
+
+ @staticmethod
+ def flags_from_ms3d(ms3d_value):
+ ui_value = set()
+ if (ms3d_value & Ms3dSpec.FLAG_SELECTED) == Ms3dSpec.FLAG_SELECTED:
+ ui_value.add(Ms3dUi.FLAG_SELECTED)
+ if (ms3d_value & Ms3dSpec.FLAG_HIDDEN) == Ms3dSpec.FLAG_HIDDEN:
+ ui_value.add(Ms3dUi.FLAG_HIDDEN)
+ if (ms3d_value & Ms3dSpec.FLAG_SELECTED2) == Ms3dSpec.FLAG_SELECTED2:
+ ui_value.add(Ms3dUi.FLAG_SELECTED2)
+ if (ms3d_value & Ms3dSpec.FLAG_DIRTY) == Ms3dSpec.FLAG_DIRTY:
+ ui_value.add(Ms3dUi.FLAG_DIRTY)
+ if (ms3d_value & Ms3dSpec.FLAG_ISKEY) == Ms3dSpec.FLAG_ISKEY:
+ ui_value.add(Ms3dUi.FLAG_ISKEY)
+ if (ms3d_value & Ms3dSpec.FLAG_NEWLYCREATED) == \
+ Ms3dSpec.FLAG_NEWLYCREATED:
+ ui_value.add(Ms3dUi.FLAG_NEWLYCREATED)
+ if (ms3d_value & Ms3dSpec.FLAG_MARKED) == Ms3dSpec.FLAG_MARKED:
+ ui_value.add(Ms3dUi.FLAG_MARKED)
+ return ui_value
+
+ @staticmethod
+ def flags_to_ms3d(ui_value):
+ ms3d_value = Ms3dSpec.FLAG_NONE
+ if Ms3dUi.FLAG_SELECTED in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_SELECTED
+ if Ms3dUi.FLAG_HIDDEN in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_HIDDEN
+ if Ms3dUi.FLAG_SELECTED2 in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_SELECTED2
+ if Ms3dUi.FLAG_DIRTY in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_DIRTY
+ if Ms3dUi.FLAG_ISKEY in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_ISKEY
+ if Ms3dUi.FLAG_NEWLYCREATED in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_NEWLYCREATED
+ if Ms3dUi.FLAG_MARKED in ui_value:
+ ms3d_value |= Ms3dSpec.FLAG_MARKED
+ return ms3d_value
+
+ ###########################################################################
+ ICON_OPTIONS = 'LAMP'
+ ICON_OBJECT = 'WORLD'
+ ICON_PROCESSING = 'OBJECT_DATAMODE'
+ ICON_MODIFIER = 'MODIFIER'
+ ICON_ANIMATION = 'RENDER_ANIMATION'
+ ICON_ROTATION_MODE = 'BONE_DATA'
+ ICON_ERROR = 'ERROR'
+
+ ###########################################################################
+ PROP_DEFAULT_VERBOSE = DEFAULT_VERBOSE
+
+ ###########################################################################
+ PROP_DEFAULT_USE_JOINT_SIZE = False
+ PROP_DEFAULT_JOINT_SIZE = 0.01
+ PROP_JOINT_SIZE_MIN = 0.01
+ PROP_JOINT_SIZE_MAX = 10.0
+ PROP_JOINT_SIZE_STEP = 0.1
+ PROP_JOINT_SIZE_PRECISION = 2
+
+ ###########################################################################
+ PROP_DEFAULT_USE_ANIMATION = True
+ PROP_DEFAULT_NORMALIZE_WEIGHTS = True
+ PROP_DEFAULT_SHRINK_TO_KEYS = False
+ PROP_DEFAULT_BAKE_EACH_FRAME = True
+ PROP_DEFAULT_JOINT_TO_BONES = False
+ PROP_DEFAULT_USE_BLENDER_NAMES = True
+ PROP_DEFAULT_USE_BLENDER_MATERIALS = False
+ PROP_DEFAULT_EXTENDED_NORMAL_HANDLING = False
+ PROP_DEFAULT_APPLY_TRANSFORM = True
+ PROP_DEFAULT_APPLY_MODIFIERS = True
+
+ ###########################################################################
+ PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW = 'PREVIEW'
+ PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER = 'RENDER'
+ PROP_DEFAULT_APPLY_MODIFIERS_MODE = PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW
+
+ ###########################################################################
+ PROP_ITEM_ROTATION_MODE_EULER = 'EULER'
+ PROP_ITEM_ROTATION_MODE_QUATERNION = 'QUATERNION'
+ PROP_DEFAULT_ANIMATION_ROTATION = PROP_ITEM_ROTATION_MODE_EULER
+
+ ###########################################################################
+ OPT_SMOOTHING_GROUP_APPLY = 'io_scene_ms3d.apply_smoothing_group'
+ OPT_GROUP_APPLY = 'io_scene_ms3d.apply_group'
+ OPT_MATERIAL_APPLY = 'io_scene_ms3d.apply_material'
+
+
+###############################################################################
+class Ms3dImportOperator(Operator, ImportHelper):
+ """ Load a MilkShape3D MS3D File """
+ bl_idname = 'import_scene.ms3d'
+ bl_label = ms3d_str['BL_LABEL_IMPORTER']
+ bl_description = ms3d_str['BL_DESCRIPTION_IMPORTER']
+ bl_options = {'PRESET', }
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+
+ filename_ext = ms3d_str['FILE_EXT']
+
+ filter_glob = StringProperty(
+ default=ms3d_str['FILE_FILTER'],
+ options={'HIDDEN', }
+ )
+
+ filepath = StringProperty(
+ subtype='FILE_PATH',
+ options={'HIDDEN', }
+ )
+
+ verbose = BoolProperty(
+ name=ms3d_str['PROP_NAME_VERBOSE'],
+ description=ms3d_str['PROP_DESC_VERBOSE'],
+ default=Ms3dUi.PROP_DEFAULT_VERBOSE,
+ )
+
+ use_animation = BoolProperty(
+ name=ms3d_str['PROP_NAME_USE_ANIMATION'],
+ description=ms3d_str['PROP_DESC_USE_ANIMATION'],
+ default=Ms3dUi.PROP_DEFAULT_USE_ANIMATION,
+ )
+
+ rotation_mode = EnumProperty(
+ name=ms3d_str['PROP_NAME_ROTATION_MODE'],
+ description=ms3d_str['PROP_DESC_ROTATION_MODE'],
+ items=( (Ms3dUi.PROP_ITEM_ROTATION_MODE_EULER,
+ ms3d_str['PROP_ITEM_ROTATION_MODE_EULER_1'],
+ ms3d_str['PROP_ITEM_ROTATION_MODE_EULER_2']),
+ (Ms3dUi.PROP_ITEM_ROTATION_MODE_QUATERNION,
+ ms3d_str['PROP_ITEM_ROTATION_MODE_QUATERNION_1'],
+ ms3d_str['PROP_ITEM_ROTATION_MODE_QUATERNION_2']),
+ ),
+ default=Ms3dUi.PROP_DEFAULT_ANIMATION_ROTATION,
+ )
+
+ use_joint_size = BoolProperty(
+ name=ms3d_str['PROP_NAME_USE_JOINT_SIZE'],
+ description=ms3d_str['PROP_DESC_USE_JOINT_SIZE'],
+ default=Ms3dUi.PROP_DEFAULT_USE_JOINT_SIZE,
+ )
+
+ joint_size = FloatProperty(
+ name=ms3d_str['PROP_NAME_IMPORT_JOINT_SIZE'],
+ description=ms3d_str['PROP_DESC_IMPORT_JOINT_SIZE'],
+ min=Ms3dUi.PROP_JOINT_SIZE_MIN, max=Ms3dUi.PROP_JOINT_SIZE_MAX,
+ precision=Ms3dUi.PROP_JOINT_SIZE_PRECISION, \
+ step=Ms3dUi.PROP_JOINT_SIZE_STEP,
+ default=Ms3dUi.PROP_DEFAULT_JOINT_SIZE,
+ subtype='FACTOR',
+ #options={'HIDDEN', },
+ )
+
+ joint_to_bones = BoolProperty(
+ name=ms3d_str['PROP_NAME_JOINT_TO_BONES'],
+ description=ms3d_str['PROP_DESC_JOINT_TO_BONES'],
+ default=Ms3dUi.PROP_DEFAULT_JOINT_TO_BONES,
+ )
+
+ extended_normal_handling = BoolProperty(
+ name=ms3d_str['PROP_NAME_EXTENDED_NORMAL_HANDLING'],
+ description=ms3d_str['PROP_DESC_EXTENDED_NORMAL_HANDLING'],
+ default=Ms3dUi.PROP_DEFAULT_EXTENDED_NORMAL_HANDLING,
+ )
+
+
+ @property
+ def is_rotation_mode_euler(self):
+ return (Ms3dUi.PROP_ITEM_ROTATION_MODE_EULER \
+ in self.rotation_mode)
+
+ @property
+ def is_rotation_mode_quaternion(self):
+ return (Ms3dUi.PROP_ITEM_ROTATION_MODE_QUATERNION \
+ in self.rotation_mode)
+
+
+ # draw the option panel
+ def draw(self, blender_context):
+ layout = self.layout
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_OPTIONS'], icon=Ms3dUi.ICON_OPTIONS)
+ box.prop(self, 'verbose', icon='SPEAKER')
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_PROCESSING'],
+ icon=Ms3dUi.ICON_PROCESSING)
+ box.prop(self, 'extended_normal_handling')
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_ANIMATION'], icon=Ms3dUi.ICON_ANIMATION)
+ box.prop(self, 'use_animation')
+ if (self.use_animation):
+ box.prop(self, 'rotation_mode', icon=Ms3dUi.ICON_ROTATION_MODE,
+ expand=False)
+ box.prop(self, 'use_joint_size')
+ if (self.use_joint_size):
+ col = box.column()
+ row = col.row()
+ row.prop(self, 'joint_size')
+ box.prop(self, 'joint_to_bones')
+ if (self.joint_to_bones):
+ box.box().label(ms3d_str['LABEL_NAME_JOINT_TO_BONES'],
+ icon=Ms3dUi.ICON_ERROR)
+
+ # entrypoint for MS3D -> blender
+ def execute(self, blender_context):
+ """ start executing """
+ from io_scene_ms3d.ms3d_import import (Ms3dImporter, )
+ return Ms3dImporter(self).read(blender_context)
+
+ def invoke(self, blender_context, event):
+ blender_context.window_manager.fileselect_add(self)
+ return {'RUNNING_MODAL', }
+
+ @staticmethod
+ def menu_func(cls, blender_context):
+ cls.layout.operator(
+ Ms3dImportOperator.bl_idname,
+ text=ms3d_str['TEXT_OPERATOR'],
+ )
+
+
+class Ms3dExportOperator(Operator, ExportHelper):
+ """Save a MilkShape3D MS3D File"""
+ bl_idname = 'export_scene.ms3d'
+ bl_label = ms3d_str['BL_LABEL_EXPORTER']
+ bl_description = ms3d_str['BL_DESCRIPTION_EXPORTER']
+ bl_options = {'PRESET', }
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+
+ filename_ext = ms3d_str['FILE_EXT']
+
+ filter_glob = StringProperty(
+ default=ms3d_str['FILE_FILTER'],
+ options={'HIDDEN', }
+ )
+
+ filepath = StringProperty(
+ subtype='FILE_PATH',
+ options={'HIDDEN', }
+ )
+
+ verbose = BoolProperty(
+ name=ms3d_str['PROP_NAME_VERBOSE'],
+ description=ms3d_str['PROP_DESC_VERBOSE'],
+ default=Ms3dUi.PROP_DEFAULT_VERBOSE,
+ )
+
+ use_blender_names = BoolProperty(
+ name=ms3d_str['PROP_NAME_USE_BLENDER_NAMES'],
+ description=ms3d_str['PROP_DESC_USE_BLENDER_NAMES'],
+ default=Ms3dUi.PROP_DEFAULT_USE_BLENDER_NAMES,
+ )
+
+ use_blender_materials = BoolProperty(
+ name=ms3d_str['PROP_NAME_USE_BLENDER_MATERIALS'],
+ description=ms3d_str['PROP_DESC_USE_BLENDER_MATERIALS'],
+ default=Ms3dUi.PROP_DEFAULT_USE_BLENDER_MATERIALS,
+ )
+
+ apply_transform = BoolProperty(
+ name=ms3d_str['PROP_NAME_APPLY_TRANSFORM'],
+ description=ms3d_str['PROP_DESC_APPLY_TRANSFORM'],
+ default=Ms3dUi.PROP_DEFAULT_APPLY_TRANSFORM,
+ )
+
+ apply_modifiers = BoolProperty(
+ name=ms3d_str['PROP_NAME_APPLY_MODIFIERS'],
+ description=ms3d_str['PROP_DESC_APPLY_MODIFIERS'],
+ default=Ms3dUi.PROP_DEFAULT_APPLY_MODIFIERS,
+ )
+
+ apply_modifiers_mode = EnumProperty(
+ name=ms3d_str['PROP_NAME_APPLY_MODIFIERS_MODE'],
+ description=ms3d_str['PROP_DESC_APPLY_MODIFIERS_MODE'],
+ items=( (Ms3dUi.PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW,
+ ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW_1'],
+ ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_VIEW_2']),
+ (Ms3dUi.PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER,
+ ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER_1'],
+ ms3d_str['PROP_ITEM_APPLY_MODIFIERS_MODE_RENDER_2']),
+ ),
+ default=Ms3dUi.PROP_DEFAULT_APPLY_MODIFIERS_MODE,
+ )
+
+ use_animation = BoolProperty(
+ name=ms3d_str['PROP_NAME_USE_ANIMATION'],
+ description=ms3d_str['PROP_DESC_USE_ANIMATION'],
+ default=Ms3dUi.PROP_DEFAULT_USE_ANIMATION,
+ )
+
+ normalize_weights = BoolProperty(
+ name=ms3d_str['PROP_NAME_NORMALIZE_WEIGHTS'],
+ description=ms3d_str['PROP_DESC_NORMALIZE_WEIGHTS'],
+ default=Ms3dUi.PROP_DEFAULT_NORMALIZE_WEIGHTS,
+ )
+
+ shrink_to_keys = BoolProperty(
+ name=ms3d_str['PROP_NAME_SHRINK_TO_KEYS'],
+ description=ms3d_str['PROP_DESC_SHRINK_TO_KEYS'],
+ default=Ms3dUi.PROP_DEFAULT_SHRINK_TO_KEYS,
+ )
+
+ bake_each_frame = BoolProperty(
+ name=ms3d_str['PROP_NAME_BAKE_EACH_FRAME'],
+ description=ms3d_str['PROP_DESC_BAKE_EACH_FRAME'],
+ default=Ms3dUi.PROP_DEFAULT_BAKE_EACH_FRAME,
+ )
+
+
+ ##EXPORT_ACTIVE_ONLY:
+ ##limit availability to only active mesh object
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.active_object
+ and blender_context.active_object.type in {'MESH', }
+ and blender_context.active_object.data
+ and blender_context.active_object.data.ms3d is not None
+ )
+
+ # draw the option panel
+ def draw(self, blender_context):
+ layout = self.layout
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_OPTIONS'], icon=Ms3dUi.ICON_OPTIONS)
+ box.prop(self, 'verbose', icon='SPEAKER')
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_PROCESSING'],
+ icon=Ms3dUi.ICON_PROCESSING)
+ row = box.row()
+ row.label(ms3d_str['PROP_NAME_ACTIVE'], icon='ROTACTIVE')
+ row.label(blender_context.active_object.name)
+ #box.prop(self, 'use_blender_names', icon='LINK_BLEND')
+ box.prop(self, 'use_blender_names')
+ box.prop(self, 'use_blender_materials')
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_MODIFIER'],
+ icon=Ms3dUi.ICON_MODIFIER)
+ box.prop(self, 'apply_transform')
+ row = box.row()
+ row.prop(self, 'apply_modifiers')
+ sub = row.row()
+ sub.active = self.apply_modifiers
+ sub.prop(self, 'apply_modifiers_mode', text="")
+
+ box = layout.box()
+ box.label(ms3d_str['LABEL_NAME_ANIMATION'],
+ icon=Ms3dUi.ICON_ANIMATION)
+ box.prop(self, 'use_animation')
+ if (self.use_animation):
+ box.prop(self, 'normalize_weights')
+ box.prop(self, 'shrink_to_keys')
+ box.prop(self, 'bake_each_frame')
+
+ # entrypoint for blender -> MS3D
+ def execute(self, blender_context):
+ """start executing"""
+ from io_scene_ms3d.ms3d_export import (Ms3dExporter, )
+ return Ms3dExporter(self).write(blender_context)
+
+ #
+ def invoke(self, blender_context, event):
+ blender_context.window_manager.fileselect_add(self)
+ return {"RUNNING_MODAL", }
+
+ @staticmethod
+ def menu_func(cls, blender_context):
+ cls.layout.operator(
+ Ms3dExportOperator.bl_idname,
+ text=ms3d_str['TEXT_OPERATOR']
+ )
+
+
+###############################################################################
+##
+###############################################################################
+
+
+###############################################################################
+class Ms3dSetSmoothingGroupOperator(Operator):
+ bl_idname = Ms3dUi.OPT_SMOOTHING_GROUP_APPLY
+ bl_label = ms3d_str['BL_LABEL_SMOOTHING_GROUP_OPERATOR']
+ bl_options = {'INTERNAL', }
+
+ smoothing_group_index = IntProperty(
+ name=ms3d_str['PROP_SMOOTHING_GROUP_INDEX'],
+ options={'HIDDEN', 'SKIP_SAVE', },
+ )
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ and blender_context.mode == 'EDIT_MESH'
+ and blender_context.tool_settings.mesh_select_mode[2]
+ )
+
+ def execute(self, blender_context):
+ custom_data = blender_context.object.data.ms3d
+ blender_mesh = blender_context.object.data
+ bm = from_edit_mesh(blender_mesh)
+ layer_smoothing_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+ if custom_data.apply_mode in {'SELECT', 'DESELECT', }:
+ if layer_smoothing_group is not None:
+ is_select = (custom_data.apply_mode == 'SELECT')
+ for bmf in bm.faces:
+ if (bmf[layer_smoothing_group] \
+ == self.smoothing_group_index):
+ bmf.select_set(is_select)
+ elif custom_data.apply_mode == 'ASSIGN':
+ if layer_smoothing_group is None:
+ layer_smoothing_group = bm.faces.layers.int.new(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+ blender_mesh_object = blender_context.object
+ get_edge_split_modifier_add_if(blender_mesh_object)
+ blender_face_list = []
+ for bmf in bm.faces:
+ if not bmf.smooth:
+ bmf.smooth = True
+ if bmf.select:
+ bmf[layer_smoothing_group] = self.smoothing_group_index
+ blender_face_list.append(bmf)
+ edge_dict = {}
+ for bmf in blender_face_list:
+ bmf.smooth = True
+ for bme in bmf.edges:
+ if edge_dict.get(bme) is None:
+ edge_dict[bme] = 0
+ else:
+ edge_dict[bme] += 1
+ is_border = (edge_dict[bme] == 0)
+ if is_border:
+ surround_face_smoothing_group_index \
+ = self.smoothing_group_index
+ for bmf in bme.link_faces:
+ if bmf[layer_smoothing_group] \
+ != surround_face_smoothing_group_index:
+ surround_face_smoothing_group_index \
+ = bmf[layer_smoothing_group]
+ break;
+ if surround_face_smoothing_group_index \
+ == self.smoothing_group_index:
+ is_border = False
+ bme.seam = is_border
+ bme.smooth = not is_border
+ bm.free()
+ enable_edit_mode(False, blender_context)
+ enable_edit_mode(True, blender_context)
+ return {'FINISHED', }
+
+
+class Ms3dGroupOperator(Operator):
+ bl_idname = Ms3dUi.OPT_GROUP_APPLY
+ bl_label = ms3d_str['BL_LABEL_GROUP_OPERATOR']
+ bl_options = {'INTERNAL', }
+
+ mode = EnumProperty(
+ items=( ('', "", ""),
+ ('ADD_GROUP',
+ ms3d_str['ENUM_ADD_GROUP_1'],
+ ms3d_str['ENUM_ADD_GROUP_2']),
+ ('REMOVE_GROUP',
+ ms3d_str['ENUM_REMOVE_GROUP_1'],
+ ms3d_str['ENUM_REMOVE_GROUP_2']),
+ ('ASSIGN',
+ ms3d_str['ENUM_ASSIGN_1'],
+ ms3d_str['ENUM_ASSIGN_2_GROUP']),
+ ('REMOVE',
+ ms3d_str['ENUM_REMOVE_1'],
+ ms3d_str['ENUM_REMOVE_2_GROUP']),
+ ('SELECT',
+ ms3d_str['ENUM_SELECT_1'],
+ ms3d_str['ENUM_SELECT_2_GROUP']),
+ ('DESELECT',
+ ms3d_str['ENUM_DESELECT_1'],
+ ms3d_str['ENUM_DESELECT_2_GROUP']),
+ ),
+ options={'HIDDEN', 'SKIP_SAVE', },
+ )
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ and blender_context.mode == 'EDIT_MESH'
+ #and blender_context.object.data.ms3d.selected_group_index != -1
+ )
+
+ def execute(self, blender_context):
+ custom_data = blender_context.object.data.ms3d
+ blender_mesh = blender_context.object.data
+ bm = None
+ bm = from_edit_mesh(blender_mesh)
+
+ if self.mode == 'ADD_GROUP':
+ item = custom_data.create_group()
+ layer_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+ if layer_group is None:
+ bm.faces.layers.int.new(ms3d_str['OBJECT_LAYER_GROUP'])
+
+ elif self.mode == 'REMOVE_GROUP':
+ custom_data.remove_group()
+
+ elif (custom_data.selected_group_index >= 0) and (
+ custom_data.selected_group_index < len(custom_data.groups)):
+ if self.mode in {'SELECT', 'DESELECT', }:
+ layer_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+ if layer_group is not None:
+ is_select = (self.mode == 'SELECT')
+ id = custom_data.groups[
+ custom_data.selected_group_index].id
+ for bmf in bm.faces:
+ if bmf[layer_group] == id:
+ bmf.select_set(is_select)
+
+ elif self.mode in {'ASSIGN', 'REMOVE', }:
+ layer_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+ if layer_group is None:
+ layer_group = bm.faces.layers.int.new(
+ ms3d_str['OBJECT_LAYER_GROUP'])
+
+ is_assign = (self.mode == 'ASSIGN')
+ id = custom_data.groups[custom_data.selected_group_index].id
+ for bmf in bm.faces:
+ if bmf.select:
+ if is_assign:
+ bmf[layer_group] = id
+ else:
+ bmf[layer_group] = -1
+ if bm is not None:
+ bm.free()
+ enable_edit_mode(False, blender_context)
+ enable_edit_mode(True, blender_context)
+ return {'FINISHED', }
+
+
+class Ms3dMaterialOperator(Operator):
+ bl_idname = Ms3dUi.OPT_MATERIAL_APPLY
+ bl_label = ms3d_str['BL_LABEL_MATERIAL_OPERATOR']
+ bl_options = {'INTERNAL', }
+
+ mode = EnumProperty(
+ items=( ('', "", ""),
+ ('FROM_BLENDER',
+ ms3d_str['ENUM_FROM_BLENDER_1'],
+ ms3d_str['ENUM_FROM_BLENDER_2']),
+ ('TO_BLENDER',
+ ms3d_str['ENUM_TO_BLENDER_1'],
+ ms3d_str['ENUM_TO_BLENDER_2']),
+ ),
+ options={'HIDDEN', 'SKIP_SAVE', },
+ )
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ and blender_context.material
+ and blender_context.material.ms3d is not None
+ )
+
+ def execute(self, blender_context):
+ blender_material = blender_context.active_object.active_material
+ ms3d_material = blender_material.ms3d
+
+ if self.mode == 'FROM_BLENDER':
+ Ms3dMaterialHelper.copy_from_blender(self, blender_context,
+ ms3d_material, blender_material)
+ pass
+
+ elif self.mode == 'TO_BLENDER':
+ # not implemented
+ pass
+
+ return {'FINISHED', }
+
+ # entrypoint for option via UI
+ def invoke(self, blender_context, event):
+ return blender_context.window_manager.invoke_props_dialog(self)
+
+
+###############################################################################
+class Ms3dGroupProperties(PropertyGroup):
+ name = StringProperty(
+ name=ms3d_str['PROP_NAME_NAME'],
+ description=ms3d_str['PROP_DESC_GROUP_NAME'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+ flags = EnumProperty(
+ name=ms3d_str['PROP_NAME_FLAGS'],
+ description=ms3d_str['PROP_DESC_FLAGS_GROUP'],
+ items=(#(Ms3dUi.FLAG_NONE, ms3d_str['ENUM_FLAG_NONE_1'],
+ # ms3d_str['ENUM_FLAG_NONE_2'],
+ # Ms3dSpec.FLAG_NONE),
+ (Ms3dUi.FLAG_SELECTED,
+ ms3d_str['ENUM_FLAG_SELECTED_1'],
+ ms3d_str['ENUM_FLAG_SELECTED_2'],
+ Ms3dSpec.FLAG_SELECTED),
+ (Ms3dUi.FLAG_HIDDEN,
+ ms3d_str['ENUM_FLAG_HIDDEN_1'],
+ ms3d_str['ENUM_FLAG_HIDDEN_2'],
+ Ms3dSpec.FLAG_HIDDEN),
+ (Ms3dUi.FLAG_SELECTED2,
+ ms3d_str['ENUM_FLAG_SELECTED2_1'],
+ ms3d_str['ENUM_FLAG_SELECTED2_2'],
+ Ms3dSpec.FLAG_SELECTED2),
+ (Ms3dUi.FLAG_DIRTY,
+ ms3d_str['ENUM_FLAG_DIRTY_1'],
+ ms3d_str['ENUM_FLAG_DIRTY_2'],
+ Ms3dSpec.FLAG_DIRTY),
+ (Ms3dUi.FLAG_ISKEY,
+ ms3d_str['ENUM_FLAG_ISKEY_1'],
+ ms3d_str['ENUM_FLAG_ISKEY_2'],
+ Ms3dSpec.FLAG_ISKEY),
+ (Ms3dUi.FLAG_NEWLYCREATED,
+ ms3d_str['ENUM_FLAG_NEWLYCREATED_1'],
+ ms3d_str['ENUM_FLAG_NEWLYCREATED_2'],
+ Ms3dSpec.FLAG_NEWLYCREATED),
+ (Ms3dUi.FLAG_MARKED,
+ ms3d_str['ENUM_FLAG_MARKED_1'],
+ ms3d_str['ENUM_FLAG_MARKED_2'],
+ Ms3dSpec.FLAG_MARKED),
+ ),
+ default=Ms3dUi.flags_from_ms3d(Ms3dSpec.DEFAULT_FLAGS),
+ options={'ENUM_FLAG', 'ANIMATABLE', },
+ )
+
+ comment = StringProperty(
+ name=ms3d_str['PROP_NAME_COMMENT'],
+ description=ms3d_str['PROP_DESC_COMMENT_GROUP'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+ template_list_controls = StringProperty(
+ default="",
+ options={'HIDDEN', 'SKIP_SAVE', },
+ )
+
+ id = IntProperty(options={'HIDDEN', },)
+
+
+class Ms3dModelProperties(PropertyGroup):
+ name = StringProperty(
+ name=ms3d_str['PROP_NAME_NAME'],
+ description=ms3d_str['PROP_DESC_NAME_MODEL'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+ joint_size = FloatProperty(
+ name=ms3d_str['PROP_NAME_JOINT_SIZE'],
+ description=ms3d_str['PROP_DESC_JOINT_SIZE'],
+ min=Ms3dUi.PROP_JOINT_SIZE_MIN, max=Ms3dUi.PROP_JOINT_SIZE_MAX,
+ precision=Ms3dUi.PROP_JOINT_SIZE_PRECISION, \
+ step=Ms3dUi.PROP_JOINT_SIZE_STEP,
+ default=Ms3dUi.PROP_DEFAULT_JOINT_SIZE,
+ subtype='FACTOR',
+ #options={'HIDDEN', },
+ )
+
+ transparency_mode = EnumProperty(
+ name=ms3d_str['PROP_NAME_TRANSPARENCY_MODE'],
+ description=ms3d_str['PROP_DESC_TRANSPARENCY_MODE'],
+ items=( (Ms3dUi.MODE_TRANSPARENCY_SIMPLE,
+ ms3d_str['PROP_MODE_TRANSPARENCY_SIMPLE_1'],
+ ms3d_str['PROP_MODE_TRANSPARENCY_SIMPLE_2'],
+ Ms3dSpec.MODE_TRANSPARENCY_SIMPLE),
+ (Ms3dUi.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES,
+ ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES_1'],
+ ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES_2'],
+ Ms3dSpec.MODE_TRANSPARENCY_DEPTH_SORTED_TRIANGLES),
+ (Ms3dUi.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF,
+ ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF_1'],
+ ms3d_str['PROP_MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF_2'],
+ Ms3dSpec.MODE_TRANSPARENCY_DEPTH_BUFFERED_WITH_ALPHA_REF),
+ ),
+ default=Ms3dUi.transparency_mode_from_ms3d(
+ Ms3dSpec.DEFAULT_MODEL_TRANSPARENCY_MODE),
+ #options={'HIDDEN', },
+ )
+
+ alpha_ref = FloatProperty(
+ name=ms3d_str['PROP_NAME_ALPHA_REF'],
+ description=ms3d_str['PROP_DESC_ALPHA_REF'],
+ min=0, max=1, precision=3, step=0.1,
+ default=0.5,
+ subtype='FACTOR',
+ #options={'HIDDEN', },
+ )
+
+ comment = StringProperty(
+ name=ms3d_str['PROP_NAME_COMMENT'],
+ description=ms3d_str['PROP_DESC_COMMENT_MODEL'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+ ##########################
+ # ms3d group handling
+ #
+ apply_mode = EnumProperty(
+ items=( ('ASSIGN',
+ ms3d_str['ENUM_ASSIGN_1'],
+ ms3d_str['ENUM_ASSIGN_2_SMOOTHING_GROUP']),
+ ('SELECT',
+ ms3d_str['ENUM_SELECT_1'],
+ ms3d_str['ENUM_SELECT_2_SMOOTHING_GROUP']),
+ ('DESELECT',
+ ms3d_str['ENUM_DESELECT_1'],
+ ms3d_str['ENUM_DESELECT_2_SMOOTHING_GROUP']),
+ ),
+ default='SELECT',
+ options={'HIDDEN', 'SKIP_SAVE', },
+ )
+
+ selected_group_index = IntProperty(
+ default=-1,
+ min=-1,
+ options={'HIDDEN', 'SKIP_SAVE', },
+ )
+ #
+ # ms3d group handling
+ ##########################
+
+ groups = CollectionProperty(
+ type=Ms3dGroupProperties,
+ #options={'HIDDEN', },
+ )
+
+
+ def generate_unique_id(self):
+ return randrange(1, 0x7FFFFFFF) # pseudo unique id
+
+ def create_group(self):
+ item = self.groups.add()
+ item.id = self.generate_unique_id()
+ length = len(self.groups)
+ self.selected_group_index = length - 1
+
+ item.name = ms3d_str['STRING_FORMAT_GROUP'].format(length)
+ return item
+
+ def remove_group(self):
+ index = self.selected_group_index
+ length = len(self.groups)
+ if (index >= 0) and (index < length):
+ if index > 0 or length == 1:
+ self.selected_group_index = index - 1
+ self.groups.remove(index)
+
+
+class Ms3dArmatureProperties(PropertyGroup):
+ name = StringProperty(
+ name=ms3d_str['PROP_NAME_NAME'],
+ description=ms3d_str['PROP_DESC_NAME_ARMATURE'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+
+class Ms3dJointProperties(PropertyGroup):
+ name = StringProperty(
+ name=ms3d_str['PROP_NAME_NAME'],
+ description=ms3d_str['PROP_DESC_NAME_JOINT'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+ flags = EnumProperty(
+ name=ms3d_str['PROP_NAME_FLAGS'],
+ description=ms3d_str['PROP_DESC_FLAGS_JOINT'],
+ items=(#(Ms3dUi.FLAG_NONE,
+ # ms3d_str['ENUM_FLAG_NONE_1'],
+ # ms3d_str['ENUM_FLAG_NONE_2'],
+ # Ms3dSpec.FLAG_NONE),
+ (Ms3dUi.FLAG_SELECTED,
+ ms3d_str['ENUM_FLAG_SELECTED_1'],
+ ms3d_str['ENUM_FLAG_SELECTED_2'],
+ Ms3dSpec.FLAG_SELECTED),
+ (Ms3dUi.FLAG_HIDDEN,
+ ms3d_str['ENUM_FLAG_HIDDEN_1'],
+ ms3d_str['ENUM_FLAG_HIDDEN_2'],
+ Ms3dSpec.FLAG_HIDDEN),
+ (Ms3dUi.FLAG_SELECTED2,
+ ms3d_str['ENUM_FLAG_SELECTED2_1'],
+ ms3d_str['ENUM_FLAG_SELECTED2_2'],
+ Ms3dSpec.FLAG_SELECTED2),
+ (Ms3dUi.FLAG_DIRTY,
+ ms3d_str['ENUM_FLAG_DIRTY_1'],
+ ms3d_str['ENUM_FLAG_DIRTY_2'],
+ Ms3dSpec.FLAG_DIRTY),
+ (Ms3dUi.FLAG_ISKEY,
+ ms3d_str['ENUM_FLAG_ISKEY_1'],
+ ms3d_str['ENUM_FLAG_ISKEY_2'],
+ Ms3dSpec.FLAG_ISKEY),
+ (Ms3dUi.FLAG_NEWLYCREATED,
+ ms3d_str['ENUM_FLAG_NEWLYCREATED_1'],
+ ms3d_str['ENUM_FLAG_NEWLYCREATED_2'],
+ Ms3dSpec.FLAG_NEWLYCREATED),
+ (Ms3dUi.FLAG_MARKED,
+ ms3d_str['ENUM_FLAG_MARKED_1'],
+ ms3d_str['ENUM_FLAG_MARKED_2'],
+ Ms3dSpec.FLAG_MARKED),
+ ),
+ default=Ms3dUi.flags_from_ms3d(Ms3dSpec.DEFAULT_FLAGS),
+ options={'ENUM_FLAG', 'ANIMATABLE', },
+ )
+
+ color = FloatVectorProperty(
+ name=ms3d_str['PROP_NAME_COLOR'],
+ description=ms3d_str['PROP_DESC_COLOR_JOINT'],
+ subtype='COLOR', size=3, min=0, max=1, precision=3, step=0.1,
+ default=Ms3dSpec.DEFAULT_JOINT_COLOR,
+ #options={'HIDDEN', },
+ )
+
+ comment = StringProperty(
+ name=ms3d_str['PROP_NAME_COMMENT'],
+ description=ms3d_str['PROP_DESC_COMMENT_JOINT'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+
+class Ms3dMaterialHelper:
+ @staticmethod
+ def copy_to_blender_ambient(cls, blender_context):
+ pass
+
+ @staticmethod
+ def copy_to_blender_diffuse(cls, blender_context):
+ cls.id_data.diffuse_color = cls.diffuse[0:3]
+ #cls.id_data.diffuse_intensity = cls.diffuse[3]
+ pass
+
+ @staticmethod
+ def copy_to_blender_specular(cls, blender_context):
+ cls.id_data.specular_color = cls.specular[0:3]
+ #cls.id_data.specular_intensity = cls.specular[3]
+ pass
+
+ @staticmethod
+ def copy_to_blender_emissive(cls, blender_context):
+ cls.id_data.emit = (cls.emissive[0] + cls.emissive[1] \
+ + cls.emissive[2]) / 3.0
+ pass
+
+ @staticmethod
+ def copy_to_blender_shininess(cls, blender_context):
+ cls.id_data.specular_hardness = cls.shininess * 4.0
+ pass
+
+ @staticmethod
+ def copy_to_blender_transparency(cls, blender_context):
+ cls.id_data.alpha = 1.0 - cls.transparency
+ pass
+
+
+ @staticmethod
+ def copy_from_blender(cls, blender_context, ms3d_material, blender_material):
+ # copy, bacause of auto update, it would distord original values
+ blender_material_diffuse_color = blender_material.diffuse_color.copy()
+ blender_material_diffuse_intensity = blender_material.diffuse_intensity
+ blender_material_specular_color = blender_material.specular_color.copy()
+ blender_material_specular_intensity = \
+ blender_material.specular_intensity
+ blender_material_emit = blender_material.emit
+ blender_material_specular_hardness = \
+ blender_material.specular_hardness
+ blender_material_alpha = blender_material.alpha
+
+ blender_material_texture = None
+ for slot in blender_material.texture_slots:
+ if slot and slot.use_map_color_diffuse \
+ and slot.texture.type == 'IMAGE':
+ blender_material_texture = slot.texture.image.filepath
+ break
+
+ blender_material_alphamap = None
+ for slot in blender_material.texture_slots:
+ if slot and not slot.use_map_color_diffuse \
+ and slot.use_map_alpha and slot.texture.type == 'IMAGE':
+ blender_material_alphamap = slot.texture.image.filepath
+ break
+
+ ms3d_material.diffuse[0] = blender_material_diffuse_color[0]
+ ms3d_material.diffuse[1] = blender_material_diffuse_color[1]
+ ms3d_material.diffuse[2] = blender_material_diffuse_color[2]
+ ms3d_material.diffuse[3] = 1.0
+ ms3d_material.specular[0] = blender_material_specular_color[0]
+ ms3d_material.specular[1] = blender_material_specular_color[1]
+ ms3d_material.specular[2] = blender_material_specular_color[2]
+ ms3d_material.specular[3] = 1.0
+ ms3d_material.emissive[0] = blender_material_emit
+ ms3d_material.emissive[1] = blender_material_emit
+ ms3d_material.emissive[2] = blender_material_emit
+ ms3d_material.emissive[3] = 1.0
+ ms3d_material.shininess = blender_material_specular_hardness / 4.0
+ ms3d_material.transparency = 1.0 - blender_material_alpha
+
+ if blender_material_texture:
+ ms3d_material.texture = blender_material_texture
+ else:
+ ms3d_material.texture = ""
+
+ if blender_material_alphamap:
+ ms3d_material.alphamap = blender_material_alphamap
+ else:
+ ms3d_material.alphamap = ""
+
+
+class Ms3dMaterialProperties(PropertyGroup):
+ name = StringProperty(
+ name=ms3d_str['PROP_NAME_NAME'],
+ description=ms3d_str['PROP_DESC_NAME_MATERIAL'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+ ambient = FloatVectorProperty(
+ name=ms3d_str['PROP_NAME_AMBIENT'],
+ description=ms3d_str['PROP_DESC_AMBIENT'],
+ subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1,
+ default=Ms3dSpec.DEFAULT_MATERIAL_AMBIENT,
+ update=Ms3dMaterialHelper.copy_to_blender_ambient,
+ #options={'HIDDEN', },
+ )
+
+ diffuse = FloatVectorProperty(
+ name=ms3d_str['PROP_NAME_DIFFUSE'],
+ description=ms3d_str['PROP_DESC_DIFFUSE'],
+ subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1,
+ default=Ms3dSpec.DEFAULT_MATERIAL_DIFFUSE,
+ update=Ms3dMaterialHelper.copy_to_blender_diffuse,
+ #options={'HIDDEN', },
+ )
+
+ specular = FloatVectorProperty(
+ name=ms3d_str['PROP_NAME_SPECULAR'],
+ description=ms3d_str['PROP_DESC_SPECULAR'],
+ subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1,
+ default=Ms3dSpec.DEFAULT_MATERIAL_SPECULAR,
+ update=Ms3dMaterialHelper.copy_to_blender_specular,
+ #options={'HIDDEN', },
+ )
+
+ emissive = FloatVectorProperty(
+ name=ms3d_str['PROP_NAME_EMISSIVE'],
+ description=ms3d_str['PROP_DESC_EMISSIVE'],
+ subtype='COLOR', size=4, min=0, max=1, precision=3, step=0.1,
+ default=Ms3dSpec.DEFAULT_MATERIAL_EMISSIVE,
+ update=Ms3dMaterialHelper.copy_to_blender_emissive,
+ #options={'HIDDEN', },
+ )
+
+ shininess = FloatProperty(
+ name=ms3d_str['PROP_NAME_SHININESS'],
+ description=ms3d_str['PROP_DESC_SHININESS'],
+ min=0, max=Ms3dSpec.MAX_MATERIAL_SHININESS, precision=3, step=0.1,
+ default=Ms3dSpec.DEFAULT_MATERIAL_SHININESS,
+ subtype='FACTOR',
+ update=Ms3dMaterialHelper.copy_to_blender_shininess,
+ #options={'HIDDEN', },
+ )
+
+ transparency = FloatProperty(
+ name=ms3d_str['PROP_NAME_TRANSPARENCY'],
+ description=ms3d_str['PROP_DESC_TRANSPARENCY'],
+ min=0, max=1, precision=3, step=0.1,
+ default=0,
+ subtype='FACTOR',
+ update=Ms3dMaterialHelper.copy_to_blender_transparency,
+ #options={'HIDDEN', },
+ )
+
+ mode = EnumProperty(
+ name=ms3d_str['PROP_NAME_MODE'],
+ description=ms3d_str['PROP_DESC_MODE_TEXTURE'],
+ items=( (Ms3dUi.FLAG_TEXTURE_COMBINE_ALPHA,
+ ms3d_str['PROP_FLAG_TEXTURE_COMBINE_ALPHA_1'],
+ ms3d_str['PROP_FLAG_TEXTURE_COMBINE_ALPHA_2'],
+ Ms3dSpec.FLAG_TEXTURE_COMBINE_ALPHA),
+ (Ms3dUi.FLAG_TEXTURE_HAS_ALPHA,
+ ms3d_str['PROP_FLAG_TEXTURE_HAS_ALPHA_1'],
+ ms3d_str['PROP_FLAG_TEXTURE_HAS_ALPHA_2'],
+ Ms3dSpec.FLAG_TEXTURE_HAS_ALPHA),
+ (Ms3dUi.FLAG_TEXTURE_SPHERE_MAP,
+ ms3d_str['PROP_FLAG_TEXTURE_SPHERE_MAP_1'],
+ ms3d_str['PROP_FLAG_TEXTURE_SPHERE_MAP_2'],
+ Ms3dSpec.FLAG_TEXTURE_SPHERE_MAP),
+ ),
+ default=Ms3dUi.texture_mode_from_ms3d(
+ Ms3dSpec.DEFAULT_MATERIAL_MODE),
+ options={'ANIMATABLE', 'ENUM_FLAG', },
+ )
+
+ texture = StringProperty(
+ name=ms3d_str['PROP_NAME_TEXTURE'],
+ description=ms3d_str['PROP_DESC_TEXTURE'],
+ default="",
+ subtype = 'FILE_PATH'
+ #options={'HIDDEN', },
+ )
+
+ alphamap = StringProperty(
+ name=ms3d_str['PROP_NAME_ALPHAMAP'],
+ description=ms3d_str['PROP_DESC_ALPHAMAP'],
+ default="",
+ subtype = 'FILE_PATH'
+ #options={'HIDDEN', },
+ )
+
+ comment = StringProperty(
+ name=ms3d_str['PROP_NAME_COMMENT'],
+ description=ms3d_str['PROP_DESC_COMMENT_MATERIAL'],
+ default="",
+ #options={'HIDDEN', },
+ )
+
+
+###############################################################################
+class Ms3dMeshPanel(Panel):
+ bl_label = ms3d_str['LABEL_PANEL_MODEL']
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'object'
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ )
+
+ def draw_header(self, blender_context):
+ layout = self.layout
+ layout.label(icon='PLUGIN')
+
+ def draw(self, blender_context):
+ layout = self.layout
+ custom_data = blender_context.object.data.ms3d
+
+ row = layout.row()
+ row.prop(custom_data, 'name')
+
+ col = layout.column()
+ row = col.row()
+ row.prop(custom_data, 'joint_size')
+ row = col.row()
+ row.prop(custom_data, 'transparency_mode')
+ row = col.row()
+ row.prop(custom_data, 'alpha_ref', )
+
+ row = layout.row()
+ row.prop(custom_data, 'comment')
+
+
+class Ms3dMaterialPanel(Panel):
+ bl_label = ms3d_str['LABEL_PANEL_MATERIALS']
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'material'
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ and blender_context.material
+ and blender_context.material.ms3d is not None
+ )
+
+ def draw_header(self, blender_context):
+ layout = self.layout
+ layout.label(icon='PLUGIN')
+
+ def draw(self, blender_context):
+ layout = self.layout
+ custom_data = blender_context.material.ms3d
+
+ row = layout.row()
+ row.prop(custom_data, 'name')
+
+ col = layout.column()
+ row = col.row()
+ row.prop(custom_data, 'diffuse')
+ row.prop(custom_data, 'ambient')
+ row = col.row()
+ row.prop(custom_data, 'specular')
+ row.prop(custom_data, 'emissive')
+ row = col.row()
+ row.prop(custom_data, 'shininess')
+ row.prop(custom_data, 'transparency')
+
+ col = layout.column()
+ row = col.row()
+ row.prop(custom_data, 'texture')
+ row = col.row()
+ row.prop(custom_data, 'alphamap')
+ row = col.row()
+ row.prop(custom_data, 'mode', expand=True)
+
+ row = layout.row()
+ row.prop(custom_data, 'comment')
+
+ layout.row().operator(
+ Ms3dUi.OPT_MATERIAL_APPLY,
+ text=ms3d_str['ENUM_FROM_BLENDER_1'],
+ icon='APPEND_BLEND').mode = 'FROM_BLENDER'
+ pass
+
+
+class Ms3dBonePanel(Panel):
+ bl_label = ms3d_str['LABEL_PANEL_JOINTS']
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'bone'
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object.type in {'ARMATURE', }
+ and blender_context.active_bone
+ and isinstance(blender_context.active_bone, Bone)
+ and blender_context.active_bone.ms3d is not None
+ )
+
+ def draw_header(self, blender_context):
+ layout = self.layout
+ layout.label(icon='PLUGIN')
+
+ def draw(self, blender_context):
+ import bpy
+ layout = self.layout
+ custom_data = blender_context.active_bone.ms3d
+
+ row = layout.row()
+ row.prop(custom_data, 'name')
+ row = layout.row()
+ row.prop(custom_data, 'flags', expand=True)
+ row = layout.row()
+ row.prop(custom_data, 'color')
+ row = layout.row()
+ row.prop(custom_data, 'comment')
+
+
+class Ms3dGroupPanel(Panel):
+ bl_label = ms3d_str['LABEL_PANEL_GROUPS']
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'data'
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ )
+
+ def draw_header(self, blender_context):
+ layout = self.layout
+ layout.label(icon='PLUGIN')
+
+ def draw(self, blender_context):
+ layout = self.layout
+ custom_data = blender_context.object.data.ms3d
+ layout.enabled = (blender_context.mode == 'EDIT_MESH') and (
+ blender_context.tool_settings.mesh_select_mode[2])
+
+ row = layout.row()
+ row.template_list(
+ custom_data, 'groups',
+ custom_data, 'selected_group_index',
+ prop_list='template_list_controls',
+ rows=2,
+ type='DEFAULT',
+ )
+
+ col = row.column(align=True)
+ col.operator(
+ Ms3dUi.OPT_GROUP_APPLY,
+ text="", icon='ZOOMIN').mode = 'ADD_GROUP'
+ col.operator(
+ Ms3dUi.OPT_GROUP_APPLY,
+ text="", icon='ZOOMOUT').mode = 'REMOVE_GROUP'
+
+ index = custom_data.selected_group_index
+ collection = custom_data.groups
+ if (index >= 0 and index < len(collection)):
+ row = layout.row()
+ row.prop(collection[index], 'name')
+
+ row = layout.row()
+ subrow = row.row(align=True)
+ subrow.operator(
+ Ms3dUi.OPT_GROUP_APPLY,
+ text=ms3d_str['ENUM_ASSIGN_1']).mode = 'ASSIGN'
+ subrow.operator(
+ Ms3dUi.OPT_GROUP_APPLY,
+ text=ms3d_str['ENUM_REMOVE_1']).mode = 'REMOVE'
+ subrow = row.row(align=True)
+ subrow.operator(
+ Ms3dUi.OPT_GROUP_APPLY,
+ text=ms3d_str['ENUM_SELECT_1']).mode = 'SELECT'
+ subrow.operator(
+ Ms3dUi.OPT_GROUP_APPLY,
+ text=ms3d_str['ENUM_DESELECT_1']).mode = 'DESELECT'
+
+ row = layout.row()
+ row.prop(collection[index], 'flags', expand=True)
+
+ row = layout.row()
+ row.prop(collection[index], 'comment')
+
+
+class Ms3dSmoothingGroupPanel(Panel):
+ bl_label = ms3d_str['BL_LABEL_PANEL_SMOOTHING_GROUP']
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'data'
+
+ def preview(self, dict, id, text):
+ item = dict.get(id)
+ if item is None:
+ return "{}".format(text)
+ elif item:
+ return "{}:".format(text)
+
+ return "{}.".format(text)
+
+ def build_preview(self, blender_context):
+ dict = {}
+ if (blender_context.mode != 'EDIT_MESH') or (
+ not blender_context.tool_settings.mesh_select_mode[2]):
+ return dict
+
+ custom_data = blender_context.object.data.ms3d
+ blender_mesh = blender_context.object.data
+ bm = from_edit_mesh(blender_mesh)
+ layer_smoothing_group = bm.faces.layers.int.get(
+ ms3d_str['OBJECT_LAYER_SMOOTHING_GROUP'])
+ if layer_smoothing_group is not None:
+ for bmf in bm.faces:
+ item = dict.get(bmf[layer_smoothing_group])
+ if item is None:
+ dict[bmf[layer_smoothing_group]] = bmf.select
+ else:
+ if not item:
+ dict[bmf[layer_smoothing_group]] = bmf.select
+ return dict
+
+ @classmethod
+ def poll(cls, blender_context):
+ return (blender_context
+ and blender_context.object
+ and blender_context.object.type in {'MESH', }
+ and blender_context.object.data
+ and blender_context.object.data.ms3d is not None
+ )
+
+ def draw_header(self, blender_context):
+ layout = self.layout
+ layout.label(icon='PLUGIN')
+
+ def draw(self, blender_context):
+ dict = self.build_preview(blender_context)
+
+ custom_data = blender_context.object.data.ms3d
+ layout = self.layout
+ layout.enabled = (blender_context.mode == 'EDIT_MESH') and (
+ blender_context.tool_settings.mesh_select_mode[2])
+
+ row = layout.row()
+ subrow = row.row()
+ subrow.prop(custom_data, 'apply_mode', expand=True)
+
+ col = layout.column(align=True)
+ subrow = col.row(align=True)
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 1, "1")
+ ).smoothing_group_index = 1
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 2, "2")
+ ).smoothing_group_index = 2
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 3, "3")
+ ).smoothing_group_index = 3
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 4, "4")
+ ).smoothing_group_index = 4
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 5, "5")
+ ).smoothing_group_index = 5
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 6, "6")
+ ).smoothing_group_index = 6
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 7, "7")
+ ).smoothing_group_index = 7
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 8, "8")
+ ).smoothing_group_index = 8
+ subrow = col.row(align=True)
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 9, "9")
+ ).smoothing_group_index = 9
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 10, "10")
+ ).smoothing_group_index = 10
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 11, "11")
+ ).smoothing_group_index = 11
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 12, "12")
+ ).smoothing_group_index = 12
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 13, "13")
+ ).smoothing_group_index = 13
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 14, "14")
+ ).smoothing_group_index = 14
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 15, "15")
+ ).smoothing_group_index = 15
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 16, "16")
+ ).smoothing_group_index = 16
+ subrow = col.row(align=True)
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 17, "17")
+ ).smoothing_group_index = 17
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 18, "18")
+ ).smoothing_group_index = 18
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 19, "19")
+ ).smoothing_group_index = 19
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 20, "20")
+ ).smoothing_group_index = 20
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 21, "21")
+ ).smoothing_group_index = 21
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 22, "22")
+ ).smoothing_group_index = 22
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 23, "23")
+ ).smoothing_group_index = 23
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 24, "24")
+ ).smoothing_group_index = 24
+ subrow = col.row(align=True)
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 25, "25")
+ ).smoothing_group_index = 25
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 26, "26")
+ ).smoothing_group_index = 26
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 27, "27")
+ ).smoothing_group_index = 27
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 28, "28")
+ ).smoothing_group_index = 28
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 29, "29")
+ ).smoothing_group_index = 29
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 30, "30")
+ ).smoothing_group_index = 30
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 31, "31")
+ ).smoothing_group_index = 31
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 32, "32")
+ ).smoothing_group_index = 32
+ subrow = col.row()
+ subrow.operator(
+ Ms3dUi.OPT_SMOOTHING_GROUP_APPLY,
+ text=self.preview(dict, 0, ms3d_str['LABEL_PANEL_BUTTON_NONE'])
+ ).smoothing_group_index = 0
+
+
+###############################################################################
+class Ms3dSetSceneToMetricOperator(Operator):
+ """ . """
+ bl_idname = 'io_scene_ms3d.set_sence_to_metric'
+ bl_label = ms3d_str['BL_LABEL_SET_SCENE_TO_METRIC']
+ bl_description = ms3d_str['BL_DESC_SET_SCENE_TO_METRIC']
+
+
+ #
+ @classmethod
+ def poll(cls, blender_context):
+ return True
+
+ # entrypoint for option
+ def execute(self, blender_context):
+ return self.set_sence_to_metric(blender_context)
+
+ # entrypoint for option via UI
+ def invoke(self, blender_context, event):
+ return blender_context.window_manager.invoke_props_dialog(self)
+
+
+ ###########################################################################
+ def set_sence_to_metric(self, blender_context):
+ set_sence_to_metric(blender_context)
+ return {"FINISHED"}
+
+
+###############################################################################
+def register():
+ register_class(Ms3dSetSceneToMetricOperator)
+ register_class(Ms3dGroupProperties)
+ register_class(Ms3dModelProperties)
+ register_class(Ms3dArmatureProperties)
+ register_class(Ms3dJointProperties)
+ register_class(Ms3dMaterialProperties)
+ inject_properties()
+ register_class(Ms3dSetSmoothingGroupOperator)
+ register_class(Ms3dGroupOperator)
+
+def unregister():
+ unregister_class(Ms3dGroupOperator)
+ unregister_class(Ms3dSetSmoothingGroupOperator)
+ delete_properties()
+ unregister_class(Ms3dMaterialProperties)
+ unregister_class(Ms3dJointProperties)
+ unregister_class(Ms3dArmatureProperties)
+ unregister_class(Ms3dModelProperties)
+ unregister_class(Ms3dGroupProperties)
+ unregister_class(Ms3dSetSceneToMetricOperator)
+
+def inject_properties():
+ Mesh.ms3d = PointerProperty(type=Ms3dModelProperties)
+ Armature.ms3d = PointerProperty(type=Ms3dArmatureProperties)
+ Bone.ms3d = PointerProperty(type=Ms3dJointProperties)
+ Material.ms3d = PointerProperty(type=Ms3dMaterialProperties)
+ Action.ms3d = PointerProperty(type=Ms3dArmatureProperties)
+ Group.ms3d = PointerProperty(type=Ms3dGroupProperties)
+
+def delete_properties():
+ del Mesh.ms3d
+ del Armature.ms3d
+ del Bone.ms3d
+ del Material.ms3d
+ del Action.ms3d
+ del Group.ms3d
+
+###############################################################################
+
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py
new file mode 100644
index 0000000..c6a885e
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_ms3d/ms3d_utils.py
@@ -0,0 +1,225 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+
+
+# ##### BEGIN COPYRIGHT BLOCK #####
+#
+# initial script copyright (c)2011,2012 Alexander Nussbaumer
+#
+# ##### END COPYRIGHT BLOCK #####
+
+
+#import python stuff
+from os import (
+ path
+ )
+
+
+# import io_scene_ms3d stuff
+from io_scene_ms3d.ms3d_strings import (
+ ms3d_str,
+ )
+
+
+#import blender stuff
+from bpy import (
+ ops,
+ )
+
+
+###############################################################################
+def enable_edit_mode(enable, blender_context):
+ if blender_context.active_object is None \
+ or not blender_context.active_object.type in {'MESH', 'ARMATURE', }:
+ return
+
+ if enable:
+ modeString = 'EDIT'
+ else:
+ modeString = 'OBJECT'
+
+ if ops.object.mode_set.poll():
+ ops.object.mode_set(mode=modeString)
+
+
+###############################################################################
+def enable_pose_mode(enable, blender_context):
+ if blender_context.active_object is None \
+ or not blender_context.active_object.type in {'ARMATURE', }:
+ return
+
+ if enable:
+ modeString = 'POSE'
+ else:
+ modeString = 'OBJECT'
+
+ if ops.object.mode_set.poll():
+ ops.object.mode_set(mode=modeString)
+
+
+###############################################################################
+def select_all(select):
+ if select:
+ actionString = 'SELECT'
+ else:
+ actionString = 'DESELECT'
+
+ if ops.object.select_all.poll():
+ ops.object.select_all(action=actionString)
+
+ if ops.mesh.select_all.poll():
+ ops.mesh.select_all(action=actionString)
+
+ if ops.pose.select_all.poll():
+ ops.pose.select_all(action=actionString)
+
+
+###############################################################################
+def pre_setup_environment(porter, blender_context):
+ # inject undo to porter
+ # and turn off undo
+ porter.undo = blender_context.user_preferences.edit.use_global_undo
+ blender_context.user_preferences.edit.use_global_undo = False
+
+ # inject active_object to self
+ porter.active_object = blender_context.scene.objects.active
+
+ # change to a well defined mode
+ enable_edit_mode(True, blender_context)
+
+ # enable face-selection-mode
+ blender_context.tool_settings.mesh_select_mode = (False, False, True)
+
+ # change back to object mode
+ enable_edit_mode(False, blender_context)
+
+ blender_context.scene.update()
+
+ # inject splitted filepath
+ porter.filepath_splitted = path.split(porter.options.filepath)
+
+
+###############################################################################
+def post_setup_environment(porter, blender_context):
+ # restore active object
+ blender_context.scene.objects.active = porter.active_object
+
+ if not blender_context.scene.objects.active \
+ and blender_context.selected_objects:
+ blender_context.scene.objects.active \
+ = blender_context.selected_objects[0]
+
+ # restore pre operator undo state
+ blender_context.user_preferences.edit.use_global_undo = porter.undo
+
+
+###############################################################################
+def get_edge_split_modifier_add_if(blender_mesh_object):
+ blender_modifier = blender_mesh_object.modifiers.get(
+ ms3d_str['OBJECT_MODIFIER_SMOOTHING_GROUP'])
+
+ if blender_modifier is None:
+ blender_modifier = blender_mesh_object.modifiers.new(
+ ms3d_str['OBJECT_MODIFIER_SMOOTHING_GROUP'],
+ type='EDGE_SPLIT')
+ blender_modifier.show_expanded = False
+ blender_modifier.use_edge_angle = False
+ blender_modifier.use_edge_sharp = True
+
+ blender_mesh_object.data.show_edge_seams = True
+ blender_mesh_object.data.show_edge_sharp = True
+
+ return blender_modifier
+
+
+###########################################################################
+def rotation_matrix(v_track, v_up):
+ ## rotation matrix from two vectors
+ ## http://gamedev.stackexchange.com/questions/20097/how-to-calculate-a-3x3-rotation-matrix-from-2-direction-vectors
+ ## http://www.fastgraph.com/makegames/3drotation/
+ matrix = Matrix().to_3x3()
+
+ c1 = v_track
+ c1.normalize()
+
+ c0 = c1.cross(v_up)
+ c0.normalize()
+
+ c2 = c0.cross(c1)
+ c2.normalize()
+
+ matrix.col[0] = c0
+ matrix.col[1] = c1
+ matrix.col[2] = c2
+
+ return matrix
+
+
+###############################################################################
+def matrix_difference(mat_src, mat_dst):
+ mat_dst_inv = mat_dst.copy()
+ mat_dst_inv.invert()
+ return mat_dst_inv * mat_src
+
+
+###############################################################################
+def set_sence_to_metric(blender_context):
+ try:
+ # set metrics
+ blender_context.scene.unit_settings.system = 'METRIC'
+ blender_context.scene.unit_settings.system_rotation = 'DEGREES'
+ blender_context.scene.unit_settings.scale_length = 0.001 # 1.0mm
+ blender_context.scene.unit_settings.use_separate = False
+ blender_context.tool_settings.normal_size = 1.0 # 1.0mm
+
+ # set all 3D views to texture shaded
+ # and set up the clipping
+ for screen in blender_context.blend_data.screens:
+ for area in screen.areas:
+ if (area.type != 'VIEW_3D'):
+ continue
+
+ for space in area.spaces:
+ if (space.type != 'VIEW_3D'):
+ continue
+
+ #space.viewport_shade = 'SOLID'
+ space.show_textured_solid = True
+ space.clip_start = 0.1 # 0.1mm
+ space.clip_end = 1000000.0 # 1km
+ #screen.scene.game_settings.material_mode = 'MULTITEXTURE'
+
+ except Exception:
+ raise
+
+ else:
+ pass
+
+
+###############################################################################
+
+###############################################################################
+#234567890123456789012345678901234567890123456789012345678901234567890123456789
+#--------1---------2---------3---------4---------5---------6---------7---------
+# ##### END OF FILE #####
diff --git a/release/scripts/addons_contrib/io_scene_open_street_map.py b/release/scripts/addons_contrib/io_scene_open_street_map.py
new file mode 100644
index 0000000..d3f2866
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_open_street_map.py
@@ -0,0 +1,370 @@
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Open Street Map (.osm)",
+ "author": "Michael Anthrax Schlachter, ideasman42, littleneo",
+ "version": (0, 2),
+ "blender": (2, 63, 0),
+ "location": "File > Import",
+ "description": "Load Open Street Map File",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Import-Export"}
+
+# originally written for blender 2.4x by (manthrax _at_ hotmail.com),
+# updated for blender 2.6x by ideasman42
+# If you use it for something cool, send me an email and let me know!
+
+# littleneo (v0.2 - september 2012) :
+
+## added a lat/lon to UTM conversion option geoToUTM() :
+# the generated mesh now almost match the exported osm image of the same area, just play with scale and rotate a bit.
+
+## added ability to retrieve openstreet tags as vertex groups :
+# add every way id as a vgroup if the tag exists in osmkeys.
+# add nodes id as vgroup if the tag value pair exists in osmvals.
+# any elligible is added in the corresponding osmkeys or value ('_V_...' vgroup
+
+## added bpy access to addon :
+# bpy.ops.import_mesh.osm(filepath="....", scale=100, utm=False, tag=False)
+
+## added custom properties to generated object so it can be used as source for other osm related scripts :
+# osmfile path to osm xml file
+# tagged bool. osm tags included
+# utm bool. default True
+
+# modified the matrix approximation for utm = False
+# ! corrected lat/lon x/y mismatch
+
+import bpy
+from mathutils import Vector, Matrix
+import math
+from math import radians, sin, cos, tan, sqrt
+
+## add more osm tags here.
+# http://wiki.openstreetmap.org/wiki/Map_Features
+osmkeys = [
+ 'highway',
+ 'barrier',
+ 'wall',
+ 'cycleway',
+ 'bicycle',
+ 'waterway',
+ 'railway',
+ 'aeroway',
+ 'aerialway',
+ 'power',
+ 'man_made',
+ 'building',
+ 'leisure',
+ 'amenity',
+ 'office',
+ 'shop',
+ 'craft',
+ 'emergency',
+ 'tourism',
+ 'historic',
+ 'landuse',
+ 'military',
+ 'natural',
+]
+
+# just a try for nodes, for retrieving v tag values.
+# keyname must exists in osmkeys
+osmvals = {'highway':['traffic_signals']}
+
+# vertex group name -> vertex group index lookup
+grouplookup = {}
+
+def parseBranch(nodes, bm, nmap, obj, scale=100.0, tag=False, UTM=False):
+ vgroups = bm.verts.layers.deform.verify()
+ tidx = 0
+ inNode = 0
+ dlat = dlong = clat = clong = minlat = maxlat = minlong = maxlong = 0.0
+ for node in nodes:
+ if node.localName == "bounds":
+ if node.hasAttributes():
+ for i in range(node.attributes.length):
+ at = node.attributes.item(i)
+ if at.name == "minlat":
+ minlat = float(at.nodeValue)
+ elif at.name == "minlon":
+ minlong = float(at.nodeValue)
+ elif at.name == "maxlat":
+ maxlat = float(at.nodeValue)
+ elif at.name == "maxlon":
+ maxlong = float(at.nodeValue)
+ dlat = maxlat - minlat
+ dlong = maxlong - minlong
+ clat = (maxlat + minlat) * 0.5
+ clong = (maxlong + minlong) * 0.5
+
+ if UTM :
+ dlong, dlat = geoToUTM(dlong, dlat)
+ clong, clat = geoToUTM(clong, clat)
+
+ print(dlat, dlong, clat, clong)
+
+ if node.localName == "way":
+
+ wayid = node.getAttribute('id')
+ nid = None
+ refs = []
+ if tag :
+ group = obj.vertex_groups.new('way_%s'%wayid)
+ gid = len(obj.vertex_groups) -1
+ '''
+ if node.hasAttributes():
+ for i in range(node.attributes.length):
+ at=node.attributes.item(i)
+ print(at.name)
+ '''
+
+ if tag :
+ metagid = []
+ for ch in node.childNodes:
+ if ch.localName == "tag":
+ key = ch.getAttribute('k')
+ if key in osmkeys :
+ metagid.append(grouplookup[key])
+
+ for ch in node.childNodes:
+ if ch.localName == "nd":
+ for i in range(ch.attributes.length):
+ at = ch.attributes.item(i)
+ if at.name == "ref":
+ vid = int(at.nodeValue)
+ refs.append(vid)
+ if tag :
+ vert = nmap[vid]
+ weigths = vert[vgroups]
+ weigths[gid] = 1.0
+ for mid in metagid : weigths[mid] = 1.0
+
+ first = 1
+ for r in refs:
+ if first == 0:
+ edge = bm.edges.get((nmap[pr], nmap[r]))
+ if edge is None:
+ edge = bm.edges.new((nmap[pr], nmap[r]))
+ del edge # don't actually use it
+ else:
+ first = 0
+ pr = r
+
+ if node.localName == "node":
+ if node.hasAttributes():
+ nid = node.getAttribute('id')
+ nlong = node.getAttribute('lon')
+ nlat = node.getAttribute('lat')
+
+ # is this test necessary ? maybe for faulty .osm files
+ if (nid != '') and (nlat != '') and (nlong != '') :
+
+ if UTM :
+ nlong, nlat = geoToUTM(float(nlong),float(nlat))
+ else :
+ nlat = float(nlat)
+ nlong = float(nlong)
+
+ x = (nlong - clong) * scale / dlat
+ y = (nlat - clat) * scale / dlat
+ vert = bm.verts.new((x, y, 0.0))
+ nmap[int(nid)] = vert
+ if tag :
+ metagid = []
+ for ch in node.childNodes:
+ if ch.localName == "tag":
+ key = ch.getAttribute('k')
+ val = ch.getAttribute('v')
+ if key in osmvals and val in osmvals[key] :
+ metagid.append(grouplookup[key])
+ metagid.append(grouplookup['_V_'+val])
+ weigths = vert[vgroups]
+ group = obj.vertex_groups.new('node_%s'%nid)
+ gid = len(obj.vertex_groups) -1
+ weigths[gid] = 1.0
+ for mid in metagid : weigths[mid] = 1.0
+
+ else : print('node is missing some elements : %s %s %s'%(nid,nlat,nlong))
+
+ tidx += 1
+ #if tidx > 1000:
+ # break
+ tidx += parseBranch(node.childNodes, bm, nmap, obj,scale,tag,UTM)
+
+ return tidx
+
+def read(context, filepath, scale=100.0, tag=False, utm=False) :
+ import bmesh
+ from xml.dom import minidom
+
+ # create mesh
+ bm = bmesh.new()
+ name = bpy.path.display_name_from_filepath(filepath)
+ me = bpy.data.meshes.new(name)
+ obj = bpy.data.objects.new(name, me)
+
+ # osm tags option
+ if tag :
+ tvid = 0
+ for gid, grname in enumerate(osmkeys) :
+ obj.vertex_groups.new('_'+grname)
+ grouplookup[grname] = gid + tvid
+ if grname in osmvals :
+ for val in osmvals[grname] :
+ tvid += 1
+ obj.vertex_groups.new('_V_'+val)
+ grouplookup['_V_'+val] = gid + tvid
+
+ # get xml then feed bmesh
+ print("Reading xml...")
+ xmldoc = minidom.parse(filepath)
+
+ print("Starting parse: %r..." % filepath)
+ nmap = {}
+ tidx = parseBranch(xmldoc.childNodes, bm, nmap, obj,scale,tag,utm)
+
+ bm.to_mesh(me)
+
+ # fast approximation of utm for not too big area
+ if utm is False :
+ global_matrix = Matrix(((0.65, 0.0, 0.0, 0.0),
+ (0.0, 1.0, 0.0, 0.0),
+ (0.0, 0.0, 1.0, 0.0),
+ (0.0, 0.0, 0.0, 1.0)))
+ me.transform(global_matrix)
+
+ # create the object in the scene
+ scene = context.scene
+ scene.objects.link(obj)
+ scene.objects.active = obj
+ obj.select = True
+
+ # entry points for other addons
+ obj['osmfile'] = filepath
+ obj['tagged'] = tag
+ obj['utm'] = utm
+
+ print("Parse done... %d" % tidx)
+
+ return {'FINISHED'}
+
+# given lat and longitude in degrees, returns x and y in UTM kilometers.
+# accuracy : supposed to be centimeter :)
+# http://fr.wikipedia.org/wiki/Projection_UTM
+# http://fr.wikipedia.org/wiki/WGS_84
+# http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
+# http://geodesie.ign.fr/contenu/fichiers/documentation/algorithmes/alg0071.pdf
+def geoToUTM(lon, lat) :
+
+ # if abs(lat) > 80 : lat = 80 #wrong coords.
+
+ # UTM zone, longitude origin, then lat lon in radians
+ z = int( (lon + 180) / 6 ) + 1
+ lon0 = radians(6*z - 183)
+ lat = radians(lat)
+ lon = radians(lon)
+
+ # CONSTANTS (see refs.)
+ # rayon de la terre à l'équateur
+ a = 6378.137
+ K0 = 0.9996
+ # flattening consts
+ f = 0.0033528106647474805 # 1 / 298.257223563
+ e2 = 0.0066943799901413165 # 2*f - f**2
+ e4 = 4.481472345240445e-05 # e2**2
+ e6 = 3.0000678794349315e-07 # e2**3
+
+ # lat0. 10000 for South, 0 for North
+ N0 = 10000 if lat < 0 else 0
+
+ # wiki is your friend (don't ask me Im just a writing monkey.)
+ A = (lon - lon0) * cos(lat)
+ C = (e2 / (1 - e2)) * cos(lat)**2
+ T = tan(lat)**2
+ vlat = 1 / sqrt( 1 - e2 * sin(lat)**2 )
+ slat = (1-(e2/4)-((3*e4)/64)-((5*e6)/256))*lat - (((3*e2)/8)+((3*e4)/32)+((45*e6)/1024))*sin(lat*2) + (((15*e4)/256) + ((45*e6)/1024) )*sin(lat*4) - ((35*e6)/3072)*sin(lat*6)
+ E = 500 + (K0 * a * vlat) * (A + (1-T+C)*((A**3)/6) + (5 - 18 * T + T**2) * ((A**5)/120) )
+ N = N0 + (K0 * a) * ( slat+vlat*tan(lat)* (A**2/2 + (5-T+9*C+4*C**2) * (A**4/24) + (61-58*T+T**2) * A**6/720) )
+ return E,N
+
+## for testing
+#if __name__ == "__main__":
+# read("/data/downloads/osm_parser/map.osm", bpy.context)
+
+
+# ----------------------------------------------------------------------------
+# blender integration
+
+from bpy.types import Operator
+from bpy_extras.io_utils import ImportHelper
+
+from bpy.props import StringProperty, FloatProperty, BoolProperty
+
+class ImportOSM(Operator, ImportHelper):
+ """Import OSM"""
+ #bl_idname = "import.open_street_map"
+ bl_idname = "import_mesh.osm"
+ bl_label = "Import OpenStreetMap (.osm)"
+
+ # ExportHelper mixin class uses this
+ filename_ext = ".osm"
+
+ filter_glob = StringProperty(
+ default="*.osm",
+ options={'HIDDEN'},
+ )
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+ scale = FloatProperty(
+ name="Scale",
+ default=100.0,
+ )
+
+ utm = BoolProperty(
+ name="in UTM coordinates",
+ default=True,
+ )
+
+ tag = BoolProperty(
+ name="retrieve .osm tags as vertex groups",
+ default=False,
+ )
+
+ def execute(self, context) :
+ return read(context, self.filepath, self.scale, self.tag, self.utm)
+
+
+# Only needed if you want to add into a dynamic menu
+def menu_func_export(self, context):
+ self.layout.operator(ImportOSM.bl_idname)
+
+
+def register():
+ bpy.utils.register_class(ImportOSM)
+ bpy.types.INFO_MT_file_import.append(menu_func_export)
+
+
+def unregister():
+ bpy.utils.unregister_class(ImportOSM)
+ bpy.types.INFO_MT_file_import.remove(menu_func_export)
diff --git a/release/scripts/addons_contrib/io_scene_x/__init__.py b/release/scripts/addons_contrib/io_scene_x/__init__.py
new file mode 100644
index 0000000..4ee29e0
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_x/__init__.py
@@ -0,0 +1,165 @@
+# ##### 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 3
+# 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, see <http://www.gnu.org/licenses/>.
+# All rights reserved.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "DirectX X Format",
+ "author": "Chris Foster",
+ "version": (3, 0, 0),
+ "blender": (2, 63, 0),
+ "location": "File > Export > DirectX (.x)",
+ "description": "Export mesh vertices, UV's, materials, textures, "\
+ "vertex colors, armatures, empties, and actions.",
+ "warning": "This script is a WIP!",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Import-Export/DirectX_Exporter",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=22795",
+ "category": "Import-Export"}
+
+import bpy
+from bpy.props import BoolProperty
+from bpy.props import EnumProperty
+from bpy.props import StringProperty
+
+
+class ExportDirectX(bpy.types.Operator):
+ """Export selection to DirectX"""
+
+ bl_idname = "export_scene.x"
+ bl_label = "Export DirectX"
+
+ filepath = StringProperty(subtype='FILE_PATH')
+
+ SelectedOnly = BoolProperty(
+ name="Export Selected Objects Only",
+ description="Export only selected objects",
+ default=True)
+
+ ApplyModifiers = BoolProperty(
+ name="Apply Modifiers",
+ description="Apply object modifiers before export",
+ default=False)
+
+ # XXX Change this stuff to property groups if possible
+ ExportMeshes = BoolProperty(
+ name="Export Meshes",
+ description="Export mesh objects",
+ default=True)
+
+ ExportNormals = BoolProperty(
+ name=" Export Normals",
+ description="Export mesh normals",
+ default=True)
+
+ ExportUVCoordinates = BoolProperty(
+ name=" Export UV Coordinates",
+ description="Export mesh UV coordinates, if any",
+ default=True)
+
+ ExportMaterials = BoolProperty(
+ name=" Export Materials",
+ description="Export material properties and reference image textures",
+ default=True)
+
+ #ExportVertexColors = BoolProperty(
+ # name=" Export Vertex Colors",
+ # description="Export mesh vertex colors, if any",
+ # default=False)
+
+ ExportSkinWeights = BoolProperty(
+ name=" Export Skin Weights",
+ description="Bind mesh vertices to armature bones",
+ default=False)
+
+ ExportArmatureBones = BoolProperty(
+ name="Export Armature Bones",
+ description="Export armatures bones",
+ default=False)
+
+ ExportRestBone = BoolProperty(
+ name=" Export Rest Position",
+ description="Export bones in their rest position (recommended for "\
+ "animation)",
+ default=False)
+
+ ExportAnimation = EnumProperty(
+ name="Animations",
+ description="Select the type of animations to export. Only object "\
+ "and armature bone animations can be exported. Full Animation "\
+ "exports every frame",
+ items=(
+ ('NONE', "None", ""),
+ ('KEYS', "Keyframes Only", ""),
+ ('FULL', "Full Animation", "")),
+ default='NONE')
+
+ IncludeFrameRate = BoolProperty(
+ name="Include Frame Rate",
+ description="Include the AnimTicksPerSecond template which is "\
+ "used by some engines to control animation speed",
+ default=False)
+
+ #ExportActionsAsSets = BoolProperty(
+ # name="Export Actions as AnimationSets",
+ # description="Export each action of each object as a separate "\
+ # "AnimationSet. Otherwise all current actions are lumped "\
+ # "together into a single set",
+ # default=False)
+
+ Verbose = BoolProperty(
+ name="Verbose",
+ description="Run the exporter in debug mode. Check the console for "\
+ "output",
+ default=False)
+
+ def execute(self, context):
+ self.filepath = bpy.path.ensure_ext(self.filepath, ".x")
+
+ import export_x
+ Exporter = export_x.DirectXExporter(self, context)
+ Exporter.Export() # XXX Rename this
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ if not self.filepath:
+ self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".x")
+ context.window_manager.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+
+def menu_func(self, context):
+ self.layout.operator(ExportDirectX.bl_idname, text="DirectX (.x)")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_file_export.append(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_file_export.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/io_scene_x/export_x.py b/release/scripts/addons_contrib/io_scene_x/export_x.py
new file mode 100644
index 0000000..1abb650
--- /dev/null
+++ b/release/scripts/addons_contrib/io_scene_x/export_x.py
@@ -0,0 +1,606 @@
+# ##### 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 3
+# 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, see <http://www.gnu.org/licenses/>.
+# All rights reserved.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+from math import radians
+
+import bpy
+from mathutils import *
+
+
+class DirectXExporter:
+ def __init__(self, Config, context):
+ self.Config = Config
+ self.context = context
+
+ self.File = File(self.Config.filepath)
+
+ self.Log("Setting up coordinate system...")
+ # SystemMatrix converts from right-handed, z-up to left-handed, y-up
+ self.SystemMatrix = (Matrix.Scale(-1, 4, Vector((0, 0, 1))) *
+ Matrix.Rotation(radians(-90), 4, 'X'))
+ self.Log("Done")
+
+ self.Log("Generating object lists for export...")
+ if self.Config.SelectedOnly:
+ ExportList = list(self.context.selected_objects)
+ else:
+ ExportList = list(self.context.scene.objects)
+
+ # ExportMap maps Blender objects to ExportObjects
+ self.ExportMap = {} # XXX Do we keep ExportMap around in self? Or should it be local?
+ for Object in ExportList:
+ if Object.type == 'EMPTY':
+ self.ExportMap[Object] = ExportObject(self.Config, self, Object)
+ elif Object.type == 'MESH':
+ self.ExportMap[Object] = MeshExportObject(self.Config, self,
+ Object)
+ elif Object.type == 'ARMATURE':
+ self.ExportMap[Object] = ArmatureExportObject(self.Config, self,
+ Object)
+
+ # Find the objects who do not have a parent or whose parent we are
+ # not exporting
+ self.RootExportList = [Object for Object in self.ExportMap.values()
+ if Object.BlenderObject.parent not in ExportList]
+ self.RootExportList = Util.SortByNameField(self.RootExportList)
+
+ # Determine each object's children from the pool of ExportObjects
+ for Object in self.ExportMap.values():
+ Children = Object.BlenderObject.children
+ Object.Children = []
+ for Child in Children:
+ if Child in self.ExportMap:
+ Object.Children.append(self.ExportMap[Child])
+ self.Log("Done")
+
+ # "Public" Interface
+
+ def Export(self):
+ self.Log("Exporting to {}".format(self.File.FilePath),
+ MessageVerbose=False)
+
+ self.Log("Opening file...")
+ self.File.Open()
+ self.Log("Done")
+
+ self.Log("Writing header...")
+ self.__WriteHeader()
+ self.Log("Done")
+
+ self.Log("Opening Root frame...")
+ self.__OpenRootFrame()
+ self.Log("Done")
+
+ self.Log("Writing objects...")
+ for Object in self.RootExportList:
+ Object.Write()
+ self.Log("Done")
+
+ self.Log("Closing Root frame...")
+ self.__CloseRootFrame()
+ self.Log("Done")
+
+ self.File.Close()
+
+ def Log(self, String, MessageVerbose=True):
+ if self.Config.Verbose is True or MessageVerbose == False:
+ print(String)
+
+ # "Private" Methods
+
+ def __WriteHeader(self):
+ self.File.Write("xof 0303txt 0032\n\n")
+
+ if self.Config.IncludeFrameRate:
+ self.File.Write("template AnimTicksPerSecond {\n\
+ <9E415A43-7BA6-4a73-8743-B73D47E88476>\n\
+ DWORD AnimTicksPerSecond;\n\
+}\n\n")
+ if self.Config.ExportSkinWeights:
+ self.File.Write("template XSkinMeshHeader {\n\
+ <3cf169ce-ff7c-44ab-93c0-f78f62d172e2>\n\
+ WORD nMaxSkinWeightsPerVertex;\n\
+ WORD nMaxSkinWeightsPerFace;\n\
+ WORD nBones;\n\
+}\n\n\
+template SkinWeights {\n\
+ <6f0d123b-bad2-4167-a0d0-80224f25fabb>\n\
+ STRING transformNodeName;\n\
+ DWORD nWeights;\n\
+ array DWORD vertexIndices[nWeights];\n\
+ array float weights[nWeights];\n\
+ Matrix4x4 matrixOffset;\n\
+}\n\n")
+
+ # Start the Root frame and write its transform matrix
+ def __OpenRootFrame(self):
+ self.File.Write("Frame Root {\n")
+ self.File.Indent()
+
+ self.File.Write("FrameTransformMatrix {\n")
+ self.File.Indent()
+ Util.WriteMatrix(self.File, self.SystemMatrix)
+ self.File.Unindent()
+ self.File.Write("}\n")
+
+ def __CloseRootFrame(self):
+ self.File.Unindent()
+ self.File.Write("} // End of Root\n")
+
+
+class ExportObject:
+ def __init__(self, Config, Exporter, BlenderObject):
+ self.Config = Config
+ self.Exporter = Exporter
+ self.BlenderObject = BlenderObject
+
+ self.name = self.BlenderObject.name # Simple alias
+ self.SafeName = Util.SafeName(self.BlenderObject.name)
+ self.Children = []
+
+ def __repr__(self):
+ return "[ExportObject: {}]".format(self.BlenderObject.name)
+
+ # "Public" Interface
+
+ def Write(self):
+ self._OpenFrame()
+
+ self._WriteChildren()
+
+ self._CloseFrame()
+
+ # "Protected" Interface
+
+ def _OpenFrame(self):
+ self.Exporter.File.Write("Frame {} {{\n".format(self.SafeName))
+ self.Exporter.File.Indent()
+
+ self.Exporter.File.Write("FrameTransformMatrix {\n")
+ self.Exporter.File.Indent()
+ Util.WriteMatrix(self.Exporter.File, self.BlenderObject.matrix_local)
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}\n")
+
+ def _CloseFrame(self):
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}} // End of {}\n".format(self.SafeName))
+
+ def _WriteChildren(self):
+ for Child in Util.SortByNameField(self.Children):
+ Child.Write()
+
+
+class MeshExportObject(ExportObject):
+ def __init__(self, Config, Exporter, BlenderObject):
+ ExportObject.__init__(self, Config, Exporter, BlenderObject)
+
+ def __repr__(self):
+ return "[MeshExportObject: {}]".format(self.BlenderObject.name)
+
+ # "Public" Interface
+
+ def Write(self):
+ self._OpenFrame()
+
+ if self.Exporter.Config.ExportMeshes:
+ # Generate the export mesh
+ Mesh = None
+ if self.Config.ApplyModifiers:
+ Mesh = self.BlenderObject.to_mesh(self.Exporter.context.scene,
+ True, 'PREVIEW')
+ else:
+ Mesh = self.BlenderObject.to_mesh(self.Exporter.context.scene,
+ False, 'PREVIEW')
+
+ self.__WriteMesh(Mesh)
+
+ self._WriteChildren()
+
+ self._CloseFrame()
+
+ # "Private" Methods
+
+ def __WriteMesh(self, Mesh):
+ self.Exporter.File.Write("Mesh {{ // {} mesh\n".format(self.SafeName))
+ self.Exporter.File.Indent()
+
+ if (self.Exporter.Config.ExportUVCoordinates and Mesh.uv_textures):# or \
+ #self.Exporter.Config.ExportVertexColors: XXX
+ VertexCount = 0
+ for Polygon in Mesh.polygons:
+ VertexCount += len(Polygon.vertices)
+
+ # Write vertex positions
+ Index = 0
+ self.Exporter.File.Write("{};\n".format(VertexCount))
+ for Polygon in Mesh.polygons:
+ Vertices = list(Polygon.vertices)[::-1]
+
+ for Vertex in [Mesh.vertices[Vertex] for Vertex in Vertices]:
+ Position = Vertex.co
+ self.Exporter.File.Write("{:9f};{:9f};{:9f};".format(
+ Position[0], Position[1], Position[2]))
+ Index += 1
+ if Index == VertexCount:
+ self.Exporter.File.Write(";\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+
+ # Write face definitions
+ Index = 0
+ self.Exporter.File.Write("{};\n".format(len(Mesh.polygons)))
+ for Polygon in Mesh.polygons:
+ self.Exporter.File.Write("{};".format(len(Polygon.vertices)))
+ for Vertex in Polygon.vertices:
+ self.Exporter.File.Write("{};".format(Index), Indent=False)
+ Index += 1
+ if Index == VertexCount:
+ self.Exporter.File.Write(";\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+ else:
+ # Write vertex positions
+ self.Exporter.File.Write("{};\n".format(len(Mesh.vertices)))
+ for Index, Vertex in enumerate(Mesh.vertices):
+ Position = Vertex.co
+ self.Exporter.File.Write("{:9f};{:9f};{:9f};".format(
+ Position[0], Position[1], Position[2]))
+ if Index == len(Mesh.vertices) - 1:
+ self.Exporter.File.Write(";\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+
+ # Write face definitions
+ self.Exporter.File.Write("{};\n".format(len(Mesh.polygons)))
+ for Index, Polygon in enumerate(Mesh.polygons):
+ # Change the winding order of the face
+ Vertices = list(Polygon.vertices)[::-1]
+
+ self.Exporter.File.Write("{};".format(len(Vertices)))
+ for Vertex in Vertices:
+ self.Exporter.File.Write("{};".format(Vertex), Indent=False)
+ if Index == len(Mesh.polygons) - 1:
+ self.Exporter.File.Write(";\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+
+ if self.Exporter.Config.ExportNormals:
+ self.__WriteMeshNormals(Mesh)
+
+ if self.Exporter.Config.ExportUVCoordinates:
+ self.__WriteMeshUVCoordinates(Mesh)
+
+ if self.Exporter.Config.ExportMaterials:
+ self.__WriteMeshMaterials(Mesh)
+
+ #if self.Exporter.Config.ExportVertexColor:
+ # self.__WriteMeshVertexColors(Mesh)
+
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}} // End of {} mesh\n".format(self.SafeName))
+
+ def __WriteMeshNormals(self, Mesh):
+ self.Exporter.File.Write("MeshNormals {{ // {} normals\n".format(
+ self.SafeName))
+ self.Exporter.File.Indent()
+
+ # Determine the number of normals to write
+ NormalCount = 0
+ for Polygon in Mesh.polygons:
+ if Polygon.use_smooth:
+ NormalCount += len(Polygon.vertices)
+ else:
+ NormalCount += 1
+
+ # Write mesh normals
+ self.Exporter.File.Write("{};\n".format(NormalCount))
+ NormalIndex = 0
+ for Polygon in Mesh.polygons:
+ # If the face is faceted, write the face normal only once
+ if not Polygon.use_smooth:
+ Normal = Polygon.normal
+ self.Exporter.File.Write("{:9f};{:9f};{:9f};".format(Normal[0],
+ Normal[1], Normal[2]))
+ NormalIndex += 1
+ if NormalIndex < NormalCount:
+ self.Exporter.File.Write(",\n", Indent=False)
+ # Otherwise, write each vertex normal
+ else:
+ # Change the winding order of the face
+ VertexNormals = [Mesh.vertices[Vertex].normal for Vertex in
+ Polygon.vertices][::-1]
+ for Normal in VertexNormals:
+ self.Exporter.File.Write("{:9f};{:9f};{:9f};".format(
+ Normal[0], Normal[1], Normal[2]))
+ NormalIndex += 1
+ if NormalIndex < NormalCount:
+ self.Exporter.File.Write(",\n", Indent=False)
+ self.Exporter.File.Write(";\n", Indent=False)
+
+ # Write face definitions
+ self.Exporter.File.Write("{};\n".format(len(Mesh.polygons)))
+ NormalIndex = 0
+ for Polygon in Mesh.polygons:
+ VertexCount = len(Polygon.vertices)
+ self.Exporter.File.Write("{};".format(VertexCount))
+ # If the face is faceted, use the normal at Index for each vertex
+ if not Polygon.use_smooth:
+ VertexIndices = [NormalIndex] * VertexCount
+ NormalIndex += 1
+ # Otherwise, use the next couple normals for the face
+ else:
+ VertexIndices = list(range(NormalIndex,
+ NormalIndex + VertexCount))
+ NormalIndex += VertexCount
+ # Write the indices for the face
+ for VertexIndex in VertexIndices:
+ self.Exporter.File.Write("{};".format(VertexIndex),
+ Indent=False)
+ if NormalIndex == NormalCount:
+ self.Exporter.File.Write(";\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}} // End of {} normals\n".format(
+ self.SafeName))
+
+ def __WriteMeshUVCoordinates(self, Mesh):
+ if not Mesh.uv_textures:
+ return
+
+ self.Exporter.File.Write("MeshTextureCoords {{ // {} UV coordinates\n".
+ format(self.SafeName))
+ self.Exporter.File.Indent()
+
+ UVCoordinates = Mesh.uv_layers.active.data
+
+ VertexCount = 0
+ for Polygon in Mesh.polygons:
+ VertexCount += len(Polygon.vertices)
+
+ Index = 0
+ self.Exporter.File.Write("{};\n".format(VertexCount))
+ for Polygon in Mesh.polygons:
+ Vertices = []
+ for Vertex in [UVCoordinates[Vertex] for Vertex in
+ Polygon.loop_indices]:
+ Vertices.append(tuple(Vertex.uv))
+ for Vertex in Vertices:
+ self.Exporter.File.Write("{:9f};{:9f};".format(Vertex[0],
+ Vertex[1]))
+ Index += 1
+ if Index == VertexCount:
+ self.Exporter.File.Write(";\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}} // End of {} UV coordinates\n".format(
+ self.SafeName))
+
+ def __WriteMeshMaterials(self, Mesh):
+ def WriteMaterial(Exporter, Material):
+ def GetMaterialTextureFileName(Material):
+ if Material:
+ # Create a list of Textures that have type 'IMAGE'
+ ImageTextures = [Material.texture_slots[TextureSlot].texture
+ for TextureSlot in Material.texture_slots.keys()
+ if Material.texture_slots[TextureSlot].texture.type ==
+ 'IMAGE']
+ # Refine to only image file names if applicable
+ ImageFiles = [bpy.path.basename(Texture.image.filepath)
+ for Texture in ImageTextures
+ if getattr(Texture.image, "source", "") == 'FILE']
+ if ImageFiles:
+ return ImageFiles[0]
+ return None
+
+ Exporter.File.Write("Material {} {{\n".format(
+ Util.SafeName(Material.name)))
+ Exporter.File.Indent()
+
+ Diffuse = list(Vector(Material.diffuse_color) *
+ Material.diffuse_intensity)
+ Diffuse.append(Material.alpha)
+ # Map Blender's range of 1 - 511 to 0 - 1000
+ Specularity = 1000 * (Material.specular_hardness - 1.0) / 510.0
+ Specular = list(Vector(Material.specular_color) *
+ Material.specular_intensity)
+
+ Exporter.File.Write("{:9f};{:9f};{:9f};{:9f};;\n".format(Diffuse[0],
+ Diffuse[1], Diffuse[2], Diffuse[3]))
+ Exporter.File.Write(" {:9f};\n".format(Specularity))
+ Exporter.File.Write("{:9f};{:9f};{:9f};;\n".format(Specular[0],
+ Specular[1], Specular[2]))
+ Exporter.File.Write(" 0.000000; 0.000000; 0.000000;;\n")
+
+ TextureFileName = GetMaterialTextureFileName(Material)
+ if TextureFileName:
+ Exporter.File.Write("TextureFilename {{\"{}\";}}\n".format(
+ TextureFileName))
+
+ Exporter.File.Unindent()
+ Exporter.File.Write("}\n");
+
+ Materials = Mesh.materials
+ # Do not write materials if there are none
+ if not Materials.keys():
+ return
+
+ self.Exporter.File.Write("MeshMaterialList {{ // {} material list\n".
+ format(self.SafeName))
+ self.Exporter.File.Indent()
+
+ self.Exporter.File.Write("{};\n".format(len(Materials)))
+ self.Exporter.File.Write("{};\n".format(len(Mesh.polygons)))
+ for Index, Polygon in enumerate(Mesh.polygons):
+ self.Exporter.File.Write("{}".format(Polygon.material_index))
+ if Index == len(Mesh.polygons) - 1:
+ self.Exporter.File.Write(";;\n", Indent=False)
+ else:
+ self.Exporter.File.Write(",\n", Indent=False)
+
+ for Material in Materials:
+ WriteMaterial(self.Exporter, Material)
+
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}} // End of {} material list\n".format(
+ self.SafeName))
+
+ def __WriteMeshVertexColors(self, Mesh):
+ pass
+
+ def __WriteMeshSkinWeights(self, Mesh):
+ ArmatureModifierList = [Modifier for Modifier in Object.modifiers
+ if Modifier.type == 'ARMATURE']
+
+ if not ArmatureModifierList:
+ return
+
+ pass
+
+
+class ArmatureExportObject(ExportObject):
+ def __init__(self, Config, Exporter, BlenderObject):
+ ExportObject.__init__(self, Config, Exporter, BlenderObject)
+
+ def __repr__(self):
+ return "[ArmatureExportObject: {}]".format(self.BlenderObject.name)
+
+ # "Public" Interface
+
+ def Write(self):
+ self._OpenFrame()
+
+ if self.Config.ExportArmatureBones:
+ Armature = self.BlenderObject.data
+ RootBones = [Bone for Bone in Armature.bones if Bone.parent is None]
+ self.__WriteBones(RootBones)
+
+ self._WriteChildren()
+
+ self._CloseFrame()
+
+ # "Private" Methods
+
+ def __WriteBones(self, Bones):
+ for Bone in Bones:
+ BoneMatrix = Matrix()
+
+ PoseBone = self.BlenderObject.pose.bones[Bone.name]
+ if Bone.parent:
+ BoneMatrix = PoseBone.parent.matrix.inverted()
+ BoneMatrix *= PoseBone.matrix
+
+ BoneSafeName = Util.SafeName(Bone.name)
+ self.__OpenBoneFrame(BoneSafeName, BoneMatrix)
+
+ self.__WriteBoneChildren(Bone)
+
+ self.__CloseBoneFrame(BoneSafeName)
+
+
+ def __OpenBoneFrame(self, BoneSafeName, BoneMatrix):
+ self.Exporter.File.Write("Frame {} {{\n".format(BoneSafeName))
+ self.Exporter.File.Indent()
+
+ self.Exporter.File.Write("FrameTransformMatrix {\n")
+ self.Exporter.File.Indent()
+ Util.WriteMatrix(self.Exporter.File, BoneMatrix)
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}\n")
+
+ def __CloseBoneFrame(self, BoneSafeName):
+ self.Exporter.File.Unindent()
+ self.Exporter.File.Write("}} // End of {}\n".format(BoneSafeName))
+
+ def __WriteBoneChildren(self, Bone):
+ self.__WriteBones(Util.SortByNameField(Bone.children))
+
+
+class File:
+ def __init__(self, FilePath):
+ self.FilePath = FilePath
+ self.File = None
+ self.__Whitespace = 0
+
+ def Open(self):
+ if not self.File:
+ self.File = open(self.FilePath, 'w')
+
+ def Close(self):
+ self.File.close()
+ self.File = None
+
+ def Write(self, String, Indent=True):
+ if Indent:
+ # Escape any formatting braces
+ String = String.replace("{", "{{")
+ String = String.replace("}", "}}")
+ self.File.write(("{}" + String).format(" " * self.__Whitespace))
+ else:
+ self.File.write(String)
+
+ def Indent(self, Levels=1):
+ self.__Whitespace += Levels
+
+ def Unindent(self, Levels=1):
+ self.__Whitespace -= Levels
+ if self.__Whitespace < 0:
+ self.__Whitespace = 0
+
+
+class Util:
+ @staticmethod
+ def SafeName(Name):
+ # Replaces each character in OldSet with NewChar
+ def ReplaceSet(String, OldSet, NewChar):
+ for OldChar in OldSet:
+ String = String.replace(OldChar, NewChar)
+ return String
+
+ import string
+
+ NewName = ReplaceSet(Name, string.punctuation + " ", "_")
+ if NewName[0].isdigit() or NewName in ["ARRAY", "DWORD", "UCHAR",
+ "FLOAT", "ULONGLONG", "BINARY_RESOURCE", "SDWORD", "UNICODE",
+ "CHAR", "STRING", "WORD", "CSTRING", "SWORD", "DOUBLE", "TEMPLATE"]:
+ NewName = "_" + NewName
+ return NewName
+
+ @staticmethod
+ def WriteMatrix(File, Matrix):
+ File.Write("{:9f},{:9f},{:9f},{:9f},\n".format(Matrix[0][0],
+ Matrix[1][0], Matrix[2][0], Matrix[3][0]))
+ File.Write("{:9f},{:9f},{:9f},{:9f},\n".format(Matrix[0][1],
+ Matrix[1][1], Matrix[2][1], Matrix[3][1]))
+ File.Write("{:9f},{:9f},{:9f},{:9f},\n".format(Matrix[0][2],
+ Matrix[1][2], Matrix[2][2], Matrix[3][2]))
+ File.Write("{:9f},{:9f},{:9f},{:9f};;\n".format(Matrix[0][3],
+ Matrix[1][3], Matrix[2][3], Matrix[3][3]))
+
+ @staticmethod
+ def SortByNameField(List):
+ def SortKey(x):
+ return x.name
+
+ return sorted(List, key=SortKey)
diff --git a/release/scripts/addons_contrib/lamp_geographical_sun.py b/release/scripts/addons_contrib/lamp_geographical_sun.py
new file mode 100644
index 0000000..36a3cb8
--- /dev/null
+++ b/release/scripts/addons_contrib/lamp_geographical_sun.py
@@ -0,0 +1,581 @@
+# -*- coding: utf-8 -*-
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# --------------------------------------------------------------------------
+# Blender 2.5 Geographical Sun Add-On
+# --------------------------------------------------------------------------
+#
+# Authors:
+# Doug Hammond
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# ***** END GPL LICENCE BLOCK *****
+#
+
+# System imports
+#-----------------------------------------------------------------------------
+import datetime, math, time
+today = datetime.datetime.now()
+
+# Blender imports
+#-----------------------------------------------------------------------------
+import bpy
+from extensions_framework import Addon, declarative_property_group
+from extensions_framework.ui import property_group_renderer
+
+# Addon setup
+#-----------------------------------------------------------------------------
+bl_info = {
+ "name": "Geographical Sun",
+ "author": "Doug Hammond (dougal2)",
+ "version": (0, 0, 1),
+ "blender": (2, 56, 0),
+ "category": "Object",
+ "location": "Lamp data > Geographical Sun",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "description": "Set SUN Lamp rotation according to geographical time and location."
+}
+GeoSunAddon = Addon(bl_info)
+
+# Sun rotation calculator implementation
+#-----------------------------------------------------------------------------
+class sun_calculator(object):
+ """
+ Based on SunLight v1.0 by Miguel Kabantsov (miguelkab at gmail.com)
+ Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand),
+ Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
+ Author: Nils-Peter Fischer (Nils-Peter.Fischer at web.de)
+ """
+
+ location_list = [
+ ("EUROPE",[
+ ("Antwerp, Belgium", 67),
+ ("Berlin, Germany", 1),
+ ("Bratislava, Slovak Republic", 70),
+ ("Brno, Czech Republic", 72),
+ ("Brussles, Belgium", 68),
+ ("Geneva, Switzerland", 65),
+ ("Helsinki, Finland", 7),
+ ("Innsbruck, Austria", 62),
+ ("Kyiv, Ukraine", 64),
+ ("London, England", 10),
+ ("Lyon, France", 66),
+ ("Nitra, Slovak Republic", 69),
+ ("Oslo, Norway", 58),
+ ("Paris, France", 15),
+ ("Praha, Czech Republic", 71),
+ ("Rome, Italy", 18),
+ ("Telfs, Austria", 63),
+ ("Warsaw, Poland", 74),
+ ("Wroclaw, Poland", 73),
+ ("Zurich, Switzerland", 21),
+ ]),
+
+ ("WORLD CITIES", [
+ ("Beijing, China", 0),
+ ("Bombay, India", 2),
+ ("Buenos Aires, Argentina", 3),
+ ("Cairo, Egypt", 4),
+ ("Cape Town, South Africa", 5),
+ ("Caracas, Venezuela", 6),
+ ("Curitiba, Brazil", 60),
+ ("Hong Kong, China", 8),
+ ("Jerusalem, Israel", 9),
+ ("Joinville, Brazil", 61),
+ ("Mexico City, Mexico", 11),
+ ("Moscow, Russia", 12),
+ ("New Delhi, India", 13),
+ ("Ottawa, Canada", 14),
+ ("Rio de Janeiro, Brazil", 16),
+ ("Riyadh, Saudi Arabia", 17),
+ ("Sao Paulo, Brazil", 59),
+ ("Sydney, Australia", 19),
+ ("Tokyo, Japan", 20),
+ ]),
+
+ ("US CITIES", [
+ ("Albuquerque, NM", 22),
+ ("Anchorage, AK", 23),
+ ("Atlanta, GA", 24),
+ ("Austin, TX", 25),
+ ("Birmingham, AL", 26),
+ ("Bismarck, ND", 27),
+ ("Boston, MA", 28),
+ ("Boulder, CO", 29),
+ ("Chicago, IL", 30),
+ ("Dallas, TX", 31),
+ ("Denver, CO", 32),
+ ("Detroit, MI", 33),
+ ("Honolulu, HI", 34),
+ ("Houston, TX", 35),
+ ("Indianapolis, IN", 36),
+ ("Jackson, MS", 37),
+ ("Kansas City, MO", 38),
+ ("Los Angeles, CA", 39),
+ ("Menomonee Falls, WI", 40),
+ ("Miami, FL", 41),
+ ("Minneapolis, MN", 42),
+ ("New Orleans, LA", 43),
+ ("New York City, NY", 44),
+ ("Oklahoma City, OK", 45),
+ ("Philadelphia, PA", 46),
+ ("Phoenix, AZ", 47),
+ ("Pittsburgh, PA", 48),
+ ("Portland, ME", 49),
+ ("Portland, OR", 50),
+ ("Raleigh, NC", 51),
+ ("Richmond, VA", 52),
+ ("Saint Louis, MO", 53),
+ ("San Diego, CA", 54),
+ ("San Francisco, CA", 55),
+ ("Seattle, WA", 56),
+ ("Washington DC", 57),
+ ])
+ ]
+
+ location_data = {
+ # Europe
+ 67: ( 51.2167, -4.4, 1),
+ 1: ( 52.33, -13.30, 1),
+ 70: ( 48.17, -17.17, 1),
+ 72: ( 49.2, -16.63, 1),
+ 68: ( 58.8467, -4.3525, 1),
+ 65: ( 46.217, -6.150, 1),
+ 7: ( 60.1667, -24.9667,2),
+ 62: ( 47.2672, -11.3928, 1),
+ 64: ( 50.75, -30.0833, 2),
+ 10: ( 51.50, 0.0, 0),
+ 66: ( 45.767, -4.833, 1),
+ 69: ( 48.32, -18.07, 1),
+ 58: ( 59.56, -10.41, 1),
+ 15: ( 48.8667, -2.667, 1),
+ 71: ( 50.08, -14.46, 1),
+ 18: ( 41.90, -12.4833, 1),
+ 63: ( 47.3, -11.0667, 1),
+ 74: ( 52.232, -21.008, 1),
+ 73: ( 51.108, -17.038, 1),
+ 21: ( 47.3833, -8.5333, 1),
+
+ # World Cities
+ 0: ( 39.9167, -116.4167, 8),
+ 2: ( 18.9333, -72.8333, 5.5),
+ 3: (-34.60, 58.45, -3),
+ 4: ( 30.10, -31.3667, 2),
+ 5: (-33.9167, -18.3667, 2),
+ 6: ( 10.50, 66.9333, -4),
+ 60: (-25.4278, 49.2731, -3),
+ 8: ( 22.25, -114.1667, 8),
+ 9: ( 31.7833, -35.2333, 2),
+ 61: (-29.3044, 48.8456, -3),
+ 11: ( 19.4, 99.15, -6),
+ 12: ( 55.75, -37.5833, 3),
+ 13: ( 28.6, -77.2, 5.5),
+ 14: ( 45.41667, 75.7, -5),
+ 16: (-22.90, 43.2333, -3),
+ 17: ( 24.633, -46.71667, 3),
+ 59: ( -23.5475, 46.6361, -3),
+ 19: (-33.8667, -151.2167,10),
+ 20: ( 35.70, -139.7667, 9),
+
+ # US Cities
+ 22: ( 35.0833, 106.65, -7),
+ 23: ( 61.217, 149.90, -9),
+ 24: ( 33.733, 84.383, -5),
+ 25: ( 30.283, 97.733, -6),
+ 26: ( 33.521, 86.8025, -6),
+ 27: ( 46.817, 100.783, -6),
+ 28: ( 42.35, 71.05, -5),
+ 29: ( 40.125, 105.237, -7),
+ 30: ( 41.85, 87.65, -6),
+ 31: ( 32.46, 96.47, -6),
+ 32: ( 39.733, 104.983, -7),
+ 33: ( 42.333, 83.05, -5),
+ 34: ( 21.30, 157.85, -10),
+ 35: ( 29.75, 95.35, -6),
+ 36: ( 39.767, 86.15, -5),
+ 37: ( 32.283, 90.183, -6),
+ 38: ( 39.083, 94.567, -6),
+ 39: ( 34.05, 118.233, -8),
+ 40: ( 43.11, 88.10, -6),
+ 41: ( 25.767, 80.183, -5),
+ 42: ( 44.967, 93.25, -6),
+ 43: ( 29.95, 90.067, -6),
+ 44: ( 40.7167, 74.0167, -5),
+ 45: ( 35.483, 97.533, -6),
+ 46: ( 39.95, 75.15, -5),
+ 47: ( 33.433, 112.067,-7),
+ 48: ( 40.433, 79.9833, -5),
+ 49: ( 43.666, 70.283, -5),
+ 50: ( 45.517, 122.65, -8),
+ 51: ( 35.783, 78.65, -5),
+ 52: ( 37.5667, 77.450, -5),
+ 53: ( 38.6167, 90.1833, -6),
+ 54: ( 32.7667, 117.2167, -8),
+ 55: ( 37.7667, 122.4167, -8),
+ 56: ( 47.60, 122.3167, -8),
+ 57: ( 38.8833, 77.0333, -5),
+ }
+
+ # mathematical helpers
+ @staticmethod
+ def sind(deg):
+ return math.sin(math.radians(deg))
+
+ @staticmethod
+ def cosd(deg):
+ return math.cos(math.radians(deg))
+
+ @staticmethod
+ def tand(deg):
+ return math.tan(math.radians(deg))
+
+ @staticmethod
+ def asind(deg):
+ return math.degrees(math.asin(deg))
+
+ @staticmethod
+ def atand(deg):
+ return math.degrees(math.atan(deg))
+
+ @staticmethod
+ def geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone):
+ if Month > 2.0:
+ Y = Year
+ M = Month
+ else:
+ Y = Year - 1.0
+ M = Month + 12.0
+
+ UT = LocalTime - Timezone
+ hour = UT / 24.0
+ A = int(Y/100.0)
+
+ JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour - 1524.4
+
+ # The following section is adopted from netCDF4 netcdftime implementation.
+ # Copyright: 2008 by Jeffrey Whitaker
+ # License: http://www.opensource.org/licenses/mit-license.php
+ if JD >= 2299170.5:
+ # 1582 October 15 (Gregorian Calendar)
+ B = 2.0 - A + int(A/4.0)
+ elif JD < 2299160.5:
+ # 1582 October 5 (Julian Calendar)
+ B = 0
+ else:
+ raise Exception('ERROR: Date falls in the gap between Julian and Gregorian calendars.')
+ B = 0
+
+ return JD+B
+
+ @staticmethod
+ def geoSunData(Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
+ JD = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
+
+ phi = Latitude
+ llambda = Longitude
+
+ n = JD - 2451545.0
+ LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
+ gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
+ LambdaDeg = LDeg + 1.915 * sun_calculator.sind(gDeg) + 0.02 * sun_calculator.sind(2.0*gDeg)
+
+ epsilonDeg = 23.439 - 0.0000004*n
+
+ alphaDeg = sun_calculator.atand( (sun_calculator.cosd(epsilonDeg) * sun_calculator.sind(LambdaDeg)) / sun_calculator.cosd(LambdaDeg) )
+ if sun_calculator.cosd(LambdaDeg) < 0.0:
+ alphaDeg += 180.0
+
+ deltaDeg = sun_calculator.asind( sun_calculator.sind(epsilonDeg) * sun_calculator.sind(LambdaDeg) )
+
+ JDNull = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
+
+ TNull = (JDNull - 2451545.0) / 36525.0
+ T = LocalTime - Timezone
+
+ thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
+ thetaGh -= math.floor(thetaGh/24.0) * 24.0
+
+ thetaG = thetaGh * 15.0
+ theta = thetaG + llambda
+
+ tau = theta - alphaDeg
+
+ a = sun_calculator.atand( sun_calculator.sind(tau) / ( sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi)) )
+ if sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi) < 0.0:
+ a += 180.0
+
+ h = sun_calculator.asind( sun_calculator.cosd(deltaDeg)*sun_calculator.cosd(tau)*sun_calculator.cosd(phi) + sun_calculator.sind(deltaDeg)*sun_calculator.sind(phi) )
+
+ R = 1.02 / (sun_calculator.tand (h+(10.3/(h+5.11))))
+ hR = h + R/60.0
+
+ azimuth = a
+ elevation = hR
+
+ return azimuth, elevation
+
+# Addon classes
+#-----------------------------------------------------------------------------
+ at GeoSunAddon.addon_register_class
+class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator):
+ bl_idname = 'object.set_geographical_sun_now'
+ bl_label = 'Set time to NOW'
+
+ @classmethod
+ def poll(cls, context):
+ cl = context.lamp
+ return cl and cl.type == 'SUN'
+
+ def execute(self, context):
+ GSP = context.lamp.GeoSunProperties
+
+ now = datetime.datetime.now()
+ for p in ("hour", "minute", "day", "month", "year"):
+ setattr(
+ GSP,
+ p,
+ getattr(now, p)
+ )
+ GSP.tz = time.timezone
+ GSP.dst = False
+
+ return {'FINISHED'}
+
+ at GeoSunAddon.addon_register_class
+class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator):
+ bl_idname = 'object.set_geographical_sun_pos'
+ bl_label = 'Set SUN position'
+
+ @classmethod
+ def poll(cls, context):
+ cl = context.lamp
+ return cl and cl.type == 'SUN'
+
+ def execute(self, context):
+ try:
+ GSP = context.lamp.GeoSunProperties
+
+ dst = 1 if GSP.dst else 0
+
+ az,el = sun_calculator.geoSunData(
+ GSP.lat,
+ GSP.long,
+ GSP.year,
+ GSP.month,
+ GSP.day,
+ GSP.hour + GSP.minute/60.0,
+ -GSP.tz + dst
+ )
+
+ context.object.rotation_euler = ( math.radians(90-el), 0, math.radians(-az) )
+ return {'FINISHED'}
+ except Exception as err:
+ self.report({'ERROR'}, str(err))
+ return {'CANCELLED'}
+
+ at GeoSunAddon.addon_register_class
+class OBJECT_OT_set_geographical_location_preset(bpy.types.Operator):
+ bl_idname = 'object.set_geographical_location_preset'
+ bl_label = 'Apply location preset'
+
+ index = bpy.props.IntProperty()
+
+ @classmethod
+ def poll(cls, context):
+ cl = context.lamp
+ return cl and cl.type == 'SUN'
+
+ def execute(self, context):
+ GSP = context.lamp.GeoSunProperties
+ GSP.lat, GSP.long, GSP.tz = sun_calculator.location_data[self.properties.index]
+ return {'FINISHED'}
+
+# Dynamic submenu magic !
+
+def draw_generator(locations):
+ def draw(self, context):
+ sl = self.layout
+ for location in locations:
+ location_name, location_index = location
+ sl.operator('OBJECT_OT_set_geographical_location_preset', text=location_name).index = location_index
+ return draw
+
+submenus = []
+for label, locations in sun_calculator.location_list:
+ submenu_idname = 'OBJECT_MT_geo_sun_location_cat%d'%len(submenus)
+ submenu = type(
+ submenu_idname,
+ (bpy.types.Menu,),
+ {
+ 'bl_idname': submenu_idname,
+ 'bl_label': label,
+ 'draw': draw_generator(locations)
+ }
+ )
+ GeoSunAddon.addon_register_class(submenu)
+ submenus.append(submenu)
+
+ at GeoSunAddon.addon_register_class
+class OBJECT_MT_geo_sun_location(bpy.types.Menu):
+ bl_label = 'Location preset'
+
+ def draw(self, context):
+ sl = self.layout
+ for sm in submenus:
+ sl.menu(sm.bl_idname)
+
+ at GeoSunAddon.addon_register_class
+class GeoSunProperties(declarative_property_group):
+ ef_attach_to = ['Lamp']
+
+ controls = [
+ ['hour', 'minute'],
+ ['day', 'month', 'year'],
+ ['tz', 'dst'],
+ 'location_menu',
+ ['lat', 'long'],
+ ['set_time', 'set_posn'],
+ ]
+
+ properties = [
+ {
+ 'type': 'int',
+ 'attr': 'minute',
+ 'name': 'Minute',
+ 'min': 0,
+ 'soft_min': 0,
+ 'max': 59,
+ 'soft_max': 59,
+ 'default': today.minute
+ },
+ {
+ 'type': 'int',
+ 'attr': 'hour',
+ 'name': 'Hour',
+ 'min': 0,
+ 'soft_min': 0,
+ 'max': 24,
+ 'soft_max': 24,
+ 'default': today.hour
+ },
+ {
+ 'type': 'int',
+ 'attr': 'day',
+ 'name': 'Day',
+ 'min': 1,
+ 'soft_min': 1,
+ 'max': 31,
+ 'soft_max': 31,
+ 'default': today.day
+ },
+ {
+ 'type': 'int',
+ 'attr': 'month',
+ 'name': 'Month',
+ 'min': 1,
+ 'soft_min': 1,
+ 'max': 12,
+ 'soft_max': 12,
+ 'default': today.month
+ },
+ {
+ 'type': 'int',
+ 'attr': 'year',
+ 'name': 'Year',
+ 'min': datetime.MINYEAR,
+ 'soft_min': datetime.MINYEAR,
+ 'max': datetime.MAXYEAR,
+ 'soft_max': datetime.MAXYEAR,
+ 'default': today.year
+ },
+ {
+ 'type': 'int',
+ 'attr': 'tz',
+ 'name': 'Time zone',
+ 'min': -13,
+ 'soft_min': -13,
+ 'max': 13,
+ 'soft_max': 13,
+ 'default': time.timezone
+ },
+ {
+ 'type': 'bool',
+ 'attr': 'dst',
+ 'name': 'DST',
+ 'default': False
+ },
+ {
+ 'type': 'float',
+ 'attr': 'lat',
+ 'name': 'Lat.',
+ 'min': -180.0,
+ 'soft_min': -180.0,
+ 'max': 180.0,
+ 'soft_max': 180.0,
+ 'default': 0.0
+ },
+ {
+ 'type': 'float',
+ 'attr': 'long',
+ 'name': 'Long.',
+ 'min': -90.0,
+ 'soft_min': -90.0,
+ 'max': 90.0,
+ 'soft_max': 90.0,
+ 'default': 0.0
+ },
+
+ # draw operators and menus
+ {
+ 'attr': 'location_menu',
+ 'type': 'menu',
+ 'menu': 'OBJECT_MT_geo_sun_location'
+ },
+ {
+ 'attr': 'set_time',
+ 'type': 'operator',
+ 'operator': 'object.set_geographical_sun_now',
+ 'icon': 'PREVIEW_RANGE'
+ },
+ {
+ 'attr': 'set_posn',
+ 'type': 'operator',
+ 'operator': 'object.set_geographical_sun_pos',
+ 'icon': 'WORLD_DATA'
+ },
+ ]
+
+ at GeoSunAddon.addon_register_class
+class GeoSunPanel(property_group_renderer):
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'data'
+ bl_label = 'Geographical Sun'
+
+ display_property_groups = [
+ ( ('lamp',), 'GeoSunProperties' )
+ ]
+
+ @classmethod
+ def poll(cls, context):
+ cl = context.lamp
+ return cl and cl.type == 'SUN'
+
+# Bootstrap the Addon
+#-----------------------------------------------------------------------------
+register, unregister = GeoSunAddon.init_functions()
diff --git a/release/scripts/addons_contrib/mesh_copy_uvs_from_joined.py b/release/scripts/addons_contrib/mesh_copy_uvs_from_joined.py
new file mode 100644
index 0000000..b883e30
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_copy_uvs_from_joined.py
@@ -0,0 +1,211 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Copy UV's from Joined",
+ "description": "Copy UV coordinates from the active joined mesh",
+ "author": "Sergey Sharybin",
+ "version": (0, 1),
+ "blender": (2, 63, 0),
+ "location": "Object mode 'Make Links' menu",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+import bpy
+from bpy.types import Operator
+from mathutils import Vector
+
+FLT_MAX = 30000.0
+KEY_PRECISION = 1
+
+
+def MINMAX_INIT():
+ return (Vector((+FLT_MAX, +FLT_MAX, +FLT_MAX)),
+ Vector((-FLT_MAX, -FLT_MAX, -FLT_MAX)))
+
+
+def MINMAX_DO(min, max, vec):
+ for x in range(3):
+ if vec[x] < min[x]:
+ min[x] = vec[x]
+
+ if vec[x] > max[x]:
+ max[x] = vec[x]
+
+
+def getObjectAABB(obj):
+ min, max = MINMAX_INIT()
+
+ matrix = obj.matrix_world.copy()
+ for vec in obj.bound_box:
+ v = matrix * Vector(vec)
+ MINMAX_DO(min, max, v)
+
+ return min, max
+
+
+class OBJECT_OT_copy_uv_from_joined(Operator):
+ """
+ Copy UVs from joined objects into originals
+ """
+
+ bl_idname = "object.copy_uv_from_joined"
+ bl_label = "Copy UVs from Joined"
+
+ def _findTranslation(self, obact, objects):
+ """
+ Find a translation from original objects to joined
+ """
+
+ bb_joined = getObjectAABB(obact)
+ bb_orig = MINMAX_INIT()
+
+ for ob in objects:
+ if ob != obact:
+ bb = getObjectAABB(ob)
+ MINMAX_DO(bb_orig[0], bb_orig[1], bb[0])
+ MINMAX_DO(bb_orig[0], bb_orig[1], bb[1])
+
+ return bb_joined[0] - bb_orig[0]
+
+ def _getPolygonMedian(self, me, poly):
+ median = Vector()
+ verts = me.vertices
+
+ for vert_index in poly.vertices:
+ median += verts[vert_index].co
+
+ median /= len(poly.vertices)
+
+ return median
+
+ def _getVertexLookupMap(self, obact, objects):
+ """
+ Create a vertex lookup map from joined object space to original object
+ """
+
+ uv_map = {}
+
+ T = self._findTranslation(obact, objects)
+
+ for obj in objects:
+ if obj != obact:
+ me = obj.data
+ mat = obj.matrix_world.copy()
+ uv_layer = me.uv_layers.active
+
+ for poly in me.polygons:
+ center = mat * self._getPolygonMedian(me, poly) + T
+ center_key = center.to_tuple(KEY_PRECISION)
+
+ for loop_index in poly.loop_indices:
+ loop = me.loops[loop_index]
+ vert = me.vertices[loop.vertex_index]
+ vec = mat * vert.co + T
+
+ key = (center_key, vec.to_tuple(KEY_PRECISION))
+
+ uv_map.setdefault(key, []).append((center, vec, (uv_layer, loop_index)))
+
+ return uv_map
+
+ def execute(self, context):
+ obact = context.object
+
+ # Check wether we're working with meshes
+ # other object types are not supported
+ if obact.type != 'MESH':
+ self.report({'ERROR'}, "Only meshes are supported")
+ return {'CANCELLED'}
+
+ objects = context.selected_objects
+
+ for obj in context.selected_objects:
+ if obj.type != 'MESH':
+ self.report({'ERROR'}, "Only meshes are supported")
+ return {'CANCELLED'}
+
+ uv_map = self._getVertexLookupMap(obact, objects)
+
+ me = obact.data
+ mat = obact.matrix_world.copy()
+ uv_layer = me.uv_layers.active
+
+ for poly in me.polygons:
+ center = mat * self._getPolygonMedian(me, poly)
+ center_key = center.to_tuple(KEY_PRECISION)
+
+ for loop_index in poly.loop_indices:
+ loop = me.loops[loop_index]
+ vert = me.vertices[loop.vertex_index]
+ vec = mat * vert.co
+
+ key = (center_key, vec.to_tuple(KEY_PRECISION))
+ check_list = uv_map.get(key)
+
+ if check_list is not None:
+ new_uv = None
+ closest_data = None
+
+ dist = FLT_MAX
+ for x in check_list:
+ cur_center, cur_vec, data = x
+
+ d1 = Vector(cur_center) - Vector(center)
+ d2 = Vector(cur_vec) - Vector(vec)
+
+ d = d1.length_squared + d2.length_squared
+
+ if d < dist:
+ closest_data = data
+ dist = d
+
+ if closest_data is not None:
+ orig_uv_layer, orig_loop_index = closest_data
+ new_uv = uv_layer.data[loop_index].uv
+ orig_uv_layer.data[orig_loop_index].uv = new_uv
+ else:
+ print("Failed to lookup %r" % key)
+
+ return {'FINISHED'}
+
+
+def menu_func(self, context):
+ self.layout.operator("OBJECT_OT_copy_uv_from_joined",
+ text="Join as UVs (active to other selected)",
+ icon="PLUGIN")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.VIEW3D_MT_make_links.append(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.VIEW3D_MT_make_links.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_discombobulator.py b/release/scripts/addons_contrib/mesh_discombobulator.py
new file mode 100644
index 0000000..ea50729
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_discombobulator.py
@@ -0,0 +1,685 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Discombobulator",
+ "description": "Its job is to easily add scifi details to a surface to create nice-looking space-ships or futuristic cities.",
+ "author": "Evan J. Rosky (syrux), Chichiri, Jace Priester",
+ "version": (0,2),
+ "blender": (2, 64, 0),
+ "location": "Spacebar > Discombobulate",
+ "warning": 'Beta',
+ 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts',
+ 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
+ 'func=detail&aid=31390',
+ "category": "Mesh"}
+
+import bpy
+import random
+import mathutils
+import math
+from mathutils import *
+
+doprots = True
+
+# Datas in which we will build the new discombobulated mesh
+nPolygons = []
+nVerts = []
+Verts = []
+Polygons = []
+dVerts = []
+dPolygons = []
+i_prots = [] # index of the top polygons on whow we will generate the doodads
+i_dood_type = [] # type of doodad (given by index of the doodad obj)
+
+bpy.types.Scene.DISC_doodads = []
+
+def randnum(a, b):
+ return random.random()*(b-a)+a
+
+def randVertex(a, b, c, d, Verts):
+ """Return a vector of a random vertex on a quad-polygon"""
+ i = random.randint(1,2)
+ A, B, C, D = 0, 0, 0, 0
+ if(a==1):
+ A, B, C, D = a, b, c, d
+ else:
+ A, B, C, D = a, d, c, b
+
+ i = randnum(0.1, 0.9)
+
+
+ vecAB=Verts[B]-Verts[A]
+ E=Verts[A]+vecAB*i
+
+ vecDC=Verts[C]-Verts[D]
+ F=Verts[D]+vecDC*i
+
+ i = randnum(0.1, 0.9)
+ vecEF=F-E
+
+ O=E+vecEF*i
+ return O
+
+################################ Protusions ###################################
+
+def fill_older_datas(verts, polygon):
+ """ Specifically coded to be called by the function addProtusionToPolygon, its sets up a tuple which contains the vertices from the base and the top of the protusions. """
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ return temp_vertices
+
+def extrude_top(temp_vertices, normal, height):
+ """ This function extrude the polygon composed of the four first members of the tuple temp_vertices along the normal multiplied by the height of the extrusion."""
+ j = 0
+ while j < 3:
+ temp_vertices[0][j]+=normal[j]*height
+ temp_vertices[1][j]+=normal[j]*height
+ temp_vertices[2][j]+=normal[j]*height
+ temp_vertices[3][j]+=normal[j]*height
+ j+=1
+
+def scale_top(temp_vertices, center, normal, height, scale_ratio):
+ """ This function scale the polygon composed of the four first members of the tuple temp_vertices. """
+ vec1 = [0, 0, 0]
+ vec2 = [0, 0, 0]
+ vec3 = [0, 0, 0]
+ vec4 = [0, 0, 0]
+
+ j = 0
+ while j < 3:
+ center[j]+=normal[j]*height
+ vec1[j] = temp_vertices[0][j] - center[j]
+ vec2[j] = temp_vertices[1][j] - center[j]
+ vec3[j] = temp_vertices[2][j] - center[j]
+ vec4[j] = temp_vertices[3][j] - center[j]
+ temp_vertices[0][j] = center[j] + vec1[j]*(1-scale_ratio)
+ temp_vertices[1][j] = center[j] + vec2[j]*(1-scale_ratio)
+ temp_vertices[2][j] = center[j] + vec3[j]*(1-scale_ratio)
+ temp_vertices[3][j] = center[j] + vec4[j]*(1-scale_ratio)
+ j+=1
+
+def add_prot_polygons(temp_vertices):
+ """ Specifically coded to be called by addProtusionToPolygon, this function put the data from the generated protusion at the end the tuples Verts and Polygons, which will later used to generate the final mesh. """
+ global Verts
+ global Polygons
+ global i_prots
+
+ findex = len(Verts)
+ Verts+=temp_vertices
+
+ polygontop = [findex+0, findex+1, findex+2, findex+3]
+ polygon1 = [findex+0, findex+1, findex+5, findex+4]
+ polygon2 = [findex+1, findex+2, findex+6, findex+5]
+ polygon3 = [findex+2, findex+3, findex+7, findex+6]
+ polygon4 = [findex+3, findex+0, findex+4, findex+7]
+
+ Polygons.append(polygontop)
+ i_prots.append(len(Polygons)-1)
+ Polygons.append(polygon1)
+ Polygons.append(polygon2)
+ Polygons.append(polygon3)
+ Polygons.append(polygon4)
+
+def addProtusionToPolygon(obpolygon, verts, minHeight, maxHeight, minTaper, maxTaper):
+ """Create a protusion from the polygon "obpolygon" of the original object and use several values sent by the user. It calls in this order the following functions:
+ - fill_older_data;
+ - extrude_top;
+ - scale_top;
+ - add_prot_polygons;
+ """
+ # some useful variables
+ polygon = obpolygon.vertices
+ polygontop = polygon
+ polygon1 = []
+ polygon2 = []
+ polygon3 = []
+ polygon4 = []
+ vertices = []
+ tVerts = list(fill_older_datas(verts, polygon)) # list of temp vertices
+ height = randnum(minHeight, maxHeight) # height of generated protusion
+ scale_ratio = randnum(minTaper, maxTaper)
+
+ # extrude the top polygon
+ extrude_top(tVerts, obpolygon.normal, height)
+ # Now, we scale, the top polygon along its normal
+ scale_top(tVerts, GetPolyCentroid(obpolygon,verts), obpolygon.normal, height, scale_ratio)
+ # Finally, we add the protusions to the list of polygons
+ add_prot_polygons(tVerts)
+
+################################## Divide a polygon ##################################
+
+def divide_one(list_polygons, list_vertices, verts, polygon, findex):
+ """ called by divide_polygon, to generate a polygon from one polygon, maybe I could simplify this process """
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+1, findex+2, findex+3])
+
+def divide_two(list_polygons, list_vertices, verts, polygon, findex):
+ """ called by divide_polygon, to generate two polygons from one polygon and add them to the list of polygons and vertices which form the discombobulated mesh"""
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[1]])/2)
+ temp_vertices.append((verts[polygon[2]]+verts[polygon[3]])/2)
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+4, findex+5, findex+3])
+ list_polygons.append([findex+1, findex+2, findex+5, findex+4])
+
+def divide_three(list_polygons, list_vertices, verts, polygon, findex, center):
+ """ called by divide_polygon, to generate three polygons from one polygon and add them to the list of polygons and vertices which form the discombobulated mesh"""
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[1]])/2)
+ temp_vertices.append((verts[polygon[2]]+verts[polygon[3]])/2)
+ temp_vertices.append((verts[polygon[1]]+verts[polygon[2]])/2)
+ temp_vertices.append(center.copy())
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+4, findex+5, findex+3])
+ list_polygons.append([findex+1, findex+6, findex+7, findex+4])
+ list_polygons.append([findex+6, findex+2, findex+5, findex+7])
+
+def divide_four(list_polygons, list_vertices, verts, polygon, findex, center):
+ """ called by divide_polygon, to generate four polygons from one polygon and add them to the list of polygons and vertices which form the discombobulated mesh"""
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[1]])/2)
+ temp_vertices.append((verts[polygon[2]]+verts[polygon[3]])/2)
+ temp_vertices.append((verts[polygon[1]]+verts[polygon[2]])/2)
+ temp_vertices.append(center.copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[3]])/2)
+ temp_vertices.append(center.copy())
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+4, findex+7, findex+8])
+ list_polygons.append([findex+1, findex+6, findex+7, findex+4])
+ list_polygons.append([findex+6, findex+2, findex+5, findex+7])
+ list_polygons.append([findex+8, findex+7, findex+5, findex+3])
+
+def dividepolygon(obpolygon, verts, number):
+ """Divide the poly into the wanted number of polygons"""
+ global nPolygons
+ global nVerts
+
+ poly = obpolygon.vertices
+ tVerts = []
+
+ if(number==1):
+ divide_one(nPolygons, nVerts, verts, poly, len(nVerts))
+ elif(number==2):
+ divide_two(nPolygons, nVerts, verts, poly, len(nVerts))
+ elif(number==3):
+ divide_three(nPolygons, nVerts, verts, poly, len(nVerts), GetPolyCentroid(obpolygon,verts))
+ elif(number==4):
+ divide_four(nPolygons, nVerts, verts, poly, len(nVerts), GetPolyCentroid(obpolygon,verts))
+
+############################### Discombobulate ################################
+
+def GetPolyCentroid(obpolygon,allvertcoords):
+ centroid=mathutils.Vector((0,0,0))
+ for vindex in obpolygon.vertices:
+ centroid+=mathutils.Vector(allvertcoords[vindex])
+ centroid/=len(obpolygon.vertices)
+ return centroid
+
+def division(obpolygons, verts, sf1, sf2, sf3, sf4):
+ """Function to divide each of the selected polygons"""
+ divide = []
+ if(sf1): divide.append(1)
+ if(sf2): divide.append(2)
+ if(sf3): divide.append(3)
+ if(sf4): divide.append(4)
+ for poly in obpolygons:
+ if(poly.select == True and len(poly.vertices)==4):
+ a = random.randint(0, len(divide)-1)
+ dividepolygon(poly, verts, divide[a])
+
+def protusion(obverts, obpolygons, minHeight, maxHeight, minTaper, maxTaper):
+ """function to generate the protusions"""
+ verts = []
+ for vertex in obverts:
+ verts.append(vertex.co)
+
+ for polygon in obpolygons:
+ if(polygon.select == True):
+ if(len(polygon.vertices) == 4):
+ addProtusionToPolygon(polygon, verts, minHeight, maxHeight, minTaper, maxTaper)
+
+def test_v2_near_v1(v1, v2):
+ if(v1.x - 0.1 <= v2.x <= v1.x + 0.1
+ and v1.y - 0.1 <= v2.y <= v1.y + 0.1
+ and v1.z - 0.1 <= v2.z <= v1.z + 0.1):
+ return True
+
+ return False
+
+def angle_between_nor(nor_orig, nor_result):
+ angle = math.acos(nor_orig.dot(nor_result))
+ axis = nor_orig.cross(nor_result).normalized()
+
+ q = mathutils.Quaternion()
+ q.x = axis.x*math.sin(angle/2)
+ q.y = axis.y*math.sin(angle/2)
+ q.z = axis.z*math.sin(angle/2)
+ q.w = math.cos(angle/2)
+
+ return q
+
+def doodads(object1, mesh1, dmin, dmax):
+ """function to generate the doodads"""
+ global dVerts
+ global dPolygons
+ i = 0
+ # on parcoure cette boucle pour ajouter des doodads a toutes les polygons
+ # english translation: this loops adds doodads to all polygons
+ while(i<len(object1.data.polygons)):
+ if object1.data.polygons[i].select==False:
+ continue
+ doods_nbr = random.randint(dmin, dmax)
+ j = 0
+ while(j<=doods_nbr):
+ origin_dood = randVertex(object1.data.polygons[i].vertices[0], object1.data.polygons[i].vertices[1], object1.data.polygons[i].vertices[2], object1.data.polygons[i].vertices[3], Verts)
+ type_dood = random.randint(0, len(bpy.context.scene.DISC_doodads)-1)
+ polygons_add = []
+ verts_add = []
+
+ # First we have to apply scaling and rotation to the mesh
+ bpy.ops.object.select_pattern(pattern=bpy.context.scene.DISC_doodads[type_dood],extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]]
+ bpy.ops.object.transform_apply(rotation=True, scale=True)
+
+ for polygon in bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]].data.polygons:
+ polygons_add.append(polygon.vertices)
+ for vertex in bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]].data.vertices:
+ verts_add.append(vertex.co.copy())
+ normal_original_polygon = object1.data.polygons[i].normal
+
+ nor_def = mathutils.Vector((0.0, 0.0, 1.0))
+ qr = nor_def.rotation_difference(normal_original_polygon.normalized())
+
+ case_z = False
+ if(test_v2_near_v1(nor_def, -normal_original_polygon)):
+ case_z = True
+ qr = mathutils.Quaternion((0.0, 0.0, 0.0, 0.0))
+ #qr = angle_between_nor(nor_def, normal_original_polygon)
+ for vertex in verts_add:
+ vertex.rotate(qr)
+ vertex+=origin_dood
+ findex = len(dVerts)
+ for polygon in polygons_add:
+ dPolygons.append([polygon[0]+findex, polygon[1]+findex, polygon[2]+findex, polygon[3]+findex])
+ i_dood_type.append(bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]].name)
+ for vertex in verts_add:
+ dVerts.append(vertex)
+ j+=1
+ i+=5
+
+def protusions_repeat(object1, mesh1, r_prot):
+
+ for j in i_prots:
+ if j<len(object1.data.polygons):
+ object1.data.polygons[j].select=True
+ else:
+ print("Warning: hit end of polygons in object1")
+
+# add material to discombobulated mesh
+def setMatProt(discObj, origObj, sideProtMat, topProtMat):
+ # First we put the materials in their slots
+ bpy.ops.object.select_pattern(pattern = discObj.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[discObj.name]
+ try:
+ origObj.material_slots[topProtMat]
+ origObj.material_slots[sideProtMat]
+ except:
+ return
+
+ bpy.ops.object.material_slot_add()
+ bpy.ops.object.material_slot_add()
+ discObj.material_slots[0].material = origObj.material_slots[topProtMat].material
+ discObj.material_slots[1].material = origObj.material_slots[sideProtMat].material
+
+ # Then we assign materials to protusions
+ for polygon in discObj.data.polygons:
+ if polygon.index in i_prots:
+ polygon.material_index = 0
+ else:
+ polygon.material_index = 1
+
+def setMatDood(doodObj):
+ # First we add the materials slots
+ bpy.ops.object.select_pattern(pattern = doodObj.name,extend=False)
+ bpy.context.scene.objects.active=doodObj
+ for name in bpy.context.scene.DISC_doodads:
+ try:
+ bpy.ops.object.material_slot_add()
+ doodObj.material_slots[-1].material = bpy.data.objects[name].material_slots[0].material
+ for polygon in doodObj.data.polygons:
+ if i_dood_type[polygon.index] == name:
+ polygon.material_index = len(doodObj.material_slots)-1
+ except:
+ print()
+
+
+def clean_doodads():
+ current_doodads=list(bpy.context.scene.DISC_doodads)
+
+ for name in current_doodads:
+ if name not in bpy.data.objects:
+ bpy.context.scene.DISC_doodads.remove(name)
+
+
+def discombobulate(minHeight, maxHeight, minTaper, maxTaper, sf1, sf2, sf3, sf4, dmin, dmax, r_prot, sideProtMat, topProtMat, isLast):
+ global doprots
+ global nVerts
+ global nPolygons
+ global Verts
+ global Polygons
+ global dVerts
+ global dPolygons
+ global i_prots
+
+
+ bpy.ops.object.mode_set(mode="OBJECT")
+
+
+ #start by cleaning up doodads that don't exist anymore
+ clean_doodads()
+
+
+ # Create the discombobulated mesh
+ mesh = bpy.data.meshes.new("tmp")
+ object = bpy.data.objects.new("tmp", mesh)
+ bpy.context.scene.objects.link(object)
+
+ # init final verts and polygons tuple
+ nPolygons = []
+ nVerts = []
+ Polygons = []
+ Verts = []
+ dPolygons = []
+ dVerts = []
+
+ origObj = bpy.context.active_object
+
+ # There we collect the rotation, translation and scaling datas from the original mesh
+ to_translate = bpy.context.active_object.location
+ to_scale = bpy.context.active_object.scale
+ to_rotate = bpy.context.active_object.rotation_euler
+
+ # First, we collect all the informations we will need from the previous mesh
+ obverts = bpy.context.active_object.data.vertices
+ obpolygons = bpy.context.active_object.data.polygons
+ verts = []
+ for vertex in obverts:
+ verts.append(vertex.co)
+
+ division(obpolygons, verts, sf1, sf2, sf3, sf4)
+
+ # Fill in the discombobulated mesh with the new polygons
+ mesh.from_pydata(nVerts, [], nPolygons)
+ mesh.update(calc_edges = True)
+
+ # Reload the datas
+ bpy.ops.object.select_all(action="DESELECT")
+ bpy.ops.object.select_pattern(pattern = object.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object.name]
+ obverts = bpy.context.active_object.data.vertices
+ obpolygons = bpy.context.active_object.data.polygons
+
+ protusion(obverts, obpolygons, minHeight, maxHeight, minTaper, maxTaper)
+
+ # Fill in the discombobulated mesh with the new polygons
+ mesh1 = bpy.data.meshes.new("discombobulated_object")
+ object1 = bpy.data.objects.new("discombobulated_mesh", mesh1)
+ bpy.context.scene.objects.link(object1)
+ mesh1.from_pydata(Verts, [], Polygons)
+ mesh1.update(calc_edges = True)
+
+
+ # Set the material's of discombobulated object
+ setMatProt(object1, origObj, sideProtMat, topProtMat)
+
+ bpy.ops.object.select_pattern(pattern = object1.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object1.name]
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.normals_make_consistent(inside=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ #if(bpy.context.scene.repeatprot):
+ protusions_repeat(object1, mesh1, r_prot)
+
+ if(len(bpy.context.scene.DISC_doodads) != 0 and bpy.context.scene.dodoodads and isLast):
+ doodads(object1, mesh1, dmin, dmax)
+ mesh2 = bpy.data.meshes.new("dood_mesh")
+ object2 = bpy.data.objects.new("dood_obj", mesh2)
+ bpy.context.scene.objects.link(object2)
+ mesh2.from_pydata(dVerts, [], dPolygons)
+ mesh2.update(calc_edges = True)
+ setMatDood(object2)
+ object2.location = to_translate
+ object2.rotation_euler = to_rotate
+ object2.scale = to_scale
+
+ bpy.ops.object.select_pattern(pattern = object.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object.name]
+ bpy.ops.object.delete()
+
+ bpy.ops.object.select_pattern(pattern=object1.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object1.name]
+ bpy.context.scene.update()
+
+ # translate, scale and rotate discombobulated results
+ object1.location = to_translate
+ object1.rotation_euler = to_rotate
+ object1.scale = to_scale
+
+ #set all polys to selected. this allows recursive discombobulating.
+ for poly in mesh1.polygons:
+ poly.select=True
+
+############ Operator to select and deslect an object as a doodad ###############
+
+class chooseDoodad(bpy.types.Operator):
+ bl_idname = "object.discombobulate_set_doodad"
+ bl_label = "Discombobulate set doodad object"
+
+ def execute(self, context):
+ bpy.context.scene.DISC_doodads.append(bpy.context.active_object.name)
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+class unchooseDoodad(bpy.types.Operator):
+ bl_idname = "object.discombobulate_unset_doodad"
+ bl_label = "Discombobulate unset doodad object"
+
+ def execute(self, context):
+ for name in bpy.context.scene.DISC_doodads:
+ if name == bpy.context.active_object.name:
+ bpy.context.scene.DISC_doodads.remove(name)
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+################################## Interpolygon ####################################
+
+class discombobulator(bpy.types.Operator):
+ bl_idname = "object.discombobulate"
+ bl_label = "Discombobulate"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ scn = context.scene
+ i=0
+ while i<scn.repeatprot:
+ isLast=False
+ if i==scn.repeatprot-1:
+ isLast=True
+ discombobulate(scn.minHeight, scn.maxHeight, scn.minTaper, scn.maxTaper, scn.subpolygon1, scn.subpolygon2, scn.subpolygon3, scn.subpolygon4, scn.mindoodads, scn.maxdoodads, scn.repeatprot, scn.sideProtMat, scn.topProtMat, isLast)
+ i+=1
+ return {'FINISHED'}
+
+class discombob_help(bpy.types.Operator):
+ bl_idname = 'help.discombobulator'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Works with Quads only not Ngons.')
+ layout.label('Select a face or faces')
+ layout.label('Press Discombobulate to create greebles')
+
+
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+
+class VIEW3D_PT_tools_discombobulate(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Discombobulator"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row = layout.split(0.80)
+ row.operator('object.discombobulate', text = 'Discombobulate', icon = 'PLUGIN')
+ row.operator('help.discombobulator', icon = 'INFO')
+ box = layout.box()
+ box.label("Protusions settings")
+ row = box.row()
+ row.prop(context.scene, 'doprots')
+ row = box.row()
+ row.prop(context.scene, 'minHeight')
+ row = box.row()
+ row.prop(context.scene, 'maxHeight')
+ row = box.row()
+ row.prop(context.scene, 'minTaper')
+ row = box.row()
+ row.prop(context.scene, 'maxTaper')
+ row = box.row()
+ col1 = row.column(align = True)
+ col1.prop(context.scene, "subpolygon1")
+ col2 = row.column(align = True)
+ col2.prop(context.scene, "subpolygon2")
+ col3 = row.column(align = True)
+ col3.prop(context.scene, "subpolygon3")
+ col4 = row.column(align = True)
+ col4.prop(context.scene, "subpolygon4")
+ row = box.row()
+ row.prop(context.scene, "repeatprot")
+ box = layout.box()
+ box.label("Doodads settings")
+ row = box.row()
+ row.prop(context.scene, 'dodoodads')
+ row = box.row()
+ row.prop(context.scene, "mindoodads")
+ row = box.row()
+ row.prop(context.scene, "maxdoodads")
+ row = box.row()
+ row.operator("object.discombobulate_set_doodad", text = "Pick doodad")
+ row = box.row()
+ row.operator("object.discombobulate_unset_doodad", text = "Remove doodad")
+ col = box.column(align = True)
+ for name in bpy.context.scene.DISC_doodads:
+ col.label(text = name)
+ box = layout.box()
+ box.label("Materials settings")
+ row = box.row()
+ row.prop(context.scene, 'topProtMat')
+ row = box.row()
+ row.prop(context.scene, "sideProtMat")
+ row = box.row()
+
+# registering and menu integration
+def register():
+ # Protusions Buttons:
+ bpy.types.Scene.repeatprot = bpy.props.IntProperty(name="Repeat protusions", description="make several layers of protusion", default = 1, min = 1, max = 10)
+ bpy.types.Scene.doprots = bpy.props.BoolProperty(name="Make protusions", description = "Check if we want to add protusions to the mesh", default = True)
+ bpy.types.Scene.polygonschangedpercent = bpy.props.FloatProperty(name="Polygon %", description = "Percentage of changed polygons", default = 1.0)
+ bpy.types.Scene.minHeight = bpy.props.FloatProperty(name="Min height", description="Minimal height of the protusions", default=0.2)
+ bpy.types.Scene.maxHeight = bpy.props.FloatProperty(name="Max height", description="Maximal height of the protusions", default = 0.4)
+ bpy.types.Scene.minTaper = bpy.props.FloatProperty(name="Min taper", description="Minimal height of the protusions", default=0.15, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.maxTaper = bpy.props.FloatProperty(name="Max taper", description="Maximal height of the protusions", default = 0.35, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.subpolygon1 = bpy.props.BoolProperty(name="1", default = True)
+ bpy.types.Scene.subpolygon2 = bpy.props.BoolProperty(name="2", default = True)
+ bpy.types.Scene.subpolygon3 = bpy.props.BoolProperty(name="3", default = True)
+ bpy.types.Scene.subpolygon4 = bpy.props.BoolProperty(name="4", default = True)
+
+ # Doodads buttons:
+ bpy.types.Scene.dodoodads = bpy.props.BoolProperty(name="Make doodads", description = "Check if we want to generate doodads", default = True)
+ bpy.types.Scene.mindoodads = bpy.props.IntProperty(name="Minimum doodads number", description = "Ask for the minimum number of doodads to generate per polygon", default = 1, min = 0, max = 50)
+ bpy.types.Scene.maxdoodads = bpy.props.IntProperty(name="Maximum doodads number", description = "Ask for the maximum number of doodads to generate per polygon", default = 6, min = 1, max = 50)
+ bpy.types.Scene.doodMinScale = bpy.props.FloatProperty(name="Scale min", description="Minimum scaling of doodad", default = 0.5, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.doodMaxScale = bpy.props.FloatProperty(name="Scale max", description="Maximum scaling of doodad", default = 1.0, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+
+ # Materials buttons:
+ bpy.types.Scene.sideProtMat = bpy.props.IntProperty(name="Side's prot mat", description = "Material of protusion's sides", default = 0, min = 0)
+ bpy.types.Scene.topProtMat = bpy.props.IntProperty(name = "Prot's top mat", description = "Material of protusion's top", default = 0, min = 0)
+
+ bpy.utils.register_class(discombobulator)
+ bpy.utils.register_class(chooseDoodad)
+ bpy.utils.register_class(unchooseDoodad)
+ bpy.utils.register_class(VIEW3D_PT_tools_discombobulate)
+ bpy.utils.register_class(discombob_help)
+
+# unregistering and removing menus
+def unregister():
+ bpy.utils.unregister_class(discombobulator)
+ bpy.utils.unregister_class(chooseDoodad)
+ bpy.utils.unregister_class(unchooseDoodad)
+ bpy.utils.unregister_class(VIEW3D_PT_tools_discombobulate)
+ bpy.utils.unregister_class(discombob_help)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_edge_intersection_tools.py b/release/scripts/addons_contrib/mesh_edge_intersection_tools.py
new file mode 100644
index 0000000..389bfdb
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_edge_intersection_tools.py
@@ -0,0 +1,332 @@
+'''
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+END GPL LICENCE BLOCK
+'''
+
+bl_info = {
+ "name": "Edge tools : tinyCAD VTX",
+ "author": "zeffii",
+ "version": (0, 5, 1),
+ "blender": (2, 56, 0),
+ "category": "Mesh",
+ "location": "View3D > EditMode > (w) Specials",
+ "warning": "Still under development",
+ "wiki_url": "http://wiki.blender.org/index.php/"\
+ "Extensions:2.6/Py/Scripts/Modeling/Edge_Slice",
+ "tracker_url": "http://projects.blender.org/tracker/"\
+ "?func=detail&aid=25227"
+ }
+
+"""
+parts based on Keith (Wahooney) Boshoff, cursor to intersection script and
+Paul Bourke's Shortest Line Between 2 lines, and thanks to PKHG from BA.org
+for attempting to explain things to me that i'm not familiar with.
+TODO: [ ] allow multi selection ( > 2 ) for Slice/Weld intersection mode
+TODO: [ ] streamline this code !
+
+1) Edge Extend To Edge ( T )
+2) Edge Slice Intersecting ( X )
+3) Edge Project Converging ( V )
+
+"""
+
+import bpy
+import sys
+from mathutils import Vector, geometry
+from mathutils.geometry import intersect_line_line as LineIntersect
+
+VTX_PRECISION = 1.0e-5 # or 1.0e-6 ..if you need
+
+# returns distance between two given points
+def mDist(A, B): return (A-B).length
+
+
+# returns True / False if a point happens to lie on an edge
+def isPointOnEdge(point, A, B):
+ eps = ((mDist(A, B) - mDist(point,B)) - mDist(A,point))
+ if abs(eps) < VTX_PRECISION: return True
+ else:
+ print('distance is ' + str(eps))
+ return False
+
+
+# returns the number of edges that a point lies on.
+def CountPointOnEdges(point, outer_points):
+ count = 0
+ if(isPointOnEdge(point, outer_points[0][0], outer_points[0][1])): count+=1
+ if(isPointOnEdge(point, outer_points[1][0], outer_points[1][1])): count+=1
+ return count
+
+
+# takes Vector List and returns tuple of points in expected order.
+def edges_to_points(edges):
+ (vp1, vp2) = (Vector((edges[0][0])), Vector((edges[0][1])))
+ (vp3, vp4) = (Vector((edges[1][0])), Vector((edges[1][1])))
+ return (vp1,vp2,vp3,vp4)
+
+
+# takes a list of 4 vectors and returns True or False depending on checks
+def checkIsMatrixCoplanar(verti):
+ (v1, v2, v3, v4) = edges_to_points(verti) #unpack
+ shortest_line = LineIntersect(v1, v2, v3, v4)
+ if mDist(shortest_line[1], shortest_line[0]) > VTX_PRECISION: return False
+ else: return True
+
+
+# point = the halfway mark on the shortlest line between two lines
+def checkEdges(Edge, obj):
+ (p1, p2, p3, p4) = edges_to_points(Edge)
+ line = LineIntersect(p1, p2, p3, p4)
+ point = ((line[0] + line[1]) / 2) # or point = line[0]
+ return point
+
+# returns (object, number of verts, number of edges) && object mode == True
+def GetActiveObject():
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.delete(type='EDGE') # removes edges + verts
+ (vert_count, edge_count) = getVertEdgeCount()
+ (vert_num, edge_num) = (len(vert_count),len(edge_count))
+
+ bpy.ops.object.mode_set(mode='OBJECT') # to be sure.
+ o = bpy.context.active_object
+ return (o, vert_num, edge_num)
+
+
+def AddVertsToObject(vert_count, o, mvX, mvA, mvB, mvC, mvD):
+ o.data.vertices.add(5)
+ pointlist = [mvX, mvA, mvB, mvC, mvD]
+ for vpoint in range(len(pointlist)):
+ o.data.vertices[vert_count+vpoint].co = pointlist[vpoint]
+
+
+# Used when the user chooses to slice/Weld, vX is intersection point
+def makeGeometryWeld(vX,outer_points):
+ (o, vert_count, edge_count) = GetActiveObject()
+ (vA, vB, vC, vD) = edges_to_points(outer_points)
+ AddVertsToObject(vert_count, o, vA, vX, vB, vC, vD) # o is the object
+
+ oe = o.data.edges
+ oe.add(4)
+ oe[edge_count].vertices = [vert_count,vert_count+1]
+ oe[edge_count+1].vertices = [vert_count+2,vert_count+1]
+ oe[edge_count+2].vertices = [vert_count+3,vert_count+1]
+ oe[edge_count+3].vertices = [vert_count+4,vert_count+1]
+
+
+# Used for extending an edge to a point on another edge.
+def ExtendEdge(vX, outer_points, count):
+ (o, vert_count, edge_count) = GetActiveObject()
+ (vA, vB, vC, vD) = edges_to_points(outer_points)
+ AddVertsToObject(vert_count, o, vX, vA, vB, vC, vD)
+
+ oe = o.data.edges
+ oe.add(4)
+ # Candidate for serious optimization.
+ if isPointOnEdge(vX, vA, vB):
+ oe[edge_count].vertices = [vert_count, vert_count+1]
+ oe[edge_count+1].vertices = [vert_count, vert_count+2]
+ # find which of C and D is farthest away from X
+ if mDist(vD, vX) > mDist(vC, vX):
+ oe[edge_count+2].vertices = [vert_count, vert_count+3]
+ oe[edge_count+3].vertices = [vert_count+3, vert_count+4]
+ if mDist(vC, vX) > mDist(vD, vX):
+ oe[edge_count+2].vertices = [vert_count, vert_count+4]
+ oe[edge_count+3].vertices = [vert_count+3, vert_count+4]
+
+ if isPointOnEdge(vX, vC, vD):
+ oe[edge_count].vertices = [vert_count, vert_count+3]
+ oe[edge_count+1].vertices = [vert_count, vert_count+4]
+ # find which of A and B is farthest away from X
+ if mDist(vB, vX) > mDist(vA, vX):
+ oe[edge_count+2].vertices = [vert_count, vert_count+1]
+ oe[edge_count+3].vertices = [vert_count+1, vert_count+2]
+ if mDist(vA, vX) > mDist(vB, vX):
+ oe[edge_count+2].vertices = [vert_count, vert_count+2]
+ oe[edge_count+3].vertices = [vert_count+1, vert_count+2]
+
+
+# ProjectGeometry is used to extend two edges to their intersection point.
+def ProjectGeometry(vX, opoint):
+
+ def return_distance_checked(X, A, B):
+ dist1 = mDist(X, A)
+ dist2 = mDist(X, B)
+ point_choice = min(dist1, dist2)
+ if point_choice == dist1: return A, B
+ else: return B, A
+
+ (o, vert_count, edge_count) = GetActiveObject()
+ vA, vB = return_distance_checked(vX, Vector((opoint[0][0])), Vector((opoint[0][1])))
+ vC, vD = return_distance_checked(vX, Vector((opoint[1][0])), Vector((opoint[1][1])))
+ AddVertsToObject(vert_count, o, vX, vA, vB, vC, vD)
+
+ oe = o.data.edges
+ oe.add(4)
+ oe[edge_count].vertices = [vert_count, vert_count+1]
+ oe[edge_count+1].vertices = [vert_count, vert_count+3]
+ oe[edge_count+2].vertices = [vert_count+1, vert_count+2]
+ oe[edge_count+3].vertices = [vert_count+3, vert_count+4]
+
+
+def getMeshMatrix(obj):
+ is_editmode = (obj.mode == 'EDIT')
+ if is_editmode:
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ (edges, meshMatrix) = ([],[])
+ mesh = obj.data
+ verts = mesh.vertices
+ for e in mesh.edges:
+ if e.select:
+ edges.append(e)
+
+ edgenum = 0
+ for edge_to_test in edges:
+ p1 = verts[edge_to_test.vertices[0]].co
+ p2 = verts[edge_to_test.vertices[1]].co
+ meshMatrix.append([Vector(p1),Vector(p2)])
+ edgenum += 1
+
+ return meshMatrix
+
+
+def getVertEdgeCount():
+ bpy.ops.object.mode_set(mode='OBJECT')
+ vert_count = bpy.context.active_object.data.vertices
+ edge_count = bpy.context.active_object.data.edges
+ return (vert_count, edge_count)
+
+
+def runCleanUp():
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='TOGGLE')
+ bpy.ops.mesh.select_all(action='TOGGLE')
+ bpy.ops.mesh.remove_doubles(threshold=VTX_PRECISION)
+ bpy.ops.mesh.select_all(action='TOGGLE') #unselect all
+
+
+def initScriptV(context, self):
+ obj = bpy.context.active_object
+ meshMatrix = getMeshMatrix(obj)
+ (vert_count, edge_count) = getVertEdgeCount()
+
+ #need 2 edges to be of any use.
+ if len(meshMatrix) < 2:
+ print(str(len(meshMatrix)) +" select, make sure (only) 2 are selected")
+ return
+
+ #dont go any further if the verts are not coplanar
+ if checkIsMatrixCoplanar(meshMatrix): print("seems within tolerance, proceed")
+ else:
+ print("check your geometry, or decrease tolerance value")
+ return
+
+ # if we reach this point, the edges are coplanar
+ # force edit mode
+ bpy.ops.object.mode_set(mode='EDIT')
+ vSel = bpy.context.active_object.data.total_vert_sel
+
+ if checkEdges(meshMatrix, obj) == None: print("lines dont intersect")
+ else:
+ count = CountPointOnEdges(checkEdges(meshMatrix, obj), meshMatrix)
+ if count == 0:
+ ProjectGeometry(checkEdges(meshMatrix, obj), meshMatrix)
+ runCleanUp()
+ else:
+ print("The intersection seems to lie on 1 or 2 edges already")
+
+
+def initScriptT(context, self):
+ obj = bpy.context.active_object
+ meshMatrix = getMeshMatrix(obj)
+ ## force edit mode
+ bpy.ops.object.mode_set(mode='EDIT')
+ vSel = bpy.context.active_object.data.total_vert_sel
+
+ if len(meshMatrix) != 2:
+ print(str(len(meshMatrix)) +" select 2 edges")
+ else:
+ count = CountPointOnEdges(checkEdges(meshMatrix, obj), meshMatrix)
+ if count == 1:
+ print("Good, Intersection point lies on one of the two edges!")
+ ExtendEdge(checkEdges(meshMatrix, obj), meshMatrix, count)
+ runCleanUp() #neutral function, for removing potential doubles
+ else:
+ print("Intersection point not on chosen edges")
+
+
+def initScriptX(context, self):
+ obj = bpy.context.active_object
+ meshMatrix = getMeshMatrix(obj)
+ ## force edit mode
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ if len(meshMatrix) != 2:
+ print(str(len(meshMatrix)) +" select, make sure (only) 2 are selected")
+ else:
+ if checkEdges(meshMatrix, obj) == None:
+ print("lines dont intersect")
+ else:
+ count = CountPointOnEdges(checkEdges(meshMatrix, obj), meshMatrix)
+ if count == 2:
+ makeGeometryWeld(checkEdges(meshMatrix, obj), meshMatrix)
+ runCleanUp()
+
+
+class EdgeIntersections(bpy.types.Operator):
+ """Makes a weld/slice/extend to intersecting edges/lines"""
+ bl_idname = 'mesh.intersections'
+ bl_label = 'Edge tools : tinyCAD VTX'
+ # bl_options = {'REGISTER', 'UNDO'}
+
+ mode = bpy.props.IntProperty(name = "Mode",
+ description = "switch between intersection modes",
+ default = 2)
+
+ @classmethod
+ def poll(self, context):
+ obj = context.active_object
+ return obj != None and obj.type == 'MESH'
+
+ def execute(self, context):
+ if self.mode == -1:
+ initScriptV(context, self)
+ if self.mode == 0:
+ initScriptT(context, self)
+ if self.mode == 1:
+ initScriptX(context, self)
+ if self.mode == 2:
+ print("something undefined happened, send me a test case!")
+ return {'FINISHED'}
+
+
+def menu_func(self, context):
+ self.layout.operator(EdgeIntersections.bl_idname, text="Edges V Intersection").mode = -1
+ self.layout.operator(EdgeIntersections.bl_idname, text="Edges T Intersection").mode = 0
+ self.layout.operator(EdgeIntersections.bl_idname, text="Edges X Intersection").mode = 1
+
+def register():
+ bpy.utils.register_class(EdgeIntersections)
+ bpy.types.VIEW3D_MT_edit_mesh_specials.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_class(EdgeIntersections)
+ bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_edgetools.py b/release/scripts/addons_contrib/mesh_edgetools.py
new file mode 100644
index 0000000..e208ff9
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_edgetools.py
@@ -0,0 +1,1979 @@
+# Blender EdgeTools
+#
+# This is a toolkit for edge manipulation based on several of mesh manipulation
+# abilities of several CAD/CAE packages, notably CATIA's Geometric Workbench
+# from which most of these tools have a functional basis based on the paradims
+# that platform enables. These tools are a collection of scripts that I needed
+# at some point, and so I will probably add and improve these as I continue to
+# use and model with them.
+#
+# It might be good to eventually merge the tinyCAD VTX tools for unification
+# purposes, and as these are edge-based tools, it would make sense. Or maybe
+# merge this with tinyCAD instead?
+#
+# The GUI and Blender add-on structure shamelessly coded in imitation of the
+# LoopTools addon.
+#
+# Examples:
+# - "Ortho" inspired from CATIA's line creation tool which creates a line of a
+# user specified length at a user specified angle to a curve at a chosen
+# point. The user then selects the plane the line is to be created in.
+# - "Shaft" is inspired from CATIA's tool of the same name. However, instead
+# of a curve around an axis, this will instead shaft a line, a point, or
+# a fixed radius about the selected axis.
+# - "Slice" is from CATIA's ability to split a curve on a plane. When
+# completed this be a Python equivalent with all the same basic
+# functionality, though it will sadly be a little clumsier to use due
+# to Blender's selection limitations.
+#
+# Notes:
+# - Buggy parts have been hidden behind bpy.app.debug. Run Blender in debug
+# to expose those. Example: Shaft with more than two edges selected.
+# - Some functions have started to crash, despite working correctly before.
+# What could be causing that? Blender bug? Or coding bug?
+#
+# Paul "BrikBot" Marshall
+# Created: January 28, 2012
+# Last Modified: October 6, 2012
+# Homepage (blog): http://post.darkarsenic.com/
+# //blog.darkarsenic.com/
+#
+# Coded in IDLE, tested in Blender 2.6.
+# Search for "@todo" to quickly find sections that need work.
+#
+# Remeber -
+# Functional code comes before fast code. Once it works, then worry about
+# making it faster/more efficient.
+#
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# The Blender Edgetools is to bring CAD tools to Blender.
+# Copyright (C) 2012 Paul Marshall
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+# ^^ Maybe. . . . :P
+
+bl_info = {
+ "name": "EdgeTools",
+ "author": "Paul Marshall",
+ "version": (0, 8),
+ "blender": (2, 64, 0),
+ "location": "View3D > Toolbar and View3D > Specials (W-key)",
+ "warning": "",
+ "description": "CAD style edge manipulation tools",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/EdgeTools",
+ "tracker_url": "https://blenderpython.svn.sourceforge.net/svnroot/blenderpython/scripts_library/scripts/addons_extern/mesh_edgetools.py",
+ "category": "Mesh"}
+
+import bpy, bmesh, mathutils
+from math import acos, pi, radians, sqrt, tan
+from mathutils import Matrix, Vector
+from mathutils.geometry import (distance_point_to_plane,
+ interpolate_bezier,
+ intersect_point_line,
+ intersect_line_line,
+ intersect_line_plane)
+from bpy.props import (BoolProperty,
+ BoolVectorProperty,
+ IntProperty,
+ FloatProperty,
+ EnumProperty)
+
+integrated = False
+
+# Quick an dirty method for getting the sign of a number:
+def sign(number):
+ return (number > 0) - (number < 0)
+
+
+# is_parallel
+#
+# Checks to see if two lines are parallel
+def is_parallel(v1, v2, v3, v4):
+ result = intersect_line_line(v1, v2, v3, v4)
+ return result == None
+
+
+# is_axial
+#
+# This is for the special case where the edge is parallel to an axis. In this
+# the projection onto the XY plane will fail so it will have to be handled
+# differently. This tells us if and how:
+def is_axial(v1, v2, error = 0.000002):
+ vector = v2 - v1
+ # Don't need to store, but is easier to read:
+ vec0 = vector[0] > -error and vector[0] < error
+ vec1 = vector[1] > -error and vector[1] < error
+ vec2 = vector[2] > -error and vector[2] < error
+ if (vec0 or vec1) and vec2:
+ return 'Z'
+ elif vec0 and vec1:
+ return 'Y'
+ return None
+
+
+# is_same_co
+#
+# For some reason "Vector = Vector" does not seem to look at the actual
+# coordinates. This provides a way to do so.
+def is_same_co(v1, v2):
+ if len(v1) != len(v2):
+ return False
+ else:
+ for co1, co2 in zip(v1, v2):
+ if co1 != co2:
+ return False
+ return True
+
+
+# is_face_planar
+#
+# Tests a face to see if it is planar.
+def is_face_planar(face, error = 0.0005):
+ for v in face.verts:
+ d = distance_point_to_plane(v.co, face.verts[0].co, face.normal)
+ if bpy.app.debug:
+ print("Distance: " + str(d))
+ if d < -error or d > error:
+ return False
+ return True
+
+
+# other_joined_edges
+#
+# Starts with an edge. Then scans for linked, selected edges and builds a
+# list with them in "order", starting at one end and moving towards the other.
+def order_joined_edges(edge, edges = [], direction = 1):
+ if len(edges) == 0:
+ edges.append(edge)
+ edges[0] = edge
+
+ if bpy.app.debug:
+ print(edge, end = ", ")
+ print(edges, end = ", ")
+ print(direction, end = "; ")
+
+ # Robustness check: direction cannot be zero
+ if direction == 0:
+ direction = 1
+
+ newList = []
+ for e in edge.verts[0].link_edges:
+ if e.select and edges.count(e) == 0:
+ if direction > 0:
+ edges.insert(0, e)
+ newList.extend(order_joined_edges(e, edges, direction + 1))
+ newList.extend(edges)
+ else:
+ edges.append(e)
+ newList.extend(edges)
+ newList.extend(order_joined_edges(e, edges, direction - 1))
+
+ # This will only matter at the first level:
+ direction = direction * -1
+
+ for e in edge.verts[1].link_edges:
+ if e.select and edges.count(e) == 0:
+ if direction > 0:
+ edges.insert(0, e)
+ newList.extend(order_joined_edges(e, edges, direction + 2))
+ newList.extend(edges)
+ else:
+ edges.append(e)
+ newList.extend(edges)
+ newList.extend(order_joined_edges(e, edges, direction))
+
+ if bpy.app.debug:
+ print(newList, end = ", ")
+ print(direction)
+
+ return newList
+
+
+# --------------- GEOMETRY CALCULATION METHODS --------------
+
+# distance_point_line
+#
+# I don't know why the mathutils.geometry API does not already have this, but
+# it is trivial to code using the structures already in place. Instead of
+# returning a float, I also want to know the direction vector defining the
+# distance. Distance can be found with "Vector.length".
+def distance_point_line(pt, line_p1, line_p2):
+ int_co = intersect_point_line(pt, line_p1, line_p2)
+ distance_vector = int_co[0] - pt
+ return distance_vector
+
+
+# interpolate_line_line
+#
+# This is an experiment into a cubic Hermite spline (c-spline) for connecting
+# two edges with edges that obey the general equation.
+# This will return a set of point coordinates (Vectors).
+#
+# A good, easy to read background on the mathematics can be found at:
+# http://cubic.org/docs/hermite.htm
+#
+# Right now this is . . . less than functional :P
+# @todo
+# - C-Spline and Bezier curves do not end on p2_co as they are supposed to.
+# - B-Spline just fails. Epically.
+# - Add more methods as I come across them. Who said flexibility was bad?
+def interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, segments, tension = 1,
+ typ = 'BEZIER', include_ends = False):
+ pieces = []
+ fraction = 1 / segments
+ # Form: p1, tangent 1, p2, tangent 2
+ if typ == 'HERMITE':
+ poly = [[2, -3, 0, 1], [1, -2, 1, 0],
+ [-2, 3, 0, 0], [1, -1, 0, 0]]
+ elif typ == 'BEZIER':
+ poly = [[-1, 3, -3, 1], [3, -6, 3, 0],
+ [1, 0, 0, 0], [-3, 3, 0, 0]]
+ p1_dir = p1_dir + p1_co
+ p2_dir = -p2_dir + p2_co
+ elif typ == 'BSPLINE':
+## Supposed poly matrix for a cubic b-spline:
+## poly = [[-1, 3, -3, 1], [3, -6, 3, 0],
+## [-3, 0, 3, 0], [1, 4, 1, 0]]
+ # My own invention to try to get something that somewhat acts right.
+ # This is semi-quadratic rather than fully cubic:
+ poly = [[0, -1, 0, 1], [1, -2, 1, 0],
+ [0, -1, 2, 0], [1, -1, 0, 0]]
+ if include_ends:
+ pieces.append(p1_co)
+ # Generate each point:
+ for i in range(segments - 1):
+ t = fraction * (i + 1)
+ if bpy.app.debug:
+ print(t)
+ s = [t ** 3, t ** 2, t, 1]
+ h00 = (poly[0][0] * s[0]) + (poly[0][1] * s[1]) + (poly[0][2] * s[2]) + (poly[0][3] * s[3])
+ h01 = (poly[1][0] * s[0]) + (poly[1][1] * s[1]) + (poly[1][2] * s[2]) + (poly[1][3] * s[3])
+ h10 = (poly[2][0] * s[0]) + (poly[2][1] * s[1]) + (poly[2][2] * s[2]) + (poly[2][3] * s[3])
+ h11 = (poly[3][0] * s[0]) + (poly[3][1] * s[1]) + (poly[3][2] * s[2]) + (poly[3][3] * s[3])
+ pieces.append((h00 * p1_co) + (h01 * p1_dir) + (h10 * p2_co) + (h11 * p2_dir))
+ if include_ends:
+ pieces.append(p2_co)
+ # Return:
+ if len(pieces) == 0:
+ return None
+ else:
+ if bpy.app.debug:
+ print(pieces)
+ return pieces
+
+
+# intersect_line_face
+#
+# Calculates the coordinate of intersection of a line with a face. It returns
+# the coordinate if one exists, otherwise None. It can only deal with tris or
+# quads for a face. A quad does NOT have to be planar. Thus the following.
+#
+# Quad math and theory:
+# A quad may not be planar. Therefore the treated definition of the surface is
+# that the surface is composed of all lines bridging two other lines defined by
+# the given four points. The lines do not "cross".
+#
+# The two lines in 3-space can defined as:
+# ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐
+# │x1│ │a11│ │b11│ │x2│ │a21│ │b21│
+# │y1│ = (1-t1)│a12│ + t1│b12│, │y2│ = (1-t2)│a22│ + t2│b22│
+# │z1│ │a13│ │b13│ │z2│ │a23│ │b23│
+# └ ┘ └ ┘ └ ┘ └ ┘ └ ┘ └ ┘
+# Therefore, the surface is the lines defined by every point alone the two
+# lines with a same "t" value (t1 = t2). This is basically R = V1 + tQ, where
+# Q = V2 - V1 therefore R = V1 + t(V2 - V1) -> R = (1 - t)V1 + tV2:
+# ┌ ┐ ┌ ┐ ┌ ┐
+# │x12│ │(1-t)a11 + t * b11│ │(1-t)a21 + t * b21│
+# │y12│ = (1 - t12)│(1-t)a12 + t * b12│ + t12│(1-t)a22 + t * b22│
+# │z12│ │(1-t)a13 + t * b13│ │(1-t)a23 + t * b23│
+# └ ┘ └ ┘ └ ┘
+# Now, the equation of our line can be likewise defined:
+# ┌ ┐ ┌ ┐ ┌ ┐
+# │x3│ │a31│ │b31│
+# │y3│ = │a32│ + t3│b32│
+# │z3│ │a33│ │b33│
+# └ ┘ └ ┘ └ ┘
+# Now we just have to find a valid solution for the two equations. This should
+# be our point of intersection. Therefore, x12 = x3 -> x, y12 = y3 -> y,
+# z12 = z3 -> z. Thus, to find that point we set the equation defining the
+# surface as equal to the equation for the line:
+# ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐
+# │(1-t)a11 + t * b11│ │(1-t)a21 + t * b21│ │a31│ │b31│
+# (1 - t12)│(1-t)a12 + t * b12│ + t12│(1-t)a22 + t * b22│ = │a32│ + t3│b32│
+# │(1-t)a13 + t * b13│ │(1-t)a23 + t * b23│ │a33│ │b33│
+# └ ┘ └ ┘ └ ┘ └ ┘
+# This leaves us with three equations, three unknowns. Solving the system by
+# hand is practically impossible, but using Mathematica we are given an insane
+# series of three equations (not reproduced here for the sake of space: see
+# http://www.mediafire.com/file/cc6m6ba3sz2b96m/intersect_line_surface.nb and
+# http://www.mediafire.com/file/0egbr5ahg14talm/intersect_line_surface2.nb for
+# Mathematica computation).
+#
+# Additionally, the resulting series of equations may result in a div by zero
+# exception if the line in question if parallel to one of the axis or if the
+# quad is planar and parallel to either the XY, XZ, or YZ planes. However, the
+# system is still solvable but must be dealt with a little differently to avaid
+# these special cases. Because the resulting equations are a little different,
+# we have to code them differently. Hence the special cases.
+#
+# Tri math and theory:
+# A triangle must be planar (three points define a plane). Therefore we just
+# have to make sure that the line intersects inside the triangle.
+#
+# If the point is within the triangle, then the angle between the lines that
+# connect the point to the each individual point of the triangle will be
+# equal to 2 * PI. Otherwise, if the point is outside the triangle, then the
+# sum of the angles will be less.
+#
+# @todo
+# - Figure out how to deal with n-gons. How the heck is a face with 8 verts
+# definied mathematically? How do I then find the intersection point of
+# a line with said vert? How do I know if that point is "inside" all the
+# verts? I have no clue, and haven't been able to find anything on it so
+# far. Maybe if someone (actually reads this and) who knows could note?
+def intersect_line_face(edge, face, is_infinite = False, error = 0.000002):
+ int_co = None
+
+ # If we are dealing with a non-planar quad:
+ if len(face.verts) == 4 and not is_face_planar(face):
+ edgeA = face.edges[0]
+ edgeB = None
+ flipB = False
+
+ for i in range(len(face.edges)):
+ if face.edges[i].verts[0] not in edgeA.verts and face.edges[i].verts[1] not in edgeA.verts:
+ edgeB = face.edges[i]
+ break
+
+ # I haven't figured out a way to mix this in with the above. Doing so might remove a
+ # few extra instructions from having to be executed saving a few clock cycles:
+ for i in range(len(face.edges)):
+ if face.edges[i] == edgeA or face.edges[i] == edgeB:
+ continue
+ if (edgeA.verts[0] in face.edges[i].verts and edgeB.verts[1] in face.edges[i].verts) or (edgeA.verts[1] in face.edges[i].verts and edgeB.verts[0] in face.edges[i].verts):
+ flipB = True
+ break
+
+ # Define calculation coefficient constants:
+ # "xx1" is the x coordinate, "xx2" is the y coordinate, and "xx3" is the z
+ # coordinate.
+ a11, a12, a13 = edgeA.verts[0].co[0], edgeA.verts[0].co[1], edgeA.verts[0].co[2]
+ b11, b12, b13 = edgeA.verts[1].co[0], edgeA.verts[1].co[1], edgeA.verts[1].co[2]
+ if flipB:
+ a21, a22, a23 = edgeB.verts[1].co[0], edgeB.verts[1].co[1], edgeB.verts[1].co[2]
+ b21, b22, b23 = edgeB.verts[0].co[0], edgeB.verts[0].co[1], edgeB.verts[0].co[2]
+ else:
+ a21, a22, a23 = edgeB.verts[0].co[0], edgeB.verts[0].co[1], edgeB.verts[0].co[2]
+ b21, b22, b23 = edgeB.verts[1].co[0], edgeB.verts[1].co[1], edgeB.verts[1].co[2]
+ a31, a32, a33 = edge.verts[0].co[0], edge.verts[0].co[1], edge.verts[0].co[2]
+ b31, b32, b33 = edge.verts[1].co[0], edge.verts[1].co[1], edge.verts[1].co[2]
+
+ # There are a bunch of duplicate "sub-calculations" inside the resulting
+ # equations for t, t12, and t3. Calculate them once and store them to
+ # reduce computational time:
+ m01 = a13 * a22 * a31
+ m02 = a12 * a23 * a31
+ m03 = a13 * a21 * a32
+ m04 = a11 * a23 * a32
+ m05 = a12 * a21 * a33
+ m06 = a11 * a22 * a33
+ m07 = a23 * a32 * b11
+ m08 = a22 * a33 * b11
+ m09 = a23 * a31 * b12
+ m10 = a21 * a33 * b12
+ m11 = a22 * a31 * b13
+ m12 = a21 * a32 * b13
+ m13 = a13 * a32 * b21
+ m14 = a12 * a33 * b21
+ m15 = a13 * a31 * b22
+ m16 = a11 * a33 * b22
+ m17 = a12 * a31 * b23
+ m18 = a11 * a32 * b23
+ m19 = a13 * a22 * b31
+ m20 = a12 * a23 * b31
+ m21 = a13 * a32 * b31
+ m22 = a23 * a32 * b31
+ m23 = a12 * a33 * b31
+ m24 = a22 * a33 * b31
+ m25 = a23 * b12 * b31
+ m26 = a33 * b12 * b31
+ m27 = a22 * b13 * b31
+ m28 = a32 * b13 * b31
+ m29 = a13 * b22 * b31
+ m30 = a33 * b22 * b31
+ m31 = a12 * b23 * b31
+ m32 = a32 * b23 * b31
+ m33 = a13 * a21 * b32
+ m34 = a11 * a23 * b32
+ m35 = a13 * a31 * b32
+ m36 = a23 * a31 * b32
+ m37 = a11 * a33 * b32
+ m38 = a21 * a33 * b32
+ m39 = a23 * b11 * b32
+ m40 = a33 * b11 * b32
+ m41 = a21 * b13 * b32
+ m42 = a31 * b13 * b32
+ m43 = a13 * b21 * b32
+ m44 = a33 * b21 * b32
+ m45 = a11 * b23 * b32
+ m46 = a31 * b23 * b32
+ m47 = a12 * a21 * b33
+ m48 = a11 * a22 * b33
+ m49 = a12 * a31 * b33
+ m50 = a22 * a31 * b33
+ m51 = a11 * a32 * b33
+ m52 = a21 * a32 * b33
+ m53 = a22 * b11 * b33
+ m54 = a32 * b11 * b33
+ m55 = a21 * b12 * b33
+ m56 = a31 * b12 * b33
+ m57 = a12 * b21 * b33
+ m58 = a32 * b21 * b33
+ m59 = a11 * b22 * b33
+ m60 = a31 * b22 * b33
+ m61 = a33 * b12 * b21
+ m62 = a32 * b13 * b21
+ m63 = a33 * b11 * b22
+ m64 = a31 * b13 * b22
+ m65 = a32 * b11 * b23
+ m66 = a31 * b12 * b23
+ m67 = b13 * b22 * b31
+ m68 = b12 * b23 * b31
+ m69 = b13 * b21 * b32
+ m70 = b11 * b23 * b32
+ m71 = b12 * b21 * b33
+ m72 = b11 * b22 * b33
+ n01 = m01 - m02 - m03 + m04 + m05 - m06
+ n02 = -m07 + m08 + m09 - m10 - m11 + m12 + m13 - m14 - m15 + m16 + m17 - m18 - m25 + m27 + m29 - m31 + m39 - m41 - m43 + m45 - m53 + m55 + m57 - m59
+ n03 = -m19 + m20 + m33 - m34 - m47 + m48
+ n04 = m21 - m22 - m23 + m24 - m35 + m36 + m37 - m38 + m49 - m50 - m51 + m52
+ n05 = m26 - m28 - m30 + m32 - m40 + m42 + m44 - m46 + m54 - m56 - m58 + m60
+ n06 = m61 - m62 - m63 + m64 + m65 - m66 - m67 + m68 + m69 - m70 - m71 + m72
+ n07 = 2 * n01 + n02 + 2 * n03 + n04 + n05
+ n08 = n01 + n02 + n03 + n06
+
+ # Calculate t, t12, and t3:
+ t = (n07 - sqrt(pow(-n07, 2) - 4 * (n01 + n03 + n04) * n08)) / (2 * n08)
+
+ # t12 can be greatly simplified by defining it with t in it:
+ # If block used to help prevent any div by zero error.
+ t12 = 0
+
+ if a31 == b31:
+ # The line is parallel to the z-axis:
+ if a32 == b32:
+ t12 = ((a11 - a31) + (b11 - a11) * t) / ((a21 - a11) + (a11 - a21 - b11 + b21) * t)
+ # The line is parallel to the y-axis:
+ elif a33 == b33:
+ t12 = ((a11 - a31) + (b11 - a11) * t) / ((a21 - a11) + (a11 - a21 - b11 + b21) * t)
+ # The line is along the y/z-axis but is not parallel to either:
+ else:
+ t12 = -(-(a33 - b33) * (-a32 + a12 * (1 - t) + b12 * t) + (a32 - b32) * (-a33 + a13 * (1 - t) + b13 * t)) / (-(a33 - b33) * ((a22 - a12) * (1 - t) + (b22 - b12) * t) + (a32 - b32) * ((a23 - a13) * (1 - t) + (b23 - b13) * t))
+ elif a32 == b32:
+ # The line is parallel to the x-axis:
+ if a33 == b33:
+ t12 = ((a12 - a32) + (b12 - a12) * t) / ((a22 - a12) + (a12 - a22 - b12 + b22) * t)
+ # The line is along the x/z-axis but is not parallel to either:
+ else:
+ t12 = -(-(a33 - b33) * (-a31 + a11 * (1 - t) + b11 * t) + (a31 - b31) * (-a33 + a13 * (1 - t) + b13 * t)) / (-(a33 - b33) * ((a21 - a11) * (1 - t) + (b21 - b11) * t) + (a31 - b31) * ((a23 - a13) * (1 - t) + (b23 - b13) * t))
+ # The line is along the x/y-axis but is not parallel to either:
+ else:
+ t12 = -(-(a32 - b32) * (-a31 + a11 * (1 - t) + b11 * t) + (a31 - b31) * (-a32 + a12 * (1 - t) + b12 * t)) / (-(a32 - b32) * ((a21 - a11) * (1 - t) + (b21 - b11) * t) + (a31 - b31) * ((a22 - a21) * (1 - t) + (b22 - b12) * t))
+
+ # Likewise, t3 is greatly simplified by defining it in terms of t and t12:
+ # If block used to prevent a div by zero error.
+ t3 = 0
+ if a31 != b31:
+ t3 = (-a11 + a31 + (a11 - b11) * t + (a11 - a21) * t12 + (a21 - a11 + b11 - b21) * t * t12) / (a31 - b31)
+ elif a32 != b32:
+ t3 = (-a12 + a32 + (a12 - b12) * t + (a12 - a22) * t12 + (a22 - a12 + b12 - b22) * t * t12) / (a32 - b32)
+ elif a33 != b33:
+ t3 = (-a13 + a33 + (a13 - b13) * t + (a13 - a23) * t12 + (a23 - a13 + b13 - b23) * t * t12) / (a33 - b33)
+ else:
+ print("The second edge is a zero-length edge")
+ return None
+
+ # Calculate the point of intersection:
+ x = (1 - t3) * a31 + t3 * b31
+ y = (1 - t3) * a32 + t3 * b32
+ z = (1 - t3) * a33 + t3 * b33
+ int_co = Vector((x, y, z))
+
+ if bpy.app.debug:
+ print(int_co)
+
+ # If the line does not intersect the quad, we return "None":
+ if (t < -1 or t > 1 or t12 < -1 or t12 > 1) and not is_infinite:
+ int_co = None
+
+ elif len(face.verts) == 3:
+ p1, p2, p3 = face.verts[0].co, face.verts[1].co, face.verts[2].co
+ int_co = intersect_line_plane(edge.verts[0].co, edge.verts[1].co, p1, face.normal)
+
+ # Only check if the triangle is not being treated as an infinite plane:
+ # Math based from http://paulbourke.net/geometry/linefacet/
+ if int_co != None and not is_infinite:
+ pA = p1 - int_co
+ pB = p2 - int_co
+ pC = p3 - int_co
+ # These must be unit vectors, else we risk a domain error:
+ pA.length = 1
+ pB.length = 1
+ pC.length = 1
+ aAB = acos(pA.dot(pB))
+ aBC = acos(pB.dot(pC))
+ aCA = acos(pC.dot(pA))
+ sumA = aAB + aBC + aCA
+
+ # If the point is outside the triangle:
+ if (sumA > (pi + error) and sumA < (pi - error)):
+ int_co = None
+
+ # This is the default case where we either have a planar quad or an n-gon.
+ else:
+ int_co = intersect_line_plane(edge.verts[0].co, edge.verts[1].co,
+ face.verts[0].co, face.normal)
+
+ return int_co
+
+
+# project_point_plane
+#
+# Projects a point onto a plane. Returns a tuple of the projection vector
+# and the projected coordinate.
+def project_point_plane(pt, plane_co, plane_no):
+ proj_co = intersect_line_plane(pt, pt + plane_no, plane_co, plane_no)
+ proj_ve = proj_co - pt
+ return (proj_ve, proj_co)
+
+
+# ------------ FILLET/CHAMPHER HELPER METHODS -------------
+
+# get_next_edge
+#
+# The following is used to return edges that might be possible edges for
+# propagation. If an edge is connected to the end vert, but is also a part
+# of the on of the faces that the current edge composes, then it is a
+# "corner edge" and is not valid as a propagation edge. If the edge is
+# part of two faces that a in the same plane, then we cannot fillet/chamfer
+# it because there is no angle between them.
+def get_next_edge(edge, vert):
+ invalidEdges = [e for f in edge.link_faces for e in f.edges if e != edge]
+ invalidEdges.append(edge)
+ if bpy.app.debug:
+ print(invalidEdges)
+ newEdge = [e for e in vert.link_edges if e not in invalidEdges and not is_planar_edge(e)]
+ if len(newEdge) == 0:
+ return None
+ elif len(newEdge) == 1:
+ return newEdge[0]
+ else:
+ return newEdge
+
+
+def is_planar_edge(edge, error = 0.000002):
+ angle = edge.calc_face_angle()
+ return (angle < error and angle > -error) or (angle < (180 + error) and angle > (180 - error))
+
+
+# fillet_axis
+#
+# Calculates the base geometry data for the fillet. This assumes that the faces
+# are planar:
+#
+# @todo
+# - Redesign so that the faces do not have to be planar
+#
+# There seems to be issues some of the vector math right now. Will need to be
+# debuged.
+def fillet_axis(edge, radius):
+ vectors = [None, None, None, None]
+
+ origin = Vector((0, 0, 0))
+ axis = edge.verts[1].co - edge.verts[0].co
+
+ # Get the "adjacency" base vectors for face 0:
+ for e in edge.link_faces[0].edges:
+ if e == edge:
+ continue
+ if e.verts[0] == edge.verts[0]:
+ vectors[0] = e.verts[1].co - e.verts[0].co
+ elif e.verts[1] == edge.verts[0]:
+ vectors[0] = e.verts[0].co - e.verts[1].co
+ elif e.verts[0] == edge.verts[1]:
+ vectors[1] = e.verts[1].co - e.verts[0].co
+ elif e.verts[1] == edge.verts[1]:
+ vectors[1] = e.verts[0].co - e.verts[1].co
+
+ # Get the "adjacency" base vectors for face 1:
+ for e in edge.link_faces[1].edges:
+ if e == edge:
+ continue
+ if e.verts[0] == edge.verts[0]:
+ vectors[2] = e.verts[1].co - e.verts[0].co
+ elif e.verts[1] == edge.verts[0]:
+ vectors[2] = e.verts[0].co - e.verts[1].co
+ elif e.verts[0] == edge.verts[1]:
+ vectors[3] = e.verts[1].co - e.verts[0].co
+ elif e.verts[1] == edge.verts[1]:
+ vectors[3] = e.verts[0].co - e.verts[1].co
+
+ # Get the normal for face 0 and face 1:
+ norm1 = edge.link_faces[0].normal
+ norm2 = edge.link_faces[1].normal
+
+ # We need to find the angle between the two faces, then bisect it:
+ theda = (pi - edge.calc_face_angle()) / 2
+
+ # We are dealing with a triangle here, and we will need the length
+ # of its adjacent side. The opposite is the radius:
+ adj_len = radius / tan(theda)
+
+ # Vectors can be thought of as being at the origin, and we need to make sure
+ # that the base vectors are planar with the "normal" definied by the edge to
+ # be filleted. Then we set the length of the vector and shift it into a
+ # coordinate:
+ for i in range(len(vectors)):
+ vectors[i] = project_point_plane(vectors[i], origin, axis)[1]
+ vectors[i].length = adj_len
+ vectors[i] = vectors[i] + edge.verts[i % 2].co
+
+ # Compute fillet axis end points:
+ v1 = intersect_line_line(vectors[0], vectors[0] + norm1, vectors[2], vectors[2] + norm2)[0]
+ v2 = intersect_line_line(vectors[1], vectors[1] + norm1, vectors[3], vectors[3] + norm2)[0]
+ return [v1, v2]
+
+
+def fillet_point(t, face1, face2):
+ return
+
+
+# ------------------- EDGE TOOL METHODS -------------------
+
+# Extends an "edge" in two directions:
+# - Requires two vertices to be selected. They do not have to form an edge.
+# - Extends "length" in both directions
+class Extend(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_extend"
+ bl_label = "Extend"
+ bl_description = "Extend the selected edges of vertice pair."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ di1 = BoolProperty(name = "Forwards",
+ description = "Extend the edge forwards",
+ default = True)
+ di2 = BoolProperty(name = "Backwards",
+ description = "Extend the edge backwards",
+ default = False)
+ length = FloatProperty(name = "Length",
+ description = "Length to extend the edge",
+ min = 0.0, max = 1024.0,
+ default = 1.0)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "di1")
+ layout.prop(self, "di2")
+ layout.prop(self, "length")
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(bpy.context.active_object.data)
+ bm.normal_update()
+
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ edges = [e for e in bEdges if e.select]
+ verts = [v for v in bVerts if v.select]
+
+ if len(edges) > 0:
+ for e in edges:
+ vector = e.verts[0].co - e.verts[1].co
+ vector.length = self.length
+
+ if self.di1:
+ v = bVerts.new()
+ if (vector[0] + vector[1] + vector[2]) < 0:
+ v.co = e.verts[1].co - vector
+ newE = bEdges.new((e.verts[1], v))
+ else:
+ v.co = e.verts[0].co + vector
+ newE = bEdges.new((e.verts[0], v))
+ if self.di2:
+ v = bVerts.new()
+ if (vector[0] + vector[1] + vector[2]) < 0:
+ v.co = e.verts[0].co + vector
+ newE = bEdges.new((e.verts[0], v))
+ else:
+ v.co = e.verts[1].co - vector
+ newE = bEdges.new((e.verts[1], v))
+ else:
+ vector = verts[0].co - verts[1].co
+ vector.length = self.length
+
+ if self.di1:
+ v = bVerts.new()
+ if (vector[0] + vector[1] + vector[2]) < 0:
+ v.co = verts[1].co - vector
+ e = bEdges.new((verts[1], v))
+ else:
+ v.co = verts[0].co + vector
+ e = bEdges.new((verts[0], v))
+ if self.di2:
+ v = bVerts.new()
+ if (vector[0] + vector[1] + vector[2]) < 0:
+ v.co = verts[0].co + vector
+ e = bEdges.new((verts[0], v))
+ else:
+ v.co = verts[1].co - vector
+ e = bEdges.new((verts[1], v))
+
+ bm.to_mesh(bpy.context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# Creates a series of edges between two edges using spline interpolation.
+# This basically just exposes existing functionality in addition to some
+# other common methods: Hermite (c-spline), Bezier, and b-spline. These
+# alternates I coded myself after some extensive research into spline
+# theory.
+#
+# @todo Figure out what's wrong with the Blender bezier interpolation.
+class Spline(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_spline"
+ bl_label = "Spline"
+ bl_description = "Create a spline interplopation between two edges"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ alg = EnumProperty(name = "Spline Algorithm",
+ items = [('Blender', 'Blender', 'Interpolation provided through \"mathutils.geometry\"'),
+ ('Hermite', 'C-Spline', 'C-spline interpolation'),
+ ('Bezier', 'Bézier', 'Bézier interpolation'),
+ ('B-Spline', 'B-Spline', 'B-Spline interpolation')],
+ default = 'Bezier')
+ segments = IntProperty(name = "Segments",
+ description = "Number of segments to use in the interpolation",
+ min = 2, max = 4096,
+ soft_max = 1024,
+ default = 32)
+ flip1 = BoolProperty(name = "Flip Edge",
+ description = "Flip the direction of the spline on edge 1",
+ default = False)
+ flip2 = BoolProperty(name = "Flip Edge",
+ description = "Flip the direction of the spline on edge 2",
+ default = False)
+ ten1 = FloatProperty(name = "Tension",
+ description = "Tension on edge 1",
+ min = -4096.0, max = 4096.0,
+ soft_min = -8.0, soft_max = 8.0,
+ default = 1.0)
+ ten2 = FloatProperty(name = "Tension",
+ description = "Tension on edge 2",
+ min = -4096.0, max = 4096.0,
+ soft_min = -8.0, soft_max = 8.0,
+ default = 1.0)
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.prop(self, "alg")
+ layout.prop(self, "segments")
+ layout.label("Edge 1:")
+ layout.prop(self, "ten1")
+ layout.prop(self, "flip1")
+ layout.label("Edge 2:")
+ layout.prop(self, "ten2")
+ layout.prop(self, "flip2")
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(bpy.context.active_object.data)
+ bm.normal_update()
+
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ seg = self.segments
+ edges = [e for e in bEdges if e.select]
+ verts = [edges[v // 2].verts[v % 2] for v in range(4)]
+
+ if self.flip1:
+ v1 = verts[1]
+ p1_co = verts[1].co
+ p1_dir = verts[1].co - verts[0].co
+ else:
+ v1 = verts[0]
+ p1_co = verts[0].co
+ p1_dir = verts[0].co - verts[1].co
+ if self.ten1 < 0:
+ p1_dir = -1 * p1_dir
+ p1_dir.length = -self.ten1
+ else:
+ p1_dir.length = self.ten1
+
+ if self.flip2:
+ v2 = verts[3]
+ p2_co = verts[3].co
+ p2_dir = verts[2].co - verts[3].co
+ else:
+ v2 = verts[2]
+ p2_co = verts[2].co
+ p2_dir = verts[3].co - verts[2].co
+ if self.ten2 < 0:
+ p2_dir = -1 * p2_dir
+ p2_dir.length = -self.ten2
+ else:
+ p2_dir.length = self.ten2
+
+ # Get the interploted coordinates:
+ if self.alg == 'Blender':
+ pieces = interpolate_bezier(p1_co, p1_dir, p2_dir, p2_co, self.segments)
+ elif self.alg == 'Hermite':
+ pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'HERMITE')
+ elif self.alg == 'Bezier':
+ pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BEZIER')
+ elif self.alg == 'B-Spline':
+ pieces = interpolate_line_line(p1_co, p1_dir, p2_co, p2_dir, self.segments, 1, 'BSPLINE')
+
+ verts = []
+ verts.append(v1)
+ # Add vertices and set the points:
+ for i in range(seg - 1):
+ v = bVerts.new()
+ v.co = pieces[i]
+ verts.append(v)
+ verts.append(v2)
+ # Connect vertices:
+ for i in range(seg):
+ e = bEdges.new((verts[i], verts[i + 1]))
+
+ bm.to_mesh(bpy.context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# Creates edges normal to planes defined between each of two edges and the
+# normal or the plane defined by those two edges.
+# - Select two edges. The must form a plane.
+# - On running the script, eight edges will be created. Delete the
+# extras that you don't need.
+# - The length of those edges is defined by the variable "length"
+#
+# @todo Change method from a cross product to a rotation matrix to make the
+# angle part work.
+# --- todo completed 2/4/2012, but still needs work ---
+# @todo Figure out a way to make +/- predictable
+# - Maybe use angel between edges and vector direction definition?
+# --- TODO COMPLETED ON 2/9/2012 ---
+class Ortho(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_ortho"
+ bl_label = "Angle Off Edge"
+ bl_description = ""
+ bl_options = {'REGISTER', 'UNDO'}
+
+ vert1 = BoolProperty(name = "Vertice 1",
+ description = "Enable edge creation for vertice 1.",
+ default = True)
+ vert2 = BoolProperty(name = "Vertice 2",
+ description = "Enable edge creation for vertice 2.",
+ default = True)
+ vert3 = BoolProperty(name = "Vertice 3",
+ description = "Enable edge creation for vertice 3.",
+ default = True)
+ vert4 = BoolProperty(name = "Vertice 4",
+ description = "Enable edge creation for vertice 4.",
+ default = True)
+ pos = BoolProperty(name = "+",
+ description = "Enable positive direction edges.",
+ default = True)
+ neg = BoolProperty(name = "-",
+ description = "Enable negitive direction edges.",
+ default = True)
+ angle = FloatProperty(name = "Angle",
+ description = "Angle off of the originating edge",
+ min = 0.0, max = 180.0,
+ default = 90.0)
+ length = FloatProperty(name = "Length",
+ description = "Length of created edges.",
+ min = 0.0, max = 1024.0,
+ default = 1.0)
+
+ # For when only one edge is selected (Possible feature to be testd):
+ plane = EnumProperty(name = "Plane",
+ items = [("XY", "X-Y Plane", "Use the X-Y plane as the plane of creation"),
+ ("XZ", "X-Z Plane", "Use the X-Z plane as the plane of creation"),
+ ("YZ", "Y-Z Plane", "Use the Y-Z plane as the plane of creation")],
+ default = "XY")
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.prop(self, "vert1")
+ layout.prop(self, "vert2")
+ layout.prop(self, "vert3")
+ layout.prop(self, "vert4")
+ row = layout.row(align = False)
+ row.alignment = 'EXPAND'
+ row.prop(self, "pos")
+ row.prop(self, "neg")
+ layout.prop(self, "angle")
+ layout.prop(self, "length")
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(bpy.context.active_object.data)
+ bm.normal_update()
+
+ bVerts = bm.verts
+ bEdges = bm.edges
+ edges = [e for e in bEdges if e.select]
+ vectors = []
+
+ # Until I can figure out a better way of handeling it:
+ if len(edges) < 2:
+ bpy.ops.object.editmode_toggle()
+ self.report({'ERROR_INVALID_INPUT'},
+ "You must select two edges.")
+ return {'CANCELLED'}
+
+ verts = [edges[0].verts[0],
+ edges[0].verts[1],
+ edges[1].verts[0],
+ edges[1].verts[1]]
+
+ cos = intersect_line_line(verts[0].co, verts[1].co, verts[2].co, verts[3].co)
+
+ # If the two edges are parallel:
+ if cos == None:
+ self.report({'WARNING'},
+ "Selected lines are parallel: results may be unpredictable.")
+ vectors.append(verts[0].co - verts[1].co)
+ vectors.append(verts[0].co - verts[2].co)
+ vectors.append(vectors[0].cross(vectors[1]))
+ vectors.append(vectors[2].cross(vectors[0]))
+ vectors.append(-vectors[3])
+ else:
+ # Warn the user if they have not chosen two planar edges:
+ if not is_same_co(cos[0], cos[1]):
+ self.report({'WARNING'},
+ "Selected lines are not planar: results may be unpredictable.")
+
+ # This makes the +/- behavior predictable:
+ if (verts[0].co - cos[0]).length < (verts[1].co - cos[0]).length:
+ verts[0], verts[1] = verts[1], verts[0]
+ if (verts[2].co - cos[0]).length < (verts[3].co - cos[0]).length:
+ verts[2], verts[3] = verts[3], verts[2]
+
+ vectors.append(verts[0].co - verts[1].co)
+ vectors.append(verts[2].co - verts[3].co)
+
+ # Normal of the plane formed by vector1 and vector2:
+ vectors.append(vectors[0].cross(vectors[1]))
+
+ # Possible directions:
+ vectors.append(vectors[2].cross(vectors[0]))
+ vectors.append(vectors[1].cross(vectors[2]))
+
+ # Set the length:
+ vectors[3].length = self.length
+ vectors[4].length = self.length
+
+ # Perform any additional rotations:
+ matrix = Matrix.Rotation(radians(90 + self.angle), 3, vectors[2])
+ vectors.append(matrix * -vectors[3]) # vectors[5]
+ matrix = Matrix.Rotation(radians(90 - self.angle), 3, vectors[2])
+ vectors.append(matrix * vectors[4]) # vectors[6]
+ vectors.append(matrix * vectors[3]) # vectors[7]
+ matrix = Matrix.Rotation(radians(90 + self.angle), 3, vectors[2])
+ vectors.append(matrix * -vectors[4]) # vectors[8]
+
+ # Perform extrusions and displacements:
+ # There will be a total of 8 extrusions. One for each vert of each edge.
+ # It looks like an extrusion will add the new vert to the end of the verts
+ # list and leave the rest in the same location.
+ # ----------- EDIT -----------
+ # It looks like I might be able to do this within "bpy.data" with the ".add"
+ # function.
+ # ------- BMESH UPDATE -------
+ # BMesh uses ".new()"
+
+ for v in range(len(verts)):
+ vert = verts[v]
+ if (v == 0 and self.vert1) or (v == 1 and self.vert2) or (v == 2 and self.vert3) or (v == 3 and self.vert4):
+ if self.pos:
+ new = bVerts.new()
+ new.co = vert.co - vectors[5 + (v // 2) + ((v % 2) * 2)]
+ bEdges.new((vert, new))
+ if self.neg:
+ new = bVerts.new()
+ new.co = vert.co + vectors[5 + (v // 2) + ((v % 2) * 2)]
+ bEdges.new((vert, new))
+
+ bm.to_mesh(bpy.context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# Usage:
+# Select an edge and a point or an edge and specify the radius (default is 1 BU)
+# You can select two edges but it might be unpredicatble which edge it revolves
+# around so you might have to play with the switch.
+class Shaft(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_shaft"
+ bl_label = "Shaft"
+ bl_description = "Create a shaft mesh around an axis"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ # Selection defaults:
+ shaftType = 0
+
+ # For tracking if the user has changed selection:
+ last_edge = IntProperty(name = "Last Edge",
+ description = "Tracks if user has changed selected edge",
+ min = 0, max = 1,
+ default = 0)
+ last_flip = False
+
+ edge = IntProperty(name = "Edge",
+ description = "Edge to shaft around.",
+ min = 0, max = 1,
+ default = 0)
+ flip = BoolProperty(name = "Flip Second Edge",
+ description = "Flip the percieved direction of the second edge.",
+ default = False)
+ radius = FloatProperty(name = "Radius",
+ description = "Shaft Radius",
+ min = 0.0, max = 1024.0,
+ default = 1.0)
+ start = FloatProperty(name = "Starting Angle",
+ description = "Angle to start the shaft at.",
+ min = -360.0, max = 360.0,
+ default = 0.0)
+ finish = FloatProperty(name = "Ending Angle",
+ description = "Angle to end the shaft at.",
+ min = -360.0, max = 360.0,
+ default = 360.0)
+ segments = IntProperty(name = "Shaft Segments",
+ description = "Number of sgements to use in the shaft.",
+ min = 1, max = 4096,
+ soft_max = 512,
+ default = 32)
+
+
+ def draw(self, context):
+ layout = self.layout
+
+ if self.shaftType == 0:
+ layout.prop(self, "edge")
+ layout.prop(self, "flip")
+ elif self.shaftType == 3:
+ layout.prop(self, "radius")
+ layout.prop(self, "segments")
+ layout.prop(self, "start")
+ layout.prop(self, "finish")
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ # Make sure these get reset each time we run:
+ self.last_edge = 0
+ self.edge = 0
+
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(bpy.context.active_object.data)
+ bm.normal_update()
+
+ bFaces = bm.faces
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ active = None
+ edges = []
+ verts = []
+
+ # Pre-caclulated values:
+
+ rotRange = [radians(self.start), radians(self.finish)]
+ rads = radians((self.finish - self.start) / self.segments)
+
+ numV = self.segments + 1
+ numE = self.segments
+
+ edges = [e for e in bEdges if e.select]
+
+ # Robustness check: there should at least be one edge selected
+ if len(edges) < 1:
+ bpy.ops.object.editmode_toggle()
+ self.report({'ERROR_INVALID_INPUT'},
+ "At least one edge must be selected.")
+ return {'CANCELLED'}
+
+ # If two edges are selected:
+ if len(edges) == 2:
+ # default:
+ edge = [0, 1]
+ vert = [0, 1]
+
+ # Edge selection:
+ #
+ # By default, we want to shaft around the last selected edge (it
+ # will be the active edge). We know we are using the default if
+ # the user has not changed which edge is being shafted around (as
+ # is tracked by self.last_edge). When they are not the same, then
+ # the user has changed selection.
+ #
+ # We then need to make sure that the active object really is an edge
+ # (robustness check).
+ #
+ # Finally, if the active edge is not the inital one, we flip them
+ # and have the GUI reflect that.
+ if self.last_edge == self.edge:
+ if isinstance(bm.select_history.active, bmesh.types.BMEdge):
+ if bm.select_history.active != edges[edge[0]]:
+ self.last_edge, self.edge = edge[1], edge[1]
+ edge = [edge[1], edge[0]]
+ else:
+ bpy.ops.object.editmode_toggle()
+ self.report({'ERROR_INVALID_INPUT'},
+ "Active geometry is not an edge.")
+ return {'CANCELLED'}
+ elif self.edge == 1:
+ edge = [1, 0]
+
+ verts.append(edges[edge[0]].verts[0])
+ verts.append(edges[edge[0]].verts[1])
+
+ if self.flip:
+ verts = [1, 0]
+
+ verts.append(edges[edge[1]].verts[vert[0]])
+ verts.append(edges[edge[1]].verts[vert[1]])
+
+ self.shaftType = 0
+ # If there is more than one edge selected:
+ # There are some issues with it ATM, so don't expose is it to normal users
+ # @todo Fix edge connection ordering issue
+ elif len(edges) > 2 and bpy.app.debug:
+ if isinstance(bm.select_history.active, bmesh.types.BMEdge):
+ active = bm.select_history.active
+ edges.remove(active)
+ # Get all the verts:
+ edges = order_joined_edges(edges[0])
+ verts = []
+ for e in edges:
+ if verts.count(e.verts[0]) == 0:
+ verts.append(e.verts[0])
+ if verts.count(e.verts[1]) == 0:
+ verts.append(e.verts[1])
+ else:
+ bpy.ops.object.editmode_toggle()
+ self.report({'ERROR_INVALID_INPUT'},
+ "Active geometry is not an edge.")
+ return {'CANCELLED'}
+ self.shaftType = 1
+ else:
+ verts.append(edges[0].verts[0])
+ verts.append(edges[0].verts[1])
+
+ for v in bVerts:
+ if v.select and verts.count(v) == 0:
+ verts.append(v)
+ v.select = False
+ if len(verts) == 2:
+ self.shaftType = 3
+ else:
+ self.shaftType = 2
+
+ # The vector denoting the axis of rotation:
+ if self.shaftType == 1:
+ axis = active.verts[1].co - active.verts[0].co
+ else:
+ axis = verts[1].co - verts[0].co
+
+ # We will need a series of rotation matrices. We could use one which
+ # would be faster but also might cause propagation of error.
+## matrices = []
+## for i in range(numV):
+## matrices.append(Matrix.Rotation((rads * i) + rotRange[0], 3, axis))
+ matrices = [Matrix.Rotation((rads * i) + rotRange[0], 3, axis) for i in range(numV)]
+
+ # New vertice coordinates:
+ verts_out = []
+
+ # If two edges were selected:
+ # - If the lines are not parallel, then it will create a cone-like shaft
+ if self.shaftType == 0:
+ for i in range(len(verts) - 2):
+ init_vec = distance_point_line(verts[i + 2].co, verts[0].co, verts[1].co)
+ co = init_vec + verts[i + 2].co
+ # These will be rotated about the orgin so will need to be shifted:
+ for j in range(numV):
+ verts_out.append(co - (matrices[j] * init_vec))
+ elif self.shaftType == 1:
+ for i in verts:
+ init_vec = distance_point_line(i.co, active.verts[0].co, active.verts[1].co)
+ co = init_vec + i.co
+ # These will be rotated about the orgin so will need to be shifted:
+ for j in range(numV):
+ verts_out.append(co - (matrices[j] * init_vec))
+ # Else if a line and a point was selected:
+ elif self.shaftType == 2:
+ init_vec = distance_point_line(verts[2].co, verts[0].co, verts[1].co)
+ # These will be rotated about the orgin so will need to be shifted:
+ verts_out = [(verts[i].co - (matrices[j] * init_vec)) for i in range(2) for j in range(numV)]
+ # Else the above are not possible, so we will just use the edge:
+ # - The vector defined by the edge is the normal of the plane for the shaft
+ # - The shaft will have radius "radius".
+ else:
+ if is_axial(verts[0].co, verts[1].co) == None:
+ proj = (verts[1].co - verts[0].co)
+ proj[2] = 0
+ norm = proj.cross(verts[1].co - verts[0].co)
+ vec = norm.cross(verts[1].co - verts[0].co)
+ vec.length = self.radius
+ elif is_axial(verts[0].co, verts[1].co) == 'Z':
+ vec = verts[0].co + Vector((0, 0, self.radius))
+ else:
+ vec = verts[0].co + Vector((0, self.radius, 0))
+ init_vec = distance_point_line(vec, verts[0].co, verts[1].co)
+ # These will be rotated about the orgin so will need to be shifted:
+ verts_out = [(verts[i].co - (matrices[j] * init_vec)) for i in range(2) for j in range(numV)]
+
+ # We should have the coordinates for a bunch of new verts. Now add the verts
+ # and build the edges and then the faces.
+
+ newVerts = []
+
+ if self.shaftType == 1:
+ # Vertices:
+ for i in range(numV * len(verts)):
+ new = bVerts.new()
+ new.co = verts_out[i]
+ new.select = True
+ newVerts.append(new)
+
+ # Edges:
+ for i in range(numE):
+ for j in range(len(verts)):
+ e = bEdges.new((newVerts[i + (numV * j)], newVerts[i + (numV * j) + 1]))
+ e.select = True
+ for i in range(numV):
+ for j in range(len(verts) - 1):
+ e = bEdges.new((newVerts[i + (numV * j)], newVerts[i + (numV * (j + 1))]))
+ e.select = True
+
+ # Faces:
+ # There is a problem with this right now
+ for i in range(len(edges)):
+ for j in range(numE):
+ f = bFaces.new((newVerts[i], newVerts[i + 1],
+ newVerts[i + (numV * j) + 1], newVerts[i + (numV * j)]))
+ f.normal_update()
+ else:
+ # Vertices:
+ for i in range(numV * 2):
+ new = bVerts.new()
+ new.co = verts_out[i]
+ new.select = True
+ newVerts.append(new)
+
+ # Edges:
+ for i in range(numE):
+ e = bEdges.new((newVerts[i], newVerts[i + 1]))
+ e.select = True
+ e = bEdges.new((newVerts[i + numV], newVerts[i + numV + 1]))
+ e.select = True
+ for i in range(numV):
+ e = bEdges.new((newVerts[i], newVerts[i + numV]))
+ e.select = True
+
+ # Faces:
+ for i in range(numE):
+ f = bFaces.new((newVerts[i], newVerts[i + 1],
+ newVerts[i + numV + 1], newVerts[i + numV]))
+ f.normal_update()
+
+ bm.to_mesh(bpy.context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# "Slices" edges crossing a plane defined by a face.
+# @todo Selecting a face as the cutting plane will cause Blender to crash when
+# using "Rip".
+class Slice(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_slice"
+ bl_label = "Slice"
+ bl_description = "Cuts edges at the plane defined by a selected face."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ make_copy = BoolProperty(name = "Make Copy",
+ description = "Make new vertices at intersection points instead of spliting the edge",
+ default = False)
+ rip = BoolProperty(name = "Rip",
+ description = "Split into two edges that DO NOT share an intersection vertice.",
+ default = False)
+ pos = BoolProperty(name = "Positive",
+ description = "Remove the portion on the side of the face normal",
+ default = False)
+ neg = BoolProperty(name = "Negative",
+ description = "Remove the portion on the side opposite of the face normal",
+ default = False)
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.prop(self, "make_copy")
+ if not self.make_copy:
+ layout.prop(self, "rip")
+ layout.label("Remove Side:")
+ layout.prop(self, "pos")
+ layout.prop(self, "neg")
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(context.active_object.data)
+ bm.normal_update()
+
+ # For easy access to verts, edges, and faces:
+ bVerts = bm.verts
+ bEdges = bm.edges
+ bFaces = bm.faces
+
+ face = None
+ normal = None
+
+ # Find the selected face. This will provide the plane to project onto:
+ # - First check to use the active face. This allows users to just
+ # select a bunch of faces with the last being the cutting plane.
+ # This is try and make the tool act more like a built-in Blender
+ # function.
+ # - If that fails, then use the first found selected face in the BMesh
+ # face list.
+ if isinstance(bm.select_history.active, bmesh.types.BMFace):
+ face = bm.select_history.active
+ normal = bm.select_history.active.normal
+ bm.select_history.active.select = False
+ else:
+ for f in bFaces:
+ if f.select:
+ face = f
+ normal = f.normal
+ f.select = False
+ break
+
+ # If we don't find a selected face, we have problem. Exit:
+ if face == None:
+ bpy.ops.object.editmode_toggle()
+ self.report({'ERROR_INVALID_INPUT'},
+ "You must select a face as the cutting plane.")
+ return {'CANCELLED'}
+ # Warn the user if they are using an n-gon. We can work with it, but it
+ # might lead to some odd results.
+ elif len(face.verts) > 4 and not is_face_planar(face):
+ self.report({'WARNING'},
+ "Selected face is an n-gon. Results may be unpredictable.")
+
+ # @todo DEBUG TRACKER - DELETE WHEN FINISHED:
+ dbg = 0
+ if bpy.app.debug:
+ print(len(bEdges))
+
+ # Iterate over the edges:
+ for e in bEdges:
+ # @todo DEBUG TRACKER - DELETE WHEN FINISHED:
+ if bpy.app.debug:
+ print(dbg)
+ dbg = dbg + 1
+
+ # Get the end verts on the edge:
+ v1 = e.verts[0]
+ v2 = e.verts[1]
+
+ # Make sure that verts are not a part of the cutting plane:
+ if e.select and (v1 not in face.verts and v2 not in face.verts):
+ if len(face.verts) < 5: # Not an n-gon
+ intersection = intersect_line_face(e, face, True)
+ else:
+ intersection = intersect_line_plane(v1.co, v2.co, face.verts[0].co, normal)
+
+ # More debug info - I think this can stay.
+ if bpy.app.debug:
+ print("Intersection", end = ': ')
+ print(intersection)
+
+ # If an intersection exists find the distance of each of the end
+ # points from the plane, with "positive" being in the direction
+ # of the cutting plane's normal. If the points are on opposite
+ # side of the plane, then it intersects and we need to cut it.
+ if intersection != None:
+ d1 = distance_point_to_plane(v1.co, face.verts[0].co, normal)
+ d2 = distance_point_to_plane(v2.co, face.verts[0].co, normal)
+ # If they have different signs, then the edge crosses the
+ # cutting plane:
+ if abs(d1 + d2) < abs(d1 - d2):
+ # Make the first vertice the positive vertice:
+ if d1 < d2:
+ v2, v1 = v1, v2
+ if self.make_copy:
+ new = bVerts.new()
+ new.co = intersection
+ new.select = True
+ elif self.rip:
+ newV1 = bVerts.new()
+ newV1.co = intersection
+
+ if bpy.app.debug:
+ print("newV1 created", end = '; ')
+
+ newV2 = bVerts.new()
+ newV2.co = intersection
+
+ if bpy.app.debug:
+ print("newV2 created", end = '; ')
+
+ newE1 = bEdges.new((v1, newV1))
+ newE2 = bEdges.new((v2, newV2))
+
+ if bpy.app.debug:
+ print("new edges created", end = '; ')
+
+ bEdges.remove(e)
+
+ if bpy.app.debug:
+ print("old edge removed.")
+ print("We're done with this edge.")
+ else:
+ new = list(bmesh.utils.edge_split(e, v1, 0.5))
+ new[1].co = intersection
+ e.select = False
+ new[0].select = False
+ if self.pos:
+ bEdges.remove(new[0])
+ if self.neg:
+ bEdges.remove(e)
+
+ bm.to_mesh(context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# This projects the selected edges onto the selected plane. This projects both
+# points on the selected edge.
+class Project(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_project"
+ bl_label = "Project"
+ bl_description = "Projects the selected vertices/edges onto the selected plane."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ make_copy = BoolProperty(name = "Make Copy",
+ description = "Make a duplicate of the vertices instead of moving it",
+ default = False)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "make_copy")
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(context.active_object.data)
+ bm.normal_update()
+
+ bFaces = bm.faces
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ fVerts = []
+
+ # Find the selected face. This will provide the plane to project onto:
+ # @todo Check first for an active face
+ for f in bFaces:
+ if f.select:
+ for v in f.verts:
+ fVerts.append(v)
+ normal = f.normal
+ f.select = False
+ break
+
+ for v in bVerts:
+ if v.select:
+ if v in fVerts:
+ v.select = False
+ continue
+ d = distance_point_to_plane(v.co, fVerts[0].co, normal)
+ if self.make_copy:
+ temp = v
+ v = bVerts.new()
+ v.co = temp.co
+ vector = normal
+ vector.length = abs(d)
+ v.co = v.co - (vector * sign(d))
+ v.select = False
+
+ bm.to_mesh(context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# Project_End is for projecting/extending an edge to meet a plane.
+# This is used be selecting a face to define the plane then all the edges.
+# The add-on will then move the vertices in the edge that is closest to the
+# plane to the coordinates of the intersection of the edge and the plane.
+class Project_End(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_project_end"
+ bl_label = "Project (End Point)"
+ bl_description = "Projects the vertice of the selected edges closest to a plane onto that plane."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ make_copy = BoolProperty(name = "Make Copy",
+ description = "Make a duplicate of the vertice instead of moving it",
+ default = False)
+ keep_length = BoolProperty(name = "Keep Edge Length",
+ description = "Maintain edge lengths",
+ default = False)
+ use_force = BoolProperty(name = "Use opposite vertices",
+ description = "Force the usage of the vertices at the other end of the edge",
+ default = False)
+ use_normal = BoolProperty(name = "Project along normal",
+ description = "Use the plane's normal as the projection direction",
+ default = False)
+
+ def draw(self, context):
+ layout = self.layout
+## layout.prop(self, "keep_length")
+ if not self.keep_length:
+ layout.prop(self, "use_normal")
+## else:
+## self.report({'ERROR_INVALID_INPUT'}, "Maintaining edge length not yet supported")
+## self.report({'WARNING'}, "Projection may result in unexpected geometry")
+ layout.prop(self, "make_copy")
+ layout.prop(self, "use_force")
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(context.active_object.data)
+ bm.normal_update()
+
+ bFaces = bm.faces
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ fVerts = []
+
+ # Find the selected face. This will provide the plane to project onto:
+ for f in bFaces:
+ if f.select:
+ for v in f.verts:
+ fVerts.append(v)
+ normal = f.normal
+ f.select = False
+ break
+
+ for e in bEdges:
+ if e.select:
+ v1 = e.verts[0]
+ v2 = e.verts[1]
+ if v1 in fVerts or v2 in fVerts:
+ e.select = False
+ continue
+ intersection = intersect_line_plane(v1.co, v2.co, fVerts[0].co, normal)
+ if intersection != None:
+ # Use abs because we don't care what side of plane we're on:
+ d1 = distance_point_to_plane(v1.co, fVerts[0].co, normal)
+ d2 = distance_point_to_plane(v2.co, fVerts[0].co, normal)
+ # If d1 is closer than we use v1 as our vertice:
+ # "xor" with 'use_force':
+ if (abs(d1) < abs(d2)) is not self.use_force:
+ if self.make_copy:
+ v1 = bVerts.new()
+ v1.co = e.verts[0].co
+ if self.keep_length:
+ v1.co = intersection
+ elif self.use_normal:
+ vector = normal
+ vector.length = abs(d1)
+ v1.co = v1.co - (vector * sign(d1))
+ else:
+ v1.co = intersection
+ else:
+ if self.make_copy:
+ v2 = bVerts.new()
+ v2.co = e.verts[1].co
+ if self.keep_length:
+ v2.co = intersection
+ elif self.use_normal:
+ vector = normal
+ vector.length = abs(d2)
+ v2.co = v2.co - (vector * sign(d2))
+ else:
+ v2.co = intersection
+ e.select = False
+
+ bm.to_mesh(context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# Edge Fillet
+#
+# Blender currently does not have a CAD-style edge-based fillet function. This
+# is my atempt to create one. It should take advantage of BMesh and the ngon
+# capabilities for non-destructive modeling, if possible. This very well may
+# not result in nice quads and it will be up to the artist to clean up the mesh
+# back into quads if necessary.
+#
+# Assumptions:
+# - Faces are planar. This should, however, do a check an warn otherwise.
+#
+# Developement Process:
+# Because this will eventaully prove to be a great big jumble of code and
+# various functionality, this is to provide an outline for the developement
+# and functionality wanted at each milestone.
+# 1) intersect_line_face: function to find the intersection point, if it
+# exists, at which a line intersects a face. The face does not have to
+# be planar, and can be an ngon. This will allow for a point to be placed
+# on the actual mesh-face for non-planar faces.
+# 2) Minimal propagation, single edge: Filleting of a single edge without
+# propagation of the fillet along "tangent" edges.
+# 3) Minimal propagation, multiple edges: Perform said fillet along/on
+# multiple edges.
+# 4) "Tangency" detection code: because we have a mesh based geometry, this
+# have to make an educated guess at what is actually supposed to be
+# treated as tangent and what constitutes a sharp edge. This should
+# respect edges marked as sharp (does not propagate passed an
+# intersecting edge that is marked as sharp).
+# 5) Tangent propagation, single edge: Filleting of a single edge using the
+# above tangency detection code to continue the fillet to adjacent
+# "tangent" edges.
+# 6) Tangent propagation, multiple edges: Same as above, but with multiple
+# edges selected. If multiple edges were selected along the same
+# tangency path, only one edge will be filleted. The others must be
+# ignored/discarded.
+class Fillet(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_fillet"
+ bl_label = "Edge Fillet"
+ bl_description = "Fillet the selected edges."
+ bl_options = {'REGISTER', 'UNDO'}
+
+ radius = FloatProperty(name = "Radius",
+ description = "Radius of the edge fillet",
+ min = 0.00001, max = 1024.0,
+ default = 0.5)
+ prop = EnumProperty(name = "Propagation",
+ items = [("m", "Minimal", "Minimal edge propagation"),
+ ("t", "Tangential", "Tangential edge propagation")],
+ default = "m")
+ prop_fac = FloatProperty(name = "Propagation Factor",
+ description = "Corner detection sensitivity factor for tangential propagation",
+ min = 0.0, max = 100.0,
+ default = 25.0)
+ deg_seg = FloatProperty(name = "Degrees/Section",
+ description = "Approximate degrees per section",
+ min = 0.00001, max = 180.0,
+ default = 10.0)
+ res = IntProperty(name = "Resolution",
+ description = "Resolution of the fillet",
+ min = 1, max = 1024,
+ default = 8)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "radius")
+ layout.prop(self, "prop")
+ if self.prop == "t":
+ layout.prop(self, "prop_fac")
+ layout.prop(self, "deg_seg")
+ layout.prop(self, "res")
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(bpy.context.active_object.data)
+ bm.normal_update()
+
+ bFaces = bm.faces
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ # Robustness check: this does not support n-gons (at least for now)
+ # because I have no idea how to handle them righ now. If there is
+ # an n-gon in the mesh, warn the user that results may be nuts because
+ # of it.
+ #
+ # I'm not going to cause it to exit if there are n-gons, as they may
+ # not be encountered.
+ # @todo I would like this to be a confirmation dialoge of some sort
+ # @todo I would REALLY like this to just handle n-gons. . . .
+ for f in bFaces:
+ if len(face.verts) > 4:
+ self.report({'WARNING'},
+ "Mesh contains n-gons which are not supported. Operation may fail.")
+ break
+
+ # Get the selected edges:
+ # Robustness check: boundary and wire edges are not fillet-able.
+ edges = [e for e in bEdges if e.select and not e.is_boundary and not e.is_wire]
+
+ for e in edges:
+ axis_points = fillet_axis(e, self.radius)
+
+
+ bm.to_mesh(bpy.context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+# For testing the mess that is "intersect_line_face" for possible math errors.
+# This will NOT be directly exposed to end users: it will always require running
+# Blender in debug mode.
+# So far no errors have been found. Thanks to anyone who tests and reports bugs!
+class Intersect_Line_Face(bpy.types.Operator):
+ bl_idname = "mesh.edgetools_ilf"
+ bl_label = "ILF TEST"
+ bl_description = "TEST ONLY: INTERSECT_LINE_FACE"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return(ob and ob.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+
+ def execute(self, context):
+ # Make sure we really are in debug mode:
+ if not bpy.app.debug:
+ self.report({'ERROR_INVALID_INPUT'},
+ "This is for debugging only: you should not be able to run this!")
+ return {'CANCELLED'}
+
+ bpy.ops.object.editmode_toggle()
+ bm = bmesh.new()
+ bm.from_mesh(bpy.context.active_object.data)
+ bm.normal_update()
+
+ bFaces = bm.faces
+ bEdges = bm.edges
+ bVerts = bm.verts
+
+ face = None
+ for f in bFaces:
+ if f.select:
+ face = f
+ break
+
+ edge = None
+ for e in bEdges:
+ if e.select and not e in face.edges:
+ edge = e
+ break
+
+ point = intersect_line_face(edge, face, True)
+
+ if point != None:
+ new = bVerts.new()
+ new.co = point
+ else:
+ bpy.ops.object.editmode_toggle()
+ self.report({'ERROR_INVALID_INPUT'}, "point was \"None\"")
+ return {'CANCELLED'}
+
+ bm.to_mesh(bpy.context.active_object.data)
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+class VIEW3D_MT_edit_mesh_edgetools(bpy.types.Menu):
+ bl_label = "EdgeTools"
+
+ def draw(self, context):
+ global integrated
+ layout = self.layout
+
+ layout.operator("mesh.edgetools_extend")
+ layout.operator("mesh.edgetools_spline")
+ layout.operator("mesh.edgetools_ortho")
+ layout.operator("mesh.edgetools_shaft")
+ layout.operator("mesh.edgetools_slice")
+ layout.operator("mesh.edgetools_project")
+ layout.operator("mesh.edgetools_project_end")
+ if bpy.app.debug:
+ ## Not ready for prime-time yet:
+ layout.operator("mesh.edgetools_fillet")
+ ## For internal testing ONLY:
+ layout.operator("mesh.edgetools_ilf")
+ # If TinyCAD VTX exists, add it to the menu.
+ # @todo This does not work.
+ if integrated and bpy.app.debug:
+ layout.operator(EdgeIntersections.bl_idname, text="Edges V Intersection").mode = -1
+ layout.operator(EdgeIntersections.bl_idname, text="Edges T Intersection").mode = 0
+ layout.operator(EdgeIntersections.bl_idname, text="Edges X Intersection").mode = 1
+
+
+def menu_func(self, context):
+ self.layout.menu("VIEW3D_MT_edit_mesh_edgetools")
+ self.layout.separator()
+
+
+# define classes for registration
+classes = [VIEW3D_MT_edit_mesh_edgetools,
+ Extend,
+ Spline,
+ Ortho,
+ Shaft,
+ Slice,
+ Project,
+ Project_End,
+ Fillet,
+ Intersect_Line_Face]
+
+
+# registering and menu integration
+def register():
+ global integrated
+ if int(bpy.app.build_revision[0:5]) < 44800:
+ print("Error in Edgetools:")
+ print("This version of Blender does not support the necessary BMesh API.")
+ print("Please download Blender 2.63 or newer.")
+ return {'ERROR'}
+
+ for c in classes:
+ bpy.utils.register_class(c)
+
+ # I would like this script to integrate the TinyCAD VTX menu options into
+ # the edge tools menu if it exists. This should make the UI a little nicer
+ # for users.
+ # @todo Remove TinyCAD VTX menu entries and add them too EdgeTool's menu
+ import inspect, os.path
+
+ path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+ if os.path.isfile(path + "\mesh_edge_intersection_tools.py"):
+ print("EdgeTools UI integration test - TinyCAD VTX Found")
+ integrated = True
+
+ bpy.types.VIEW3D_MT_edit_mesh_specials.prepend(menu_func)
+
+
+# unregistering and removing menus
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+
+ bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/__init__.py b/release/scripts/addons_contrib/mesh_extra_tools/__init__.py
new file mode 100644
index 0000000..b2fb9c2
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/__init__.py
@@ -0,0 +1,159 @@
+# ##### 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 LICENSE BLOCK #####
+# Contributed to by
+# meta-androcto #
+
+bl_info = {
+ "name": "Extra Tools",
+ "author": "various",
+ "version": (0, 1),
+ "blender": (2, 64, 0),
+ "location": "View3D > Toolbar and View3D > Specials (W-key)",
+ "description": "Add extra mesh edit tools",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=32711",
+ "category": "Mesh"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(mesh_bump)
+ imp.reload(face_inset_fillet)
+ imp.reload(mesh_bevel_witold)
+ imp.reload(mesh_filletplus)
+ imp.reload(mesh_normal_smooth)
+ imp.reload(mesh_polyredux)
+ imp.reload(mesh_vertex_chamfer)
+ imp.reload(mesh_mextrude_plus)
+
+else:
+ from . import mesh_bump
+ from . import face_inset_fillet
+ from . import mesh_bevel_witold
+ from . import mesh_filletplus
+ from . import mesh_normal_smooth
+ from . import mesh_polyredux
+ from . import mesh_vertex_chamfer
+ from . import mesh_mextrude_plus
+
+import bpy
+
+class VIEW3D_MT_edit_mesh_extras(bpy.types.Menu):
+ # Define the "Extras" menu
+ bl_idname = "VIEW3D_MT_edit_mesh_extras"
+ bl_label = "Extra Tools"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("faceinfillet.op0_id",
+ text="Face Inset Fillet")
+ layout.operator("fillet.op0_id",
+ text="Edge Fillet Plus")
+ layout.operator("object.mextrude",
+ text="Multi Extrude")
+ layout.operator("mesh.bump",
+ text="Inset Extrude Bump")
+ layout.operator("mesh.mbevel",
+ text="Bevel Selected")
+ layout.operator("mesh.vertex_chamfer",
+ text="Vertex Chamfer")
+ layout.operator("mesh.polyredux",
+ text="Poly Redux")
+ layout.operator("normal.smooth",
+ text="Normal Smooth")
+
+
+class ExtrasPanel(bpy.types.Panel):
+ bl_label = 'Mesh Extra Tools'
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_context = 'mesh_edit'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.split(0.80)
+ row.operator('faceinfillet.op0_id', text = 'Face Inset Fillet', icon = 'PLUGIN')
+ row.operator('help.face_inset', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('fillet.op0_id', text = 'Edge Fillet plus', icon = 'PLUGIN')
+ row.operator('help.edge_fillet', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('object.mextrude', text = 'Multi Face Extrude', icon = 'PLUGIN')
+ row.operator('help.mextrude', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('mesh.bump', text = 'Inset Bump', icon = 'PLUGIN')
+ row.operator('help.bump', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('mesh.mbevel', text = 'Bevel Selected', icon = 'PLUGIN')
+ row.operator('help.edge_bevel', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('mesh.vertex_chamfer', text = 'Vertex Chamfer' , icon = 'PLUGIN')
+ row.operator('help.vertexchamfer', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('mesh.polyredux', text = 'Poly Redux', icon = 'PLUGIN')
+ row.operator('help.polyredux', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('normal.smooth', text = 'Normal Smooth', icon = 'PLUGIN')
+ row.operator('help.normal_smooth', text = '', icon = 'INFO')
+ row = layout.split(0.50)
+ row.operator('mesh.flip_normals', text = 'Normals Flip')
+ row.operator('mesh.remove_doubles', text = 'Remove Doubles')
+
+
+# Multi Extrude Panel
+
+class ExtrudePanel(bpy.types.Panel):
+ bl_label = 'Multi Extrude Plus'
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.split(0.80)
+ row.operator('object.mextrude', text = 'Multi Face Extrude', icon = 'PLUGIN')
+ row.operator('help.mextrude', text = '', icon = 'INFO')
+ row = layout.split(0.80)
+ row.operator('object.mesh2bones', text = 'Add Armature', icon = 'PLUGIN')
+ row.operator('help.addarm', text = '', icon = 'INFO')
+
+# Define "Extras" menu
+def menu_func(self, context):
+ self.layout.menu('VIEW3D_MT_edit_mesh_extras', icon='PLUGIN')
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ # Add "Extras" menu to the "Add Mesh" menu
+ bpy.types.VIEW3D_MT_edit_mesh_specials.prepend(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ # Remove "Extras" menu from the "Add Mesh" menu.
+ bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/face_inset_fillet.py b/release/scripts/addons_contrib/mesh_extra_tools/face_inset_fillet.py
new file mode 100644
index 0000000..bc4824e
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/face_inset_fillet.py
@@ -0,0 +1,226 @@
+# -*- coding: utf-8 -*-
+
+# ***** 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 *****
+# based completely on addon by zmj100
+# ------ ------
+import bpy
+import bmesh
+from bpy.props import FloatProperty, IntProperty, BoolProperty, EnumProperty
+from math import tan, cos, degrees, radians, sin
+from mathutils import Matrix
+
+# ------ ------
+def edit_mode_out():
+ bpy.ops.object.mode_set(mode = 'OBJECT')
+
+def edit_mode_in():
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+def a_rot(ang, rp, axis, q):
+ return (Matrix.Rotation(ang, 3, axis) * (q - rp)) + rp
+
+# ------ ------
+def f_(bme, list_0, opp, adj1, n_, out, radius, en0, kp):
+
+ list_del = []
+ for fi in list_0:
+ f = bme.faces[fi]
+ f.select_set(0)
+ list_del.append(f)
+ f.normal_update()
+ list_2 = [v.index for v in f.verts]
+ dict_0 = {}
+ list_1 = []
+ n = len(list_2)
+ for i in range(n):
+ dict_0[i] = []
+ p = (bme.verts[ list_2[i] ].co).copy()
+ p1 = (bme.verts[ list_2[(i - 1) % n] ].co).copy()
+ p2 = (bme.verts[ list_2[(i + 1) % n] ].co).copy()
+ dict_0[i].append(bme.verts[list_2[i]])
+ vec1 = p - p1
+ vec2 = p - p2
+ ang = vec1.angle(vec2)
+ adj = opp / tan(ang * 0.5)
+ h = (adj ** 2 + opp ** 2) ** 0.5
+ if round(degrees(ang)) == 180 or round(degrees(ang)) == 0.0:
+ p6 = a_rot(radians(90), p, vec1, p + ((f.normal).normalized() * opp) if out == True else p - ((f.normal).normalized() * opp))
+ list_1.append(p6)
+ else:
+ p6 = a_rot(-radians(90), p, ((p - (vec1.normalized() * adj)) - (p - (vec2.normalized() * adj))), p + ((f.normal).normalized() * h) if out == True else p - ((f.normal).normalized() * h))
+ list_1.append(p6)
+
+ list_2 = []
+ n1_ = len(list_1)
+ for j in range(n1_):
+ q = list_1[j]
+ q1 = list_1[(j - 1) % n1_]
+ q2 = list_1[(j + 1) % n1_]
+ vec1_ = q - q1
+ vec2_ = q - q2
+ ang_ = vec1_.angle(vec2_)
+ if round(degrees(ang_)) == 180 or round(degrees(ang_)) == 0.0:
+ bme.verts.new(q)
+ bme.verts.index_update()
+ list_2.append(bme.verts[-1])
+ dict_0[j].append(bme.verts[-1])
+ else:
+ opp_ = adj1
+ if radius == False:
+ h_ = adj1 * (1 / cos(ang_ * 0.5))
+ d = adj1
+ elif radius == True:
+ h_ = opp_ / sin(ang_ * 0.5)
+ d = opp_ / tan(ang_ * 0.5)
+
+ q3 = q - (vec1_.normalized() * d)
+ q4 = q - (vec2_.normalized() * d)
+ rp_ = q - ((q - ((q3 + q4) * 0.5)).normalized() * h_)
+ axis_ = vec1_.cross(vec2_)
+ vec3_ = rp_ - q3
+ vec4_ = rp_ - q4
+ rot_ang = vec3_.angle(vec4_)
+ list_3 = []
+
+ for o in range(n_ + 1):
+ q5 = a_rot((rot_ang * o / n_), rp_, axis_, q4)
+ bme.verts.new(q5)
+ bme.verts.index_update()
+ dict_0[j].append(bme.verts[-1])
+ list_3.append(bme.verts[-1])
+ list_3.reverse()
+ list_2.extend(list_3)
+
+ if out == False:
+ bme.faces.new(list_2)
+ bme.faces.index_update()
+ bme.faces[-1].select_set(1)
+ elif out == True and kp == True:
+ bme.faces.new(list_2)
+ bme.faces.index_update()
+ bme.faces[-1].select_set(1)
+
+ n2_ = len(dict_0)
+ for o in range(n2_):
+ list_a = dict_0[o]
+ list_b = dict_0[(o + 1) % n2_]
+ bme.faces.new( [ list_a[0], list_b[0], list_b[-1], list_a[1] ] )
+ bme.faces.index_update()
+
+ if en0 == 'opt0':
+ for k in dict_0:
+ if len(dict_0[k]) > 2:
+ bme.faces.new(dict_0[k])
+ bme.faces.index_update()
+ if en0 == 'opt1':
+ for k_ in dict_0:
+ q_ = dict_0[k_][0]
+ dict_0[k_].pop(0)
+ n3_ = len(dict_0[k_])
+ for kk in range(n3_ - 1):
+ bme.faces.new( [ dict_0[k_][kk], dict_0[k_][(kk + 1) % n3_], q_ ] )
+ bme.faces.index_update()
+
+
+ del_ = [bme.faces.remove(f) for f in list_del]
+ del del_
+
+# ------ operator 0 ------
+class faceinfillet_op0(bpy.types.Operator):
+ bl_idname = 'faceinfillet.op0_id'
+ bl_label = 'Face Inset Fillet'
+ bl_description = 'inset selected faces'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ opp = FloatProperty( name = '', default = 0.04, min = 0, max = 100.0, step = 1, precision = 3 ) # inset amount
+ n_ = IntProperty( name = '', default = 4, min = 1, max = 100, step = 1 ) # number of sides
+ adj1 = FloatProperty( name = '', default = 0.04, min = 0.00001, max = 100.0, step = 1, precision = 3 )
+ out = BoolProperty( name = 'Out', default = False )
+ radius = BoolProperty( name = 'Radius', default = False )
+ en0 = EnumProperty( items =( ('opt0', 'Type 1', ''), ('opt1', 'Type 2', '') ), name = '', default = 'opt0' )
+ kp = BoolProperty( name = 'Keep face', default = False )
+
+ def draw(self, context):
+ layout = self.layout
+ box = layout.box()
+ box.prop(self, 'en0', text = 'Corner type')
+ row0 = box.row(align = True)
+ row0.prop(self, 'out')
+ if self.out == True:
+ row0.prop(self, 'kp')
+ row = box.split(0.40, align = True)
+ row.label('Inset amount:')
+ row.prop(self, 'opp')
+ row1 = box.split(0.60, align = True)
+ row1.label('Number of sides:')
+ row1.prop(self, 'n_', slider = True)
+ box.prop(self, 'radius')
+ row2 = box.split(0.40, align = True)
+ if self.radius == True:
+ row2.label('Radius:')
+ else:
+ row2.label('Distance:')
+ row2.prop(self, 'adj1')
+
+ def execute(self, context):
+ opp = self.opp
+ n_ = self.n_
+ adj1 = self.adj1
+ out = self.out
+ radius = self.radius
+ en0 = self.en0
+ kp = self.kp
+
+ edit_mode_out()
+ ob_act = context.active_object
+ bme = bmesh.new()
+ bme.from_mesh(ob_act.data)
+
+ list_0 = [ f.index for f in bme.faces if f.select and f.is_valid ]
+
+ if len(list_0) == 0:
+ self.report({'INFO'}, 'No faces selected unable to continue.')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(list_0) != 0:
+ f_(bme, list_0, opp, adj1, n_, out, radius, en0, kp)
+
+ bme.to_mesh(ob_act.data)
+ edit_mode_in()
+ return {'FINISHED'}
+
+class inset_help(bpy.types.Operator):
+ bl_idname = 'help.face_inset'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Select a face or faces & inset.')
+ layout.label('Inset square, circle or outside.')
+ layout.label('To Help:')
+ layout.label('Circle: use remove doubles to tidy joins.')
+ layout.label('Outset: select & use normals flip before extruding.')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 350)
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_bevel_witold.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_bevel_witold.py
new file mode 100644
index 0000000..01b0f95
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_bevel_witold.py
@@ -0,0 +1,198 @@
+# ##### 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 LICENSE BLOCK #####
+'''
+Bevel add-on
+'''
+#--- ### Header
+bl_info = {
+ "name": "Bevel witold",
+ "author": "Witold Jaworski",
+ "version": (1, 2, 0),
+ "blender": (2, 57, 0),
+ "api": 36147,
+ "location": "View3D >Specials (W-key)",
+ "category": "Mesh",
+ "description": "Bevels selected edges",
+ "warning": "",
+ "wiki_url": "http://airplanes3d.net/scripts-252_e.xml",
+ "tracker_url": "http://airplanes3d.net/track-252_e.xml"
+ }
+#--- ### Change log
+#2011-08-08 Witold Jaworski: added "Vertex only" feature
+#--- ### Imports
+import bpy
+from bpy.utils import register_module, unregister_module
+from bpy.props import FloatProperty, IntProperty, BoolProperty
+from math import log10, floor, pow
+#--- ### Constants
+DEBUG = 0 #Debug flag - just some text printed on the console...
+#--- ### Core operation
+def bevel(obj, width, use_vertices):
+ """Bevels selected edges of the mesh
+ Arguments:
+ @obj (Object): an object with a mesh.
+ It should have some edges selected
+ @width (float): width of the bevel
+ @use_vertices (bool): True, when bevel only vertices. False otherwise
+ This function should be called in the Edit Mode, only!
+ """
+ #
+ #edge = bpy.types.MeshEdge
+ #obj = bpy.types.Object
+ #bevel = bpy.types.BevelModifier
+
+ bpy.ops.object.editmode_toggle() #switch into OBJECT mode
+ #adding the Bevel modifier
+ bpy.ops.object.modifier_add(type = 'BEVEL')
+ bevel = obj.modifiers[-1] #the new modifier is always added at the end
+ bevel.limit_method = 'WEIGHT'
+ bevel.edge_weight_method = 'LARGEST'
+ bevel.width = width
+ bevel.use_only_vertices = use_vertices
+ #moving it up, to the first position on the modifier stack:
+ while obj.modifiers[0] != bevel:
+ bpy.ops.object.modifier_move_up(modifier = bevel.name)
+
+ for elm in (obj.data.vertices if use_vertices else obj.data.edges):
+ if elm.select:
+ elm.bevel_weight = 1.0
+
+ bpy.ops.object.modifier_apply(apply_as = 'DATA', modifier = bevel.name)
+
+ #clean up after applying our modifier: remove bevel weights:
+ for elm in (obj.data.vertices if use_vertices else obj.data.edges):
+ if elm.select:
+ elm.bevel_weight = 0.0
+
+ bpy.ops.object.editmode_toggle() #switch back into EDIT_MESH mode
+
+class bevel_help(bpy.types.Operator):
+ bl_idname = 'help.edge_bevel'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Select A edge or edges & bevel.')
+ layout.label('or Select 2 or more verices & bevel.')
+ layout.label('To Help:')
+ layout.label('best used on flat edges & simple edgeflow')
+ layout.label('may error if vert joins multiple edges/complex edge selection')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 350)
+#--- ### Operator
+class Bevel(bpy.types.Operator):
+ ''' Bevels selected edges of the mesh'''
+ bl_idname = "mesh.mbevel" #it is not named mesh.bevel, to not confuse with the standard bevel in the future...
+ bl_label = "Bevel Selected"
+ bl_description = "Bevels selected edges"
+ bl_options = {'REGISTER', 'UNDO'} #Set this options, if you want to update
+ # parameters of this operator interactively
+ # (in the Tools pane)
+ #--- parameters
+ use_vertices = BoolProperty(name="Only Vertices", description="Bevel vertices (corners), not edges", default = False)
+
+ width = FloatProperty(name="Width", description="Bevel width value (it is multiplied by 10^Exponent)",
+ subtype = 'DISTANCE', default = 0.1, min = 0.0,
+ step = 1, precision = 2)
+# exponent = IntProperty(name="Exponent", description="Order of magnitude of the bevel width (the power of 10)", default = 0)
+
+ use_scale = BoolProperty(name="Use object scale", description="Multiply bevel width by the scale of this object", default = False)
+
+ #--- other fields
+ LAST_VERT_NAME = "mesh.mbevel.last_vert" #the name of the custom scene property
+ LAST_WIDTH_NAME = "mesh.mbevel.last_width" #the name of the custom scene property
+ LAST_EXP_NAME = "mesh.mbevel.last_exponent" #the name of the custom scene property
+ LAST_SCALE_NAME = "mesh.mbevel.last_scale" #scale Bevel width by the object scale
+ #--- Blender interface methods
+ @classmethod
+ def poll(cls,context):
+ return (context.mode == 'EDIT_MESH')
+
+ def invoke(self, context, event):
+ #input validation:
+ # 1. Require single-user mesh (modifiers cannot be applied to the multi-user ones):
+ obj = context.object
+ if obj.data.users > 1:
+ self.report(type='ERROR', message="Make this mesh single-user, first")
+ return {'CANCELLED'}
+ # 2. is there anything selected?
+ self.use_vertices = context.scene.get(self.LAST_VERT_NAME, self.use_vertices)
+
+ bpy.ops.object.editmode_toggle()
+
+ if self.use_vertices :
+ selected = list(filter(lambda e: e.select, context.object.data.vertices))
+ else:
+ selected = list(filter(lambda e: e.select, context.object.data.edges))
+
+ bpy.ops.object.editmode_toggle()
+
+ if len(selected) > 0:
+ self.use_scale = context.object.get(self.LAST_SCALE_NAME, self.use_scale)
+
+ #setup the default width, to avoid user surprises :)
+ def_exp = floor(log10(obj.dimensions.length)) #heuristic: default width exponent is derived from the object size...
+ self.exponent = context.scene.get(self.LAST_EXP_NAME, def_exp) #Let's read the last used value, stored in the scene...
+ larger = def_exp - self.exponent #How larger/smaller is actual object, comparing to the last used value?
+ if larger <= 1 and larger >= 0: #OK, this object has similar size to the previous one...
+ self.width = context.scene.get(self.LAST_WIDTH_NAME, self.width)
+ else: #the previous bevel size would be too small or too large - revert to defaults:
+ self.width = 0.1 #10% of the object order of magnitude
+ self.exponent = def_exp #the order of magnitude
+ #parameters adjusted, run the command!
+ return self.execute(context)
+ else:
+ self.report(type='ERROR', message="Nothing is selected")
+ return {'CANCELLED'}
+
+ def execute(self,context):
+ #calculate the bevel width, for this object size and scale
+ width = self.width*pow(10,self.exponent)
+ if not self.use_scale : width /= max(context.object.scale)
+ #call the main function:
+ bevel(context.object,width, self.use_vertices)
+ #save the last used parameters:
+ context.scene[self.LAST_VERT_NAME] = self.use_vertices
+ context.scene[self.LAST_WIDTH_NAME] = self.width
+ context.scene[self.LAST_EXP_NAME] = self.exponent
+ context.object[self.LAST_SCALE_NAME] = self.use_scale
+ return {'FINISHED'}
+
+def menu_draw(self, context):
+ self.layout.operator_context = 'INVOKE_REGION_WIN'
+ self.layout.operator(Bevel.bl_idname, "Bevel_Witold")
+
+#--- ### Register
+def register():
+ register_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_specials.prepend(menu_draw)
+
+def unregister():
+ bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_draw)
+ unregister_module(__name__)
+
+#--- ### Main code
+if __name__ == '__main__':
+ register()
+
+if DEBUG > 0: print("mesh_bevel.py loaded!")
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_bump.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_bump.py
new file mode 100644
index 0000000..94f12cb
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_bump.py
@@ -0,0 +1,213 @@
+# mesh_bump.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Extrude a selection from a mesh multiple times
+#
+# ***** 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 *****
+
+bl_info = {
+ "name": "Bump",
+ "author": "Dolf Veenvliet",
+ "version": 1,
+ "blender": (2, 56, 0),
+ "api": 31847,
+ "location": "View3D > Specials > Bump",
+ "description": "Extrude and translate/rotate/scale multiple times",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from "W-menu"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+
+import bpy
+from bpy.props import EnumProperty, FloatVectorProperty, FloatProperty, BoolProperty
+from . import mesh_extras
+
+# Bump stuff!
+class Bump():
+
+ # Initialise the class
+ def __init__(self, context, type, scale, steps):
+
+ self.ob = context.active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ translate = mesh_extras.get_average_outer_edge_length()
+ #inset = mesh_extras.get_shortest_outer_edge_length() * 0.25
+
+ translate *= scale
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ stepped = 0
+
+ # Simple... we just do a bunch of steps... set in stone... easy!
+ if type == 'BUM':
+
+ self.extrude()
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ self.shrink(-translate)
+ self.shrink(translate*0.3)
+
+ stepped += 1
+
+ # Spike!
+ elif type == 'SPI':
+
+ for i in range(3):
+
+ self.extrude()
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ if not i:
+ f = 0.5
+ elif i == 1:
+ f = 0.3
+ elif i == 2:
+ f = 0.2
+
+ t = translate * f
+
+ self.shrink(-t)
+ self.shrink(t * (2 * f))
+
+ stepped += 1
+
+ # Dimple!
+ elif type == 'DIM' or type == 'PIM':
+
+ self.extrude()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ self.shrink(-translate * 0.2)
+
+ self.extrude()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ self.shrink(translate * 0.2)
+ self.shrink(-translate * 0.2)
+
+ if type == 'PIM':
+ self.extrude()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ self.shrink(-translate * 0.2)
+ stepped = 3
+ else:
+ stepped = 2
+
+
+
+
+ if steps:
+ self.ob['growsteps'] = stepped
+
+
+
+ # Extrude the selection (do not move it)
+ def extrude(self):
+ bpy.ops.mesh.extrude_faces_move()
+
+ # SHrink!
+ def shrink(self,v):
+ bpy.ops.transform.shrink_fatten(value=v, mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)
+
+
+
+class Bump_init(bpy.types.Operator):
+ '''Bump by extruding and moving/rotating/scaling multiple times'''
+ bl_idname = 'mesh.bump'
+ bl_label = 'Inset Extrude Bump'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ # The falloffs we use
+ types=(
+ ('BUM', 'Bump',''),
+ ('SPI', 'Spike',''),
+ ('DIM', 'Dimple',''),
+ ('PIM', 'Pimple',''),
+ )
+
+ type = EnumProperty(items=types, name='Type', description='The type of bump', default='BUM')
+
+ # Scale
+ scale = FloatProperty(name='Scale factor', description='Translation in Blender units', default=1.0, min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, step=10, precision=2)
+
+ steps = BoolProperty(name='Retain steps', description='Keep the step count in a property', default=False)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and bpy.context.tool_settings.mesh_select_mode[0] == False and bpy.context.tool_settings.mesh_select_mode[1] == False and bpy.context.tool_settings.mesh_select_mode[2] == True)
+
+ def execute(self, context):
+ BUMP = Bump(context, self.type, self.scale, self.steps)
+ return {'FINISHED'}
+
+class bump_help(bpy.types.Operator):
+ bl_idname = 'help.bump'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Make a selection or selection of Faces ')
+ layout.label('Choose from the bump types in the menu')
+ layout.label('To Help:')
+ layout.label('Keep extrusions small to prevent overlapping')
+ layout.label('Do not select all faces')
+ layout.label('if using with create armature, enter object mode first')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 350)
+'''
+def menu_func(self, context):
+ self.layout.operator(Bump_init.bl_idname, text="Bump")
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_specials.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
+'''
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_extras.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_extras.py
new file mode 100644
index 0000000..49ddd44
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_extras.py
@@ -0,0 +1,274 @@
+import bpy, mathutils, math
+from mathutils import geometry
+
+# Get a matrix for the selected faces that you can use to do local transforms
+def get_selection_matrix(faces=False):
+
+ me = bpy.context.active_object.data
+
+ if not faces:
+ faces = get_selected_faces()
+
+ yVec = mathutils.Vector()
+ zVec = mathutils.Vector()
+
+ # Ok so we have a basic matrix, but lets base it more on the mesh!
+ for f in faces:
+
+ v1 = me.vertices[f.vertices[0]].co
+ v2 = me.vertices[f.vertices[1]].co
+ edge = v2-v1
+
+ yVec += edge
+
+ if len(f.vertices) == 4:
+ v1 = me.vertices[f.vertices[2]].co
+ v2 = me.vertices[f.vertices[3]].co
+ edge = v1-v2
+
+ yVec += edge
+
+ zVec += mathutils.Vector(f.normal)
+
+ if not yVec.length:
+ quat = zVec.to_track_quat('-Z', 'Y')
+ tMat = quat.to_matrix()
+ yVec = tMat[1]
+ yVec = yVec.normalized()
+ else:
+ yVec = yVec.normalized()
+ zVec = zVec.normalized()
+
+ # Rotate yVec so it's 90 degrees to zVec
+ cross =yVec.cross(zVec)
+ vec = float(yVec.angle(zVec) - math.radians(90))
+ mat = mathutils.Matrix.Rotation(vec, 3, cross)
+ yVec = (mat * yVec)
+
+ xVec = yVec.cross(zVec)
+
+ xVec = xVec.normalized()
+
+ nMat = mathutils.Matrix((xVec, yVec, zVec))
+
+ return nMat
+
+
+
+# Get the selection radius (minimum distance of an outer edge to the centre)
+def get_selection_radius():
+
+ ob = bpy.context.active_object
+
+ radius = 0.0
+
+ # no use continueing if nothing is selected
+ if contains_selected_item(ob.data.polygons):
+
+ # Find the center of the selection
+ cent = mathutils.Vector()
+ nr = 0
+ nonVerts = []
+ selVerts = []
+ for f in ob.data.polygons:
+ if f.select:
+ nr += 1
+ cent += f.center
+ else:
+ nonVerts.extend(f.vertices)
+
+ cent /= nr
+
+ chk = 0
+
+ # Now that we know the center.. we can figure out how close the nearest point on an outer edge is
+ for e in get_selected_edges():
+
+ nonSection = [v for v in e.vertices if v in nonVerts]
+ if len(nonSection):
+
+ v0 = ob.data.vertices[e.vertices[0]].co
+ v1 = ob.data.vertices[e.vertices[1]].co
+
+ # If there's more than 1 vert of this edge on the outside... we need the edge length to be long enough too!
+ if len(nonSection) > 1:
+ edge = v0 - v1
+ edgeRad = edge.length * 0.5
+
+ if edgeRad < radius or not chk:
+ radius = edgeRad
+ chk += 1
+
+ int = geometry.intersect_point_line(cent, v0, v1)
+
+ rad = cent - int[0]
+ l = rad.length
+
+ if l < radius or not chk:
+ radius = l
+ chk += 1
+
+ return radius
+
+
+
+# Get the average length of the outer edges of the current selection
+def get_shortest_outer_edge_length():
+
+ ob = bpy.context.active_object
+
+ min = False
+ me = ob.data
+
+ delVerts = []
+ for f in me.faces:
+ if not f.select:
+ delVerts.extend(f.vertices)
+ selEdges = [e.vertices for e in me.edges if e.select]
+
+ if len(selEdges) and len(delVerts):
+
+ for eVerts in selEdges:
+
+ v0 = eVerts[0]
+ v1 = eVerts[1]
+
+ if v0 in delVerts and v1 in delVerts:
+ ln = (me.vertices[v0].co - me.vertices[v1].co).length
+ if min is False or (ln > 0.0 and ln < min):
+ min = ln
+
+ return min
+
+
+# Get the average length of the outer edges of the current selection
+def get_average_outer_edge_length():
+
+ ob = bpy.context.active_object
+
+ ave = 0.0
+ me = ob.data
+
+ delFaces = [f.vertices for f in me.polygons if not f.select]
+ selEdges = [e.vertices for e in me.edges if e.select]
+
+ if len(selEdges) and len(delFaces):
+
+ number = 0
+
+ for eVerts in selEdges:
+
+ v0 = eVerts[0]
+ v1 = eVerts[1]
+
+ for fVerts in delFaces:
+ if v0 in fVerts and v1 in fVerts:
+ number += 1
+ ave += (me.vertices[v0].co - me.vertices[v1].co).length
+ break
+
+ if number:
+ ave /= number
+
+ return ave
+
+
+
+# Get the selected (or deselected items)
+def get_selected(type='vertices',invert=False):
+
+ mesh = bpy.context.active_object.data
+
+ if type == 'vertices':
+ items = mesh.vertices
+ elif type == 'edges':
+ items = mesh.edges
+ else:
+ items = mesh.polygons
+
+ if invert:
+ L = [i for i in items if not i.select]
+ else:
+ L = [i for i in items if i.select]
+ return L
+
+
+
+# See if the mesh has something selected
+def has_selected(type='vertices',invert=False):
+
+ mesh = bpy.context.active_object.data
+
+ if type == 'vertices':
+ items = mesh.vertices
+ elif type == 'edges':
+ items = mesh.edges
+ else:
+ items = mesh.polygons
+
+ for i in items:
+ if not invert and i.select:
+ return True
+ elif invert and not i.select:
+ return True
+
+ return False
+
+
+
+# Get all the selected vertices (mode is selected or deselected)
+def get_selected_vertices(mode='selected'):
+
+ vertices = bpy.context.active_object.data.vertices
+
+ if mode == 'deselected':
+ L = [v for v in vertices if not v.select]
+ else:
+ L = [v for v in vertices if v.select]
+ return L
+
+
+
+# Get all the selected edges (mode is selected or deselected)
+def get_selected_edges(mode='selected'):
+
+ edges = bpy.context.active_object.data.edges
+
+ if mode == 'deselected':
+ L = [e for e in edges if not e.select]
+ else:
+ L = [e for e in edges if e.select]
+ return L
+
+
+
+# Get all the selected faces (mode is selected or deselected)
+def get_selected_faces(mode='selected'):
+
+ polygons = bpy.context.active_object.data.polygons
+
+ if mode == 'deselected':
+ L = [f for f in polygons if not f.select]
+ else:
+ L = [f for f in polygons if f.select]
+ return L
+
+
+
+# See if there is at least one selected item in 'items'
+def contains_selected_item(items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_filletplus.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_filletplus.py
new file mode 100644
index 0000000..c390d17
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_filletplus.py
@@ -0,0 +1,382 @@
+# -*- coding: utf-8 -*-
+
+# ***** 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 *****
+
+# ------ ------
+bl_info = {
+ "name": "FilletPlus",
+ "author": "Gert De Roost - original by zmj100",
+ "version": (0, 4, 2),
+ "blender": (2, 61, 0),
+ "api": 43085,
+ "location": "View3D > Tool Shelf",
+ "description": "",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+# ------ ------
+import bpy
+from bpy.props import FloatProperty, IntProperty, BoolProperty
+import bmesh
+from mathutils import Matrix
+from math import cos, pi, degrees, sin, tan
+
+
+def list_clear_(l):
+ del l[:]
+ return l
+
+def get_adj_v_(list_):
+ tmp = {}
+ for i in list_:
+ try: tmp[i[0]].append(i[1])
+ except KeyError: tmp[i[0]] = [i[1]]
+ try: tmp[i[1]].append(i[0])
+ except KeyError: tmp[i[1]] = [i[0]]
+ return tmp
+
+# ------ ------
+class f_buf():
+ an = 0
+
+# ------ ------
+def f_(list_0, startv, vertlist, face, adj, n, out, flip, radius):
+
+ dict_0 = get_adj_v_(list_0)
+ list_1 = [[dict_0[i][0], i, dict_0[i][1]] for i in dict_0 if (len(dict_0[i]) == 2)][0]
+ list_3 = []
+ for elem in list_1:
+ list_3.append(bm.verts[elem])
+ list_2 = []
+
+ p_ = list_3[1]
+ p = (list_3[1].co).copy()
+ p1 = (list_3[0].co).copy()
+ p2 = (list_3[2].co).copy()
+
+ vec1 = p - p1
+ vec2 = p - p2
+
+ ang = vec1.angle(vec2, any)
+ f_buf.an = round(degrees(ang))
+
+ # -- -- -- --
+ if f_buf.an == 180 or f_buf.an == 0.0:
+ return
+
+ # -- -- -- --
+ opp = adj
+
+ if radius == False:
+ h = adj * (1 / cos(ang * 0.5))
+ adj_ = adj
+ elif radius == True:
+ h = opp / sin(ang * 0.5)
+ adj_ = opp / tan(ang * 0.5)
+
+ p3 = p - (vec1.normalized() * adj_)
+ p4 = p - (vec2.normalized() * adj_)
+ rp = p - ((p - ((p3 + p4) * 0.5)).normalized() * h)
+
+ vec3 = rp - p3
+ vec4 = rp - p4
+
+ axis = vec1.cross(vec2)
+
+ if out == False:
+ if flip == False:
+ rot_ang = vec3.angle(vec4)
+ elif flip == True:
+ rot_ang = vec1.angle(vec2)
+ elif out == True:
+ rot_ang = (2 * pi) - vec1.angle(vec2)
+
+ for j in range(n + 1):
+ new_angle = rot_ang * j / n
+ mtrx = Matrix.Rotation(new_angle, 3, axis)
+ if out == False:
+ if flip == False:
+ tmp = p4 - rp
+ tmp1 = mtrx * tmp
+ tmp2 = tmp1 + rp
+ elif flip == True:
+ p3 = p - (vec1.normalized() * opp)
+ tmp = p3 - p
+ tmp1 = mtrx * tmp
+ tmp2 = tmp1 + p
+ elif out == True:
+ p4 = p - (vec2.normalized() * opp)
+ tmp = p4 - p
+ tmp1 = mtrx * tmp
+ tmp2 = tmp1 + p
+
+ v = bm.verts.new(tmp2)
+ list_2.append(v)
+
+ if flip == True:
+ list_3[1:2] = list_2
+ else:
+ list_2.reverse()
+ list_3[1:2] = list_2
+
+ list_clear_(list_2)
+
+ n1 = len(list_3)
+ for t in range(n1 - 1):
+ bm.edges.new([list_3[t], list_3[(t + 1) % n1]])
+
+ v = bm.verts.new(p)
+ bm.edges.new([v, p_])
+
+ if face != None:
+ for l in face.loops:
+ if l.vert == list_3[0]:
+ startl = l
+ break
+ vertlist2 = []
+ if startl.link_loop_next.vert == startv:
+ l = startl.link_loop_prev
+ while len(vertlist) > 0:
+ vertlist2.insert(0, l.vert)
+ vertlist.pop(vertlist.index(l.vert))
+ l = l.link_loop_prev
+ else:
+ l = startl.link_loop_next
+ while len(vertlist) > 0:
+ vertlist2.insert(0, l.vert)
+ vertlist.pop(vertlist.index(l.vert))
+ l = l.link_loop_next
+ for v in list_3:
+ vertlist2.append(v)
+ bm.faces.new(vertlist2)
+
+ bm.verts.remove(startv)
+ list_3[1].select = 1
+ list_3[-2].select = 1
+ bm.edges.get([list_3[0], list_3[1]]).select = 1
+ bm.edges.get([list_3[-1], list_3[-2]]).select = 1
+ bm.verts.index_update()
+ bm.edges.index_update()
+ bm.faces.index_update()
+
+ me.update(calc_edges = True, calc_tessface=True)
+
+
+
+def do_filletplus(pair):
+
+ global inaction
+ global flip
+
+
+ list_0 = [list([e.verts[0].index, e.verts[1].index]) for e in pair]
+
+ vertset = set([])
+ vertset.add(bm.verts[list_0[0][0]])
+ vertset.add(bm.verts[list_0[0][1]])
+ vertset.add(bm.verts[list_0[1][0]])
+ vertset.add(bm.verts[list_0[1][1]])
+
+ v1, v2, v3 = vertset
+
+ if len(list_0) != 2:
+ self.report({'INFO'}, 'Two adjacent edges must be selected.')
+ return
+ else:
+ inaction = 1
+ vertlist = []
+ found = 0
+ for f in v1.link_faces:
+ if v2 in f.verts and v3 in f.verts:
+ found = 1
+ if not(found):
+ for v in [v1, v2, v3]:
+ if v.index in list_0[0] and v.index in list_0[1]:
+ startv = v
+ face = None
+ else:
+ for f in v1.link_faces:
+ if v2 in f.verts and v3 in f.verts:
+ for v in f.verts:
+ if not(v in vertset):
+ vertlist.append(v)
+ if v in vertset and v.link_loops[0].link_loop_prev.vert in vertset and v.link_loops[0].link_loop_next.vert in vertset:
+ startv = v
+ face = f
+ if out == True:
+ flip = False
+ f_(list_0, startv, vertlist, face, adj, n, out, flip, radius)
+
+
+'''
+
+# ------ panel 0 ------
+class f_p0(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ #bl_idname = 'f_p0_id'
+ bl_label = 'Fillet'
+ bl_context = 'mesh_edit'
+
+ def draw(self, context):
+ layout = self.layout
+
+ row = layout.split(0.80)
+ row.operator('f.op0_id', text = 'Fillet plus')
+ row.operator('f.op1_id', text = '?')
+'''
+# ------ operator 0 ------
+class fillet_op0(bpy.types.Operator):
+ bl_idname = 'fillet.op0_id'
+ bl_label = 'Fillet'
+ bl_description = 'Fillet ajoining edges'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ adj = FloatProperty( name = '', default = 0.1, min = 0.00001, max = 100.0, step = 1, precision = 3 )
+ n = IntProperty( name = '', default = 3, min = 1, max = 100, step = 1 )
+ out = BoolProperty( name = 'Outside', default = False )
+ flip = BoolProperty( name = 'Flip', default = False )
+ radius = BoolProperty( name = 'Radius', default = False )
+
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and context.mode == 'EDIT_MESH')
+
+ def draw(self, context):
+ layout = self.layout
+
+ if f_buf.an == 180 or f_buf.an == 0.0:
+ layout.label('Info:')
+ layout.label('Angle equal to 0 or 180,')
+ layout.label('can not fillet.')
+ else:
+ layout.prop(self, 'radius')
+ if self.radius == True:
+ layout.label('Radius:')
+ elif self.radius == False:
+ layout.label('Distance:')
+ layout.prop(self, 'adj')
+ layout.label('Number of sides:')
+ layout.prop(self, 'n', slider = True)
+ if self.n > 1:
+ row = layout.row(align = False)
+ row.prop(self, 'out')
+ if self.out == False:
+ row.prop(self, 'flip')
+
+ def execute(self, context):
+
+ global inaction
+ global bm, me, adj, n, out, flip, radius
+
+ adj = self.adj
+ n = self.n
+ out = self.out
+ flip = self.flip
+ radius = self.radius
+
+ inaction = 0
+
+ ob_act = context.active_object
+ me = ob_act.data
+ bm = bmesh.from_edit_mesh(me)
+# e_mode = bpy.context.tool_settings.mesh_select_mode
+
+ done = 1
+ while done:
+ tempset = set([])
+ for v in bm.verts:
+ if v.select:
+ tempset.add(v)
+ done = 0
+ for v in tempset:
+ cnt = 0
+ edgeset = set([])
+ for e in v.link_edges:
+ if e.select:
+ edgeset.add(e)
+ cnt += 1
+ if cnt == 2:
+ do_filletplus(edgeset)
+ done = 1
+ break
+ #return {'FINISHED'}
+ if done:
+ break
+
+ if inaction == 1:
+ bpy.ops.mesh.select_all(action="DESELECT")
+ for v in bm.verts:
+ if len(v.link_edges) == 0:
+ bm.verts.remove(v)
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+ else:
+ return {'CANCELLED'}
+
+# ------ operator 1 ------
+class filletedgehelp(bpy.types.Operator):
+ bl_idname = 'help.edge_fillet'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Select two adjacent edges and press Fillet button.')
+ layout.label('To Help:')
+ layout.label('best used on flat plane.')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 350)
+
+# ------ operator 2 ------
+class fillet_op2(bpy.types.Operator):
+ bl_idname = 'fillet.op2_id'
+ bl_label = ''
+
+ def execute(self, context):
+ bpy.ops.f.op1_id('INVOKE_DEFAULT')
+ return {'FINISHED'}
+'''
+# ------ ------
+class_list = [ f_op0, f_op1, f_op2, f_p0]
+
+# ------ register ------
+def register():
+ for c in class_list:
+ bpy.utils.register_class(c)
+
+# ------ unregister ------
+def unregister():
+ for c in class_list:
+ bpy.utils.unregister_class(c)
+
+# ------ ------
+if __name__ == "__main__":
+ register()
+'''
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_mextrude_plus.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_mextrude_plus.py
new file mode 100644
index 0000000..2dba166
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_mextrude_plus.py
@@ -0,0 +1,385 @@
+# ##### 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 LICENSE BLOCK #####
+
+################################################################################
+# Repeats extrusion + rotation + scale for one or more faces #
+
+################################################################################
+
+bl_info = {
+ "name": "MExtrude Plus",
+ "author": "liero",
+ "version": (1, 2, 8),
+ "blender": (2, 62, 0),
+ "location": "View3D > Tool Shelf",
+ "description": "Repeat extrusions from faces to create organic shapes",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=28570",
+ "category": "Mesh"}
+
+import bpy, bmesh, mathutils, random
+from random import gauss
+from math import radians
+from mathutils import Euler, Vector
+from bpy.props import BoolProperty, FloatProperty, IntProperty, StringProperty
+
+def vloc(self, r):
+ random.seed(self.ran + r)
+ return self.off * (1 + random.gauss(0, self.var1 / 3))
+
+def vrot(self,r):
+ random.seed(self.ran + r)
+ return Euler((radians(self.rotx) + random.gauss(0, self.var2 / 3), \
+ radians(self.roty) + random.gauss(0, self.var2 / 3), \
+ radians(self.rotz) + random.gauss(0,self.var2 / 3)), 'XYZ')
+
+def vsca(self, r):
+ random.seed(self.ran + r)
+ return self.sca * (1 + random.gauss(0, self.var3 / 3))
+
+# centroide de una seleccion de vertices
+def centro(ver):
+ vvv = [v for v in ver if v.select]
+ if not vvv or len(vvv) == len(ver): return ('error')
+ x = sum([round(v.co[0],4) for v in vvv]) / len(vvv)
+ y = sum([round(v.co[1],4) for v in vvv]) / len(vvv)
+ z = sum([round(v.co[2],4) for v in vvv]) / len(vvv)
+ return (x,y,z)
+
+# recuperar el estado original del objeto
+def volver(obj, copia, om, msm, msv):
+ for i in copia: obj.data.vertices[i].select = True
+ bpy.context.tool_settings.mesh_select_mode = msm
+ for i in range(len(msv)):
+ obj.modifiers[i].show_viewport = msv[i]
+
+class MExtrude(bpy.types.Operator):
+ bl_idname = 'object.mextrude'
+ bl_label = 'MExtrude'
+ bl_description = 'Multi Extrude'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ off = FloatProperty(name='Offset', min=-2, soft_min=0.001, \
+ soft_max=2, max=5, default=.5, description='Translation')
+ rotx = FloatProperty(name='Rot X', min=-85, soft_min=-30, \
+ soft_max=30, max=85, default=0, description='X rotation')
+ roty = FloatProperty(name='Rot Y', min=-85, soft_min=-30, \
+ soft_max=30, max=85, default=0, description='Y rotation')
+ rotz = FloatProperty(name='Rot Z', min=-85, soft_min=-30, \
+ soft_max=30, max=85, default=-0, description='Z rotation')
+ sca = FloatProperty(name='Scale', min=0.1, soft_min=0.5, \
+ soft_max=1.2, max =2, default=1.0, description='Scaling')
+ var1 = FloatProperty(name='Offset Var', min=-5, soft_min=-1, \
+ soft_max=1, max=5, default=0, description='Offset variation')
+ var2 = FloatProperty(name='Rotation Var', min=-5, soft_min=-1, \
+ soft_max=1, max=5, default=0, description='Rotation variation')
+ var3 = FloatProperty(name='Scale Noise', min=-5, soft_min=-1, \
+ soft_max=1, max=5, default=0, description='Scaling noise')
+ num = IntProperty(name='Repeat', min=1, max=50, soft_max=100, \
+ default=5, description='Repetitions')
+ ran = IntProperty(name='Seed', min=-9999, max=9999, default=0, \
+ description='Seed to feed random values')
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.type == 'MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ column = layout.column(align=True)
+ column.label(text='Transformations:')
+ column.prop(self, 'off', slider=True)
+ column.prop(self, 'rotx', slider=True)
+ column.prop(self, 'roty', slider=True)
+ column.prop(self, 'rotz', slider=True)
+ column.prop(self, 'sca', slider=True)
+ column = layout.column(align=True)
+ column.label(text='Variation settings:')
+ column.prop(self, 'var1', slider=True)
+ column.prop(self, 'var2', slider=True)
+ column.prop(self, 'var3', slider=True)
+ column.prop(self, 'ran')
+ column = layout.column(align=False)
+ column.prop(self, 'num')
+
+ def execute(self, context):
+ obj = bpy.context.object
+ data, om = obj.data, obj.mode
+ bpy.context.tool_settings.mesh_select_mode = [False, False, True]
+
+ # bmesh operations
+ bpy.ops.object.mode_set()
+ bm = bmesh.new()
+ bm.from_mesh(obj.data)
+ sel = [f for f in bm.faces if f.select]
+
+ # faces loop
+ for i, of in enumerate(sel):
+ rot = vrot(self, i)
+ off = vloc(self, i)
+ of.normal_update()
+
+ # extrusion loop
+ for r in range(self.num):
+ nf = of.copy()
+ nf.normal_update()
+ no = nf.normal.copy()
+ ce = nf.calc_center_bounds()
+ s = vsca(self, i + r)
+
+ for v in nf.verts:
+ v.co -= ce
+ v.co.rotate(rot)
+ v.co += ce + no * off
+ v.co = v.co.lerp(ce, 1 - s)
+
+ # extrude code from TrumanBlending
+ for a, b in zip(of.loops, nf.loops):
+ sf = bm.faces.new((a.vert, a.link_loop_next.vert, \
+ b.link_loop_next.vert, b.vert))
+ sf.normal_update()
+
+ bm.faces.remove(of)
+ of = nf
+
+ for v in bm.verts: v.select = False
+ for e in bm.edges: e.select = False
+ bm.to_mesh(obj.data)
+ obj.data.update()
+
+ # restore user settings
+ bpy.ops.object.mode_set(mode=om)
+
+ if not len(sel):
+ self.report({'INFO'}, 'Select one or more faces...')
+ return{'FINISHED'}
+
+class mextrude_help(bpy.types.Operator):
+ bl_idname = 'help.mextrude'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Make a selection or selection of Faces.')
+ layout.label('Extrude, rotate extrusions & more.')
+ layout.label('For rigging capabilities, see Multi Extrude Plus panel.')
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+
+class addarm_help(bpy.types.Operator):
+ bl_idname = 'help.addarm'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('With Multi extrude to rig extrusions.')
+ layout.label('Adds Empty to control rig.')
+ layout.label('Based on selected face/s & object center.')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+
+class BB(bpy.types.Operator):
+ bl_idname = 'object.mesh2bones'
+ bl_label = 'Create Armature'
+ bl_description = 'Create an armature rig based on mesh selection'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ numb = IntProperty(name='Max Bones', min=1, max=1000, soft_max=100, default=5, description='Max number of bones')
+ skip = IntProperty(name='Skip Loops', min=0, max=5, default=0, description='Skip some edges to get longer bones')
+ long = FloatProperty(name='Min Length', min=0.01, max=5, default=0.15, description='Discard bones shorter than this value')
+ ika = BoolProperty(name='IK constraints', default=True, description='Add IK constraint and Empty as target')
+ rotk = BoolProperty(name='IK Rotation', default=False, description='IK constraint follows target rotation')
+ auto = BoolProperty(name='Auto weight', default=True, description='Auto weight and assign vertices')
+ env = BoolProperty(name='Envelopes', default=False, description='Use envelopes instead of weights')
+ rad = FloatProperty(name='Radius', min=0.01, max=5, default=0.25, description='Envelope deform radius')
+ nam = StringProperty(name='', default='hueso', description='Default name for bones / groups')
+
+ @classmethod
+ def poll(cls, context):
+ obj = bpy.context.object
+ return (obj and obj.type == 'MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ column = layout.column(align=True)
+ column.prop(self,'numb')
+ column.prop(self,'skip')
+ column.prop(self,'long')
+ column = layout.column(align=True)
+ column.prop(self,'auto')
+ if self.auto:
+ column.prop(self,'env')
+ if self.env: column.prop(self,'rad')
+ column.prop(self,'ika')
+ if self.ika: column.prop(self,'rotk')
+ layout.prop(self,'nam')
+
+ def execute(self, context):
+ scn = bpy.context.scene
+ obj = bpy.context.object
+ fac = obj.data.polygons
+ # guardar estado y seleccion
+ ver, om = obj.data.vertices, obj.mode
+ msm, msv = list(bpy.context.tool_settings.mesh_select_mode), []
+ for i in range(len(obj.modifiers)):
+ msv.append(obj.modifiers[i].show_viewport)
+ obj.modifiers[i].show_viewport = False
+ bpy.ops.object.mode_set(mode='OBJECT')
+ copia = [v.index for v in ver if v.select]
+ sel = [f.index for f in fac if f.select]
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.context.tool_settings.mesh_select_mode = [True, False, False]
+ bpy.ops.mesh.select_all(action='DESELECT')
+ txt = 'Select a face or a vertex where the chain should end...'
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # crear rig unico -desde vertice/s y no desde caras-
+ if sel == []:
+ sel = ['simple']
+ for i in copia:
+ obj.data.vertices[i].select = True
+
+ # reciclar el rig en cada refresco...
+ try: scn.objects.unlink(rig)
+ except: pass
+
+ # loop de caras
+ for i in sel:
+ if sel[0] != 'simple':
+ for v in ver: v.select = False
+ for v in fac[i].vertices: ver[v].select = True
+ lista = [centro(ver)]
+ if lista[0] == 'error':
+ self.report({'INFO'}, txt)
+ volver(obj, copia, om, msm, msv)
+ return{'FINISHED'}
+
+ # crear lista de coordenadas para los huesos
+ scn.objects.active = obj
+ for t in range(self.numb):
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.object.vertex_group_assign(new=True)
+ for m in range(self.skip+1):
+ bpy.ops.mesh.select_more()
+ bpy.ops.object.vertex_group_deselect()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ lista.append(centro(ver))
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.object.vertex_group_select()
+ bpy.ops.object.vertex_group_remove()
+ if lista[-1] == 'error':
+ self.numb = t
+ lista.pop()
+ break
+ if len(lista) > 1:
+ delta = Vector(lista[-2]) - Vector(lista[-1])
+ if delta.length < self.long:
+ lista.pop()
+
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # crear armature y copiar transformaciones del objeto
+ lista.reverse()
+ if len(lista) < 2:
+ self.report({'INFO'}, txt)
+ volver(obj, copia, om, msm, msv)
+ return{'FINISHED'}
+ try: arm
+ except:
+ arm = bpy.data.armatures.new('arm')
+ if self.env: arm.draw_type = 'ENVELOPE'
+ else: arm.draw_type = 'STICK'
+ rig = bpy.data.objects.new(obj.name+'_rig', arm)
+ rig.matrix_world = obj.matrix_world
+ if self.env: rig.draw_type = 'WIRE'
+ rig.show_x_ray = True
+ scn.objects.link(rig)
+ scn.objects.active = rig
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # crear la cadena de huesos desde la lista
+ for i in range(len(lista)-1):
+ bon = arm.edit_bones.new(self.nam+'.000')
+ bon.use_connect = True
+ bon.tail = lista[i+1]
+ bon.head = lista[i]
+ if self.auto and self.env:
+ bon.tail_radius = self.rad
+ bon.head_radius = self.rad
+ if i: bon.parent = padre
+ padre = bon
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # crear IK constraint y un Empty como target
+ if self.ika:
+ ik = rig.data.bones[-1].name
+ loc = rig.matrix_world * Vector(lista[-1])
+ rot = rig.matrix_world * rig.data.bones[-1].matrix_local
+ bpy.ops.object.add(type='EMPTY', location=loc, rotation=rot.to_euler())
+ tgt = bpy.context.object
+ tgt.name = obj.name+'_target.000'
+ if len(sel) > 1:
+ try: mega
+ except:
+ bpy.ops.object.add(type='EMPTY', location = obj.location)
+ mega = bpy.context.object
+ mega.name = obj.name+'_Controls'
+ tgt.select = True
+ scn.objects.active = mega
+ bpy.ops.object.parent_set(type='OBJECT')
+
+ scn.objects.active = rig
+ bpy.ops.object.mode_set(mode='POSE')
+ con = rig.pose.bones[ik].constraints.new('IK')
+ con.target = tgt
+ if self.rotk: con.use_rotation = True
+ tgt.select = False
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ obj.select = True
+ if self.auto:
+ if self.env: bpy.ops.object.parent_set(type='ARMATURE_ENVELOPE')
+ else: bpy.ops.object.parent_set(type='ARMATURE_AUTO')
+ scn.objects.active = obj
+ volver(obj, copia, om, msm, msv)
+ return{'FINISHED'}
+'''
+def register():
+ bpy.utils.register_class(MExtrude)
+
+ bpy.utils.register_class(BB)
+
+def unregister():
+ bpy.utils.unregister_class(MExtrude)
+
+ bpy.utils.unregister_class(BB)
+
+
+if __name__ == '__main__':
+ register()
+'''
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_normal_smooth.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_normal_smooth.py
new file mode 100644
index 0000000..32d36b9
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_normal_smooth.py
@@ -0,0 +1,215 @@
+# mesh_normalsmooth_7.py Copyright (C) 2010, Dolf Veenvliet
+#
+# Relaxes selected vertices while retaining the shape as much as possible
+#
+# ***** 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 *****
+
+bl_info = {
+ "name": "Normal Smooth",
+ "author": "Dolf Veenvliet",
+ "version": (7,),
+ "blender": (2, 63, 0),
+ "location": "View3D > Specials > Normal Smooth ",
+ "description": "Smooth the vertex position based on the normals",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=32587",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from "W-menu" or from "Mesh -> Vertices -> Normal Smooth"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+
+import bpy, mathutils, math
+from bpy.props import IntProperty
+
+## Rotate one vector (vec1) towards another (vec2)
+## (rad = ammount of degrees to rotate in radians)
+def RotVtoV(vec1, vec2, rad):
+ cross = vec1.cross(vec2)
+ mat = mathutils.Matrix.Rotation(rad, 3, cross)
+ return (mat * vec1)
+
+
+# Find the new coordinate for this verticle
+def smoothVert(v1, v1in, me):
+
+ v1co = v1.co
+ v1no = v1.normal
+
+ # List of verts not to check (don't check against yourself)
+ chk = [v1in]
+ newCo = []
+
+ # Make sure there's faces, otherwise we do nothing
+ if len(me.polygons):
+
+ # Check every face
+ for f in me.polygons:
+
+ # Only check faces that this vert is in
+ if v1in in f.vertices:
+
+ # Loop through all the verts in the face
+ for v2in in f.vertices:
+
+ # Make sure you check every vert only once
+ if not v2in in chk:
+
+ chk.append(v2in)
+
+ v2 = me.vertices[v2in]
+
+ v2co = v2.co
+
+ # Get the vector from one vert to the other
+ vTov = v2co - v1co
+
+ vLen = vTov.length
+
+ # Use half the distance (actually 0.514 seems to be the specific nr to multiply by... just by experience)
+ vLen *= 0.514
+
+ # Get the normal rotated 90 degrees (pi * 0.5 = 90 degrees in radians) towards the original vert
+ vNor = RotVtoV(v2.normal, vTov.normalized(), (math.pi * 0.5))
+
+ # Make the vector the correct length
+ vNor = vNor.normalized() * vLen
+
+ # Add the vector to the vert position to get the correct coord
+ vNor = v2co + vNor
+
+ newCo.append(vNor)
+
+ # Calculate the new coord only if there's a result
+ if len(newCo):
+
+ nC = mathutils.Vector()
+
+ # Add all the new coordinates together
+ for c in newCo:
+ nC = nC + c
+
+ # Divide the resulting vector by the total to get the average
+ nC = nC / len(newCo)
+
+ # If there's no result, just return the original coord
+ else:
+ nC = v1co
+
+ return nC
+
+
+# Base function
+def normal_smooth(context):
+
+ ob = context.active_object
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ vNew = {}
+ me = ob.data
+
+ # loop through all verts
+ for v1 in me.vertices:
+
+ # only smooth selected verts
+ if v1.select:
+
+ v1in = v1.index
+
+ # Get the new coords for this vert
+ vNew[v1in] = smoothVert(v1, v1in, me)
+
+ # Only if they're anything new, can we apply anything
+ if len(vNew):
+
+ # Get the indexes for all verts to adapt
+ for k in vNew.keys():
+
+ # Set the vert's new coords
+ me.vertices[k].co = vNew[k]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+class nsmooth_help(bpy.types.Operator):
+ bl_idname = 'help.normal_smooth'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Select A vertex or group of verts.')
+ layout.label('Smooth the vertex position based on the normals')
+
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+
+class NormalSmooth(bpy.types.Operator):
+ """Smoothes verticle position based on vertex normals"""
+ bl_idname = 'normal.smooth'
+ bl_label = 'Normal Smooth'
+ bl_options = {'REGISTER', 'UNDO'}
+
+
+ iterations = IntProperty(name="Smoothing iterations",
+ default=1, min=0, max=100, soft_min=0, soft_max=10)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def execute(self, context):
+ for i in range(0,self.iterations):
+ normal_smooth(context)
+ return {'FINISHED'}
+
+
+def menu_func(self, context):
+ self.layout.operator(NormalSmooth.bl_idname, text="Normal Smooth")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.VIEW3D_MT_edit_mesh_specials.append(menu_func)
+ bpy.types.VIEW3D_MT_edit_mesh_vertices.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.VIEW3D_MT_edit_mesh_specials.remove(menu_func)
+ bpy.types.VIEW3D_MT_edit_mesh_vertices.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_polyredux.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_polyredux.py
new file mode 100644
index 0000000..ca7a29e
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_polyredux.py
@@ -0,0 +1,387 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Script copyright (C) Campbell J Barton
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+bl_info = {
+ "name": "PolyRedux",
+ "author": "Campbell J Barton - updated by Gert De Roost",
+ "version": (2, 0, 4),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tools",
+ "description": "predictable mesh simplifaction maintaining face loops",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+
+if "bpy" in locals():
+ import imp
+
+import bpy
+import bmesh
+import time
+
+
+class PolyRedux(bpy.types.Operator):
+ bl_idname = "mesh.polyredux"
+ bl_label = "PolyRedux"
+ bl_description = "predictable mesh simplifaction maintaining face loops"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def invoke(self, context, event):
+
+ scn = bpy.context.scene
+
+ self.save_global_undo = bpy.context.user_preferences.edit.use_global_undo
+ bpy.context.user_preferences.edit.use_global_undo = False
+
+ do_polyredux(self)
+
+ return {'FINISHED'}
+
+class redux_help(bpy.types.Operator):
+ bl_idname = 'help.polyredux'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Make a selection of verts or polygons to reduce.')
+ layout.label('works on whole mesh or selected')
+ layout.label('To Help:')
+ layout.label('Single operation, no parameters.')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+'''
+def panel_func(self, context):
+
+ scn = bpy.context.scene
+ self.layout.label(text="PolyRedux:")
+ self.layout.operator("mesh.polyredux", text="Poly Redux")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_PT_tools_meshedit.append(panel_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_PT_tools_meshedit.remove(panel_func)
+
+
+if __name__ == "__main__":
+ register()
+
+
+'''
+
+def my_mesh_util():
+ bm_verts = bm.verts
+
+ vert_faces = [ [] for v in bm_verts]
+ vert_faces_corner = [ [] for v in bm_verts]
+
+
+ # Ignore topology where there are not 2 faces connected to an edge.
+ edge_count = {}
+ for f in bm.faces:
+ for edge in f.edges:
+ edkey = (edge.verts[0].index, edge.verts[1].index)
+ try:
+ edge_count[edkey] += 1
+ except:
+ edge_count[edkey] = 1
+
+ for edkey, count in edge_count.items():
+
+ # Ignore verts that connect to edges with more than 2 faces.
+ if count != 2:
+ vert_faces[edkey[0]] = None
+ vert_faces[edkey[1]] = None
+ # Done
+
+
+
+ def faces_set_verts(face_ls):
+ unique_verts = set()
+ for f in face_ls:
+ for v in f.verts:
+ unique_verts.add(v.index)
+ return unique_verts
+
+ for f in bm.faces:
+ for corner, v in enumerate(f.verts):
+ i = v.index
+ if vert_faces[i] != None:
+ vert_faces[i].append(f)
+ vert_faces_corner[i].append(corner)
+
+ grid_data_ls = []
+
+ for vi, face_ls in enumerate(vert_faces):
+ if face_ls != None:
+ if len(face_ls) == 4:
+ if face_ls[0].select and face_ls[1].select and face_ls[2].select and face_ls[3].select:
+ # Support triangles also
+ unique_vert_count = len(faces_set_verts(face_ls))
+ quads = 0
+ for f in face_ls:
+ if len(f.verts) ==4:
+ quads += 1
+ if unique_vert_count==5+quads: # yay we have a grid
+ grid_data_ls.append( (vi, face_ls) )
+
+ elif len(face_ls) == 3:
+ if face_ls[0].select and face_ls[1].select and face_ls[2].select:
+ unique_vert_count = len(faces_set_verts(face_ls))
+ if unique_vert_count==4: # yay we have 3 triangles to make into a bigger triangle
+ grid_data_ls.append( (vi, face_ls) )
+
+
+
+ # Now sort out which grid faces to use
+
+
+ # This list will be used for items we can convert, vertex is key, faces are values
+ grid_data_dict = {}
+
+ if not grid_data_ls:
+ print ("doing nothing")
+ return
+
+ # quick lookup for the opposing corner of a qiad
+ quad_diag_mapping = 2,3,0,1
+
+ verts_used = [0] * len(bm_verts) # 0 == untouched, 1==should touch, 2==touched
+ verts_used[grid_data_ls[0][0]] = 1 # start touching 1!
+
+ # From the corner vert, get the 2 edges that are not the corner or its opposing vert, this edge will make a new face
+ quad_edge_mapping = (1,3), (2,0), (1,3), (0,2) # hi-low, low-hi order is intended
+ tri_edge_mapping = (1,2), (0,2), (0,1)
+
+ done_somthing = True
+ while done_somthing:
+ done_somthing = False
+ grid_data_ls_index = -1
+
+ for vi, face_ls in grid_data_ls:
+ grid_data_ls_index += 1
+ if len(face_ls) == 3:
+ grid_data_dict[bm.verts[vi]] = face_ls
+ grid_data_ls.pop( grid_data_ls_index )
+ break
+ elif len(face_ls) == 4:
+ # print vi
+ if verts_used[vi] == 1:
+ verts_used[vi] = 2 # dont look at this again.
+ done_somthing = True
+
+ grid_data_dict[bm.verts[vi]] = face_ls
+
+ # Tag all faces verts as used
+
+ for i, f in enumerate(face_ls):
+ # i == face index on vert, needed to recall which corner were on.
+ v_corner = vert_faces_corner[vi][i]
+ fv =f.verts
+
+ if len(f.verts) == 4:
+ v_other = quad_diag_mapping[v_corner]
+ # get the 2 other corners
+ corner1, corner2 = quad_edge_mapping[v_corner]
+ if verts_used[fv[v_other].index] == 0:
+ verts_used[fv[v_other].index] = 1 # TAG for touching!
+ else:
+ corner1, corner2 = tri_edge_mapping[v_corner]
+
+ verts_used[fv[corner1].index] = 2 # Dont use these, they are
+ verts_used[fv[corner2].index] = 2
+
+
+ # remove this since we have used it.
+ grid_data_ls.pop( grid_data_ls_index )
+
+ break
+
+ if done_somthing == False:
+ # See if there are any that have not even been tagged, (probably on a different island), then tag them.
+
+ for vi, face_ls in grid_data_ls:
+ if verts_used[vi] == 0:
+ verts_used[vi] = 1
+ done_somthing = True
+ break
+
+
+ # Now we have all the areas we will fill, calculate corner triangles we need to fill in.
+ new_faces = []
+ quad_del_vt_map = (1,2,3), (0,2,3), (0,1,3), (0,1,2)
+ for v, face_ls in grid_data_dict.items():
+ for i, f in enumerate(face_ls):
+ if len(f.verts) == 4:
+ # i == face index on vert, needed to recall which corner were on.
+ v_corner = vert_faces_corner[v.index][i]
+ v_other = quad_diag_mapping[v_corner]
+ fv =f.verts
+
+ #print verts_used[fv[v_other].index]
+ #if verts_used[fv[v_other].index] != 2: # DOSNT WORK ALWAYS
+
+ if 1: # THIS IS LAzY - some of these faces will be removed after adding.
+ # Ok we are removing half of this face, add the other half
+
+ # This is probably slower
+ # new_faces.append( [fv[ii].index for ii in (0,1,2,3) if ii != v_corner ] )
+
+ # do this instead
+ new_faces.append( (fv[quad_del_vt_map[v_corner][0]].index, fv[quad_del_vt_map[v_corner][1]].index, fv[quad_del_vt_map[v_corner][2]].index) )
+
+ del grid_data_ls
+
+
+ # me.sel = 0
+ def faceCombine4(vi, face_ls):
+ edges = []
+
+ for i, f in enumerate(face_ls):
+ fv = f.verts
+ v_corner = vert_faces_corner[vi][i]
+ if len(f.verts)==4: ed = quad_edge_mapping[v_corner]
+ else: ed = tri_edge_mapping[v_corner]
+
+ edges.append( [fv[ed[0]].index, fv[ed[1]].index] )
+
+ # get the face from the edges
+ face = edges.pop()
+ while len(face) != 4:
+ # print len(edges), edges, face
+ for ed_idx, ed in enumerate(edges):
+ if face[-1] == ed[0] and (ed[1] != face[0]):
+ face.append(ed[1])
+ elif face[-1] == ed[1] and (ed[0] != face[0]):
+ face.append(ed[0])
+ else:
+ continue
+
+ edges.pop(ed_idx) # we used the edge alredy
+ break
+
+ return face
+
+ for v, face_ls in grid_data_dict.items():
+ vi = v.index
+ if len(face_ls) == 4:
+ new_faces.append( faceCombine4(vi, face_ls) )
+ #pass
+ if len(face_ls) == 3: # 3 triangles
+ face = list(faces_set_verts(face_ls))
+ face.remove(vi)
+ new_faces.append( face )
+
+
+ # Now remove verts surounded by 3 triangles
+
+
+
+ # print new_edges
+ # me.faces.extend(new_faces, ignoreDups=True)
+
+ '''
+ faces_remove = []
+ for vi, face_ls in grid_data_dict.items():
+ faces_remove.extend(face_ls)
+ '''
+
+ orig_facelen = len(bm.faces)
+
+ orig_faces = list(bm.faces)
+ made_faces = []
+ bpy.ops.mesh.select_all(action="DESELECT")
+ for vertidxs in new_faces:
+ verts = []
+ for idx in vertidxs:
+ verts.append(bm.verts[idx])
+ verts.append(verts[0])
+ for idx in range(len(verts) - 1):
+ verts.append(verts[0])
+ v1 = verts[idx]
+ v2 = verts[idx + 1]
+ if bm.edges.get((v1, v2)) == None:
+ for f in v1.link_faces:
+ if f in v2.link_faces:
+ bmesh.utils.face_split(f, v1, v2)
+ break
+
+ for vert in grid_data_dict.keys():
+ bmesh.utils.face_join(vert.link_faces[:])
+
+ # me.faces.delete(1, faces_remove)
+
+ bm.normal_update()
+
+def do_polyredux(self):
+
+ global bm, me
+
+ # Gets the current scene, there can be many scenes in 1 blend file.
+ sce = bpy.context.scene
+
+ # Get the active object, there can only ever be 1
+ # and the active object is always the editmode object.
+ mode = "EDIT"
+ if bpy.context.mode == "OBJECT":
+ mode = "OBJECT"
+ bpy.ops.object.editmode_toggle()
+ ob_act = bpy.context.active_object
+ if not ob_act or ob_act.type != 'MESH':
+ return
+ me = ob_act.data
+ bm = bmesh.from_edit_mesh(me)
+
+ t = time.time()
+
+ # Run the mesh editing function
+ my_mesh_util()
+ me.update(calc_edges=True, calc_tessface=True)
+ bm.free()
+
+ # Restore editmode if it was enabled
+ if mode == "OBJECT":
+ bpy.ops.object.editmode_toggle()
+ else:
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+
+ # Timing the script is a good way to be aware on any speed hits when scripting
+ print ('My Script finished in %.2f seconds' % (time.time()-t))
+
+
+
diff --git a/release/scripts/addons_contrib/mesh_extra_tools/mesh_vertex_chamfer.py b/release/scripts/addons_contrib/mesh_extra_tools/mesh_vertex_chamfer.py
new file mode 100644
index 0000000..96a695a
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extra_tools/mesh_vertex_chamfer.py
@@ -0,0 +1,154 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Vertex Chamfer",
+ "author": "Andrew Hale (TrumanBlending)",
+ "version": (0, 1),
+ "blender": (2, 63, 0),
+ "location": "Spacebar Menu",
+ "description": "Chamfer vertex",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+
+import bpy
+import bmesh
+
+
+class VertexChamfer(bpy.types.Operator):
+ bl_idname = "mesh.vertex_chamfer"
+ bl_label = "Chamfer Vertex"
+ bl_description = "Tri chamfer selected vertices"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ factor = bpy.props.FloatProperty(name="Factor",
+ default=0.1,
+ min=0.0,
+ soft_max=1.0)
+ relative = bpy.props.BoolProperty(name="Relative", default=True)
+ dissolve = bpy.props.BoolProperty(name="Remove", default=True)
+ displace = bpy.props.FloatProperty(name="Displace",
+ soft_min=-5.0,
+ soft_max=5.0)
+
+ @classmethod
+ def poll(self, context):
+ return (context.active_object.type == 'MESH' and
+ context.mode == 'EDIT_MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "factor", text="Fac" if self.relative else "Dist")
+ sub = layout.row()
+ sub.prop(self, "relative")
+ sub.prop(self, "dissolve")
+ if not self.dissolve:
+ layout.prop(self, "displace")
+
+ def execute(self, context):
+ ob = context.active_object
+ me = ob.data
+ bm = bmesh.from_edit_mesh(me)
+
+ bm.select_flush(True)
+
+ fac = self.factor
+ rel = self.relative
+ dissolve = self.dissolve
+ displace = self.displace
+
+ for v in bm.verts:
+ v.tag = False
+
+ # Loop over edges to find those with both verts selected
+ for e in bm.edges[:]:
+ e.tag = e.select
+ if not e.select:
+ continue
+ elen = e.calc_length()
+ val = fac if rel else fac / elen
+ val = min(val, 0.5)
+ # Loop over the verts of the edge to split
+ for v in e.verts:
+ #if val == 0.5 and e.other_vert(v).tag:
+ # continue
+ en, vn = bmesh.utils.edge_split(e, v, val)
+ en.tag = vn.tag = True
+ val = 1.0 if val == 1.0 else val / (1.0 - val)
+
+ # Get all verts which are selected but not created previously
+ verts = [v for v in bm.verts if v.select and not v.tag]
+
+ # Loop over all verts to split their linked edges
+ for v in verts:
+ for e in v.link_edges[:]:
+ if e.tag:
+ continue
+ elen = e.calc_length()
+ val = fac if rel else fac / elen
+ bmesh.utils.edge_split(e, v, val)
+
+ # Loop over all the loops of the vert
+ for l in v.link_loops:
+ # Split the face
+ bmesh.utils.face_split(l.face,
+ l.link_loop_next.vert,
+ l.link_loop_prev.vert)
+
+ # Remove the vert or displace otherwise
+ if dissolve:
+ bmesh.utils.vert_dissolve(v)
+ else:
+ v.co += displace * v.normal
+
+ me.calc_tessface()
+
+ return {'FINISHED'}
+
+class chamfer_help(bpy.types.Operator):
+ bl_idname = 'help.vertexchamfer'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Make a selection or selection of verts ')
+ layout.label('Result is triangle chamfer, works on single vert.')
+ layout.label('To Help:')
+ layout.label('In some cases may need to press F to fill result.')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+
+def register():
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_extrude_along_curve.py b/release/scripts/addons_contrib/mesh_extrude_along_curve.py
new file mode 100644
index 0000000..dc548f3
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_extrude_along_curve.py
@@ -0,0 +1,212 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+
+bl_info = {
+ "name": "Extrude Along Curve",
+ "author": "Andrew Hale (TrumanBlending)",
+ "version": (0, 1),
+ "blender": (2, 63, 0),
+ "location": "",
+ "description": "Extrude a face along a Bezier Curve",
+ "warning": "",
+ 'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts",
+ 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
+ 'func=detail&aid=32585',
+ "category": "Mesh"}
+
+
+import bpy
+import bmesh
+from mathutils import Vector, Quaternion
+from math import ceil, floor, pi
+
+
+def eval_bez_tan(mat, points, t):
+ num = len(points)
+ t *= num - 1
+ upper = ceil(t)
+ lower = floor(t)
+ if upper == lower:
+ if upper == 0:
+ return (mat * (points[upper].handle_right - points[upper].co)).normalized()
+ elif upper == num - 1:
+ return (mat * (points[upper].co - points[upper].handle_left)).normalized()
+ else:
+ return (mat * (points[upper].co - points[upper].handle_left)).normalized()
+ else:
+ t -= lower
+ pupper = points[upper]
+ plower = points[lower]
+ tangent = -3 * (1 - t) ** 2 * plower.co + (-6 * (1 - t) * t + 3 * (1 - t) ** 2) * plower.handle_right + (-3 * t ** 2 + 3 * (1 - t) * 2 * t) * pupper.handle_left + 3 * t ** 2 * pupper.co
+ tangent = mat * tangent
+ tangent.normalize()
+ return tangent
+
+
+def eval_bez(mat, points, t):
+ num = len(points)
+ t *= num - 1
+ upper = ceil(t)
+ lower = floor(t)
+ if upper == lower:
+ return mat * points[upper].co
+ else:
+ t -= lower
+ pupper = points[upper]
+ plower = points[lower]
+ pos = (1 - t) ** 3 * plower.co + 3 * (1 - t) ** 2 * t * plower.handle_right + 3 * (1 - t) * t ** 2 * pupper.handle_left + t ** 3 * pupper.co
+ return mat * pos
+
+
+def curve_ob_enum(self, context):
+ obs = context.scene.objects
+ cuobs = [(str(i), ob.name, ob.name) for i, ob in enumerate(obs) if ob.type == 'CURVE']
+ curve_ob_enum.temp = cuobs
+ return cuobs
+
+
+class ExtrudeAlongCurve(bpy.types.Operator):
+ bl_idname = "mesh.extrude_along_curve"
+ bl_label = "Extrude Along Curve"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ resolution = bpy.props.IntProperty(name="Resolution", default=1, min=1, soft_max=100)
+ scale = bpy.props.FloatProperty(name="Scale", default=1.0, soft_min=0.0, soft_max=5.0)
+ rotation = bpy.props.FloatProperty(name="Rotation", default=0.0, soft_min=-2 * pi, soft_max=2 * pi, subtype='ANGLE')
+ splineidx = bpy.props.IntProperty(name="Spline Index", default=0, min=0)
+ snapto = bpy.props.BoolProperty(name="Snap To Face", default=True)
+ curveob = bpy.props.EnumProperty(name="Curve", items=curve_ob_enum)
+
+ @classmethod
+ def poll(self, context):
+ ob = context.active_object
+ for cuob in context.scene.objects:
+ if cuob.type == 'CURVE':
+ break
+ else:
+ return False
+
+ return (ob is not None) and (ob.type == 'MESH') and (context.mode == 'EDIT_MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "curveob", text="", icon='CURVE_DATA')
+ layout.prop(self, "resolution")
+ layout.prop(self, "scale")
+ layout.prop(self, "rotation")
+ layout.prop(self, "splineidx")
+ layout.prop(self, "snapto")
+
+ def execute(self, context):
+ ob = bpy.context.active_object
+ me = ob.data
+ bm = bmesh.from_edit_mesh(me)
+
+ # Get the selected curve object and the required spline
+ cuob = context.scene.objects[int(self.curveob)]
+ cu = cuob.data
+
+ self.splineidx = min(self.splineidx, len(cu.splines) - 1)
+ p = cu.splines[self.splineidx].bezier_points
+
+ # Get the property values
+ res = self.resolution
+ scale = self.scale
+ rotation = self.rotation
+ dscale = (1 - scale) / res
+ drot = rotation / res
+
+ # Get the matrices to convert between spaces
+ cmat = ob.matrix_world.inverted() * cuob.matrix_world
+ ctanmat = cmat.to_3x3().inverted().transposed()
+
+ # The list of parameter values to evaluate the bezier curve at
+ tvals = [t / res for t in range(res + 1)]
+
+ # Get the first selected face, if none, cancel
+ for f in bm.faces:
+ if f.select:
+ break
+ else:
+ return {'CANCELLED'}
+
+ # Get the position vecs on the curve and tangent values
+ bezval = [eval_bez(cmat, p, t) for t in tvals]
+ beztan = [eval_bez_tan(ctanmat, p, t) for t in tvals]
+ bezquat = [0] * len(tvals)
+
+ # Using curve only
+ bezquat[0] = beztan[0].to_track_quat('Z', 'Y')
+ fquat = bezquat[0].inverted()
+
+ # Calculate the min twist orientations
+ for i in range(1, res + 1):
+ ang = beztan[i - 1].angle(beztan[i], 0.0)
+ if ang > 0.0:
+ axis = beztan[i - 1].cross(beztan[i])
+ q = Quaternion(axis, ang)
+ bezquat[i] = q * bezquat[i - 1]
+ else:
+ bezquat[i] = bezquat[i - 1].copy()
+
+ # Get the faces to be modified
+ fprev = f
+ # no = f.normal.copy()
+ faces = [f.copy() for i in range(res)]
+
+ # Offset if we need to snap to the face
+ offset = Vector() if not self.snapto else (f.calc_center_median() - bezval[0])
+
+ # For each of the faces created, set their vert positions and create side faces
+ for i, data in enumerate(zip(faces, bezval[1:], bezquat[1:])):
+
+ fn, pos, quat = data
+ cen = fn.calc_center_median()
+
+ rotquat = Quaternion((0, 0, 1), i * drot)
+
+ for v in fn.verts:
+ v.co = quat * rotquat * fquat * (v.co - cen) * (1 - (i + 1) * dscale) + pos + offset
+
+ for ll, ul in zip(fprev.loops, fn.loops):
+ ff = bm.faces.new((ll.vert, ll.link_loop_next.vert, ul.link_loop_next.vert, ul.vert))
+ ff.normal_update()
+
+ bm.faces.remove(fprev)
+ fprev = fn
+
+ me.calc_tessface()
+ me.calc_normals()
+ me.update()
+
+ return {'FINISHED'}
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_face_info_select.py b/release/scripts/addons_contrib/mesh_face_info_select.py
new file mode 100644
index 0000000..ecf79d0
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_face_info_select.py
@@ -0,0 +1,127 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Face info / select by type",
+ "author": "CoDEmanX",
+ "version": (0, 0, 3),
+ "blender": (2, 62, 0),
+ "location": "Properties > Object data > Face info / select",
+ "description": "Displays triangle, quad and ngon count of the active object. Allows to select faces by these types.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Mesh/Face_Info_Select",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=31926",
+ "support": 'TESTING',
+ "category": "Mesh"
+}
+
+# Written by CoDEmanX for frivus
+
+
+import bpy
+from bpy.props import EnumProperty
+
+class DATA_OP_facetype_select(bpy.types.Operator):
+ """Select all faces of a certain type"""
+ bl_idname = "data.facetype_select"
+ bl_label = "Select by face type"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ face_type = EnumProperty(name="Select faces:",
+ items = (("3","Triangles","Faces made up of 3 vertices"),
+ ("4","Quads","Faces made up of 4 vertices"),
+ ("5","Ngons","Faces made up of 5 and more vertices")),
+ default = "5")
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None and context.active_object.type == 'MESH'
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='DESELECT')
+ context.tool_settings.mesh_select_mode=(False, False, True)
+
+ if self.face_type == "3":
+ bpy.ops.mesh.select_face_by_sides(number=3, type='EQUAL')
+ elif self.face_type == "4":
+ bpy.ops.mesh.select_face_by_sides(number=4, type='EQUAL')
+ else:
+ bpy.ops.mesh.select_face_by_sides(number=4, type='GREATER')
+
+ return {'FINISHED'}
+
+
+class DATA_PT_info_panel(bpy.types.Panel):
+ """Creates a face info / select panel in the Object properties window"""
+ bl_label = "Face info / select"
+ bl_idname = "DATA_PT_face_info"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "data"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ return context.active_object is not None and context.active_object.type == 'MESH'
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.active_object
+
+ info_str = ""
+ tris = quads = ngons = 0
+
+ for p in ob.data.polygons:
+ count = p.loop_total
+ if count == 3:
+ tris += 1
+ elif count == 4:
+ quads += 1
+ else:
+ ngons += 1
+
+ info_str = " Ngons: %i Quads: %i Tris: %i" % (ngons, quads, tris)
+
+ col = layout.column()
+ col.label(info_str, icon='MESH_DATA')
+
+ col = layout.column()
+ col.label("Select faces by type:")
+
+ row = layout.row()
+ row.operator("data.facetype_select", text="Ngons").face_type = "5"
+ row.operator("data.facetype_select", text="Quads").face_type = "4"
+ row.operator("data.facetype_select", text="Tris").face_type = "3"
+
+
+def register():
+ bpy.utils.register_class(DATA_PT_info_panel)
+ bpy.utils.register_class(DATA_OP_facetype_select)
+
+
+def unregister():
+ bpy.utils.unregister_class(DATA_PT_info_panel)
+ bpy.utils.unregister_class(DATA_OP_facetype_select)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_insert_edge_ring.py b/release/scripts/addons_contrib/mesh_insert_edge_ring.py
new file mode 100644
index 0000000..5d8440e
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_insert_edge_ring.py
@@ -0,0 +1,374 @@
+#Simplified BSD License
+#
+#Copyright (c) 2012, Florian Meyer
+#tstscr at web.de
+#All rights reserved.
+#
+#Redistribution and use in source and binary forms, with or without
+#modification, are permitted provided that the following conditions are met:
+#
+#1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#################################################################
+bl_info = {
+ "name": "Insert Edge Ring",
+ "author": "tstscr (tstscr at web.de)",
+ "version": (1, 0),
+ "blender": (2, 64, 0),
+ "location": "View3D > Edge Specials > Insert edge ring (Ctrl Alt R)",
+ "description": "Insert an edge ring along the selected edge loop",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Mesh/Insert_Edge_Ring",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=32424",
+ "category": "Mesh"}
+###########################################################################
+import bpy, bmesh, math
+from bpy.types import Operator
+from bpy.props import FloatProperty, BoolProperty, EnumProperty
+from mathutils import Vector
+from collections import deque
+from bmesh.utils import vert_separate
+###########################################################################
+def update(bme):
+ bme.verts.index_update()
+ bme.edges.index_update()
+
+def selected_edges(component, invert=False):
+ def is_vert(vert):
+ if invert:
+ return [e for e in component.link_edges if not e.select]
+ return [e for e in component.link_edges if e.select]
+ if type(component) == bmesh.types.BMVert:
+ return is_vert(component)
+ if type(component) == bmesh.types.BMEdge:
+ edges = []
+ for vert in component.verts:
+ edges.extend(is_vert(vert))
+ if component in edges:
+ edges.remove(component)
+ return edges
+
+def edge_loop_from(v_start):
+
+ def walk(vert, vert_loop=deque()):
+ #print('from', vert.index)
+ edges_select = selected_edges(vert)
+ #print('length edges_select', len(edges_select))
+ if not vert_loop:
+ #print('inserting %d into vert_loop' %vert.index)
+ vert_loop.append(vert)
+
+ for edge in edges_select:
+ other_vert = edge.other_vert(vert)
+ #print('other_vert %d' %other_vert.index)
+
+ edge_is_valid = True
+ if edge.is_boundary \
+ or other_vert in vert_loop \
+ or len(edges_select) > 2 \
+ or len(selected_edges(other_vert)) > 2:
+ #print('is not valid')
+ edge_is_valid = False
+
+ if edge_is_valid:
+ if vert == vert_loop[-1]:
+ #print('appending %d' %other_vert.index)
+ vert_loop.append(other_vert)
+ else:
+ #print('prepending %d' %other_vert.index)
+ vert_loop.appendleft(other_vert)
+
+ walk(other_vert, vert_loop)
+
+ return vert_loop
+ #####################################
+ v_loop = walk(v_start)
+ #print('returning', [v.index for v in v_loop])
+ return v_loop
+
+
+def collect_edge_loops(bme):
+ edge_loops = []
+ verts_to_consider = [v for v in bme.verts if v.select]
+
+ while verts_to_consider:
+
+ v_start = verts_to_consider[-1]
+ #print('\nverts_to_consider', [v.index for v in verts_to_consider])
+ edge_loop = edge_loop_from(v_start)
+ #update(bme)
+ #print('edge_loop', [v.index for v in edge_loop])
+ for v in edge_loop:
+ try:
+ verts_to_consider.remove(v)
+ except:
+ print('tried to remove vert %d from verts_to_consider. \
+ Failed somehow' %v.index)
+
+ if len(edge_loop) >= 3:
+ edge_loops.append(edge_loop)
+ else:
+ for v in edge_loop:
+ v.select = False
+
+ if not verts_to_consider:
+ #print('no more verts_to_consider')
+ pass
+
+ return edge_loops
+
+
+def insert_edge_ring(self, context):
+ def split_edge_loop(vert_loop):
+ other_loop = deque()
+ new_loop = deque()
+ for vert in vert_loop:
+ #print('OPERATING ON VERT', vert.index)
+ edges = selected_edges(vert)
+ v_new = bmesh.utils.vert_separate(vert, edges)
+ #print('RIPPING vert %d into' %vert.index, [v.index for v in v_new][:], \
+ # 'along edges', [e.index for e in edges])
+ if not closed:
+ if len(v_new) == 2:
+ other_loop.append([v for v in v_new if v != vert][0])
+ else:
+ other_loop.append(vert)
+
+ if closed:
+ if not new_loop:
+ #print('start_new_loop')
+ new_loop.append(v_new[0])
+ other_loop.append(v_new[1])
+ else:
+ neighbours = [e.other_vert(v_new[0]) for e in v_new[0].link_edges]
+ #print('neighbours', [n.index for n in neighbours])
+ for n in neighbours:
+ if n in new_loop and v_new[0] not in new_loop:
+ #print('v_detect')
+ new_loop.append(v_new[0])
+ other_loop.append(v_new[1])
+ if n in other_loop and v_new[0] not in other_loop:
+ #print('v_not_detect')
+ new_loop.append(v_new[1])
+ other_loop.append(v_new[0])
+
+ return other_loop, new_loop
+
+ def move_verts(vert_loop, other_vert_loop):
+
+ ### Offsets ###
+ def calc_offsets():
+ #print('\nCALCULATING OFFSETS')
+ offset = {}
+ for i, vert in enumerate(vert_loop):
+ edges_select = selected_edges(vert)
+ edges_unselect = selected_edges(vert, invert=True)
+
+ vert_opposite = other_vert_loop[i]
+ edges_select_opposite = selected_edges(vert_opposite)
+ edges_unselect_opposite = selected_edges(vert_opposite, invert=True)
+
+ ### MESH END VERT
+ if vert == other_vert_loop[0] or vert == other_vert_loop[-1]:
+ #print('vert %d is start-end in middle of mesh, \
+ # does not need moving\n' %vert.index)
+ continue
+
+ ### BOUNDARY VERT
+ if len(edges_select) == 1:
+ #print('verts %d %d are on boundary' \
+ #%(vert.index, other_vert_loop[i].index))
+ border_edge = [e for e in edges_unselect if e.is_boundary][0]
+ off = (border_edge.other_vert(vert).co - vert.co).normalized()
+ if self.direction == 'LEFT':
+ off *= 0
+ offset[vert] = off
+ #opposite vert
+ border_edge_opposite = [e for e in edges_unselect_opposite \
+ if e.is_boundary][0]
+ off = (border_edge_opposite.other_vert(vert_opposite).co \
+ - vert_opposite.co).normalized()
+ if self.direction == 'RIGHT':
+ off *= 0
+ offset[vert_opposite] = off
+ continue
+
+ ### MIDDLE VERT
+ if len(edges_select) == 2:
+ #print('\nverts %d %d are in middle of loop' \
+ #%(vert.index, other_vert_loop[i].index))
+ tangents = [e.calc_tangent(e.link_loops[0]) for e in edges_select]
+ off = (tangents[0] + tangents[1]).normalized()
+ angle = tangents[0].angle(tangents[1])
+ if self.even:
+ off += off * angle * 0.263910
+ if self.direction == 'LEFT':
+ off *= 0
+ offset[vert] = off
+ #opposite vert
+ tangents = [e.calc_tangent(e.link_loops[0]) \
+ for e in edges_select_opposite]
+ off = (tangents[0] + tangents[1]).normalized()
+ #angle= tangents[0].angle(tangents[1])
+ if self.even:
+ off += off * angle * 0.263910
+ if self.direction == 'RIGHT':
+ off *= 0
+ offset[vert_opposite] = off
+ continue
+
+ return offset
+
+ ### Moving ###
+ def move(offsets):
+ #print('\nMOVING VERTS')
+ for vert in offsets:
+ vert.co += offsets[vert] * self.distance
+
+ offsets = calc_offsets()
+ move(offsets)
+
+ def generate_new_geo(vert_loop, other_vert_loop):
+ #print('\nGENERATING NEW GEOMETRY')
+
+ for i, vert in enumerate(vert_loop):
+ if vert == other_vert_loop[i]:
+ continue
+ edge_new = bme.edges.new([vert, other_vert_loop[i]])
+ edge_new.select = True
+
+ bpy.ops.mesh.edge_face_add()
+
+ #####################################################################################
+ #####################################################################################
+ #####################################################################################
+
+ bme = bmesh.from_edit_mesh(context.object.data)
+
+ ### COLLECT EDGE LOOPS ###
+ e_loops = collect_edge_loops(bme)
+
+ for e_loop in e_loops:
+
+ #check for closed loop - douple vert at start-end
+ closed = False
+ edges_select = selected_edges(e_loop[0])
+ for e in edges_select:
+ if e_loop[-1] in e.verts:
+ closed = True
+
+ ### SPLITTING OF EDGES
+ other_vert_loop, new_loop = split_edge_loop(e_loop)
+ if closed:
+ e_loop = new_loop
+
+ ### MOVE RIPPED VERTS ###
+ move_verts(e_loop, other_vert_loop)
+
+ ### GENERATE NEW GEOMETRY ###
+ if self.generate_geo:
+ generate_new_geo(e_loop, other_vert_loop)
+
+ update(bme)
+
+###########################################################################
+# OPERATOR
+class MESH_OT_Insert_Edge_Ring(Operator):
+ """insert_edge_ring"""
+ bl_idname = "mesh.insert_edge_ring"
+ bl_label = "Insert edge ring"
+ bl_description = "Insert an edge ring along the selected edge loop"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ distance = FloatProperty(
+ name="distance",
+ default=0.01,
+ min=0, soft_min=0,
+ precision=4,
+ description="distance to move verts from original location")
+
+ even = BoolProperty(
+ name='even',
+ default=True,
+ description='keep 90 degrees angles straight')
+
+ generate_geo = BoolProperty(
+ name='Generate Geo',
+ default=True,
+ description='Fill edgering with faces')
+
+ direction = EnumProperty(
+ name='direction',
+ description='Direction in which to expand the edge_ring',
+ items={
+ ('LEFT', '<|', 'only move verts left of loop (arbitrary)'),
+ ('CENTER', '<|>', 'move verts on both sides of loop'),
+ ('RIGHT', '|>', 'only move verts right of loop (arbitrary)'),
+ },
+ default='CENTER')
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+
+ col.prop(self, 'distance', slider=False)
+ col.prop(self, 'even', toggle=True)
+ col.prop(self, 'generate_geo', toggle=True)
+ col.separator()
+ col.label(text='Direction')
+ row = layout.row(align=True)
+ row.prop(self, 'direction', expand=True)
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == 'EDIT_MESH'
+
+ def execute(self, context):
+ #print('\nInserting edge ring')
+ insert_edge_ring(self, context)
+ return {'FINISHED'}
+
+def insert_edge_ring_button(self, context):
+ self.layout.operator(MESH_OT_Insert_Edge_Ring.bl_idname,
+ text="Insert edge ring")
+###########################################################################
+# REGISTRATION
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_edges.append(insert_edge_ring_button)
+
+ kc = bpy.context.window_manager.keyconfigs.addon
+ if kc:
+ km = kc.keymaps.new(name="3D View", space_type="VIEW_3D")
+ kmi = km.keymap_items.new('mesh.insert_edge_ring', \
+ 'R', 'PRESS', ctrl=True, alt=True)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_edges.remove(insert_edge_ring_button)
+
+ kc = bpy.context.window_manager.keyconfigs.addon
+ if kc:
+ km = kc.keymaps["3D View"]
+ for kmi in km.keymap_items:
+ if kmi.idname == 'mesh.insert_edge_ring':
+ km.keymap_items.remove(kmi)
+ break
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_select_tools/__init__.py b/release/scripts/addons_contrib/mesh_select_tools/__init__.py
new file mode 100644
index 0000000..3db805a
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/__init__.py
@@ -0,0 +1,173 @@
+# ##### 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 LICENSE BLOCK #####
+# menu & updates by meta-androcto #
+# contributed to by Macouno, dustractor, liero, CoDEmanX, meta-androcto #
+
+bl_info = {
+ "name": "Select Tools",
+ "author": "Multiple Authors",
+ "version": (0, 3),
+ "blender": (2, 64, 0),
+ "location": "Editmode select menu",
+ "description": "Adds More vert/face/edge select modes.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
+ "Scripts/",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=32877",
+ "category": "Mesh"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(mesh_select_by_direction)
+ imp.reload(mesh_select_by_edge_length)
+ imp.reload(mesh_select_by_pi)
+ imp.reload(mesh_select_by_type)
+ imp.reload(mesh_select_connected_faces)
+ imp.reload(mesh_select_innermost)
+ imp.reload(mesh_index_select)
+ imp.reload(mesh_selection_topokit)
+ imp.reload(mesh_info_select)
+else:
+ from . import mesh_select_by_direction
+ from . import mesh_select_by_edge_length
+ from . import mesh_select_by_pi
+ from . import mesh_select_by_type
+ from . import mesh_select_connected_faces
+ from . import mesh_select_innermost
+ from . import mesh_index_select
+ from . import mesh_selection_topokit
+ from . import mesh_info_select
+
+import bpy, bmesh
+
+class VIEW3D_MT_selectface_edit_mesh_add(bpy.types.Menu):
+ # Define the "Mesh_Select_Tools" menu
+ bl_idname = "mesh.face_select_tools"
+ bl_label = "Select by Face"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.label(text = 'Face Select')
+ layout.separator()
+ layout.operator("data.facetype_select",
+ text="Triangles").face_type = "3"
+ layout.operator("data.facetype_select",
+ text="Quads").face_type = "4"
+ layout.operator("data.facetype_select",
+ text="Ngons").face_type = "5"
+ layout.separator()
+ layout.operator("mesh.select_vert_index",
+ text="By Face Index")
+ layout.operator("mesh.select_by_direction",
+ text="By Direction")
+ layout.operator("mesh.select_by_pi",
+ text="By Pi")
+ layout.operator("mesh.select_connected_faces",
+ text="By Connected Faces")
+ layout.operator("mesh.e2e_efe",
+ text="Neighbors by Face")
+ layout.operator("mesh.f2f_fvnef",
+ text="Neighbors by Vert not Edge")
+ layout.operator("mesh.conway",
+ text="Conway")
+
+class VIEW3D_MT_selectedge_edit_mesh_add(bpy.types.Menu):
+ # Define the "Mesh_Select_Tools" menu
+ bl_idname = "mesh.edge_select_tools"
+ bl_label = "Select by Edge"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.label(text = 'Edge Select')
+ layout.separator()
+ layout.operator("mesh.select_vert_index",
+ text="By Edge Index")
+ layout.operator("mesh.select_by_direction",
+ text="By Direction")
+ layout.operator("mesh.select_by_pi",
+ text="By Pi")
+ layout.operator("mesh.select_by_edge_length",
+ text="By Edge Length")
+ layout.separator()
+ layout.operator("mesh.e2e_eve",
+ text="Neighbors by Vert")
+ layout.operator("mesh.e2e_evfe",
+ text="Neighbors by Vert + Face")
+ layout.operator("mesh.e2e_efnve",
+ text="Lateral Neighbors")
+ layout.operator("mesh.e2e_evnfe",
+ text="Longitudinal Edges")
+# layout.operator("mesh.je",
+# text="only_edge_selection")
+
+class VIEW3D_MT_selectvert_edit_mesh_add(bpy.types.Menu):
+ # Define the "Mesh_Select_Tools" menu
+ bl_idname = "mesh.vert_select_tools"
+ bl_label = "Select by Vert"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.label(text = 'Vert Select')
+ layout.separator()
+ layout.operator("mesh.select_vert_index",
+ text="By Vert Index")
+ layout.operator("mesh.select_by_direction",
+ text="By Direction")
+ layout.operator("mesh.select_by_pi",
+ text="By Pi")
+# layout.operator("mesh.select_innermost",
+# text="innermost")
+ layout.separator()
+ layout.operator("mesh.v2v_by_edge",
+ text="Neighbors by Edge")
+ layout.operator("mesh.e2e_eve",
+ text="Neighbors by Vert")
+ layout.operator("mesh.e2e_efe",
+ text="Neighbors by Face")
+ layout.operator("mesh.v2v_facewise",
+ text="Neighbors by Face - Edge")
+# layout.operator("mesh.ie",
+# text="inner_edge_selection")
+
+# Register all operators and panels
+
+# Define "Extras" menu
+def menu_func(self, context):
+ if context.tool_settings.mesh_select_mode[2]:
+ self.layout.menu("mesh.face_select_tools", icon="PLUGIN")
+ if context.tool_settings.mesh_select_mode[1]:
+ self.layout.menu("mesh.edge_select_tools", icon="PLUGIN")
+ if context.tool_settings.mesh_select_mode[0]:
+ self.layout.menu("mesh.vert_select_tools", icon="PLUGIN")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_MT_select_edit_mesh.append(menu_func)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_select_edit_mesh.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_extras.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_extras.py
new file mode 100644
index 0000000..9b317b8
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_extras.py
@@ -0,0 +1,274 @@
+import bpy, mathutils, math
+from mathutils import geometry
+
+# Get a matrix for the selected faces that you can use to do local transforms
+def get_selection_matrix(faces=False):
+
+ me = bpy.context.active_object.data
+
+ if not faces:
+ faces = get_selected_faces()
+
+ yVec = mathutils.Vector()
+ zVec = mathutils.Vector()
+
+ # Ok so we have a basic matrix, but lets base it more on the mesh!
+ for f in faces:
+
+ v1 = me.vertices[f.vertices[0]].co
+ v2 = me.vertices[f.vertices[1]].co
+ edge = v2-v1
+
+ yVec += edge
+
+ if len(f.vertices) == 4:
+ v1 = me.vertices[f.vertices[2]].co
+ v2 = me.vertices[f.vertices[3]].co
+ edge = v1-v2
+
+ yVec += edge
+
+ zVec += mathutils.Vector(f.normal)
+
+ if not yVec.length:
+ quat = zVec.to_track_quat('-Z', 'Y')
+ tMat = quat.to_matrix()
+ yVec = tMat[1]
+ yVec = yVec.normalized()
+ else:
+ yVec = yVec.normalized()
+ zVec = zVec.normalized()
+
+ # Rotate yVec so it's 90 degrees to zVec
+ cross =yVec.cross(zVec)
+ vec = float(yVec.angle(zVec) - math.radians(90))
+ mat = mathutils.Matrix.Rotation(vec, 3, cross)
+ yVec = (mat * yVec)
+
+ xVec = yVec.cross(zVec)
+
+ xVec = xVec.normalized()
+
+ nMat = mathutils.Matrix((xVec, yVec, zVec))
+
+ return nMat
+
+
+
+# Get the selection radius (minimum distance of an outer edge to the centre)
+def get_selection_radius():
+
+ ob = bpy.context.active_object
+
+ radius = 0.0
+
+ # no use continueing if nothing is selected
+ if contains_selected_item(ob.data.polygons):
+
+ # Find the center of the selection
+ cent = mathutils.Vector()
+ nr = 0
+ nonVerts = []
+ selVerts = []
+ for f in ob.data.polygons:
+ if f.select:
+ nr += 1
+ cent += f.center
+ else:
+ nonVerts.extend(f.vertices)
+
+ cent /= nr
+
+ chk = 0
+
+ # Now that we know the center.. we can figure out how close the nearest point on an outer edge is
+ for e in get_selected_edges():
+
+ nonSection = [v for v in e.vertices if v in nonVerts]
+ if len(nonSection):
+
+ v0 = ob.data.vertices[e.vertices[0]].co
+ v1 = ob.data.vertices[e.vertices[1]].co
+
+ # If there's more than 1 vert of this edge on the outside... we need the edge length to be long enough too!
+ if len(nonSection) > 1:
+ edge = v0 - v1
+ edgeRad = edge.length * 0.5
+
+ if edgeRad < radius or not chk:
+ radius = edgeRad
+ chk += 1
+
+ int = geometry.intersect_point_line(cent, v0, v1)
+
+ rad = cent - int[0]
+ l = rad.length
+
+ if l < radius or not chk:
+ radius = l
+ chk += 1
+
+ return radius
+
+
+
+# Get the average length of the outer edges of the current selection
+def get_shortest_outer_edge_length():
+
+ ob = bpy.context.active_object
+
+ min = False
+ me = ob.data
+
+ delVerts = []
+ for f in me.faces:
+ if not f.select:
+ delVerts.extend(f.vertices)
+ selEdges = [e.vertices for e in me.edges if e.select]
+
+ if len(selEdges) and len(delVerts):
+
+ for eVerts in selEdges:
+
+ v0 = eVerts[0]
+ v1 = eVerts[1]
+
+ if v0 in delVerts and v1 in delVerts:
+ ln = (me.vertices[v0].co - me.vertices[v1].co).length
+ if min is False or (ln > 0.0 and ln < min):
+ min = ln
+
+ return min
+
+
+# Get the average length of the outer edges of the current selection
+def get_average_outer_edge_length():
+
+ ob = bpy.context.active_object
+
+ ave = 0.0
+ me = ob.data
+
+ delFaces = [f.vertices for f in me.faces if not f.select]
+ selEdges = [e.vertices for e in me.edges if e.select]
+
+ if len(selEdges) and len(delFaces):
+
+ number = 0
+
+ for eVerts in selEdges:
+
+ v0 = eVerts[0]
+ v1 = eVerts[1]
+
+ for fVerts in delFaces:
+ if v0 in fVerts and v1 in fVerts:
+ number += 1
+ ave += (me.vertices[v0].co - me.vertices[v1].co).length
+ break
+
+ if number:
+ ave /= number
+
+ return ave
+
+
+
+# Get the selected (or deselected items)
+def get_selected(type='vertices',invert=False):
+
+ mesh = bpy.context.active_object.data
+
+ if type == 'vertices':
+ items = mesh.vertices
+ elif type == 'edges':
+ items = mesh.edges
+ else:
+ items = mesh.polygons
+
+ if invert:
+ L = [i for i in items if not i.select]
+ else:
+ L = [i for i in items if i.select]
+ return L
+
+
+
+# See if the mesh has something selected
+def has_selected(type='vertices',invert=False):
+
+ mesh = bpy.context.active_object.data
+
+ if type == 'vertices':
+ items = mesh.vertices
+ elif type == 'edges':
+ items = mesh.edges
+ else:
+ items = mesh.polygons
+
+ for i in items:
+ if not invert and i.select:
+ return True
+ elif invert and not i.select:
+ return True
+
+ return False
+
+
+
+# Get all the selected vertices (mode is selected or deselected)
+def get_selected_vertices(mode='selected'):
+
+ vertices = bpy.context.active_object.data.vertices
+
+ if mode == 'deselected':
+ L = [v for v in vertices if not v.select]
+ else:
+ L = [v for v in vertices if v.select]
+ return L
+
+
+
+# Get all the selected edges (mode is selected or deselected)
+def get_selected_edges(mode='selected'):
+
+ edges = bpy.context.active_object.data.edges
+
+ if mode == 'deselected':
+ L = [e for e in edges if not e.select]
+ else:
+ L = [e for e in edges if e.select]
+ return L
+
+
+
+# Get all the selected faces (mode is selected or deselected)
+def get_selected_faces(mode='selected'):
+
+ polygons = bpy.context.active_object.data.polygons
+
+ if mode == 'deselected':
+ L = [f for f in polygons if not f.select]
+ else:
+ L = [f for f in polygons if f.select]
+ return L
+
+
+
+# See if there is at least one selected item in 'items'
+def contains_selected_item(items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_index_select.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_index_select.py
new file mode 100644
index 0000000..4965cb7
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_index_select.py
@@ -0,0 +1,182 @@
+bl_info = {
+ "name": "Select by index",
+ "author": "liero",
+ "version": (0, 2),
+ "blender": (2, 55, 0),
+ "api": 33333,
+ "location": "View3D > Tool Shelf",
+ "description": "Select mesh data by index / area / length / cursor",
+ "category": "Mesh"}
+
+import bpy, mathutils
+from mathutils import Vector
+
+class SelVert(bpy.types.Operator):
+ bl_idname = 'mesh.select_vert_index'
+ bl_label = 'Verts'
+ bl_description = 'Select vertices by index'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ indice = bpy.props.FloatProperty(name='Selected', default=0, min=0, max=100, description='Percentage of selected edges', precision = 2, subtype = 'PERCENTAGE')
+ delta = bpy.props.BoolProperty(name='Use Cursor', default=False, description='Select by Index / Distance to Cursor')
+ flip = bpy.props.BoolProperty(name='Reverse Order', default=False, description='Reverse selecting order')
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type == 'MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self,'indice', slider=True)
+ layout.prop(self,'delta')
+ layout.prop(self,'flip')
+
+ def execute(self, context):
+ obj = bpy.context.object
+ mode = [a for a in bpy.context.tool_settings.mesh_select_mode]
+ if mode != [True, False, False]:
+ bpy.context.tool_settings.mesh_select_mode = [True, False, False]
+ ver = obj.data.vertices
+ loc = context.scene.cursor_location
+ sel = []
+ for v in ver:
+ d = v.co - loc
+ sel.append((d.length, v.index))
+ sel.sort()
+ if self.flip:
+ sel.reverse()
+ bpy.ops.object.mode_set()
+ valor = round(len(sel) / 100 * self.indice)
+ if self.delta:
+ for i in range(len(sel[:valor])):
+ ver[sel[i][1]].select = True
+ else:
+ for i in range(len(sel[:valor])):
+ if self.flip:
+ ver[len(sel)-i-1].select = True
+ else:
+ ver[i].select = True
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+class SelEdge(bpy.types.Operator):
+ bl_idname = 'mesh.select_edge_index'
+ bl_label = 'Edges'
+ bl_description = 'Select edges by index'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ indice = bpy.props.FloatProperty(name='Selected', default=0, min=0, max=100, description='Percentage of selected edges', precision = 2, subtype = 'PERCENTAGE')
+ delta = bpy.props.BoolProperty(name='Use Edges Length', default=False, description='Select Edges by Index / Length')
+ flip = bpy.props.BoolProperty(name='Reverse Order', default=False, description='Reverse selecting order')
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type == 'MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self,'indice', slider=True)
+ layout.prop(self,'delta')
+ layout.prop(self,'flip')
+
+ def execute(self, context):
+ obj = bpy.context.object
+ mode = [a for a in bpy.context.tool_settings.mesh_select_mode]
+ if mode != [False, True, False]:
+ bpy.context.tool_settings.mesh_select_mode = [False, True, False]
+ ver = obj.data.vertices
+ edg = obj.data.edges
+ sel = []
+ for e in edg:
+ d = ver[e.vertices[0]].co - ver[e.vertices[1]].co
+ sel.append((d.length, e.index))
+ sel.sort()
+ if self.flip:
+ sel.reverse()
+ bpy.ops.object.mode_set()
+ valor = round(len(sel) / 100 * self.indice)
+ if self.delta:
+ for i in range(len(sel[:valor])):
+ edg[sel[i][1]].select = True
+ else:
+ for i in range(len(sel[:valor])):
+ if self.flip:
+ edg[len(sel)-i-1].select = True
+ else:
+ edg[i].select = True
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+class SelFace(bpy.types.Operator):
+ bl_idname = 'mesh.select_face_index'
+ bl_label = 'Faces'
+ bl_description = 'Select faces by index'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ indice = bpy.props.FloatProperty(name='Selected', default=0, min=0, max=100, description='Percentage of selected faces', precision = 2, subtype = 'PERCENTAGE')
+ delta = bpy.props.BoolProperty(name='Use Faces Area', default=False, description='Select Faces by Index / Area')
+ flip = bpy.props.BoolProperty(name='Reverse Order', default=False, description='Reverse selecting order')
+
+ @classmethod
+ def poll(cls, context):
+ return (context.object and context.object.type == 'MESH')
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self,'indice', slider=True)
+ layout.prop(self,'delta')
+ layout.prop(self,'flip')
+
+ def execute(self, context):
+ obj = bpy.context.object
+ mode = [a for a in bpy.context.tool_settings.mesh_select_mode]
+ if mode != [False, False, True]:
+ bpy.context.tool_settings.mesh_select_mode = [False, False, True]
+ fac = obj.data.polygons
+ sel = []
+ for f in fac:
+ sel.append((f.area, f.index))
+ sel.sort()
+ if self.flip:
+ sel.reverse()
+ print (sel)
+ bpy.ops.object.mode_set()
+ valor = round(len(sel) / 100 * self.indice)
+ if self.delta:
+ for i in range(len(sel[:valor])):
+ fac[sel[i][1]].select = True
+ else:
+ for i in range(len(sel[:valor])):
+ if self.flip:
+ fac[len(sel)-i-1].select = True
+ else:
+ fac[i].select = True
+ bpy.ops.object.mode_set(mode='EDIT')
+ return {'FINISHED'}
+
+class GUI(bpy.types.Panel):
+ bl_label = 'Select mesh data'
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row(align=True)
+ row.operator('mesh.select_vert_index')
+ row.operator('mesh.select_edge_index')
+ row.operator('mesh.select_face_index')
+
+def register():
+ bpy.utils.register_class(SelVert)
+ bpy.utils.register_class(SelEdge)
+ bpy.utils.register_class(SelFace)
+ bpy.utils.register_class(GUI)
+
+def unregister():
+ bpy.utils.unregister_class(SelVert)
+ bpy.utils.unregister_class(SelEdge)
+ bpy.utils.unregister_class(SelFace)
+ bpy.utils.unregister_class(GUI)
+
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_info_select.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_info_select.py
new file mode 100644
index 0000000..c97381e
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_info_select.py
@@ -0,0 +1,64 @@
+# ##### 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 LICENSE BLOCK #####
+
+# By CoDEmanX
+
+import bpy
+
+class DATA_PT_info_panel(bpy.types.Panel):
+ """Creates a face info / select panel in the Object properties window"""
+ bl_label = "Face info / select"
+ bl_idname = "DATA_PT_face_info"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "data"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ return context.active_object is not None and context.active_object.type == 'MESH'
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.active_object
+
+ info_str = ""
+ tris = quads = ngons = 0
+
+ for p in ob.data.polygons:
+ count = p.loop_total
+ if count == 3:
+ tris += 1
+ elif count == 4:
+ quads += 1
+ else:
+ ngons += 1
+
+ info_str = " Ngons: %i Quads: %i Tris: %i" % (ngons, quads, tris)
+
+ col = layout.column()
+ col.label(info_str, icon='MESH_DATA')
+
+ col = layout.column()
+ col.label("Select faces by type:")
+
+ row = layout.row()
+ row.operator("data.facetype_select", text="Ngons").face_type = "5"
+ row.operator("data.facetype_select", text="Quads").face_type = "4"
+ row.operator("data.facetype_select", text="Tris").face_type = "3"
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_direction.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_direction.py
new file mode 100644
index 0000000..cb2cca2
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_direction.py
@@ -0,0 +1,214 @@
+# mesh_select_by_direction.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Extrude a selection from a mesh multiple times
+#
+# ***** 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 *****
+'''
+bl_info = {
+ "name": "Select by direction",
+ "author": "Dolf Veenvliet",
+ "version": 1,
+ "blender": (2, 56, 0),
+ "api": 31847,
+ "location": "View3D > Select",
+ "description": "Select all items whose normals face a certain direction",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from from "Select -> By direction"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+'''
+import bpy, mathutils, math
+from bpy.props import FloatVectorProperty, FloatProperty, BoolProperty, EnumProperty
+
+
+class Select_by_direction():
+
+ # Initialise the class
+ def __init__(self, context, direction, divergence, extend, space):
+
+ self.ob = context.active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ self.space = space
+
+ # if we do stuff in global space we need to object matrix
+ if self.space == 'GLO':
+ direction = mathutils.Vector(direction) * mathutils.Matrix(self.ob.matrix_world.rotation_part()).invert()
+ else:
+ direction = mathutils.Vector(direction)
+
+ direction = direction.normalized()
+
+ vertSelect = bpy.context.tool_settings.mesh_select_mode[0]
+ edgeSelect = bpy.context.tool_settings.mesh_select_mode[1]
+ faceSelect = bpy.context.tool_settings.mesh_select_mode[2]
+
+ if mathutils.Vector(direction).length:
+
+ # Vert select
+ if vertSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.vertices)
+
+ for v in self.ob.data.vertices:
+
+ normal = v.normal
+
+ s = self.selectCheck(v.select, hasSelected, extend)
+ d = self.deselectCheck(v.select, hasSelected, extend)
+
+ if s or d:
+ angle = direction.angle(normal)
+
+ # Check if the verts match any of the directions
+ if s and angle <= divergence:
+ v.select = True
+
+ if d and angle > divergence:
+ v.select = False
+
+ # Edge select
+ if edgeSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.edges)
+
+ for e in self.ob.data.edges:
+
+ s = self.selectCheck(e.select, hasSelected, extend)
+ d = self.deselectCheck(e.select, hasSelected, extend)
+
+
+ # Check if the edges match any of the directions
+ if s or d:
+ normal = self.ob.data.vertices[e.vertices[0]].normal
+ normal += self.ob.data.vertices[e.vertices[1]].normal
+
+ angle =direction.angle(normal)
+
+
+ if s and angle <= divergence:
+ e.select = True
+
+ if d and angle > divergence:
+ e.select = False
+
+ # Face select
+ if faceSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.polygons)
+
+ # Loop through all the given faces
+ for f in self.ob.data.polygons:
+
+ s = self.selectCheck(f.select, hasSelected, extend)
+ d = self.deselectCheck(f.select, hasSelected, extend)
+
+ if s or d:
+ angle = direction.angle(f.normal)
+
+ # Check if the faces match any of the directions
+ if s and angle <= divergence:
+ f.select = True
+
+ if d and angle > divergence:
+ f.select = False
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+
+
+ # See if the current item should be selected or not
+ def selectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is not selected we may want to select
+ if not isSelected:
+
+ # If we are extending or nothing is selected we want to select
+ if extend or not hasSelected:
+ return True
+
+ return False
+
+
+
+ # See if the current item should be deselected or not
+ def deselectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is selected we may want to deselect
+ if isSelected:
+
+ # If something is selected and we're not extending we want to deselect
+ if hasSelected and not extend:
+ return True
+
+ return False
+
+
+
+ # See if there is at least one selected item
+ def hasSelected(self, items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+class Select_init(bpy.types.Operator):
+ '''Select all items with normals facing a certain direction'''
+ bl_idname = 'mesh.select_by_direction'
+ bl_label = 'Select by direction'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ direction = FloatVectorProperty(name="Direction", description="Direction as a vector", default=(0.0, 0.0, 1.0), min=-100.0, max=100.0, soft_min=-10.0, soft_max=10.0, step=100, precision=2)
+
+ divergence = FloatProperty(name='Divergence', description='The nr of degrees the selection may differ from the vector', default=math.radians(30.0), min=0.0, max=math.radians(360.0), soft_min=0.0, soft_max=math.radians(360.0), step=math.radians(5000), precision=2, subtype='ANGLE')
+
+ extend = BoolProperty(name='Extend', description='Extend the current selection', default=False)
+
+ # The spaces we use
+ spaces=(('LOC', 'Local', ''),('GLO', 'Global', ''))
+
+ space = EnumProperty(items=spaces, name='Space', description='The space to interpret the directions in', default='LOC')
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def execute(self, context):
+ SELECT_DIRECTION = Select_by_direction(context, self.direction, self.divergence, self.extend, self.space)
+ return {'FINISHED'}
+
+
+
+
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_edge_length.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_edge_length.py
new file mode 100644
index 0000000..9b4d025
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_edge_length.py
@@ -0,0 +1,219 @@
+# mesh_select_by_edge_length.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Extrude a selection from a mesh multiple times
+#
+# ***** 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 *****
+'''
+bl_info = {
+ "name": "Select by edge length",
+ "author": "Dolf Veenvliet",
+ "version": 1,
+ "blender": (2, 56, 0),
+ "api": 31847,
+ "location": "View3D > Select",
+ "description": "Select all items whose scale/length/surface matches a certain edge length",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from from "Select -> By edge length"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+'''
+import bpy, mathutils, math
+from bpy.props import FloatProperty, BoolProperty, EnumProperty
+
+
+class Select_by_edge_length():
+
+ # Initialise the class
+ def __init__(self, context, edgeLength, bigger, smaller, extend, space):
+
+ self.ob = context.active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ self.space = space
+ self.obMat = self.ob.matrix_world
+
+ # We ignore vert selections completely
+ #vertSelect = bpy.context.tool_settings.mesh_select_mode[0]
+ edgeSelect = bpy.context.tool_settings.mesh_select_mode[1]
+ faceSelect = bpy.context.tool_settings.mesh_select_mode[2]
+
+
+ # Edge select
+ if edgeSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.edges)
+
+ for e in self.ob.data.edges:
+
+ if self.selectCheck(e.select, hasSelected, extend):
+
+ len = self.getEdgeLength(e.vertices)
+
+ if len == edgeLength or (bigger and len >= edgeLength) or (smaller and len <= edgeLength):
+ e.select = True
+
+ if self.deselectCheck(e.select, hasSelected, extend):
+ len = self.getEdgeLength(e.vertices)
+
+ if len != edgeLength and not (bigger and len >= edgeLength) and not (smaller and len <= edgeLength):
+ e.select = False
+
+ # Face select
+ if faceSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.polygons)
+
+ # Loop through all the given faces
+ for f in self.ob.data.polygons:
+
+ # Check if the faces match any of the directions
+ if self.selectCheck(f.select, hasSelected, extend):
+
+ min = 0.0
+ max = 0.0
+
+ for i, e in enumerate(f.edge_keys):
+ len = self.getEdgeLength(e)
+ if not i:
+ min = len
+ max = len
+ elif len < min:
+ min = len
+ elif len > max:
+ max = len
+
+ if (min == edgeLength and max == edgeLength) or (bigger and min >= edgeLength) or (smaller and max <= edgeLength):
+ f.select = True
+
+ if self.deselectCheck(f.select, hasSelected, extend):
+
+ min = 0.0
+ max = 0.0
+
+ for i, e in enumerate(f.edge_keys):
+ len = self.getEdgeLength(e)
+ if not i:
+ min = len
+ max = len
+ elif len < min:
+ min = len
+ elif len > max:
+ max = len
+
+ if (min != edgeLength and max != edgeLength) and not (bigger and min >= edgeLength) and not (smaller and max <= edgeLength):
+ f.select = False
+
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+
+
+ # Get the lenght of an edge, by giving this function all verts (2) in the edge
+ def getEdgeLength(self, verts):
+
+ vec1 = self.ob.data.vertices[verts[0]].co
+ vec2 = self.ob.data.vertices[verts[1]].co
+
+ vec = vec1 - vec2
+
+ if self.space == 'GLO':
+ vec *= self.obMat
+
+ return round(vec.length, 5)
+
+
+
+ # See if the current item should be selected or not
+ def selectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is not selected we may want to select
+ if not isSelected:
+
+ # If we are extending or nothing is selected we want to select
+ if extend or not hasSelected:
+ return True
+
+ return False
+
+
+
+ # See if the current item should be deselected or not
+ def deselectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is selected we may want to deselect
+ if isSelected:
+
+ # If something is selected and we're not extending we want to deselect
+ if hasSelected and not extend:
+ return True
+
+ return False
+
+
+
+ # See if there is at least one selected item
+ def hasSelected(self, items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+class Select_init(bpy.types.Operator):
+ '''Select all items with normals facing a certain direction'''
+ bl_idname = 'mesh.select_by_edge_length'
+ bl_label = 'Select by edge length'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ edgeLength = FloatProperty(name='Edge length', description='The scale in Blender units', default=1.0, min=0.0, max=1000.0, soft_min=0.0, soft_max=100.0, step=100, precision=2)
+
+ bigger = BoolProperty(name='Bigger', description='Select items bigger than the size setting', default=False)
+
+ smaller = BoolProperty(name='Smaller', description='Select items smaller than the size setting', default=False)
+
+ extend = BoolProperty(name='Extend', description='Extend the current selection', default=False)
+
+ # The spaces we use
+ spaces=(('LOC', 'Local', ''),('GLO', 'Global', ''))
+
+ space = EnumProperty(items=spaces, name='Space', description='The space to interpret the directions in', default='LOC')
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and not bpy.context.tool_settings.mesh_select_mode[0])
+
+ def execute(self, context):
+ SELECT_EDGES = Select_by_edge_length(context, self.edgeLength, self.bigger, self.smaller, self.extend, self.space)
+ return {'FINISHED'}
+
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_pi.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_pi.py
new file mode 100644
index 0000000..c3a6108
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_pi.py
@@ -0,0 +1,214 @@
+# mesh_select_by_pi.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Extrude a selection from a mesh multiple times
+#
+# ***** 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 *****
+'''
+bl_info = {
+ "name": "Select by pi",
+ "author": "Dolf Veenvliet",
+ "version": 1,
+ "blender": (2, 56, 0),
+ "api": 31847,
+ "location": "View3D > Select",
+ "description": "Select fake random based on pi",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from from "Select -> By pi"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+'''
+import bpy
+from bpy.props import BoolProperty
+
+
+class Select_by_pi():
+
+ # Initialise the class
+ def __init__(self, context, e, invert, extend):
+
+ self.ob = context.active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ self.invert = invert
+
+ # Make pi as a list of integers
+ if e:
+ self.pi = list('27182818284590452353602874713526624977572470936999')
+ else:
+ self.pi = list('31415926535897932384626433832795028841971693993751')
+
+ self.piLen = len(self.pi)
+ self.piPos = 0
+
+ vertSelect = bpy.context.tool_settings.mesh_select_mode[0]
+ edgeSelect = bpy.context.tool_settings.mesh_select_mode[1]
+ faceSelect = bpy.context.tool_settings.mesh_select_mode[2]
+
+ # Vert select
+ if vertSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.vertices)
+
+ for v in self.ob.data.vertices:
+
+ s = self.selectCheck(v.select, hasSelected, extend)
+ d = self.deselectCheck(v.select, hasSelected, extend)
+
+ # Check if the verts match any of the directions
+ if s and self.choose():
+ v.select = True
+
+ if d and not self.choose():
+ v.select = False
+
+ # Edge select
+ if edgeSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.edges)
+
+ for e in self.ob.data.edges:
+
+ s = self.selectCheck(e.select, hasSelected, extend)
+ d = self.deselectCheck(e.select, hasSelected, extend)
+
+ if s and self.choose():
+ e.select = True
+
+ if d and not self.choose():
+ e.select = False
+
+ # Face select
+ if faceSelect:
+
+ hasSelected = self.hasSelected(self.ob.data.polygons)
+
+ # Loop through all the given faces
+ for f in self.ob.data.polygons:
+
+ s = self.selectCheck(f.select, hasSelected, extend)
+ d = self.deselectCheck(f.select, hasSelected, extend)
+
+ # Check if the faces match any of the directions
+ if s and self.choose():
+ f.select = True
+
+ if d and not self.choose():
+ f.select = False
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+
+
+ # Choose by pi
+ def choose(self):
+ choice = True
+
+ # We just choose the odd numbers
+ if int(self.pi[self.piPos]) % 2:
+ choice = False
+
+ if self.invert:
+ if choice:
+ choice = False
+ else:
+ choice = True
+
+ self.incrementPiPos()
+ return choice
+
+
+
+ # Increment the pi position
+ def incrementPiPos(self):
+ self.piPos += 1
+ if self.piPos == self.piLen:
+ self.piPos = 0
+
+
+
+ # See if the current item should be selected or not
+ def selectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is not selected we may want to select
+ if not isSelected:
+
+ # If we are extending or nothing is selected we want to select
+ if extend or not hasSelected:
+ return True
+
+ return False
+
+
+
+ # See if the current item should be deselected or not
+ def deselectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is selected we may want to deselect
+ if isSelected:
+
+ # If something is selected and we're not extending we want to deselect
+ if hasSelected and not extend:
+ return True
+
+ return False
+
+
+
+ # See if there is at least one selected item
+ def hasSelected(self, items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+class Select_init(bpy.types.Operator):
+ '''Select faces based on pi'''
+ bl_idname = 'mesh.select_by_pi'
+ bl_label = 'Select by pi'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ e = BoolProperty(name='Use e', description='use e in stead of pi', default=False)
+
+ invert = BoolProperty(name='Invert', description='Invert the selection result', default=False)
+
+ extend = BoolProperty(name='Extend', description='Extend the current selection', default=False)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def execute(self, context):
+ SELECT_DIRECTION = Select_by_pi(context, self.e, self.invert, self.extend)
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_type.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_type.py
new file mode 100644
index 0000000..c75d6b5
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_by_type.py
@@ -0,0 +1,59 @@
+# ##### 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 LICENSE BLOCK #####
+
+# By CoDEmanX
+
+import bpy
+from bpy.props import EnumProperty, BoolProperty
+
+class DATA_OP_facetype_select(bpy.types.Operator):
+ """Select all faces of a certain type"""
+ bl_idname = "data.facetype_select"
+ bl_label = "Select by face type"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ face_type = EnumProperty(name="Select faces:",
+ items = (("3","Triangles","Faces made up of 3 vertices"),
+ ("4","Quads","Faces made up of 4 vertices"),
+ ("5","Ngons","Faces made up of 5 and more vertices")),
+ default = "5")
+
+ extend = BoolProperty(name="Extend", description="Extend Selection", default=False)
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None and context.active_object.type == 'MESH'
+
+ def execute(self, context):
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ if not self.extend:
+ bpy.ops.mesh.select_all(action='DESELECT')
+
+ context.tool_settings.mesh_select_mode=(False, False, True)
+
+ if self.face_type == "3":
+ bpy.ops.mesh.select_face_by_sides(number=3, type='EQUAL')
+ elif self.face_type == "4":
+ bpy.ops.mesh.select_face_by_sides(number=4, type='EQUAL')
+ else:
+ bpy.ops.mesh.select_face_by_sides(number=4, type='GREATER')
+
+ return {'FINISHED'}
+
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_checkered.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_checkered.py
new file mode 100644
index 0000000..e027632
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_checkered.py
@@ -0,0 +1,185 @@
+# mesh_select_checkered.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Extrude a selection from a mesh multiple times
+#
+# ***** 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 *****
+
+bl_info = {
+ "name": "Select checkered",
+ "author": "Dolf Veenvliet",
+ "version": 1,
+ "blender": (2, 56, 0),
+ "api": 31847,
+ "location": "View3D > Select",
+ "description": "Select checkered",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from from "Select -> checkered"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+
+import bpy
+from bpy.props import BoolProperty
+
+
+class Select_checkered():
+
+ # Initialise the class
+ def __init__(self, context, invert, extend):
+
+ self.ob = context.active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ self.invert = invert
+
+ self.selectedVerts = []
+ self.selectedFaces = []
+ self.deselectedFaces = []
+
+ hasSelected = self.hasSelected(self.ob.data.polygons)
+
+
+ working = True
+ while working:
+
+ working = False
+
+ # Loop through all the given faces
+ for f in self.ob.data.polygons:
+
+ if not f.index in self.selectedFaces and not f.index in self.deselectedFaces:
+
+ choice = self.Choose(f)
+
+ if choice != 'skip':
+
+ s = self.selectCheck(f.select, hasSelected, extend)
+ d = self.deselectCheck(f.select, hasSelected, extend)
+
+ # Check if the faces match any of the directions
+ if s and choice:
+ f.select = True
+ working = True
+
+ if d and not choice:
+ f.select = False
+ working = True
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+
+
+ # Choose whether or not to select
+ def Choose(self, f):
+
+ choice = 'skip'
+
+ if not len(self.selectedFaces):
+ choice = True
+ self.selectedFaces.append(f.index)
+ self.selectedVerts.extend(f.vertices)
+
+ else:
+ intersection = [v for v in f.vertices if v in self.selectedVerts]
+
+ if len(intersection) == 1:
+ choice = True
+ self.selectedFaces.append(f.index)
+ self.selectedVerts.extend(f.vertices)
+
+ elif len(intersection) == 2:
+ choice = False
+ self.deselectedFaces.append(f.index)
+
+ if self.invert:
+ if choice:
+ choice = False
+ else:
+ choice = True
+ return choice
+
+
+ # See if the current item should be selected or not
+ def selectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is not selected we may want to select
+ if not isSelected:
+
+ # If we are extending or nothing is selected we want to select
+ if extend or not hasSelected:
+ return True
+
+ return False
+
+
+
+ # See if the current item should be deselected or not
+ def deselectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is selected we may want to deselect
+ if isSelected:
+
+ # If something is selected and we're not extending we want to deselect
+ if hasSelected and not extend:
+ return True
+
+ return False
+
+
+
+ # See if there is at least one selected item
+ def hasSelected(self, items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+class Select_init(bpy.types.Operator):
+ '''Select faces based on pi'''
+ bl_idname = 'mesh.select_checkered'
+ bl_label = 'Select checkered'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ invert = BoolProperty(name='Invert', description='Invert the selection result', default=False)
+
+ extend = BoolProperty(name='Extend', description='Extend the current selection', default=False)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def execute(self, context):
+ SELECT_DIRECTION = Select_checkered(context, self.invert, self.extend)
+ return {'FINISHED'}
+
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_connected_faces.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_connected_faces.py
new file mode 100644
index 0000000..06ebac8
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_connected_faces.py
@@ -0,0 +1,149 @@
+# mesh_select_connected_faces.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Extrude a selection from a mesh multiple times
+#
+# ***** 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 *****
+'''
+ bl_info = {
+ "name": "Select connected faces",
+ "author": "Dolf Veenvliet",
+ "version": 1,
+ "blender": (2, 56, 0),
+ "api": 31847,
+ "location": "View3D > Select",
+ "description": "Select all faces connected to the current selection",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from from "Select -> Connected faces"
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+'''
+import bpy, mathutils, math
+from bpy.props import IntProperty, BoolProperty
+
+
+class Select_connected_faces():
+
+ # Initialise the class
+ def __init__(self, context, iterations, extend):
+
+ self.ob = context.active_object
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Make a list of all selected vertices
+ selVerts = [v.index for v in self.ob.data.vertices if v.select]
+
+ hasSelected = self.hasSelected(self.ob.data.polygons)
+
+ for i in range(iterations):
+
+ nextVerts = []
+
+ for f in self.ob.data.polygons:
+
+ if self.selectCheck(f.select, hasSelected, extend):
+
+ for v in f.vertices:
+ if v in selVerts:
+ f.select = True
+
+ if f.select:
+ for v in f.vertices:
+ if v not in selVerts:
+ nextVerts.append(v)
+
+ elif self.deselectCheck(f.select, hasSelected, extend):
+
+ for v in f.vertices:
+ if v in selVerts:
+ f.select = False
+
+
+ selVerts = nextVerts
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+
+
+ # See if the current item should be selected or not
+ def selectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is not selected we may want to select
+ if not isSelected:
+ return True
+
+ return False
+
+
+
+ # See if the current item should be deselected or not
+ def deselectCheck(self, isSelected, hasSelected, extend):
+
+ # If the current item is selected we may want to deselect
+ if isSelected:
+
+ # If something is selected and we're not extending we want to deselect
+ if hasSelected and not extend:
+ return True
+
+ return False
+
+
+
+ # See if there is at least one selected item
+ def hasSelected(self, items):
+
+ for item in items:
+ if item.select:
+ return True
+
+ return False
+
+
+
+class Select_init(bpy.types.Operator):
+ '''Select all faces connected to the current selection'''
+ bl_idname = 'mesh.select_connected_faces'
+ bl_label = 'Select connected faces'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ # Iterations
+ iterations = IntProperty(name='Iterations', default=1, min=0, max=1000, soft_min=0, soft_max=100)
+
+ extend = BoolProperty(name='Extend', description='Extend the current selection', default=False)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and bpy.context.tool_settings.mesh_select_mode[0] == False and bpy.context.tool_settings.mesh_select_mode[1] == False and bpy.context.tool_settings.mesh_select_mode[2] == True)
+
+ def execute(self, context):
+ SELECT_CONNECTED = Select_connected_faces(context, self.iterations, self.extend)
+ return {'FINISHED'}
+
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_select_innermost.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_innermost.py
new file mode 100644
index 0000000..00f61fd
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_select_innermost.py
@@ -0,0 +1,139 @@
+# mesh_Select_innermost.py Copyright (C) 2011, Dolf Veenvliet
+#
+# Relaxes selected vertices while retaining the shape as much as possible
+#
+# ***** 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 *****
+'''
+bl_info = {
+ "name": "Select innermost",
+ "author": "Dolf Veenvliet",
+ "version": (0,3),
+ "blender": (2, 57, 0),
+ "api": 35851,
+ "location": "Select > Innermost",
+ "description": "Select the innermost faces",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+"""
+Usage:
+
+Launch from "Select -> Innermost"
+
+
+Additional links:
+ Author Site: http://www.macouno.com
+ e-mail: dolf {at} macouno {dot} com
+"""
+'''
+import bpy
+from bpy.props import BoolProperty
+from . import mesh_extras
+
+# Grow stuff!
+class Select_innermost():
+
+ # Initialise the class
+ def __init__(self, context, invert):
+
+ me = context.active_object.data
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ oList = [f.index for f in mesh_extras.get_selected_faces()]
+ oLen = len(oList)
+
+ # If no faces are selected, we just return
+ if not oLen:
+ bpy.ops.object.mode_set(mode='EDIT')
+ return
+
+ # If all faces are selected, select nothing and return
+ if oLen == len(me.polygons):
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='DESELECT')
+ return
+
+ fList = False
+
+ # If we invert, we just want to select less once, and then we're done
+ if invert:
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_less()
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ fList = [f.index for f in mesh_extras.get_selected_faces()]
+
+ # Only if there's now less selected do we change anything
+ if len(fList) < oLen:
+
+ for f in me.polygons:
+ fIn = f.index
+ if fIn in oList and not fIn in fList:
+ f.select = True
+ else:
+ f.select = False
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ return
+
+
+ # So now we can start and see what's up
+ while mesh_extras.contains_selected_item(me.polygons):
+
+ if fList is False:
+ fList = oList
+ else:
+ fList = [f.index for f in mesh_extras.get_selected_faces()]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_less()
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ if len(fList) < oLen:
+ for f in me.faces:
+ if f.index in fList:
+ f.select = True
+ else:
+ f.select = False
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+
+
+class Select_innermost_init(bpy.types.Operator):
+ '''Select the innermost faces of the current selection'''
+ bl_idname = 'mesh.select_innermost'
+ bl_label = 'Select innermost'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ invert = BoolProperty(name='Invert', description='Invert the selection result (select outermost)', default=False)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def execute(self, context):
+ innermost = Select_innermost(context, self.invert)
+ return {'FINISHED'}
+
diff --git a/release/scripts/addons_contrib/mesh_select_tools/mesh_selection_topokit.py b/release/scripts/addons_contrib/mesh_select_tools/mesh_selection_topokit.py
new file mode 100644
index 0000000..9ebc253
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_tools/mesh_selection_topokit.py
@@ -0,0 +1,567 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Topokit 2",
+ "author": "dustractor",
+ "version": (2, 0),
+ "blender": (2, 60, 0),
+ "api": 41935,
+ "location": "edit mesh vertices/edges/faces menus",
+ "description": "",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Mesh"}
+
+
+import bpy
+# In between calls, this stores any data that is expensive or static,
+# matched to the size of the mesh and the id of the operator that created it
+cachedata = dict()
+# and the object keeps the key to the cachedata
+bpy.types.Object.tkkey = bpy.props.IntVectorProperty(size=4)
+
+# just a mix-in for the operators...
+class meshpoller:
+ @classmethod
+ def poll(self,context):
+ try:
+ assert context.active_object.type == "MESH"
+ except:
+ return False
+ finally:
+ return True
+
+#BEGIN VERTICES SECTION
+
+# This one works similarly to normal 'grow' (ctrl + NUMPAD_PLUS),
+# except the original selection is not part of the result,
+#
+# 0--0--0 0--1--0
+# | | | | | |
+# 0--1--0 --> 1--0--1
+# | | | | | |
+# 0--0--0 0--1--0
+#
+class MESH_OT_vneighbors_edgewise(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.v2v_by_edge"
+ bl_label = "Neighbors by Edge"
+ bl_options = {"REGISTER","UNDO"}
+
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ next_state = bytearray(meshkey[0])
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ vert_to_vert_map,prev_state = cachedata[meshkey]
+ else:
+ vert_to_vert_map = {i:{} for i in range(meshkey[0])}
+ for a,b in mesh.edge_keys:
+ vert_to_vert_map[a][b] = 1
+ vert_to_vert_map[b][a] = 1
+ obj.tkkey = meshkey
+ prev_state = None
+ if not prev_state:
+ selected_vert_indices = filter(lambda _:mesh.vertices[_].select,range(len(mesh.vertices)))
+ else:
+ selected_vert_indices = filter(lambda _:mesh.vertices[_].select and not prev_state[_],range(len(mesh.vertices)))
+ for v in selected_vert_indices:
+ for neighbor_index in vert_to_vert_map[v]:
+ next_state[neighbor_index] = True
+ mesh.vertices.foreach_set("select",next_state)
+ cachedata[meshkey] = (vert_to_vert_map,next_state)
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+# This one is an alternate / counterpart to the previous.
+# Think: diagonal opposite corners of a quad
+# NOTE: does not apply to a triangle, since verts have no 'opposite'
+#
+# 0--0--0 1--0--1
+# | | | | | |
+# 0--1--0 --> 0--0--0
+# | | | | | |
+# 0--0--0 1--0--1
+#
+class MESH_OT_vneighbors_facewise(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.v2v_facewise"
+ bl_label = "Neighbors by Face - Edge"
+ bl_options = {"REGISTER","UNDO"}
+
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ next_state = bytearray(meshkey[0])
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ vert_to_vert_map = cachedata[meshkey]
+ else:
+ vert_to_vert_map = {i:{} for i in range(meshkey[0])}
+ for a,b in mesh.edge_keys:
+ vert_to_vert_map[a][b] = 1
+ vert_to_vert_map[b][a] = 1
+ obj.tkkey = meshkey
+ faces = filter(lambda face:(len(face.vertices)==4) and (face.select == False),mesh.polygons)
+ for f in faces:
+ has = False
+ t = set()
+ for v in f.vertices:
+ if mesh.vertices[v].select:
+ has = True
+ t.update(vert_to_vert_map[v])
+ if has:
+ for v in f.vertices:
+ if not mesh.vertices[v].select:
+ if v not in t:
+ next_state[v]=1
+ mesh.vertices.foreach_set("select",next_state)
+ cachedata[meshkey] = vert_to_vert_map
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+def vvmenuitem(self,context):
+ self.layout.operator(MESH_OT_vneighbors_edgewise.bl_idname)
+ self.layout.operator(MESH_OT_vneighbors_facewise.bl_idname)
+ #for the sake of completeness, yes there is one alg missing - one for both...
+
+#END VERTICES SECTION
+#BEGIN EDGES SECTION
+
+# +--0--+--0--+--0--+ +--0--+--0--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 1 1 0
+# | | | | | | | |
+# +--0--+--1--+--0--+ ---> +--0--+--0--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 1 1 0
+# | | | | | | | |
+# +--0--+--0--+--0--+ +--0--+--0--+--0--+
+class MESH_OT_eneighbors_shared_v_f(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.e2e_evfe"
+ bl_label = "Neighbors by Vert+Face"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ state_mask = bytearray(meshkey[1])
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_to_edges_dict = cachedata
+ else:
+ edge_key_to_index = {k:i for i,k in enumerate(mesh.edge_keys)}
+ edge_to_edges_dict = {i:set() for i in range(len(mesh.edges))}
+ for f in mesh.polygons:
+ fed=[edge_key_to_index[k] for k in f.edge_keys]
+ for k in f.edge_keys:
+ edge_to_edges_dict[edge_key_to_index[k]].update(fed)
+ obj.tkkey = meshkey
+ for e in filter(lambda _:mesh.edges[_].select,edge_to_edges_dict):
+ k1 = set(mesh.edges[e].key)
+ for n in edge_to_edges_dict[e]:
+ k2 = set(mesh.edges[n].key)
+ if not k1.isdisjoint(k2):
+ state_mask[n] = True
+ for e in mesh.edges:
+ e.select ^= state_mask[e.index]
+ cachedata[meshkey] = edge_key_to_index
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+# +--0--+--0--+--0--+ +--0--+--0--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 1 1 0
+# | | | | | | | |
+# +--0--+--1--+--0--+ ---> +--1--+--0--+--1--+
+# | | | | | | | |
+# 0 0 0 0 0 1 1 0
+# | | | | | | | |
+# +--0--+--0--+--0--+ +--0--+--0--+--0--+
+class MESH_OT_eneighbors_shared_v(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.e2e_eve"
+ bl_label = "Neighbors by Vert"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ bpy.ops.object.mode_set(mode="OBJECT")
+ mesh = context.active_object.data
+ state_mask = bytearray(len(mesh.edges))
+ for e in mesh.edges:
+ state_mask[e.index] = mesh.vertices[e.vertices[0]].select ^ mesh.vertices[e.vertices[1]].select
+ mesh.edges.foreach_set('select',state_mask)
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+# +--0--+--0--+--0--+ +--0--+--1--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 1 1 0
+# | | | | | | | |
+# +--0--+--1--+--0--+ ---> +--0--+--0--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 1 1 0
+# | | | | | | | |
+# +--0--+--0--+--0--+ +--0--+--1--+--0--+
+class MESH_OT_eneighbors_shared_f(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.e2e_efe"
+ bl_label = "Neighbors by Face"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_to_edges_dict = cachedata
+ else:
+ edge_key_to_index = {k:i for i,k in enumerate(mesh.edge_keys)}
+ edge_to_edges_dict = {i:set() for i in range(len(mesh.edges))}
+ for f in mesh.polygons:
+ fed=[edge_key_to_index[k] for k in f.edge_keys]
+ for k in f.edge_keys:
+ edge_to_edges_dict[edge_key_to_index[k]].update(fed)
+ obj.tkkey = meshkey
+ state_mask,esel = (bytearray(meshkey[1]),bytearray(meshkey[1]))
+ mesh.edges.foreach_get('select',esel)
+ for e in filter(lambda _:mesh.edges[_].select,range(meshkey[1])):
+ for n in edge_to_edges_dict[e]:
+ state_mask[n] = 1
+ for e in range(meshkey[1]):
+ esel[e] ^= state_mask[e]
+ mesh.edges.foreach_set('select',esel)
+ cachedata[meshkey] = edge_to_edges_dict
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+# notice that on these next two, the original selection stays
+# +--0--+--0--+--0--+ +--0--+--1--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 0 0 0
+# | | | | | | | |
+# +--0--+--1--+--0--+ ---> +--0--+--1--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 0 0 0
+# | | | | | | | |
+# +--0--+--0--+--0--+ +--0--+--1--+--0--+
+class MESH_OT_eneighbors_shared_f_notv(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.e2e_efnve"
+ bl_label = "Lateral Neighbors"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ state_mask = bytearray(meshkey[1])
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_to_face_map,edge_key_to_index = cachedata[meshkey]
+ else:
+ edge_key_to_index = {}
+ edge_to_face_map = {i:set() for i in range(meshkey[1])}
+ for i,k in enumerate(mesh.edge_keys):
+ edge_key_to_index[k] = i
+ for f in mesh.polygons:
+ for k in f.edge_keys:
+ edge_to_face_map[edge_key_to_index[k]].add(f.index)
+ obj.tkkey = meshkey
+ selected_edge_indices = filter(lambda _:mesh.edges[_].select,range(meshkey[1]))
+ for e in selected_edge_indices:
+ for f in edge_to_face_map[e]:
+ for k in mesh.polygons[f].edge_keys:
+ hasv_in = False
+ for v in mesh.edges[e].key:
+ if v in k:
+ hasv_in = True
+ if hasv_in:
+ continue
+ else:
+ state_mask[edge_key_to_index[k]] = True
+ for e in filter(lambda _:state_mask[_],range(meshkey[1])):
+ mesh.edges[e].select |= state_mask[e]
+ cachedata[meshkey] = (edge_to_face_map,edge_key_to_index)
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+
+# +--0--+--0--+--0--+ +--0--+--0--+--0--+
+# | | | | | | | |
+# 0 0 0 0 0 0 0 0
+# | | | | | | | |
+# +--0--+--1--+--0--+ ---> +--1--+--1--+--1--+
+# | | | | | | | |
+# 0 0 0 0 0 0 0 0
+# | | | | | | | |
+# +--0--+--0--+--0--+ +--0--+--0--+--0--+
+class MESH_OT_eneighbors_shared_v_notf(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.e2e_evnfe"
+ bl_label = "Longitudinal Edges"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ state_mask = bytearray(meshkey[1])
+ vstate = bytearray(meshkey[0])
+ mesh.vertices.foreach_get('select',vstate)
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_to_face_map,vert_to_vert_map,edge_key_to_index = cachedata[meshkey]
+ else:
+ edge_key_to_index = {}
+ vert_to_vert_map = {i:set() for i in range(meshkey[0])}
+ edge_to_face_map = {i:set() for i in range(meshkey[1])}
+ for i,k in enumerate(mesh.edge_keys):
+ edge_key_to_index[k] = i
+ vert_to_vert_map[k[0]].add(k[1])
+ vert_to_vert_map[k[1]].add(k[0])
+ for f in mesh.polygons:
+ for k in f.edge_keys:
+ edge_to_face_map[edge_key_to_index[k]].add(f.index)
+ obj.tkkey = meshkey
+ selected_edge_indices = filter(lambda _:mesh.edges[_].select,range(meshkey[1]))
+ for e in selected_edge_indices:
+ for v in mesh.edges[e].key:
+ state_mask[v] ^=1
+ for f in edge_to_face_map[e]:
+ for v in mesh.polygons[f].vertices:
+ vstate[v] = 1
+ for v in filter(lambda _:state_mask[_],range(meshkey[1])):
+ for n in vert_to_vert_map[v]:
+ if not vstate[n] and (n != v):
+ mesh.edges[edge_key_to_index[(min(v,n),max(v,n))]].select = True
+ cachedata[meshkey] = (edge_to_face_map,vert_to_vert_map,edge_key_to_index)
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+#deselects faces, leaving only edges selected
+class MESH_OT_just_the_edges(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.je"
+ bl_label = "Just the Edge Selection"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ state_mask = bytearray(meshkey[1])
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_key_to_index = cachedata[meshkey]
+ else:
+ edge_key_to_index = {k:i for i,k in enumerate(mesh.edge_keys)}
+ obj.tkkey = meshkey
+ for f in filter(lambda _:mesh.polygons[_].select,range(meshkey[2])):
+ for k in mesh.polygons[f].edge_keys:
+ state_mask[edge_key_to_index[k]] = 1
+ for e in range(meshkey[1]):
+ mesh.edges[e].select ^= state_mask[e]
+ cachedata[meshkey] = edge_key_to_index
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+# deselects edges which are at the edge of a face-selection,
+# causing selection to 'shrink in'
+class MESH_OT_inner_edges(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.ie"
+ bl_label = "Inner Edge Selection"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ state_mask = bytearray(meshkey[1])
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_to_face_map = cachedata[meshkey]
+ else:
+ edge_key_to_index = {k:i for i,k in enumerate(mesh.edge_keys)}
+ edge_to_face_map = {i:set() for i in range(meshkey[1])}
+ for f in mesh.polygons:
+ for k in f.edge_keys:
+ edge_to_face_map[edge_key_to_index[k]].add(f.index)
+ obj.tkkey = meshkey
+ for e in filter(lambda _:mesh.edges[_].select,range(meshkey[1])):
+ for f in edge_to_face_map[e]:
+ if mesh.polygons[f].select:
+ state_mask[e] ^=1
+ for e in range(meshkey[1]):
+ mesh.edges[e].select ^= state_mask[e]
+ cachedata[meshkey] = edge_to_face_map
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+def eemenuitem(self,context):
+ self.layout.operator(MESH_OT_eneighbors_shared_v_f.bl_idname)
+ self.layout.operator(MESH_OT_eneighbors_shared_v.bl_idname)
+ self.layout.operator(MESH_OT_eneighbors_shared_f.bl_idname)
+ self.layout.operator(MESH_OT_eneighbors_shared_f_notv.bl_idname)
+ self.layout.operator(MESH_OT_eneighbors_shared_v_notf.bl_idname)
+ self.layout.operator(MESH_OT_just_the_edges.bl_idname)
+ self.layout.operator(MESH_OT_inner_edges.bl_idname)
+
+#END EDGES SECTION
+#BEGIN FACES SECTION
+
+# here is another one which functions very similarly to the ctrl+NUMPAD_PLUS 'growth'
+# but it deselects the original selection, of course.
+# This would be your checkerboard-type growth.
+# [0][0][0] [0][1][0]
+# [0][1][0] ---> [1][0][1]
+# [0][0][0] [0][1][0]
+class MESH_OT_fneighbors_shared_e(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.f2f_fef"
+ bl_label = "Neighbors by Edge"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ face_to_face_map = cachedata[meshkey]
+ else:
+ edge_key_to_index = {k:i for i,k in enumerate(mesh.edge_keys)}
+ edge_to_face_map = {i:set() for i in range(meshkey[1])}
+ for f in mesh.polygons:
+ for k in f.edge_keys:
+ edge_to_face_map[edge_key_to_index[k]].add(f.index)
+ face_to_face_map = {i:set() for i in range(meshkey[2])}
+ for f in mesh.polygons:
+ for k in f.edge_keys:
+ face_to_face_map[f.index].update(edge_to_face_map[edge_key_to_index[k]])
+ obj.tkkey = meshkey
+ mask_state = bytearray(meshkey[2])
+ for f in filter(lambda _:mesh.polygons[_].select,range(meshkey[2])):
+ for n in face_to_face_map[f]:
+ mask_state[n] = True
+ for f in range(meshkey[2]):
+ mesh.polygons[f].select ^= mask_state[f]
+ cachedata[meshkey] = face_to_face_map
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+# [0][0][0] [1][0][1]
+# [0][1][0] ---> [0][0][0]
+# [0][0][0] [1][0][1]
+class MESH_OT_fneighbors_shared_v_note(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.f2f_fvnef"
+ bl_label = "Neighbors by Vert not Edge"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ edge_key_to_index = cachedata[meshkey]
+ else:
+ edge_key_to_index = {k:i for i,k in enumerate(mesh.edge_keys)}
+ obj.tkkey = meshkey
+ state_mask = bytearray(meshkey[2])
+ face_verts = set()
+ for f in filter(lambda _:mesh.polygons[_].select,range(meshkey[2])):
+ face_verts.update(mesh.polygons[f].vertices)
+ for f in filter(lambda _:not mesh.polygons[_].select,range(meshkey[2])):
+ ct = 0
+ for v in mesh.polygons[f].vertices:
+ ct += (v in face_verts)
+ if ct == 1:
+ state_mask[f] = 1
+ mesh.polygons.foreach_set('select',state_mask)
+ cachedata[meshkey] = edge_key_to_index
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+# http://en.wikipedia.org/wiki/Conway's_Game_of_Life
+class MESH_OT_conway(meshpoller,bpy.types.Operator):
+ bl_idname = "mesh.conway"
+ bl_label = "Conway"
+ bl_options = {"REGISTER","UNDO"}
+ def execute(self,context):
+ global cachedata
+ bpy.ops.object.mode_set(mode="OBJECT")
+ obj = context.active_object
+ mesh = obj.data
+ meshkey = (len(mesh.vertices),len(mesh.edges),len(mesh.polygons),id(self))
+ if (meshkey == obj.tkkey) and (meshkey in cachedata):
+ vert_to_face_map = cachedata[meshkey]
+ else:
+ vert_to_face_map = {i:set() for i in range(meshkey[0])}
+ for f in mesh.polygons:
+ for v in f.vertices:
+ vert_to_face_map[v].add(f.index)
+ obj.tkkey = meshkey
+ sel = set()
+ uns = set()
+ F = {i:set() for i in range(meshkey[2])}
+ for f in range(meshkey[2]):
+ for v in mesh.polygons[f].vertices:
+ for n in filter(lambda _: mesh.polygons[_].select and (_ != f),vert_to_face_map[v]):
+ F[f].add(n)
+ for f in F:
+ if len(F[f]) == 3:
+ sel.add(f)
+ elif len(F[f]) != 2:
+ uns.add(f)
+ for f in range(meshkey[2]):
+ if f in sel:
+ mesh.polygons[f].select = True
+ if f in uns:
+ mesh.polygons[f].select = False
+ cachedata[meshkey] = vert_to_face_map
+ bpy.ops.object.mode_set(mode="EDIT")
+ return {"FINISHED"}
+
+
+
+def ffmenuitem(self,context):
+ self.layout.operator(MESH_OT_fneighbors_shared_e.bl_idname)
+ self.layout.operator(MESH_OT_fneighbors_shared_v_note.bl_idname)
+ self.layout.operator(MESH_OT_conway.bl_idname)
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_vertices.append(vvmenuitem)
+ bpy.types.VIEW3D_MT_edit_mesh_edges.append(eemenuitem)
+ bpy.types.VIEW3D_MT_edit_mesh_faces.append(ffmenuitem)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_vertices.remove(vvmenuitem)
+ bpy.types.VIEW3D_MT_edit_mesh_edges.remove(eemenuitem)
+ bpy.types.VIEW3D_MT_edit_mesh_faces.remove(ffmenuitem)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_select_vertex_groups.py b/release/scripts/addons_contrib/mesh_select_vertex_groups.py
new file mode 100644
index 0000000..e4f6ee2
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_select_vertex_groups.py
@@ -0,0 +1,234 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Select Vertex Groups",
+ "author": "Martin Ellison",
+ "version": (1, 0),
+ "blender": (2, 59, 0),
+ "location": "Toolbox",
+ "description": "Finds all the vertex groups that chosen verts are in, & any verts that are not in any group",
+ "warning": "Buggy", # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Modeling/Select_Vertex_Groups",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=22025",
+ "category": "Mesh"}
+
+"""
+This script finds all the vertex groups that chosen vertexes are in, and any vertexes that are not in any vertex group.
+
+This is useful for cleaning up a mesh if vertex groups under animation go off to the wrong place (because they are in a vertex group that they should not be in, or not in the vertex group that they should be in).
+
+How to use:
+1. select a mesh and get into edit mode.
+2. by default it will use all vertexes; alternatively, select vertexes of interest and click on 'use selected vertexes'. Note that subsequent selections and deselections of vertexes will not change the set of vertexes to be used, you need to click on these buttons again to do that.
+3. click on 'select' and 'deselect' buttons for listed vertex groups, and for no vertex group, to select and deselect vertexes.
+
+This only lists vertex groups that have used vertexes.
+
+You may want to use the mesh select/deselect all (keyboard A) operator to start.
+
+Once you have the right vertexes selected, you can use the standard vertex groups property editor to add them to or remove them from the desired vertex groups.
+"""
+
+
+import bpy
+from bpy.props import *
+
+global use_selected_only, used_vertexes, the_mesh, vertex_usage
+use_selected_only = False
+used_vertexes = set()
+the_mesh = None
+vertex_usage = ''
+
+class UseAll(bpy.types.Operator):
+ bl_idname = "mesh.primitive_fvg_useall"
+ bl_label = "Use all Vertexes"
+ bl_register = True
+ bl_undo = True
+ #limit = FloatProperty(name="limit", description="Ignore weights under this limit.", default= 0.01, min = 0.0, max = 1.0, soft_min=0.0, soft_max=1.0)
+
+ def execute(self, context):
+ global use_selected_only
+ use_selected_only = False
+ bpy.ops.object.editmode_toggle()
+ set_used()
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+class UseSelected(bpy.types.Operator):
+ bl_idname = "mesh.primitive_fvg_useselected"
+ bl_label = "Use Selected Vertexes"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ global use_selected_only
+ use_selected_only = True
+ bpy.ops.object.editmode_toggle()
+ set_used()
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+class SelectFound(bpy.types.Operator):
+ bl_idname = "mesh.primitive_fvg_selfound"
+ bl_label = "Select"
+ bl_register = True
+ bl_undo = True
+ vertexgroup = bpy.props.StringProperty(name = 'vertexgroup', description = 'vertexgroup', default = '', options = set())
+
+ def execute(self, context):
+ global the_mesh
+ bpy.ops.object.editmode_toggle()
+ vertexgroup = self.properties.vertexgroup
+ fv = found_verts(vertexgroup)
+ for v in fv: v.select = True
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+class DeselectFound(bpy.types.Operator):
+ bl_idname = "mesh.primitive_fvg_deselfound"
+ bl_label = "Deselect"
+ bl_register = True
+ bl_undo = True
+ vertexgroup = bpy.props.StringProperty(name = 'vertexgroup', description = 'vertexgroup', default = '', options = set())
+
+ def execute(self, context):
+ global the_mesh
+ bpy.ops.object.editmode_toggle()
+ vertexgroup = self.properties.vertexgroup
+ fv = found_verts(vertexgroup)
+ for v in fv: v.select = False
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+def set_used():
+ global use_selected_only, used_vertexes, the_mesh, vertex_usage
+ obj = bpy.context.active_object
+ used_vertexes = set()
+ if use_selected_only:
+ for v in obj.data.vertices:
+ if v.select: used_vertexes.add(v.index)
+ else:
+ for v in obj.data.vertices: used_vertexes.add(v.index)
+ the_mesh = obj
+ vertex_usage = '%d vertexes used' % (len(used_vertexes))
+
+
+def make_groups(limit):
+ global used_vertexes
+ vgp = []
+ vgdict = {}
+ vgused = {}
+ obj = bpy.context.active_object
+ all_in_group = True
+ for vg in obj.vertex_groups:
+ vgdict[vg.index] = vg.name
+ for v in obj.data.vertices:
+ in_group = False
+ if v.index in used_vertexes:
+ for g in v.groups:
+ gr = g.group
+ w = g.weight
+ if w > limit:
+ if not gr in vgused: vgused[gr] = 0
+ vgused[gr] += 1
+ in_group = True
+ if not in_group: all_in_group = False
+ if not all_in_group:
+ vgp.append(("no group", "(No group)"))
+ for gn in vgused.keys():
+ name = vgdict[gn]
+ vgp.append((name, '%s has %d vertexes' % (name, vgused[gn]) ))
+ print("%d groups found\n" % len(vgp))
+ return vgp
+
+def found_verts(vertex_group):
+ global used_vertexes
+ vgfound = []
+ obj = bpy.context.active_object
+ if vertex_group == 'no group':
+ for v in obj.data.vertices:
+ if v.index in used_vertexes and (not v.groups):
+ vgfound.append(v)
+ else:
+ vgnum = obj.vertex_groups.find(vertex_group)
+ for v in obj.data.vertices:
+ if v.index in used_vertexes:
+ for g in v.groups:
+ if g.group == vgnum:
+ vgfound.append(v)
+ break
+
+ print('%d vertexes found for %s' % (len(vgfound), vertex_group))
+ return vgfound
+
+
+class VIEW3D_PT_FixVertexGroups(bpy.types.Panel):
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ bl_label = "Select Vertex Groups"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ if bpy.context.active_object:
+ obj = bpy.context.active_object
+ if obj.type == 'MESH' and obj.mode == 'EDIT': return True
+ return False
+
+ def draw(self, context):
+ global use_selected_only, used_vertexes, the_mesh, vertex_usage
+
+ if bpy.context.active_object:
+ obj = bpy.context.active_object
+ if obj.type == 'MESH' and obj.mode == 'EDIT':
+ layout = self.layout
+ use_all = layout.operator("mesh.primitive_fvg_useall", "Use all vertexes")
+ layout.operator("mesh.primitive_fvg_useselected", "Use selected vertexes")
+ if use_selected_only:
+ layout.label(text = 'Using selected vertexes.')
+ else:
+ layout.label(text = 'Using all vertexes.')
+ layout.label(vertex_usage)
+ if len(used_vertexes) == 0 or obj is not the_mesh: set_used()
+ #layout.prop(use_all, 'limit', slider = True)
+ #groups = make_groups(use_all.limitval)
+ groups = make_groups(0.01)
+ for gp in groups:
+ layout.label(text = gp[1])
+ row = layout.row()
+ sel_op = row.operator("mesh.primitive_fvg_selfound", "Select")
+ sel_op.vertexgroup = gp[0]
+ desel_op = row.operator("mesh.primitive_fvg_deselfound", "Deselect")
+ desel_op.vertexgroup = gp[0]
+
+classes = [UseAll, UseSelected, SelectFound, DeselectFound]
+
+def register():
+ bpy.utils.register_module(__name__)
+ pass
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ pass
+
+if __name__ == "__main__":
+ print('------ executing --------')
+ register()
diff --git a/release/scripts/addons_contrib/mesh_show_vgroup_weights.py b/release/scripts/addons_contrib/mesh_show_vgroup_weights.py
new file mode 100644
index 0000000..fe2ce03
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_show_vgroup_weights.py
@@ -0,0 +1,458 @@
+# ***** 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 *****
+
+# <pep8 compliant> (Thanks to CodemanX on IRC)
+
+bl_info = {
+ "name": "Show Vertex Groups/Weights",
+ "author": "Jason van Gumster (Fweeb), Bartius Crouch",
+ "version": (0, 7, 1),
+ "blender": (2, 62, 0),
+ "location": "3D View > Properties Region > Show Weights",
+ "description": "Finds the vertex groups of a selected vertex and displays the corresponding weights",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Modeling/Show_Vertex_Group_Weights",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=30609",
+ "category": "Mesh"}
+
+#TODO - Add button for selecting vertices with no groups
+
+
+import bpy, bmesh, bgl, blf, mathutils
+
+
+# Borrowed/Modified from Bart Crouch's old Index Visualizer add-on
+def calc_callback(self, context):
+ #polling
+ if context.mode != "EDIT_MESH" or len(context.active_object.vertex_groups) == 0:
+ return
+
+ # get color info from theme
+ acol = context.user_preferences.themes[0].view_3d.editmesh_active
+ tcol = (acol[0] * 0.85, acol[1] * 0.85, acol[2] * 0.85)
+
+ # get screen information
+ mid_x = context.region.width / 2.0
+ mid_y = context.region.height / 2.0
+ width = context.region.width
+ height = context.region.height
+
+ # get matrices
+ view_mat = context.space_data.region_3d.perspective_matrix
+ ob_mat = context.active_object.matrix_world
+ total_mat = view_mat * ob_mat
+
+ # calculate location info
+ texts = []
+ locs = []
+ weights = []
+ me = context.active_object.data
+ bm = bmesh.from_edit_mesh(me)
+ dvert_lay = bm.verts.layers.deform.active
+
+ for v in bm.verts:
+ if v.select: #XXX Should check v.hide here, but it doesn't work
+ if bm.select_mode == {'VERT'} and bm.select_history.active is not None and bm.select_history.active.index == v.index:
+ locs.append([acol[0], acol[1], acol[2], v.index, v.co.to_4d()])
+ else:
+ locs.append([tcol[0], tcol[1], tcol[2], v.index, v.co.to_4d()])
+ dvert = v[dvert_lay]
+ for vgroup in context.active_object.vertex_groups:
+ if vgroup.index in dvert.keys():
+ weights += [v.index, vgroup.index, dvert[vgroup.index]]
+
+ for loc in locs:
+ vec = total_mat * loc[4] # order is important
+ # dehomogenise
+ vec = mathutils.Vector((vec[0] / vec[3], vec[1] / vec[3], vec[2] / vec[3]))
+ x = int(mid_x + vec[0] * width / 2.0)
+ y = int(mid_y + vec[1] * height / 2.0)
+ texts += [loc[0], loc[1], loc[2], loc[3], x, y, 0]
+
+ # store as ID property in mesh
+ context.active_object.data["show_vgroup_verts"] = texts
+ context.active_object.data["show_vgroup_weights"] = weights
+
+
+# draw in 3d-view
+def draw_callback(self, context):
+ # polling
+ if context.mode != "EDIT_MESH" or len(context.active_object.vertex_groups) == 0:
+ return
+ # retrieving ID property data
+ try:
+ texts = context.active_object.data["show_vgroup_verts"]
+ weights = context.active_object.data["show_vgroup_weights"]
+ except:
+ return
+ if not texts:
+ return
+
+ bm = bmesh.from_edit_mesh(context.active_object.data)
+
+ if bm.select_mode == {'VERT'} and bm.select_history.active is not None:
+ active_vert = bm.select_history.active
+ else:
+ active_vert = None
+
+ # draw
+ blf.size(0, 13, 72)
+ blf.enable(0, blf.SHADOW)
+ blf.shadow(0, 3, 0.0, 0.0, 0.0, 1.0)
+ blf.shadow_offset(0, 2, -2)
+ for i in range(0, len(texts), 7):
+ bgl.glColor3f(texts[i], texts[i+1], texts[i+2])
+ blf.position(0, texts[i+4], texts[i+5], texts[i+6])
+ blf.draw(0, "Vertex " + str(int(texts[i+3])) + ":")
+ font_y = texts[i+5]
+ group_name = ""
+ for j in range(0, len(weights), 3):
+ if int(weights[j]) == int(texts[i+3]):
+ font_y -= 13
+ blf.position(0, texts[i+4] + 10, font_y, texts[i+6])
+ for group in context.active_object.vertex_groups:
+ if group.index == int(weights[j+1]):
+ group_name = group.name
+ break
+ blf.draw(0, group_name + ": %.3f" % weights[j+2])
+ if group_name == "":
+ font_y -= 13
+ blf.position(0, texts[i+4] + 10, font_y, texts[i+6])
+ blf.draw(0, "No Groups")
+
+ # restore defaults
+ blf.disable(0, blf.SHADOW)
+
+
+# operator
+class ShowVGroupWeights(bpy.types.Operator):
+ bl_idname = "view3d.show_vgroup_weights"
+ bl_label = "Show Vertex Group Weights"
+ bl_description = "Toggle the display of the vertex groups and weights for selected vertices"
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == 'EDIT_MESH'
+
+ def __del__(self):
+ bpy.context.scene.display_indices = -1
+ clear_properties(full=False)
+
+ def modal(self, context, event):
+ if context.area:
+ context.area.tag_redraw()
+
+ # removal of callbacks when operator is called again
+ if context.scene.display_indices == -1:
+ context.region.callback_remove(self.handle1)
+ context.region.callback_remove(self.handle2)
+ context.scene.display_indices = 0
+ return {'CANCELLED'}
+
+ return {'PASS_THROUGH'}
+
+ def invoke(self, context, event):
+ if context.area.type == 'VIEW_3D':
+ if context.scene.display_indices < 1:
+ # operator is called for the first time, start everything
+ context.scene.display_indices = 1
+ self.handle1 = context.region.callback_add(calc_callback,
+ (self, context), 'POST_VIEW')
+ self.handle2 = context.region.callback_add(draw_callback,
+ (self, context), 'POST_PIXEL')
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ # operator is called again, stop displaying
+ context.scene.display_indices = -1
+ clear_properties(full=False)
+ return {'RUNNING_MODAL'}
+ else:
+ self.report({'WARNING'}, "View3D not found, can't run operator")
+ return {'CANCELLED'}
+
+
+# removal of ID-properties when script is disabled
+def clear_properties(full=True):
+ # can happen on reload
+ if bpy.context.scene is None:
+ return
+
+ if "show_vgroup_verts" in bpy.context.active_object.data.keys():
+ del bpy.context.active_object.data["show_vgroup_verts"]
+ if "show_vgroup_weights" in bpy.context.active_object.data.keys():
+ del bpy.context.active_object.data["show_vgroup_weights"]
+ if full:
+ props = ["display_indices"]
+ for p in props:
+ if p in bpy.types.Scene.bl_rna.properties:
+ exec("del bpy.types.Scene." + p)
+ if p in bpy.context.scene.keys():
+ del bpy.context.scene[p]
+
+
+class AssignVertexWeight(bpy.types.Operator):
+ bl_idname = "mesh.vertex_group_assign"
+ bl_label = "Assign Weights"
+ bl_description = "Assign weights for all of the groups on a specific vertex"
+
+ vgroup_weights = bpy.props.StringProperty(name = "Vertex Group Weights")
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == 'EDIT_MESH'
+
+ def execute(self, context):
+ me = context.active_object.data
+ bm = bmesh.from_edit_mesh(me)
+ dvert_lay = bm.verts.layers.deform.active
+ weights = eval(self.vgroup_weights) #XXX Would be nice if I didn't have to use an eval
+
+ for v in bm.verts:
+ if v.index == weights["__index__"]:
+ del weights["__index__"]
+ dvert = v[dvert_lay]
+ for vgroup in dvert.keys():
+ dvert[vgroup] = weights[vgroup]
+ break
+
+ return {'FINISHED'}
+
+
+class RemoveFromVertexGroup(bpy.types.Operator):
+ bl_idname = "mesh.vertex_group_remove"
+ bl_label = "Remove Vertex from Group"
+ bl_description = "Remove a specific vertex from a specific vertex group"
+
+ #XXX abusing vector props here a bit; the first element is the vert index and the second is the group index
+ vert_and_group = bpy.props.IntVectorProperty(name = "Vertex and Group to remove", size = 2)
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == 'EDIT_MESH'
+
+ def execute(self, context):
+ ob = context.active_object
+ me = ob.data
+ bm = bmesh.from_edit_mesh(me)
+
+ # Save current selection
+ selected_verts = []
+ for v in bm.verts:
+ if v.select is True:
+ selected_verts.append(v.index)
+ if v.index != self.vert_and_group[0]:
+ v.select = False
+
+ ob.vertex_groups.active_index = self.vert_and_group[1]
+ bpy.ops.object.vertex_group_remove_from()
+
+ # Re-select vertices
+ for v in bm.verts:
+ if v.index in selected_verts:
+ v.select = True
+
+ #XXX Hacky, but there's no other way to update the UI panels
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+class AddToVertexGroup(bpy.types.Operator):
+ bl_idname = "mesh.vertex_group_add"
+ bl_label = "Add Vertex to Group"
+ bl_description = "Add a specific vertex to a specific vertex group"
+
+ def avail_vgroups(self, context):
+ ob = context.active_object
+ bm = bmesh.from_edit_mesh(ob.data)
+ dvert_lay = bm.verts.layers.deform.active
+ items = []
+ self.vertex = bm.select_history.active.index
+
+ dvert = bm.select_history.active[dvert_lay]
+
+ items.append(("-1", "New Vertex Group", "-1", -1))
+
+ for i in ob.vertex_groups:
+ if i.index not in dvert.keys():
+ items.append((i.name, i.name, str(i.index), i.index))
+
+ return items
+
+ vertex = bpy.props.IntProperty()
+ available_vgroups = bpy.props.EnumProperty(items = avail_vgroups, name = "Available Groups")
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == 'EDIT_MESH'
+
+ def execute(self, context):
+ ob = context.active_object
+ me = ob.data
+ bm = bmesh.from_edit_mesh(me)
+ #print(self.available_vgroups)
+
+ # Save current selection
+ selected_verts = []
+ for v in bm.verts:
+ if v.select is True:
+ selected_verts.append(v.index)
+ if v.index != self.vertex:
+ v.select = False
+
+ weight = context.tool_settings.vertex_group_weight
+ context.tool_settings.vertex_group_weight = 1.0
+ if self.available_vgroups == "-1":
+ bpy.ops.object.vertex_group_assign(new = True) #XXX Assumes self.vertex is the active vertex
+ else:
+ bpy.ops.object.vertex_group_set_active(group = self.available_vgroups)
+ bpy.ops.object.vertex_group_assign() #XXX Assumes self.vertex is the active vertex
+ context.tool_settings.vertex_group_weight = weight
+
+ # Re-select vertices
+ for v in bm.verts:
+ if v.index in selected_verts:
+ v.select = True
+
+ #XXX Hacky, but there's no other way to update the UI panels
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.editmode_toggle()
+ return {'FINISHED'}
+
+
+class PanelShowWeights(bpy.types.Panel):
+ bl_label = "Show Weights"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "UI"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == 'EDIT_MESH'
+
+ def draw(self, context):
+ layout = self.layout
+ ob = context.active_object
+ me = ob.data
+ bm = bmesh.from_edit_mesh(me)
+ dvert_lay = bm.verts.layers.deform.active
+
+ if context.scene.display_indices < 1:
+ layout.operator(ShowVGroupWeights.bl_idname, text = "Show Weights Overlay")
+ else:
+ layout.operator(ShowVGroupWeights.bl_idname, text = "Hide Weights Overlay")
+
+ if len(ob.vertex_groups) > 0:
+ # Active vertex
+ active_vert = bm.select_history.active
+ sub = layout.box()
+ col = sub.column(align = True)
+ if bm.select_mode == {'VERT'} and active_vert is not None:
+ col.label(text = "Active Vertex")
+ row = col.row()
+ row.label(text = "Vertex " + str(active_vert.index) + ":")
+ row.operator_menu_enum("mesh.vertex_group_add", "available_vgroups", text = "Add Group", icon = 'GROUP_VERTEX')
+ has_groups = False
+ vgroup_weights = {}
+
+ for i in me.vertices:
+ if i.index == active_vert.index:
+ vgroup_weights["__index__"] = i.index
+ for j in range(len(i.groups)):
+ for k in ob.vertex_groups:
+ if k.index == i.groups[j].group:
+ has_groups = True
+ split = col.split(percentage = 0.90, align = True)
+ vgroup_weights[k.index] = i.groups[j].weight
+ row = split.row(align = True)
+ row.prop(i.groups[j], "weight", text = k.name, slider = True, emboss = not k.lock_weight)
+ row = split.row(align = True)
+ row.operator("mesh.vertex_group_remove", text = "R").vert_and_group = (i.index, k.index)
+
+ if not has_groups:
+ col.label(text = " No Groups")
+ else:
+ col.operator("mesh.vertex_group_assign").vgroup_weights = str(vgroup_weights)
+ layout.separator()
+ else:
+ col.label(text = "No Active Vertex")
+ layout.prop(context.window_manager, "show_vgroups_show_all", toggle = True)
+ # All selected vertices (except for the active vertex)
+ if context.window_manager.show_vgroups_show_all:
+ for v in bm.verts:
+ if v.select:
+ if active_vert is not None and v.index == active_vert.index:
+ continue
+ sub = layout.box()
+ col = sub.column(align = True)
+ col.label(text = "Vertex " + str(v.index) + ":")
+ has_groups = False
+ vgroup_weights = {}
+ for i in me.vertices:
+ if i.index == v.index:
+ vgroup_weights["__index__"] = i.index
+ for j in range(len(i.groups)):
+ for k in ob.vertex_groups:
+ if k.index == i.groups[j].group:
+ has_groups = True
+ split = col.split(percentage = 0.90, align = True)
+ vgroup_weights[k.index] = i.groups[j].weight
+ row = split.row(align = True)
+ row.prop(i.groups[j], "weight", text = k.name, slider = True, emboss = not k.lock_weight)
+ row = split.row(align = True)
+ row.operator("mesh.vertex_group_remove", text = "R").vert_and_group = (i.index, k.index)
+ if not has_groups:
+ col.label(text = " No Groups")
+ else:
+ col.operator("mesh.vertex_group_assign").vgroup_weights = str(vgroup_weights)
+ else:
+ layout.label(text = "No Groups")
+
+
+def register():
+ bpy.types.WindowManager.show_vgroups_show_all = bpy.props.BoolProperty(
+ name = "Show All Selected Vertices",
+ description = "Show all vertices with vertex groups assigned to them",
+ default = False)
+ bpy.types.Mesh.assign_vgroup = bpy.props.StringProperty()
+ bpy.utils.register_class(ShowVGroupWeights)
+ bpy.types.Scene.display_indices = bpy.props.IntProperty(
+ name="Display indices",
+ default=0)
+ bpy.utils.register_class(AssignVertexWeight)
+ bpy.utils.register_class(RemoveFromVertexGroup)
+ bpy.utils.register_class(AddToVertexGroup)
+ bpy.utils.register_class(PanelShowWeights)
+
+
+def unregister():
+ bpy.utils.unregister_class(ShowVGroupWeights)
+ clear_properties()
+ bpy.utils.unregister_class(AssignVertexWeight)
+ bpy.utils.unregister_class(RemoveFromVertexGroup)
+ bpy.utils.unregister_class(AddToVertexGroup)
+ bpy.utils.unregister_class(PanelShowWeights)
+ del bpy.types.WindowManager.show_vgroups_show_all
+ del bpy.types.Mesh.assign_vgroup
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/mesh_vertex_slide.py b/release/scripts/addons_contrib/mesh_vertex_slide.py
new file mode 100644
index 0000000..5fc14a0
--- /dev/null
+++ b/release/scripts/addons_contrib/mesh_vertex_slide.py
@@ -0,0 +1,473 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Vertex slide for Bmesh",
+ "author": "Valter Battioli (ValterVB) and PKHG",
+ "version": (2, 0, 0),
+ "blender": (2, 62, 0),
+ "location": "View3D > Mesh > Vertices (CTRL V-key)",
+ "description": "Slide a vertex along an edge or a line",
+ "warning": "Work only with Blender 2.62 or higher",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Modeling/Vertex_Slide2",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27561",
+ "category": "Mesh"}
+
+#***********************************************************************
+#ver. 1.0.0: -First version
+#ver. 1.0.1: -Now the mouse wheel select in continuos mode the next vertex
+# -Add a marker for the vertex to move
+#ver. 1.0.2: -Add check for vertices not selected
+# -Some cleanup
+#ver. 1.0.3: -Now the movement is proportional to the mouse movement
+# 1/10 of the distance between 2 points for every pixel
+# mouse movement (1/100 with SHIFT)
+#ver. 1.0.4: all coordinate as far as possible replaced by vectors
+# view3d_utils are used to define length of an edge on screen!
+# partial simplified logic by PKHG
+#ver. 1.0.6: Restore continuous slide, code cleanup
+# Correct the crash with not linked vertex
+#ver. 1.0.7: Restore shift, and some code cleanup
+#ver. 1.0.8: Restore 2 type of sliding with 2 vertex selected
+#ver. 1.0.9: Fix for reverse vector multiplication
+#ver. 1.1.0: Delete debug info, some cleanup and add some comments
+#ver. 1.1.1: Now UNDO work properly
+#ver. 1.1.2: Refactory and some clean of the code.
+# Add edge drawing (from chromoly vertex slide)
+# Add help on screen (from chromooly vertex slide)
+#ver. 1.1.3: Now work also with Continuos Grab, some clean on code
+#ver. 1.1.4: Remove a lot of mode switching in Invoke. It was too slow
+# with big mesh.
+#ver. 1.1.5: Changed Lay out of the Help and the Key for reverse the
+# movement. Left/Right arrow rather than Pus/Minus numpad
+#ver. 1.1.6: Now the vertex movement is always coherent with Mouse movement
+#ver. 2.0.0: Update to Bmesh and remove all mode switching
+#ver. 2.0.1: Replaced Conv3DtoScreen2D function with location_3d_to_region_2d
+#ver. 2.0.2: Fix crash if there are some duplicate vertices
+#***********************************************************************
+
+import bpy
+import bmesh
+import bgl
+import blf
+from mathutils import Vector
+from bpy_extras.view3d_utils import location_3d_to_region_2d as loc3d2d
+
+# Equation of the line
+# Changing t we have a new point coordinate on the line along v0 v1
+# With t from 0 to 1 I move from v0 to v1
+def NewCoordinate(v0, v1, t):
+ return v0 + t * (v1 - v0)
+
+# This class store Vertex data
+class Point():
+ def __init__(self):
+ self.original = self.Vertex() # Original position
+ self.new = self.Vertex() # New position
+ self.t = 0 # Used for move the vertex
+ self.x2D = 0 # Screen 2D cooord of the point
+ self.y2D = 0 # Screen 2D cooord of the point
+ self.selected = False
+
+ class Vertex():
+ def __init__(self):
+ self.co = None
+ self.idx = None
+
+class BVertexSlideOperator(bpy.types.Operator):
+ bl_idname = "vertex.slide"
+ bl_label = "Vertex Slide"
+ bl_options = {'REGISTER', 'UNDO', 'GRAB_POINTER', 'BLOCKING', 'INTERNAL'}
+
+ Vertex1 = Point() # First selected vertex data
+ LinkedVertices1 = [] # List of index of linked verts of Vertex1
+ Vertex2 = Point() # Second selected vertex data
+ LinkedVertices2 = [] # List of index of linked verts of Vertex2
+ ActiveVertex = None # Index of vertex to be moved
+ tmpMouse_x = 0
+ tmpMouse = Vector((0, 0))
+ Direction = 1.0 # Used for direction and precision of the movement
+ FirstVertexMove = True # If true move the first vertex
+ VertLinkedIdx = 0 # Index of LinkedVertices1. Used only for 1 vertex select case
+ LeftAltPress = False # Flag to know if ALT is hold on
+ LeftShiftPress = False # Flag to know if SHIFT is hold on
+ obj = None # Object
+ mesh = None # Mesh
+ bm = None # BMesh
+
+ # OpenGL Function to draw on the screen help and pointer *
+ def draw_callback_px(self, context):
+ x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[self.ActiveVertex].co)
+
+ # Draw an * at the active vertex
+ blf.position(0, x, y, 0)
+ blf.size(0, 26, 72)
+ blf.draw(0, "*")
+
+ #Draw Help
+ yPos=30
+ blf.size(0, 11, context.user_preferences.system.dpi)
+ txtHelp1 = "{SHIFT}:Precision"
+ txtHelp2 = "{WHEEL}:Change the vertex/edge"
+ txtHelp3 = "{ALT}:Continuos slide"
+ txtHelp4 = "{LEFT ARROW}:Reverse the movement"
+ txtHelp5 = "{RIGHT ARROW}:Restore the movement"
+ blf.position(0, 70, yPos, 0)
+ blf.draw(0, txtHelp5)
+ yPos += (int(blf.dimensions(0, txtHelp4)[1]*2))
+ blf.position(0 , 70, yPos, 0)
+ blf.draw(0, txtHelp4)
+ yPos += (int(blf.dimensions(0, txtHelp3)[1]*2))
+ blf.position(0 , 70, yPos, 0)
+ blf.draw(0, txtHelp3)
+ yPos += (int(blf.dimensions(0, txtHelp2)[1]*2))
+ blf.position(0 , 70, yPos, 0)
+ blf.draw(0, txtHelp2)
+ yPos += (int(blf.dimensions(0, txtHelp1)[1]*2))
+ blf.position(0 , 70, yPos, 0)
+ blf.draw(0, txtHelp1)
+
+ # Draw edge
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glColor4f(1.0, 0.1, 0.8, 1.0)
+ bgl.glBegin(bgl.GL_LINES)
+ for p in self.LinkedVertices1:
+ bgl.glVertex2f(self.Vertex1.x2D, self.Vertex1.y2D)
+ bgl.glVertex2f(p.x2D, p.y2D)
+ for p in self.LinkedVertices2:
+ bgl.glVertex2f(self.Vertex2.x2D, self.Vertex2.y2D)
+ bgl.glVertex2f(p.x2D, p.y2D)
+ bgl.glEnd()
+
+ # Compute the screen distance of two vertices
+ def ScreenDistance(self, vertex_zero_co, vertex_one_co):
+ matw = bpy.context.active_object.matrix_world
+ V0 = matw * vertex_zero_co
+ res0 = loc3d2d(bpy.context.region, bpy.context.space_data.region_3d, V0)
+ V1 = matw * vertex_one_co
+ res1 = loc3d2d(bpy.context.region, bpy.context.space_data.region_3d, V1)
+ result = (res0 - res1).length
+ return result
+
+ def modal(self, context, event):
+ if event.type == 'MOUSEMOVE':
+ Vertices = self.bm.verts
+ # Calculate the temp t value. Stored in td
+ tmpMouse = Vector((event.mouse_x, event.mouse_y))
+ t_diff = (tmpMouse - self.tmpMouse).length
+ self.tmpMouse = tmpMouse
+ if self.Vertex2.original.idx is not None: # 2 vertex selected
+ td = t_diff * self.Direction / self.ScreenDistance(self.Vertex1.original.co,
+ self.Vertex2.original.co)
+ else: # 1 vertex selected
+ td = t_diff * self.Direction / self.ScreenDistance(self.Vertex1.original.co,
+ self.LinkedVertices1[self.VertLinkedIdx].original.co)
+ if event.mouse_x < self.tmpMouse_x:
+ td = -td
+
+ if self.Vertex2.original.idx is not None: # 2 vertex selected
+ # Calculate the t valuse
+ if self.FirstVertexMove:
+ self.Vertex1.t = self.Vertex1.t + td
+ else:
+ self.Vertex2.t = self.Vertex2.t + td
+ # Move the vertex
+ Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex1.original.co,
+ self.Vertex2.original.co,
+ self.Vertex1.t)
+ Vertices[self.Vertex2.original.idx].co = NewCoordinate(self.Vertex2.original.co,
+ self.Vertex1.original.co,
+ self.Vertex2.t)
+ else: # 1 vertex selected
+ if self.LeftAltPress: # Continuous slide
+ # Calculate the t valuse
+ self.Vertex2.t = self.Vertex2.t + td
+ # Move the vertex
+ Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex2.original.co,
+ self.LinkedVertices1[self.VertLinkedIdx].original.co,
+ self.Vertex2.t)
+ else:
+ # Calculate the t valuse
+ self.LinkedVertices1[self.VertLinkedIdx].t = self.LinkedVertices1[self.VertLinkedIdx].t + td
+ # Move the vertex
+ Vertices[self.Vertex1.original.idx].co = NewCoordinate(self.Vertex1.original.co,
+ self.LinkedVertices1[self.VertLinkedIdx].original.co,
+ self.LinkedVertices1[self.VertLinkedIdx].t)
+ self.ActiveVertex = self.Vertex1.original.idx
+ self.tmpMouse_x = event.mouse_x
+ context.area.tag_redraw()
+
+ elif event.type == 'LEFT_SHIFT': # Hold left SHIFT for precision
+ self.LeftShiftPress = not self.LeftShiftPress
+ if self.LeftShiftPress:
+ self.Direction *= 0.1
+ else:
+ if self.Direction < 0:
+ self.Direction = -1
+ else:
+ self.Direction = 1
+
+ elif event.type == 'LEFT_ALT': # Hold ALT to use continuous slide
+ self.LeftAltPress = not self.LeftAltPress
+ if self.LeftAltPress and self.Vertex2.original.idx is None:
+ vert = self.bm.verts[self.Vertex1.original.idx]
+ self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z))
+ self.Vertex2.t = 0
+
+ elif event.type == 'LEFT_ARROW': # Reverse direction
+ if self.Direction < 0.0:
+ self.Direction = - self.Direction
+
+ elif event.type == 'RIGHT_ARROW': # Restore direction
+ if self.Direction > 0.0:
+ self.Direction = - self.Direction
+
+ elif event.type == 'WHEELDOWNMOUSE': # Change the vertex to be moved
+ if self.Vertex2.original.idx is None:
+ if self.LeftAltPress:
+ vert=self.bm.verts[self.Vertex1.original.idx]
+ self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z))
+ self.Vertex2.t = 0
+ self.VertLinkedIdx = self.VertLinkedIdx + 1
+ if self.VertLinkedIdx > len(self.LinkedVertices1) - 1:
+ self.VertLinkedIdx = 0
+ bpy.ops.mesh.select_all(action='DESELECT')
+ self.bm.verts[self.Vertex1.original.idx].select = True
+ self.bm.verts[self.LinkedVertices1[self.VertLinkedIdx].original.idx].select = True
+ else:
+ self.FirstVertexMove = not self.FirstVertexMove
+ if self.LeftAltPress == False:
+ self.Vertex1.t = 0
+ self.Vertex2.t = 0
+ if self.FirstVertexMove:
+ self.ActiveVertex = self.Vertex1.original.idx
+ else:
+ self.ActiveVertex = self.Vertex2.original.idx
+ # Keep Vertex movement coherent with Mouse movement
+ if self.Vertex2.original.idx is not None:
+ if self.FirstVertexMove:
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
+ if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction >= 0)):
+ self.Direction = -self.Direction
+ else:
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ if (tmpX1 < tmpX2 and self.Direction < 0) or (tmpX2 < tmpX1 and self.Direction >= 0):
+ self.Direction = -self.Direction
+ else:
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[self.VertLinkedIdx].original.co)
+ if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction < 0)):
+ self.Direction = -self.Direction
+ context.area.tag_redraw()
+
+ elif event.type == 'WHEELUPMOUSE': # Change the vertex to be moved
+ if self.Vertex2.original.idx is None:
+ if self.LeftAltPress:
+ vert = self.bm.verts[self.Vertex1.original.idx]
+ self.Vertex2.original.co = Vector((vert.co.x, vert.co.y, vert.co.z))
+ self.Vertex2.t = 0
+ self.VertLinkedIdx = self.VertLinkedIdx - 1
+ if self.VertLinkedIdx < 0:
+ self.VertLinkedIdx = len(self.LinkedVertices1) - 1
+ bpy.ops.mesh.select_all(action='DESELECT')
+ self.bm.verts[self.Vertex1.original.idx].select = True
+ self.bm.verts[self.LinkedVertices1[self.VertLinkedIdx].original.idx].select = True
+ else:
+ self.FirstVertexMove = not self.FirstVertexMove
+ if self.LeftAltPress == False:
+ self.Vertex1.t = 0
+ self.Vertex2.t = 0
+ if self.FirstVertexMove:
+ self.ActiveVertex = self.Vertex1.original.idx
+ else:
+ self.ActiveVertex = self.Vertex2.original.idx
+ # Keep Vertex movement coherent with Mouse movement
+ if self.Vertex2.original.idx is not None:
+ if self.FirstVertexMove:
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
+ if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction >= 0)):
+ self.Direction = -self.Direction
+ else:
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ if (tmpX1 < tmpX2 and self.Direction < 0) or (tmpX2 < tmpX1 and self.Direction >= 0):
+ self.Direction = -self.Direction
+ else:
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[self.VertLinkedIdx].original.co)
+ if ((tmpX1 > tmpX2 and self.Direction >= 0) or (tmpX2 > tmpX1 and self.Direction < 0)):
+ self.Direction = -self.Direction
+ context.area.tag_redraw()
+
+ elif event.type == 'LEFTMOUSE': # Confirm and exit
+ Vertices = self.bm.verts
+ bpy.ops.mesh.select_all(action='DESELECT')
+ Vertices[self.Vertex1.original.idx].select = True
+ if self.Vertex2.original.idx is not None:
+ Vertices[self.Vertex2.original.idx].select = True
+ context.region.callback_remove(self._handle)
+ context.area.tag_redraw()
+ return {'FINISHED'}
+
+ elif event.type in {'RIGHTMOUSE', 'ESC'}: # Restore and exit
+ Vertices = self.bm.verts
+ bpy.ops.mesh.select_all(action='DESELECT')
+ Vertices[self.Vertex1.original.idx].co = self.Vertex1.original.co
+ Vertices[self.Vertex1.original.idx].select = True
+ if self.Vertex2.original.idx is not None:
+ Vertices[self.Vertex2.original.idx].co = self.Vertex2.original.co
+ Vertices[self.Vertex2.original.idx].select = True
+ context.region.callback_remove(self._handle)
+ context.area.tag_redraw()
+ return {'CANCELLED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ if context.active_object == None or context.active_object.type != "MESH":
+ self.report({'WARNING'}, "Not any active object or not an mesh object:")
+ return {'CANCELLED'}
+
+ if context.active_object.mode != 'EDIT':
+ self.report({'WARNING'}, "Mesh isn't in Edit Mode")
+ return {'CANCELLED'}
+
+ self.obj = bpy.context.object
+ self.mesh = self.obj.data
+ self.bm = bmesh.from_edit_mesh(self.mesh)
+
+ Count=0
+ Selected=False
+ SelectedVertices = [] # Index of selected vertices
+ for i, v in enumerate(self.bm.verts):
+ if v.select and v.is_valid:
+ SelectedVertices.append(v.index)
+ Selected = True
+ Count += 1
+ if (Count > 2): # More than 2 vertices selected
+ Selected = False
+ break
+
+ if Selected == False:
+ self.report({'WARNING'}, "0 or more then 2 vertices selected, could not start")
+ return {'CANCELLED'}
+
+ self.tmpMouse[0], self.tmpMouse[1] = (event.mouse_x, event.mouse_y)
+ self.tmpMouse_x = self.tmpMouse[0]
+
+ self.Vertex1 = Point()
+ self.Vertex2 = Point()
+ self.LinkedVertices1 = []
+ self.LinkedVertices2 = []
+
+ # Store selected vertices data. To move in the first Loop
+ self.Vertex1.original.idx = SelectedVertices[0]
+ self.Vertex1.original.co = self.bm.verts[SelectedVertices[0]].co.copy()
+ self.Vertex1.new = self.Vertex1.original
+ x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[SelectedVertices[0]].co) # For draw edge
+ self.Vertex1.x2D = x
+ self.Vertex1.y2D = y
+ if len(SelectedVertices) == 2:
+ self.Vertex2.original.idx = SelectedVertices[1]
+ self.Vertex2.original.co = self.bm.verts[SelectedVertices[1]].co.copy()
+ self.Vertex2.new = self.Vertex2.original
+ x, y = loc3d2d(context.region, context.space_data.region_3d, self.bm.verts[SelectedVertices[1]].co) # For draw edge
+ self.Vertex2.x2D = x
+ self.Vertex2.y2D = y
+
+ if len(SelectedVertices) == 2:
+ self.bm.verts[self.Vertex2.original.idx].select = False # Unselect the second selected vertex
+
+ # Store linked vertices data, except the selected vertices
+ for i, vert in enumerate(self.bm.verts[self.Vertex1.original.idx].link_edges):
+ self.LinkedVertices1.append(Point())
+ self.LinkedVertices1[-1].original.idx = vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).index #e_0.other_vert(v_0).index
+ self.LinkedVertices1[-1].original.co = vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).co.copy()
+ self.LinkedVertices1[-1].new = self.LinkedVertices1[-1].original
+ x, y = loc3d2d(context.region, context.space_data.region_3d, vert.other_vert(self.bm.verts[self.Vertex1.original.idx]).co) # For draw edge
+ self.LinkedVertices1[-1].x2D = x
+ self.LinkedVertices1[-1].y2D = y
+ if len(SelectedVertices) == 2:
+ for i, vert in enumerate(self.bm.verts[self.Vertex2.original.idx].link_edges):
+ self.LinkedVertices2.append(Point())
+ self.LinkedVertices2[-1].original.idx = vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).index
+ self.LinkedVertices2[-1].original.co = vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).co.copy()
+ self.LinkedVertices2[-1].new = self.LinkedVertices1[-1].original
+ x, y = loc3d2d(context.region, context.space_data.region_3d, vert.other_vert(self.bm.verts[self.Vertex2.original.idx]).co) # For draw edge
+ self.LinkedVertices2[-1].x2D = x
+ self.LinkedVertices2[-1].y2D = y
+
+ # Check for no linked vertex. Can be happen also with a mix of Select Mode
+ # Need only with 1 vertex selected
+ if len(SelectedVertices) == 1 and len(self.LinkedVertices1) == 0:
+ self.report({'WARNING'}, "Isolated vertex or mixed Select Mode!")
+ return {'CANCELLED'}
+ # Check for duplicate vertices. If some linked vertice have the same coords of selected vertice
+ # we have the error "division by 0
+ if self.Vertex1.original.co == self.Vertex2.original.co:
+ self.report({'WARNING'}, "At least one duplicate vertex")
+ return {'CANCELLED'}
+
+ self.bm.verts[self.Vertex1.original.idx].select = True # Select the first selected vertex
+ if len(SelectedVertices) == 2:
+ self.bm.verts[self.Vertex2.original.idx].select = True # Select the second selected vertex
+ else:
+ self.bm.verts[self.LinkedVertices1[0].original.idx].select = True # Select the first linked vertex
+ self.ActiveVertex = self.Vertex1.original.idx
+
+ # Keep Vertex movement coherent with Mouse movement
+ tmpX1, tmpY1 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex1.original.co)
+ if len(SelectedVertices) == 2:
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.Vertex2.original.co)
+ else:
+ tmpX2, tmpY2 = loc3d2d(context.region, context.space_data.region_3d, self.LinkedVertices1[0].original.co)
+ if tmpX2 - tmpX1 < 0:
+ self.Direction = -self.Direction
+
+ context.area.tag_redraw() # Force the redraw of the 3D View
+
+ # Add the region OpenGL drawing callback
+ # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
+ self._handle = context.region.callback_add(self.__class__.draw_callback_px, (self, context), 'POST_PIXEL')
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+def menu_func(self, context):
+ self.layout.operator_context = "INVOKE_DEFAULT"
+ self.layout.operator(BVertexSlideOperator.bl_idname, text="Vertex Slide Bmesh")
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_vertices.prepend(menu_func)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_MT_edit_mesh_vertices.remove(menu_func)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/node_categories/__init__.py b/release/scripts/addons_contrib/node_categories/__init__.py
new file mode 100644
index 0000000..815bdd4
--- /dev/null
+++ b/release/scripts/addons_contrib/node_categories/__init__.py
@@ -0,0 +1,505 @@
+#
+# Copyright 2011, Blender Foundation.
+#
+# 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.
+#
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Node Categories",
+ "author": "Lukas Toenne",
+ "blender": (2, 64, 0),
+ "location": "Node editor toolbar",
+ "description": "Panels for adding nodes, sorted by category",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Nodes/Node_Categories",
+ "tracker_url": "",
+ "support": "TESTING",
+ "category": "Nodes"}
+
+import bpy
+from bpy.types import PropertyGroup, Panel, Operator, Menu
+from bpy.props import CollectionProperty, PointerProperty, StringProperty, BoolProperty, EnumProperty, IntProperty
+from bl_operators.node import NodeAddOperator
+
+
+# Types
+
+# Get an iterator over all actual node classes
+def gen_node_subclasses(base):
+ for nodeclass in base.__subclasses__():
+ # get_node_type used to distinguish base classes from actual node type classes
+ if hasattr(nodeclass, 'get_node_type'):
+ yield nodeclass
+ # call recursively for subclasses
+ for subclass in gen_node_subclasses(nodeclass):
+ yield subclass
+
+
+# Enum items callback to get a list of possible node types from context.
+# Used for both the node item and operator properties.
+# self argument is unused, can be None
+def node_type_items(self, context):
+ node_tree = context.space_data.edit_tree
+
+ # XXX In customnodes branch, node will use a poll function to determine possible types in the context tree.
+ # For now just use a poll function based on node subclass base
+ if node_tree.type == 'SHADER':
+ poll = lambda nodeclass: issubclass(nodeclass, bpy.types.ShaderNode) or issubclass(nodeclass, bpy.types.SpecialNode)
+ elif node_tree.type == 'COMPOSITING':
+ poll = lambda nodeclass: issubclass(nodeclass, bpy.types.CompositorNode) or issubclass(nodeclass, bpy.types.SpecialNode)
+ elif node_tree.type == 'TEXTURE':
+ poll = lambda nodeclass: issubclass(nodeclass, bpy.types.TextureNode) or issubclass(nodeclass, bpy.types.SpecialNode)
+
+ return [(nc.get_node_type(), nc.bl_rna.name, nc.bl_rna.description) for nc in gen_node_subclasses(bpy.types.Node) if (poll is None) or poll(nc)]
+
+
+node_class_dict = { nc.get_node_type() : nc for nc in set(gen_node_subclasses(bpy.types.Node)) }
+
+
+class NodeCategoryItemSetting(PropertyGroup):
+ value = StringProperty(name="Value", description="Initial value to assign to the node property")
+
+bpy.utils.register_class(NodeCategoryItemSetting)
+
+
+class NodeCategoryItem(PropertyGroup):
+ def node_type_update(self, context):
+ # convenience feature: reset to default label when changing the node type
+ # XXX might be better to check if the label has actually been modified?
+ self.label = node_class_dict[self.node_type].bl_rna.name
+
+ node_type = EnumProperty(name="Node Type", description="Node type identifier", items=node_type_items, update=node_type_update)
+ label = StringProperty(name="Label")
+
+ settings = CollectionProperty(name="Settings", description="Initial settings of the node", type=NodeCategoryItemSetting)
+
+ # internal edit values
+ edit = BoolProperty(name="Edit", description="Toggle edit mode of this item", default=False) # only used when general category edit is on
+
+bpy.utils.register_class(NodeCategoryItem)
+
+
+def node_category_update_name(self, context):
+ wm = context.window_manager
+ if self.panel_type:
+ unregister_node_panel(self)
+ register_node_panel(self)
+
+class NodeCategory(PropertyGroup):
+ type_items = [
+ ("SHADER", "Shader", "Shader node category"),
+ ("TEXTURE", "Texture", "Texture node category"),
+ ("COMPOSITING", "Compositing", "Compositing node category"),
+ ]
+
+ name = StringProperty(name="Name", update=node_category_update_name)
+ type = EnumProperty(name="Type", description="Category type used to check visibility", items=type_items)
+ items = CollectionProperty(name="Items", description="Node items in this category", type=NodeCategoryItem)
+
+ panel_type = StringProperty(name="Panel Type", description="Identifier of the associated panel type")
+
+bpy.utils.register_class(NodeCategory)
+
+
+# XXX window manager properties don't seem to be saved and reloaded, using Scene for now ...
+#bpy.types.WindowManager.node_categories = CollectionProperty(type=NodeCategory)
+#bpy.types.WindowManager.node_categories_edit = BoolProperty(name="Edit Node Categories", default=False)
+bpy.types.Scene.node_categories = CollectionProperty(type=NodeCategory)
+bpy.types.Scene.node_categories_edit = BoolProperty(name="Edit Node Categories", default=False)
+
+
+
+# Panels & Menus
+
+class NodePanel():
+ bl_space_type = 'NODE_EDITOR'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ return space.edit_tree
+
+
+class NODE_MT_category_add_node_type(Menu):
+ '''Select a node type'''
+ bl_label = "Node Type"
+
+ def draw(self, context):
+ layout = self.layout
+ node_tree = context.space_data.edit_tree
+ node_types = node_type_items(None, context)
+
+ for nt in node_types:
+ identifier = nt[0]
+ name = nt[1]
+
+ op = layout.operator("node.category_add_item", text=name)
+ op.node_type = identifier
+ op.label = name
+
+
+class NODE_MT_category_add_setting(Menu):
+ '''Select a node setting'''
+ bl_label = "Node Setting"
+
+ def draw(self, context):
+ layout = self.layout
+
+ for prop in bpy.types.Node.bl_rna.properties:
+ if prop.is_hidden or prop.is_readonly:
+ continue
+
+ op = layout.operator("node.category_add_setting", text=prop.name)
+ op.setting = prop.identifier
+
+ layout.separator()
+
+ layout.operator("node.category_add_setting", text="Custom ...")
+ # op.setting is undefined, so the operator opens a popup to get it
+
+
+def gen_valid_identifier(seq):
+ # get an iterator
+ itr = iter(seq)
+ # pull characters until we get a legal one for first in identifer
+ for ch in itr:
+ if ch == '_' or ch.isalpha():
+ yield ch
+ break
+ # pull remaining characters and yield legal ones for identifier
+ for ch in itr:
+ if ch == '_' or ch.isalpha() or ch.isdigit():
+ yield ch
+
+
+def get_unique_identifier(prefix, name):
+ base = prefix + ''.join(gen_valid_identifier(name))
+
+ identifier = base
+ index = 1
+ while hasattr(bpy.types, identifier):
+ identifier = base + str(index)
+ index += 1
+
+ return identifier
+
+
+def register_node_panel(_category):
+ identifier = get_unique_identifier("NODE_PT_category_", _category.name)
+
+ @classmethod
+ def panel_poll(cls, context):
+ space = context.space_data
+ category = context.scene.node_categories[cls.category]
+ return space.tree_type == category.type
+
+ def panel_draw_header(self, context):
+ layout = self.layout
+ category = context.scene.node_categories[self.category]
+ edit = context.scene.node_categories_edit
+
+ if edit:
+ row = layout.row()
+ row.prop(category, "name", text="")
+ op = row.operator("node.remove_category", text="", icon='X')
+ op.category_name = self.category
+
+ def panel_draw(self, context):
+ layout = self.layout
+ category = context.scene.node_categories[self.category]
+ edit = context.scene.node_categories_edit
+
+ layout.context_pointer_set("node_category", category)
+
+ if edit:
+ for index, item in enumerate(category.items):
+ layout.context_pointer_set("node_category_item", item)
+
+ if item.edit:
+ row = layout.row(align=True)
+ row.prop(item, "edit", icon='TRIA_DOWN', text="", icon_only=True, toggle=True)
+
+ box = row.box()
+
+ sub = box.row(align=True)
+ sub.prop(item, "label", text="")
+ op = sub.operator("node.category_remove_item", text="", icon='X')
+ op.index = index
+
+ box.prop_menu_enum(item, "node_type", text="Node: "+node_class_dict[item.node_type].bl_rna.name, icon='NODE')
+
+ for setting_index, setting in enumerate(item.settings):
+ row = box.row(align=True)
+ row.label(text=setting.name + " = ")
+ row.prop(setting, "value", text="")
+
+ op = row.operator("node.category_remove_setting", text="", icon='X')
+ op.index = setting_index
+
+ box.menu("NODE_MT_category_add_setting", text="Add Setting", icon='ZOOMIN')
+ else:
+ row = layout.row(align=True)
+ row.prop(item, "edit", icon='TRIA_RIGHT', text="", icon_only=True, toggle=True)
+ row.label(text=item.label)
+
+ layout.menu("NODE_MT_category_add_node_type", text="Add Node", icon='ZOOMIN')
+ else:
+ for item in category.items:
+ layout.context_pointer_set("node_category_item", item)
+
+ row = layout.row(align=True)
+ row.operator("node.category_add_node", text=item.label)
+
+ panel_class_dict = {
+ 'category' : ''.join(_category.name), # careful here! category can be removed, needs a deep string copy!
+ 'bl_idname' : identifier,
+ 'bl_label' : ''.join(_category.name),
+ 'poll' : panel_poll,
+ 'draw_header' : panel_draw_header,
+ 'draw' : panel_draw,
+ }
+ panel_class = type(identifier, (NodePanel, Panel), panel_class_dict)
+
+ _category.panel_type = identifier
+ bpy.utils.register_class(panel_class)
+
+def register_all_node_panels(context):
+ categories = context.scene.node_categories
+ for cat in categories:
+ register_node_panel(cat)
+
+
+def unregister_node_panel(category):
+ panel_type_identifier = getattr(category, "panel_type", None)
+ if panel_type_identifier:
+ panel_type = getattr(bpy.types, panel_type_identifier, None)
+ if panel_type:
+ bpy.utils.unregister_class(panel_type)
+ category.panel_type = ""
+
+def unregister_all_node_panels(context):
+ categories = context.scene.node_categories
+ for cat in categories:
+ unregister_node_panel(cat)
+
+
+class NODE_PT_categories(NodePanel, Panel):
+ bl_label = "Categories"
+ bl_options = {'HIDE_HEADER'}
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ edit = scene.node_categories_edit
+
+ layout.prop(scene, "node_categories_edit", text="Edit", toggle=True)
+ if edit:
+ layout.operator("node.add_category", text="Add Category")
+
+
+# Operators
+
+class NodeOperator():
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ # needs active node editor and a tree
+ return (space.type == 'NODE_EDITOR' and space.edit_tree)
+
+
+class NODE_OT_add_category(NodeOperator, Operator):
+ '''Create a new node category'''
+ bl_idname = "node.add_category"
+ bl_label = "Add Node Category"
+ bl_options = {'UNDO'}
+
+ category_name = StringProperty(name="Category Name", description="Name of the new node category")
+
+ def execute(self, context):
+ categories = context.scene.node_categories
+
+ # cancel if name is already registered
+ if self.category_name in categories.keys():
+ self.report({'ERROR'}, "Node category "+self.category_name+" is already registered")
+ return {'CANCELLED'}
+
+ cat = categories.add()
+ cat.name = self.category_name
+ cat.type = context.space_data.tree_type
+ register_node_panel(cat)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "category_name", text="Name")
+
+
+class NODE_OT_remove_category(NodeOperator, Operator):
+ '''Remove a node category'''
+ bl_idname = "node.remove_category"
+ bl_label = "Remove Node Category"
+ bl_options = {'UNDO'}
+
+ category_name = StringProperty(name="Category Name", description="Name of the node category")
+
+ def execute(self, context):
+ categories = context.scene.node_categories
+
+ # cancel if name is not registered
+ if not self.category_name in categories.keys():
+ self.report({'ERROR'}, "Node category "+self.category_name+" is not registered")
+ return {'CANCELLED'}
+
+ cat = categories[self.category_name]
+
+ unregister_node_panel(cat)
+ categories.remove(categories.values().index(cat))
+
+ return {'FINISHED'}
+
+
+class NODE_OT_category_add_item(NodeOperator, Operator):
+ '''Add a node item in a category'''
+ bl_idname = "node.category_add_item"
+ bl_label = "Add Item"
+ bl_options = {'UNDO'}
+
+ node_type = EnumProperty(name="Node Type", description="Node type identifier", items=node_type_items)
+ label = StringProperty(name="Label")
+
+ def execute(self, context):
+ category = context.node_category
+
+ item = category.items.add()
+ item.node_type = self.node_type
+ item.label = self.label
+
+ return {'FINISHED'}
+
+
+class NODE_OT_category_remove_item(NodeOperator, Operator):
+ '''Remove a node item from a category'''
+ bl_idname = "node.category_remove_item"
+ bl_label = "Remove Item"
+ bl_options = {'UNDO'}
+
+ index = IntProperty(name="Index", description="Index of the category item to remove")
+
+ def execute(self, context):
+ category = context.node_category
+ category.items.remove(self.index)
+ return {'FINISHED'}
+
+
+class NODE_OT_category_add_setting(NodeOperator, Operator):
+ '''Define an initial node setting'''
+ bl_idname = "node.category_add_setting"
+ bl_label = "Add Setting"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ setting = StringProperty(name="Setting", description="Name of the node setting")
+
+ def execute(self, context):
+ # set in the invoke function below as a workaround
+ item = self.item
+
+ if self.setting in [setting.name for setting in item.settings]:
+ self.report({'ERROR'}, "Node setting "+self.setting+" already defined")
+ return {'CANCELLED'}
+
+ setting = item.settings.add()
+ setting.name = self.setting
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ # XXX workaround for popup invoke: context loses the item pointer during popup,
+ # setting this as a py object in the invoke function is a workaround
+ self.item = context.node_category_item
+
+ if self.properties.is_property_set("setting"):
+ return self.execute(context)
+ else:
+ wm = context.window_manager
+ return wm.invoke_props_popup(self, event)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "setting", text="Name")
+
+
+class NODE_OT_category_remove_setting(NodeOperator, Operator):
+ '''Remove a node setting'''
+ bl_idname = "node.category_remove_setting"
+ bl_label = "Remove Setting"
+ bl_options = {'UNDO'}
+
+ index = IntProperty(name="Index", description="Index of the category item setting to remove")
+
+ def execute(self, context):
+ item = context.node_category_item
+ item.settings.remove(self.index)
+ return {'FINISHED'}
+
+
+# Node Add operator that uses category item settings for additional initialization
+class NODE_OT_category_add_node(NodeAddOperator, Operator):
+ '''Add a node to the active tree and initialize from settings'''
+ bl_idname = "node.category_add_node"
+ bl_label = "Add Node"
+
+ def execute(self, context):
+ item = context.node_category_item
+
+ node = self.create_node(context, item.node_type)
+
+ for setting in item.settings:
+ print("SETTING: ", setting.name, " = ", setting.value)
+
+ # XXX catch exceptions here?
+ value = eval(setting.value)
+
+ try:
+ setattr(node, setting.name, value)
+ except AttributeError as e:
+ self.report({'ERROR_INVALID_INPUT'}, "Node has no attribute "+setting.name)
+ print (str(e))
+ # Continue despite invalid attribute
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ self.store_mouse_cursor(context, event)
+ self.execute(context)
+ return bpy.ops.transform.translate('INVOKE_DEFAULT')
+
+
+def register():
+ register_all_node_panels(bpy.context)
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ unregister_all_node_panels(bpy.context)
+ bpy.utils.unregister_module(__name__)
+
diff --git a/release/scripts/addons_contrib/object_batch_rename_datablocks.py b/release/scripts/addons_contrib/object_batch_rename_datablocks.py
new file mode 100644
index 0000000..0fde09e
--- /dev/null
+++ b/release/scripts/addons_contrib/object_batch_rename_datablocks.py
@@ -0,0 +1,187 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Batch Rename Datablocks",
+ "author": "tstscr",
+ "version": (1, 0),
+ "blender": (2, 59, 0),
+ "location": "Search > (rename)",
+ "description": "Batch renaming of datablocks (e.g. rename materials after objectnames)",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Object/Batch_Rename_Datablocks",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=25242",
+ "category": "Object"}
+
+
+import bpy
+from bpy.props import *
+
+def get_first_material_name(ob):
+ for m_slot in ob.material_slots:
+ if m_slot.material:
+ material_name = m_slot.material.name
+ return material_name
+
+def get_name(self, ob):
+ if self.naming_base == 'Object':
+ return ob.name
+
+ if self.naming_base == 'Mesh':
+ if ob.data: return ob.data.name
+ else: return ob.name
+
+ if self.naming_base == 'Material':
+ material_name = get_first_material_name(ob)
+ if not material_name: return ob.name
+ else: return material_name
+
+ if self.naming_base == 'Custom':
+ return self.rename_custom
+
+
+def rename_datablocks_main(self, context):
+ obs = context.selected_editable_objects
+ for ob in obs:
+ name = get_name(self, ob)
+
+ if self.rename_object:
+ if (self.rename_use_prefix
+ and self.prefix_object):
+ ob.name = self.rename_prefix + name
+ else:
+ ob.name = name
+
+ if self.rename_data:
+ if (ob.data
+ and ob.data.users == 1):
+ if (self.rename_use_prefix
+ and self.prefix_data):
+ ob.data.name = self.rename_prefix + name
+ else:
+ ob.data.name = name
+
+ if self.rename_material:
+ if ob.material_slots:
+ for m_slot in ob.material_slots:
+ if m_slot.material:
+ if m_slot.material.users == 1:
+ if (self.rename_use_prefix
+ and self.prefix_material):
+ m_slot.material.name = self.rename_prefix + name
+ else:
+ m_slot.material.name = name
+
+class OBJECT_OT_batch_rename_datablocks(bpy.types.Operator):
+ """Batch rename Datablocks"""
+ bl_idname = "object.batch_rename_datablocks"
+ bl_label = "Batch Rename Datablocks"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ name_origins = [
+ ('Object', 'Object', 'Object'),
+ ('Mesh', 'Mesh', 'Mesh'),
+ ('Material', 'Material', 'Material'),
+ ('Custom', 'Custom', 'Custom')
+ ]
+ naming_base = EnumProperty(name='Name after:',
+ items=name_origins)
+ rename_custom = StringProperty(name='Custom Name',
+ default='New Name',
+ description='Rename all with this String')
+ rename_object = BoolProperty(name='Rename Objects',
+ default=False,
+ description='Rename Objects')
+ rename_data = BoolProperty(name='Rename Data',
+ default=True,
+ description='Rename Object\'s Data')
+ rename_material = BoolProperty(name='Rename Materials',
+ default=True,
+ description='Rename Objects\' Materials')
+ rename_use_prefix = BoolProperty(name='Add Prefix',
+ default=False,
+ description='Prefix Objectnames with first Groups name')
+ rename_prefix = StringProperty(name='Prefix',
+ default='',
+ description='Prefix name with this string')
+ prefix_object = BoolProperty(name='Object',
+ default=True,
+ description='Prefix Object Names')
+ prefix_data = BoolProperty(name='Data',
+ default=True,
+ description='Prefix Data Names')
+ prefix_material = BoolProperty(name='Material',
+ default=True,
+ description='Prefix Material Names')
+
+ dialog_width = 260
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column()
+ col.label(text='Rename after:')
+
+ row = layout.row()
+ row.prop(self.properties, 'naming_base', expand=True)
+
+ col = layout.column()
+ col.prop(self.properties, 'rename_custom')
+
+ col.separator()
+ col.label('Datablocks to rename:')
+ col.prop(self.properties, 'rename_object')
+ col.prop(self.properties, 'rename_data')
+ col.prop(self.properties, 'rename_material')
+
+ col.separator()
+ col.prop(self.properties, 'rename_use_prefix')
+ col.prop(self.properties, 'rename_prefix')
+
+ row = layout.row()
+ row.prop(self.properties, 'prefix_object')
+ row.prop(self.properties, 'prefix_data')
+ row.prop(self.properties, 'prefix_material')
+
+ col = layout.column()
+
+ @classmethod
+ def poll(cls, context):
+ return context.selected_objects != None
+
+ def execute(self, context):
+
+ rename_datablocks_main(self, context)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.invoke_props_dialog(self, self.dialog_width)
+ return {'RUNNING_MODAL'}
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ pass
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ pass
+if __name__ == '__main__':
+ register()
diff --git a/release/scripts/addons_contrib/object_creaprim.py b/release/scripts/addons_contrib/object_creaprim.py
new file mode 100644
index 0000000..bb0c8b1
--- /dev/null
+++ b/release/scripts/addons_contrib/object_creaprim.py
@@ -0,0 +1,442 @@
+
+# ***** 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.
+#
+# If you have Internet access, you can find the license text at
+# http://www.gnu.org/licenses/gpl.txt,
+# if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+__bpydoc__ = """\
+CreaPrim does what it says. I takes the active object and turns it into an Add Mesh addon. When you
+enable this, your custom object will be added to the Add->Mesh menu.
+
+
+Documentation
+
+Go to User Preferences->Addons and enable the CreaPrim addon in the Object section.
+First select your object or objects. The addon will show up in the 3dview properties panel.
+The name (in panel) will be set to the active object name. Select "Apply transform" if you
+want transforms to be applied to the selected objects. Modifiers will taken into account.
+You can always change this. Just hit the button and the selected
+objects will be saved in your addons folder as an Add Mesh addon with the name
+"add_mesh_XXXX.py" with XXXX being your object name. The addon will show up in User
+Preferences->Addons in the Add Mesh section.
+Enable this addon et voila, your new custom primitive will now show up in the Add Mesh menu.
+
+REMARK - dont need to be admin anymore - saves to user scripts dir
+
+ALSO - dont forget to Apply rotation and scale to have your object show up correctly
+"""
+
+bl_info = {
+ "name": "CreaPrim",
+ "author": "Gert De Roost",
+ "version": (0, 3, 9),
+ "blender": (2, 64, 0),
+ "location": "View3D > Object Tools",
+ "description": "Create primitive addon",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=32801",
+ "category": "Object"}
+
+if "bpy" in locals():
+ import imp
+
+
+import bpy
+import bmesh
+import os
+
+
+started = 0
+oldname = ""
+
+bpy.types.Scene.Name = bpy.props.StringProperty(
+ name="Name",
+ description="name for primitive",
+ maxlen= 1024)
+
+bpy.types.Scene.Apply = bpy.props.BoolProperty(
+ name = "Apply transform",
+ description = "apply transform to selected objects",
+ default = False)
+
+
+class CreaPrim(bpy.types.Operator):
+ bl_idname = "object.creaprim"
+ bl_label = "CreaPrim"
+ bl_description = "Create primitive addon."
+ bl_options = {"REGISTER"}
+
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and context.mode == 'OBJECT')
+
+ def invoke(self, context, event):
+
+ global oldname, groupname, message
+
+ scn = bpy.context.scene
+
+ objlist = []
+ for selobj in bpy.context.scene.objects:
+ if selobj.select:
+ objlist.append(selobj)
+
+ try:
+ direc = bpy.utils.script_paths()[1]
+ scriptdir = 1
+ except:
+ direc = bpy.utils.script_paths()[0]
+ scriptdir = 0
+ if len(objlist) > 1:
+ groupname = scn.Name
+ groupname = groupname.replace(".", "")
+ addondir = direc + os.sep + "addons" + os.sep + "add_mesh_" + groupname + os.sep
+ if not os.path.exists(addondir):
+ os.makedirs(addondir)
+ else:
+ groupname = scn.Name
+ print (bpy.utils.script_paths())
+ addondir = direc + os.sep + "addons" + os.sep
+ print (addondir)
+ if not os.path.exists(addondir):
+ os.makedirs(addondir)
+
+ actobj = bpy.context.active_object
+ txtlist = []
+ namelist = []
+ for selobj in objlist:
+ if len(objlist) == 1:
+ objname = scn.Name
+ else:
+ objname = selobj.name
+ objname = objname.replace(".", "")
+ namelist.append(objname)
+ mesh = selobj.to_mesh(scn, True, "PREVIEW")
+ oldname = selobj.name
+ scn.objects.active = selobj
+ if scn.Apply:
+ bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
+ txt = do_creaprim(self, mesh, objname, addondir)
+ if txt == 0:
+ return {'CANCELLED'}
+ txtlist.append(txt)
+ oldname = actobj.name
+ scn.objects.active = actobj
+
+ if len(txtlist) > 1:
+ makeinit(txtlist, namelist, groupname, addondir)
+ bpy.ops.wm.addon_enable(module="add_mesh_" + groupname)
+ else:
+ bpy.ops.wm.addon_enable(module="add_mesh_" + str.lower(objname))
+
+ if scriptdir == 1:
+ message = "Add Mesh addon " + groupname + " saved to user scripts directory."
+ else:
+ message = "Add Mesh addon " + groupname + " saved to main scripts directory."
+ bpy.ops.creaprim.message('INVOKE_DEFAULT')
+
+ return {'FINISHED'}
+
+
+class MessageOperator(bpy.types.Operator):
+ bl_idname = "creaprim.message"
+ bl_label = "Saved"
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_popup(self, width=500, height=20)
+ return {'FINISHED'}
+
+ def draw(self, context):
+
+ global groupname
+
+ layout = self.layout
+ row = layout.row()
+ row.label(text = '', icon = "PLUGIN")
+ row.label(message)
+
+def panel_func(self, context):
+
+ global started
+
+ scn = bpy.context.scene
+
+ self.layout.label(text="CreaPrim:")
+ self.layout.operator("object.creaprim", text="Create primitive", icon = 'PLUGIN')
+ self.layout.prop(scn, "Name")
+ self.layout.prop(scn, "Apply")
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_PT_tools_objectmode.append(panel_func)
+ bpy.app.handlers.scene_update_post.append(setname)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_PT_tools_objectmode.remove(panel_func)
+ bpy.app.handlers.scene_update_post.remove(setname)
+
+if __name__ == "__main__":
+ register()
+
+
+
+
+def do_creaprim(self, mesh, objname, addondir):
+
+ global message
+
+ objname = objname.replace(".", "")
+ bm = bmesh.new()
+ bm.from_mesh(mesh)
+
+
+ try:
+ txt = bpy.data.texts[str.lower("add_mesh_" + objname) + ".py"]
+ txt.clear()
+ except:
+ txt = bpy.data.texts.new("add_mesh_" + str.lower(objname) + ".py")
+
+ strlist = []
+ strlist.append("bl_info = {\n")
+ strlist.append("\"name\": \"" + objname + "\", \n")
+ strlist.append("\"author\": \"Gert De Roost\",\n")
+ strlist.append("\"version\": (1, 0, 0),\n")
+ strlist.append("\"blender\": (2, 65, 0),\n")
+ strlist.append("\"location\": \"Add > Mesh\",\n")
+ strlist.append("\"description\": \"Create " + objname + " primitive.\",\n")
+ strlist.append("\"warning\": \"\",\n")
+ strlist.append("\"wiki_url\": \"\",\n")
+ strlist.append("\"tracker_url\": \"\",\n")
+ strlist.append("\"category\": \"Add Mesh\"}\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("if \"bpy\" in locals():\n")
+ strlist.append(" import imp\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("import bpy\n")
+ strlist.append("import bmesh\n")
+ strlist.append("import math\n")
+ strlist.append("from mathutils import *\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("class " + objname + "(bpy.types.Operator):\n")
+ strlist.append(" bl_idname = \"mesh." + str.lower(objname) + "\"\n")
+ strlist.append(" bl_label = \"" + objname + "\"\n")
+ strlist.append(" bl_options = {\'REGISTER\', \'UNDO\'}\n")
+ strlist.append(" bl_description = \"add " + objname + " primitive\"\n")
+ strlist.append("\n")
+ strlist.append(" def invoke(self, context, event):\n")
+ strlist.append("\n")
+ strlist.append(" mesh = bpy.data.meshes.new(name=\"" + objname + "\")\n")
+ strlist.append(" obj = bpy.data.objects.new(name=\"" + objname + "\", object_data=mesh)\n")
+ strlist.append(" scene = bpy.context.scene\n")
+ strlist.append(" scene.objects.link(obj)\n")
+ strlist.append(" obj.location = scene.cursor_location\n")
+ strlist.append(" bm = bmesh.new()\n")
+ strlist.append(" bm.from_mesh(mesh)\n")
+ strlist.append("\n")
+ strlist.append(" idxlist = []\n")
+ posn = 0
+ strlist.append(" vertlist = [")
+ for v in bm.verts:
+ if posn > 0:
+ strlist.append(", ")
+ posn += 1
+ strlist.append(str(v.co[:]))
+ strlist.append("]\n")
+ strlist.append(" for co in vertlist:\n")
+ strlist.append(" v = bm.verts.new(co)\n")
+ strlist.append(" bm.verts.index_update()\n")
+ strlist.append(" idxlist.append(v.index)\n")
+ posn = 0
+ strlist.append(" edgelist = [")
+ for e in bm.edges:
+ if posn > 0:
+ strlist.append(", ")
+ posn += 1
+ strlist.append("[" + str(e.verts[0].index) + ", " + str(e.verts[1].index) + "]")
+ strlist.append("]\n")
+ strlist.append(" for verts in edgelist:\n")
+ strlist.append(" bm.edges.new((bm.verts[verts[0]], bm.verts[verts[1]]))\n")
+ posn1 = 0
+ strlist.append(" facelist = [(")
+ for f in bm.faces:
+ if posn1 > 0:
+ strlist.append(", (")
+ posn1 += 1
+ posn2 = 0
+ for v in f.verts:
+ if posn2 > 0:
+ strlist.append(", ")
+ strlist.append(str(v.index))
+ posn2 += 1
+ strlist.append(")")
+ strlist.append("]\n")
+ strlist.append(" for verts in facelist:\n")
+ strlist.append(" vlist = []\n")
+ strlist.append(" for idx in verts:\n")
+ strlist.append(" vlist.append(bm.verts[idxlist[idx]])\n")
+ strlist.append(" bm.faces.new(vlist)\n")
+ strlist.append("\n")
+ strlist.append(" bm.to_mesh(mesh)\n")
+ strlist.append(" mesh.update()\n")
+ strlist.append(" bm.free()\n")
+ strlist.append(" obj.rotation_quaternion = (Matrix.Rotation(math.radians(90), 3, \'X\').to_quaternion())\n")
+ strlist.append("\n")
+ strlist.append(" return {\'FINISHED\'}\n")
+
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("def menu_item(self, context):\n")
+ strlist.append(" self.layout.operator(" + objname + ".bl_idname, text=\"" + objname + "\", icon=\"PLUGIN\")\n")
+ strlist.append("\n")
+ strlist.append("def register():\n")
+ strlist.append(" bpy.utils.register_module(__name__)\n")
+ strlist.append(" bpy.types.INFO_MT_mesh_add.append(menu_item)\n")
+ strlist.append("\n")
+ strlist.append("def unregister():\n")
+ strlist.append(" bpy.utils.unregister_module(__name__)\n")
+ strlist.append(" bpy.types.INFO_MT_mesh_add.remove(menu_item)\n")
+ strlist.append("\n")
+ strlist.append("if __name__ == \"__main__\":\n")
+ strlist.append(" register()\n")
+ endstring = ''.join(strlist)
+ txt.write(endstring)
+
+ try:
+ fileobj = open(addondir + "add_mesh_" + str.lower(objname) + ".py", "w")
+ except:
+ message = "Permission problem - cant write file - run Blender as Administrator!"
+ bpy.ops.creaprim.message('INVOKE_DEFAULT')
+ return 0
+
+ fileobj.write(endstring)
+ fileobj.close()
+
+ bm.free()
+
+ return txt
+
+
+def makeinit(txtlist, namelist, groupname, addondir):
+
+ global message
+
+ try:
+ txt = bpy.data.texts["__init__.py"]
+ txt.clear()
+ except:
+ txt = bpy.data.texts.new("__init__.py")
+
+ strlist = []
+ strlist.append("bl_info = {\n")
+ strlist.append("\"name\": \"" + groupname + "\", \n")
+ strlist.append("\"author\": \"Gert De Roost\",\n")
+ strlist.append("\"version\": (1, 0, 0),\n")
+ strlist.append("\"blender\": (2, 65, 0),\n")
+ strlist.append("\"location\": \"Add > Mesh\",\n")
+ strlist.append("\"description\": \"Create " + groupname + " primitive group.\",\n")
+ strlist.append("\"warning\": \"\",\n")
+ strlist.append("\"wiki_url\": \"\",\n")
+ strlist.append("\"tracker_url\": \"\",\n")
+ strlist.append("\"category\": \"Add Mesh\"}\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("if \"bpy\" in locals():\n")
+ strlist.append(" import imp\n")
+ addonlist = []
+ for txt in txtlist:
+ name = txt.name.replace(".py", "")
+ addonlist.append(name)
+ for name in addonlist:
+ strlist.append(" imp.reload(" + name + ")\n")
+ strlist.append("else:\n")
+ for name in addonlist:
+ strlist.append(" from . import " + name + "\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("import bpy\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("class INFO_MT_mesh_" + str.lower(groupname) + "_add(bpy.types.Menu):\n")
+ strlist.append(" bl_idname = \"INFO_MT_mesh_" + str.lower(groupname) + "_add\"\n")
+ strlist.append(" bl_label = \"" + groupname + "\"\n")
+ strlist.append("\n")
+ strlist.append(" def draw(self, context):\n")
+ strlist.append(" layout = self.layout\n")
+# layout.operator_context = 'INVOKE_REGION_WIN'
+ for name in namelist:
+ strlist.append(" layout.operator(\"mesh." + str.lower(name) + "\", text=\"" + name + "\")\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("\n")
+ strlist.append("def menu_item(self, context):\n")
+ strlist.append(" self.layout.menu(\"INFO_MT_mesh_" + str.lower(groupname) + "_add\", icon=\"PLUGIN\")\n")
+ strlist.append("\n")
+ strlist.append("def register():\n")
+ strlist.append(" bpy.utils.register_module(__name__)\n")
+ strlist.append(" bpy.types.INFO_MT_mesh_add.append(menu_item)\n")
+ strlist.append("\n")
+ strlist.append("def unregister():\n")
+ strlist.append(" bpy.utils.unregister_module(__name__)\n")
+ strlist.append(" bpy.types.INFO_MT_mesh_add.remove(menu_item)\n")
+ strlist.append("\n")
+ strlist.append("if __name__ == \"__main__\":\n")
+ strlist.append(" register()\n")
+ endstring = ''.join(strlist)
+ txt.write(endstring)
+
+ try:
+ fileobj = open(addondir + "__init__.py", "w")
+ except:
+ message = "Permission problem - cant write file - run Blender as Administrator!"
+ bpy.ops.creaprim.message('INVOKE_DEFAULT')
+ return 0
+ fileobj.write(endstring)
+ fileobj.close()
+
+
+
+def setname(dummy):
+
+ global oldname
+
+ scn = bpy.context.scene
+
+ if bpy.context.active_object.name != oldname:
+ scn.Name = bpy.context.active_object.name
+ oldname = scn.Name
+
+
+
+
diff --git a/release/scripts/addons_contrib/object_drop_to_ground.py b/release/scripts/addons_contrib/object_drop_to_ground.py
new file mode 100644
index 0000000..12333c6
--- /dev/null
+++ b/release/scripts/addons_contrib/object_drop_to_ground.py
@@ -0,0 +1,181 @@
+# ##### 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 LICENSE BLOCK #####
+bl_info = {
+ 'name': 'Drop to Ground',
+ 'author': 'Unnikrishnan(kodemax), Florian Meyer(testscreenings)',
+ 'version': (1,2),
+ "blender": (2, 63, 0),
+ 'location': '3D View -> Tool Shelf -> Object Tools Panel (at the bottom)',
+ 'description': 'Drop selected objects on active object',
+ 'warning': '',
+ 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Object/Drop_to_ground',
+ "tracker_url": "http://projects.blender.org/tracker/?func=detail&atid=25349",
+ 'category': 'Object'}
+#################################################################
+import bpy, bmesh
+from mathutils import *
+from bpy.types import Operator
+from bpy.props import *
+#################################################################
+def get_align_matrix(location, normal):
+ up = Vector((0,0,1))
+ angle = normal.angle(up)
+ axis = up.cross(normal)
+ mat_rot = Matrix.Rotation(angle, 4, axis)
+ mat_loc = Matrix.Translation(location)
+ mat_align = mat_rot * mat_loc
+ return mat_align
+
+def transform_ground_to_world(sc, ground):
+ tmpMesh = ground.to_mesh(sc, True, 'PREVIEW')
+ tmpMesh.transform(ground.matrix_world)
+ tmp_ground = bpy.data.objects.new('tmpGround', tmpMesh)
+ sc.objects.link(tmp_ground)
+ sc.update()
+ return tmp_ground
+
+def get_lowest_world_co_from_mesh(ob, mat_parent=None):
+ bme = bmesh.new()
+ bme.from_mesh(ob.data)
+ mat_to_world = ob.matrix_world.copy()
+ if mat_parent:
+ mat_to_world = mat_parent * mat_to_world
+ lowest=None
+ #bme.verts.index_update() #probably not needed
+ for v in bme.verts:
+ if not lowest:
+ lowest = v
+ if (mat_to_world * v.co).z < (mat_to_world * lowest.co).z:
+ lowest = v
+ lowest_co = mat_to_world * lowest.co
+ bme.free()
+ return lowest_co
+
+def get_lowest_world_co(context, ob, mat_parent=None):
+ if ob.type == 'MESH':
+ return get_lowest_world_co_from_mesh(ob)
+
+ elif ob.type == 'EMPTY' and ob.dupli_type == 'GROUP':
+ if not ob.dupli_group:
+ return None
+
+ else:
+ lowest_co = None
+ for ob_l in ob.dupli_group.objects:
+ if ob_l.type == 'MESH':
+ lowest_ob_l = get_lowest_world_co_from_mesh(ob_l, ob.matrix_world)
+ if not lowest_co:
+ lowest_co = lowest_ob_l
+ if lowest_ob_l.z < lowest_co.z:
+ lowest_co = lowest_ob_l
+
+ return lowest_co
+
+def drop_objects(self, context):
+ ground = context.object
+ obs = context.selected_objects
+ obs.remove(ground)
+ tmp_ground = transform_ground_to_world(context.scene, ground)
+ down = Vector((0, 0, -10000))
+
+ for ob in obs:
+ if self.use_origin:
+ lowest_world_co = ob.location
+ else:
+ lowest_world_co = get_lowest_world_co(context, ob)
+ if not lowest_world_co:
+ print(ob.type, 'is not supported. Failed to drop', ob.name)
+ continue
+ hit_location, hit_normal, hit_index = tmp_ground.ray_cast(lowest_world_co,
+ lowest_world_co + down)
+ if hit_index == -1:
+ print(ob.name, 'didn\'t hit the ground')
+ continue
+
+ # simple drop down
+ to_ground_vec = hit_location - lowest_world_co
+ ob.location += to_ground_vec
+
+ # drop with align to hit normal
+ if self.align:
+ to_center_vec = ob.location - hit_location #vec: hit_loc to origin
+ # rotate object to align with face normal
+ mat_normal = get_align_matrix(hit_location, hit_normal)
+ rot_euler = mat_normal.to_euler()
+ mat_ob_tmp = ob.matrix_world.copy().to_3x3()
+ mat_ob_tmp.rotate(rot_euler)
+ mat_ob_tmp = mat_ob_tmp.to_4x4()
+ ob.matrix_world = mat_ob_tmp
+ # move_object to hit_location
+ ob.location = hit_location
+ # move object above surface again
+ to_center_vec.rotate(rot_euler)
+ ob.location += to_center_vec
+
+
+ #cleanup
+ bpy.ops.object.select_all(action='DESELECT')
+ tmp_ground.select = True
+ bpy.ops.object.delete('EXEC_DEFAULT')
+ for ob in obs:
+ ob.select = True
+ ground.select = True
+
+#################################################################
+class OBJECT_OT_drop_to_ground(Operator):
+ """Drop selected objects on active object"""
+ bl_idname = "object.drop_on_active"
+ bl_label = "Drop to Ground"
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Drop selected objects on active object"
+
+ align = BoolProperty(
+ name="Align to ground",
+ description="Aligns the object to the ground",
+ default=True)
+ use_origin = BoolProperty(
+ name="Use Center",
+ description="Drop to objects origins",
+ default=False)
+
+ ##### POLL #####
+ @classmethod
+ def poll(cls, context):
+ return len(context.selected_objects) >= 2
+
+ ##### EXECUTE #####
+ def execute(self, context):
+ print('\nDropping Objects')
+ drop_objects(self, context)
+ return {'FINISHED'}
+
+#################################################################
+def drop_to_ground_button(self, context):
+ self.layout.operator(OBJECT_OT_drop_to_ground.bl_idname,
+ text="Drop to Ground")
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.VIEW3D_PT_tools_objectmode.append(drop_to_ground_button)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.VIEW3D_PT_tools_objectmode.remove(drop_to_ground_button)
+
+if __name__ == '__main__':
+ register()
diff --git a/release/scripts/addons_contrib/object_edit_linked.py b/release/scripts/addons_contrib/object_edit_linked.py
new file mode 100644
index 0000000..f79bc1a
--- /dev/null
+++ b/release/scripts/addons_contrib/object_edit_linked.py
@@ -0,0 +1,185 @@
+# ***** 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 *****
+
+bl_info = {
+ "name": "Edit Linked Library",
+ "author": "Jason van Gumster (Fweeb)",
+ "version": (0, 7, 1),
+ "blender": (2, 60, 0),
+ "location": "View3D > Toolshelf > Edit Linked Library",
+ "description": "Allows editing of objects linked from a .blend library.",
+ "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.6/Py/Scripts/Object/Edit_Linked_Library",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=29630",
+ "category": "Object"}
+
+
+import bpy
+from bpy.app.handlers import persistent
+
+settings = {
+ "original_file": "",
+ "linked_file": "",
+ "linked_objects": [],
+ }
+
+ at persistent
+def linked_file_check(context):
+ if settings["linked_file"] != "":
+ if settings["linked_file"] in {bpy.data.filepath, bpy.path.abspath(bpy.data.filepath)}:
+ print("Editing a linked library.")
+ bpy.ops.object.select_all(action = 'DESELECT')
+ for ob_name in settings["linked_objects"]:
+ bpy.data.objects[ob_name].select = True
+ if len(settings["linked_objects"]) == 1:
+ bpy.context.scene.objects.active = bpy.data.objects[settings["linked_objects"][0]]
+ else:
+ # For some reason, the linked editing session ended (failed to find a file or opened a different file before returning to the originating .blend)
+ settings["original_file"] = ""
+ settings["linked_file"] = ""
+
+
+
+class EditLinked(bpy.types.Operator):
+ """Edit Linked Library"""
+ bl_idname = "object.edit_linked"
+ bl_label = "Edit Linked Library"
+
+ autosave = bpy.props.BoolProperty(name = "Autosave", description = "Automatically save the current file before opening the linked library", default = True)
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None
+
+ def execute(self, context):
+ #print(bpy.context.active_object.library)
+ target = context.active_object
+
+ if target.dupli_group and target.dupli_group.library:
+ targetpath = target.dupli_group.library.filepath
+ settings["linked_objects"].extend([ob.name for ob in target.dupli_group.objects])
+ elif target.library:
+ targetpath = target.library.filepath
+ settings["linked_objects"].append(target.name)
+
+ if targetpath:
+ print(target.name + " is linked to " + targetpath)
+
+ if self.properties.autosave == True:
+ bpy.ops.wm.save_mainfile()
+
+ settings["original_file"] = bpy.data.filepath
+
+ # XXX: need to test for proxied rigs
+ settings["linked_file"] = bpy.path.abspath(targetpath)
+
+ bpy.ops.wm.open_mainfile(filepath=settings["linked_file"])
+ print("Opened linked file!")
+ else:
+ self.report({'WARNING'}, target.name + " is not linked")
+ print(target.name + " is not linked")
+
+ return {'FINISHED'}
+
+
+class ReturnToOriginal(bpy.types.Operator):
+ """Return to the original file after editing the linked library .blend"""
+ bl_idname = "wm.return_to_original"
+ bl_label = "Return to Original File"
+
+ autosave = bpy.props.BoolProperty(name = "Autosave", description = "Automatically save the current file before opening original file", default = True)
+
+ @classmethod
+ def poll(cls, context):
+ # Probably the wrong context to check for here...
+ return context.active_object is not None
+
+ def execute(self, context):
+ if self.properties.autosave == True:
+ bpy.ops.wm.save_mainfile()
+ bpy.ops.wm.open_mainfile(filepath=settings["original_file"])
+ settings["original_file"] = ""
+ settings["linked_objects"] = []
+ print("Back to the original!")
+ return {'FINISHED'}
+
+
+# UI
+# TODO: Add operators to the File menu? Hide the entire panel for non-linked objects?
+class PanelLinkedEdit(bpy.types.Panel):
+ bl_label = "Edit Linked Library"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+
+
+ def draw(self, context):
+ kc = bpy.context.window_manager.keyconfigs.addon
+ km = kc.keymaps["3D View"]
+ kmi_edit = km.keymap_items["object.edit_linked"]
+ kmi_return = km.keymap_items["wm.return_to_original"]
+
+ if settings["original_file"] == "" and ((context.active_object.dupli_group and context.active_object.dupli_group.library is not None) or context.active_object.library is not None):
+ kmi_edit.active = True
+ kmi_return.active = False
+ self.layout.operator("object.edit_linked").autosave = context.scene.edit_linked_autosave
+ self.layout.prop(context.scene, "edit_linked_autosave")
+ elif settings["original_file"] != "":
+ kmi_edit.active = False
+ kmi_return.active = True
+ self.layout.operator("wm.return_to_original").autosave = context.scene.edit_linked_autosave
+ self.layout.prop(context.scene, "edit_linked_autosave")
+ else:
+ kmi_edit.active = False
+ kmi_return.active = False
+ self.layout.label(text = "Active object is not linked")
+
+
+def register():
+ bpy.app.handlers.load_post.append(linked_file_check)
+ bpy.utils.register_class(EditLinked)
+ bpy.utils.register_class(ReturnToOriginal)
+ bpy.utils.register_class(PanelLinkedEdit)
+
+ # Is there a better place to store this property?
+ bpy.types.Scene.edit_linked_autosave = bpy.props.BoolProperty(name = "Autosave", description = "Automatically save the current file before opening a linked file", default = True)
+
+ # Keymapping (deactivated by default; activated when a library object is selected)
+ kc = bpy.context.window_manager.keyconfigs.addon
+ km = kc.keymaps.new(name = "3D View", space_type='VIEW_3D')
+ kmi = km.keymap_items.new("object.edit_linked", 'NUMPAD_SLASH', 'PRESS', shift = True)
+ kmi.active = False
+ kmi = km.keymap_items.new("wm.return_to_original", 'NUMPAD_SLASH', 'PRESS', shift = True)
+ kmi.active = False
+
+
+def unregister():
+ bpy.utils.unregister_class(EditLinked)
+ bpy.utils.unregister_class(ReturnToOriginal)
+ bpy.utils.unregister_class(PanelLinkedEdit)
+ bpy.app.handlers.load_post.remove(linked_file_check)
+
+ del bpy.types.Scene.edit_linked_autosave
+
+ kc = bpy.context.window_manager.keyconfigs.addon
+ km = kc.keymaps["3D View"]
+ km.keymap_items.remove(km.keymap_items["object.edit_linked"])
+ km.keymap_items.remove(km.keymap_items["wm.return_to_original"])
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/object_laplace_lightning.py b/release/scripts/addons_contrib/object_laplace_lightning.py
new file mode 100644
index 0000000..85665e4
--- /dev/null
+++ b/release/scripts/addons_contrib/object_laplace_lightning.py
@@ -0,0 +1,1244 @@
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+bl_info = {
+ "name": "Laplacian Lightning",
+ "author": "teldredge",
+ "version": (0, 2, 6),
+ "blender": (2, 61, 0),
+ "location": "View3D > ToolShelf > Laplacian Lightning",
+ "description": "Lightning mesh generator using laplacian growth algorithm",
+ "warning": "Beta/Buggy.",
+ "wiki_url": "http://www.funkboxing.com/wordpress/?p=301",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=27189",
+ "category": "Object"}
+
+######################################################################
+######################################################################
+##################### BLENDER LAPLACIAN LIGHTNING ####################
+############################ teldredge ###############################
+######################## www.funkboxing.com ##########################
+######################################################################
+######################## using algorithm from ########################
+######################################################################
+############## FAST SIMULATION OF LAPLACIAN GROWTH (FSLG) ############
+#################### http://gamma.cs.unc.edu/FRAC/ ###################
+######################################################################
+###################### and a few ideas ideas from ####################
+######################################################################
+##### FAST ANIMATION OF LIGHTNING USING AN ADAPTIVE MESH (FALUAM) ####
+################ http://gamma.cs.unc.edu/FAST_LIGHTNING/ #############
+######################################################################
+######################################################################
+""" -----RELEASE LOG/NOTES/PONTIFICATIONS-----
+v0.1.0 - 04.11.11
+ basic generate functions and UI
+ object creation report (Custom Properties: FSLG_REPORT)
+v0.2.0 - 04.15.11
+ started spelling laplacian right.
+ add curve function (not in UI) ...twisting problem
+ classify stroke by MAIN path, h-ORDER paths, TIP paths
+ jitter cells for mesh creation
+ add materials if present
+v0.2.1 - 04.16.11
+ mesh classification speedup
+v0.2.2 - 04.21.11
+ fxns to write/read array to file
+ restrict growth to insulator cells (object bounding box)
+ origin/ground defineable by object
+ gridunit more like 'resolution'
+v0.2.3 - 04.24.11
+ cloud attractor object (termintates loop if hit)
+ secondary path orders (hOrder) disabled in UI (set to 1)
+v0.2.4 - 04.26.11
+ fixed object selection in UI
+ will not run if required object not selected
+ moved to view 3d > toolbox
+v0.2.5 - 05.08.11
+ testing for 2.57b
+ single mesh output (for build modifier)
+ speedups (dist fxn)
+v0.2.6 - 06.20.11
+ scale/pos on 'write to cubes' works now
+ if origin obj is mesh, uses all verts as initial charges
+ semi-helpful tooltips
+ speedups, faster dedupe fxn, faster classification
+ use any shape mesh obj as insulator mesh
+ must have rot=0, scale=1, origin set to geometry
+ often fails to block bolt with curved/complex shapes
+ separate single and multi mesh creation
+
+v0.x -
+ -fix vis fxn to only buildCPGraph once for VM or VS
+ -improve list fxns (rid of ((x,y,z),w) and use (x,y,z,w)), use 'sets'
+ -create python cmodule for a few of most costly fxns
+ i have pretty much no idea how to do this yet
+ -cloud and insulator can be groups of MESH objs
+ -?text output, possibly to save on interrupt, allow continue from text
+ -?hook modifiers from tips->sides->main, weight w/ vert groups
+ -user defined 'attractor' path
+ -fix add curve function
+ -animated arcs via. ionization path
+ -environment map boundary conditions - requires Eqn. 15 from FSLG...
+ -?assign wattage at each segment for HDRI
+ -?default settings for -lightning, -teslacoil, -spark/arc
+ -fix hOrder functionality
+ -multiple 'MAIN' brances for non-lightning discharges
+ -n-symmetry option, create mirror images, snowflakes, etc...
+"""
+
+######################################################################
+######################################################################
+######################################################################
+import bpy
+import time
+import random
+from math import sqrt
+from mathutils import Vector
+import struct
+import bisect
+import os.path
+notZero = 0.0000000001
+scn = bpy.context.scene
+
+######################################################################
+########################### UTILITY FXNS #############################
+######################################################################
+def within(x,y,d):
+###---CHECK IF x-d <= y <= x+d
+ if x-d <= y and x + d >= y:
+ return True
+ else: return False
+
+def dist(ax, ay, az ,bx, by, bz):
+ dv = Vector((ax,ay,az)) - Vector((bx,by,bz))
+ d = dv.length
+ return d
+
+def splitList(aList, idx):
+ ll = []
+ for x in aList:
+ ll.append(x[idx])
+ return ll
+
+def splitListCo(aList):
+ ll = []
+ for p in aList:
+ ll.append((p[0], p[1], p[2]))
+ return ll
+
+def getLowHigh(aList):
+ tLow = aList[0]; tHigh = aList[0]
+ for a in aList:
+ if a < tLow: tLow = a
+ if a > tHigh: tHigh = a
+ return tLow, tHigh
+
+def weightedRandomChoice(aList):
+ tL = []
+ tweight = 0
+ for a in range(len(aList)):
+ idex = a; weight = aList[a]
+ if weight > 0.0:
+ tweight += weight
+ tL.append((tweight, idex))
+ i = bisect.bisect(tL, (random.uniform(0, tweight), None))
+ r = tL[i][1]
+ return r
+
+def getStencil3D_26(x,y,z):
+ nL = []
+ for xT in range(x-1, x+2):
+ for yT in range(y-1, y+2):
+ for zT in range(z-1, z+2):
+ nL.append((xT, yT, zT))
+ nL.remove((x,y,z))
+ return nL
+
+def jitterCells(aList, jit):
+ j = jit/2
+ bList = []
+ for a in aList:
+ ax = a[0] + random.uniform(-j, j)
+ ay = a[1] + random.uniform(-j, j)
+ az = a[2] + random.uniform(-j, j)
+ bList.append((ax, ay, az))
+ return bList
+
+def deDupe(seq, idfun=None):
+###---THANKS TO THIS GUY - http://www.peterbe.com/plog/uniqifiers-benchmark
+ if idfun is None:
+ def idfun(x): return x
+ seen = {}
+ result = []
+ for item in seq:
+ marker = idfun(item)
+ if marker in seen: continue
+ seen[marker] = 1
+ result.append(item)
+ return result
+
+######################################################################
+######################## VISUALIZATION FXNS ##########################
+######################################################################
+def writeArrayToVoxel(arr, filename):
+ gridS = 64
+ half = int(gridS/2)
+ bitOn = 255
+ aGrid = [[[0 for z in range(gridS)] for y in range(gridS)] for x in range(gridS)]
+ for a in arr:
+ try:
+ aGrid[a[0]+half][a[1]+half][a[2]+half] = bitOn
+ except:
+ print('Particle beyond voxel domain')
+ file = open(filename, "wb")
+ for z in range(gridS):
+ for y in range(gridS):
+ for x in range(gridS):
+ file.write(struct.pack('B', aGrid[x][y][z]))
+ file.flush()
+ file.close()
+
+def writeArrayToFile(arr, filename):
+ file = open(filename, "w")
+ for a in arr:
+ tstr = str(a[0]) + ',' + str(a[1]) + ',' + str(a[2]) + '\n'
+ file.write(tstr)
+ file.close
+
+def readArrayFromFile(filename):
+ file = open(filename, "r")
+ arr = []
+ for f in file:
+ pt = f[0:-1].split(',')
+ arr.append((int(pt[0]), int(pt[1]), int(pt[2])))
+ return arr
+
+def makeMeshCube(msize):
+ msize = msize/2
+ mmesh = bpy.data.meshes.new('q')
+ mmesh.vertices.add(8)
+ mmesh.vertices[0].co = [-msize, -msize, -msize]
+ mmesh.vertices[1].co = [-msize, msize, -msize]
+ mmesh.vertices[2].co = [ msize, msize, -msize]
+ mmesh.vertices[3].co = [ msize, -msize, -msize]
+ mmesh.vertices[4].co = [-msize, -msize, msize]
+ mmesh.vertices[5].co = [-msize, msize, msize]
+ mmesh.vertices[6].co = [ msize, msize, msize]
+ mmesh.vertices[7].co = [ msize, -msize, msize]
+ mmesh.faces.add(6)
+ mmesh.faces[0].vertices_raw = [0,1,2,3]
+ mmesh.faces[1].vertices_raw = [0,4,5,1]
+ mmesh.faces[2].vertices_raw = [2,1,5,6]
+ mmesh.faces[3].vertices_raw = [3,2,6,7]
+ mmesh.faces[4].vertices_raw = [0,3,7,4]
+ mmesh.faces[5].vertices_raw = [5,4,7,6]
+ mmesh.update(calc_edges=True)
+ return(mmesh)
+
+def writeArrayToCubes(arr, gridBU, orig, cBOOL = False, jBOOL = True):
+ for a in arr:
+ x = a[0]; y = a[1]; z = a[2]
+ me = makeMeshCube(gridBU)
+ ob = bpy.data.objects.new('xCUBE', me)
+ ob.location.x = (x*gridBU) + orig[0]
+ ob.location.y = (y*gridBU) + orig[1]
+ ob.location.z = (z*gridBU) + orig[2]
+ if cBOOL: ###---!!!MOSTLY UNUSED
+ ### POS+BLUE, NEG-RED, ZERO:BLACK
+ col = (1.0, 1.0, 1.0, 1.0)
+ if a[3] == 0: col = (0.0, 0.0, 0.0, 1.0)
+ if a[3] < 0: col = (-a[3], 0.0, 0.0, 1.0)
+ if a[3] > 0: col = (0.0, 0.0, a[3], 1.0)
+ ob.color = col
+ bpy.context.scene.objects.link(ob)
+ bpy.context.scene.update()
+ if jBOOL:
+ ###---SELECTS ALL CUBES w/ ?bpy.ops.object.join() b/c
+ ### CAN'T JOIN ALL CUBES TO A SINGLE MESH RIGHT... ARGH...
+ for q in bpy.context.scene.objects:
+ q.select = False
+ if q.name[0:5] == 'xCUBE':
+ q.select = True
+ bpy.context.scene.objects.active = q
+
+def addVert(ob, pt, conni = -1):
+ mmesh = ob.data
+ mmesh.vertices.add(1)
+ vcounti = len(mmesh.vertices)-1
+ mmesh.vertices[vcounti].co = [pt[0], pt[1], pt[2]]
+ if conni > -1:
+ mmesh.edges.add(1)
+ ecounti = len(mmesh.edges)-1
+ mmesh.edges[ecounti].vertices = [conni, vcounti]
+ mmesh.update()
+
+def addEdge(ob, va, vb):
+ mmesh = ob.data
+ mmesh.edges.add(1)
+ ecounti = len(mmesh.edges)-1
+ mmesh.edges[ecounti].vertices = [va, vb]
+ mmesh.update()
+
+def newMesh(mname):
+ mmesh = bpy.data.meshes.new(mname)
+ omesh = bpy.data.objects.new(mname, mmesh)
+ bpy.context.scene.objects.link(omesh)
+ return omesh
+
+def writeArrayToMesh(mname, arr, gridBU, rpt = None):
+ mob = newMesh(mname)
+ mob.scale = (gridBU, gridBU, gridBU)
+ if rpt: addReportProp(mob, rpt)
+ addVert(mob, arr[0], -1)
+ for ai in range(1, len(arr)):
+ a = arr[ai]
+ addVert(mob, a, ai-1)
+ return mob
+
+###---!!!OUT OF ORDER - SOME PROBLEM WITH IT ADDING (0,0,0)
+def writeArrayToCurves(cname, arr, gridBU, bd = .05, rpt = None):
+ cur = bpy.data.curves.new('fslg_curve', 'CURVE')
+ cur.use_fill_front = False
+ cur.use_fill_back = False
+ cur.bevel_depth = bd
+ cur.bevel_resolution = 2
+ cob = bpy.data.objects.new(cname, cur)
+ cob.scale = (gridBU, gridBU, gridBU)
+ if rpt: addReportProp(cob, rpt)
+ bpy.context.scene.objects.link(cob)
+ cur.splines.new('BEZIER')
+ cspline = cur.splines[0]
+ div = 1 ### SPACING FOR HANDLES (2 - 1/2 WAY, 1 - NEXT BEZIER)
+ for a in range(len(arr)):
+ cspline.bezier_points.add(1)
+ bp = cspline.bezier_points[len(cspline.bezier_points)-1]
+ if a-1 < 0: hL = arr[a]
+ else:
+ hx = arr[a][0] - ((arr[a][0]-arr[a-1][0]) / div)
+ hy = arr[a][1] - ((arr[a][1]-arr[a-1][1]) / div)
+ hz = arr[a][2] - ((arr[a][2]-arr[a-1][2]) / div)
+ hL = (hx,hy,hz)
+
+ if a+1 > len(arr)-1: hR = arr[a]
+ else:
+ hx = arr[a][0] + ((arr[a+1][0]-arr[a][0]) / div)
+ hy = arr[a][1] + ((arr[a+1][1]-arr[a][1]) / div)
+ hz = arr[a][2] + ((arr[a+1][2]-arr[a][2]) / div)
+ hR = (hx,hy,hz)
+ bp.co = arr[a]
+ bp.handle_left = hL
+ bp.handle_right = hR
+
+def addArrayToMesh(mob, arr):
+ addVert(mob, arr[0], -1)
+ mmesh = mob.data
+ vcounti = len(mmesh.vertices)-1
+ for ai in range(1, len(arr)):
+ a = arr[ai]
+ addVert(mob, a, len(mmesh.vertices)-1)
+
+def addMaterial(ob, matname):
+ mat = bpy.data.materials[matname]
+ ob.active_material = mat
+
+def writeStokeToMesh(arr, jarr, MAINi, HORDERi, TIPSi, orig, gs, rpt=None):
+ ###---MAIN BRANCH
+ print(' WRITING MAIN BRANCH')
+ llmain = []
+ for x in MAINi:
+ llmain.append(jarr[x])
+ mob = writeArrayToMesh('la0MAIN', llmain, gs)
+ mob.location = orig
+
+ ###---hORDER BRANCHES
+ for hOi in range(len(HORDERi)):
+ print(' WRITING ORDER', hOi)
+ hO = HORDERi[hOi]
+ hob = newMesh('la1H'+str(hOi))
+
+ for y in hO:
+ llHO = []
+ for x in y:
+ llHO.append(jarr[x])
+ addArrayToMesh(hob, llHO)
+ hob.scale = (gs, gs, gs)
+ hob.location = orig
+
+ ###---TIPS
+ print(' WRITING TIP PATHS')
+ tob = newMesh('la2TIPS')
+ for y in TIPSi:
+ llt = []
+ for x in y:
+ llt.append(jarr[x])
+ addArrayToMesh(tob, llt)
+ tob.scale = (gs, gs, gs)
+ tob.location = orig
+
+ ###---ADD MATERIALS TO OBJECTS (IF THEY EXIST)
+ try:
+ addMaterial(mob, 'edgeMAT-h0')
+ addMaterial(hob, 'edgeMAT-h1')
+ addMaterial(tob, 'edgeMAT-h2')
+ print(' ADDED MATERIALS')
+ except: print(' MATERIALS NOT FOUND')
+ ###---ADD GENERATION REPORT TO ALL MESHES
+ if rpt:
+ addReportProp(mob, rpt)
+ addReportProp(hob, rpt)
+ addReportProp(tob, rpt)
+
+def writeStokeToSingleMesh(arr, jarr, orig, gs, mct, rpt=None):
+ sgarr = buildCPGraph(arr, mct)
+ llALL = []
+
+ Aob = newMesh('laALL')
+ for pt in jarr:
+ addVert(Aob, pt)
+ for cpi in range(len(sgarr)):
+ ci = sgarr[cpi][0]
+ pi = sgarr[cpi][1]
+ addEdge(Aob, pi, ci)
+ Aob.location = orig
+ Aob.scale = ((gs,gs,gs))
+
+ if rpt:
+ addReportProp(Aob, rpt)
+
+def visualizeArray(cg, oob, gs, vm, vs, vc, vv, rst):
+###---IN: (cellgrid, origin, gridscale,
+### mulimesh, single mesh, cubes, voxels, report sting)
+ origin = oob.location
+
+ ###---DEAL WITH VERT MULTI-ORIGINS
+ oct = 2
+ if oob.type == 'MESH': oct = len(oob.data.vertices)
+
+ ###---JITTER CELLS
+ if vm or vs: cjarr = jitterCells(cg, 1)
+
+
+ if vm: ###---WRITE ARRAY TO MULTI MESH
+
+ aMi, aHi, aTi = classifyStroke(cg, oct, scn.HORDER)
+ print(':::WRITING TO MULTI-MESH')
+ writeStokeToMesh(cg, cjarr, aMi, aHi, aTi, origin, gs, rst)
+ print(':::MULTI-MESH WRITTEN')
+
+ if vs: ###---WRITE TO SINGLE MESH
+ print(':::WRITING TO SINGLE MESH')
+ writeStokeToSingleMesh(cg, cjarr, origin, gs, oct, rst)
+ print(':::SINGLE MESH WRITTEN')
+
+ if vc: ###---WRITE ARRAY TO CUBE OBJECTS
+ print(':::WRITING TO CUBES')
+ writeArrayToCubes(cg, gs, origin)
+ print(':::CUBES WRITTEN')
+
+ if vv: ###---WRITE ARRAY TO VOXEL DATA FILE
+ print(':::WRITING TO VOXELS')
+ fname = "FSLGvoxels.raw"
+ path = os.path.dirname(bpy.data.filepath)
+ writeArrayToVoxel(cg, path + "\\" + fname)
+ print(':::VOXEL DATA WRITTEN TO - ', path + "\\" + fname)
+
+ ###---READ/WRITE ARRAY TO FILE (MIGHT NOT BE NECESSARY)
+ #tfile = 'c:\\testarr.txt'
+ #writeArrayToFile(cg, tfile)
+ #cg = readArrayFromFile(tfile)
+
+ ###---READ/WRITE ARRAY TO CURVES (OUT OF ORDER)
+ #writeArrayToCurves('laMAIN', llmain, .10, .25)
+
+######################################################################
+########################### ALGORITHM FXNS ###########################
+########################## FROM FALUAM PAPER #########################
+###################### PLUS SOME STUFF I MADE UP #####################
+######################################################################
+def buildCPGraph(arr, sti = 2):
+###---IN -XYZ ARRAY AS BUILT BY GENERATOR
+###---OUT -[(CHILDindex, PARENTindex)]
+### sti - start index, 2 for Empty, len(me.vertices) for Mesh
+ sgarr = []
+ sgarr.append((1, 0)) #
+ for ai in range(sti, len(arr)):
+ cs = arr[ai]
+ cpts = arr[0:ai]
+ cslap = getStencil3D_26(cs[0], cs[1], cs[2])
+
+ for nc in cslap:
+ ct = cpts.count(nc)
+ if ct>0:
+ cti = cpts.index(nc)
+ sgarr.append((ai, cti))
+ return sgarr
+
+def buildCPGraph_WORKINPROGRESS(arr, sti = 2):
+###---IN -XYZ ARRAY AS BUILT BY GENERATOR
+###---OUT -[(CHILDindex, PARENTindex)]
+### sti - start index, 2 for Empty, len(me.vertices) for Mesh
+ sgarr = []
+ sgarr.append((1, 0)) #
+ ctix = 0
+ for ai in range(sti, len(arr)):
+ cs = arr[ai]
+ #cpts = arr[0:ai]
+ cpts = arr[ctix:ai]
+ cslap = getStencil3D_26(cs[0], cs[1], cs[2])
+ for nc in cslap:
+ ct = cpts.count(nc)
+ if ct>0:
+ #cti = cpts.index(nc)
+ cti = ctix + cpts.index(nc)
+ ctix = cpts.index(nc)
+
+ sgarr.append((ai, cti))
+ return sgarr
+
+def findChargePath(oc, fc, ngraph, restrict = [], partial = True):
+ ###---oc -ORIGIN CHARGE INDEX, fc -FINAL CHARGE INDEX
+ ###---ngraph -NODE GRAPH, restrict- INDEX OF SITES CANNOT TRAVERSE
+ ###---partial -RETURN PARTIAL PATH IF RESTRICTION ENCOUNTERD
+ cList = splitList(ngraph, 0)
+ pList = splitList(ngraph, 1)
+ aRi = []
+ cNODE = fc
+ for x in range(len(ngraph)):
+ pNODE = pList[cList.index(cNODE)]
+ aRi.append(cNODE)
+ cNODE = pNODE
+ npNODECOUNT = cList.count(pNODE)
+ if cNODE == oc: ### STOP IF ORIGIN FOUND
+ aRi.append(cNODE) ### RETURN PATH
+ return aRi
+ if npNODECOUNT == 0: ### STOP IF NO PARENTS
+ return [] ### RETURN []
+ if pNODE in restrict: ### STOP IF PARENT IS IN RESTRICTION
+ if partial: ### RETURN PARTIAL OR []
+ aRi.append(cNODE)
+ return aRi
+ else: return []
+
+def findTips(arr):
+ lt = []
+ for ai in arr[0:len(arr)-1]:
+ a = ai[0]
+ cCOUNT = 0
+ for bi in arr:
+ b = bi[1]
+ if a == b:
+ cCOUNT += 1
+ if cCOUNT == 0:
+ lt.append(a)
+ return lt
+
+def findChannelRoots(path, ngraph, restrict = []):
+ roots = []
+ for ai in range(len(ngraph)):
+ chi = ngraph[ai][0]
+ par = ngraph[ai][1]
+ if par in path and not chi in path and \
+ not chi in restrict:
+ roots.append(par)
+ droots = deDupe(roots)
+ return droots
+
+def findChannels(roots, tips, ngraph, restrict):
+ cPATHS = []
+ for ri in range(len(roots)):
+ r = roots[ri]
+ sL = 1
+ sPATHi = []
+ for ti in range(len(tips)):
+ t = tips[ti]
+ if t < r: continue
+ tPATHi = findChargePath(r, t, ngraph, restrict, False)
+ tL = len(tPATHi)
+ if tL > sL:
+ if countChildrenOnPath(tPATHi, ngraph) > 1:
+ sL = tL
+ sPATHi = tPATHi
+ tTEMP = t; tiTEMP = ti
+ if len(sPATHi) > 0:
+ print(' found path/idex from', ri, 'of',
+ len(roots), 'possible | tips:', tTEMP, tiTEMP)
+ cPATHS.append(sPATHi)
+ tips.remove(tTEMP)
+ return cPATHS
+
+def findChannels_WORKINPROGRESS(roots, ttips, ngraph, restrict):
+ cPATHS = []
+ tips = list(ttips)
+ for ri in range(len(roots)):
+ r = roots[ri]
+ sL = 1
+ sPATHi = []
+ tipREMOVE = [] ###---CHECKED TIP INDEXES, TO BE REMOVED FOR NEXT LOOP
+ for ti in range(len(tips)):
+ t = tips[ti]
+ #print('-CHECKING RT/IDEX:', r, ri, 'AGAINST TIP', t, ti)
+ #if t < r: continue
+ if ti < ri: continue
+ tPATHi = findChargePath(r, t, ngraph, restrict, False)
+ tL = len(tPATHi)
+ if tL > sL:
+ if countChildrenOnPath(tPATHi, ngraph) > 1:
+ sL = tL
+ sPATHi = tPATHi
+ tTEMP = t; tiTEMP = ti
+ if tL > 0:
+ tipREMOVE.append(t)
+ if len(sPATHi) > 0:
+ print(' found path from root idex', ri, 'of',
+ len(roots), 'possible roots | #oftips=', len(tips))
+ cPATHS.append(sPATHi)
+ for q in tipREMOVE: tips.remove(q)
+
+ return cPATHS
+
+def countChildrenOnPath(aPath, ngraph, quick = True):
+ ###---RETURN HOW MANY BRANCHES
+ ### COUNT WHEN NODE IS A PARENT >1 TIMES
+ ### quick -STOP AND RETURN AFTER FIRST
+ cCOUNT = 0
+ pList = splitList(ngraph,1)
+ for ai in range(len(aPath)-1):
+ ap = aPath[ai]
+ pc = pList.count(ap)
+ if quick and pc > 1:
+ return pc
+ return cCOUNT
+
+###---CLASSIFY CHANNELS INTO 'MAIN', 'hORDER/SECONDARY' and 'SIDE'
+def classifyStroke(sarr, mct, hORDER = 1):
+ print(':::CLASSIFYING STROKE')
+ ###---BUILD CHILD/PARENT GRAPH (INDEXES OF sarr)
+ sgarr = buildCPGraph(sarr, mct)
+
+ ###---FIND MAIN CHANNEL
+ print(' finding MAIN')
+ oCharge = sgarr[0][1]
+ fCharge = sgarr[len(sgarr)-1][0]
+ aMAINi = findChargePath(oCharge, fCharge, sgarr)
+
+ ###---FIND TIPS
+ print(' finding TIPS')
+ aTIPSi = findTips(sgarr)
+
+ ###---FIND hORDER CHANNEL ROOTS
+ ### hCOUNT = ORDERS BEWTEEN MAIN and SIDE/TIPS
+ ### !!!STILL BUGGY!!!
+ hRESTRICT = list(aMAINi) ### ADD TO THIS AFTER EACH TIME
+ allHPATHSi = [] ### ALL hO PATHS: [[h0], [h1]...]
+ curPATHSi = [aMAINi] ### LIST OF PATHS FIND ROOTS ON
+ for h in range(hORDER):
+ allHPATHSi.append([])
+ for pi in range(len(curPATHSi)): ### LOOP THROUGH ALL PATHS IN THIS ORDER
+ p = curPATHSi[pi]
+ ### GET ROOTS FOR THIS PATH
+ aHROOTSi = findChannelRoots(p, sgarr, hRESTRICT)
+ print(' found', len(aHROOTSi), 'roots in ORDER', h, ':#paths:', len(curPATHSi))
+ ### GET CHANNELS FOR THESE ROOTS
+ if len(aHROOTSi) == 0:
+ print('NO ROOTS FOR FOUND FOR CHANNEL')
+ aHPATHSi = []
+ continue
+ else:
+ aHPATHSiD = findChannels(aHROOTSi, aTIPSi, sgarr, hRESTRICT)
+ aHPATHSi = aHPATHSiD
+ allHPATHSi[h] += aHPATHSi
+ ### SET THESE CHANNELS AS RESTRICTIONS FOR NEXT ITERATIONS
+ for hri in aHPATHSi:
+ hRESTRICT += hri
+ curPATHSi = aHPATHSi
+
+ ###---SIDE BRANCHES, FINAL ORDER OF HEIRARCHY
+ ### FROM TIPS THAT ARE NOT IN AN EXISTING PATH
+ ### BACK TO ANY OTHER POINT THAT IS ALREADY ON A PATH
+ aDRAWNi = []
+ aDRAWNi += aMAINi
+ for oH in allHPATHSi:
+ for o in oH:
+ aDRAWNi += o
+ aTPATHSi = []
+ for a in aTIPSi:
+ if not a in aDRAWNi:
+ aPATHi = findChargePath(oCharge, a, sgarr, aDRAWNi)
+ aDRAWNi += aPATHi
+ aTPATHSi.append(aPATHi)
+
+ return aMAINi, allHPATHSi, aTPATHSi
+
+def voxelByVertex(ob, gs):
+###---'VOXELIZES' VERTS IN A MESH TO LIST [(x,y,z),(x,y,z)]
+### W/ RESPECT GSCALE AND OB ORIGIN (B/C SHOULD BE ORIGIN OBJ)
+ orig = ob.location
+ ll = []
+ for v in ob.data.vertices:
+ x = int( v.co.x / gs )
+ y = int( v.co.y / gs )
+ z = int( v.co.z / gs )
+ ll.append((x,y,z))
+ return ll
+
+def voxelByRays(ob, orig, gs):
+###--- MESH INTO A 3DGRID W/ RESPECT GSCALE AND BOLT ORIGIN
+### -DOES NOT TAKE OBJECT ROTATION/SCALE INTO ACCOUNT
+### -THIS IS A HORRIBLE, INEFFICIENT FUNCTION
+### MAYBE THE RAYCAST/GRID THING ARE A BAD IDEA. BUT I
+### HAVE TO 'VOXELIZE THE OBJECT W/ RESCT TO GSCALE/ORIGIN
+ bbox = ob.bound_box
+ bbxL = bbox[0][0]; bbxR = bbox[4][0]
+ bbyL = bbox[0][1]; bbyR = bbox[2][1]
+ bbzL = bbox[0][2]; bbzR = bbox[1][2]
+ xct = int((bbxR - bbxL) / gs)
+ yct = int((bbyR - bbyL) / gs)
+ zct = int((bbzR - bbzL) / gs)
+ xs = int(xct/2); ys = int(yct/2); zs = int(zct/2)
+ print(' CASTING', xct, '/', yct, '/', zct, 'cells, total:', xct*yct*zct, 'in obj-', ob.name)
+ ll = []
+ rc = 100 ###---DISTANCE TO CAST FROM
+ ###---RAYCAST TOP/BOTTOM
+ print(' RAYCASTING TOP/BOTTOM')
+ for x in range(xct):
+ for y in range(yct):
+ xco = bbxL + (x*gs); yco = bbyL + (y*gs)
+ v1 = ((xco, yco, rc)); v2 = ((xco, yco, -rc))
+ vz1 = ob.ray_cast(v1,v2); vz2 = ob.ray_cast(v2,v1)
+ if vz1[2] != -1: ll.append((x-xs, y-ys, int(vz1[0][2] * (1/gs)) ))
+ if vz2[2] != -1: ll.append((x-xs, y-ys, int(vz2[0][2] * (1/gs)) ))
+ ###---RAYCAST FRONT/BACK
+ print(' RAYCASTING FRONT/BACK')
+ for x in range(xct):
+ for z in range(zct):
+ xco = bbxL + (x*gs); zco = bbzL + (z*gs)
+ v1 = ((xco, rc, zco)); v2 = ((xco, -rc, zco))
+ vy1 = ob.ray_cast(v1,v2); vy2 = ob.ray_cast(v2,v1)
+ if vy1[2] != -1: ll.append((x-xs, int(vy1[0][1] * (1/gs)), z-zs))
+ if vy2[2] != -1: ll.append((x-xs, int(vy2[0][1] * (1/gs)), z-zs))
+ ###---RAYCAST LEFT/RIGHT
+ print(' RAYCASTING LEFT/RIGHT')
+ for y in range(yct):
+ for z in range(zct):
+ yco = bbyL + (y*gs); zco = bbzL + (z*gs)
+ v1 = ((rc, yco, zco)); v2 = ((-rc, yco, zco))
+ vx1 = ob.ray_cast(v1,v2); vx2 = ob.ray_cast(v2,v1)
+ if vx1[2] != -1: ll.append((int(vx1[0][0] * (1/gs)), y-ys, z-zs))
+ if vx2[2] != -1: ll.append((int(vx2[0][0] * (1/gs)), y-ys, z-zs))
+
+ ###---ADD IN NEIGHBORS SO BOLT WONT GO THRU
+ nlist = []
+ for l in ll:
+ nl = getStencil3D_26(l[0], l[1], l[2])
+ nlist += nl
+
+ ###---DEDUPE
+ print(' ADDED NEIGHBORS, DEDUPING...')
+ rlist = deDupe(ll+nlist)
+ qlist = []
+
+ ###---RELOCATE GRID W/ RESPECT GSCALE AND BOLT ORIGIN
+ ### !!!NEED TO ADD IN OBJ ROT/SCALE HERE SOMEHOW...
+ od = Vector(( (ob.location[0] - orig[0]) / gs,
+ (ob.location[1] - orig[1]) / gs,
+ (ob.location[2] - orig[2]) / gs ))
+ for r in rlist:
+ qlist.append((r[0]+int(od[0]), r[1]+int(od[1]), r[2]+int(od[2]) ))
+
+ return qlist
+
+def fakeGroundChargePlane(z, charge):
+ eCL = []
+ xy = abs(z)/2
+ eCL += [(0, 0, z, charge)]
+ eCL += [(xy, 0, z, charge)]
+ eCL += [(0, xy, z, charge)]
+ eCL += [(-xy, 0, z, charge)]
+ eCL += [(0, -xy, z, charge)]
+ return eCL
+
+def addCharges(ll, charge):
+###---IN: ll - [(x,y,z), (x,y,z)], charge - w
+### OUT clist - [(x,y,z,w), (x,y,z,w)]
+ clist = []
+ for l in ll:
+ clist.append((l[0], l[1], l[2], charge))
+ return clist
+
+######################################################################
+########################### ALGORITHM FXNS ###########################
+############################## FROM FSLG #############################
+######################################################################
+def getGrowthProbability_KEEPFORREFERENCE(uN, aList):
+ ###---IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES
+ ### OUT: LIST OF [(XYZ), POT, PROB]
+ cList = splitList(aList, 0)
+ oList = splitList(aList, 1)
+ Omin, Omax = getLowHigh(oList)
+ if Omin == Omax: Omax += notZero; Omin -= notZero
+ PdL = []
+ E = 0
+ E = notZero ###===DIVISOR FOR (FSLG - Eqn. 12)
+ for o in oList:
+ Uj = (o - Omin) / (Omax - Omin) ###===(FSLG - Eqn. 13)
+ E += pow(Uj, uN)
+ for oi in range(len(oList)):
+ o = oList[oi]
+ Ui = (o - Omin) / (Omax - Omin)
+ Pd = (pow(Ui, uN)) / E ###===(FSLG - Eqn. 12)
+ PdINT = Pd * 100
+ PdL.append(Pd)
+ return PdL
+
+###---WORK IN PROGRESS, TRYING TO SPEED THESE UP
+def fslg_e13(x, min, max, u): return pow((x - min) / (max - min), u)
+def addit(x,y):return x+y
+def fslg_e12(x, min, max, u, e): return (fslg_e13(x, min, max, u) / e) * 100
+
+def getGrowthProbability(uN, aList):
+ ###---IN: uN -USER TERM, cList -CANDIDATE SITES, oList -CANDIDATE SITE CHARGES
+ ### OUT: LIST OF PROB
+ cList = splitList(aList, 0)
+ oList = splitList(aList, 1)
+ Omin, Omax = getLowHigh(oList)
+ if Omin == Omax: Omax += notZero; Omin -= notZero
+ PdL = []
+ E = notZero
+ minL = [Omin for q in range(len(oList))]
+ maxL = [Omax for q in range(len(oList))]
+ uNL = [uN for q in range(len(oList))]
+ E = sum(map(fslg_e13, oList, minL, maxL, uNL))
+ EL = [E for q in range(len(oList))]
+ mp = map(fslg_e12, oList, minL, maxL, uNL, EL)
+ for m in mp: PdL.append(m)
+ return PdL
+
+def updatePointCharges(p, cList, eList = []):
+ ###---IN: pNew -NEW GROWTH CELL
+ ### cList -OLD CANDIDATE SITES, eList -SAME
+ ### OUT: LIST OF NEW CHARGE AT CANDIDATE SITES
+ r1 = 1/2 ###===(FSLG - Eqn. 10)
+ nOiL = []
+ for oi in range(len(cList)):
+ o = cList[oi][1]
+ c = cList[oi][0]
+ iOe = 0
+ rit = dist(c[0], c[1], c[2], p[0], p[1], p[2])
+ iOe += (1 - (r1/rit))
+ Oit = o + iOe
+ nOiL.append((c, Oit))
+ return nOiL
+
+def initialPointCharges(pList, cList, eList = []):
+ ###---IN: p -CHARGED CELL (XYZ), cList -CANDIDATE SITES (XYZ, POT, PROB)
+ ### OUT: cList -WITH POTENTIAL CALCULATED
+ r1 = 1/2 ###===(FSLG - Eqn. 10)
+ npList = []
+ for p in pList:
+ npList.append(((p[0], p[1], p[2]), 1.0))
+ for e in eList:
+ npList.append(((e[0], e[1], e[2]), e[3]))
+ OiL = []
+ for i in cList:
+ Oi = 0
+ for j in npList:
+ if i != j[0]:
+ rij = dist(i[0], i[1], i[2], j[0][0], j[0][1], j[0][2])
+ Oi += (1 - (r1 / rij)) * j[1] ### CHARGE INFLUENCE
+ OiL.append(((i[0], i[1], i[2]), Oi))
+ return OiL
+
+def getCandidateSites(aList, iList = []):
+ ###---IN: aList -(X,Y,Z) OF CHARGED CELL SITES, iList -insulator sites
+ ### OUT: CANDIDATE LIST OF GROWTH SITES [(X,Y,Z)]
+ tt1 = time.clock()
+ cList = []
+ for c in aList:
+ tempList = getStencil3D_26(c[0], c[1], c[2])
+ for t in tempList:
+ if not t in aList and not t in iList:
+ cList.append(t)
+ ncList = deDupe(cList)
+ tt2 = time.clock()
+ #print('FXNTIMER:getCandidateSites:', tt2-tt1, 'check 26 against:', len(aList)+len(iList))
+ return ncList
+
+######################################################################
+############################# SETUP FXNS #############################
+######################################################################
+def setupObjects():
+ oOB = bpy.data.objects.new('ELorigin', None)
+ oOB.location = ((0,0,10))
+ bpy.context.scene.objects.link(oOB)
+
+ gOB = bpy.data.objects.new('ELground', None)
+ gOB.empty_draw_type = 'ARROWS'
+ bpy.context.scene.objects.link(gOB)
+
+ cME = makeMeshCube(1)
+ cOB = bpy.data.objects.new('ELcloud', cME)
+ cOB.location = ((-2,8,12))
+ cOB.hide_render = True
+ bpy.context.scene.objects.link(cOB)
+
+ iME = makeMeshCube(1)
+ for v in iME.vertices:
+ xyl = 6.5; zl = .5
+ v.co[0] = v.co[0] * xyl
+ v.co[1] = v.co[1] * xyl
+ v.co[2] = v.co[2] * zl
+ iOB = bpy.data.objects.new('ELinsulator', iME)
+ iOB.location = ((0,0,5))
+ iOB.hide_render = True
+ bpy.context.scene.objects.link(iOB)
+
+ try:
+ scn.OOB = 'ELorigin'
+ scn.GOB = 'ELground'
+ scn.COB = 'ELcloud'
+ scn.IOB = 'ELinsulator'
+ except: pass
+
+def checkSettings():
+ check = True
+ if scn.OOB == "":
+ print('ERROR: NO ORIGIN OBJECT SELECTED')
+ check = False
+ if scn.GROUNDBOOL and scn.GOB == "":
+ print('ERROR: NO GROUND OBJECT SELECTED')
+ check = False
+ if scn.CLOUDBOOL and scn.COB == "":
+ print('ERROR: NO CLOUD OBJECT SELECTED')
+ check = False
+ if scn.IBOOL and scn.IOB == "":
+ print('ERROR: NO INSULATOR OBJECT SELECTED')
+ check = False
+ #should make a popup here
+ return check
+
+
+######################################################################
+############################### MAIN #################################
+######################################################################
+def FSLG():
+###======FAST SIMULATION OF LAPLACIAN GROWTH======###
+ print('\n<<<<<<------GO GO GADGET: FAST SIMULATION OF LAPLACIAN GROWTH!')
+ tc1 = time.clock()
+ TSTEPS = scn.TSTEPS
+
+ obORIGIN = scn.objects[scn.OOB]
+ obGROUND = scn.objects[scn.GOB]
+ scn.ORIGIN = obORIGIN.location
+ scn.GROUNDZ = int((obGROUND.location[2] - scn.ORIGIN[2]) / scn.GSCALE)
+
+ ###====== 1) INSERT INTIAL CHARGE(S) POINT (USES VERTS IF MESH)
+ cgrid = [(0, 0, 0)]
+ if obORIGIN.type == 'MESH':
+ print("<<<<<<------ORIGIN OBJECT IS MESH, 'VOXELIZING' INTIAL CHARGES FROM VERTS")
+ cgrid = voxelByVertex(obORIGIN, scn.GSCALE)
+ if scn.VMMESH:
+ print("<<<<<<------CANNOT CLASSIFY STROKE FROM VERT ORIGINS YET, NO MULTI-MESH OUTPUT")
+ scn.VMMESH = False; scn.VSMESH = True
+
+ ###---GROUND CHARGE CELL / INSULATOR LISTS (eChargeList/icList)
+ eChargeList = []; icList = []
+ if scn.GROUNDBOOL:
+ eChargeList = fakeGroundChargePlane(scn.GROUNDZ, scn.GROUNDC)
+ if scn.CLOUDBOOL:
+ print("<<<<<<------'VOXELIZING' CLOUD OBJECT (COULD TAKE SOME TIME)")
+ obCLOUD = scn.objects[scn.COB]
+ eChargeListQ = voxelByRays(obCLOUD, scn.ORIGIN, scn.GSCALE)
+ eChargeList = addCharges(eChargeListQ, scn.CLOUDC)
+ print('<<<<<<------CLOUD OBJECT CELL COUNT = ', len(eChargeList) )
+ if scn.IBOOL:
+ print("<<<<<<------'VOXELIZING' INSULATOR OBJECT (COULD TAKE SOME TIME)")
+ obINSULATOR = scn.objects[scn.IOB]
+ icList = voxelByRays(obINSULATOR, scn.ORIGIN, scn.GSCALE)
+ print('<<<<<<------INSULATOR OBJECT CELL COUNT = ', len(icList) )
+ #writeArrayToCubes(icList, scn.GSCALE, scn.ORIGIN)
+ #return 'THEEND'
+
+ ###====== 2) LOCATE CANDIDATE SITES AROUND CHARGE
+ cSites = getCandidateSites(cgrid, icList)
+
+ ###====== 3) CALC POTENTIAL AT EACH SITE (Eqn. 10)
+ cSites = initialPointCharges(cgrid, cSites, eChargeList)
+
+ ts = 1
+ while ts <= TSTEPS:
+ ###====== 1) SELECT NEW GROWTH SITE (Eqn. 12)
+ ###===GET PROBABILITIES AT CANDIDATE SITES
+ gProbs = getGrowthProbability(scn.BIGVAR, cSites)
+ ###===CHOOSE NEW GROWTH SITE BASED ON PROBABILITIES
+ gSitei = weightedRandomChoice(gProbs)
+ gsite = cSites[gSitei][0]
+
+ ###====== 2) ADD NEW POINT CHARGE AT GROWTH SITE
+ ###===ADD NEW GROWTH CELL TO GRID
+ cgrid.append(gsite)
+ ###===REMOVE NEW GROWTH CELL FROM CANDIDATE SITES
+ cSites.remove(cSites[gSitei])
+
+ ###====== 3) UPDATE POTENTIAL AT CANDIDATE SITES (Eqn. 11)
+ cSites = updatePointCharges(gsite, cSites, eChargeList)
+
+ ###====== 4) ADD NEW CANDIDATES SURROUNDING GROWTH SITE
+ ###===GET CANDIDATE 'STENCIL'
+ ncSitesT = getCandidateSites([gsite], icList)
+ ###===REMOVE CANDIDATES ALREADY IN CANDIDATE LIST OR CHARGE GRID
+ ncSites = []
+ cSplit = splitList(cSites, 0)
+ for cn in ncSitesT:
+ if not cn in cSplit and \
+ not cn in cgrid:
+ ncSites.append((cn, 0))
+
+ ###====== 5) CALC POTENTIAL AT NEW CANDIDATE SITES (Eqn. 10)
+ ncSplit = splitList(ncSites, 0)
+ ncSites = initialPointCharges(cgrid, ncSplit, eChargeList)
+
+ ###===ADD NEW CANDIDATE SITES TO CANDIDATE LIST
+ for ncs in ncSites:
+ cSites.append(ncs)
+
+ ###===ITERATION COMPLETE
+ istr1 = ':::T-STEP: ' + str(ts) + '/' + str(TSTEPS)
+ istr12 = ' | GROUNDZ: ' + str(scn.GROUNDZ) + ' | '
+ istr2 = 'CANDS: ' + str(len(cSites)) + ' | '
+ istr3 = 'GSITE: ' + str(gsite)
+ print(istr1 + istr12 + istr2 + istr3)
+ ts += 1
+
+ ###---EARLY TERMINATION FOR GROUND/CLOUD STRIKE
+ if scn.GROUNDBOOL:
+ if gsite[2] == scn.GROUNDZ:
+ ts = TSTEPS+1
+ print('<<<<<<------EARLY TERMINATION DUE TO GROUNDSTRIKE')
+ continue
+ if scn.CLOUDBOOL:
+ #if gsite in cloudList:
+ if gsite in splitListCo(eChargeList):
+ ts = TSTEPS+1
+ print('<<<<<<------EARLY TERMINATION DUE TO CLOUDSTRIKE')
+ continue
+
+ tc2 = time.clock()
+ tcRUN = tc2 - tc1
+ print('<<<<<<------LAPLACIAN GROWTH LOOP COMPLETED: ' + str(len(cgrid)) + ' / ' + str(tcRUN)[0:5] + ' SECONDS')
+ print('<<<<<<------VISUALIZING DATA')
+
+ reportSTRING = getReportString(tcRUN)
+ ###---VISUALIZE ARRAY
+ visualizeArray(cgrid, obORIGIN, scn.GSCALE, scn.VMMESH, scn.VSMESH, scn.VCUBE, scn.VVOX, reportSTRING)
+ print('<<<<<<------COMPLETE')
+
+######################################################################
+################################ GUI #################################
+######################################################################
+###---NOT IN UI
+bpy.types.Scene.ORIGIN = bpy.props.FloatVectorProperty(name = "origin charge")
+bpy.types.Scene.GROUNDZ = bpy.props.IntProperty(name = "ground Z coordinate")
+bpy.types.Scene.HORDER = bpy.props.IntProperty(name = "secondary paths orders")
+###---IN UI
+bpy.types.Scene.TSTEPS = bpy.props.IntProperty(
+ name = "iterations", description = "number of cells to create, will end early if hits ground plane or cloud")
+bpy.types.Scene.GSCALE = bpy.props.FloatProperty(
+ name = "grid unit size", description = "scale of cells, .25 = 4 cells per blenderUnit")
+bpy.types.Scene.BIGVAR = bpy.props.FloatProperty(
+ name = "straightness", description = "straightness/branchiness of bolt, <2 is mush, >12 is staight line, 6.3 is good")
+bpy.types.Scene.GROUNDBOOL = bpy.props.BoolProperty(
+ name = "use ground object", description = "use ground plane or not")
+bpy.types.Scene.GROUNDC = bpy.props.IntProperty(
+ name = "ground charge", description = "charge of ground plane")
+bpy.types.Scene.CLOUDBOOL = bpy.props.BoolProperty(
+ name = "use cloud object", description = "use cloud obj, attracts and terminates like ground but any obj instead of z plane, can slow down loop if obj is large, overrides ground")
+bpy.types.Scene.CLOUDC = bpy.props.IntProperty(
+ name = "cloud charge", description = "charge of a cell in cloud object (so total charge also depends on obj size)")
+
+bpy.types.Scene.VMMESH = bpy.props.BoolProperty(
+ name = "multi mesh", description = "output to multi-meshes for different materials on main/sec/side branches")
+bpy.types.Scene.VSMESH = bpy.props.BoolProperty(
+ name = "single mesh", description = "output to single mesh for using build modifier and particles for effects")
+bpy.types.Scene.VCUBE = bpy.props.BoolProperty(
+ name = "cubes", description = "CTRL-J after run to JOIN, outputs a bunch of cube objest, mostly for testing")
+bpy.types.Scene.VVOX = bpy.props.BoolProperty(
+ name = "voxel (experimental)", description = "output to a voxel file to bpy.data.filepath\FSLGvoxels.raw - doesn't work well right now")
+bpy.types.Scene.IBOOL = bpy.props.BoolProperty(
+ name = "use insulator object", description = "use insulator mesh object to prevent growth of bolt in areas")
+bpy.types.Scene.OOB = bpy.props.StringProperty(description = "origin of bolt, can be an Empty, if obj is mesh will use all verts as charges")
+bpy.types.Scene.GOB = bpy.props.StringProperty(description = "object to use as ground plane, uses z coord only")
+bpy.types.Scene.COB = bpy.props.StringProperty(description = "object to use as cloud, best to use a cube")
+bpy.types.Scene.IOB = bpy.props.StringProperty(description = "object to use as insulator, 'voxelized' before generating bolt, can be slow")
+
+###---DEFAULT USER SETTINGS
+scn.TSTEPS = 350
+scn.HORDER = 1
+scn.GSCALE = 0.12
+scn.BIGVAR = 6.3
+scn.GROUNDBOOL = True
+scn.GROUNDC = -250
+scn.CLOUDBOOL = False
+scn.CLOUDC = -1
+scn.VMMESH = True
+scn.VSMESH = False
+scn.VCUBE = False
+scn.VVOX = False
+scn.IBOOL = False
+try:
+ scn.OOB = "ELorigin"
+ scn.GOB = "ELground"
+ scn.COB = "ELcloud"
+ scn.IOB = "ELinsulator"
+except: pass
+### TESTING
+if False:
+#if True:
+ #scn.BIGVAR = 6.3
+ #scn.VSMESH = True
+ #scn.VMMESH = False
+ #scn.VCUBE = True
+ #scn.TSTEPS = 7500
+ scn.TSTEPS = 100
+ #scn.GROUNDC = -500
+ #scn.CLOUDC = -5
+ #scn.GROUNDBOOL = False
+ #scn.CLOUDBOOL = True
+
+ #scn.IBOOL = True
+
+class runFSLGLoopOperator(bpy.types.Operator):
+ """By The Mighty Hammer Of Thor!!!"""
+ bl_idname = "object.runfslg_operator"
+ bl_label = "run FSLG Loop Operator"
+
+ def execute(self, context):
+ if checkSettings():
+ FSLG()
+ else: pass
+ return {'FINISHED'}
+
+class setupObjectsOperator(bpy.types.Operator):
+ """Create origin/ground/cloud/insulator objects"""
+ bl_idname = "object.setup_objects_operator"
+ bl_label = "Setup Objects Operator"
+
+ def execute(self, context):
+ setupObjects()
+ return {'FINISHED'}
+
+class OBJECT_PT_fslg(bpy.types.Panel):
+ bl_label = "Laplacian Lightning - v0.2.6"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "TOOLS"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ scn = context.scene
+ layout = self.layout
+ colR = layout.column()
+ #row1 = layout.row()
+ #colL = row1.column()
+ #colR = row1.column()
+ colR.label('-for progress open console-')
+ colR.label('Help > Toggle System Console')
+ colR.prop(scn, 'TSTEPS')
+ colR.prop(scn, 'GSCALE')
+ colR.prop(scn, 'BIGVAR')
+ colR.operator('object.setup_objects_operator', text = 'create setup objects')
+ colR.label('origin object')
+ colR.prop_search(scn, "OOB", context.scene, "objects")
+ colR.prop(scn, 'GROUNDBOOL')
+ colR.prop_search(scn, "GOB", context.scene, "objects")
+ colR.prop(scn, 'GROUNDC')
+ colR.prop(scn, 'CLOUDBOOL')
+ colR.prop_search(scn, "COB", context.scene, "objects")
+ colR.prop(scn, 'CLOUDC')
+ colR.prop(scn, 'IBOOL')
+ colR.prop_search(scn, "IOB", context.scene, "objects")
+ colR.operator('object.runfslg_operator', text = 'generate lightning')
+ #col.prop(scn, 'HORDER')
+ colR.prop(scn, 'VMMESH')
+ colR.prop(scn, 'VSMESH')
+ colR.prop(scn, 'VCUBE')
+ colR.prop(scn, 'VVOX')
+
+def getReportString(rtime):
+ rSTRING1 = 't:' + str(scn.TSTEPS) + ',sc:' + str(scn.GSCALE)[0:4] + ',uv:' + str(scn.BIGVAR)[0:4] + ','
+ rSTRING2 = 'ori:' + str(scn. ORIGIN[0]) + '/' + str(scn. ORIGIN[1]) + '/' + str(scn. ORIGIN[2]) + ','
+ rSTRING3 = 'gz:' + str(scn.GROUNDZ) + ',gc:' + str(scn.GROUNDC) + ',rtime:' + str(int(rtime))
+ return rSTRING1 + rSTRING2 + rSTRING3
+
+def addReportProp(ob, str):
+ bpy.types.Object.FSLG_REPORT = bpy.props.StringProperty(
+ name = 'fslg_report', default = '')
+ ob.FSLG_REPORT = str
+
+def register():
+ bpy.utils.register_class(runFSLGLoopOperator)
+ bpy.utils.register_class(setupObjectsOperator)
+ bpy.utils.register_class(OBJECT_PT_fslg)
+
+def unregister():
+ bpy.utils.unregister_class(runFSLGLoopOperator)
+ bpy.utils.unregister_class(setupObjectsOperator)
+ bpy.utils.unregister_class(OBJECT_PT_fslg)
+
+if __name__ == "__main__":
+ ### RUN FOR TESTING
+ #FSLG()
+
+ ### UI
+ register()
+ pass
+
+###########################
+##### FXN BENCHMARKS ######
+###########################
+def BENCH():
+ print('\n\n\n--->BEGIN BENCHMARK')
+ bt0 = time.clock()
+ ###---MAKE A BIG LIST
+ tsize = 25
+ tlist = []
+ for x in range(tsize):
+ for y in range(tsize):
+ for z in range(tsize):
+ tlist.append((x,y,z))
+ tlist.append((x,y,z))
+
+ ###---FUNCTION TO TEST
+ bt1 = time.clock()
+
+ #ll = deDupe(tlist)
+ #ll = f5(tlist)
+ print('LENS - ', len(tlist), len(ll) )
+
+ bt2 = time.clock()
+ btRUNb = bt2 - bt1
+ btRUNa = bt1 - bt0
+ print('--->SETUP TIME : ', btRUNa)
+ print('--->BENCHMARK TIME: ', btRUNb)
+ print('--->GRIDSIZE: ', tsize, ' - ', tsize*tsize*tsize)
+
+#BENCH()
+
+
+##################################
+################################
diff --git a/release/scripts/addons_contrib/object_mangle_tools.py b/release/scripts/addons_contrib/object_mangle_tools.py
new file mode 100644
index 0000000..3102623
--- /dev/null
+++ b/release/scripts/addons_contrib/object_mangle_tools.py
@@ -0,0 +1,206 @@
+# mangle_tools.py (c) 2011 Phil Cote (cotejrp1)
+#
+# ***** 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 *****
+bl_info = {
+ "name": "Mangle Tools",
+ "author": "Phil Cote",
+ "version": (0, 2),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tools",
+ "description": "Set of tools to mangle curves, meshes, and shape keys",
+ "warning": "", # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=29071",
+ "category": "Object"}
+
+import bpy
+import random
+import time
+from math import pi
+import bmesh
+
+def move_coordinate(context, co, is_curve=False):
+ xyz_const = context.scene.constraint_vector
+ random.seed(time.time())
+ multiplier = 1
+
+ # For curves, we base the multiplier on the circumference formula.
+ # This helps make curve changes more noticable.
+ if is_curve:
+ multiplier = 2 * pi
+ random_mag = context.scene.random_magnitude
+ if xyz_const[0]:
+ co.x += .01 * random.randrange( -random_mag, random_mag ) * multiplier
+ if xyz_const[1]:
+ co.y += .01 * random.randrange( -random_mag, random_mag ) * multiplier
+ if xyz_const[2]:
+ co.z += .01 * random.randrange( -random_mag, random_mag ) * multiplier
+
+
+class MeshManglerOperator(bpy.types.Operator):
+ """Push vertices on the selected object around in random """ \
+ """directions to create a crumpled look"""
+ bl_idname = "ba.mesh_mangler"
+ bl_label = "Mangle Mesh"
+ bl_options = { "REGISTER", "UNDO" }
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return ob != None and ob.type == 'MESH'
+
+ def execute(self, context):
+ mesh = context.active_object.data
+ bm = bmesh.new()
+ bm.from_mesh(mesh)
+ verts, faces = bm.verts, bm.faces
+ randomMag = context.scene.random_magnitude
+ random.seed( time.time() )
+
+ if mesh.shape_keys != None:
+ self.report({'INFO'}, "Cannot mangle mesh: Shape keys present")
+ return {'CANCELLED'}
+
+ for vert in verts:
+ xVal = .01 * random.randrange( -randomMag, randomMag )
+ yVal = .01 * random.randrange( -randomMag, randomMag)
+ zVal = .01 * random.randrange( -randomMag, randomMag )
+ vert.co.x = vert.co.x + xVal
+ vert.co.y = vert.co.y + yVal
+ vert.co.z = vert.co.z + zVal
+
+ bm.to_mesh(mesh)
+ mesh.update()
+ return {'FINISHED'}
+
+
+class AnimanglerOperator(bpy.types.Operator):
+ """Make a shape key and pushes the verts around on it """ \
+ """to set up for random pulsating animation"""
+ bl_idname = "ba.ani_mangler"
+ bl_label = "Mangle Shape Key"
+
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return ob != None and ob.type in [ 'MESH', 'CURVE' ]
+
+ def execute(self, context):
+ scn = context.scene
+ mangleName = scn.mangle_name
+ ob = context.object
+ shapeKey = ob.shape_key_add( name=mangleName )
+ verts = shapeKey.data
+
+ for vert in verts:
+ move_coordinate(context, vert.co, is_curve=ob.type=='CURVE')
+
+ return {'FINISHED'}
+
+
+class CurveManglerOp(bpy.types.Operator):
+ """Mangle a curve to the degree the user specifies"""
+ bl_idname = "ba.curve_mangler"
+ bl_label = "Mangle Curve"
+ bl_options = { 'REGISTER', 'UNDO' }
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return ob != None and ob.type == "CURVE"
+
+
+ def execute(self, context):
+
+ ob = context.active_object
+ if ob.data.shape_keys != None:
+ self.report({'INFO'}, "Cannot mangle curve. Shape keys present")
+ return {'CANCELLED'}
+ splines = context.object.data.splines
+
+ for spline in splines:
+ if spline.type == 'BEZIER':
+ points = spline.bezier_points
+ elif spline.type in {'POLY', 'NURBS'}:
+ points = spline.points
+
+ for point in points:
+ move_coordinate(context, point.co, is_curve=True)
+
+ return {'FINISHED'}
+
+
+class MangleToolsPanel(bpy.types.Panel):
+ bl_label = "Mangle Tools"
+ bl_space_type = "VIEW_3D"
+ bl_region_type="TOOLS"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ scn = context.scene
+ layout = self.layout
+ col = layout.column()
+ col.prop(scn, "constraint_vector")
+ col.prop(scn, "random_magnitude")
+
+ col.operator("ba.curve_mangler")
+ col.operator("ba.mesh_mangler")
+ col.separator()
+ col.prop(scn, "mangle_name")
+ col.operator("ba.ani_mangler")
+
+
+IntProperty = bpy.props.IntProperty
+StringProperty = bpy.props.StringProperty
+BoolVectorProperty = bpy.props.BoolVectorProperty
+
+def register():
+ bpy.utils.register_class(AnimanglerOperator)
+ bpy.utils.register_class(MeshManglerOperator)
+ bpy.utils.register_class(CurveManglerOp)
+ bpy.utils.register_class(MangleToolsPanel)
+ scnType = bpy.types.Scene
+
+
+ scnType.constraint_vector = BoolVectorProperty(name="Mangle Constraint",
+ default=(True,True,True),
+ subtype='XYZ',
+ description="Constrains Mangle Direction")
+
+ scnType.random_magnitude = IntProperty( name = "Mangle Severity",
+ default = 10, min = 1, max = 30,
+ description = "Severity of mangling")
+
+ scnType.mangle_name = StringProperty(name="Shape Key Name",
+ default="mangle",
+ description="Name given for mangled shape keys")
+def unregister():
+ bpy.utils.unregister_class(AnimanglerOperator)
+ bpy.utils.unregister_class(MeshManglerOperator)
+ bpy.utils.unregister_class(MangleToolsPanel)
+ bpy.utils.unregister_class(CurveManglerOp)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/object_powerlib.py b/release/scripts/addons_contrib/object_powerlib.py
new file mode 100644
index 0000000..8c5f336
--- /dev/null
+++ b/release/scripts/addons_contrib/object_powerlib.py
@@ -0,0 +1,329 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Powerlib",
+ "description": "Control panel for managing "
+ "groups contained in linked libraries",
+ "author": "Olivier Amrein, Francesco Siddi",
+ "version": (0, 5),
+ "blender": (2, 53, 0),
+ "location": "Properties Panel",
+ "warning": "", # used for warning icon and text in addons panel
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Object/PowerLib",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=31475&group_id=153&atid=467",
+ "category": "3D View"}
+
+import bpy
+from bpy.props import (FloatProperty, BoolProperty,
+FloatVectorProperty, StringProperty, EnumProperty)
+
+# Generic function to toggle across 3 different model resolutions
+def SetProxyResolution(elem,target_resolution):
+
+ obj = bpy.data.objects[elem.name]
+
+ try:
+ dupgroup_name = obj.dupli_group.name
+ except:
+ return
+
+ root = dupgroup_name[:-3]
+ ext = dupgroup_name[-3:]
+ new_group = root + target_resolution
+
+ if ext in {'_hi', '_lo', '_me'}:
+ try:
+ obj.dupli_group = bpy.data.groups[new_group]
+ #print("PowerLib: CHANGE " + str(elem) + " to " + new_group)
+ except:
+ print ("Group %s not found" % new_group.upper())
+
+
+class PowerlibPanel(bpy.types.Panel):
+ bl_label = "Powerlib"
+ bl_idname = "SCENE_PT_powerlib"
+ bl_context = "scene"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+
+ def draw(self, context):
+ layout = self.layout
+ object = bpy.context.active_object
+ scene = context.scene
+ active_subgroup = scene.ActiveSubgroup
+
+ if len(active_subgroup) > 0:
+ ob = bpy.data.objects[active_subgroup]
+ else:
+ ob = bpy.context.active_object
+
+ if ob.dupli_type == 'GROUP':
+ group = ob.dupli_group
+ group_name = group.name # set variable for group toggle
+ group_objs = bpy.data.groups[group.name].objects
+ total_groups = 0
+
+ row = layout.row()
+ row.label(" GROUP: " + group.name, icon = 'GROUP')
+ active_subgroup = scene.ActiveSubgroup
+ if len(active_subgroup) > 0:
+ subgroup = row.operator("powerlib.display_subgroup_content",
+ text="Back to subgroup", icon='BACK')
+ subgroup.item_name = ''
+
+ box = layout.box()
+
+ for elem in group_objs:
+
+ if elem.dupli_group != None:
+ row = box.row()
+ col=row.row()
+
+ total_groups += 1
+
+ if (elem.dupli_type == 'GROUP'):
+ subgroup = col.operator("powerlib.toggle_subgroup",
+ text="", icon='RESTRICT_VIEW_OFF', emboss=False)
+ subgroup.display = "NONE"
+ subgroup.item_name = elem.name
+ subgroup.group_name = group.name
+ col.label(elem.name)
+ else:
+ subgroup = col.operator("powerlib.toggle_subgroup",
+ text="", icon='RESTRICT_VIEW_ON', emboss=False)
+ subgroup.display = "GROUP"
+ subgroup.item_name = elem.name
+ subgroup.group_name = group.name
+ col.label(elem.name)
+
+ if len(bpy.data.groups[elem.dupli_group.name].objects.items()) > 1:
+ subgroup = col.operator("powerlib.display_subgroup_content",
+ text="Explore", icon='GROUP')
+ subgroup.item_name = elem.name
+ else:
+ col.label(text="")
+
+ resolution = str(elem.dupli_group.name)[-3:]
+ if resolution in {'_hi', '_lo', '_me'}:
+ res = resolution[-2:].upper()
+
+ subgroup = col.operator("powerlib.toggle_subgroup_res",
+ text=res, icon='FILE_REFRESH')
+ subgroup.item_name = elem.name
+ subgroup.group_name = group.name
+ else:
+ col.label(text="")
+ else:
+ pass
+
+ if total_groups == 0 :
+ box.label(" No subgroups found in this group",icon="LAYER_USED")
+ resolution = str(object.dupli_group.name)[-3:]
+ if resolution in {'_hi', '_lo', '_me'}:
+
+ res = resolution[-2:].upper()
+
+ subgroup = box.operator("powerlib.toggle_subgroup_res",
+ text=res, icon='FILE_REFRESH')
+ subgroup.item_name = bpy.context.active_object.name
+ subgroup.group_name = group.name
+ else:
+ row = layout.row(align=True)
+ row.label("Total groups: " + str(total_groups))
+ box = layout.box()
+ row = box.row(align=True)
+ group = row.operator("powerlib.toggle_group",
+ text="Show All", icon='RESTRICT_VIEW_OFF')
+ group.display = "showall"
+ group.group_name = group_name
+
+ group = row.operator("powerlib.toggle_group",
+ text="Hide All", icon='RESTRICT_VIEW_ON')
+ group.display = "hideall"
+ group.group_name = group_name
+
+ row = box.row()
+
+ row.label(text="Set all subgroups to: ")
+
+ row = box.row(align=True)
+
+ group = row.operator("powerlib.toggle_group",
+ text="Low", icon='MESH_CIRCLE')
+ group.display = "low"
+ group.group_name = group_name
+
+ group = row.operator("powerlib.toggle_group",
+ text="Medium", icon='MESH_UVSPHERE')
+ group.display = "medium"
+ group.group_name = group_name
+
+ group = row.operator("powerlib.toggle_group",
+ text="High", icon='MESH_ICOSPHERE')
+ group.display = "high"
+ group.group_name = group_name
+
+ else:
+ layout.label(" Select a group")
+
+
+class ToggleSubgroupResolution(bpy.types.Operator):
+ bl_idname = "powerlib.toggle_subgroup_res"
+ bl_label = "Powerlib Toggle Soubgroup Res"
+ bl_description = "Change the resolution of a subgroup"
+ item_name = bpy.props.StringProperty()
+ group_name = bpy.props.StringProperty()
+
+ def execute(self, context):
+
+ group_name = self.group_name
+ item_name = self.item_name
+
+ obj = bpy.data.objects[item_name]
+
+ dupgroup = obj.dupli_group
+ dupgroup_name = obj.dupli_group.name
+
+ root = dupgroup_name[:-2]
+ ext = dupgroup_name[-2:]
+
+ if (root + 'me') in bpy.data.groups:
+ if ext == 'hi':
+ new_group = root + "me"
+ elif ext == 'me':
+ new_group = root + "lo"
+ elif ext == 'lo':
+ new_group = root + "hi"
+ else:
+ new_group = dupgroup # if error, do not change dupligroup
+ else:
+ if ext == 'hi':
+ new_group = root + "lo"
+ elif ext == 'lo':
+ new_group = root + "hi"
+ else:
+ new_group = dupgroup # if error, do not change dupligroup
+
+ if bpy.data.groups[dupgroup_name].library:
+ # link needed object
+ filepath = bpy.data.groups[dupgroup_name].library.filepath
+
+ print(filepath)
+ with bpy.data.libraries.load(filepath,
+ link=True) as (data_from, data_to):
+ data_to.groups.append(new_group)
+
+ try:
+ obj.dupli_group = bpy.data.groups[new_group]
+ print("PowerLib: CHANGE " + str(item_name) + " to " + new_group)
+ except:
+ self.report({'WARNING'}, "Group %s not found" % new_group.upper())
+
+ return {'FINISHED'}
+
+
+class ToggleAllSubgroups(bpy.types.Operator):
+ bl_idname = "powerlib.toggle_group"
+ bl_label = "Powerlib Toggle Group"
+ bl_description = "Toggle a property for all subgroups"
+ display = bpy.props.StringProperty()
+ group_name = bpy.props.StringProperty()
+
+ def execute(self, context):
+
+ display = self.display
+ grp_name = self.group_name
+ group_objs = bpy.data.groups[grp_name].objects
+
+ for elem in group_objs:
+ if display == 'showall':
+ elem.dupli_type = "GROUP"
+ #print("Powerlib: SHOW " + elem.name)
+ elif display == 'hideall':
+ elem.dupli_type = "NONE"
+ #print("Powerlib: HIDE " + elem.name)
+ if display == 'low':
+ #print("Powerlib: ALL LOW " + elem.name)
+ SetProxyResolution(elem,'_lo')
+ elif display == 'medium':
+ #print("Powerlib: ALL MEDIUM " + elem.name)
+ SetProxyResolution(elem,'_me')
+ elif display == 'high':
+ #print("Powerlib: ALL HIGH " + elem.name)
+ SetProxyResolution(elem,'_hi')
+ else:
+ print("nothing")
+
+ return {'FINISHED'}
+
+
+class ToggleSubgroupDisplay(bpy.types.Operator):
+ bl_idname = "powerlib.toggle_subgroup"
+ bl_label = "Powelib Toggle Subgroup"
+ bl_description = "Toggle the display of a subgroup"
+ display = bpy.props.StringProperty()
+ item_name = bpy.props.StringProperty()
+ group_name = bpy.props.StringProperty()
+
+ def execute(self, context):
+
+ display = self.display
+ obj_name = self.item_name
+ grp_name = self.group_name
+
+ print("Powerlib: " + obj_name + " is being set to " + display)
+
+ bpy.data.groups[grp_name].objects[obj_name].dupli_type = display
+ return {'FINISHED'}
+
+
+class DisplaySubgroupContent(bpy.types.Operator):
+ bl_idname = "powerlib.display_subgroup_content"
+ bl_label = "Powerlib Display Subgroup Content"
+ bl_description = "Display the content of a subgroup"
+
+ item_name = bpy.props.StringProperty()
+
+ def execute(self, context):
+ scene = context.scene
+ scene.ActiveSubgroup = self.item_name
+ return {'FINISHED'}
+
+
+def register():
+ bpy.types.Scene.ActiveSubgroup = StringProperty(
+ name="Commit untracked",
+ default="",
+ description="Add untracked files into svn and commit all of them")
+ bpy.utils.register_class(DisplaySubgroupContent)
+ bpy.utils.register_class(ToggleSubgroupResolution)
+ bpy.utils.register_class(ToggleAllSubgroups)
+ bpy.utils.register_class(ToggleSubgroupDisplay)
+ bpy.utils.register_class(PowerlibPanel)
+
+def unregister():
+ del bpy.types.Scene.ActiveSubgroup
+ bpy.utils.unregister_class(DisplaySubgroupContent)
+ bpy.utils.unregister_class(ToggleSubgroupResolution)
+ bpy.utils.unregister_class(ToggleAllSubgroups)
+ bpy.utils.unregister_class(ToggleSubgroupDisplay)
+ bpy.utils.unregister_class(PowerlibPanel)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/object_render_wire.py b/release/scripts/addons_contrib/object_render_wire.py
new file mode 100644
index 0000000..4ffb03f
--- /dev/null
+++ b/release/scripts/addons_contrib/object_render_wire.py
@@ -0,0 +1,421 @@
+# ***** 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 th
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# object_render_wire.py liero, meta-androcto,
+# Yorik van Havre, Alejandro Sierra, Howard Trickey
+# ***** END GPL LICENCE BLOCK *****
+
+bl_info = {
+ "name": "Render Wireframe",
+ "author": "Community",
+ "description": " WireRender & WireSoild modes",
+ "version": (2, 3),
+ "blender": (2, 63, 0),
+ "location": "Object > Render Wireframe",
+ "warning": '',
+ 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts',
+ 'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
+ 'func=detail&aid=26997',
+ 'category': 'Object'}
+
+import bpy, mathutils
+
+cube_faces = [ [0,3,2,1], [5,6,7,4], [0,1,5,4],
+ [7,6,2,3], [2,6,5,1], [0,4,7,3] ]
+cube_normals = [ mathutils.Vector((0,0,-1)),
+ mathutils.Vector((0,0,1)),
+ mathutils.Vector((0,-1,0)),
+ mathutils.Vector((0,1,0)),
+ mathutils.Vector((1,0,0)),
+ mathutils.Vector((-1,0,0)) ]
+
+def create_cube(me, v, d):
+ x = v.co.x
+ y = v.co.y
+ z = v.co.z
+ coords=[ [x-d,y-d,z-d], [x+d,y-d,z-d], [x+d,y+d,z-d], [x-d,y+d,z-d],
+ [x-d,y-d,z+d], [x+d,y-d,z+d], [x+d,y+d,z+d], [x-d,y+d,z+d] ]
+ for coord in coords:
+ me.vertices.add(1)
+ me.vertices[-1].co = mathutils.Vector(coord)
+
+def norm_dot(e, k, fnorm, me):
+ v = me.vertices[e[1]].co - me.vertices[e[0]].co
+ if k == 1:
+ v = -v
+ v.normalize()
+ return v * fnorm
+
+def fill_cube_face(me, index, f):
+ return [index + cube_faces[f][i] for i in range(4)]
+
+# Coords of jth point of face f in cube instance i
+def cube_face_v(me, f, i, j):
+ return me.vertices[i + cube_faces[f][j]].co
+
+def cube_face_center(me, f, i):
+ return 0.5 * (cube_face_v(me, f, i, 0) + \
+ cube_face_v(me, f, i, 2))
+
+# Return distance between points on two faces when
+# each point is projected onto the plane that goes through
+# the face center and is perpendicular to the line
+# through the face centers.
+def projected_dist(me, i1, i2, f1, f2, j1, j2):
+ f1center = cube_face_center(me, f1, i1)
+ f2center = cube_face_center(me, f2, i2)
+ axis_norm = (f2center - f1center).normalized()
+ v1 = cube_face_v(me, f1, i1, j1)
+ v2 = cube_face_v(me, f2, i2, j2)
+ v1proj = v1 - (axis_norm * (v1 - f1center)) * axis_norm
+ v2proj = v2 - (axis_norm * (v2 - f2center)) * axis_norm
+ return (v2proj - v1proj).length
+
+def skin_edges(me, i1, i2, f1, f2):
+ # Connect verts starting at i1 forming cube face f1
+ # to those starting at i2 forming cube face f2.
+ # Need to find best alignment to avoid a twist.
+ shortest_length = 1e6
+ f2_start_index = 0
+ for i in range(4):
+ x = projected_dist(me, i1, i2, f1, f2, 0, i)
+ if x < shortest_length:
+ shortest_length = x
+ f2_start_index = i
+ ans = []
+ j = f2_start_index
+ for i in range(4):
+ fdata = [i1 + cube_faces[f1][i],
+ i2 + cube_faces[f2][j],
+ i2 + cube_faces[f2][(j + 1) % 4],
+ i1 + cube_faces[f1][(i - 1) % 4]]
+ if fdata[3] == 0:
+ fdata = [fdata[3]] + fdata[0:3]
+ ans.extend(fdata)
+ j = (j - 1) % 4
+ return ans
+
+
+# Return map: v -> list of length len(node_normals) where
+# each element of the list is either None (no assignment)
+# or ((v0, v1), 0 or 1) giving an edge and direction that face is assigned to.
+def find_assignment(me, edges, vert_edges, node_normals):
+ nf = len(node_normals)
+ feasible = {}
+ for e in edges:
+ for k in (0, 1):
+ fds = [(f, norm_dot(e, k, node_normals[f], me)) for f in range(nf)]
+ feasible[(e, k)] = [fd for fd in fds if fd[1] > 0.01]
+ assignment = {}
+ for v, ves in vert_edges.items():
+ assignment[v] = best_assignment(ves, feasible, nf)
+ return assignment
+
+def best_assignment(ves, feasible, nf):
+ apartial = [ None ] * nf
+ return best_assign_help(ves, feasible, apartial, 0.0)[0]
+
+def best_assign_help(ves, feasible, apartial, sumpartial):
+ if len(ves) == 0:
+ return (apartial, sumpartial)
+ else:
+ ek0 = ves[0]
+ vesrest = ves[1:]
+ feas = feasible[ek0]
+ bestsum = 0
+ besta = None
+ for (f, d) in feas:
+ if apartial[f] is None:
+ ap = apartial[:]
+ ap[f] = ek0
+ # sum up d**2 to penalize smaller d's more
+ sp = sumpartial + d*d
+ (a, s) = best_assign_help(vesrest, feasible, ap, sp)
+ if s > bestsum:
+ bestsum = s
+ besta = a
+ if besta:
+ return (besta, bestsum)
+ else:
+ # not feasible to assign e0, k0; try to assign rest
+ return best_assign_help(vesrest, feasible, apartial, sumpartial)
+
+def assigned_face(e, assignment):
+ (v0, v1), dir = e
+ a = assignment[v1]
+ for j, ee in enumerate(a):
+ if e == ee:
+ return j
+ return -1
+
+def create_wired_mesh(me2, me, thick):
+ edges = []
+ vert_edges = {}
+ for be in me.edges:
+ if be.select and not be.hide:
+ e = (be.key[0], be.key[1])
+ edges.append(e)
+ for k in (0, 1):
+ if e[k] not in vert_edges:
+ vert_edges[e[k]] = []
+ vert_edges[e[k]].append((e, k))
+
+ assignment = find_assignment(me, edges, vert_edges, cube_normals)
+
+ # Create the geometry
+ n_idx = {}
+ for v in assignment:
+ vpos = me.vertices[v]
+ index = len(me2.vertices)
+ # We need to associate each node with the new geometry
+ n_idx[v] = index
+ # Geometry for the nodes, each one a cube
+ create_cube(me2, vpos, thick)
+
+ # Skin using the new geometry
+ cfaces = []
+ for k, f in assignment.items():
+ # Skin the nodes
+ for i in range(len(cube_faces)):
+ if f[i] is None:
+ cfaces.extend(fill_cube_face(me2, n_idx[k], i))
+ else:
+ (v0, v1), dir = f[i]
+ # only skin between edges in forward direction
+ # to avoid making doubles
+ if dir == 1:
+ # but first make sure other end actually assigned
+ i2 = assigned_face(((v0, v1), 0), assignment)
+ if i2 == -1:
+ cfaces.extend(fill_cube_face(me2, n_idx[k], i))
+ continue
+ i2 = assigned_face(((v0, v1), 1), assignment)
+ if i2 != -1:
+ cfaces.extend(skin_edges(me2, n_idx[v0], n_idx[v1], i, i2))
+ else:
+ # assignment failed for this edge
+ cfaces.extend(fill_cube_face(me2, n_idx[k], i))
+
+ # adding faces to the mesh
+ me2.tessfaces.add(len(cfaces) // 4)
+ me2.tessfaces.foreach_set("vertices_raw", cfaces)
+ me2.update(calc_edges=True)
+
+# Add built in wireframe
+def wire_add(mallas):
+ if mallas:
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.context.scene.objects.active = mallas[0]
+ for o in mallas: o.select = True
+ bpy.ops.object.duplicate()
+ obj, sce = bpy.context.object, bpy.context.scene
+ for mod in obj.modifiers: obj.modifiers.remove(mod)
+ bpy.ops.object.join()
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.wireframe(thickness=0.005)
+ bpy.ops.object.mode_set()
+ for mat in obj.material_slots: bpy.ops.object.material_slot_remove()
+ if 'wire_object' in sce.objects.keys():
+ sce.objects.get('wire_object').data = obj.data
+ sce.objects.get('wire_object').matrix_world = mallas[0].matrix_world
+ sce.objects.unlink(obj)
+ else:
+ obj.name = 'wire_object'
+ obj.data.materials.append(bpy.data.materials.get('mat_wireobj'))
+
+ return{'FINISHED'}
+'''
+class VIEW3D_PT_tools_SolidifyWireframe(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_context = "mesh_edit"
+ bl_label = "Solidify Wireframe"
+
+ def draw(self, context):
+ active_obj = context.active_object
+ layout = self.layout
+ col = layout.column(align=True)
+ col.operator("mesh.solidify_wireframe", text="Solidify")
+ col.prop(context.scene, "swThickness")
+ col.prop(context.scene, "swSelectNew")
+'''
+# a class for your operator
+class SolidifyWireframe(bpy.types.Operator):
+ """Turns the selected edges of a mesh into solid objects"""
+ bl_idname = "mesh.solidify_wireframe"
+ bl_label = "Solidify Wireframe"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def invoke(self, context, event):
+ return self.execute(context)
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return ob and ob.type == 'MESH'
+
+ def execute(self, context):
+ # Get the active object
+ ob_act = context.active_object
+ # getting current edit mode
+ currMode = ob_act.mode
+ # switching to object mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.select_all(action='DESELECT')
+ # getting mesh data
+ mymesh = ob_act.data
+ #getting new mesh
+ newmesh = bpy.data.meshes.new(mymesh.name + " wire")
+ obj = bpy.data.objects.new(newmesh.name,newmesh)
+ obj.location = ob_act.location
+ obj.rotation_euler = ob_act.rotation_euler
+ obj.scale = ob_act.scale
+ context.scene.objects.link(obj)
+ create_wired_mesh(newmesh, mymesh, context.scene.swThickness)
+
+ # restoring original editmode if needed
+ if context.scene.swSelectNew:
+ obj.select = True
+ context.scene.objects.active = obj
+ else:
+ bpy.ops.object.mode_set(mode=currMode)
+
+ # returning after everything is done
+ return {'FINISHED'}
+
+class WireMaterials(bpy.types.Operator):
+ bl_idname = 'scene.wire_render'
+ bl_label = 'Apply Materials'
+ bl_description = 'Set Up Materials for a Wire Render'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ wm = bpy.context.window_manager
+ sce = bpy.context.scene
+
+ if 'mat_clay' not in bpy.data.materials:
+ mat = bpy.data.materials.new('mat_clay')
+ mat.specular_intensity = 0
+ else: mat = bpy.data.materials.get('mat_clay')
+ mat.diffuse_color = wm.col_clay
+ mat.use_shadeless = wm.shadeless_mat
+
+ if 'mat_wire' not in bpy.data.materials:
+ mat = bpy.data.materials.new('mat_wire')
+ mat.specular_intensity = 0
+ mat.use_transparency = True
+ mat.type = 'WIRE'
+ mat.offset_z = 0.05
+ else: mat = bpy.data.materials.get('mat_wire')
+ mat.diffuse_color = wm.col_wire
+ mat.use_shadeless = wm.shadeless_mat
+
+ try: bpy.ops.object.mode_set()
+ except: pass
+
+ if wm.selected_meshes: objetos = bpy.context.selected_objects
+ else: objetos = sce.objects
+
+ mallas = [o for o in objetos if o.type == 'MESH' and o.is_visible(sce) and o.name != 'wire_object']
+
+ for obj in mallas:
+ sce.objects.active = obj
+ print ('procesando >', obj.name)
+ obj.show_wire = wm.wire_view
+ for mat in obj.material_slots:
+ bpy.ops.object.material_slot_remove()
+ obj.data.materials.append(bpy.data.materials.get('mat_wire'))
+ obj.data.materials.append(bpy.data.materials.get('mat_clay'))
+ obj.material_slots.data.active_material_index = 1
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.object.material_slot_assign()
+ bpy.ops.object.mode_set()
+
+ if wm.wire_object:
+ if 'mat_wireobj' not in bpy.data.materials:
+ mat = bpy.data.materials.new('mat_wireobj')
+ mat.specular_intensity = 0
+ else: mat = bpy.data.materials.get('mat_wireobj')
+ mat.diffuse_color = wm.col_wire
+ mat.use_shadeless = wm.shadeless_mat
+ wire_add(mallas)
+
+ return{'FINISHED'}
+
+class PanelWMat(bpy.types.Panel):
+ bl_label = 'Setup Wire Render'
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ wm = bpy.context.window_manager
+ active_obj = context.active_object
+ layout = self.layout
+
+ column = layout.column(align=True)
+ column.prop(wm, 'col_clay')
+ column.prop(wm, 'col_wire')
+ column = layout.column(align=True)
+ column.prop(wm, 'selected_meshes')
+ column.prop(wm, 'shadeless_mat')
+ column.prop(wm, 'wire_view')
+ column.prop(wm, 'wire_object')
+ column.separator()
+ column.operator('scene.wire_render')
+ column.label(text='- - - - - - - - - - - - - - - - - - - - - -')
+ col = layout.column(align=True)
+ column.label(text='Solid WireFrame')
+ layout.operator("mesh.solidify_wireframe", text="Create Mesh Object")
+ col.prop(context.scene, "swThickness")
+ col.prop(context.scene, "swSelectNew")
+bpy.types.WindowManager.selected_meshes = bpy.props.BoolProperty(name='Selected Meshes', default=False, description='Apply materials to Selected Meshes / All Visible Meshes')
+bpy.types.WindowManager.shadeless_mat = bpy.props.BoolProperty(name='Shadeless', default=False, description='Generate Shadeless Materials')
+bpy.types.WindowManager.col_clay = bpy.props.FloatVectorProperty(name='', description='Clay Color', default=(1.0, 0.9, 0.8), min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
+bpy.types.WindowManager.col_wire = bpy.props.FloatVectorProperty(name='', description='Wire Color', default=(0.1 ,0.0 ,0.0), min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
+bpy.types.WindowManager.wire_view = bpy.props.BoolProperty(name='Viewport Wires', default=False, description='Overlay wires display over solid in Viewports')
+bpy.types.WindowManager.wire_object = bpy.props.BoolProperty(name='Create Mesh Object', default=False, description='Add a Wire Object to scene to be able to render wires in Cycles')
+bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness", description="Thickness of the skinned edges", default=0.01)
+bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire", description="If checked, the wire object will be selected after creation", default=True)
+
+# Register the operator
+def solidifyWireframe_menu_func(self, context):
+ self.layout.operator(SolidifyWireframe.bl_idname, text="Solidify Wireframe", icon='PLUGIN')
+
+# Add "Solidify Wireframe" menu to the "Mesh" menu.
+def register():
+ bpy.utils.register_class(WireMaterials)
+ bpy.utils.register_class(PanelWMat)
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness",
+ description="Thickness of the skinned edges",
+ default=0.01)
+ bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire",
+ description="If checked, the wire object will be selected after creation",
+ default=True)
+ bpy.types.VIEW3D_MT_edit_mesh_edges.append(solidifyWireframe_menu_func)
+
+# Remove "Solidify Wireframe" menu entry from the "Mesh" menu.
+def unregister():
+ bpy.utils.unregister_class(WireMaterials)
+ bpy.utils.unregister_class(PanelWMat)
+ bpy.utils.unregister_module(__name__)
+ del bpy.types.Scene.swThickness
+ bpy.types.VIEW3D_MT_edit_mesh_edges.remove(solidifyWireframe_menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/online_mat_lib/__init__.py b/release/scripts/addons_contrib/online_mat_lib/__init__.py
new file mode 100644
index 0000000..3a78fff
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/__init__.py
@@ -0,0 +1,3782 @@
+# ***** 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 3 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, see http://www.gnu.org/licenses/
+# or write to the Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2012 by Peter Cassetta ###
+# All rights reserved.
+#
+# Contact: matlib at peter.cassetta.info ###
+# Information: http://peter.cassetta.info/material-library/ ###
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Peter Cassetta.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+bl_info = {
+ "name": "Online Material Library",
+ "author": "Peter Cassetta",
+ "version": (0, 5),
+ "blender": (2, 63, 0),
+ "location": "Properties > Material > Online Material Library",
+ "description": "Browse and download materials from online CC0 libraries.",
+ "warning": "Beta version",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Material/Online_Material_Library",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=31802",
+ "category": "Material"}
+
+import bpy
+from bpy_extras.io_utils import ExportHelper
+import os.path
+import http.client
+import xml.dom.minidom
+
+library = ""
+library_data = []
+update_data = ["Up-to-date.", ""]
+
+library_enum_items = [("peter.cassetta.info/material-library/release/", "Peter's Library - Release", "Stable library hosted on peter.cassetta.info (Default)"),
+ ("peter.cassetta.info/material-library/testing/", "Peter's Library - Testing", "Continually updated library hosted on peter.cassetta.info (Online only)"),
+ ("bundled", "Bundled Library", "The library bundled with this add-on (Offline only)")]
+bpy.types.Scene.mat_lib_library = bpy.props.EnumProperty(name = "Select library:", items = library_enum_items, description = "Choose a library", options = {'SKIP_SAVE'})
+
+working_mode = "none"
+mat_lib_host = ""
+mat_lib_location = ""
+mat_lib_cached_files = -1
+
+mat_lib_folder = ""
+
+def findLibrary():
+ global mat_lib_folder
+
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ if len(bpy.utils.script_paths()) > 2 and os.path.exists(os.path.join(str(bpy.utils.script_paths()[2]), "addons", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(str(bpy.utils.script_paths()[2]), "addons", "online_mat_lib", "material-library")
+ elif len(bpy.utils.script_paths()) > 1 and os.path.exists(os.path.join(bpy.utils.script_paths()[1], "addons", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(bpy.utils.script_paths()[1], "addons", "online_mat_lib", "material-library")
+ elif os.path.exists(os.path.join(bpy.utils.script_paths()[0], "addons", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(bpy.utils.script_paths()[0], "addons", "online_mat_lib", "material-library")
+ elif os.path.exists(os.path.join(bpy.utils.script_paths()[0], "addons_contrib", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(bpy.utils.script_paths()[0], "addons_contrib", "online_mat_lib", "material-library")
+ else:
+ print("ONLINE MATERIAL LIBRARY -- MAJOR PROBLEM:"\
+ "COULD NOT LOCATE ADD-ON INSTALLATION PATH.")
+ mat_lib_folder = "error"
+ else:
+ if os.path.exists(os.path.join(str(bpy.utils.script_path_pref()), "addons", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(str(bpy.utils.script_path_pref()), "addons", "online_mat_lib", "material-library")
+ elif os.path.exists(os.path.join(bpy.utils.script_path_user(), "addons", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(bpy.utils.script_path_user(), "addons", "online_mat_lib", "material-library")
+ elif os.path.exists(os.path.join(bpy.utils.script_paths()[0], "addons", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(bpy.utils.script_paths()[0], "addons", "online_mat_lib", "material-library")
+ elif os.path.exists(os.path.join(bpy.utils.script_paths()[0], "addons_contrib", "online_mat_lib", "material-library")):
+ mat_lib_folder = os.path.join(bpy.utils.script_paths()[0], "addons_contrib", "online_mat_lib", "material-library")
+ else:
+ print("ONLINE MATERIAL LIBRARY -- MAJOR PROBLEM:"\
+ "COULD NOT LOCATE ADD-ON INSTALLATION PATH.")
+ mat_lib_folder = "error"
+
+findLibrary()
+
+mat_lib_contents = "Please refresh."
+mat_lib_category_filenames = []
+mat_lib_category_types = []
+mat_lib_category_names = []
+mat_lib_categories = 0
+
+category_contents = "None"
+category_name = ""
+category_filename = ""
+category_materials = 0
+
+category_type = "none"
+
+sub_category_contents = "None"
+sub_category_name = ""
+sub_category_filename = ""
+sub_category_categories = 0
+sub_category_names = []
+sub_category_filenames = []
+
+material_names = []
+material_filenames = []
+material_contributors = []
+material_ratings = []
+material_fireflies = []
+material_speeds = []
+material_complexities = []
+material_scripts = []
+material_images = []
+
+material_file_contents = ""
+
+current_material_number = -1
+current_material_cached = False
+current_material_previewed = False
+material_detail_view = "RENDER"
+preview_message = []
+node_message = []
+save_filename = ""
+script_stack = []
+osl_scripts = []
+
+bpy.types.Scene.mat_lib_auto_preview = bpy.props.BoolProperty(name = "Auto-download previews", description = "Automatically download material previews in online mode", default = True, options = {'SKIP_SAVE'})
+bpy.types.Scene.mat_lib_show_osl_materials = bpy.props.BoolProperty(name = "Show OSL materials", description = "Enable to show materials with OSL shading scripts", default = False, options = {'SKIP_SAVE'})
+bpy.types.Scene.mat_lib_show_textured_materials = bpy.props.BoolProperty(name = "Show textured materials", description = "Enable to show materials with image textures", default = True, options = {'SKIP_SAVE'})
+bpy.types.Scene.mat_lib_osl_only_trusted = bpy.props.BoolProperty(name = "Use OSL scripts from trusted sources only", description = "Disable to allow downloading OSL scripts from anywhere on the web (Not recommended)", default = True, options = {'SKIP_SAVE'})
+bpy.types.Scene.mat_lib_images_only_trusted = bpy.props.BoolProperty(name = "Use image textures from trusted sources only", description = "Disable to allow downloading image textures from anywhere on the web (Not recommended)", default = True, options = {'SKIP_SAVE'})
+
+bpy.types.Scene.mat_lib_bcm_write = bpy.props.StringProperty(name = "Text Datablock", description = "Name of text datablock to write .bcm data to", default="bcm_file", options = {'SKIP_SAVE'})
+bpy.types.Scene.mat_lib_bcm_read = bpy.props.StringProperty(name = "Text Datablock", description = "Name of text datablock to read .bcm data from", default="bcm_file", options = {'SKIP_SAVE'})
+bpy.types.Scene.mat_lib_bcm_name = bpy.props.StringProperty(name = "Material Name", description = "Specify a name for the new material", default="Untitled", options = {'SKIP_SAVE'})
+
+bpy.types.Scene.mat_lib_bcm_save_location = bpy.props.StringProperty(name = "Save location", description = "Directory to save .bcm files in", default=mat_lib_folder + os.sep + "my-materials" + os.sep, options = {'SKIP_SAVE'}, subtype="DIR_PATH")
+bpy.types.Scene.mat_lib_bcm_open_location = bpy.props.StringProperty(name = "Open location", description = "Location of .bcm file to open", default=mat_lib_folder + os.sep + "my-materials" + os.sep + "untitled.bcm", options = {'SKIP_SAVE'})
+
+category_enum_items = [("None0", "None", "No category selected")]
+bpy.types.Scene.mat_lib_material_category = bpy.props.EnumProperty(name = "", items = category_enum_items, description = "Choose a category", options = {'SKIP_SAVE'})
+prev_category = "None0"
+
+subcategory_enum_items = [("None0", "None", "No Subcategory Selected")]
+bpy.types.Scene.mat_lib_material_subcategory = bpy.props.EnumProperty(name = "", items = subcategory_enum_items, description = "Choose a subcategory", options = {'SKIP_SAVE'})
+
+class OnlineMaterialLibraryPanel(bpy.types.Panel):
+ """Creates a Panel in the Object properties window"""
+ bl_label = "Online Material Library"
+ bl_idname = "OnlineMaterialLibraryPanel"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "material"
+
+ def draw(self, context):
+ global show_success_message
+ global show_success_message_timeout
+ global current_material_number
+ global mat_lib_contents
+ global prev_category
+ global save_filename
+
+ layout = self.layout
+
+ if context.scene.render.engine == "CYCLES":
+ #Cycles is enabled!
+ row = layout.row()
+
+ if category_type is not "info" and category_type is not "settings" and category_type is not "tools":
+ if mat_lib_contents == "" or mat_lib_contents == "Please refresh.":
+ if mat_lib_folder == "error":
+ row.label(text="ERROR: Could not find installation path!", icon='ERROR')
+ else:
+ #Material Library Contents variable is empty -- show welcome message
+ row.label(text="Online Material Library Add-on -- Version 0.5", icon='SMOOTH')
+
+ row = layout.row()
+ rowcol = row.column(align=True)
+ rowcol.alignment = 'EXPAND'
+ rowcol.prop(context.scene, "mat_lib_library", text="")
+
+ rowcolrow = rowcol.row(align=True)
+ rowcolrow.alignment = 'EXPAND'
+ if "bundled" not in context.scene.mat_lib_library:
+ rowcolrow.operator("material.libraryconnect", text="Connect", icon='WORLD').mode = "online"
+ if "testing" not in context.scene.mat_lib_library:
+ rowcolrow.operator("material.libraryconnect", text="Work Offline", icon='DISK_DRIVE').mode = "offline"
+
+ elif working_mode is not "none":
+ #We have a valid material library
+ row = layout.row(align=True)
+ row.alignment = 'EXPAND'
+ row.prop(bpy.context.scene, "mat_lib_material_category")
+ else:
+ #Could not retrive a valid material library
+ row.label(text="Could not retrieve material library.", icon='CANCEL')
+ row = layout.row()
+ row.label(text=str(mat_lib_contents))
+ row = layout.row()
+ row.label(text="..." + str(mat_lib_contents)[-50:])
+
+ row = layout.row()
+ rowcol = row.column(align=True)
+ rowcol.alignment = 'EXPAND'
+ rowcol.prop(context.scene, "mat_lib_library", text="")
+
+ rowcolrow = rowcol.row(align=True)
+ rowcolrow.alignment = 'EXPAND'
+ if "bundled" not in context.scene.mat_lib_library:
+ rowcolrow.operator("material.libraryconnect", text="Attempt Reconnect", icon='WORLD').mode = "online"
+ if "testing" not in context.scene.mat_lib_library:
+ rowcolrow.operator("material.libraryconnect", text="Work Offline", icon='DISK_DRIVE').mode = "offline"
+
+ #Here we check if the user has changed the category, if so, update.
+ if prev_category != bpy.context.scene.mat_lib_material_category:
+ prev_category = bpy.context.scene.mat_lib_material_category
+ libraryCategoryUpdate()
+
+ if category_type == "none":
+ #Not browsing category
+ if working_mode is not "none":
+ row = layout.row()
+ rowcol = row.column(align=True)
+ rowcol.alignment = 'EXPAND'
+ rowcol.prop(context.scene, "mat_lib_library", text="")
+
+ rowcolrow = rowcol.row(align=True)
+ rowcolrow.alignment = 'EXPAND'
+ if "bundled" not in context.scene.mat_lib_library:
+ if working_mode == "online":
+ rowcolrow.operator("material.libraryconnect", text="Reconnect", icon='WORLD').mode = "online"
+ else:
+ rowcolrow.operator("material.libraryconnect", text="Connect", icon='WORLD').mode = "online"
+ if "testing" not in context.scene.mat_lib_library:
+ if working_mode == "offline":
+ rowcolrow.operator("material.libraryconnect", text="Reload Library", icon='DISK_DRIVE').mode = "offline"
+ else:
+ rowcolrow.operator("material.libraryconnect", text="Work Offline", icon='DISK_DRIVE').mode = "offline"
+
+ row = layout.row(align=True)
+ row.alignment = 'EXPAND'
+ row.operator("material.libraryinfo", text="Info", icon='INFO')
+ row.operator("material.librarytools", text="Tools", icon='MODIFIER')
+ row.operator("material.librarysettings", text="Settings", icon='SETTINGS')
+
+ if "Up-to-date." not in update_data[0]:
+ row = layout.row()
+ row.label(text=update_data[0])
+ row.operator("wm.url_open", text="Get latest version", icon='WORLD').url = update_data[1]
+
+ elif category_type == "info":
+ row.label(text="Add-on Info", icon='INFO')
+ row.operator("material.libraryhome", text="", icon='LOOP_BACK')
+
+ row = layout.row()
+ row.operator("wm.url_open", text="All materials are CC0 - learn more.", emboss=False).url = "http://creativecommons.org/publicdomain/zero/1.0/"
+
+ row = layout.row()
+ row.operator("wm.url_open", text="Material previews generated with B.M.P.S.", emboss=False).url = "https://svn.blender.org/svnroot/bf-blender/trunk/lib/tests/rendering/cycles/blend_files/bmps.blend"
+ row = layout.row()
+ row.operator("wm.url_open", text="B.M.P.S. created by Robin \"tuqueque\" Marín", emboss=False).url = "http://blenderartists.org/forum/showthread.php?151903-b.m.p.s.-1.5!"
+
+ elif category_type == "settings":
+ row.label(text="Library Settings", icon='SETTINGS')
+ row.operator("material.libraryhome", text="", icon='LOOP_BACK')
+
+ row = layout.row()
+ row.prop(bpy.context.scene, "mat_lib_auto_preview")
+ row = layout.row()
+ row.prop(bpy.context.scene, "mat_lib_osl_only_trusted")
+ row = layout.row()
+ row.prop(bpy.context.scene, "mat_lib_images_only_trusted")
+
+ row = layout.row()
+ row.label(text="Cached data for active library:")
+
+ row = layout.row()
+ if mat_lib_cached_files == 0:
+ row.label(text="No cached files.")
+ elif mat_lib_cached_files == -2:
+ row.label(text="The Bundled library contains no cached files.")
+ elif mat_lib_cached_files == 1:
+ row.label(text="1 cached file.")
+ row.operator("material.libraryclearcache", text="Clear Cache", icon='CANCEL')
+ elif mat_lib_cached_files != -1:
+ row.label(text=str(mat_lib_cached_files) + " cached files.")
+ row.operator("material.libraryclearcache", text="Clear Cache", icon='CANCEL')
+ else:
+ row.label(text="Please select a library first.", icon="ERROR")
+
+ elif category_type == "tools":
+ row.label(text="Material Tools", icon='MODIFIER')
+ row.operator("material.libraryhome", text="", icon='LOOP_BACK')
+
+ row = layout.row()
+ row.label(text="Write material data to text as .bcm:")
+
+ row = layout.row(align=True)
+ row.alignment = 'EXPAND'
+ row.prop(bpy.context.scene, "mat_lib_bcm_write", text="", icon="TEXT")
+ row.operator("material.libraryconvert", text="Write to text", icon='MATERIAL_DATA')
+
+ row = layout.row()
+ row.label(text="Save material(s) as .bcm files:")
+
+ row = layout.row()
+ col = row.column(align=True)
+ col.alignment = 'EXPAND'
+ colrow = col.row()
+ colrow.prop(context.scene, "mat_lib_bcm_save_location", text="")
+ colrow = col.row(align=True)
+ colrow.alignment = 'EXPAND'
+ colrow.operator("material.libraryconvert", text="Save active", icon='DISK_DRIVE').save_location = context.scene.mat_lib_bcm_save_location
+ save_button = colrow.operator("material.libraryconvert", text="Save all materials", icon='DISK_DRIVE')
+ save_button.save_location = context.scene.mat_lib_bcm_save_location
+ save_button.all_materials = True
+
+ row = layout.row()
+ row.label(text="Open a local .bcm file:")
+
+ row = layout.row()
+ col = row.column(align=True)
+ col.alignment = 'EXPAND'
+ colrow = col.row()
+ colrow.prop(context.scene, "mat_lib_bcm_open_location", text="")
+ colrow.operator("buttons.file_browse", text="", icon='FILESEL').relative_path = False
+ colrow = col.row(align=True)
+ colrow.alignment = 'EXPAND'
+ colrow.operator("material.libraryadd", text="Add to materials", icon='ZOOMIN').open_location = context.scene.mat_lib_bcm_open_location
+ colrow.operator("material.libraryapply", text="Apply to active", icon='PASTEDOWN').open_location = context.scene.mat_lib_bcm_open_location
+
+ row = layout.row()
+ row.label(text="Read .bcm data in a text block to a material:")
+
+ row = layout.row()
+ col = row.column(align=True)
+ col.alignment = 'EXPAND'
+ colrow = col.row()
+ colrow.prop(context.scene, "mat_lib_bcm_read", text="", icon='TEXT')
+ colrow = col.row()
+ colrow.prop(context.scene, "mat_lib_bcm_name", text="", icon='MATERIAL')
+ colrow = col.row(align=True)
+ colrow.alignment = 'EXPAND'
+ colrow.operator("material.libraryadd", text="Add to materials", icon='ZOOMIN').text_block = context.scene.mat_lib_bcm_read
+ colrow.operator("material.libraryapply", text="Apply to active", icon='PASTEDOWN').text_block = context.scene.mat_lib_bcm_read
+
+ elif category_type == "category":
+ #Browsing category - show materials
+ row = layout.row()
+ matwrap = row.box()
+ i = 0
+ while i < category_materials:
+ if i == current_material_number:
+ matwraprow = matwrap.row()
+ matwrapbox = matwraprow.box()
+ matwrapboxrow = matwrapbox.row()
+ matwrapboxrow.operator("material.libraryviewmaterial", text=material_names[i], icon='MATERIAL', emboss=False).material = i
+ matwrapboxrowcol = matwrapboxrow.column()
+ matwrapboxrowcolrow = matwrapboxrowcol.row()
+ matwrapboxrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapboxrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapboxrowcol = matwrapboxrow.column()
+ matwrapboxrowcolrow = matwrapboxrowcol.row()
+ matwrapboxrowcolrowsplit = matwrapboxrowcolrow.split(percentage=0.8)
+ matwrapboxrowcolrowsplitrow = matwrapboxrowcolrowsplit.row()
+
+ #Ratings
+ if material_ratings[i] == 0:
+ matwrapboxrowcolrowsplitrow.operator("material.libraryviewmaterial", text="Unrated", emboss=False).material = i
+ else:
+ e = 0
+ while e < material_ratings[i]:
+ matwrapboxrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_ON', emboss=False).material = i
+ e = e + 1
+
+ if material_ratings[i] is not 5:
+ e = 0
+ while e < (5 - material_ratings[i]):
+ matwrapboxrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_OFF', emboss=False).material = i
+ e = e + 1
+ else:
+ matwraprow = matwrap.row()
+ matwrapcol = matwraprow.column()
+ matwrapcolrow = matwrapcol.row()
+ matwrapcolrow.operator("material.libraryviewmaterial", text=material_names[i], icon='MATERIAL', emboss=False).material = i
+ matwrapcolrowcol = matwrapcolrow.column()
+ matwrapcolrowcolrow = matwrapcolrowcol.row()
+ matwrapcolrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapcolrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapcolrowcol = matwrapcolrow.column()
+ matwrapcolrowcolrow = matwrapcolrowcol.row()
+ matwrapcolrowcolrowsplit = matwrapcolrowcolrow.split(percentage=0.8)
+ matwrapcolrowcolrowsplitrow = matwrapcolrowcolrowsplit.row()
+
+ #Ratings
+ if material_ratings[i] == 0:
+ matwrapcolrowcolrowsplitrow.operator("material.libraryviewmaterial", text="Unrated", emboss=False).material = i
+ else:
+ e = 0
+ while e < material_ratings[i]:
+ matwrapcolrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_ON', emboss=False).material = i
+ e = e + 1
+
+ if material_ratings[i] is not 5:
+ e = 0
+ while e < (5 - material_ratings[i]):
+ matwrapcolrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_OFF', emboss=False).material = i
+ e = e + 1
+ i = i + 1
+
+ if current_material_number is not -1:
+ #Display selected material's info
+ row = layout.row()
+ infobox = row.box()
+ inforow = infobox.row()
+
+ #Material name
+ inforow.label(text=(material_names[current_material_number]))
+
+ #Preview download button
+ if current_material_previewed == False:
+ preview_button = inforow.operator("material.librarypreview", text="", icon='COLOR', emboss=False)
+ preview_button.name = material_names[current_material_number]
+ preview_button.filename = material_filenames[current_material_number]
+
+ if library == "release":
+ #Cache indicator/button
+ if current_material_cached:
+ inforow.label(text="", icon="SAVE_COPY")
+ else:
+ inforow.operator("material.librarycache", text="", icon="LONGDISPLAY", emboss=False).filename = material_filenames[current_material_number]
+
+ #Close button
+ inforow.operator("material.libraryviewmaterial", text="", icon='PANEL_CLOSE').material = -1
+
+ #inforow = infobox.row()
+ inforowsplit = infobox.split(percentage=0.5)
+
+ #Display a preview
+ if bpy.data.textures.find("mat_lib_preview_texture") == -1:
+ bpy.data.textures.new("mat_lib_preview_texture", "IMAGE")
+ preview_texture = bpy.data.textures["mat_lib_preview_texture"]
+ inforowcol = inforowsplit.column()
+
+ if material_contributors[current_material_number] != "Unknown" and material_contributors[current_material_number] != "Anonymous":
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.label(text="By %s." % material_contributors[current_material_number])
+ else:
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.label(text="Author unknown.")
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.template_preview(preview_texture)
+ else:
+ preview_texture = bpy.data.textures['mat_lib_preview_texture']
+ inforowcol = inforowsplit.column()
+ if material_contributors[current_material_number] != "Unknown" and material_contributors[current_material_number] != "Anonymous":
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.label(text="By %s." % material_contributors[current_material_number])
+ else:
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.label(text="Author unknown.")
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.template_preview(preview_texture)
+
+ inforowcol = inforowsplit.column()
+ inforowcolrow = inforowcol.row()
+ inforowcolcol = inforowcol.column(align=True)
+ inforowcolcol.alignment = 'EXPAND'
+ inforowcolcolrow = inforowcolcol.row()
+ if material_detail_view == 'RENDER':
+ if material_fireflies[current_material_number] == "high":
+ inforowcolcolrow.label(text="Firefly Level: High")
+ inforowcolcolrow.label(text="", icon='PARTICLES')
+ elif material_fireflies[current_material_number] == "medium":
+ inforowcolcolrow.label(text="Firefly Level: Medium")
+ inforowcolcolrow.label(text="", icon='MOD_PARTICLES')
+ else:
+ inforowcolcolrow.label(text="Firefly Level: Low")
+ inforowcolcolrow = inforowcolcol.row()
+
+ if material_complexities[current_material_number] == "simple":
+ inforowcolcolrow.label(text="Complexity: Simple")
+ elif material_complexities[current_material_number] == "intermediate":
+ inforowcolcolrow.label(text="Complexity: Intermediate")
+ elif material_complexities[current_material_number] == "complex":
+ inforowcolcolrow.label(text="Complexity: Complex")
+ inforowcolcolrow = inforowcolcol.row()
+
+ if material_speeds[current_material_number] == "slow":
+ inforowcolcolrow.label(text="Render Speed: Slow")
+ inforowcolcolrow.label(text="", icon='PREVIEW_RANGE')
+ elif material_speeds[current_material_number] == "fair":
+ inforowcolcolrow.label(text="Render Speed: Fair")
+ inforowcolcolrow.label(text="", icon='TIME')
+ else:
+ inforowcolcolrow.label(text="Render Speed: Good")
+ inforowcolcolrow = inforowcolcol.row()
+ details = inforowcolcolrow.row(align=True)
+ details.alignment = 'RIGHT'
+ detailshidden = details.row()
+ detailshidden.enabled = False
+ detailshidden.operator("material.librarydetailview", text="", icon='PLAY_REVERSE').mode = "PREVIOUS"
+ details.operator("material.librarydetailview", text="", icon='PLAY').mode = "NEXT"
+ elif material_detail_view == "DATA":
+ if material_scripts[current_material_number] == "0":
+ inforowcolcolrow.label(text="OSL Scripts: 0")
+ else:
+ inforowcolcolrow.label(text="OSL Scripts: %s" % material_scripts[current_material_number])
+ inforowcolcolrow.label(text="", icon='TEXT')
+ inforowcolcolrow = inforowcolcol.row()
+
+ if material_images[current_material_number] == "0":
+ inforowcolcolrow.label(text="Images: 0")
+ else:
+ inforowcolcolrow.label(text="Images: %s" % material_images[current_material_number])
+ inforowcolcolrow.label(text="", icon='IMAGE_RGB')
+
+ inforowcolcolrow = inforowcolcol.row()
+ inforowcolcolrow.label(text=" ")
+
+ inforowcolcolrow = inforowcolcol.row()
+ details = inforowcolcolrow.row(align=True)
+ details.alignment = 'RIGHT'
+ details.operator("material.librarydetailview", text="", icon='PLAY_REVERSE').mode = "PREVIOUS"
+ detailshidden = details.row()
+ detailshidden.enabled = False
+ detailshidden.operator("material.librarydetailview", text="", icon='PLAY').mode = "NEXT"
+
+ inforowcolcolcol = inforowcolcol.column(align=True)
+ inforowcolcolcol.alignment = 'EXPAND'
+ functions = inforowcolcolcol.row()
+ #Display "Add" button
+ mat_button = functions.operator("material.libraryadd", text="Add to materials", icon='ZOOMIN')
+ mat_button.mat_name = material_names[current_material_number]
+ mat_button.filename = material_filenames[current_material_number]
+ functions = inforowcolcolcol.row()
+
+ #Display "Apply" button
+ mat_button = functions.operator("material.libraryapply", text="Apply to active", icon='PASTEDOWN')
+ mat_button.mat_name = material_names[current_material_number]
+ mat_button.filename = material_filenames[current_material_number]
+ functions = inforowcolcolcol.row()
+
+ #Display "Save" button
+ mat_button = functions.operator("material.librarysave", text="Save as...", icon='DISK_DRIVE')
+ mat_button.filepath = mat_lib_folder + os.sep + "my-materials" + os.sep + material_filenames[current_material_number] + ".bcm"
+ mat_button.filename = material_filenames[current_material_number]
+ save_filename = material_filenames[current_material_number]
+
+ elif category_type == "subcategory":
+ #Browsing subcategory - show materials
+ row = layout.row()
+ matwrap = row.box()
+ i = 0
+ while i < category_materials:
+ if (i == current_material_number):
+ matwraprow = matwrap.row()
+ matwrapbox = matwraprow.box()
+ matwrapboxrow = matwrapbox.row()
+ matwrapboxrow.operator("material.libraryviewmaterial", text=material_names[i], icon='MATERIAL', emboss=False).material = i
+ matwrapboxrowcol = matwrapboxrow.column()
+ matwrapboxrowcolrow = matwrapboxrowcol.row()
+ matwrapboxrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapboxrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapboxrowcol = matwrapboxrow.column()
+ matwrapboxrowcolrow = matwrapboxrowcol.row()
+ matwrapboxrowcolrowsplit = matwrapboxrowcolrow.split(percentage=0.8)
+ matwrapboxrowcolrowsplitrow = matwrapboxrowcolrowsplit.row()
+
+ #Ratings
+ e = 0
+ while e < material_ratings[i]:
+ matwrapboxrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_ON', emboss=False).material = i
+ e = e + 1
+
+ if material_ratings[i] is not 5:
+ e = 0
+ while e < (5 - material_ratings[i]):
+ matwrapboxrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_OFF', emboss=False).material = i
+ e = e + 1
+ else:
+ matwraprow = matwrap.row()
+ matwrapcol = matwraprow.column()
+ matwrapcolrow = matwrapcol.row()
+ matwrapcolrow.operator("material.libraryviewmaterial", text=material_names[i], icon='MATERIAL', emboss=False).material = i
+ matwrapcolrowcol = matwrapcolrow.column()
+ matwrapcolrowcolrow = matwrapcolrowcol.row()
+ matwrapcolrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapcolrowcolrow.operator("material.libraryviewmaterial", text="", icon='BLANK1', emboss=False).material = i
+ matwrapcolrowcol = matwrapcolrow.column()
+ matwrapcolrowcolrow = matwrapcolrowcol.row()
+ matwrapcolrowcolrowsplit = matwrapcolrowcolrow.split(percentage=0.8)
+ matwrapcolrowcolrowsplitrow = matwrapcolrowcolrowsplit.row()
+
+ #Ratings
+ e = 0
+ while e < material_ratings[i]:
+ matwrapcolrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_ON', emboss=False).material = i
+ e = e + 1
+
+ if material_ratings[i] is not 5:
+ e = 0
+ while e < (5 - material_ratings[i]):
+ matwrapcolrowcolrowsplitrow.operator("material.libraryviewmaterial", text="", icon='SOLO_OFF', emboss=False).material = i
+ e = e + 1
+ i = i + 1
+
+ if current_material_number is not -1:
+ #Display selected material's info
+ row = layout.row()
+ infobox = row.box()
+ inforow = infobox.row()
+
+ inforow.label(text=material_names[current_material_number])
+ if bpy.context.scene.mat_lib_auto_preview == False:
+ mat_button = inforow.operator("material.librarypreview", text="", icon='IMAGE_COL')
+ mat_button.name = material_names[current_material_number]
+ mat_button.filename = material_filenames[current_material_number]
+ inforow.operator("material.viewmaterial", text="", icon='PANEL_CLOSE').material = -1
+
+ inforow = infobox.row()
+
+ #Display a preview
+ if bpy.data.textures.find("mat_lib_preview_texture") == -1:
+ bpy.data.textures.new("mat_lib_preview_texture", "IMAGE")
+ preview_texture = bpy.data.textures["mat_lib_preview_texture"]
+ inforowcol = inforow.column(align=True)
+ inforowcol.alignment = 'EXPAND'
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.operator("material.librarypreview", text="Preview Material", icon='IMAGE_COL')
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.template_preview(preview_texture)
+ else:
+ preview_texture = bpy.data.textures['mat_lib_preview_texture']
+ inforowcol = inforow.column(align=True)
+ inforowcol.alignment = 'EXPAND'
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.operator("material.librarypreview", text="Preview Material", icon='IMAGE_COL')
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.template_preview(preview_texture)
+
+ inforowcol = inforow.column()
+ inforowcolrow = inforowcol.row()
+ if bpy.data.materials.find(material_names[current_material_number]) is not -1:
+ inforowcolrow.label(text="Material exists", icon='ERROR')
+ if material_contributors[current_material_number] == "Unknown" or material_contributors[current_material_number] == "Anonymous":
+ inforowcolrow = inforowcol.row()
+ else:
+ inforowcolrow = inforowcol.row()
+ inforowcolrow.label(text="By %s." % material_contributors[current_material_number])
+ inforowcolrow = inforowcol.row()
+
+ if bpy.data.materials.find(material_names[current_material_number]) is not -1:
+ inforowcolrow.label(text="\"Add\" will overwrite.")
+ inforowcolcol = inforowcol.column(align=True)
+ inforowcolcol.alignment = 'EXPAND'
+
+
+ #Display "Add" or "Overwrite" button
+ mat_button = inforowcolcol.operator("material.libraryadd", text="Add to materials", icon='ZOOMIN')
+ mat_button.name = material_names[current_material_number]
+ mat_button.filename = material_filenames[current_material_number]
+
+ #Display "Paste" button
+ mat_button = inforowcolcol.operator("material.libraryapply", text="Apply to active", icon='PASTEDOWN')
+ mat_button.name = bpy.context.object.active_material.name
+ mat_button.filename = material_filenames[current_material_number]
+
+ #Display "Save" button
+ mat_button = inforowcolcol.operator("material.librarysave", text="Save to disk", icon='DISK_DRIVE')
+ mat_button.name = bpy.context.object.active_material.name
+ mat_button.filename = material_filenames[current_material_number]
+ save_filename = material_filenames[current_material_number]
+ else:
+ #Dude, you gotta switch to Cycles to use this.
+ row = layout.row()
+ row.label(text="Sorry, Cycles only at the moment.",icon='ERROR')
+
+class libraryCategory:
+ def __init__(self, title, folder):
+ self.title = title
+ self.folder = folder
+ self.materials = []
+
+class libraryMaterial:
+ def __init__(self, name, href, contrib, stars, fireflies, speed, complexity, scripts, images):
+ self.name = name
+ self.href = href
+ self.contrib = contrib
+ self.stars = stars
+ self.fireflies = fireflies
+ self.speed = speed
+ self.complexity = complexity
+ self.scripts = scripts
+ self.images = images
+
+def handleCategories(categories):
+ for index, category in enumerate(categories):
+ handleCategory(category, index)
+
+def handleCategory(category, index):
+ if 'addon' in category.attributes:
+ needed_version = float(category.attributes['addon'].value)
+ this_version = bl_info["version"][0] + (bl_info["version"][1] / 10.0)
+
+ #Check this addon's compatibility with this category
+ if needed_version > this_version:
+ print('\n\n-Category "' + category.attributes['title'].value + '" not used; its materials are for a newer version of this add-on.')
+ return
+
+ if 'bl' in category.attributes:
+ bl_version = bpy.app.version[0] + (bpy.app.version[1] / 100)
+
+ #Check Blender's compatibility with this category
+ if category.attributes['bl'].value[-1] == "-":
+ #This option is for if Blender's compatiblity
+ #with a category started only with a specific
+ #version, but has not yet ended; this will
+ #look like the following: bl="2.64-"
+ bl_lower = float(category.attributes['bl'].value[:-1])
+ if bl_lower > bl_version:
+ print('\n\n-Category "' + category.attributes['title'].value + '" was not used; its materials are not compatible with this version of Blender.')
+ return
+
+ elif category.attributes['bl'].value[0] == "-":
+ #This option is for if Blender's compatiblity
+ #with a category ended at some point, and will
+ #look like the following: bl="-2.73"
+ bl_upper = float(category.attributes['bl'].value[1:])
+ if bl_upper < bl_version:
+ print('\n\n-Category "' + category.attributes['title'].value + '" was not used; its materials are not compatible with this version of Blender.')
+ return
+
+ else:
+ #This option is for if Blender's compatiblity
+ #with a category started with a certain version,
+ #then ended with another; it will look
+ #like the following: bl="2.64-2.73"
+ bl_lower = float(category.attributes['bl'].value.split('-')[0])
+ bl_upper = float(category.attributes['bl'].value.split('-')[1])
+ if bl_upper < bl_version:
+ print('\n\n-Category "' + category.attributes['title'].value + '" was not used; its materials are not compatible with this version of Blender.')
+ return
+ elif bl_lower > bl_version:
+ print('\n\n-Category "' + category.attributes['title'].value + '" was not used; its materials are not compatible with this version of Blender.')
+ return
+
+ if library is not "bundled":
+ if not os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category.attributes['folder'].value):
+ print("Folder \"/" + category.attributes['folder'].value + "/\" does not exist; creating now.")
+ if library == "composite":
+ os.mkdir(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category.attributes['folder'].value)
+ else:
+ os.mkdir(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category.attributes['folder'].value)
+
+ if 'remove' in category.attributes:
+ if library == "composite":
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category.attributes['folder'].value):
+ for the_file in os.listdir(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category.attributes['folder'].value):
+ file_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category.attributes['folder'].value + os.sep + the_file
+ if os.path.isfile(file_path):
+ os.remove(file_path)
+ elif os.path.isdir(file_path):
+ for sub_file in os.listdir(file_path):
+ if os.path.isfile(file_path + sub_file):
+ os.remove(file_path + sub_file)
+ os.rmdir(file_path)
+ os.rmdir(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category.attributes['folder'].value)
+ else:
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category.attributes['folder'].value):
+ for the_file in os.listdir(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category.attributes['folder'].value):
+ file_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category.attributes['folder'].value + os.sep + the_file
+ if os.path.isfile(file_path):
+ os.remove(file_path)
+ elif os.path.isdir(file_path):
+ for sub_file in os.listdir(file_path):
+ if os.path.isfile(file_path + sub_file):
+ os.remove(file_path + sub_file)
+ os.rmdir(file_path)
+ os.rmdir(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category.attributes['folder'].value)
+ return
+
+ print ('\n\n-Category "' + category.attributes['title'].value + '"; located in folder "/' + category.attributes['folder'].value + '/".')
+ library_data.append(libraryCategory(category.attributes['title'].value, category.attributes['folder'].value))
+ handleMaterials(category.getElementsByTagName("material"), index)
+
+def handleMaterials(materials, index):
+ for material in materials:
+ handleMaterial(material, index)
+
+def handleMaterial(material, index):
+ if 'addon' in material.attributes:
+ needed_version = float(material.attributes['addon'].value)
+ this_version = bl_info["version"][0] + (bl_info["version"][1] / 10.0)
+
+ #Check this addon's compatibility with this material
+ if needed_version > this_version:
+ print('\n -Material "' + material.attributes['name'].value + '" was not used, and is for a newer version of this add-on.')
+ return
+
+ if 'bl' in material.attributes:
+ bl_version = bpy.app.version[0] + (bpy.app.version[1] / 100)
+
+ #Check Blender's compatibility with this material
+ if material.attributes['bl'].value[-1] == "-":
+ #This option is for if Blender's compatiblity
+ #with a material started only with a specific
+ #version, but has not yet ended; this will
+ #look like the following: bl="2.64-"
+ bl_lower = float(material.attributes['bl'].value[:-1])
+ if bl_lower > bl_version:
+ print('\n -Material "' + material.attributes['name'].value + '" was not used, and is not compatible with this version of Blender.')
+ return
+
+ elif material.attributes['bl'].value[0] == "-":
+ #This option is for if Blender's compatiblity
+ #with a material ended at some point, and will
+ #look like the following: bl="-2.73"
+ bl_upper = float(material.attributes['bl'].value[1:])
+ if bl_upper < bl_version:
+ print('\n -Material "' + material.attributes['name'].value + '" was not used, and is not compatible with this version of Blender.')
+ return
+
+ else:
+ #This option is for if Blender's compatiblity
+ #with a material started with a certain version,
+ #then ended with another; it will
+ #look like the following: bl="2.64-2.73"
+ bl_lower = float(material.attributes['bl'].value.split('-')[0])
+ bl_upper = float(material.attributes['bl'].value.split('-')[1])
+ if bl_upper < bl_version:
+ print('\n -Material "' + material.attributes['name'].value + '" was not used, and is not compatible with this version of Blender.')
+ return
+ elif bl_lower > bl_version:
+ print('\n -Material "' + material.attributes['name'].value + '" was not used, and is not compatible with this version of Blender.')
+ return
+
+ if 'by' in material.attributes:
+ contributor = material.attributes['by'].value
+ else:
+ contributor = "Unknown"
+
+ if 'stars' in material.attributes:
+ stars = material.attributes['stars'].value
+ else:
+ stars = '0'
+
+ if 'fireflies' in material.attributes:
+ fireflies = material.attributes['fireflies'].value
+ else:
+ fireflies = 'low'
+
+ if 'speed' in material.attributes:
+ speed = material.attributes['speed'].value
+ else:
+ speed = 'good'
+
+ if 'complexity' in material.attributes:
+ complexity = material.attributes['complexity'].value
+ else:
+ complexity = 'simple'
+
+ if 'scripts' in material.attributes:
+ scripts = material.attributes['scripts'].value
+ else:
+ scripts = '0'
+
+ if 'images' in material.attributes:
+ images = material.attributes['images'].value
+ else:
+ images = '0'
+
+ library_data[index].materials.append(
+ libraryMaterial(
+ material.attributes['name'].value,
+ material.attributes['href'].value,
+ contributor,
+ int(stars),
+ fireflies,
+ speed,
+ complexity,
+ scripts,
+ images))
+ print ('\n -Material "' +
+ material.attributes['name'].value +
+ '"\n -Filename: "' +
+ material.attributes['href'].value +
+ '.bcm"\n -Rating: ' + stars +
+ ' stars\n -Contributed by "' +
+ contributor + '"')
+
+class LibraryConnect(bpy.types.Operator):
+ '''Connect to the material library'''
+ bl_idname = "material.libraryconnect"
+ bl_label = "Connect to the material library"
+ mode = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global library_data
+ global library
+ global update_data
+
+ global mat_lib_contents
+ global mat_lib_categories
+ global mat_lib_category_names
+ global mat_lib_category_types
+ global mat_lib_category_filenames
+
+ global category_enum_items
+ global subcategory_enum_items
+
+ global show_success_message
+ global show_success_message_timeout
+
+ global prev_category
+ global mat_lib_host
+ global mat_lib_location
+ global working_mode
+
+ findLibrary()
+
+ if self.mode == "online":
+ mat_lib_host = context.scene.mat_lib_library[:context.scene.mat_lib_library.index("/")]
+ mat_lib_location = context.scene.mat_lib_library[(context.scene.mat_lib_library.index(mat_lib_host) + len(mat_lib_host)):]
+ print(mat_lib_host)
+ print(mat_lib_location)
+ elif "bundled" not in context.scene.mat_lib_library:
+ mat_lib_host = context.scene.mat_lib_library[:context.scene.mat_lib_library.index("/")]
+
+ #Pre-create preview image
+ if not os.path.exists(mat_lib_folder + os.sep + "mat_lib_preview_image.jpg"):
+ f = open(mat_lib_folder + os.sep + "mat_lib_preview_image.jpg", 'w+b')
+ f.close()
+
+ if self.mode == "online":
+ #Connect and download
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/index.xml")
+
+ if "release" in context.scene.mat_lib_library:
+ response = connection.getresponse().read()
+
+ #Cache the index.xml file for offline use
+ library_file = open(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "index.xml"), mode="w+b")
+ library_file.write(response)
+ library_file.close()
+
+ #Create /textures/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "textures")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "textures"))
+
+ #Create /scripts/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "scripts")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "scripts"))
+ library = "release"
+ elif "testing" in context.scene.mat_lib_library:
+ response = connection.getresponse().read()
+
+ #Create /textures/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "testing", "cycles", "textures")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "testing", "cycles", "textures"))
+
+ #Create /scripts/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "testing", "cycles", "scripts")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "testing", "cycles", "scripts"))
+ library = "testing"
+ else:
+ response = connection.getresponse().read()
+
+ #Cache the index.xml file for offline use
+ library_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + "index.xml", mode="w+b")
+ library_file.write(response)
+ library_file.close()
+
+ #Create /textures/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures"))
+
+ #Create /scripts/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts"))
+ library = "composite"
+
+ #Convert the response to a string
+ mat_lib_contents = str(response)
+
+ #Check for connection errors
+ if "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" not in mat_lib_contents:
+ self.report({'ERROR'}, "Error connecting; see console for details.")
+ print("Received following response from server:\n" + mat_lib_contents)
+ return {'CANCELLED'}
+
+ #Format nicely
+ mat_lib_contents = mat_lib_contents.replace("b'<?xml version=\"1.0\" encoding=\"UTF-8\"?>",'')
+ mat_lib_contents = mat_lib_contents.replace("\\r\\n",'')
+ mat_lib_contents = mat_lib_contents.replace("\\t",'')[:-1]
+ mat_lib_contents = mat_lib_contents.replace("\\",'')
+
+ else:
+ if "release" in context.scene.mat_lib_library:
+ #Check for cached index.xml file
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "release" + os.sep + "cycles" + os.sep + "index.xml"):
+ library_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "release" + os.sep + "cycles" + os.sep + "index.xml", mode="r", encoding="UTF-8")
+ mat_lib_contents = library_file.read()
+ library_file.close()
+ else:
+ self.report({'ERROR'}, "No cached library exists!")
+ return {'CANCELLED'}
+
+ #Create /textures/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "textures")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "textures"))
+
+ #Create /scripts/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "scripts")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "release", "cycles", "scripts"))
+ library = "release"
+ elif context.scene.mat_lib_library == "bundled":
+ #Check for index.xml file
+ if os.path.exists(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + "index.xml"):
+ library_file = open(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + "index.xml", mode="r", encoding="UTF-8")
+ mat_lib_contents = library_file.read()
+ library_file.close()
+ else:
+ self.report({'ERROR'}, "Bundled library does not exist!")
+ return {'CANCELLED'}
+ library = "bundled"
+ else:
+ #Check for cached index.xml file
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + "index.xml"):
+ library_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + "index.xml", mode="r", encoding="UTF-8")
+ mat_lib_contents = library_file.read()
+ library_file.close()
+ else:
+ self.report({'ERROR'}, "No cached library exists!")
+ return {'CANCELLED'}
+
+ #Create /textures/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures"))
+
+ #Create /scripts/ folder
+ if not os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts")):
+ os.mkdir(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts"))
+ library = "composite"
+
+ if '<?xml version="1.0" encoding="UTF-8"?>' not in mat_lib_contents:
+ self.report({'ERROR'}, "Cached XML file is invalid!")
+ return {'CANCELLED'}
+
+ #Format nicely
+ mat_lib_contents = mat_lib_contents.replace('<?xml version="1.0" encoding="UTF-8"?>', '')
+ mat_lib_contents = mat_lib_contents.replace("\r\n",'')
+ mat_lib_contents = mat_lib_contents.replace("\n",'')
+ mat_lib_contents = mat_lib_contents.replace("\t",'')
+ mat_lib_contents = mat_lib_contents.replace("\\",'')
+
+ #Clear important lists
+ library_data = []
+ mat_lib_category_names = []
+ mat_lib_category_types = []
+ mat_lib_category_filenames = []
+
+ dom = xml.dom.minidom.parseString(mat_lib_contents)
+
+ if self.mode == "online":
+ if library == "composite":
+ rev_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + "revision_data.ini", mode="r", encoding="UTF-8")
+ rev_data = rev_file.read()
+ rev_file.close()
+ else:
+ rev_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + "revision_data.ini", mode="r", encoding="UTF-8")
+ rev_data = rev_file.read()
+ rev_file.close()
+
+ if "revision=" in rev_data:
+ revision = int(rev_data[9:])
+ else:
+ revision = -1
+ print("The revision_data.ini file is invalid; clearing cache and re-creating.")
+
+ if revision is not int(dom.getElementsByTagName("library")[0].attributes['rev'].value):
+ bpy.ops.material.libraryclearcache()
+
+ if library == "composite":
+ rev_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + "revision_data.ini", mode="w", encoding="UTF-8")
+ else:
+ rev_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + "revision_data.ini", mode="w", encoding="UTF-8")
+ rev_file.write("revision=" + dom.getElementsByTagName("library")[0].attributes['rev'].value)
+ rev_file.close()
+
+ if 'addon' in dom.getElementsByTagName("library")[0].attributes:
+ current_version = float(dom.getElementsByTagName("library")[0].attributes['addon'].value)
+ this_version = bl_info["version"][0] + (bl_info["version"][1] / 10.0)
+ if current_version > this_version:
+ update_data = ["Add-on is outdated.", dom.getElementsByTagName("library")[0].attributes['download'].value]
+
+ print ("\n\n---Material Library---")
+ categories = dom.getElementsByTagName("category")
+ handleCategories(categories)
+
+ for cat in library_data:
+ #Find category names
+ mat_lib_category_names.append(cat.title)
+ #Find category types
+ #NOTE: Will have to redo this.
+ #mat_lib_category_types = safeEval(mat_lib_contents[(mat_lib_contents.index('[types]') + 7):mat_lib_contents.index('[/types]')])
+ #Get category filenames
+ mat_lib_category_filenames.append(cat.folder)
+
+ #Find amount of categories
+ mat_lib_categories = len(mat_lib_category_names)
+
+ #Set enum items for category dropdown
+ category_enum_items = [("None0", "None", "No category selected")]
+
+ i = 0
+ while i < mat_lib_categories:
+ print ("Adding category #%d" % (i + 1))
+ category_enum_items.append(((mat_lib_category_names[i] + str(i + 1)), mat_lib_category_names[i], (mat_lib_category_names[i] + " category")))
+ i = i + 1
+ bpy.types.Scene.mat_lib_material_category = bpy.props.EnumProperty(name = "", items = category_enum_items, description = "Choose a category")
+ bpy.context.scene.mat_lib_material_category = "None0";
+
+ #No errors - set working mode
+ working_mode = self.mode
+
+ self.report({'INFO'}, "Retrieved library!")
+
+ return {'FINISHED'}
+
+class LibraryInfo(bpy.types.Operator):
+ '''Display add-on info'''
+ bl_idname = "material.libraryinfo"
+ bl_label = "Display add-on info"
+
+ def execute(self, context):
+ global category_type
+
+ category_type = "info"
+
+ return {'FINISHED'}
+
+class LibraryTools(bpy.types.Operator):
+ '''Display material tools'''
+ bl_idname = "material.librarytools"
+ bl_label = "Display material tools"
+
+ def execute(self, context):
+ global category_type
+
+ category_type = "tools"
+
+ return {'FINISHED'}
+
+class LibrarySettings(bpy.types.Operator):
+ '''Display add-on settings'''
+ bl_idname = "material.librarysettings"
+ bl_label = "Display add-on settings"
+
+ def execute(self, context):
+ global category_type
+ global mat_lib_cached_files
+
+ category_type = "settings"
+ if library == "":
+ return {'FINISHED'}
+ elif library == "bundled":
+ mat_lib_cached_files = -2
+ return {'FINISHED'}
+ elif library == "composite":
+ cached_data_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep
+ else:
+ cached_data_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep
+ mat_lib_cached_files = 0
+ for root, dirs, files in os.walk(cached_data_path):
+ for name in files:
+ if ".jpg" in name.lower():
+ mat_lib_cached_files += 1
+ elif ".png" in name.lower():
+ mat_lib_cached_files += 1
+ elif ".osl" in name.lower():
+ mat_lib_cached_files += 1
+ elif ".osl" in name.lower():
+ mat_lib_cached_files += 1
+ elif ".bcm" in name:
+ mat_lib_cached_files += 1
+
+ return {'FINISHED'}
+
+class LibraryHome(bpy.types.Operator):
+ '''Go back'''
+ bl_idname = "material.libraryhome"
+ bl_label = "Go back"
+
+ def execute(self, context):
+ global category_type
+
+ category_type = "none"
+
+ return {'FINISHED'}
+
+def libraryCategoryUpdate():
+ print("Updating Material Category.")
+ #Check if the category is None
+ if bpy.context.scene.mat_lib_material_category != "None0":
+ #Selected category is not None; select category.
+
+ global category_contents
+ global category_name
+ global category_filename
+ global category_materials
+
+ global material_names
+ global material_filenames
+ global material_contributors
+ global material_ratings
+ global material_fireflies
+ global material_speeds
+ global material_complexities
+ global material_scripts
+ global material_images
+
+ global current_material_number
+
+ global category_type
+
+ findLibrary()
+
+ i = 0
+ while i < len(category_enum_items):
+ if category_enum_items[i][0] == bpy.context.scene.mat_lib_material_category:
+ #Set category filename for refresh button
+ category_filename = mat_lib_category_filenames[i - 1]
+ #Set category name for header
+ category_name = mat_lib_category_names[i - 1]
+ category_index = i - 1
+ i = i + 1
+
+ if True:
+ current_material_number = -1
+
+ material_names = []
+ material_filenames = []
+ material_contributors = []
+ material_ratings = []
+ material_fireflies = []
+ material_speeds = []
+ material_complexities = []
+ material_scripts = []
+ material_images = []
+
+ for mat in library_data[category_index].materials:
+ #Get material names
+ material_names.append(mat.name)
+ #Get material filenames
+ material_filenames.append(mat.href)
+ #Get material contributors
+ material_contributors.append(mat.contrib)
+ #Get material ratings
+ material_ratings.append(mat.stars)
+ #Get material firefly levels
+ material_fireflies.append(mat.fireflies)
+ #Get material render speeds
+ material_speeds.append(mat.speed)
+ #Get material complexities
+ material_complexities.append(mat.complexity)
+ #Get material image textures
+ material_images.append(mat.images)
+ #Get material OSL scripts
+ material_scripts.append(mat.scripts)
+
+ #Set amount of materials in selected category
+ category_materials = len(material_names)
+
+ category_type = "category"
+
+ elif "parent" == "parent":
+ current_material_number = -1
+ #REWRITE, REWRITE...
+ #Find category names
+ #parent_category_names = safeEval(parent_category_contents[(parent_category_contents.index('[names]') + 7):parent_category_contents.index('[/names]')])
+ #
+ #Get category filenames
+ #parent_category_filenames = safeEval(parent_category_contents[(parent_category_contents.index('[filenames]') + 11):parent_category_contents.index('[/filenames]')])
+ #
+ #Set parent category name for header
+ #parent_category_name = self.name
+ #
+ #Set parent category filename
+ #parent_category_filename = self.filename
+ #
+ #Set amount of categories in parent category
+ #parent_category_categories = len(parent_category_names)
+
+ category_type = "parent"
+
+ elif "subcategory" == "subcategory":
+ current_material_number = -1
+ #ANOTHER REWRITE.
+ #Get material names
+ #material_names = safeEval(category_contents[(category_contents.index("[names]") + 7):category_contents.index("[/names]")])
+ #
+ #Get material filenames
+ #material_filenames = safeEval(category_contents[(category_contents.index("[filenames]") + 11):category_contents.index("[/filenames]")])
+ #
+ #Get material contributors
+ #material_contributors = safeEval(category_contents[(category_contents.index("[contributors]") + 14):category_contents.index("[/contributors]")])
+ #
+ #Get material ratings
+ #material_ratings = safeEval(category_contents[(category_contents.index("[ratings]") + 9):category_contents.index("[/ratings]")])
+ #
+ #Set category name for header
+ #category_name = self.name
+ #
+ #Set category filename for refresh button
+ #category_filename = self.filename
+
+ #Set amount of materials in selected category
+ #category_materials = len(material_names)
+
+ category_type = "subcategory"
+
+ else:
+ self.report({'ERROR'}, "Invalid category! See console for details.")
+ print ("Invalid category!")
+ print (category_contents)
+ else:
+ #Selected category is None
+ parent_category_contents = "None"
+ category_contents = "None"
+ current_material_number = -1
+ category_type = "none"
+
+class ViewMaterial(bpy.types.Operator):
+ '''View material details'''
+ bl_idname = "material.libraryviewmaterial"
+ bl_label = "view material details"
+ material = bpy.props.IntProperty()
+
+ def execute(self, context):
+ global current_material_number
+ global current_material_cached
+ global current_material_previewed
+
+ findLibrary()
+
+ if current_material_number == self.material:
+ if current_material_previewed:
+ current_material_previewed = True
+ else:
+ current_material_previewed = False
+ else:
+ current_material_previewed = False
+
+ current_material_number = self.material
+ current_material_cached = False
+
+ if self.material == -1:
+ return {'FINISHED'}
+
+ if library == "composite":
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + material_filenames[self.material] + ".bcm"):
+ current_material_cached = True
+ elif library != "bundled":
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + material_filenames[self.material] + ".bcm"):
+ current_material_cached = True
+
+ if context.scene.mat_lib_auto_preview == True:
+ print("Auto-download previews on.")
+ bpy.ops.material.librarypreview(name=material_names[self.material], filename=material_filenames[self.material])
+ self.report({preview_message[0]}, preview_message[1])
+ elif working_mode == "offline":
+ bpy.ops.material.librarypreview(name=material_names[self.material], filename=material_filenames[self.material])
+ self.report({preview_message[0]}, preview_message[1])
+ elif library == "composite":
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + material_filenames[self.material] + ".jpg"):
+ bpy.ops.material.librarypreview(name=material_names[self.material], filename=material_filenames[self.material])
+ self.report({preview_message[0]}, preview_message[1])
+ else:
+ if os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + material_filenames[self.material] + ".jpg"):
+ bpy.ops.material.librarypreview(name=material_names[self.material], filename=material_filenames[self.material])
+ self.report({preview_message[0]}, preview_message[1])
+ return {'FINISHED'}
+
+class MaterialDetailView(bpy.types.Operator):
+ '''Change detail view'''
+ bl_idname = "material.librarydetailview"
+ bl_label = "change detail view"
+ mode = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global material_detail_view
+
+ if self.mode == "NEXT":
+ if material_detail_view == "RENDER":
+ material_detail_view = "DATA"
+ else:
+ if material_detail_view == "DATA":
+ material_detail_view = "RENDER"
+ return {'FINISHED'}
+
+
+class LibraryClearCache(bpy.types.Operator):
+ '''Delete active library's cached previews and/or materials'''
+ bl_idname = "material.libraryclearcache"
+ bl_label = "delete cached previews and materials"
+
+ def execute(self, context):
+ global mat_lib_cached_files
+ findLibrary()
+
+ if library == "bundled":
+ self.report({'ERROR'}, "The bundled library is local only and contains no cached online data.")
+ return {'CANCELLED'}
+ if library == "composite":
+ for root, dirs, files in os.walk(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep):
+ for name in files:
+ if name[-4:].lower() == ".jpg":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".png":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".osl":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".oso":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".bcm":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ else:
+ for root, dirs, files in os.walk(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep):
+ for name in files:
+ if name[-4:].lower() == ".jpg":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".png":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".osl":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".oso":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+ elif name[-4:].lower() == ".bcm":
+ print("Deleting \"" + os.path.join(root, name) + "\".")
+ os.remove(os.path.join(root, name))
+
+ if library == "":
+ return {'FINISHED'}
+ elif library == "bundled":
+ return {'FINISHED'}
+ elif library == "composite":
+ cached_data_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep
+ else:
+ cached_data_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep
+ mat_lib_cached_files = 0
+ for root, dirs, files in os.walk(cached_data_path):
+ for name in files:
+ if ".jpg" in name:
+ mat_lib_cached_files += 1
+ elif ".bcm" in name:
+ mat_lib_cached_files += 1
+
+ self.report({'INFO'}, "Preview cache cleared.")
+ return {'FINISHED'}
+
+class LibraryPreview(bpy.types.Operator):
+ '''Download preview'''
+ bl_idname = "material.librarypreview"
+ bl_label = "preview material"
+ name = bpy.props.StringProperty()
+ filename = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global parent_category_filename
+ global category_filename
+ global preview_message
+ global library
+ global current_material_previewed
+
+ findLibrary()
+
+ #Check for a cached preview
+ if library == "bundled":
+ image_path = mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".jpg"
+ elif library == "composite":
+ image_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".jpg"
+ else:
+ image_path = mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".jpg"
+
+ if os.path.exists(image_path):
+ #Cached preview exists
+ cached_image = open(image_path, 'r+b')
+ response = cached_image.read()
+ cached_image.close()
+ f = open(mat_lib_folder + os.sep + "mat_lib_preview_image.jpg", 'w+b')
+ f.write(response)
+ f.close()
+
+ elif working_mode == "online":
+ #This preview doesn't exist yet; let's download it.
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/" + category_filename + "/" + self.filename + ".jpg")
+ response = connection.getresponse().read()
+ f = open(mat_lib_folder + os.sep + "mat_lib_preview_image.jpg", 'w+b')
+ f.write(response)
+ f.close()
+
+ #Cache this preview
+ f = open(image_path, 'w+b')
+ f.write(response)
+ f.close()
+
+ else:
+ self.report({'WARNING'}, "Preview does not exist; cannot download in offline mode.")
+ preview_message = ['WARNING', "Preview does not exist; cannot download in offline mode."]
+ return {'CANCELLED'}
+
+ #Check if has texture
+ if bpy.data.images.find("mat_lib_preview_image.jpg") == -1:
+ bpy.ops.image.open(filepath=os.path.join(mat_lib_folder, "mat_lib_preview_image.jpg"))
+
+ if "mat_lib_preview_texture" not in bpy.data.textures:
+ bpy.data.textures.new("mat_lib_preview_texture", "IMAGE")
+
+ if bpy.data.textures["mat_lib_preview_texture"].image != bpy.data.images["mat_lib_preview_image.jpg"]:
+ bpy.data.textures["mat_lib_preview_texture"].image = bpy.data.images["mat_lib_preview_image.jpg"]
+
+ if bpy.data.images["mat_lib_preview_image.jpg"].filepath != os.path.join(mat_lib_folder, "mat_lib_preview_image.jpg"):
+ bpy.data.images["mat_lib_preview_image.jpg"].filepath != os.path.join(mat_lib_folder, "mat_lib_preview_image.jpg")
+
+ #Do everything possible to get Blender to reload the preview.
+ bpy.data.images["mat_lib_preview_image.jpg"].reload()
+ bpy.ops.wm.redraw_timer()
+ bpy.data.scenes[bpy.context.scene.name].update()
+ bpy.data.scenes[bpy.context.scene.name].frame_set(bpy.data.scenes[bpy.context.scene.name].frame_current)
+
+ self.report({'INFO'}, "Preview applied.")
+ preview_message = ['INFO', "Preview applied."]
+ current_material_previewed = True
+
+ return {'FINISHED'}
+
+class AddLibraryMaterial(bpy.types.Operator):
+ '''Add material to scene'''
+ bl_idname = "material.libraryadd"
+ bl_label = "add material to scene"
+ mat_name = bpy.props.StringProperty()
+ filename = bpy.props.StringProperty()
+ open_location = bpy.props.StringProperty()
+ text_block = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global material_file_contents
+ global library
+ global node_message
+ global current_material_cached
+
+ findLibrary()
+
+ if not bpy.context.active_object:
+ self.report({'ERROR'}, "No object selected!")
+ if self.open_location == "" and self.text_block == "":
+ if library == "composite" and os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm"):
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="r", encoding="UTF-8")
+ material_file_contents = ""
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+ elif library != "bundled" and os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm"):
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="r", encoding="UTF-8")
+ material_file_contents = ""
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+ elif library == "bundled" and os.path.exists(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm"):
+ bcm_file = open(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/" + category_filename + "/" + self.filename + ".bcm")
+ response = connection.getresponse().read()
+
+ #Check file for validitity
+ if '<?xml version="1.0" encoding="UTF-8"?>' not in str(response)[2:40]:
+ self.report({'ERROR'}, "Material file is either outdated or invalid.")
+ self.filename = ""
+ return {'CANCELLED'}
+
+ #Cache material
+ if library == "composite":
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+ else:
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+
+ material_file_contents = str(response)
+ else:
+ self.report({'ERROR'}, "Material is not cached; cannot download in offline mode!")
+ return {'CANCELLED'}
+ print (material_file_contents)
+ mat_name = self.mat_name
+ elif self.open_location is not "":
+ if ".bcm" in self.open_location:
+ bcm_file = open(self.open_location, mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+
+ #Check file for validitity
+ if '<?xml version="1.0" encoding="UTF-8"?>' not in material_file_contents:
+ self.open_location = ""
+ self.report({'ERROR'}, "Material file is either outdated or invalid.")
+ return {'CANCELLED'}
+ mat_name = ""
+ for word in self.open_location.split(os.sep)[-1][:-4].split("_"):
+ if mat_name is not "":
+ mat_name += " "
+ mat_name += word.capitalize()
+ else:
+ self.report({'ERROR'}, "Not a .bcm file.")
+ self.open_location = ""
+ return {'CANCELLED'}
+ else:
+ if self.text_block in bpy.data.texts:
+ #Read from a text datablock
+ material_file_contents = bpy.data.texts[self.text_block].as_string()
+ else:
+ self.report({'ERROR'}, "Requested text block does not exist.")
+ self.text_block = ""
+ return {'CANCELLED'}
+
+ #Check file for validitity
+ if '<?xml version="1.0" encoding="UTF-8"?>' not in material_file_contents[0:38]:
+ self.report({'ERROR'}, "Material data is either outdated or invalid.")
+ self.text_block = ""
+ return {'CANCELLED'}
+ mat_name = ""
+
+ separator = ""
+ if context.scene.mat_lib_bcm_name is "":
+ separator = ""
+ if "_" in self.text_block:
+ separator = "_"
+ elif "-" in self.text_block:
+ separator = "-"
+ elif " " in self.text_block:
+ separator = " "
+
+ if separator is not "":
+ for word in self.text_block.split(separator):
+ if mat_name is not "":
+ mat_name += " "
+ mat_name += word.capitalize()
+ else:
+ mat_name = self.text_block
+ else:
+ mat_name = context.scene.mat_lib_bcm_name
+
+ if '<?xml version="1.0" encoding="UTF-8"?>' in material_file_contents[0:40]:
+ material_file_contents = material_file_contents[material_file_contents.index("<material"):(material_file_contents.rindex("</material>") + 11)]
+ else:
+ self.mat_name = ""
+ self.filename = ""
+ self.text_block = ""
+ self.open_location = ""
+ self.report({'ERROR'}, "Material file is either invalid or outdated.")
+ print(material_file_contents)
+ return {'CANCELLED'}
+
+ #Create new material
+ new_mat = bpy.data.materials.new(mat_name)
+ new_mat.use_nodes = True
+ new_mat.node_tree.nodes.clear()
+
+ #Parse file
+ dom = xml.dom.minidom.parseString(material_file_contents)
+
+ #Create internal OSL scripts
+ scripts = dom.getElementsByTagName("script")
+ osl_scripts = []
+ for s in scripts:
+ osl_datablock = bpy.data.texts.new(name=s.attributes['name'].value)
+ osl_text = s.toxml()[s.toxml().index(">"):s.toxml().rindex("<")]
+ osl_text = osl_text[1:].replace("<br/>","\n").replace("<", "<").replace(">", ">").replace(""", "\"").replace("&", "&")
+ osl_datablock.write(osl_text)
+ osl_scripts.append(osl_datablock)
+
+ #Add nodes
+ nodes = dom.getElementsByTagName("node")
+ addNodes(nodes, new_mat)
+ if node_message:
+ self.report({node_message[0]}, node_message[1])
+ node_message = []
+ self.mat_name = ""
+ self.filename = ""
+ self.open_location = ""
+ self.text_block = ""
+ return {'CANCELLED'}
+
+ #Create links
+ links = dom.getElementsByTagName("link")
+ createLinks(links, new_mat)
+
+ m = dom.getElementsByTagName("material")[0]
+
+ #Set viewport color
+ new_mat.diffuse_color = color(m.attributes["view_color"].value)
+
+ #Set sample-as-lamp-ness
+ if m.attributes["sample_lamp"].value == "True":
+ sample_lamp = True
+ else:
+ sample_lamp = False
+ new_mat.cycles.sample_as_light = sample_lamp
+
+ self.mat_name = ""
+ self.filename = ""
+ self.open_location = ""
+ self.text_block = ""
+ self.report({'INFO'}, "Material added.")
+ current_material_cached = True
+
+ return {'FINISHED'}
+
+class ApplyLibraryMaterial(bpy.types.Operator):
+ '''Apply to active material'''
+ bl_idname = "material.libraryapply"
+ bl_label = "Apply to active material"
+ mat_name = bpy.props.StringProperty()
+ filename = bpy.props.StringProperty()
+ open_location = bpy.props.StringProperty()
+ text_block = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global material_file_contents
+ global library
+ global node_message
+ global current_material_cached
+ global osl_scripts
+
+ findLibrary()
+
+ mat_name = ""
+ material_file_contents = ""
+ if not bpy.context.active_object:
+ self.report({'ERROR'}, "No object selected!")
+ return {'CANCELLED'}
+ if self.filename is not "":
+ if library == "composite" and os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm"):
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+ elif library != "bundled" and os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm"):
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+ elif library == "bundled" and os.path.exists(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm"):
+ bcm_file = open(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/" + category_filename + "/" + self.filename + ".bcm")
+ response = connection.getresponse().read()
+
+ #Check file for validitity
+ if '<?xml version="1.0" encoding="UTF-8"?>' not in str(response)[2:40]:
+ self.report({'ERROR'}, "Material file is either outdated or invalid.")
+ self.mat_name = ""
+ self.filename = ""
+ return {'CANCELLED'}
+
+ #Cache material
+ if library == "composite":
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+ else:
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+
+ material_file_contents = str(response)
+ else:
+ self.report({'ERROR'}, "Material is not cached; cannot download in offline mode!")
+ self.mat_name = ""
+ self.filename = ""
+ return {'CANCELLED'}
+ mat_name = self.mat_name
+ elif self.open_location is not "":
+ if ".bcm" in self.open_location:
+ material_file_contents = ""
+ bcm_file = open(self.open_location, mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+
+ mat_name = ""
+ for word in self.open_location.split(os.sep)[-1][:-4].split("_"):
+ if mat_name is not "":
+ mat_name += " "
+ mat_name += word.capitalize()
+ else:
+ self.open_location = ""
+ self.report({'ERROR'}, "Not a .bcm file.")
+ return {'CANCELLED'}
+ else:
+ if self.text_block in bpy.data.texts:
+ #Read from a text datablock
+ material_file_contents = ""
+ material_file_contents = bpy.data.texts[self.text_block].as_string()
+ else:
+ self.report({'ERROR'}, "Requested text block does not exist.")
+ self.text_block = "";
+ return {'CANCELLED'}
+
+ if context.scene.mat_lib_bcm_name is "":
+ separator = ""
+ if "_" in self.text_block:
+ separator = "_"
+ elif "-" in self.text_block:
+ separator = "-"
+ elif " " in self.text_block:
+ separator = " "
+
+ if separator is not "":
+ for word in self.text_block.split(separator):
+ if mat_name is not "":
+ mat_name += " "
+ mat_name += word.capitalize()
+ else:
+ mat_name = self.text_block
+ else:
+ mat_name = context.scene.mat_lib_bcm_name
+
+
+ if context.active_object.active_material:
+ context.active_object.active_material.name = mat_name
+ else:
+ new_material = bpy.data.materials.new(mat_name)
+ if len(context.active_object.material_slots.keys()) is 0:
+ bpy.ops.object.material_slot_add()
+ context.active_object.material_slots[context.active_object.active_material_index].material = new_material
+
+ #Prepare material for new nodes
+ context.active_object.active_material.use_nodes = True
+ context.active_object.active_material.node_tree.nodes.clear()
+
+ if '<?xml version="1.0" encoding="UTF-8"?>' in material_file_contents[0:40]:
+ material_file_contents = material_file_contents[material_file_contents.index("<material"):(material_file_contents.rindex("</material>") + 11)]
+ else:
+ self.mat_name = ""
+ self.filename = ""
+ self.text_block = ""
+ self.open_location = ""
+ self.report({'ERROR'}, "Material file is either invalid or outdated.")
+ print(material_file_contents)
+ return {'CANCELLED'}
+
+ #Parse file
+ dom = xml.dom.minidom.parseString(material_file_contents)
+
+ #Create internal OSL scripts
+ scripts = dom.getElementsByTagName("script")
+ osl_scripts = []
+ for s in scripts:
+ osl_datablock = bpy.data.texts.new(name=s.attributes['name'].value)
+ osl_text = s.toxml()[s.toxml().index(">"):s.toxml().rindex("<")]
+ osl_text = osl_text[1:].replace("<br/>","\n").replace("<", "<").replace(">", ">").replace(""", "\"").replace("&", "&")
+ osl_datablock.write(osl_text)
+ osl_scripts.append(osl_datablock)
+
+ #Add nodes
+ nodes = dom.getElementsByTagName("node")
+ addNodes(nodes, context.active_object.active_material)
+ if node_message:
+ self.report({node_message[0]}, node_message[1])
+ node_message = []
+ self.mat_name = ""
+ self.filename = ""
+ self.open_location = ""
+ self.text_block = ""
+ return {'CANCELLED'}
+
+ #Create links
+ links = dom.getElementsByTagName("link")
+ createLinks(links, context.active_object.active_material)
+
+ m = dom.getElementsByTagName("material")[0]
+
+ #Set viewport color
+ context.active_object.active_material.diffuse_color = color(m.attributes["view_color"].value)
+
+ #Set sample-as-lamp-ness
+ if boolean(m.attributes["sample_lamp"].value):
+ sample_lamp = True
+ else:
+ sample_lamp = False
+ context.active_object.active_material.cycles.sample_as_light = sample_lamp
+
+ self.mat_name = ""
+ self.filename = ""
+ self.open_location = ""
+ self.text_block = ""
+ self.report({'INFO'}, "Material applied.")
+ current_material_cached = True
+
+ return {'FINISHED'}
+
+class CacheLibraryMaterial(bpy.types.Operator):
+ '''Cache material to disk'''
+ bl_idname = "material.librarycache"
+ bl_label = "cache material to disk"
+ filename = bpy.props.StringProperty()
+
+ def execute(self, context):
+ global material_file_contents
+ global current_material_cached
+
+ findLibrary()
+
+ if working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/" + category_filename + "/" + self.filename + ".bcm")
+ response = connection.getresponse().read()
+ else:
+ self.report({'ERROR'}, "Cannot cache material in offline mode.")
+ return {'CANCELLED'}
+
+ material_file_contents = str(response)
+ if '<?xml version="1.0" encoding="UTF-8"?>' in material_file_contents[2:40]:
+ material_file_contents = material_file_contents[material_file_contents.index("<material"):(material_file_contents.rindex("</material>") + 11)]
+ else:
+ self.report({'ERROR'}, "Invalid material file.")
+ print(material_file_contents)
+ return {'CANCELLED'}
+
+ #Parse file
+ dom = xml.dom.minidom.parseString(material_file_contents)
+
+ #Create external OSL scripts and cache image textures
+ nodes = dom.getElementsByTagName("node")
+ for node in nodes:
+ node_data = node.attributes
+ if node_data['type'].value == "TEX_IMAGE":
+ if node_data['image'].value:
+ if "file://" in node_data['image'].value:
+ self.report({'ERROR'}, "Cannot cache image texture located at %s." % node_data['image'].value)
+ elif "http://" in node_data['image'].value:
+ self.report({'ERROR'}, "Cannot cache image texture hosted at %s." % node_data['image'].value)
+ else:
+ ext = "." + node_data['image'].value.split(".")[-1]
+ image_name = node_data['image'].value[:-4]
+
+ if ext.lower() != ".jpg" and ext.lower() != ".png":
+ node_message = ['ERROR', "The image file referenced by this image texture node is not .jpg or .png; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/textures/" + image_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache image texture
+ if library == "composite":
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ node_message = ['ERROR', "The image texture, \"%s\", is not cached; cannot download in offline mode." % (image_name + ext)]
+ image_filepath = ""
+ elif node_data['type'].value == "SCRIPT":
+ if node_data['script'].value:
+ if "file://" in node_data['script'].value:
+ self.report({'ERROR'}, "Cannot cache OSL script located at %s." % node_data['script'].value)
+ elif "http://" in node_data['script'].value:
+ self.report({'ERROR'}, "Cannot cache OSL script hosted at %s." % node_data['script'].value)
+ else:
+ ext = "." + node_data['script'].value.split(".")[-1]
+ script_name = node_data['script'].value[:-4]
+
+ if ext.lower() != ".osl" and ext.lower() != ".oso":
+ node_message = ['ERROR', "The OSL script file referenced by this script node is not .osl or .oso; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)):
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)):
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "scripts", script_name + ext)):
+ script_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "scripts", script_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/scripts/" + script_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache image texture
+ if library == "composite":
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)
+ script_file = open(script_filepath, mode="w+b")
+ script_file.write(response)
+ script_file.close()
+ else:
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)
+ script_file = open(script_filepath, mode="w+b")
+ script_file.write(response)
+ script_file.close()
+ else:
+ node_message = ['ERROR', "The OSL script, \"%s\", is not cached; cannot download in offline mode." % (script_name + ext)]
+ script_filepath = ""
+
+
+ if library == "composite":
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+ elif library != "bundled":
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename + ".bcm", mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+ else:
+ self.report({'ERROR'}, "Cannot cache materials from this library.")
+ return {'CANCELLED'}
+
+ current_material_cached = True
+ self.report({'INFO'}, "Material cached.")
+ return {'FINISHED'}
+
+class SaveLibraryMaterial(bpy.types.Operator, ExportHelper):
+ '''Save material to disk'''
+ bl_idname = "material.librarysave"
+ bl_label = "Save material to disk"
+ filepath = bpy.props.StringProperty()
+ filename = bpy.props.StringProperty()
+
+ #ExportHelper uses this
+ filename_ext = ".bcm"
+
+ filter_glob = bpy.props.StringProperty(
+ default="*.bcm",
+ options={'HIDDEN'},
+ )
+
+ def execute(self, context):
+ global material_file_contents
+ global save_filename
+ global current_material_cached
+
+ findLibrary()
+
+ if library == "composite" and os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + save_filename):
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename, mode="r+b")
+ response = bcm_file.read()
+ bcm_file.close()
+ elif library != "bundled" and os.path.exists(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + save_filename):
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename, mode="r+b")
+ response = bcm_file.read()
+ bcm_file.close()
+ elif library == "bundled" and os.path.exists(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + save_filename):
+ bcm_file = open(mat_lib_folder + os.sep + "bundled" + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename, mode="r+b")
+ response = bcm_file.read()
+ bcm_file.close()
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/" + category_filename + "/" + self.filename)
+ response = connection.getresponse().read()
+
+ #Cache material
+ if library == "composite":
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename, mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+ else:
+ bcm_file = open(mat_lib_folder + os.sep + mat_lib_host + os.sep + library + os.sep + "cycles" + os.sep + category_filename + os.sep + self.filename, mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+ else:
+ self.report({'ERROR'}, "Material is not cached; cannot download in offline mode.")
+ return {'FINISHED'}
+
+ material_file_contents = str(response)
+
+ bcm_file = open(self.filepath, mode="w+b")
+ bcm_file.write(response)
+ bcm_file.close()
+
+ if '<?xml version="1.0" encoding="UTF-8"?>' in material_file_contents[0:40]:
+ material_file_contents = material_file_contents[material_file_contents.index("<material"):(material_file_contents.rindex("</material>") + 11)]
+ else:
+ self.report({'ERROR'}, "Invalid material file.")
+ print(material_file_contents)
+ return {'CANCELLED'}
+
+ #Parse file
+ dom = xml.dom.minidom.parseString(material_file_contents)
+
+ bcm_file = open(self.filepath, mode="r", encoding="UTF-8")
+ material_file_contents = bcm_file.read()
+ bcm_file.close()
+
+ #Create external OSL scripts and cache image textures
+ nodes = dom.getElementsByTagName("node")
+ for node in nodes:
+ node_data = node.attributes
+ if node_data['type'].value == "TEX_IMAGE":
+ if node_data['image'].value:
+ node_attributes = (
+ node_data['image'].value,
+ node_data['source'].value,
+ node_data['color_space'].value,
+ node_data['projection'].value,
+ node_data['loc'].value)
+ original_xml = ("<node type=\"TEX_IMAGE\" image=\"%s\" source=\"%s\" color_space=\"%s\" projection=\"%s\" loc=\"%s\" />" % node_attributes)
+ if "file://" in node_data['image'].value:
+ if os.path.exists(node_data['image'].value[7:]):
+ image_file = open(node_data['image'].value[7:], mode="r+b")
+ image_data = image_file.read()
+ image_file.close()
+ copied_image = open(self.filepath[:-len(self.filename)] + node_data['image'].value.split(os.sep)[-1], mode="w+b")
+ copied_image.write(image_data)
+ copied_image.close()
+ image_location = ("file://" + self.filepath[:-len(self.filename)] + node_data['image'].value.split(os.sep)[-1])
+ else:
+ image_location = ""
+ elif "http://" in node_data['image'].value:
+ self.report({'ERROR'}, "Cannot save image texture hosted at %s." % node_data['image'].value)
+ image_location = ""
+ else:
+ ext = "." + node_data['image'].value.split(".")[-1]
+ image_name = node_data['image'].value[:-4]
+
+ if ext.lower() != ".jpg" and ext.lower() != ".png":
+ node_message = ['ERROR', "The image file referenced by this image texture node is not .jpg or .png; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/textures/" + image_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache image texture
+ if library == "composite":
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ node_message = ['ERROR', "The image texture, \"%s\", is not cached; cannot download in offline mode." % (image_name + ext)]
+ image_filepath = ""
+ image_location = ("file://" + self.filepath[:-len(self.filename)] + node_data['image'].value)
+
+ if image_filepath:
+ print(image_filepath)
+ image_file = open(image_filepath, mode="r+b")
+ image_data = image_file.read()
+ image_file.close()
+ saved_image = open(self.filepath[:-len(self.filename)] + node_data['image'].value, mode="w+b")
+ saved_image.write(image_data)
+ saved_image.close()
+
+ updated_xml = original_xml.replace(node_data['image'].value, image_location)
+ material_file_contents = material_file_contents.replace(original_xml, updated_xml)
+ elif node_data['type'].value == "SCRIPT":
+ if node_data['script'].value:
+ node_attributes = (
+ node_data['mode'].value,
+ node_data['script'].value,
+ node_data['loc'].value)
+ original_xml = ("<node type=\"SCRIPT\" mode=\"%s\" script=\"%s\" loc=\"%s\" />" % node_attributes)
+ if "file://" in node_data['script'].value:
+ if os.path.exists(node_data['script'].value[7:]):
+ script_file = open(node_data['script'].value[7:], mode="r+b")
+ script_data = script_file.read()
+ script_file.close()
+ copied_script = open(self.filepath[:-len(self.filename)] + node_data['script'].value.split(os.sep)[-1], mode="w+b")
+ copied_script.write(script_data)
+ copied_script.close()
+ script_location = ("file://" + self.filepath[:-len(self.filename)] + node_data['script'].value.split(os.sep)[-1])
+ else:
+ script_location = ""
+ elif "http://" in node_data['script'].value:
+ self.report({'ERROR'}, "Cannot save OSL script hosted at %s." % node_data['script'].value)
+ script_location = ""
+ else:
+ ext = "." + node_data['script'].value.split(".")[-1]
+ script_name = node_data['script'].value[:-4]
+
+ if ext.lower() != ".osl" and ext.lower() != ".oso":
+ node_message = ['ERROR', "The OSL script file referenced by this script node is not .osl or .oso; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)):
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)):
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "scripts", script_name + ext)):
+ script_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "scripts", script_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/scripts/" + script_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache OSL script
+ if library == "composite":
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)
+ script_file = open(script_filepath, mode="w+b")
+ script_file.write(response)
+ script_file.close()
+ else:
+ script_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)
+ script_file = open(script_filepath, mode="w+b")
+ script_file.write(response)
+ script_file.close()
+ else:
+ node_message = ['ERROR', "The OSL script, \"%s\", is not cached; cannot download in offline mode." % (script_name + ext)]
+ script_filepath = ""
+
+ if script_filepath:
+ print(script_filepath)
+ script_file = open(script_filepath, mode="r+b")
+ script_data = script_file.read()
+ script_file.close()
+ saved_script = open(self.filepath[:-len(self.filename)] + node_data['script'].value, mode="w+b")
+ saved_script.write(script_data)
+ saved_script.close()
+
+ updated_xml = original_xml.replace(node_data['script'].value, script_location)
+ material_file_contents = material_file_contents.replace(original_xml, updated_xml)
+
+ bcm_file = open(self.filepath, mode="w", encoding="UTF-8")
+ bcm_file.write(material_file_contents)
+ bcm_file.close()
+
+ self.report({'INFO'}, "Material saved.")
+ current_material_cached = True
+
+ return {'FINISHED'}
+
+def createLinks(links, mat):
+ node_tree = mat.node_tree
+ for dom_link in links:
+ link = {
+ "to": int(dom_link.attributes['to'].value),
+ "input": int(dom_link.attributes['input'].value),
+ "from": int(dom_link.attributes['from'].value),
+ "output": int(dom_link.attributes['output'].value)}
+ node_tree.links.new(
+ node_tree.nodes[link["to"]].inputs[link["input"]],
+ node_tree.nodes[link["from"]].outputs[link["output"]])
+
+def addNodes(nodes, mat):
+ global node_message
+ global osl_scripts
+
+ for dom_node in nodes:
+ node_type = dom_node.attributes['type'].value
+ loc = dom_node.attributes['loc'].value
+ node_location = [int(loc[:loc.index(",")]), int(loc[(loc.index(",") + 1):])]
+ node_tree = mat.node_tree
+ node_data = dom_node.attributes
+
+ #Below here checks the type of the node and adds the correct type
+
+ #INPUT TYPES
+ #This is totally crafty, but some of these nodes actually
+ # store their values as their output's default value!
+ if node_type == "ATTRIBUTE":
+ print ("ATTRIBUTE")
+ node = node_tree.nodes.new(node_type)
+ node.attribute_name = node_data['attribute'].value
+
+ elif node_type == "CAMERA":
+ print ("CAMERA")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "FRESNEL":
+ print ("FRESNEL")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['IOR'].default_value = float(node_data['ior'].value)
+
+ elif node_type == "LAYER_WEIGHT":
+ print ("LAYER_WEIGHT")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Blend'].default_value = float(node_data['blend'].value)
+
+ elif node_type == "LIGHT_PATH":
+ print ("LIGHT_PATH")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "NEW_GEOMETRY":
+ print ("NEW_GEOMETRY")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "OBJECT_INFO":
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ print ("OBJECT_INFO")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "PARTICLE_INFO":
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ print ("PARTICLE_INFO")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "RGB":
+ print ("RGB")
+ node = node_tree.nodes.new(node_type)
+ node.outputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "TANGENT":
+ print ("TANGENT")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.direction_type = node_data['direction'].value
+ node.axis = node_data['axis'].value
+
+ elif node_type == "TEX_COORD":
+ print ("TEX_COORD")
+ node = node_tree.nodes.new(node_type)
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.64 and "dupli" in node_data:
+ node.from_dupli = boolean(node_data['dupli'].value)
+
+ elif node_type == "VALUE":
+ print ("VALUE")
+ node = node_tree.nodes.new(node_type)
+ node.outputs['Value'].default_value = float(node_data['value'].value)
+
+ #OUTPUT TYPES
+ elif node_type == "OUTPUT_LAMP":
+ print ("OUTPUT_LAMP")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "OUTPUT_MATERIAL":
+ print ("OUTPUT_MATERIAL")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "OUTPUT_WORLD":
+ print ("OUTPUT_WORLD")
+ node = node_tree.nodes.new(node_type)
+
+ #SHADER TYPES
+ elif node_type == "ADD_SHADER":
+ print ("ADD_SHADER")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "AMBIENT_OCCLUSION":
+ print ("AMBIENT_OCCLUSION")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "BACKGROUND":
+ print ("BACKGROUND")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Strength'].default_value = float(node_data['strength'].value)
+
+ elif node_type == "BSDF_ANISOTROPIC":
+ print ("BSDF_ANISOTROPIC")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Roughness'].default_value = float(node_data['roughness'].value)
+ node.inputs['Anisotropy'].default_value = float(node_data['anisotropy'].value)
+ node.inputs['Rotation'].default_value = float(node_data['rotation'].value)
+
+ elif node_type == "BSDF_DIFFUSE":
+ print ("BSDF_DIFFUSE")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Roughness'].default_value = float(node_data['roughness'].value)
+
+ elif node_type == "BSDF_GLASS":
+ print ("BSDF_GLASS")
+ node = node_tree.nodes.new(node_type)
+ node.distribution = node_data['distribution'].value
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Roughness'].default_value = float(node_data['roughness'].value)
+ node.inputs['IOR'].default_value = float(node_data['ior'].value)
+
+ elif node_type == "BSDF_GLOSSY":
+ print ("BSDF_GLOSSY")
+ node = node_tree.nodes.new(node_type)
+ node.distribution = node_data['distribution'].value
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Roughness'].default_value = float(node_data['roughness'].value)
+
+ elif node_type == "BSDF_REFRACTION":
+ print ("BSDF_REFRACTION")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.distribution = node_data['distribution'].value
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Roughness'].default_value = float(node_data['roughness'].value)
+ node.inputs['IOR'].default_value = float(node_data['ior'].value)
+
+ elif node_type == "BSDF_TRANSLUCENT":
+ print ("BSDF_TRANSLUCENT")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "BSDF_TRANSPARENT":
+ print ("BSDF_TRANSPARENT")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "BSDF_VELVET":
+ print ("BSDF_VELVET")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Sigma'].default_value = float(node_data['sigma'].value)
+
+ elif node_type == "EMISSION":
+ print ("EMISSION")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Strength'].default_value = float(node_data['strength'].value)
+
+ elif node_type == "HOLDOUT":
+ print ("HOLDOUT")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "MIX_SHADER":
+ print ("MIX_SHADER")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Fac'].default_value = float(node_data['fac'].value)
+
+ #TEXTURE TYPES
+ elif node_type == "TEX_BRICK":
+ print ("TEX_BRICK")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.offset = float(node_data['offset'].value)
+ node.offset_frequency = float(node_data['offset_freq'].value)
+ node.squash = float(node_data['squash'].value)
+ node.squash_frequency = float(node_data['squash_freq'].value)
+ node.inputs['Color1'].default_value = color(node_data['color1'].value)
+ node.inputs['Color2'].default_value = color(node_data['color2'].value)
+ node.inputs['Mortar'].default_value = color(node_data['mortar'].value)
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+ node.inputs['Mortar Size'].default_value = float(node_data['mortar_size'].value)
+ node.inputs['Bias'].default_value = float(node_data['bias'].value)
+ node.inputs['Brick Width'].default_value = float(node_data['width'].value)
+ node.inputs['Row Height'].default_value = float(node_data['height'].value)
+
+ elif node_type == "TEX_CHECKER":
+ print ("TEX_CHECKER")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color1'].default_value = color(node_data['color1'].value)
+ node.inputs['Color2'].default_value = color(node_data['color2'].value)
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+
+ elif node_type == "TEX_ENVIRONMENT":
+ print ("TEX_ENVIRONMENT")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.color_space = node_data['color_space'].value
+ node.projection = node_data['projection'].value
+ if 'image' in node_data:
+ if "file://" in node_data['image'].value:
+ image_filepath = node_data['image'].value[7:]
+ image_name = node_data['image'].value.split(os.sep)[-1]
+ image_datablock = bpy.data.images.new(name=image_name, width=4, height=4)
+ image_datablock.source = node_data['source'].value
+ image_datablock.filepath = image_filepath
+ node.image = image_datablock
+ if node_data['source'].value == 'MOVIE' or node_data['source'].value == 'SEQUENCE':
+ node.image_user.frame_duration = int(node_data['frame_duration'].value)
+ node.image_user.frame_start = int(node_data['frame_start'].value)
+ node.image_user.frame_offset = int(node_data['frame_offset'].value)
+ node.image_user.use_cyclic = boolean(node_data['cyclic'].value)
+ node.image_user.use_auto_refresh = boolean(node_data['auto_refresh'].value)
+ elif "http://" in node_data['image'].value and bpy.context.scene.mat_lib_images_only_trusted == False:
+ ext = "." + node_data['image'].value.split(".")[-1]
+ image_name = node_data['image'].value.split("/")[-1][:-4]
+ image_host = node_data['image'].value[7:].split("/")[0]
+ image_location = node_data['image'].value[(7 + len(image_host)):]
+
+ if ext.lower() != ".jpg" and ext.lower() != ".png":
+ node_message = ['ERROR', "The image file referenced by this image texture node is not .jpg or .png; not downloading."]
+ return
+
+ connection = http.client.HTTPConnection(image_host)
+ connection.request("GET", image_location)
+ response = connection.getresponse().read()
+ #Save image texture
+ image_filepath = os.path.join(mat_lib_folder, "my-materials", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ image_datablock = bpy.data.images.new(name=(image_name + ext), width=4, height=4)
+ image_datablock.source = node_data['source'].value
+ image_datablock.filepath = image_filepath
+ node.image = image_datablock
+ if node_data['source'].value == 'MOVIE' or node_data['source'].value == 'SEQUENCE':
+ node.image_user.frame_duration = int(node_data['frame_duration'].value)
+ node.image_user.frame_start = int(node_data['frame_start'].value)
+ node.image_user.frame_offset = int(node_data['frame_offset'].value)
+ node.image_user.use_cyclic = boolean(node_data['cyclic'].value)
+ node.image_user.use_auto_refresh = boolean(node_data['auto_refresh'].value)
+ else:
+ ext = "." + node_data['image'].value.split(".")[-1]
+ image_name = node_data['image'].value[:-4]
+
+ if ext.lower() != ".jpg" and ext.lower() != ".png":
+ node_message = ['ERROR', "The image file referenced by this image texture node is not .jpg or .png; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/textures/" + image_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache image texture
+ if library == "composite":
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ node_message = ['ERROR', "The image texture, \"%s\", is not cached; cannot download in offline mode." % (image_name + ext)]
+ image_filepath = ""
+ if image_filepath != "":
+ image_datablock = bpy.data.images.new(name=(image_name + ext), width=4, height=4)
+ image_datablock.source = node_data['source'].value
+ image_datablock.filepath = image_filepath
+ node.image = image_datablock
+ if node_data['source'].value == 'MOVIE' or node_data['source'].value == 'SEQUENCE':
+ node.image_user.frame_duration = int(node_data['frame_duration'].value)
+ node.image_user.frame_start = int(node_data['frame_start'].value)
+ node.image_user.frame_offset = int(node_data['frame_offset'].value)
+ node.image_user.use_cyclic = boolean(node_data['cyclic'].value)
+ node.image_user.use_auto_refresh = boolean(node_data['auto_refresh'].value)
+
+ elif node_type == "TEX_GRADIENT":
+ print ("TEX_GRADIENT")
+ node = node_tree.nodes.new(node_type)
+ node.gradient_type = node_data['gradient'].value
+
+ elif node_type == "TEX_IMAGE":
+ print ("TEX_IMAGE")
+ node = node_tree.nodes.new(node_type)
+ node.color_space = node_data['color_space'].value
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63 and "projection" in node_data:
+ node.projection = node_data['projection'].value
+ if 'image' in node_data:
+ if "file://" in node_data['image'].value:
+ image_filepath = node_data['image'].value[7:]
+ image_name = node_data['image'].value.split(os.sep)[-1]
+ image_datablock = bpy.data.images.new(name=image_name, width=4, height=4)
+ image_datablock.source = node_data['source'].value
+ image_datablock.filepath = image_filepath
+ node.image = image_datablock
+ if node_data['source'].value == 'MOVIE' or node_data['source'].value == 'SEQUENCE':
+ node.image_user.frame_duration = int(node_data['frame_duration'].value)
+ node.image_user.frame_start = int(node_data['frame_start'].value)
+ node.image_user.frame_offset = int(node_data['frame_offset'].value)
+ node.image_user.use_cyclic = boolean(node_data['cyclic'].value)
+ node.image_user.use_auto_refresh = boolean(node_data['auto_refresh'].value)
+ elif "http://" in node_data['image'].value and bpy.context.scene.mat_lib_images_only_trusted == False:
+ ext = "." + node_data['image'].value.split(".")[-1]
+ image_name = node_data['image'].value.split("/")[-1][:-4]
+ image_host = node_data['image'].value[7:].split("/")[0]
+ image_location = node_data['image'].value[(7 + len(image_host)):]
+
+ if ext.lower() != ".jpg" and ext.lower() != ".png":
+ node_message = ['ERROR', "The image file referenced by this image texture node is not .jpg or .png; not downloading."]
+ return
+
+ connection = http.client.HTTPConnection(image_host)
+ connection.request("GET", image_location)
+ response = connection.getresponse().read()
+ #Save image texture
+ image_filepath = os.path.join(mat_lib_folder, "my-materials", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ image_datablock = bpy.data.images.new(name=(image_name + ext), width=4, height=4)
+ image_datablock.source = node_data['source'].value
+ image_datablock.filepath = image_filepath
+ node.image = image_datablock
+ if node_data['source'].value == 'MOVIE' or node_data['source'].value == 'SEQUENCE':
+ node.image_user.frame_duration = int(node_data['frame_duration'].value)
+ node.image_user.frame_start = int(node_data['frame_start'].value)
+ node.image_user.frame_offset = int(node_data['frame_offset'].value)
+ node.image_user.use_cyclic = boolean(node_data['cyclic'].value)
+ node.image_user.use_auto_refresh = boolean(node_data['auto_refresh'].value)
+ else:
+ ext = "." + node_data['image'].value.split(".")[-1]
+ image_name = node_data['image'].value[:-4]
+
+ if ext.lower() != ".jpg" and ext.lower() != ".png":
+ node_message = ['ERROR', "The image file referenced by this image texture node is not .jpg or .png; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)):
+ image_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "textures", image_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/textures/" + image_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache image texture
+ if library == "composite":
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ image_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "textures", image_name + ext)
+ image_file = open(image_filepath, mode="w+b")
+ image_file.write(response)
+ image_file.close()
+ else:
+ node_message = ['ERROR', "The image texture, \"%s\", is not cached; cannot download in offline mode." % (image_name + ext)]
+ image_filepath = ""
+ if image_filepath != "":
+ image_datablock = bpy.data.images.new(name=(image_name + ext), width=4, height=4)
+ image_datablock.source = node_data['source'].value
+ image_datablock.filepath = image_filepath
+ node.image = image_datablock
+ if node_data['source'].value == 'MOVIE' or node_data['source'].value == 'SEQUENCE':
+ node.image_user.frame_duration = int(node_data['frame_duration'].value)
+ node.image_user.frame_start = int(node_data['frame_start'].value)
+ node.image_user.frame_offset = int(node_data['frame_offset'].value)
+ node.image_user.use_cyclic = boolean(node_data['cyclic'].value)
+ node.image_user.use_auto_refresh = boolean(node_data['auto_refresh'].value)
+
+ elif node_type == "TEX_MAGIC":
+ print ("TEX_MAGIC")
+ node = node_tree.nodes.new(node_type)
+ node.turbulence_depth = int(node_data['depth'].value)
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+ node.inputs['Distortion'].default_value = float(node_data['distortion'].value)
+
+ elif node_type == "TEX_MUSGRAVE":
+ print ("TEX_MUSGRAVE")
+ node = node_tree.nodes.new(node_type)
+ node.musgrave_type = node_data['musgrave'].value
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+ node.inputs['Detail'].default_value = float(node_data['detail'].value)
+ node.inputs['Dimension'].default_value = float(node_data['dimension'].value)
+ node.inputs['Lacunarity'].default_value = float(node_data['lacunarity'].value)
+ node.inputs['Offset'].default_value = float(node_data['offset'].value)
+ node.inputs['Gain'].default_value = float(node_data['gain'].value)
+
+ elif node_type == "TEX_NOISE":
+ print ("TEX_NOISE")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+ node.inputs['Detail'].default_value = float(node_data['detail'].value)
+ node.inputs['Distortion'].default_value = float(node_data['distortion'].value)
+
+ elif node_type == "TEX_SKY":
+ print ("TEX_SKY")
+ node = node_tree.nodes.new(node_type)
+ node.sun_direction = vector(node_data['sun_direction'].value)
+ node.turbidity = float(node_data['turbidity'].value)
+
+ elif node_type == "TEX_VORONOI":
+ print ("TEX_VORONOI")
+ node = node_tree.nodes.new(node_type)
+ node.coloring = node_data['coloring'].value
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+
+ elif node_type == "TEX_WAVE":
+ print ("TEX_WAVE")
+ node = node_tree.nodes.new(node_type)
+ node.wave_type = node_data['wave'].value
+ node.inputs['Scale'].default_value = float(node_data['scale'].value)
+ node.inputs['Distortion'].default_value = float(node_data['distortion'].value)
+ node.inputs['Detail'].default_value = float(node_data['detail'].value)
+ node.inputs['Detail Scale'].default_value = float(node_data['detail_scale'].value)
+
+ #COLOR TYPES
+ elif node_type == "BRIGHTCONTRAST":
+ print ("BRIGHTCONTRAST")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Bright'].default_value = float(node_data['bright'].value)
+ node.inputs['Contrast'].default_value = float(node_data['contrast'].value)
+
+ elif node_type == "GAMMA":
+ print ("GAMMA")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+ node.inputs['Gamma'].default_value = float(node_data['gamma'].value)
+
+ elif node_type == "HUE_SAT":
+ print ("HUE_SAT")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Hue'].default_value = float(node_data['hue'].value)
+ node.inputs['Saturation'].default_value = float(node_data['saturation'].value)
+ node.inputs['Value'].default_value = float(node_data['value'].value)
+ node.inputs['Fac'].default_value = float(node_data['fac'].value)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "INVERT":
+ print ("INVERT")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Fac'].default_value = float(node_data['fac'].value)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "LIGHT_FALLOFF":
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ print ("LIGHT_FALLOFF")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Strength'].default_value = float(node_data['strength'].value)
+ node.inputs['Smooth'].default_value = float(node_data['smooth'].value)
+
+ elif node_type == "MIX_RGB":
+ print ("MIX_RGB")
+ node = node_tree.nodes.new(node_type)
+ node.blend_type = node_data['blend_type'].value
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63 and "clamp" in node_data:
+ node.use_clamp = boolean(node_data['clamp'].value)
+ node.inputs['Fac'].default_value = float(node_data['fac'].value)
+ node.inputs['Color1'].default_value = color(node_data['color1'].value)
+ node.inputs['Color2'].default_value = color(node_data['color2'].value)
+
+ #VECTOR TYPES
+ elif node_type == "BUMP":
+ print ("BUMP")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.inputs["Strength"].default_value = float(node_data['strength'].value)
+
+ elif node_type == "MAPPING":
+ print ("MAPPING")
+ node = node_tree.nodes.new(node_type)
+ node.translation = vector(node_data['translation'].value)
+ node.rotation = vector(node_data['rotation'].value)
+ node.scale = vector(node_data['scale'].value)
+ if boolean(node_data['use_min'].value):
+ node.use_min = True
+ node.min = vector(node_data['min'].value)
+ if boolean(node_data['use_max'].value):
+ node.use_max = True
+ node.max = vector(node_data['max'].value)
+ node.inputs['Vector'].default_value = vector(node_data['vector'].value)
+
+ elif node_type == "NORMAL":
+ print ("NORMAL")
+ node = node_tree.nodes.new(node_type)
+ node.outputs['Normal'].default_value = vector(node_data['vector_output'].value)
+ node.inputs['Normal'].default_value = vector(node_data['vector_input'].value)
+
+ elif node_type == "NORMAL_MAP":
+ print ("NORMAL_MAP")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ node = node_tree.nodes.new(node_type)
+ node.space = node_data['space'].value
+ node.uv_map = node_data['uv_map'].value
+ node.inputs["Strength"].default_value = float(node_data['strength'].value)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ #CONVERTOR TYPES
+ elif node_type == "COMBRGB":
+ print ("COMBRGB")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['R'].default_value = float(node_data['red'].value)
+ node.inputs['G'].default_value = float(node_data['green'].value)
+ node.inputs['B'].default_value = float(node_data['blue'].value)
+
+ elif node_type == "MATH":
+ print ("MATH")
+ node = node_tree.nodes.new(node_type)
+ node.operation = node_data['operation'].value
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63 and "clamp" in node_data:
+ node.use_clamp = boolean(node_data['clamp'].value)
+ node.inputs[0].default_value = float(node_data['value1'].value)
+ node.inputs[1].default_value = float(node_data['value2'].value)
+
+ elif node_type == "RGBTOBW":
+ print ("RGBTOBW")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Color'].default_value = color(node_data['color'].value)
+
+ elif node_type == "SEPRGB":
+ print ("SEPRGB")
+ node = node_tree.nodes.new(node_type)
+ node.inputs['Image'].default_value = color(node_data['image'].value)
+
+ elif node_type == "VALTORGB":
+ print ("VALTORGB")
+ node = node_tree.nodes.new(node_type)
+ node.color_ramp.interpolation = node_data['interpolation'].value
+ node.inputs['Fac'].default_value = float(node_data['fac'].value)
+
+ #Delete the first stop which comes with the ramp by default
+ node.color_ramp.elements.remove(node.color_ramp.elements[0])
+
+ # The first stop will be "stop1", so set i to 1
+ i = 1
+ while i <= int(node_data['stops'].value):
+ #Each color stop element is formatted like this:
+ # stop1="0.35|rgba(1, 0.5, 0.8, 0.5)"
+ #The "|" separates the stop's position and color.
+ element_data = node_data[("stop" + str(i))].value.split('|')
+ if i == 1:
+ element = node.color_ramp.elements[0]
+ element.position = float(element_data[0])
+ else:
+ element = node.color_ramp.elements.new(float(element_data[0]))
+ element.color = color(element_data[1])
+ i = i + 1
+
+ elif node_type == "VECT_MATH":
+ print ("VECT_MATH")
+ node = node_tree.nodes.new(node_type)
+ node.operation = node_data['operation'].value
+ node.inputs[0].default_value = vector(node_data['vector1'].value)
+ node.inputs[1].default_value = vector(node_data['vector2'].value)
+
+ #MISCELLANEOUS NODE TYPES
+ elif node_type == "FRAME":
+ #Don't attempt to add frame nodes in builds previous
+ #to rev51926, as Blender's nodes.new() operator was
+ #unable to add FRAME nodes. Was fixed with rev51926.
+ if int(bpy.app.build_revision.decode()) > 51925:
+ print("FRAME")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "REROUTE":
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.64:
+ node_message = ['ERROR', """The material file contains the node \"%s\".
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly.""" % node_type]
+ return
+ print ("REROUTE")
+ node = node_tree.nodes.new(node_type)
+
+ elif node_type == "SCRIPT":
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) < 2.65:
+ node_message = ['ERROR', """The material file contains an OSL script node.
+This node is not available in the Blender version you are currently using.
+You may need a newer version of Blender for this material to work properly."""]
+ return
+ print ("SCRIPT")
+ node = node_tree.nodes.new(node_type)
+ node.mode = node_data['mode'].value
+ if node_data['mode'].value == 'EXTERNAL':
+ if 'script' in node_data:
+ if "file://" in node_data['script'].value:
+ node.filepath = node_data['script'].value[7:]
+ elif "http://" in node_data['script'].value and bpy.context.scene.mat_lib_osl_only_trusted == False:
+ ext = "." + node_data['script'].value.split(".")[-1]
+ script_name = node_data['script'].value.split("/")[-1][:-4]
+ osl_host = node_data['script'].value[7:].split("/")[0]
+ script_location = node_data['script'].value[(7 + len(osl_host)):]
+
+ if ext.lower() != ".osl" and ext.lower() != ".oso":
+ node_message = ['ERROR', "The OSL script file referenced by this script node is not .osl or .oso; not downloading."]
+ return
+
+ connection = http.client.HTTPConnection(osl_host)
+ connection.request("GET", script_location + script_name + ext)
+ response = connection.getresponse().read()
+ #Save OSL script
+ osl_filepath = os.path.join(mat_lib_folder, "my-materials", script_name + ext)
+ osl_file = open(osl_filepath, mode="w+b")
+ osl_file.write(response)
+ osl_file.close()
+ node.filepath = osl_filepath
+
+ else:
+ ext = "." + node_data['script'].value.split(".")[-1]
+ script_name = node_data['script'].value[:-4]
+
+ if ext.lower() != ".osl" and ext.lower() != ".oso":
+ node_message = ['ERROR', "The OSL script file referenced by this script node is not .osl or .oso; not downloading."]
+ return
+
+ if library == "composite" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)):
+ osl_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)
+ elif library != "bundled" and os.path.exists(os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)):
+ osl_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)
+ elif library == "bundled" and os.path.exists(os.path.join(mat_lib_folder, "bundled", "cycles", "scripts", script_name + ext)):
+ osl_filepath = os.path.join(mat_lib_folder, "bundled", "cycles", "scripts", script_name + ext)
+ elif working_mode == "online":
+ connection = http.client.HTTPConnection(mat_lib_host)
+ connection.request("GET", mat_lib_location + "cycles/scripts/" + script_name + ext)
+ response = connection.getresponse().read()
+
+ #Cache OSL script
+ if library == "composite":
+ osl_filepath = os.path.join(mat_lib_folder, mat_lib_host, "cycles", "scripts", script_name + ext)
+ osl_file = open(osl_filepath, mode="w+b")
+ osl_file.write(response)
+ osl_file.close()
+ else:
+ osl_filepath = os.path.join(mat_lib_folder, mat_lib_host, library, "cycles", "scripts", script_name + ext)
+ osl_file = open(osl_filepath, mode="w+b")
+ osl_file.write(response)
+ osl_file.close()
+ else:
+ node_message = ['ERROR', "The OSL script, \"%s\", is not cached; cannot download in offline mode." % (script_name + ext)]
+ osl_filepath = ""
+ node.filepath = osl_filepath
+ else:
+ if 'script' in node_data:
+ node.script = osl_scripts[int(node_data['script'].value)]
+ if node.inputs:
+ for input in node.inputs:
+ if input.name.lower() in node_data:
+ if input.type == 'RGBA':
+ input.default_value = color(node_data[input.name.lower()].value)
+ elif input.type == 'VECTOR':
+ input.default_value = vector(node_data[input.name.lower()].value)
+ elif input.type == 'VALUE':
+ input.default_value = float(node_data[input.name.lower()].value)
+ elif input.type == 'INT':
+ input.default_value = int(node_data[input.name.lower()].value)
+ elif input.type == 'BOOL':
+ input.default_value = boolean(node_data[input.name.lower()].value)
+ else:
+ input.default_value = str(node_data[input.name.lower()].value)
+ else:
+ node_message = ['WARNING', "There was no value specified for input \"%s\", leaving at default." % input.name]
+
+ else:
+ node_message = ['ERROR', """The material file contains the node name \"%s\", which is not known.
+The material file may contain an error, or you may need to check for updates to this add-on.""" % node_type]
+ return
+ node.location = node_location
+
+ #Give the node a custom label
+ if 'label' in node_data:
+ node.label = node_data['label'].value
+
+ #Give the node a custom color
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63:
+ if 'custom_color' in node_data:
+ node.use_custom_color = True
+ node.color = color(node_data['custom_color'].value)
+
+ #Collapse node if needed
+ if 'hide' in node_data:
+ node.hide = boolean(node_data['hide'].value)
+
+def boolean(string):
+ if string == "True":
+ boolean = True
+ elif string == "False":
+ boolean = False
+ elif string == "true":
+ boolean = True
+ elif string == "false":
+ boolean = False
+ else:
+ print('Error converting string to a boolean')
+ return
+ return boolean
+
+def color(string):
+ if "rgba" in string:
+ colors = string[5:-1].replace(" ", "").split(",")
+ r = float(colors[0])
+ g = float(colors[1])
+ b = float(colors[2])
+ a = float(colors[3])
+ color = [r,g,b,a]
+ elif "rgb" in string:
+ colors = string[4:-1].replace(" ", "").split(",")
+ r = float(colors[0])
+ g = float(colors[1])
+ b = float(colors[2])
+ color = [r,g,b]
+ else:
+ print('Error converting string to a color')
+ return
+ return color
+
+def vector(string):
+ import mathutils
+ if "Vector" in string:
+ vectors = string[7:-1].replace(" ", "").split(",")
+ x = float(vectors[0])
+ y = float(vectors[1])
+ z = float(vectors[2])
+ vector = mathutils.Vector((x, y, z))
+ else:
+ print('Error converting string to a vector')
+ return
+ return vector
+
+class MaterialConvert(bpy.types.Operator):
+ '''Convert material(s) to the .bcm format'''
+ bl_idname = "material.libraryconvert"
+ bl_label = "Convert Cycles Material to .bcm"
+ save_location = bpy.props.StringProperty()
+ all_materials = bpy.props.BoolProperty()
+
+ def execute(self, context):
+ global material_file_contents
+ global script_stack
+
+ if self.all_materials:
+ #For all_materials, access the materials with an index
+ mat = 0
+ loop_length = len(bpy.data.materials)
+ else:
+ if not context.active_object:
+ if not context.active_object.get("active_material"):
+ self.save_location = ""
+ self.all_materials = False
+ self.report({'ERROR'}, "No material selected!")
+ return {'CANCELLED'}
+ self.save_location = ""
+ self.all_materials = False
+ self.report({'ERROR'}, "No object selected!")
+ return {'CANCELLED'}
+ #For single materials, access the materials with a name
+ mat = context.active_object.active_material.name
+ loop_length = 1
+
+ if self.save_location is "":
+ if context.scene.mat_lib_bcm_write is not "":
+ txt = context.scene.mat_lib_bcm_write
+ else:
+ txt = "bcm_file"
+
+ if txt not in bpy.data.texts:
+ bpy.data.texts.new(txt)
+
+ j = 0
+ while j < loop_length:
+ if self.save_location is not "":
+ if self.all_materials:
+ filename = bpy.data.materials[mat].name.replace("(", "")
+ else:
+ filename = mat.replace("(", "")
+ filename = filename.replace(")", "")
+ filename = filename.replace("!", "")
+ filename = filename.replace("@", "")
+ filename = filename.replace("#", "")
+ filename = filename.replace("$", "")
+ filename = filename.replace("%", "")
+ filename = filename.replace("&", "")
+ filename = filename.replace("*", "")
+ filename = filename.replace("/", "")
+ filename = filename.replace("|", "")
+ filename = filename.replace("\\", "")
+ filename = filename.replace("'", "")
+ filename = filename.replace("\"", "")
+ filename = filename.replace("?", "")
+ filename = filename.replace(";", "")
+ filename = filename.replace(":", "")
+ filename = filename.replace("[", "")
+ filename = filename.replace("]", "")
+ filename = filename.replace("{", "")
+ filename = filename.replace("}", "")
+ filename = filename.replace("`", "")
+ filename = filename.replace("~", "")
+ filename = filename.replace("+", "")
+ filename = filename.replace("=", "")
+ filename = filename.replace(".", "")
+ filename = filename.replace(",", "")
+ filename = filename.replace("<", "")
+ filename = filename.replace(">", "")
+ filename = filename.replace(" ", "_")
+ filename = filename.replace("-", "_")
+ filename = filename.lower()
+
+ material_file_contents = ""
+ write('<?xml version="1.0" encoding="UTF-8"?>')
+
+ red = smallFloat(bpy.data.materials[mat].diffuse_color.r)
+ green = smallFloat(bpy.data.materials[mat].diffuse_color.g)
+ blue = smallFloat(bpy.data.materials[mat].diffuse_color.b)
+ write("\n<material view_color=\"%s\"" % ("rgb(" + red + ", " + green + ", " + blue + ")"))
+
+ write(" sample_lamp=\"" + str(bpy.data.materials[mat].cycles.sample_as_light) + "\">")
+ write("\n\t<nodes>")
+
+ group_warning = False
+ frame_warning = False
+ for node in bpy.data.materials[mat].node_tree.nodes:
+ if "NodeGroup" in str(node.items):
+ node_type = "GROUP"
+ group_warning = True
+
+ elif node.type == 'FRAME' and int(bpy.app.build_revision.decode()) < 51926:
+ #Don't attempt to write frame nodes in builds previous
+ #to rev51926, as Blender's nodes.new() operator was
+ #unable to add FRAME nodes. Was fixed with rev51926.
+ frame_warning = True
+ print("Skipping frame node; this Blender version will not support adding it back."\
+ "\nFrame nodes are not supported on builds prior to rev51926.")
+ else:
+ node_type = node.type
+ #Write node opening bracket
+ write("\n\t\t<node ")
+
+ #Write node type
+ write("type=\"%s\"" % node_type)
+
+ #Write node custom color
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63:
+ if node.use_custom_color:
+ r = smallFloat(node.color.r)
+ g = smallFloat(node.color.g)
+ b = smallFloat(node.color.b)
+ write(" custom_color=\"%s\"" % ("rgb(" + r + ", " + g + ", " + b + ")"))
+
+ #Write node label
+ if node.label:
+ write(" label=\"%s\"" % node.label)
+
+ #Write node hidden-ness
+ if node.hide:
+ write(" hide=\"True\"")
+
+ #Write node data
+ writeNodeData(node)
+
+ #Write node closing bracket
+ write(" />")
+
+ write("\n\t</nodes>")
+
+ write("\n\t<links>")
+ writeNodeLinks(bpy.data.materials[mat].node_tree)
+ write("\n\t</links>")
+ if script_stack:
+ write("\n\t<scripts>")
+ i = 0
+ while i < len(script_stack):
+ write("\n\t\t<script name=\"%s\" id=\"%s\">\n" % (script_stack[i], str(i)))
+ first_line = True
+ for l in bpy.data.texts[script_stack[i]].lines:
+ if first_line == True:
+ write(l.body.replace("<", "lt;").replace(">", "gt;"))
+ first_line = False
+ else:
+ write("<br />" + l.body.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """))
+ write("\n\t\t</script>")
+ i += 1
+ write("\n\t</scripts>")
+ script_stack = []
+ write("\n</material>")
+
+ if self.save_location == "":
+ if group_warning:
+ self.report({'ERROR'}, "Material \"" + mat + "\" contains a group node (not supported). Please un-group the nodes and try again.")
+ else:
+ bpy.data.texts[txt].clear()
+ bpy.data.texts[txt].write(material_file_contents)
+ if not self.all_materials:
+ if frame_warning:
+ self.report({'WARNING'}, "Material \"" + mat + "\" contains a frame node, which was skipped; see console for details.")
+ else:
+ self.report({'INFO'}, "Material \"" + mat + "\" written to Text \"" + txt + "\" as .bcm")
+ else:
+ if group_warning:
+ self.report({'ERROR'}, "Material \"" + mat + "\" contains a group node (not supported). Please un-group the nodes and try again.")
+ else:
+ print(context.scene.mat_lib_bcm_save_location + filename + ".bcm")
+ bcm_file = open(context.scene.mat_lib_bcm_save_location + filename + ".bcm", mode="w", encoding="UTF-8")
+ bcm_file.write(material_file_contents)
+ bcm_file.close()
+ if not self.all_materials:
+ if frame_warning:
+ self.report({'WARNING'}, "Material \"" + mat + "\" contains a frame node which was skipped; see console for details.")
+ self.report({'WARNING'}, "Material \"" + mat + "\" contains a frame node which was skipped; see console for details.")
+ else:
+ self.report({'INFO'}, "Material \"" + mat + "\" saved to \"" + filename + ".bcm\"")
+ j += 1
+ if self.all_materials:
+ mat += 1
+ if self.all_materials and not group_warning and not frame_warning:
+ self.report({'INFO'}, "All materials successfully saved!")
+
+ self.save_location = ""
+ self.all_materials = False
+ return {'FINISHED'}
+
+def writeNodeData(node):
+ global material_file_contents
+ global script_stack
+
+ I = node.inputs
+ O = node.outputs
+
+ if "NodeGroup" in str(node.items):
+ node_type = "GROUP"
+ else:
+ node_type = node.type
+
+ if node_type == "GROUP":
+ print("GROUP NODE!")
+ write("ERROR: GROUP NODES NOT YET SUPPORTED.")
+
+ #INPUT TYPES
+ elif node_type == "ATTRIBUTE":
+ print("ATTRIBUTE")
+ write(" attribute=\"%s\"" % node.attribute_name)
+
+ elif node_type == "CAMERA":
+ print("CAMERA")
+
+ elif node_type == "FRESNEL":
+ print("FRESNEL")
+ write(" ior=\"%s\"" % smallFloat(I['IOR'].default_value))
+
+ elif node_type == "LAYER_WEIGHT":
+ print("LAYER_WEIGHT")
+ write(" blend=\"%s\"" % smallFloat(I['Blend'].default_value))
+
+ elif node_type == "LIGHT_PATH":
+ print("LIGHT_PATH")
+
+ elif node_type == "NEW_GEOMETRY":
+ print("NEW_GEOMETRY")
+
+ elif node_type == "OBJECT_INFO":
+ print("OBJECT_INFO")
+
+ elif node_type == "PARTICLE_INFO":
+ print("PARTICLE_INFO")
+
+ elif node_type == "RGB":
+ print("RGB")
+ write(" color=\"%s\"" % rgba(O['Color'].default_value))
+
+ elif node_type == "TANGENT":
+ print("TANGENT")
+ write(" direction=\"%s\"" % node.direction_type)
+ write(" axis=\"%s\"" % node.axis)
+
+ elif node_type == "TEX_COORD":
+ print("TEX_COORD")
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.64:
+ write(" dupli=\"%s\"" % node.from_dupli)
+ else:
+ write(" dupli=\"False\"")
+
+ elif node_type == "VALUE":
+ print("VALUE")
+ write(" value=\"%s\"" % smallFloat(O['Value'].default_value))
+
+ #OUTPUT TYPES
+ elif node_type == "OUTPUT_LAMP":
+ print("OUTPUT_LAMP")
+
+ elif node_type == "OUTPUT_MATERIAL":
+ print("OUTPUT_MATERIAL")
+
+ elif node_type == "OUTPUT_WORLD":
+ print("OUTPUT_WORLD")
+
+ #SHADER TYPES
+ elif node_type == "ADD_SHADER":
+ print("ADD_SHADER")
+
+ elif node_type == "AMBIENT_OCCLUSION":
+ print("AMBIENT_OCCLUSION")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ elif node_type == "BACKGROUND":
+ print("BACKGROUND")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" strength=\"%s\"" % smallFloat(I['Strength'].default_value))
+
+ elif node_type == "BSDF_ANISOTROPIC":
+ print("BSDF_ANISOTROPIC")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" roughness=\"%s\"" % smallFloat(I['Roughness'].default_value))
+ write(" anisotropy=\"%s\"" % smallFloat(I['Anisotropy'].default_value))
+ write(" rotation=\"%s\"" % smallFloat(I['Rotation'].default_value))
+
+ elif node_type == "BSDF_DIFFUSE":
+ print("BSDF_DIFFUSE")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" roughness=\"%s\"" % smallFloat(I['Roughness'].default_value))
+
+ elif node_type == "BSDF_GLASS":
+ print("BSDF_GLASS")
+ write(" distribution=\"%s\"" % node.distribution)
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" roughness=\"%s\"" % smallFloat(I['Roughness'].default_value))
+ write(" ior=\"%s\"" % smallFloat(I['IOR'].default_value))
+
+ elif node_type == "BSDF_GLOSSY":
+ print("BSDF_GLOSSY")
+ write(" distribution=\"%s\"" % node.distribution)
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" roughness=\"%s\"" % smallFloat(I['Roughness'].default_value))
+
+ elif node_type == "BSDF_REFRACTION":
+ print("BSDF_REFRACTION")
+ write(" distribution=\"%s\"" % node.distribution)
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" roughness=\"%s\"" % smallFloat(I['Roughness'].default_value))
+ write(" ior=\"%s\"" % smallFloat(I['IOR'].default_value))
+
+ elif node_type == "BSDF_TRANSLUCENT":
+ print("BSDF_TRANSLUCENT")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ elif node_type == "BSDF_TRANSPARENT":
+ print("BSDF_TRANSPARENT")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ elif node_type == "BSDF_VELVET":
+ print("BSDF_VELVET")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" sigma=\"%s\"" % smallFloat(I['Sigma'].default_value))
+
+ elif node_type == "EMISSION":
+ print("EMISSION")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" strength=\"%s\"" % smallFloat(I['Strength'].default_value))
+
+ elif node_type == "HOLDOUT":
+ print("HOLDOUT")
+
+ elif node_type == "MIX_SHADER":
+ print("MIX_SHADER")
+ write(" fac=\"%s\"" % smallFloat(I['Fac'].default_value))
+
+ #TEXTURE TYPES
+ elif node_type == "TEX_BRICK":
+ print ("TEX_BRICK")
+ write(" offset=\"%s\"" % smallFloat(node.offset))
+ write(" offset_freq=\"%s\"" % str(node.offset_frequency))
+ write(" squash=\"%s\"" % smallFloat(node.squash))
+ write(" squash_freq=\"%s\"" % str(node.squash_frequency))
+ write(" color1=\"%s\"" % rgba(I['Color1'].default_value))
+ write(" color2=\"%s\"" % rgba(I['Color2'].default_value))
+ write(" mortar=\"%s\"" % rgba(I['Mortar'].default_value))
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+ write(" mortar_size=\"%s\"" % smallFloat(I['Mortar Size'].default_value))
+ write(" bias=\"%s\"" % smallFloat(I['Bias'].default_value))
+ write(" width=\"%s\"" % smallFloat(I['Brick Width'].default_value))
+ write(" height=\"%s\"" % smallFloat(I['Row Height'].default_value))
+
+ elif node_type == "TEX_CHECKER":
+ print("TEX_CHECKER")
+ write(" color1=\"%s\"" % rgba(I['Color1'].default_value))
+ write(" color2=\"%s\"" % rgba(I['Color2'].default_value))
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+
+ elif node_type == "TEX_ENVIRONMENT":
+ print("TEX_ENVIRONMENT")
+ if node.image:
+ write(" image=\"file://%s\"" % os.path.realpath(bpy.path.abspath(node.image.filepath)))
+ write(" source=\"%s\"" % node.image.source)
+ if node.image.source == "SEQUENCE" or node.image.source == "MOVIE":
+ write(" frame_duration=\"%s\"" % str(node.image_user.frame_duration))
+ write(" frame_start=\"%s\"" % str(node.image_user.frame_start))
+ write(" frame_offset=\"%s\"" % str(node.image_user.frame_offset))
+ write(" cyclic=\"%s\"" % str(node.image_user.use_cyclic))
+ write(" auto_refresh=\"%s\"" % str(node.image_user.use_auto_refresh))
+ else:
+ write(" image=\"\"")
+ write(" color_space=\"%s\"" % node.color_space)
+ write(" projection=\"%s\"" % node.projection)
+
+ elif node_type == "TEX_GRADIENT":
+ print("TEX_GRADIENT")
+ write(" gradient=\"%s\"" % node.gradient_type)
+
+ elif node_type == "TEX_IMAGE":
+ print("TEX_IMAGE")
+ if node.image:
+ write(" image=\"file://%s\"" % os.path.realpath(bpy.path.abspath(node.image.filepath)))
+ write(" source=\"%s\"" % node.image.source)
+ if node.image.source == "SEQUENCE" or node.image.source == "MOVIE":
+ write(" frame_duration=\"%s\"" % str(node.image_user.frame_duration))
+ write(" frame_start=\"%s\"" % str(node.image_user.frame_start))
+ write(" frame_offset=\"%s\"" % str(node.image_user.frame_offset))
+ write(" cyclic=\"%s\"" % str(node.image_user.use_cyclic))
+ write(" auto_refresh=\"%s\"" % str(node.image_user.use_auto_refresh))
+ else:
+ write(" image=\"\"")
+ write(" color_space=\"%s\"" % node.color_space)
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63:
+ write(" projection=\"%s\"" % node.projection)
+ if node.projection == "BOX":
+ write(" blend=\"%s\"" % smallFloat(node.projection_blend))
+ else:
+ write(" projection=\"FLAT\"")
+
+ elif node_type == "TEX_MAGIC":
+ print("TEX_MAGIC")
+ write(" depth=\"%s\"" % str(node.turbulence_depth))
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+ write(" distortion=\"%s\"" % smallFloat(I['Distortion'].default_value))
+
+ elif node_type == "TEX_MUSGRAVE":
+ print("TEX_MUSGRAVE")
+ write(" musgrave=\"%s\"" % node.musgrave_type)
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+ write(" detail=\"%s\"" % smallFloat(I['Detail'].default_value))
+ write(" dimension=\"%s\"" % smallFloat(I['Dimension'].default_value))
+ write(" lacunarity=\"%s\"" % smallFloat(I['Lacunarity'].default_value))
+ write(" offset=\"%s\"" % smallFloat(I['Offset'].default_value))
+ write(" gain=\"%s\"" % smallFloat(I['Gain'].default_value))
+
+ elif node_type == "TEX_NOISE":
+ print("TEX_NOISE")
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+ write(" detail=\"%s\"" % smallFloat(I['Detail'].default_value))
+ write(" distortion=\"%s\"" % smallFloat(I['Distortion'].default_value))
+
+ elif node_type == "TEX_SKY":
+ print("TEX_SKY")
+ write(" sun_direction=\"%s\"" % smallVector(node.sun_direction))
+ write(" turbidity=\"%s\"" % smallFloat(node.turbidity))
+
+ elif node_type == "TEX_VORONOI":
+ print("TEX_VORONOI")
+ write(" coloring=\"%s\"" % node.coloring)
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+
+ elif node_type == "TEX_WAVE":
+ print("TEX_WAVE")
+ write(" wave=\"%s\"" % node.wave_type)
+ write(" scale=\"%s\"" % smallFloat(I['Scale'].default_value))
+ write(" distortion=\"%s\"" % smallFloat(I['Distortion'].default_value))
+ write(" detail=\"%s\"" % smallFloat(I['Detail'].default_value))
+ write(" detail_scale=\"%s\"" % smallFloat(I['Detail Scale'].default_value))
+
+ #COLOR TYPES
+ elif node_type == "BRIGHTCONTRAST":
+ print("BRIGHTCONTRAST")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" bright=\"%s\"" % smallFloat(I['Bright'].default_value))
+ write(" contrast=\"%s\"" % smallFloat(I['Contrast'].default_value))
+
+ elif node_type == "GAMMA":
+ print("GAMMA")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+ write(" gamma=\"%s\"" % smallFloat(I['Gamma'].default_value))
+
+ elif node_type == "HUE_SAT":
+ print("HUE_SAT")
+ write(" hue=\"%s\"" % smallFloat(I['Hue'].default_value))
+ write(" saturation=\"%s\"" % smallFloat(I['Saturation'].default_value))
+ write(" value=\"%s\"" % smallFloat(I['Value'].default_value))
+ write(" fac=\"%s\"" % smallFloat(I['Fac'].default_value))
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ elif node_type == "LIGHT_FALLOFF":
+ print("LIGHT_FALLOFF")
+ write(" strength=\"%s\"" % smallFloat(I['Strength'].default_value))
+ write(" smooth=\"%s\"" % smallFloat(I['Smooth'].default_value))
+
+ elif node_type == "MIX_RGB":
+ print("MIX_RGB")
+ write(" blend_type=\"%s\"" % node.blend_type)
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63:
+ write(" use_clamp=\"%s\"" % str(node.use_clamp))
+ write(" fac=\"%s\"" % smallFloat(I['Fac'].default_value))
+ write(" color1=\"%s\"" % rgba(I[1].default_value))
+ write(" color2=\"%s\"" % rgba(I[2].default_value))
+
+ elif node_type == "INVERT":
+ print("INVERT")
+ write(" fac=\"%s\"" % smallFloat(I['Fac'].default_value))
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ #VECTOR TYPES
+ elif node_type == "BUMP":
+ print("BUMP")
+ write(" strength=\"%s\"" % smallFloat(I['Strength'].default_value))
+
+ elif node_type == "MAPPING":
+ print("MAPPING")
+ write(" translation=\"%s\"" % smallVector(node.translation))
+ write(" rotation=\"%s\"" % smallVector(node.rotation))
+ write(" scale=\"%s\"" % smallVector(node.scale))
+
+ write(" use_min=\"%s\"" % str(node.use_min))
+ if node.use_min:
+ write(" min=\"%s\"" % smallVector(node.min))
+
+ write(" use_max=\"%s\"" % str(node.use_max))
+ if node.use_max:
+ write(" max=\"%s\"" % smallVector(node.max))
+
+ vec = I[0].default_value
+ write(" vector=\"%s\"" % smallVector(I['Vector'].default_value))
+
+ elif node_type == "NORMAL":
+ print("NORMAL")
+ write(" vector_output=\"%s\"" % smallVector(O['Normal'].default_value))
+ write(" vector_input=\"%s\"" % smallVector(I['Normal'].default_value))
+
+ elif node_type == "NORMAL_MAP":
+ print("NORMAL_MAP")
+ write(" space=\"%s\"" % node.space)
+ write(" uv_map=\"%s\"" % node.uv_map)
+ write(" strength=\"%s\"" % smallFloat(I['Strength'].default_value))
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ #CONVERTER TYPES
+ elif node_type == "COMBRGB":
+ print("COMBRGB")
+ write(" red=\"%s\"" % smallFloat(I['R'].default_value))
+ write(" green=\"%s\"" % smallFloat(I['G'].default_value))
+ write(" blue=\"%s\"" % smallFloat(I['B'].default_value))
+
+ elif node_type == "MATH":
+ print("MATH")
+ write(" operation=\"%s\"" % node.operation)
+ if bpy.app.version[0] + (bpy.app.version[1] / 100.0) > 2.63:
+ write(" use_clamp=\"%s\"" % str(node.use_clamp))
+ write(" value1=\"%s\"" % smallFloat(I[0].default_value))
+ write(" value2=\"%s\"" % smallFloat(I[1].default_value))
+
+ elif node_type == "RGBTOBW":
+ print ("RGBTOBW")
+ write(" color=\"%s\"" % rgba(I['Color'].default_value))
+
+ elif node_type == "SEPRGB":
+ print("SEPRGB")
+ write(" image=\"%s\"" % rgba(I['Image'].default_value))
+
+ elif node_type == "VALTORGB":
+ print("VALTORGB")
+ write(" interpolation=\"%s\"" % str(node.color_ramp.interpolation))
+ write(" fac=\"%s\"" % smallFloat(I['Fac'].default_value))
+ write(" stops=\"%s\"" % str(len(node.color_ramp.elements)))
+
+ k = 1
+ while k <= len(node.color_ramp.elements):
+ write(" stop%s=\"%s\"" %
+ (str(k),
+ (smallFloat(node.color_ramp.elements[k-1].position) +
+ "|" +
+ rgba(node.color_ramp.elements[k-1].color))
+ ))
+ k += 1
+
+ elif node_type == "VECT_MATH":
+ print("VECT_MATH")
+ write(" operation=\"%s\"" % node.operation)
+ write(" vector1=\"%s\"" % smallVector(I[0].default_value))
+ write(" vector2=\"%s\"" % smallVector(I[1].default_value))
+
+ #MISCELLANEOUS NODE TYPES
+ elif node_type == "FRAME":
+ print("FRAME")
+
+ elif node_type == "REROUTE":
+ print("REROUTE")
+
+ elif node_type == "SCRIPT":
+ print("SCRIPT")
+ write(" mode=\"%s\"" % node.mode)
+ if node.mode == 'EXTERNAL':
+ if node.filepath:
+ write(" script=\"file://%s\"" % os.path.realpath(bpy.path.abspath(node.filepath)))
+ else:
+ if node.script:
+ write(" script=\"%s\"" % len(script_stack))
+ script_stack.append(node.script.name)
+ if node.inputs:
+ for input in node.inputs:
+ if input.type == 'RGBA':
+ input_value = rgba(input.default_value)
+ elif input.type == 'VECTOR':
+ input_value = smallVector(input.default_value)
+ elif input.type == 'VALUE':
+ input_value = smallFloat(input.default_value)
+ elif input.type == 'INT':
+ input_value = str(input.default_value)
+ elif input.type == 'BOOL':
+ input_value = str(input.default_value)
+ else:
+ input_value = str(input.default_value)
+
+ write(" %s=\"%s\"" % (input.name.lower(), input_value))
+ else:
+ write(" ERROR: UNKNOWN NODE TYPE. ")
+ return
+ writeLocation(node)
+
+def rgba(color):
+ red = smallFloat(color[0])
+ green = smallFloat(color[1])
+ blue = smallFloat(color[2])
+ alpha = smallFloat(color[3])
+ return ("rgba(" + red + ", " + green + ", " + blue + ", " + alpha + ")")
+
+def smallFloat(float):
+ if len(str(float)) < (6 + str(float).index(".")):
+ return str(float)
+ else:
+ return str(float)[:(6 + str(float).index("."))]
+
+def smallVector(vector):
+ return "Vector(" + smallFloat(vector[0]) + ", " + smallFloat(vector[1]) + ", " + smallFloat(vector[2]) + ")"
+
+def write (string):
+ global material_file_contents
+ material_file_contents += string
+
+def writeLocation(node):
+ global material_file_contents
+ #X location
+ x = str(int(node.location.x))
+ #Y location
+ y = str(int(node.location.y))
+
+ material_file_contents += (" loc=\"" + x + ", " + y + "\"")
+
+def writeNodeLinks(node_tree):
+ global material_file_contents
+
+ #Loop through the links
+ i = 0
+ while i < len(node_tree.links):
+ material_file_contents += ("\n\t\t<link ")
+
+ to_node_name = node_tree.links[i].to_node.name
+ #Loop through nodes to check name
+ e = 0
+ while e < len(node_tree.nodes):
+ #Write the index if name matches
+ if to_node_name == node_tree.nodes[e].name:
+ material_file_contents += "to=\"%d\"" % e
+ #Set input socket's name
+ to_socket = node_tree.links[i].to_socket.path_from_id()
+ material_file_contents += (" input=\"%s\"" % to_socket[(to_socket.index("inputs[") + 7):-1])
+ e = len(node_tree.nodes)
+ e = e + 1
+
+
+ from_node_name = node_tree.links[i].from_node.name
+ #Loop through nodes to check name
+ e = 0
+ while e < len(node_tree.nodes):
+ #Write the index if name matches
+ if from_node_name == node_tree.nodes[e].name:
+ material_file_contents += " from=\"%d\"" % e
+ #Set input socket's name
+ from_socket = node_tree.links[i].from_socket.path_from_id()
+ material_file_contents += (" output=\"%s\"" % from_socket[(from_socket.index("outputs[") + 8):-1])
+ e = len(node_tree.nodes)
+ e = e + 1
+ material_file_contents += (" />")
+ i = i + 1
+
+
+def register():
+ bpy.utils.register_class(OnlineMaterialLibraryPanel)
+ bpy.utils.register_class(LibraryConnect)
+ bpy.utils.register_class(LibraryInfo)
+ bpy.utils.register_class(LibrarySettings)
+ bpy.utils.register_class(LibraryTools)
+ bpy.utils.register_class(LibraryHome)
+ bpy.utils.register_class(ViewMaterial)
+ bpy.utils.register_class(MaterialDetailView)
+ bpy.utils.register_class(LibraryClearCache)
+ bpy.utils.register_class(LibraryPreview)
+ bpy.utils.register_class(AddLibraryMaterial)
+ bpy.utils.register_class(ApplyLibraryMaterial)
+ bpy.utils.register_class(CacheLibraryMaterial)
+ bpy.utils.register_class(SaveLibraryMaterial)
+ bpy.utils.register_class(MaterialConvert)
+
+
+def unregister():
+ bpy.utils.unregister_class(OnlineMaterialLibraryPanel)
+ bpy.utils.unregister_class(LibraryConnect)
+ bpy.utils.unregister_class(LibraryInfo)
+ bpy.utils.unregister_class(LibrarySettings)
+ bpy.utils.unregister_class(LibraryTools)
+ bpy.utils.unregister_class(LibraryHome)
+ bpy.utils.unregister_class(ViewMaterial)
+ bpy.utils.unregister_class(MaterialDetailView)
+ bpy.utils.unregister_class(LibraryClearCache)
+ bpy.utils.unregister_class(LibraryPreview)
+ bpy.utils.unregister_class(AddLibraryMaterial)
+ bpy.utils.unregister_class(ApplyLibraryMaterial)
+ bpy.utils.unregister_class(CacheLibraryMaterial)
+ bpy.utils.unregister_class(SaveLibraryMaterial)
+ bpy.utils.unregister_class(MaterialConvert)
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_coral.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_coral.bcm
new file mode 100644
index 0000000..5c13bd8
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_coral.bcm
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(1.0, 0.37373, 0.16895)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="1000, 250" />
+ <node type="MIX_SHADER" fac="0.05000" loc="750, 300" />
+ <node type="MIX_SHADER" fac="0.5" loc="500, 340" />
+ <node type="MATH" operation="LESS_THAN" use_clamp="False" value1="0.5" value2="0.25" loc="250, 500" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="10000.0" loc="0, 500" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="1.0" loc="250, 350" />
+ <node type="BRIGHTCONTRAST" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" bright="-0.89999" contrast="0.0" loc="-250, 350" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.15000" color1="rgba(0.80000, 0.80000, 0.80000, 1.0)" color2="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="0, 100" />
+ <node type="RGB" color="rgba(1.0, 0.13917, 0.0, 0.0)" loc="-464, -12" />
+ <node type="RGB" color="rgba(0.95332, 0.38194, 0.17285, 1.0)" loc="-469, 202" />
+ <node type="BSDF_GLOSSY" distribution="SHARP" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="493, 103" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.15000" loc="227, 106" />
+ <node type="BRIGHTCONTRAST" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" bright="-0.89999" contrast="0.0" loc="-220, -50" />
+ <node type="LAYER_WEIGHT" blend="0.89999" loc="-250, 149" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.15000" color1="rgba(0.80000, 0.80000, 0.80000, 1.0)" color2="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="39, 323" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="1" from="2" output="0" />
+ <link to="2" input="0" from="3" output="0" />
+ <link to="3" input="0" from="4" output="1" />
+ <link to="2" input="1" from="5" output="0" />
+ <link to="5" input="0" from="14" output="0" />
+ <link to="14" input="0" from="13" output="1" />
+ <link to="14" input="1" from="9" output="0" />
+ <link to="14" input="2" from="6" output="0" />
+ <link to="6" input="0" from="9" output="0" />
+ <link to="2" input="2" from="11" output="0" />
+ <link to="11" input="0" from="7" output="0" />
+ <link to="7" input="0" from="13" output="1" />
+ <link to="7" input="1" from="8" output="0" />
+ <link to="7" input="2" from="12" output="0" />
+ <link to="12" input="0" from="8" output="0" />
+ <link to="1" input="2" from="10" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_coral.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_coral.jpg
new file mode 100644
index 0000000..9f01f19
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_coral.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_olive.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_olive.bcm
new file mode 100644
index 0000000..8ae311c
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_olive.bcm
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.48630, 0.39677, 0.10075)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="759, 69" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.00999" loc="300, 12" />
+ <node type="MIX_SHADER" fac="0.02500" loc="504, 130" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.09999" loc="95, 13" />
+ <node type="MIX_SHADER" fac="0.05000" loc="300, 131" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.19999" loc="-115, 70" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.39999" loc="-209, -61" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-345, 69" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="0.0" contrast="0.0" loc="-523, -58" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="-0.39999" contrast="0.0" loc="-526, 71" />
+ <node type="FRESNEL" ior="8.0" loc="-884, 228" />
+ <node type="RGB" color="rgba(0.5, 0.15069, 0.0, 1.0)" loc="-785, 95" />
+ <node type="RGB" color="rgba(0.5, 0.43265, 0.09540, 1.0)" loc="-785, -95" />
+ <node type="MIX_SHADER" fac="0.09999" loc="89, 188" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="1.0" value2="0.5" loc="-509, 236" />
+ <node type="LAYER_WEIGHT" blend="0.80000" loc="-704, 229" />
+ </nodes>
+ <links>
+ <link to="7" input="1" from="9" output="0" />
+ <link to="7" input="2" from="8" output="0" />
+ <link to="15" input="0" from="10" output="0" />
+ <link to="7" input="0" from="14" output="0" />
+ <link to="14" input="1" from="15" output="1" />
+ <link to="6" input="0" from="7" output="0" />
+ <link to="0" input="0" from="2" output="0" />
+ <link to="9" input="0" from="11" output="0" />
+ <link to="8" input="0" from="12" output="0" />
+ <link to="2" input="2" from="1" output="0" />
+ <link to="2" input="1" from="4" output="0" />
+ <link to="4" input="2" from="3" output="0" />
+ <link to="4" input="1" from="13" output="0" />
+ <link to="13" input="2" from="5" output="0" />
+ <link to="13" input="1" from="6" output="0" />
+ <link to="5" input="0" from="9" output="0" />
+ </links>
+</material>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_olive.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_olive.jpg
new file mode 100644
index 0000000..c014eb3
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/dull_olive.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_green.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_green.bcm
new file mode 100644
index 0000000..985e11e
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_green.bcm
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.04379, 0.60201, 0.04091)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="250, 128" />
+ <node type="LAYER_WEIGHT" blend="0.15000" loc="-248, 328" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.00999" loc="-233, -65" />
+ <node type="MIX_SHADER" fac="0.02999" loc="43, 125" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="5.0" loc="-489, 280" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.39999" loc="-501, 175" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.29999" loc="-503, 40" />
+ <node type="MIX_SHADER" fac="0.5" loc="-314, 177" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="500.0" loc="-673, 291" />
+ <node type="BRIGHTCONTRAST" hide="True" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="-0.20000" contrast="0.0" loc="-668, 35" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="500.0" loc="-997, 303" />
+ <node type="RGB" custom_color="rgb(0.89999, 0.89999, 0.89999)" color="rgba(0.10972, 0.5, 0.09735, 1.0)" loc="-1151, 127" />
+ <node type="HUE_SAT" label="Color Repeater" hue="0.5" saturation="1.0" value="1.0" fac="1.0" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="-877, 134" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="3" output="0" />
+ <link to="3" input="2" from="2" output="0" />
+ <link to="3" input="1" from="7" output="0" />
+ <link to="3" input="0" from="1" output="1" />
+ <link to="7" input="1" from="6" output="0" />
+ <link to="6" input="0" from="9" output="0" />
+ <link to="4" input="0" from="8" output="0" />
+ <link to="7" input="0" from="4" output="0" />
+ <link to="7" input="2" from="5" output="0" />
+ <link to="12" input="4" from="11" output="0" />
+ <link to="5" input="0" from="12" output="0" />
+ <link to="9" input="0" from="12" output="0" />
+ <link to="8" input="1" from="10" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_green.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_green.jpg
new file mode 100644
index 0000000..096753f
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_green.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_purple.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_purple.bcm
new file mode 100644
index 0000000..9580307
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_purple.bcm
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.57112, 0.02518, 0.37123)" sample_lamp="True">
+ <nodes>
+ <node type="LAYER_WEIGHT" blend="0.32499" loc="170, 224" />
+ <node type="MIX_SHADER" fac="0.5" loc="172, 110" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.29998" loc="-250, -24" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.29998" loc="-248, 118" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="5.0" loc="-199, 237" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="500.0" loc="-380, 289" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="-0.20000" contrast="0.0" loc="-405, 111" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="-0.20000" contrast="0.0" loc="-409, -25" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.20000" loc="-697, -19" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="1.0" value2="0.5" loc="-832, -18" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.07500" loc="-832, 161" />
+ <node type="HOLDOUT" loc="-811, 220" />
+ <node type="FRESNEL" ior="1.95000" loc="-813, 302" />
+ <node type="MIX_SHADER" fac="0.5" loc="-617, 238" />
+ <node type="LAYER_WEIGHT" blend="0.89999" loc="-1001, -43" />
+ <node type="MIX_SHADER" fac="0.5" loc="-13, 76" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.00999" loc="153, -19" />
+ <node type="MIX_SHADER" fac="0.03999" loc="346, 113" />
+ <node type="OUTPUT_MATERIAL" loc="513, 107" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="1.0" value2="-0.19999" loc="-559, -18" />
+ <node type="RGB" color="rgba(0.86887, 0.22238, 0.61303, 1.0)" loc="-777, -164" />
+ <node type="RGB" color="rgba(0.5, 0.13597, 0.45640, 1.0)" loc="-592, -162" />
+ </nodes>
+ <links>
+ <link to="15" input="1" from="3" output="0" />
+ <link to="3" input="0" from="6" output="0" />
+ <link to="4" input="0" from="5" output="0" />
+ <link to="15" input="0" from="4" output="0" />
+ <link to="15" input="2" from="2" output="0" />
+ <link to="17" input="2" from="16" output="0" />
+ <link to="17" input="0" from="0" output="0" />
+ <link to="13" input="1" from="11" output="0" />
+ <link to="13" input="2" from="10" output="0" />
+ <link to="13" input="0" from="12" output="0" />
+ <link to="1" input="1" from="15" output="0" />
+ <link to="1" input="2" from="13" output="0" />
+ <link to="1" input="0" from="4" output="0" />
+ <link to="17" input="1" from="1" output="0" />
+ <link to="2" input="0" from="7" output="0" />
+ <link to="9" input="1" from="14" output="1" />
+ <link to="8" input="0" from="9" output="0" />
+ <link to="19" input="0" from="8" output="0" />
+ <link to="7" input="1" from="19" output="0" />
+ <link to="18" input="0" from="17" output="0" />
+ <link to="7" input="0" from="21" output="0" />
+ <link to="6" input="0" from="20" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_purple.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_purple.jpg
new file mode 100644
index 0000000..3842f8d
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_purple.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_tangelo.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_tangelo.bcm
new file mode 100644
index 0000000..dd8ac29
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_tangelo.bcm
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(1.0, 0.12743, 0.02028)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.03999" loc="403, 181" />
+ <node type="MIX_SHADER" fac="0.5" loc="235, 205" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.00999" loc="213, 75" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="5.0" loc="13, 318" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.29999" loc="12, 215" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.29999" loc="14, 82" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="500.0" loc="-172, 334" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-114, 177" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="-0.20000" contrast="0.0" loc="-329, 113" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="0.5" contrast="0.0" loc="-329, -14" />
+ <node type="OUTPUT_MATERIAL" loc="573, 175" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-111, 5" />
+ <node type="FRESNEL" ior="2.0" loc="-887, 225" />
+ <node type="RGB" color="rgba(1.0, 0.18256, 0.0, 1.0)" loc="-893, 103" />
+ <node type="RGB" color="rgba(0.5, 0.24046, 0.0, 1.0)" loc="-839, -105" />
+ <node type="RGB" color="rgba(0.75750, 0.50051, 0.0, 1.0)" loc="-655, -201" />
+ <node type="MATH" hide="True" operation="ADD" use_clamp="False" value1="0.10000" value2="0.5" loc="-501, -8" />
+ <node type="MATH" hide="True" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.20000" loc="-633, -7" />
+ </nodes>
+ <links>
+ <link to="1" input="1" from="4" output="0" />
+ <link to="7" input="1" from="8" output="0" />
+ <link to="0" input="1" from="1" output="0" />
+ <link to="3" input="0" from="6" output="0" />
+ <link to="1" input="0" from="3" output="0" />
+ <link to="1" input="2" from="5" output="0" />
+ <link to="10" input="0" from="0" output="0" />
+ <link to="0" input="2" from="2" output="0" />
+ <link to="4" input="0" from="7" output="0" />
+ <link to="5" input="0" from="11" output="0" />
+ <link to="11" input="2" from="9" output="0" />
+ <link to="11" input="1" from="8" output="0" />
+ <link to="16" input="1" from="17" output="0" />
+ <link to="5" input="1" from="16" output="0" />
+ <link to="7" input="0" from="12" output="0" />
+ <link to="11" input="0" from="12" output="0" />
+ <link to="17" input="0" from="12" output="0" />
+ <link to="7" input="2" from="15" output="0" />
+ <link to="9" input="0" from="14" output="0" />
+ <link to="8" input="0" from="13" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_tangelo.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_tangelo.jpg
new file mode 100644
index 0000000..0e42930
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/flaky_tangelo.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/glossy_yellow.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/glossy_yellow.bcm
new file mode 100644
index 0000000..f62e838
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/glossy_yellow.bcm
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(1.0, 0.46594, 0.03595)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.5" loc="92, 119" />
+ <node type="MIX_SHADER" fac="0.5" loc="427, 123" />
+ <node type="MIX_SHADER" fac="0.5" loc="756, 116" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="65, 385" />
+ <node type="MATH" operation="DIVIDE" use_clamp="False" value1="0.5" value2="2.0" loc="246, 351" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="1000.0" loc="-732, 197" />
+ <node type="INVERT" fac="1.0" color="rgba(0.0, 0.0, 0.0, 1.0)" loc="-548, 149" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="7.0" loc="-426, 136" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="-230, 141" />
+ <node type="FRESNEL" ior="1.20000" loc="-197, 436" />
+ <node type="LAYER_WEIGHT" blend="0.01999" loc="-194, 325" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.0" loc="91, -33" />
+ <node type="LAYER_WEIGHT" blend="0.5" loc="-447, 242" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.10000" loc="-433, -164" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.20000" loc="446, -70" />
+ <node type="FRESNEL" ior="1.10000" loc="465, 245" />
+ <node type="BSDF_DIFFUSE" color="rgba(1.0, 0.03999, 0.0, 1.0)" roughness="0.0" loc="-423, -11" />
+ <node type="RGB" custom_color="rgb(1.0, 0.80000, 0.5)" label="Gloss Color" color="rgba(1.0, 0.73231, 0.0, 1.0)" loc="-1138, 470" />
+ <node type="RGB" custom_color="rgb(1.0, 0.80000, 0.5)" label="Paint Color" color="rgba(1.0, 0.44275, 0.0, 1.0)" loc="-1127, 657" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Roughness" value="0.0" loc="-1142, 265" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Fresnel" value="1.29999" loc="-1142, 176" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Flake Size" value="1000.0" loc="-1142, -165" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Flake Spread" value="0.10000" loc="-1142, -342" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Flake Intensity" value="0.60000" loc="-1142, -254" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Blend" value="0.01999" loc="-1142, 94" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="1000.0" loc="-736, -4" />
+ <node type="OUTPUT_MATERIAL" loc="957, 98" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Gloss Roughness" value="0.0" loc="-1142, 8" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Gloss Spread" value="2.0" loc="-1142, -78" />
+ </nodes>
+ <links>
+ <link to="26" input="0" from="2" output="0" />
+ <link to="0" input="2" from="13" output="0" />
+ <link to="1" input="1" from="0" output="0" />
+ <link to="0" input="1" from="16" output="0" />
+ <link to="1" input="2" from="11" output="0" />
+ <link to="13" input="0" from="25" output="0" />
+ <link to="0" input="0" from="8" output="0" />
+ <link to="8" input="1" from="7" output="0" />
+ <link to="8" input="0" from="12" output="0" />
+ <link to="6" input="1" from="5" output="1" />
+ <link to="7" input="0" from="6" output="0" />
+ <link to="2" input="2" from="14" output="0" />
+ <link to="2" input="1" from="1" output="0" />
+ <link to="2" input="0" from="15" output="0" />
+ <link to="3" input="1" from="10" output="1" />
+ <link to="4" input="0" from="3" output="0" />
+ <link to="3" input="0" from="9" output="0" />
+ <link to="1" input="0" from="4" output="0" />
+ <link to="16" input="0" from="18" output="0" />
+ <link to="11" input="0" from="17" output="0" />
+ <link to="11" input="1" from="19" output="0" />
+ <link to="9" input="0" from="20" output="0" />
+ <link to="10" input="0" from="24" output="0" />
+ <link to="5" input="1" from="21" output="0" />
+ <link to="25" input="1" from="21" output="0" />
+ <link to="12" input="0" from="23" output="0" />
+ <link to="13" input="1" from="22" output="0" />
+ <link to="14" input="1" from="27" output="0" />
+ <link to="15" input="0" from="28" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/glossy_yellow.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/glossy_yellow.jpg
new file mode 100644
index 0000000..2b3c35d
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/glossy_yellow.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/metallic_blue.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/metallic_blue.bcm
new file mode 100644
index 0000000..331a94e
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/metallic_blue.bcm
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.20428, 0.26886, 0.36288)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.85000" loc="455, 102" />
+ <node type="OUTPUT_MATERIAL" loc="660, 96" />
+ <node type="LAYER_WEIGHT" blend="0.89999" loc="-615, 152" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Spread" value="0.70000" loc="-883, 468" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Flake Size" value="600.0" loc="-921, 351" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.00499" loc="44, 203" />
+ <node type="RGB" custom_color="rgb(0.89999, 0.89999, 0.89999)" color="rgba(0.0, 0.04970, 0.50288, 1.0)" loc="-987, 248" />
+ <node type="RGB" custom_color="rgb(0.89999, 0.89999, 0.89999)" color="rgba(0.0, 0.0, 0.09989, 1.0)" loc="-987, 46" />
+ <node type="RGB" custom_color="rgb(0.89999, 0.89999, 0.89999)" color="rgba(0.0, 1.0, 1.0, 1.0)" loc="-906, -174" />
+ <node type="GAMMA" hide="True" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="3.5" loc="-392, 240" />
+ <node type="MIX_SHADER" fac="0.75" loc="-415, 155" />
+ <node type="MIX_SHADER" fac="0.75" loc="-200, 157" />
+ <node type="LAYER_WEIGHT" blend="0.69999" loc="260, 317" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="600.0" loc="-615, 310" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.0, 0.04970, 0.50288, 1.0)" roughness="1.0" loc="-615, 47" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.0, 0.0, 0.09989, 1.0)" roughness="1.0" loc="-615, -70" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.0, 1.0, 1.0, 1.0)" roughness="0.30000" loc="-418, -74" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.0, 0.0, 0.00972, 1.0)" roughness="0.64999" loc="-211, -73" />
+ <node type="MIX_SHADER" fac="0.25" loc="44, 43" />
+ <node type="MIX_SHADER" fac="0.49999" loc="260, 105" />
+ </nodes>
+ <links>
+ <link to="9" input="0" from="13" output="1" />
+ <link to="1" input="0" from="0" output="0" />
+ <link to="0" input="0" from="12" output="1" />
+ <link to="19" input="2" from="18" output="0" />
+ <link to="0" input="1" from="19" output="0" />
+ <link to="0" input="2" from="17" output="0" />
+ <link to="10" input="2" from="15" output="0" />
+ <link to="10" input="1" from="14" output="0" />
+ <link to="10" input="0" from="2" output="1" />
+ <link to="11" input="2" from="16" output="0" />
+ <link to="11" input="1" from="10" output="0" />
+ <link to="11" input="0" from="9" output="0" />
+ <link to="19" input="1" from="5" output="0" />
+ <link to="14" input="0" from="6" output="0" />
+ <link to="12" input="0" from="3" output="0" />
+ <link to="13" input="1" from="4" output="0" />
+ <link to="16" input="0" from="8" output="0" />
+ <link to="15" input="0" from="7" output="0" />
+ <link to="18" input="1" from="11" output="0" />
+ <link to="18" input="2" from="17" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/metallic_blue.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/metallic_blue.jpg
new file mode 100644
index 0000000..d44a563
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/car-paint/metallic_blue.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/blaster_bolt_red.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/blaster_bolt_red.bcm
new file mode 100644
index 0000000..d6c8f55
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/blaster_bolt_red.bcm
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(1.0, 0.0, 0.0)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="300, 300" />
+ <node type="EMISSION" color="rgba(1.0, 0.0, 0.0, 1.0)" strength="30.0" loc="-189, 219" />
+ <node type="MIX_SHADER" fac="0.5" loc="70, 302" />
+ <node type="LAYER_WEIGHT" blend="0.89999" loc="-195, 431" />
+ <node type="EMISSION" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" strength="30.0" loc="-190, 326" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="2" output="0" />
+ <link to="2" input="0" from="3" output="1" />
+ <link to="2" input="1" from="4" output="0" />
+ <link to="2" input="2" from="1" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/blaster_bolt_red.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/blaster_bolt_red.jpg
new file mode 100644
index 0000000..b5f7178
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/blaster_bolt_red.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fake_shading.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fake_shading.bcm
new file mode 100644
index 0000000..5199153
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fake_shading.bcm
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.84148, 0.74040, 0.00749)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="545, 173" />
+ <node type="NEW_GEOMETRY" loc="-759, 221" />
+ <node type="LIGHT_PATH" loc="-464, -35" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="1.0" loc="103, 86" />
+ <node type="EMISSION" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" strength="10.13210" loc="290, 179" />
+ <node type="MATH" operation="MAXIMUM" use_clamp="False" value1="0.5" value2="0.5" loc="-130, 30" />
+ <node type="VECT_MATH" operation="ADD" vector1="Vector(0.5, 0.5, 0.5)" vector2="Vector(0.5, 0.5, 0.5)" loc="-386, 202" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.47510, 0.01064, 0.00834, 1.0)" color2="rgba(0.88760, 0.81437, 0.00747, 1.0)" loc="-13, 254" />
+ <node type="TEX_COORD" loc="-776, 30" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="4" output="0" />
+ <link to="5" input="1" from="2" output="3" />
+ <link to="4" input="1" from="3" output="0" />
+ <link to="3" input="0" from="5" output="0" />
+ <link to="5" input="0" from="2" output="0" />
+ <link to="6" input="0" from="1" output="4" />
+ <link to="7" input="0" from="6" output="1" />
+ <link to="4" input="0" from="7" output="0" />
+ <link to="6" input="1" from="8" output="6" />
+ </links>
+</material>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fake_shading.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fake_shading.jpg
new file mode 100644
index 0000000..dd72be2
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fake_shading.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fingerprint_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fingerprint_osl.bcm
new file mode 100644
index 0000000..20a014d
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fingerprint_osl.bcm
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="VALTORGB" interpolation="LINEAR" fac="0.5" stops="2" stop1="0.0|rgba(0.0, 0.0, 0.0, 1.0)" stop2="1.0|rgba(1.0, 1.0, 1.0, 1.0)" loc="8, 456" />
+ <node type="TEX_NOISE" scale="5.0" detail="2.0" distortion="0.0" loc="-195, 467" />
+ <node type="MATH" operation="GREATER_THAN" use_clamp="False" value1="0.5" value2="0.0" loc="-129, -8" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="20, 118" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="163, 242" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="303, 403" />
+ <node type="MATH" operation="LESS_THAN" use_clamp="False" value1="0.5" value2="0.20000" loc="451, 326" />
+ <node type="BSDF_DIFFUSE" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.0" loc="180, 83" />
+ <node type="MIX_SHADER" fac="0.79999" loc="373, 95" />
+ <node type="MIX_SHADER" fac="0.5" loc="606, 201" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.10000" loc="178, -39" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="376, -48" />
+ <node type="MATH" operation="SINE" use_clamp="False" value1="0.5" value2="1.0" loc="-272, 138" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="24.0" loc="-419, 137" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" vector="Vector(0.0, 0.0, 0.0)" scale="1.0" ridges="50" seed="42" loc="-588, 137" />
+ <node type="SCRIPT" mode="INTERNAL" script="1" vector="Vector(0.0, 0.0, 0.0)" center="Vector(0.5, 0.5, 0.5)" radius="0.15000" ellipse="0.90000" rotation="10.0" blur="1.0" loc="-593, 388" />
+ <node type="TEX_COORD" dupli="False" loc="-1050, 186" />
+ <node type="MAPPING" translation="Vector(-0.49999, 0.09999, 0.0)" rotation="Vector(0.08726, 0.10471, 0.03490)" scale="Vector(1.89999, 1.89999, 1.89999)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-865, 265" />
+ <node type="OUTPUT_MATERIAL" loc="811, 307" />
+ </nodes>
+ <links>
+ <link to="18" input="0" from="9" output="0" />
+ <link to="0" input="0" from="1" output="1" />
+ <link to="5" input="0" from="0" output="0" />
+ <link to="6" input="0" from="5" output="0" />
+ <link to="5" input="1" from="4" output="0" />
+ <link to="4" input="0" from="15" output="0" />
+ <link to="13" input="0" from="14" output="0" />
+ <link to="12" input="0" from="13" output="0" />
+ <link to="3" input="0" from="12" output="0" />
+ <link to="2" input="0" from="12" output="0" />
+ <link to="3" input="1" from="2" output="0" />
+ <link to="4" input="1" from="3" output="0" />
+ <link to="9" input="2" from="11" output="0" />
+ <link to="9" input="1" from="8" output="0" />
+ <link to="8" input="2" from="10" output="0" />
+ <link to="8" input="1" from="7" output="0" />
+ <link to="18" input="2" from="5" output="0" />
+ <link to="17" input="0" from="16" output="2" />
+ <link to="9" input="0" from="6" output="0" />
+ <link to="14" input="0" from="17" output="0" />
+ <link to="15" input="0" from="17" output="0" />
+ </links>
+ <scripts>
+ <script name="MAFingerprint.osl" id="0">
+/*<br /> fingerprint pattern by Michel J. Anders (c)2012<br /> license: cc-by-sa<br /> http://blenderthings.blogspot.com.au/2012/12/a-fingerprint-osl-shader-for-blender.html<br />*/<br /><br />#include "stdosl.h"<br />#include "node_texture.h"<br /><br />shader MAFingerprint(<br /> point Vector = P,<br /> float Scale = 1.0,<br /> int Ridges = 5,<br /> int Seed = 42,<br /> output float Fac = 0.0 )<br />{<br /> float da;<br /> point pa;<br /> float d;<br /><br /> vector up = vector(0,0,1);<br /> vector tdir = 0;<br /><br /> int pi;<br /><br /> for(pi=0; pi< Ridges; pi++){<br /> pa = Scale * point(<br /> cellnoise(point(pi,pi,pi)),<br /> cellnoise(point(pi,pi+Seed,pi)),<br /> cellnoise(point(pi,pi,pi+Seed)));<br /> da = pa[2];<br /> vector v = pa - Vector;<br /> float d = length(v);<br /> v[2]=0;<br /> v = normalize(v);<br /> tdir += cross(v,up)*da*d;<br /> }<br /> Fac = sqrt(dot(tdir,tdir));<br />}<br /><br />
+ </script>
+ <script name="MAEllipseMask.osl" id="1">
+/*<br /> ellipse mask by Michel J. Anders (c)2012<br /> license: cc-by-sa<br /> http://blenderthings.blogspot.com.au/2012/12/a-fingerprint-osl-shader-for-blender.html<br />*/<br /><br />#include "stdosl.h"<br /><br />shader MAEllipseMask(<br /> point Vector = P,<br /> point Center = 0.5,<br /> float Radius = 0.5,<br /> float Ellipse = 1.0,<br /> float Rotation = 0.0,<br /> float Blur = 0.0,<br /> output float Fac = 0.0 )<br />{<br /> point p = rotate(Vector,radians(Rotation),Center,Center+vector(0,0,1));<br /> vector d = p - Center;<br /> d[0] *= Ellipse;<br /> float r2 = d[0]*d[0]+d[1]*d[1];<br /> if (r2 <= Radius*Radius) {<br /> Fac = 1-Blur*sqrt(r2/(Radius*Radius));<br /> }<br />}<br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fingerprint_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fingerprint_osl.jpg
new file mode 100644
index 0000000..4dad5c6
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/fingerprint_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/invisible_light.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/invisible_light.bcm
new file mode 100644
index 0000000..ee4ec58
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/invisible_light.bcm
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.37983, 0.37828, 0.79909)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="300, 300" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="-180, 225" />
+ <node type="LIGHT_PATH" loc="-742, 566" />
+ <node type="EMISSION" color="rgba(0.11494, 0.11202, 0.80000, 1.0)" strength="2.35998" loc="-351, 321" />
+ <node type="MIX_SHADER" fac="0.5" loc="40, 322" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="1.0" loc="-271, 490" />
+ </nodes>
+ <links>
+ <link to="4" input="1" from="3" output="0" />
+ <link to="0" input="0" from="4" output="0" />
+ <link to="4" input="2" from="1" output="0" />
+ <link to="5" input="1" from="2" output="1" />
+ <link to="5" input="0" from="2" output="0" />
+ <link to="4" input="0" from="5" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/invisible_light.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/invisible_light.jpg
new file mode 100644
index 0000000..7d96e82
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/invisible_light.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/simulated_sss.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/simulated_sss.bcm
new file mode 100644
index 0000000..6a244e4
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/simulated_sss.bcm
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80220, 0.34073, 0.11822)" sample_lamp="False">
+ <nodes>
+ <node type="MATH" hide="True" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="345, 357" />
+ <node type="MATH" hide="True" operation="MINIMUM" use_clamp="False" value1="0.5" value2="1.0" loc="531, 370" />
+ <node type="MATH" hide="True" operation="SUBTRACT" use_clamp="False" value1="1.0" value2="0.5" loc="-61, 201" />
+ <node type="NEW_GEOMETRY" hide="True" loc="-247, 217" />
+ <node type="MIX_SHADER" hide="True" fac="0.5" loc="617, 462" />
+ <node type="BSDF_DIFFUSE" hide="True" color="rgba(0.80000, 0.21108, 0.0, 1.0)" roughness="0.0" loc="321, 442" />
+ <node type="BSDF_GLOSSY" hide="True" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.20000" loc="166, 480" />
+ <node type="BSDF_TRANSLUCENT" hide="True" color="rgba(0.80000, 0.50765, 0.23623, 1.0)" loc="599, 243" />
+ <node type="MIX_SHADER" hide="True" fac="0.5" loc="806, 329" />
+ <node type="OUTPUT_MATERIAL" hide="True" loc="996, 315" />
+ <node type="RGB" label="Subdermal Color" color="rgba(0.80000, 0.21108, 0.0, 1.0)" loc="-680, 555" />
+ <node type="VALUE" label="Specularity" value="0.5" loc="-670, 678" />
+ <node type="RGB" label="Epidermal Color" color="rgba(0.80000, 0.50765, 0.23623, 1.0)" loc="-680, 244" />
+ <node type="LIGHT_PATH" loc="-488, 505" />
+ <node type="MATH" hide="True" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="-0.75199" loc="-258, 307" />
+ <node type="MATH" hide="True" operation="POWER" use_clamp="False" value1="2.71798" value2="0.5" loc="-104, 327" />
+ <node type="MATH" hide="True" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="68, 368" />
+ <node type="VALUE" label="Absorption Value" value="-0.75199" loc="-670, 351" />
+ </nodes>
+ <links>
+ <link to="14" input="0" from="13" output="7" />
+ <link to="15" input="1" from="14" output="0" />
+ <link to="2" input="1" from="3" output="6" />
+ <link to="16" input="0" from="13" output="0" />
+ <link to="0" input="0" from="16" output="0" />
+ <link to="0" input="1" from="2" output="0" />
+ <link to="1" input="0" from="0" output="0" />
+ <link to="8" input="0" from="1" output="0" />
+ <link to="9" input="0" from="8" output="0" />
+ <link to="4" input="2" from="5" output="0" />
+ <link to="4" input="1" from="6" output="0" />
+ <link to="8" input="2" from="7" output="0" />
+ <link to="8" input="1" from="4" output="0" />
+ <link to="5" input="0" from="10" output="0" />
+ <link to="4" input="0" from="11" output="0" />
+ <link to="14" input="1" from="17" output="0" />
+ <link to="7" input="0" from="12" output="0" />
+ <link to="16" input="1" from="15" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/simulated_sss.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/simulated_sss.jpg
new file mode 100644
index 0000000..eab220e
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/simulated_sss.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/volumetric_light.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/volumetric_light.bcm
new file mode 100644
index 0000000..1dca858
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/volumetric_light.bcm
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.68979, 1.25306, 1.30810)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="1037, 349" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="-0.03200" loc="-263, 445" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="303, 580" />
+ <node type="LIGHT_PATH" loc="-451, 602" />
+ <node type="MATH" operation="POWER" use_clamp="False" value1="25.0" value2="0.5" loc="-78, 443" />
+ <node type="NEW_GEOMETRY" loc="-265, 273" />
+ <node type="BSDF_GLASS" distribution="SHARP" color="rgba(1.0, 1.0, 1.0, 0.98518)" roughness="0.0" ior="1.0" loc="305, 256" />
+ <node type="EMISSION" color="rgba(0.09172, 0.17486, 0.80000, 1.0)" strength="52.49996" loc="308, 375" />
+ <node type="MATH" operation="MINIMUM" use_clamp="False" value1="0.5" value2="1.0" loc="526, 569" />
+ <node type="RGB" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Emission Color" color="rgba(0.09172, 0.17486, 0.80000, 1.0)" loc="-533, 413" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="1.0" value2="0.5" loc="-79, 257" />
+ <node type="MIX_SHADER" fac="0.5" loc="855, 373" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="88, 580" />
+ <node type="VALUE" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Brightness" value="40.0" loc="-527, 227" />
+ </nodes>
+ <links>
+ <link to="1" input="0" from="3" output="7" />
+ <link to="4" input="1" from="1" output="0" />
+ <link to="10" input="1" from="5" output="6" />
+ <link to="12" input="0" from="3" output="0" />
+ <link to="2" input="0" from="12" output="0" />
+ <link to="2" input="1" from="10" output="0" />
+ <link to="8" input="0" from="2" output="0" />
+ <link to="11" input="0" from="8" output="0" />
+ <link to="0" input="0" from="11" output="0" />
+ <link to="11" input="1" from="7" output="0" />
+ <link to="12" input="1" from="4" output="0" />
+ <link to="7" input="1" from="13" output="0" />
+ <link to="7" input="0" from="9" output="0" />
+ <link to="11" input="2" from="6" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/volumetric_light.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/volumetric_light.jpg
new file mode 100644
index 0000000..9f62bbd
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/volumetric_light.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/wireframe_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/wireframe_osl.bcm
new file mode 100644
index 0000000..f2a3108
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/wireframe_osl.bcm
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="300, 300" />
+ <node type="MIX_SHADER" fac="0.5" loc="75, 304" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.0, 0.0, 0.0, 1.0)" roughness="0.0" loc="-149, 133" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.14667, 0.26590, 0.39998, 0.0)" roughness="0.0" loc="-299, 265" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" line_width="0.99998" raster="1" loc="-142, 435" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="-115, 257" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="0" from="4" output="0" />
+ <link to="1" input="2" from="2" output="0" />
+ <link to="5" input="0" from="3" output="0" />
+ <link to="1" input="1" from="5" output="0" />
+ </links>
+ <scripts>
+ <script name="TDwireframe.osl.001" id="0">
+<br />/*<br /> Wireframe texture by Thomas Dinges (c)2012<br /> http://www.openshading.com/osl/example-shaders/<br />*/<br /><br />#include "stdosl.h"<br />#include "oslutil.h"<br /><br />shader TDwireframe(<br /> float Line_Width = 2.0,<br /> int Raster = 1,<br /> output float Factor = 0.0)<br />{<br /> //Factor = wireframe("triangles", Line_Width, Raster);<br /> /* currently blender always provides triangles at this point in the render <br /> as in fully triangulated mesh that the render engine works with<br /> at some stage the polygons option will provide original poly edges instead */<br /> Factor = wireframe("polygons", Line_Width, Raster);<br />}<br /><br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/wireframe_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/wireframe_osl.jpg
new file mode 100644
index 0000000..a70fda5
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/effects/wireframe_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/gummy_worm.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/gummy_worm.bcm
new file mode 100644
index 0000000..08ee650
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/gummy_worm.bcm
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.28012, 0.08883, 0.07812)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.86000" loc="250, 356" />
+ <node type="OUTPUT_MATERIAL" loc="517, 356" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.80000, 0.45208, 0.0, 1.0)" loc="25, 220" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.69998, 0.03863, 0.13707, 1.0)" roughness="0.0" loc="25, 356" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.24683, 0.5, 0.10869, 1.0)" color2="rgba(0.5, 0.42882, 0.0, 1.0)" loc="-158, 292" />
+ <node type="FRESNEL" ior="1.66733" loc="-412, 292" />
+ </nodes>
+ <links>
+ <link to="0" input="1" from="3" output="0" />
+ <link to="1" input="0" from="0" output="0" />
+ <link to="0" input="2" from="2" output="0" />
+ <link to="4" input="0" from="5" output="0" />
+ <link to="2" input="0" from="4" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/gummy_worm.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/gummy_worm.jpg
new file mode 100644
index 0000000..0da81b2
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/gummy_worm.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/milk_chocolate.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/milk_chocolate.bcm
new file mode 100644
index 0000000..4abaeca
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/milk_chocolate.bcm
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.30000, 0.10498, 0.04715)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="237, 123" />
+ <node type="MIX_SHADER" fac="0.85000" loc="37, 123" />
+ <node type="MIX_SHADER" fac="0.10000" loc="-165, 38" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.15053, 0.08335, 0.04656, 1.0)" roughness="0.31999" loc="-171, 186" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.14248, 0.04986, 0.02239, 1.0)" roughness="0.0" loc="-381, 106" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.19999, 0.11313, 0.08168, 1.0)" loc="-391, -4" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="1" from="3" output="0" />
+ <link to="1" input="2" from="2" output="0" />
+ <link to="2" input="1" from="4" output="0" />
+ <link to="2" input="2" from="5" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/milk_chocolate.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/milk_chocolate.jpg
new file mode 100644
index 0000000..cdc2138
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/milk_chocolate.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/raspberry.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/raspberry.bcm
new file mode 100644
index 0000000..d539d4a
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/raspberry.bcm
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.68075, 0.03067, 0.04267)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="1000, 250" />
+ <node type="MIX_SHADER" fac="0.5" loc="700, 250" />
+ <node type="LAYER_WEIGHT" blend="0.15000" loc="400, 400" />
+ <node type="MIX_SHADER" fac="0.5" loc="400, 250" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.62673, 0.94107, 1.0)" roughness="0.10000" loc="400, 100" />
+ <node type="LAYER_WEIGHT" blend="0.10000" loc="100, 400" />
+ <node type="MIX_SHADER" fac="0.80000" loc="100, 250" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.54095, 0.72606, 1.0)" roughness="0.60000" loc="100, 100" />
+ <node type="BSDF_GLASS" distribution="SHARP" color="rgba(0.83876, 0.35837, 0.31907, 1.0)" roughness="0.0" ior="1.0" loc="-200, 325" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.96478, 0.21441, 0.25363, 1.0)" loc="-200, 175" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="0" from="2" output="0" />
+ <link to="1" input="1" from="3" output="0" />
+ <link to="1" input="2" from="4" output="0" />
+ <link to="3" input="0" from="5" output="0" />
+ <link to="3" input="1" from="6" output="0" />
+ <link to="3" input="2" from="7" output="0" />
+ <link to="6" input="1" from="8" output="0" />
+ <link to="6" input="2" from="9" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/raspberry.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/raspberry.jpg
new file mode 100644
index 0000000..1c5e323
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/food/raspberry.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/absorption.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/absorption.bcm
new file mode 100644
index 0000000..71c325e
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/absorption.bcm
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.10572, 0.13248, 0.47976)" sample_lamp="True">
+ <nodes>
+ <node type="NEW_GEOMETRY" loc="-247, 217" />
+ <node type="LIGHT_PATH" loc="-451, 561" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="-0.68007" loc="-263, 461" />
+ <node type="MATH" operation="POWER" use_clamp="False" value1="2.71798" value2="0.5" loc="-78, 429" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="128, 489" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="345, 357" />
+ <node type="MATH" operation="MINIMUM" use_clamp="False" value1="0.5" value2="1.0" loc="528, 370" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" ior="1.45000" loc="834, 341" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.0, 0.08540, 1.0, 1.0)" color2="rgba(0.97188, 1.0, 0.97017, 1.0)" loc="692, 378" />
+ <node type="OUTPUT_MATERIAL" loc="1037, 349" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="1.0" value2="0.5" loc="-61, 201" />
+ </nodes>
+ <links>
+ <link to="3" input="1" from="2" output="0" />
+ <link to="10" input="1" from="0" output="6" />
+ <link to="4" input="0" from="3" output="0" />
+ <link to="4" input="1" from="1" output="0" />
+ <link to="9" input="0" from="7" output="0" />
+ <link to="5" input="0" from="4" output="0" />
+ <link to="5" input="1" from="10" output="0" />
+ <link to="6" input="0" from="5" output="0" />
+ <link to="8" input="0" from="6" output="0" />
+ <link to="7" input="0" from="8" output="0" />
+ <link to="2" input="0" from="1" output="7" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/absorption.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/absorption.jpg
new file mode 100644
index 0000000..da3e159
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/absorption.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/iridescent.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/iridescent.bcm
new file mode 100644
index 0000000..27f18e2
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/iridescent.bcm
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.41442, 0.41442, 0.39642)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.5" loc="-99, 306" />
+ <node type="MIX_SHADER" fac="0.5" loc="-90, 7" />
+ <node type="LAYER_WEIGHT" blend="0.30000" loc="-522, 495" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.0, 0.12627, 0.80000, 1.0)" roughness="0.00999" loc="-318, 306" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.00999" ior="1.45000" loc="-318, -206" />
+ <node type="OUTPUT_MATERIAL" loc="390, 154" />
+ <node type="MIX_SHADER" fac="0.25" loc="120, 154" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.00999" ior="1.45000" loc="-318, 154" />
+ <node type="TEX_NOISE" scale="10.0" detail="2.0" distortion="0.0" loc="-675, 154" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.00999" loc="-318, -32" />
+ <node type="INVERT" fac="1.0" color="rgba(0.0, 0.0, 0.0, 1.0)" loc="-285, 467" />
+ </nodes>
+ <links>
+ <link to="5" input="0" from="6" output="0" />
+ <link to="0" input="1" from="3" output="0" />
+ <link to="0" input="0" from="10" output="0" />
+ <link to="9" input="0" from="8" output="0" />
+ <link to="0" input="2" from="7" output="0" />
+ <link to="6" input="1" from="0" output="0" />
+ <link to="1" input="1" from="9" output="0" />
+ <link to="1" input="2" from="4" output="0" />
+ <link to="6" input="2" from="1" output="0" />
+ <link to="3" input="0" from="8" output="0" />
+ <link to="10" input="1" from="2" output="1" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/iridescent.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/iridescent.jpg
new file mode 100644
index 0000000..b217b1c
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/iridescent.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/lalique.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/lalique.bcm
new file mode 100644
index 0000000..b358716
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/lalique.bcm
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.60382, 0.60382, 0.77582)" sample_lamp="True">
+ <nodes>
+ <node type="FRESNEL" ior="1.79999" loc="-676, 464" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.05000" ior="1.45000" loc="-123, 104" />
+ <node type="MIX_SHADER" fac="0.34999" loc="104, 214" />
+ <node type="ADD_SHADER" loc="-1113, 55" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.77942, 0.86935, 1.0, 1.0)" loc="-636, 364" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(1.0, 0.90754, 0.99431, 1.0)" loc="-626, 274" />
+ <node type="MIX_SHADER" fac="0.5" loc="-384, 439" />
+ <node type="ADD_SHADER" loc="-121, 453" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.31400, 0.31400, 0.31400, 1.0)" loc="-784, 87" />
+ <node type="OUTPUT_MATERIAL" loc="386, 181" />
+ </nodes>
+ <links>
+ <link to="9" input="0" from="2" output="0" />
+ <link to="6" input="0" from="0" output="0" />
+ <link to="2" input="2" from="1" output="0" />
+ <link to="6" input="1" from="4" output="0" />
+ <link to="6" input="2" from="5" output="0" />
+ <link to="7" input="0" from="6" output="0" />
+ <link to="2" input="1" from="7" output="0" />
+ <link to="7" input="1" from="8" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/lalique.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/lalique.jpg
new file mode 100644
index 0000000..2fdec98
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/lalique.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/soda_lime_common.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/soda_lime_common.bcm
new file mode 100644
index 0000000..efd2d0f
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/soda_lime_common.bcm
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.85013, 1.0, 0.80923)" sample_lamp="True">
+ <nodes>
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(0.96069, 1.0, 0.94998, 1.0)" roughness="0.00999" ior="1.51800" loc="62, 412" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="95, 230" />
+ <node type="OUTPUT_MATERIAL" loc="520, 292" />
+ <node type="MIX_SHADER" fac="0.0" loc="317, 296" />
+ <node type="LIGHT_PATH" loc="-189, 325" />
+ </nodes>
+ <links>
+ <link to="3" input="2" from="1" output="0" />
+ <link to="3" input="0" from="4" output="1" />
+ <link to="3" input="1" from="0" output="0" />
+ <link to="2" input="0" from="3" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/soda_lime_common.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/soda_lime_common.jpg
new file mode 100644
index 0000000..4064ca9
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/glass/soda_lime_common.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/index.xml b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/index.xml
new file mode 100644
index 0000000..9e6fd6c
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/index.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<library>
+ <category title="Car Paint" folder="car-paint" addon="0.4">
+ <material name="Dull Coral" href="dull_coral" by="monsterdog" stars="4" addon="0.4" />
+ <material name="Dull Olive" href="dull_olive" stars="5" addon="0.4" />
+ <material name="Flaky Green" href="flaky_green" stars="5" fireflies="medium" addon="0.4" />
+ <material name="Flaky Purple" href="flaky_purple" stars="4" fireflies="medium" addon="0.4" />
+ <material name="Flaky Tangelo" href="flaky_tangelo" stars="5" fireflies="medium" addon="0.4" />
+ <material name="Glossy Yellow" href="glossy_yellow" stars="4" fireflies="medium" addon="0.4" />
+ <material name="Metallic Blue" href="metallic_blue" stars="5" addon="0.4" />
+ </category>
+ <category title="Effects" folder="effects" addon="0.4">
+ <material name="Blaster Bolt (Red)" href="blaster_bolt_red" stars="3" addon="0.4" />
+ <material name="Invisible Light" href="invisible_light" stars="4" addon="0.4" />
+ <material name="Fake Shading" href="fake_shading" by="Ace Dragon" stars="3" addon="0.4" />
+ <material name="Fingerprint OSL" href="fingerprint_osl" by="varkenvarken" stars="4" complexity="intermediate" addon="0.4" bl="2.65-" />
+ <material name="Simulated SSS" href="simulated_sss" by="ZetShandow" stars="4" complexity="intermediate" addon="0.4" bl="2.64-" />
+ <material name="Volumetric Light" href="volumetric_light" by="ZetShandow" stars="4" complexity="intermediate" fireflies="medium" addon="0.4" bl="2.64-" />
+ <material name="Wireframe OSL" href="wireframe_osl" by="DingTo" stars="4" complexity="intermediate" fireflies="medium" addon="0.4" />
+ </category>
+ <category title="Food" folder="food" addon="0.4">
+ <material name="Gummy Worm" href="gummy_worm" by="Jimmy Gunawan" stars="4" addon="0.4" />
+ <material name="Milk Chocolate" href="milk_chocolate" by="Peter Cassetta" stars="3" addon="0.4" />
+ <material name="Raspberry" href="raspberry" stars="4" addon="0.4" />
+ </category>
+ <category title="Glass" folder="glass" addon="0.4">
+ <material name="Absorption" href="absorption" by="ZetShandow" stars="4" fireflies="medium" addon="0.4" bl="2.64-" />
+ <material name="Iridescent" href="iridescent" by="moony" stars="5" fireflies="medium" speed="fair" addon="0.4" />
+ <material name="Lalique" href="lalique" by="moony" stars="4" addon="0.4" speed="medium" />
+ <material name="Soda-Lime (Common)" href="soda_lime_common" by="Peter Cassetta" stars="3" addon="0.4" />
+ </category>
+ <category title="Liquids" folder="liquids" addon="0.4">
+ <material name="Cranberry Juice" href="cranberry_juice" by="Peter Cassetta" stars="4" addon="0.4" />
+ <material name="Slime" href="slime" stars="3" addon="0.4" bl="2.64-" />
+ <material name="Soap Bubble" href="soap_bubble" by="moony" stars="4" fireflies="medium" speed="fair" addon="0.4" />
+ </category>
+ <category title="Metals" folder="metals" addon="0.4">
+ <material name="Bronze (Ancient)" href="bronze_ancient" stars="4" addon="0.4" />
+ <material name="Fool's Gold" href="fools_gold" stars="4" complexity="complex" addon="0.4" />
+ <material name="Galvanized Steel" href="galvanized_steel" by="moony" stars="4" fireflies="medium" addon="0.4" />
+ </category>
+ <category title="Nature" folder="nature" addon="0.4">
+ <material name="Pearl" href="pearl" by="moony" stars="4" addon="0.4" />
+ <material name="Forest" href="forest" by="Jonathan L" stars="4" complexity="complex" addon="0.4" />
+ </category>
+ <category title="Patterns" folder="patterns" addon="0.4">
+ <material name="Barb Wire OSL" href="barbwire_osl" by="varkenvarken" stars="4" complexity="complex" addon="0.4" />
+ <material name="Chain Link OSL" href="chain_link_osl" by="varkenvarken" stars="4" complexity="complex" addon="0.4" />
+ <material name="Hex Tile OSL" href="hex_tile_osl" by="varkenvarken" stars="4" addon="0.4" />
+
+ <material name="Sierpinski Squares OSL" href="sierpinski_squares_osl" by="elbrujodelatribu" stars="4" complexity="complex" addon="0.4" />
+ </category>
+ <category title="Plastics" folder="plastics" addon="0.4">
+ <material name="Toy Brick (Red)" href="toy_brick_red" by="Peter Cassetta" stars="4" addon="0.4" />
+ </category>
+ <category title="Skin" folder="skin" addon="0.4">
+ <material name="Pox" href="pox" by="moony" stars="4" addon="0.4" />
+ <material name="Dragon Scales OSL" href="dragon_scales_osl" by="varken/androcto" stars="4" complexity="complex" addon="0.4" />
+ </category>
+ <category title="Stones" folder="stones" addon="0.4">
+ <material name="Diamond" href="diamond" stars="3" fireflies="high" speed="slow" addon="0.4" />
+ <material name="Malachite" href="malachite" by="moony" stars="3" addon="0.4" />
+ <material name="Polished Haematite" href="polished_haematite" by="moony" stars="5" complexity="intermediate" addon="0.4" />
+ <material name="Veined Marble OSL" href="veined_marble_osl" by="sambler" stars="4" complexity="intermediate" addon="0.4" />
+ </category>
+ <category title="Synthetic" folder="synthetic" addon="0.4">
+ <material name="Carbon Fiber" href="carbon_fiber" stars="5" complexity="complex" addon="0.4" />
+ <material name="Carbon Fiber (Glossy)" href="carbon_fiber_glossy" stars="3" complexity="complex" addon="0.4" />
+ <material name="Polystyrene Foam" href="polystyrene_foam" by="Peter Cassetta" stars="4" complexity="intermediate" addon="0.4" />
+ <material name="Rubber" href="rubber" stars="3" addon="0.4" />
+ </category>
+ <category title="Textiles" folder="textiles" addon="0.4">
+ <material name="Denim" href="denim" by="Peter Cassetta" stars="4" complexity="complex" addon="0.4" />
+ <material name="Hessian OSL" href="hessian_osl" by="varkenvarken" stars="4" complexity="complex" addon="0.4" />
+ <material name="Velvet (Edged)" href="velvet_edged" stars="4" addon="0.4" />
+ <material name="Weave OSL" href="weave_osl" by="varkenvarken" stars="4" complexity="complex" addon="0.4" />
+ <material name="Weave Test" href="weave_test" by="niabot" stars="4" complexity="complex" addon="0.4" />
+ </category>
+ <category title="Wood" folder="wood" addon="0.4">
+ <material name="Parquete Tile OSL" href="parquete_tile_osl" by="sambler" stars="4" complexity="intermediate" addon="0.4" />
+ <material name="Polished Walnut" href="polished_walnut" by="Peter Cassetta" stars="4" complexity="intermediate" addon="0.4" />
+ <material name="Rough Pine" href="rough_pine" by="Peter Cassetta" stars="4" complexity="intermediate" addon="0.4" />
+ <material name="Rough Walnut" href="rough_walnut" by="Peter Cassetta" stars="3" complexity="intermediate" addon="0.4" />
+ </category>
+</library>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/cranberry_juice.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/cranberry_juice.bcm
new file mode 100644
index 0000000..1e9c634
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/cranberry_juice.bcm
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.87406, 0.02816, 0.03187)" sample_lamp="True">
+ <nodes>
+ <node type="LIGHT_PATH" loc="-236, 318" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 0.37799, 0.37799, 1.0)" loc="95, 230" />
+ <node type="BSDF_GLASS" distribution="SHARP" color="rgba(1.0, 0.41999, 0.41999, 1.0)" roughness="0.00999" ior="1.35099" loc="62, 412" />
+ <node type="MIX_SHADER" fac="0.0" loc="294, 303" />
+ <node type="OUTPUT_MATERIAL" loc="520, 292" />
+ </nodes>
+ <links>
+ <link to="3" input="2" from="1" output="0" />
+ <link to="4" input="0" from="3" output="0" />
+ <link to="3" input="1" from="2" output="0" />
+ <link to="3" input="0" from="0" output="1" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/cranberry_juice.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/cranberry_juice.jpg
new file mode 100644
index 0000000..bc96ab6
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/cranberry_juice.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/slime.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/slime.bcm
new file mode 100644
index 0000000..c66af61
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/slime.bcm
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.17464, 0.52099, 0.03071)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="286, 432" />
+ <node type="MIX_SHADER" fac="0.5" loc="67, 330" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.17583, 0.52207, 0.03054, 1.0)" roughness="0.0" loc="-151, 303" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.88750, 0.66609, 0.19976, 1.0)" roughness="0.5" loc="-157, 195" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="True" value1="0.5" value2="1.0" loc="-135, 463" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="-326, 470" />
+ <node type="TEX_MUSGRAVE" musgrave="FBM" scale="-5.10382" detail="2.0" dimension="2.0" lacunarity="1.0" offset="0.0" gain="1.0" loc="-584, 508" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="1.99999" loc="-590, 669" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.78539, 0.78539, 0.0)" scale="Vector(3.0, 3.0, 3.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-898, 505" />
+ <node type="TEX_COORD" loc="-1129, 475" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="2" from="3" output="0" />
+ <link to="0" input="2" from="4" output="0" />
+ <link to="1" input="0" from="4" output="0" />
+ <link to="8" input="0" from="9" output="0" />
+ <link to="5" input="0" from="7" output="1" />
+ <link to="4" input="0" from="5" output="0" />
+ <link to="5" input="1" from="6" output="1" />
+ <link to="6" input="0" from="8" output="0" />
+ <link to="1" input="1" from="2" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/slime.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/slime.jpg
new file mode 100644
index 0000000..39891cc
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/slime.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/soap_bubble.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/soap_bubble.bcm
new file mode 100644
index 0000000..5952423
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/soap_bubble.bcm
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.75489, 0.68663, 0.79909)" sample_lamp="True">
+ <nodes>
+ <node type="LAYER_WEIGHT" blend="0.89999" loc="-651, 778" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.0, 0.0, 1.0)" roughness="0.0" loc="-655, 631" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.0, 1.0, 0.0, 1.0)" roughness="0.0" loc="-651, 471" />
+ <node type="LAYER_WEIGHT" blend="0.30000" loc="-201, 737" />
+ <node type="MIX_SHADER" fac="0.5" loc="-184, 520" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.0, 0.0, 1.0, 1.0)" roughness="0.0" loc="-188, 341" />
+ <node type="LAYER_WEIGHT" blend="0.39998" loc="123, 733" />
+ <node type="MIX_SHADER" fac="0.5" loc="123, 516" />
+ <node type="MIX_SHADER" fac="0.5" loc="469, 321" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="486, 76" />
+ <node type="MIX_SHADER" fac="0.5" loc="797, 265" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.0" ior="1.45000" loc="808, 486" />
+ <node type="FRESNEL" ior="1.45000" loc="864, 676" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.48350, 0.0, 0.80000, 1.0)" roughness="0.0" loc="131, 217" />
+ <node type="OUTPUT_MATERIAL" loc="1790, 301" />
+ <node type="MIX_SHADER" fac="0.89999" loc="1232, 271" />
+ <node type="MIX_SHADER" fac="0.89999" loc="1570, 333" />
+ <node type="LIGHT_PATH" loc="1364, 592" />
+ <node type="BSDF_TRANSPARENT" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="1254, 128" />
+ </nodes>
+ <links>
+ <link to="16" input="1" from="15" output="0" />
+ <link to="4" input="0" from="0" output="1" />
+ <link to="7" input="1" from="4" output="0" />
+ <link to="7" input="0" from="3" output="1" />
+ <link to="8" input="1" from="7" output="0" />
+ <link to="4" input="1" from="1" output="0" />
+ <link to="4" input="2" from="2" output="0" />
+ <link to="7" input="2" from="5" output="0" />
+ <link to="8" input="2" from="13" output="0" />
+ <link to="8" input="0" from="6" output="0" />
+ <link to="10" input="1" from="8" output="0" />
+ <link to="10" input="2" from="9" output="0" />
+ <link to="15" input="1" from="11" output="0" />
+ <link to="15" input="2" from="10" output="0" />
+ <link to="15" input="0" from="12" output="0" />
+ <link to="14" input="0" from="16" output="0" />
+ <link to="16" input="0" from="17" output="1" />
+ <link to="16" input="2" from="18" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/soap_bubble.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/soap_bubble.jpg
new file mode 100644
index 0000000..35b1d9e
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/liquids/soap_bubble.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/bronze_ancient.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/bronze_ancient.bcm
new file mode 100644
index 0000000..f9d75b4
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/bronze_ancient.bcm
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.30153, 0.11162, 0.05403)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="633, 386" />
+ <node type="NEW_GEOMETRY" loc="-202, 555" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.10000" loc="182, 374" />
+ <node type="LAYER_WEIGHT" blend="0.46500" loc="-12, 235" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.04357, 0.04357, 0.04357, 1.0)" roughness="0.03999" loc="-33, 129" />
+ <node type="MIX_SHADER" fac="0.5" loc="214, 171" />
+ <node type="MIX_SHADER" fac="0.5" loc="429, 338" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.06498" loc="-33, -2" />
+ <node type="RGB" color="rgba(0.85499, 0.28891, 0.15745, 1.0)" loc="-414, 435" />
+ <node type="RGB" color="rgba(0.79909, 0.43415, 0.07225, 1.0)" loc="-414, 228" />
+ <node type="RGB" color="rgba(0.09000, 0.04159, 0.01396, 1.0)" loc="-414, 39" />
+ <node type="VECT_MATH" operation="DOT_PRODUCT" vector1="Vector(0.5, 0.5, 0.5)" vector2="Vector(0.5, 0.5, 0.5)" loc="-39, 565" />
+ <node type="MATH" operation="POWER" use_clamp="False" value1="0.5" value2="4.0" loc="159, 548" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="6" output="0" />
+ <link to="11" input="0" from="1" output="1" />
+ <link to="11" input="1" from="1" output="4" />
+ <link to="12" input="0" from="11" output="1" />
+ <link to="6" input="0" from="12" output="0" />
+ <link to="6" input="1" from="2" output="0" />
+ <link to="5" input="1" from="4" output="0" />
+ <link to="5" input="2" from="7" output="0" />
+ <link to="6" input="2" from="5" output="0" />
+ <link to="5" input="0" from="3" output="1" />
+ <link to="4" input="0" from="8" output="0" />
+ <link to="7" input="0" from="9" output="0" />
+ <link to="2" input="0" from="10" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/bronze_ancient.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/bronze_ancient.jpg
new file mode 100644
index 0000000..a04b47a
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/bronze_ancient.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/fools_gold.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/fools_gold.bcm
new file mode 100644
index 0000000..7bfa065
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/fools_gold.bcm
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.94870, 0.50081, 0.05448)" sample_lamp="True">
+ <nodes>
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.68531, 0.15028, 1.0)" roughness="0.15000" loc="48, 300" />
+ <node type="TEX_NOISE" scale="68.99987" detail="2.40684" distortion="12.65606" loc="52, 156" />
+ <node type="MATH" operation="GREATER_THAN" use_clamp="False" value1="0.5" value2="0.81199" loc="253, 125" />
+ <node type="TEX_MUSGRAVE" musgrave="FBM" scale="860.48791" detail="2.37062" dimension="2.0" lacunarity="44.37200" offset="0.0" gain="1.0" loc="51, -35" />
+ <node type="TEX_MAGIC" depth="2" scale="519.49645" distortion="28.07604" loc="41, -279" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.26600" loc="621, -107" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="593, 125" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="774, 118" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="-0.00400" loc="1052, -477" />
+ <node type="MATH" operation="SINE" use_clamp="False" value1="0.5" value2="2.43676" loc="762, -469" />
+ <node type="MATH" operation="TANGENT" use_clamp="False" value1="0.5" value2="0.52956" loc="909, -456" />
+ <node type="TEX_WAVE" wave="RINGS" scale="39.22412" distortion="21.16782" detail="2.31078" detail_scale="1.94421" loc="571, -411" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="954, 75" />
+ <node type="MATH" operation="SINE" use_clamp="False" value1="1.0" value2="0.5" loc="1603, -158" />
+ <node type="TEX_WAVE" wave="RINGS" scale="9.16790" distortion="9.56811" detail="2.04166" detail_scale="28.49596" loc="1318, -223" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.37356" value2="0.5" loc="1781, -163" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.05601" value2="0.5" loc="1959, -166" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="275.35241" loc="43, -465" />
+ <node type="VALUE" value="9.16800" loc="1210, -304" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="-89, 96" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="-100, -121" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="-90, -298" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="-97, -482" />
+ <node type="VALUE" value="39.22399" loc="421, -459" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="424, -548" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="1232, -456" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.00300" loc="1118, -164" />
+ <node type="TEX_MUSGRAVE" musgrave="MULTIFRACTAL" scale="504.95214" detail="2.26371" dimension="2.0" lacunarity="1.16760" offset="0.0" gain="1.0" loc="948, -170" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="1.0" value2="0.5" loc="806, -135" />
+ <node type="VALUE" value="504.95199" loc="831, -280" />
+ <node type="VALUE" value="0.5" loc="-532, 234" />
+ <node type="MATH" operation="GREATER_THAN" use_clamp="False" value1="0.5" value2="0.5" loc="442, -316" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="442, -108" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.30959" loc="282, -291" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="-0.20536" loc="605, -259" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.01236" loc="395, 131" />
+ <node type="VALUE" value="314.93222" loc="-339, -542" />
+ <node type="VALUE" value="296.85839" loc="-364, -375" />
+ <node type="VALUE" value="860.48797" loc="-356, -205" />
+ <node type="VALUE" value="69.0" loc="-368, 0" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="2184, -23" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.84039" loc="2485, 56" />
+ <node type="OUTPUT_MATERIAL" loc="2715, 178" />
+ </nodes>
+ <links>
+ <link to="42" input="0" from="0" output="0" />
+ <link to="35" input="0" from="2" output="0" />
+ <link to="2" input="1" from="1" output="1" />
+ <link to="6" input="0" from="35" output="0" />
+ <link to="32" input="1" from="4" output="1" />
+ <link to="32" input="0" from="3" output="1" />
+ <link to="6" input="1" from="5" output="0" />
+ <link to="31" input="0" from="17" output="1" />
+ <link to="34" input="0" from="31" output="0" />
+ <link to="5" input="0" from="34" output="0" />
+ <link to="7" input="0" from="6" output="0" />
+ <link to="26" input="0" from="27" output="1" />
+ <link to="7" input="1" from="26" output="0" />
+ <link to="9" input="0" from="11" output="1" />
+ <link to="12" input="0" from="7" output="0" />
+ <link to="10" input="0" from="9" output="0" />
+ <link to="12" input="1" from="8" output="0" />
+ <link to="8" input="0" from="10" output="0" />
+ <link to="40" input="1" from="12" output="0" />
+ <link to="41" input="0" from="40" output="0" />
+ <link to="13" input="1" from="14" output="1" />
+ <link to="15" input="1" from="13" output="0" />
+ <link to="16" input="1" from="15" output="0" />
+ <link to="40" input="0" from="16" output="0" />
+ <link to="19" input="1" from="39" output="0" />
+ <link to="1" input="1" from="19" output="0" />
+ <link to="20" input="1" from="38" output="0" />
+ <link to="3" input="1" from="20" output="0" />
+ <link to="21" input="1" from="37" output="0" />
+ <link to="4" input="1" from="21" output="0" />
+ <link to="22" input="1" from="36" output="0" />
+ <link to="17" input="1" from="22" output="0" />
+ <link to="24" input="1" from="23" output="0" />
+ <link to="11" input="1" from="24" output="0" />
+ <link to="25" input="1" from="18" output="0" />
+ <link to="14" input="1" from="25" output="0" />
+ <link to="28" input="1" from="29" output="0" />
+ <link to="27" input="1" from="28" output="0" />
+ <link to="19" input="0" from="30" output="0" />
+ <link to="20" input="0" from="30" output="0" />
+ <link to="21" input="0" from="30" output="0" />
+ <link to="22" input="0" from="30" output="0" />
+ <link to="28" input="0" from="30" output="0" />
+ <link to="25" input="0" from="30" output="0" />
+ <link to="24" input="0" from="30" output="0" />
+ <link to="42" input="2" from="41" output="0" />
+ <link to="33" input="0" from="32" output="0" />
+ <link to="31" input="1" from="33" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/fools_gold.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/fools_gold.jpg
new file mode 100644
index 0000000..b76bdf5
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/fools_gold.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/galvanized_steel.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/galvanized_steel.bcm
new file mode 100644
index 0000000..5838eb9
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/galvanized_steel.bcm
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="878, 186" />
+ <node type="MIX_SHADER" fac="0.5" loc="592, 198" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.86666, 1.0, 1.0, 1.0)" roughness="0.20000" loc="390, 315" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.20000" loc="396, 109" />
+ <node type="MATH" operation="DIVIDE" use_clamp="False" value1="0.5" value2="5.0" loc="182, 188" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="15.0" loc="-702, -28" />
+ <node type="RGBTOBW" color="rgba(0.5, 0.5, 0.5, 1.0)" loc="-221, -66" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="0.5" loc="-19, -32" />
+ <node type="TEX_NOISE" scale="10.0" detail="2.0" distortion="0.0" loc="-687, 259" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="15.0" value2="4.0" loc="-893, 268" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.75" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-479, -20" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="-64, 307" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="1.0" loc="-271, 56" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="15.0" loc="-1242, 75" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="3" input="1" from="4" output="0" />
+ <link to="11" input="0" from="12" output="0" />
+ <link to="4" input="0" from="11" output="0" />
+ <link to="1" input="1" from="2" output="0" />
+ <link to="1" input="2" from="3" output="0" />
+ <link to="2" input="1" from="4" output="0" />
+ <link to="3" input="0" from="7" output="0" />
+ <link to="7" input="0" from="6" output="0" />
+ <link to="10" input="1" from="8" output="0" />
+ <link to="10" input="2" from="5" output="0" />
+ <link to="12" input="0" from="10" output="0" />
+ <link to="6" input="0" from="10" output="0" />
+ <link to="8" input="1" from="9" output="0" />
+ <link to="9" input="0" from="13" output="0" />
+ <link to="5" input="1" from="13" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/galvanized_steel.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/galvanized_steel.jpg
new file mode 100644
index 0000000..ad8ff45
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/metals/galvanized_steel.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/forest.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/forest.bcm
new file mode 100644
index 0000000..683282d
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/forest.bcm
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="BSDF_DIFFUSE" color="rgba(0.07457, 0.07457, 0.07457, 1.0)" roughness="0.0" loc="653, 127" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="300.0" loc="655, 6" />
+ <node type="OUTPUT_MATERIAL" loc="3169, 115" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.0, 0.15665, 0.0, 1.0)" roughness="1.0" loc="-358, 276" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.01193, 0.02232, 0.0, 1.0)" roughness="0.0" loc="-364, 166" />
+ <node type="MIX_SHADER" fac="0.5" loc="76, 296" />
+ <node type="MIX_SHADER" fac="0.5" loc="142, -51" />
+ <node type="MIX_SHADER" fac="0.5" loc="362, 387" />
+ <node type="TEX_NOISE" scale="75.0" detail="2.0" distortion="0.0" loc="-366, 464" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.01066, 0.02866, 0.00134, 1.0)" roughness="1.0" loc="-282, -179" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.0, 0.0, 0.0, 1.0)" loc="952, 303" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="0.19999" contrast="1.0" loc="769, 417" />
+ <node type="TEX_NOISE" scale="10.0" detail="5.0" distortion="1.0" loc="530, 545" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="250.0" loc="1103, -226" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.08599, 0.19126, 0.00800, 1.0)" roughness="1.0" loc="-285, -301" />
+ <node type="MIX_SHADER" fac="0.5" loc="1355, 217" />
+ <node type="TEX_NOISE" scale="15.0" detail="5.0" distortion="0.0" loc="1386, 54" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="0.0" contrast="1.0" loc="1574, -19" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.0, 0.0, 0.0, 1.0)" color2="rgba(1.0, 1.0, 1.0, 1.0)" loc="1735, 547" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="1765, -133" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.0, 0.0, 0.0, 1.0)" color2="rgba(1.0, 1.0, 1.0, 1.0)" loc="2217, 3" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.01405, 0.03752, 0.01255, 1.0)" roughness="1.0" loc="64, 137" />
+ <node type="TEX_NOISE" scale="100.0" detail="2.0" distortion="5.0" loc="74, 532" />
+ <node type="MIX_SHADER" fac="0.5" loc="1956, 336" />
+ <node type="TEX_NOISE" scale="10.0" detail="5.0" distortion="0.5" loc="1296, 683" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="2.0" contrast="20.0" loc="1523, 638" />
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="2.0" contrast="20.0" loc="2054, 46" />
+ <node type="TEX_NOISE" scale="10.0" detail="5.0" distortion="0.5" loc="1880, 138" />
+ <node type="HUE_SAT" hue="0.5" saturation="1.0" value="500.0" fac="1.0" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="1961, -95" />
+ <node type="TEX_NOISE" scale="300.0" detail="5.0" distortion="0.0" loc="1092, -25" />
+ <node type="INVERT" fac="1.0" color="rgba(0.0, 0.0, 0.0, 1.0)" loc="2494, -41" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.0, 0.0, 0.0, 1.0)" color2="rgba(1.0, 1.0, 1.0, 1.0)" loc="2370, -135" />
+ <node type="TEX_NOISE" scale="50.0" detail="5.0" distortion="0.0" loc="-355, 15" />
+ </nodes>
+ <links>
+ <link to="2" input="0" from="23" output="0" />
+ <link to="2" input="2" from="30" output="0" />
+ <link to="5" input="1" from="3" output="0" />
+ <link to="5" input="2" from="4" output="0" />
+ <link to="7" input="1" from="5" output="0" />
+ <link to="7" input="2" from="21" output="0" />
+ <link to="6" input="1" from="9" output="0" />
+ <link to="6" input="2" from="14" output="0" />
+ <link to="15" input="1" from="7" output="0" />
+ <link to="15" input="2" from="6" output="0" />
+ <link to="11" input="0" from="12" output="1" />
+ <link to="15" input="0" from="10" output="0" />
+ <link to="10" input="0" from="11" output="0" />
+ <link to="5" input="0" from="8" output="1" />
+ <link to="7" input="0" from="22" output="1" />
+ <link to="6" input="0" from="32" output="1" />
+ <link to="19" input="1" from="29" output="1" />
+ <link to="19" input="2" from="13" output="1" />
+ <link to="28" input="4" from="19" output="0" />
+ <link to="17" input="0" from="16" output="1" />
+ <link to="19" input="0" from="17" output="0" />
+ <link to="23" input="2" from="15" output="0" />
+ <link to="25" input="0" from="24" output="1" />
+ <link to="23" input="0" from="18" output="0" />
+ <link to="18" input="0" from="25" output="0" />
+ <link to="26" input="0" from="27" output="1" />
+ <link to="20" input="0" from="26" output="0" />
+ <link to="31" input="0" from="20" output="0" />
+ <link to="30" input="1" from="31" output="0" />
+ <link to="31" input="2" from="28" output="0" />
+ <link to="23" input="1" from="0" output="0" />
+ <link to="31" input="1" from="1" output="1" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/forest.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/forest.jpg
new file mode 100644
index 0000000..81b2db0
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/forest.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/lava.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/lava.bcm
new file mode 100644
index 0000000..cf89843
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/lava.bcm
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.5" loc="87, 374" />
+ <node type="EMISSION" color="rgba(0.54981, 0.25838, 0.0, 1.0)" strength="1.0" loc="-100, 422" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="3.0" loc="-315, 423" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.25" loc="-321, 208" />
+ <node type="MIX_SHADER" fac="0.25" loc="-98, 291" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.75" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-317, 68" />
+ <node type="INVERT" fac="1.0" color="rgba(0.0, 0.0, 0.0, 1.0)" loc="-511, 26" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="5.0" loc="-709, 153" />
+ <node type="TEX_COORD" loc="-941, 183" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="50.0" loc="-709, 316" />
+ <node type="OUTPUT_MATERIAL" loc="285, 296" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.10000, 0.10000, 0.10000, 1.0)" roughness="0.0" loc="-317, 319" />
+ </nodes>
+ <links>
+ <link to="2" input="0" from="7" output="1" />
+ <link to="4" input="1" from="11" output="0" />
+ <link to="0" input="1" from="1" output="0" />
+ <link to="1" input="1" from="2" output="0" />
+ <link to="0" input="2" from="4" output="0" />
+ <link to="4" input="2" from="3" output="0" />
+ <link to="7" input="0" from="8" output="3" />
+ <link to="9" input="0" from="8" output="3" />
+ <link to="6" input="1" from="7" output="1" />
+ <link to="5" input="2" from="6" output="0" />
+ <link to="5" input="1" from="9" output="1" />
+ <link to="10" input="2" from="5" output="0" />
+ <link to="10" input="0" from="0" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/lava.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/lava.jpg
new file mode 100644
index 0000000..3836ed3
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/lava.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/pearl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/pearl.bcm
new file mode 100644
index 0000000..759721a
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/pearl.bcm
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.76051, 0.76051, 0.56025)" sample_lamp="True">
+ <nodes>
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.99220, 0.81102, 1.0)" roughness="0.05000" loc="-556, 423" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.5" loc="-572, 29" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="-572, -148" />
+ <node type="MIX_SHADER" fac="0.5" loc="-41, 177" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="-34, -3" />
+ <node type="MIX_SHADER" fac="0.5" loc="-291, 33" />
+ <node type="MIX_SHADER" fac="0.5" loc="-289, 253" />
+ <node type="BSDF_DIFFUSE" color="rgba(1.0, 0.99220, 0.81102, 1.0)" roughness="0.0" loc="-569, 231" />
+ <node type="MIX_SHADER" fac="0.10000" loc="191, 130" />
+ <node type="OUTPUT_MATERIAL" loc="451, 150" />
+ </nodes>
+ <links>
+ <link to="9" input="0" from="8" output="0" />
+ <link to="3" input="1" from="6" output="0" />
+ <link to="6" input="1" from="0" output="0" />
+ <link to="8" input="1" from="3" output="0" />
+ <link to="6" input="2" from="7" output="0" />
+ <link to="5" input="1" from="1" output="0" />
+ <link to="5" input="2" from="2" output="0" />
+ <link to="3" input="2" from="5" output="0" />
+ <link to="8" input="2" from="4" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/pearl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/pearl.jpg
new file mode 100644
index 0000000..162b98f
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/nature/pearl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/barbwire_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/barbwire_osl.bcm
new file mode 100644
index 0000000..071aa86
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/barbwire_osl.bcm
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="SCRIPT" mode="INTERNAL" script="0" width="0.05000" turns="2" spiketurns="2" xscale="1.0" pos="Vector(0.0, 0.0, 0.0)" loc="-219, 356" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="-224, 120" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.48658, 0.48658, 0.48658, 1.0)" roughness="0.20000" loc="-222, 41" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(15.0, 15.0, 15.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-503, 315" />
+ <node type="TEX_COORD" dupli="False" loc="-702, 259" />
+ <node type="MIX_SHADER" fac="0.5" loc="-31, 231" />
+ <node type="OUTPUT_MATERIAL" loc="165, 323" />
+ </nodes>
+ <links>
+ <link to="6" input="0" from="5" output="0" />
+ <link to="6" input="2" from="0" output="1" />
+ <link to="5" input="0" from="0" output="0" />
+ <link to="0" input="4" from="3" output="0" />
+ <link to="3" input="0" from="4" output="2" />
+ <link to="5" input="1" from="1" output="0" />
+ <link to="5" input="2" from="2" output="0" />
+ </links>
+ <scripts>
+ <script name="MABarbWire.osl" id="0">
+/*<br /> Barbwire shader by Michel J. Anders (c)2012<br /> license: cc-by-sa<br /> http://blenderthings.blogspot.com.au/2012/12/a-barbwire-osl-shader-for-blender-cycles.html<br />*/<br /><br />#include "stdosl.h"<br /><br />float arc(float r){ return sqrt(0.25-(r-0.5)*(r-0.5)); }<br /><br />shader barbwire(<br /> float Width = 0.05,<br /> int Turns = 2,<br /> int Spiketurns = 2,<br /> float Xscale = 1,<br /> point Pos = P,<br /> output float Fac = 0,<br /> output float Displ = 0 )<br />{<br /> float x = mod(Pos[0],1);<br /> float y = mod(Pos[1],1);<br /><br /> if ( x > 0.5 ) {<br /> x = 1 - x;<br /> y = 1 - y;<br /> }<br /><br /> float w = Width/2;<br /> float t = M_2PI*x*Turns;<br /><br /> float c = cos(t);<br /> float h = c*w+w;<br /> float l = c*w-w;<br /><br /> y -= 0.5;<br /> // the barb part<br /> float BWidth = Width*Xscale;<br /> float Lw = BWidth*(Spiketurns-1);<br /> float Hw = BWidth*Spiketurns;<br /> if ( x > Lw && x < Hw && y > 1.5*Width && y<4*Width ) { // the spikey part<br /> if( y<3*Width || y-3*Width < x-Width){<br /> Fac = 1;<br /> Displ = arc(mod(x,BWidth)/BWidth);<br /> }<br /> } else if ( x < Hw && abs(y) < 2*Width ){<br /> if ( abs(y) > 1.5*Width) { // the rounded top and bottom parts<br /> if ( abs(y) - 1.5*Width < w*arc(mod(x,BWidth)/BWidth) ){<br /> Fac = 1;<br /> Displ = arc(mod(x,BWidth)/BWidth);<br /> }<br /> } else { // the main part<br /> Fac = 1;<br /> Displ = arc(mod(x,BWidth)/BWidth);<br /> }<br /> }<br /> // the wire part<br /> else {<br /> // alternating top/bottom checks to get correct crossings<br /> if ( (int)(t/M_PI) % 2 == 1 ){<br /><br /> if ( y > l && y < h ) {<br /> Fac = 1;<br /> Displ = arc((y-l)/Width);<br /> } else if ( -y > l && -y < h ) {<br /> Fac = 1;<br /> Displ = arc((-y-l)/Width);<br /> }<br /><br /> } else {<br /><br /> if ( -y > l && -y < h ) {<br /> Fac = 1;<br /> Displ = arc((-y-l)/Width);<br /> } else if ( y > l && y < h ) {<br /> Fac = 1;<br /> Displ = arc((y-l)/Width);<br /> }<br /> }<br /> }<br />}<br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/barbwire_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/barbwire_osl.jpg
new file mode 100644
index 0000000..7ac7dfd
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/barbwire_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/chain_link_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/chain_link_osl.bcm
new file mode 100644
index 0000000..c174784
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/chain_link_osl.bcm
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(30.0, 30.0, 30.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-718, 291" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" vector="Vector(0.0, 0.0, 0.0)" width="0.05000" loc="-417, 331" />
+ <node type="BSDF_TRANSPARENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="-415, 151" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.47248, 0.47248, 0.47248, 1.0)" roughness="0.30000" loc="-423, 64" />
+ <node type="TEX_COORD" dupli="False" loc="-942, 196" />
+ <node type="OUTPUT_MATERIAL" loc="-58, 331" />
+ <node type="MIX_SHADER" fac="0.5" loc="-233, 233" />
+ </nodes>
+ <links>
+ <link to="5" input="2" from="1" output="1" />
+ <link to="5" input="0" from="6" output="0" />
+ <link to="6" input="0" from="1" output="0" />
+ <link to="6" input="1" from="2" output="0" />
+ <link to="1" input="0" from="0" output="0" />
+ <link to="0" input="0" from="4" output="2" />
+ <link to="6" input="2" from="3" output="0" />
+ </links>
+ <scripts>
+ <script name="MAChainLink.osl" id="0">
+/*<br /> Chainlink shader by Michel J. Anders (c)2012<br /> license: cc-by-sa<br /> http://blenderthings.blogspot.com.au/2012/12/a-chainlink-fence-osl-shader-for.html<br />*/<br /><br />#include "stdosl.h"<br /><br />float arc(float x){ return sqrt(1-(x-0.5)*(x-0.5)/0.25); }<br /><br />shader chainlink(<br /> point Vector = P,<br /> float Width = 0.05,<br /> output float Fac = 0,<br /> output float Displ = 0<br />){<br /> float x = mod(Vector[0],1);<br /> float y = mod(Vector[1],1);<br /> float ox = x ;<br /> float oy = y ;<br /> x += Width * (0.5 - oy );<br /> y -= Width * (ox - 0.5 );<br /><br /> if ( y > 0.5 ){<br /> y = 1 - y;<br /> x = 1 - x;<br /> }<br /> if ( x > 0.5 ){<br /> if ( y > 0.5 - Width ){<br /> Fac = 1;<br /> Displ = arc((y-(0.5-Width))/Width);<br /> }else if (x < 0.5 + Width) {<br /> Fac = 1;<br /> Displ = arc((x-0.5)/Width);<br /> }else{<br /> float r = hypot(x-0.5,y-0.5);<br /> if (r < Width) {<br /> Fac = 1;<br /> Displ = arc(r/Width);<br /> }<br /> }<br /> }<br />}<br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/chain_link_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/chain_link_osl.jpg
new file mode 100644
index 0000000..e2a35de
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/chain_link_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/hex_tile_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/hex_tile_osl.bcm
new file mode 100644
index 0000000..c14444e
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/hex_tile_osl.bcm
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="17, 420" />
+ <node type="TEX_COORD" dupli="False" loc="-885, 347" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" vector="Vector(0.0, 0.0, 0.0)" diffuseamt="0.70000" specularamt="0.10000" roughness="0.19999" specularcolor="rgba(1.0, 1.0, 1.0, 1.0)" tilecolor="rgba(0.55000, 0.04777, 0.06694, 1.0)" mortarcolor="rgba(0.12053, 0.13075, 0.39999, 1.0)" tileradius="0.20000" mortarwidth="0.01999" tilevary="1.0" scuffing="0.70000" scufffrequency="4.0" scuffcolor="rgba(0.05000, 0.05000, 0.05000, 1.0)" stains="0.60000" stainfrequency="2.0" loc="-269, 467" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(10.0, 10.0, 10.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-626, 392" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="2" output="0" />
+ <link to="2" input="0" from="3" output="0" />
+ <link to="3" input="0" from="1" output="2" />
+ </links>
+ <scripts>
+ <script name="LGHexTile.osl" id="0">
+/*<br /> * hextile.sl -- surface shader for hexagonal tiles in st space<br /> *<br /> * DESCRIPTION<br /> * This surface shader operates in s-t space and gives a pattern of<br /> * hexagonal tiles, similar to that found as floor patterns in public<br /> * places and such.<br /> * The basic pattern is a hexagonal tiling, with a little bit of<br /> * color variation from tile to tile. On top of that is some staining<br /> * (presumably due to water or something), which darkens the tile or<br /> * mortar underneath it. Finally, there is Scuffing due to people's<br /> * shoes, which really only affects the tile part not the mortar part.<br /> *<br /> *<br /> * PARAMTERS<br /> * DiffuseAmt, SpecularAmt, Roughness, SpecularColor - work just like plastic<br /> * TileColor - the color of the tiles<br /> * MortarColor - the color of the mortar (space between the tiles)<br /> * TileRadius - the "radius" (in s-t units) of a single tile<br /> * MortarWidth - the width of the mortar (in s-t units)<br /> * TileVary - the color variance from tile to tile<br /> *<br /> * ANTIALIASING<br /> * Some rudimentary antialiasing is performed on the borders between<br /> * tile and mortar.<br /> *<br /> * HINTS & APPLICATIONS<br /> * If all of the default parameters are used, the tiles look just like<br /> * the floors in the public areas of the Washington DC subway system.<br /> *<br /> * AUTHOR: written by Larry Gritz, 1994<br /> *<br /> * HISTORY:<br /> * 15 Feb 1994 -- written by lg<br /> * Dec 2012 -- converted/hacked to OSL by varkenvarken<br /> * 17 Dec 2012 -- rename inputs by SAmbler<br /> *<br /> * last modified 15 Feb 94 by Larry Gritz<br /> */<br /><br />shader<br />LGHexTile (<br /> point Vector = P,<br /> float DiffuseAmt = .5,<br /> float SpecularAmt = .2,<br /> float Roughness = .1,<br /> color SpecularColor = 1,<br /> color TileColor = color(.55,0,0),<br /> color MortarColor = color(.5,.5,.5),<br /> float TileRadius = 0.2,<br /> float MortarWidth = 0.02,<br /> float TileVary = 0.15,<br /> float Scuffing = 0.5,<br /> float ScuffFrequency = 4,<br /> color ScuffColor = color (.05,.05,.05),<br /> float Stains = 0.4,<br /> float StainFrequency = 2,<br /> output closure color BSDF = diffuse(N)<br />)<br />{<br /> #define snoise(x) (2*noise(x)-1)<br /> #define snoise2(x,y) (2*noise((x),(y))-1)<br /> #define MINFILTERWIDTH 1.0e-7<br /> #define M_SQRT3 1.7320508 /* sqrt(3) */<br /> <br /> point Nf;<br /> color Ct, Ctile;<br /> float tilewidth;<br /> float ss, tt;<br /> float ttile, stile;<br /> float x, y;<br /> float mortar;<br /> float swidth, twidth, sfuzz, tfuzz, fuzzmax;<br /> float mw2, mw2srt3;<br /> float tileindex;<br /> float stain, scuff;<br /> float ks;<br /><br /> float s = Vector[0];<br /> float t = Vector[1];<br /><br /> swidth = abs(Dx(s)) + abs(Dy(s));<br /> twidth = abs(Dx(t)) + abs(Dy(t));<br /> sfuzz = 0.5 * swidth;<br /> tfuzz = 0.5 * twidth;<br /> fuzzmax = max(sfuzz, tfuzz);<br /> Nf = N;<br /><br /> tilewidth = TileRadius * M_SQRT3;<br /> tt = mod (t, 1.5*TileRadius);<br /> ttile = floor(t/(1.5*TileRadius));<br /> if (mod(ttile/2, 1) == 0.5)<br /> ss = s + tilewidth/2;<br /> else ss = s;<br /> stile = floor(ss / tilewidth);<br /> ss = mod(ss, tilewidth);<br /> mortar = 0;<br /> mw2 = MortarWidth/2;<br /> if (tt < TileRadius) {<br /> mortar = 1 - (smoothstep(mw2,mw2+sfuzz,ss) *<br /> (1 - smoothstep(tilewidth-mw2-sfuzz,tilewidth-mw2,ss)));<br /> }<br /> else {<br /> x = tilewidth/2 - abs(ss - tilewidth/2);<br /> y = M_SQRT3 * (tt - TileRadius);<br /> if (y > x) {<br /> if (mod (ttile/2, 1) == 0.5)<br /> stile -= 1;<br /> ttile += 1;<br /> if (ss > tilewidth/2)<br /> stile += 1;<br /> }<br /><br /> mw2srt3 = M_SQRT3*mw2;<br /> mortar = (smoothstep(x-mw2srt3-tfuzz, x-mw2srt3, y) *<br /> (1 - smoothstep(x+mw2srt3, x+mw2srt3+tfuzz, y)));<br /> }<br /><br /> tileindex = stile+41*ttile;<br /> Ctile = TileColor * (1 + TileVary * snoise(tileindex+0.5));<br /><br /> stain = Stains * smoothstep (.5,1, noise(s*StainFrequency,t*StainFrequency));<br /><br /> scuff = Scuffing * smoothstep (.6,1, noise(t*ScuffFrequency-90.26,s*ScuffFrequency+123.82));<br /><br /> ks = SpecularAmt * (1-scuff/2);<br /> Ct = (1-stain) * mix(mix(Ctile, ScuffColor, scuff), MortarColor, mortar);<br /><br /> Nf = normalize(N);<br /> BSDF = Ct*DiffuseAmt*diffuse(Nf);<br /> BSDF += SpecularColor*ks*microfacet_beckmann(Nf,Roughness);<br />}<br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/hex_tile_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/hex_tile_osl.jpg
new file mode 100644
index 0000000..80519d6
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/hex_tile_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/sierpinski_squares_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/sierpinski_squares_osl.bcm
new file mode 100644
index 0000000..5743419
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/sierpinski_squares_osl.bcm
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="BRIGHTCONTRAST" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="-0.05000" contrast="0.30000" loc="223, 395" />
+ <node type="TANGENT" direction="RADIAL" axis="Y" loc="199, 258" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(1.0, 0.89999, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-659, 401" />
+ <node type="TEX_COORD" dupli="False" loc="-889, 332" />
+ <node type="VALTORGB" interpolation="LINEAR" fac="0.5" stops="8" stop1="0.0|rgba(0.42573, 0.38247, 0.05731, 1.0)" stop2="0.25|rgba(0.25, 0.20410, 0.0, 1.0)" stop3="0.5|rgba(0.5, 0.0, 0.05438, 1.0)" stop4="0.625|rgba(0.0, 0.17271, 0.02292, 1.0)" stop5="0.75|rgba(0.50702, 0.0, 0.52719, 1.0)" stop6="0.875|rgba(0.17083, 0.14998, 0.16761, 1.0)" stop7="0.9375|rgba(0.08121, 0.42573, 0.0, 1.0)" stop8="1.0|rgba(0.14220, 0.14909, 0.44060, 1.0)" loc="-67, 357" />
+ <node type="OUTPUT_MATERIAL" loc="733, 388" />
+ <node type="BSDF_ANISOTROPIC" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.09999" anisotropy="0.80000" rotation="0.49999" loc="411, 402" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" zoom="0.05000" vector="Vector(0.0, 0.0, 0.0)" maxiterations="6.0" loc="-379, 400" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="4" output="0" />
+ <link to="4" input="0" from="7" output="1" />
+ <link to="6" input="0" from="0" output="0" />
+ <link to="7" input="1" from="2" output="0" />
+ <link to="2" input="0" from="3" output="2" />
+ <link to="5" input="0" from="6" output="0" />
+ <link to="6" input="5" from="1" output="0" />
+ </links>
+ <scripts>
+ <script name="sierpinski squares.osl" id="0">
+#include "stdosl.h"<br /><br />float genCheck(vector p, float res)<br />{<br /> return (mod(res * p[0], 1.0) < 0.5 ^ mod(res * p[1], 1.0) < 0.5) ?<br /> 0.0 : 1.0;<br />}<br /><br />shader sierpinski_squares(<br /> float Zoom = 1.0,<br /> vector Vector = P,<br /> float MaxIterations = 10.0,<br /> output float Fac = 1.0,<br /> output color ColorOut = 0.8) <br />{<br /> vector p = Vector/(2.0*Zoom);<br /> float diExp = 1.0;<br /> float result = genCheck(p,1.0);<br /><br /> for(float i = 0.7; i <= MaxIterations; i++)<br /> {<br /> result += genCheck(p,diExp) / i;<br /><br /> diExp *= 2.0;<br /> }<br /> result /= MaxIterations / 2.0;<br /><br /> Fac = result;<br /> ColorOut = color(result,result,result);<br />}<br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/sierpinski_squares_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/sierpinski_squares_osl.jpg
new file mode 100644
index 0000000..835c296
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/patterns/sierpinski_squares_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/plastics/toy_brick_red.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/plastics/toy_brick_red.bcm
new file mode 100644
index 0000000..41f0350
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/plastics/toy_brick_red.bcm
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.99730, 0.01052, 0.01052)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="520, 292" />
+ <node type="MIX_SHADER" fac="0.87999" loc="320, 292" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.67269, 0.19188, 0.19725, 1.0)" roughness="0.11998" loc="120, 292" />
+ <node type="MIX_SHADER" fac="0.05000" loc="116, 157" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.74998, 0.22974, 0.23562, 1.0)" loc="-83, 13" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.91029, 0.00455, 0.00455, 1.0)" roughness="0.11999" loc="-80, 148" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="1" from="2" output="0" />
+ <link to="1" input="2" from="3" output="0" />
+ <link to="3" input="1" from="5" output="0" />
+ <link to="3" input="2" from="4" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/plastics/toy_brick_red.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/plastics/toy_brick_red.jpg
new file mode 100644
index 0000000..796fcbe
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/plastics/toy_brick_red.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/dragon_scales_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/dragon_scales_osl.bcm
new file mode 100644
index 0000000..48f6e44
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/dragon_scales_osl.bcm
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="VALTORGB" interpolation="EASE" fac="0.5" stops="4" stop1="0.00454|rgba(0.00891, 0.04817, 0.00561, 1.0)" stop2="0.11817|rgba(1.0, 1.0, 1.0, 1.0)" stop3="0.81362|rgba(0.79909, 0.43964, 0.13562, 1.0)" stop4="1.0|rgba(0.00903, 0.06681, 0.0, 1.0)" loc="424, 643" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.20000" loc="727, 475" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="729, 610" />
+ <node type="MIX_SHADER" fac="0.11998" loc="927, 553" />
+ <node type="OUTPUT_MATERIAL" loc="1102, 446" />
+ <node type="TEX_MAGIC" depth="2" scale="0.5" distortion="1.0" loc="472, 427" />
+ <node type="TEX_MUSGRAVE" musgrave="FBM" scale="0.48800" detail="4.80000" dimension="2.0" lacunarity="1.0" offset="0.0" gain="1.0" loc="233, 619" />
+ <node type="INVERT" fac="1.0" color="rgba(0.0, 0.0, 0.0, 1.0)" loc="133, 359" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" diffuse_color1="rgba(0.20000, 0.80000, 0.20000, 1.0)" diffuse_color2="rgba(0.80000, 0.20000, 0.20000, 1.0)" coordinates="Vector(0.0, 0.0, 0.0)" n="0.09999" loc="-67, 618" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(60.0, 60.0, 60.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-234, 567" />
+ <node type="TEX_COORD" dupli="False" loc="-468, 574" />
+ </nodes>
+ <links>
+ <link to="8" input="2" from="9" output="0" />
+ <link to="6" input="0" from="8" output="3" />
+ <link to="4" input="0" from="3" output="0" />
+ <link to="3" input="1" from="2" output="0" />
+ <link to="3" input="2" from="1" output="0" />
+ <link to="2" input="0" from="0" output="0" />
+ <link to="0" input="0" from="6" output="1" />
+ <link to="4" input="2" from="7" output="0" />
+ <link to="6" input="1" from="8" output="1" />
+ <link to="7" input="1" from="8" output="2" />
+ <link to="1" input="0" from="5" output="0" />
+ <link to="9" input="0" from="10" output="0" />
+ </links>
+ <scripts>
+ <script name="MAscales.osl" id="0">
+<br />/*<br /> scales shader by Michel J. Anders (c)2012<br /> license: cc-by-sa<br /> http://blenderthings.blogspot.co.uk/2012/11/a-scales-osl-shader-for-blender.html<br />*/<br /><br />#include "stdosl.h"<br /><br />shader MAscales(<br /> color Diffuse_Color1 = color(0.2, 0.8, 0.2),<br /> color Diffuse_Color2 = color(0.8, 0.2, 0.2),<br /> vector Coordinates = 0,<br /> float n = 0,<br /> output color Color = 0,<br /> output int Index = 1,<br /> output float Distance = 0,<br /> output vector Vindex = 0)<br />{<br /> float sx = mod(Coordinates[0],1);<br /> float sy = mod(Coordinates[1],1);<br /> <br /> vector p = vector(sx,sy,0);<br /> vector p0 = vector(0.5,0,0);<br /> vector p1 = vector(0.5,1,0);<br /> vector p2 = vector(0,0.5,0);<br /> vector p3 = vector(1,0.5,0);<br /> <br /> vector cell = vector(floor(Coordinates[0]),floor(Coordinates[1]),0);<br /> int oddx = int(cell[0])%2;<br /> int oddy = int(cell[1])%2;<br /> <br /> float dist(vector a, vector b, float n){<br /> float x = b[0]-a[0];<br /> float y = b[1]-a[1];<br /> float r2 = x*x+y*y;<br /> if ( n != 0.0 ) {<br /> float theta = atan2(y,x);<br /> float cost, sint;<br /> sincos(theta, sint, cost);<br /> float cost2= cos(theta*2);<br /> float Y = pow(abs(sint),1+n*(1-cost2*cost2));<br /> r2 /= cost*cost+Y*Y;<br /> }<br /> return sqrt(r2);<br /> }<br /> <br /> float d1 = dist(p,p0,n);<br /> if ( d1<=0.5 ){<br /> Color = Diffuse_Color1;<br /> Index = 0 ;<br /> Distance = d1;<br /> Vindex = cell + p0;<br /> } else {<br /> float d2 = dist(p,p2,n);<br /> float d3 = dist(p,p3,n);<br /> if ( d2 <= 0.5 ) {<br /> Color = Diffuse_Color2;<br /> Index = 1;<br /> Distance = d2;<br /> Vindex = cell + p2;<br /> } else if ( d3 <= 0.5 ) {<br /> Color = Diffuse_Color2;<br /> Index = 1;<br /> Distance = d3;<br /> Vindex = cell + p3;<br /> } else {<br /> Color = Diffuse_Color1;<br /> Index = 0;<br /> Distance = dist(p,p1,n);<br /> Vindex = cell + p1;<br /> }<br /> }<br />}<br /><br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/dragon_scales_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/dragon_scales_osl.jpg
new file mode 100644
index 0000000..5a23a0a
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/dragon_scales_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/pox.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/pox.bcm
new file mode 100644
index 0000000..a2e2e5c
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/pox.bcm
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="572, 314" />
+ <node type="VALTORGB" interpolation="B_SPLINE" fac="0.5" stops="3" stop1="0.0|rgba(1.0, 1.0, 1.0, 1.0)" stop2="0.09772|rgba(0.0, 0.0, 0.0, 1.0)" stop3="0.15454|rgba(0.0, 0.0, 0.0, 1.0)" loc="-1016, 194" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.86315, 0.73791, 0.65140, 1.0)" roughness="0.0" loc="-817, 539" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.13812, 0.12151, 1.0)" roughness="0.30000" loc="-474, 186" />
+ <node type="RGBTOBW" color="rgba(0.5, 0.5, 0.5, 1.0)" loc="-119, 17" />
+ <node type="MIX_SHADER" fac="0.20000" loc="-212, 252" />
+ <node type="MIX_SHADER" fac="0.5" loc="-14, 419" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.30000" loc="34, 69" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="10.0" loc="-1255, 93" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.86315, 0.73791, 0.65140, 1.0)" roughness="0.30000" loc="-864, 409" />
+ <node type="MIX_SHADER" fac="0.10000" loc="-397, 491" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.13812, 0.12151, 1.0)" roughness="0.10000" loc="-598, 23" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="6" output="0" />
+ <link to="0" input="2" from="7" output="0" />
+ <link to="1" input="0" from="8" output="0" />
+ <link to="4" input="0" from="1" output="0" />
+ <link to="6" input="0" from="1" output="0" />
+ <link to="10" input="1" from="2" output="0" />
+ <link to="6" input="1" from="10" output="0" />
+ <link to="10" input="2" from="9" output="0" />
+ <link to="7" input="0" from="4" output="0" />
+ <link to="5" input="1" from="3" output="0" />
+ <link to="6" input="2" from="5" output="0" />
+ <link to="5" input="2" from="11" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/pox.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/pox.jpg
new file mode 100644
index 0000000..93e7340
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/skin/pox.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/diamond.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/diamond.bcm
new file mode 100644
index 0000000..ef2d70c
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/diamond.bcm
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.85058, 0.84081, 0.85058)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="1.0" color1="rgba(0.0, 0.0, 1.0, 1.0)" color2="rgba(0.0, 0.0, 1.0, 1.0)" loc="-199, -49" />
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="1.0" color1="rgba(1.0, 0.0, 0.0, 1.0)" color2="rgba(0.0, 0.0, 1.0, 1.0)" loc="-199, 290" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(0.0, 0.0, 1.0, 1.0)" roughness="0.0" ior="1.44000" loc="-51, -51" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(1.0, 0.0, 0.0, 1.0)" roughness="0.0" ior="1.39999" loc="-51, 286" />
+ <node type="ADD_SHADER" loc="128, 236" />
+ <node type="ADD_SHADER" loc="297, 173" />
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="1.0" color1="rgba(0.0, 1.0, 0.0, 1.0)" color2="rgba(0.0, 0.0, 1.0, 1.0)" loc="-199, 119" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.10000" value2="0.10000" loc="-687, 119" />
+ <node type="SEPRGB" image="rgba(1.0, 1.0, 1.0, 1.0)" loc="-334, 119" />
+ <node type="BSDF_GLASS" distribution="BECKMANN" color="rgba(0.0, 1.0, 0.0, 1.0)" roughness="0.0" ior="2.46000" loc="-51, 119" />
+ <node type="ADD_SHADER" loc="466, 119" />
+ <node type="OUTPUT_MATERIAL" loc="642, 119" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="2.46000" value2="0.5" loc="-493, -67" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="2.46000" value2="0.5" loc="-493, 287" />
+ </nodes>
+ <links>
+ <link to="11" input="0" from="10" output="0" />
+ <link to="5" input="0" from="4" output="0" />
+ <link to="10" input="0" from="5" output="0" />
+ <link to="4" input="0" from="3" output="0" />
+ <link to="5" input="1" from="9" output="0" />
+ <link to="10" input="1" from="2" output="0" />
+ <link to="6" input="2" from="8" output="1" />
+ <link to="3" input="0" from="1" output="0" />
+ <link to="9" input="0" from="6" output="0" />
+ <link to="2" input="0" from="0" output="0" />
+ <link to="2" input="2" from="12" output="0" />
+ <link to="3" input="2" from="13" output="0" />
+ <link to="12" input="1" from="7" output="0" />
+ <link to="13" input="1" from="7" output="0" />
+ <link to="0" input="2" from="8" output="2" />
+ <link to="1" input="2" from="8" output="0" />
+ </links>
+</material>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/diamond.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/diamond.jpg
new file mode 100644
index 0000000..a16a4ff
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/diamond.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/malachite.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/malachite.bcm
new file mode 100644
index 0000000..340a5ef
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/malachite.bcm
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.08228, 0.33245, 0.09529)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.05000" loc="382, 116" />
+ <node type="MIX_SHADER" fac="0.5" loc="105, 116" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="105, -14" />
+ <node type="LAYER_WEIGHT" blend="0.10000" loc="105, 258" />
+ <node type="GAMMA" color="rgba(1.0, 1.0, 1.0, 1.0)" gamma="0.5" loc="-105, 301" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.08229, 0.33015, 0.09638, 1.0)" roughness="0.0" loc="-324, 116" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.0, 0.0, 0.0, 1.0)" roughness="0.25" loc="-324, -14" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="5.0" loc="-324, 301" />
+ <node type="MATH" operation="DIVIDE" use_clamp="False" value1="200.0" value2="4.0" loc="-613, 116" />
+ <node type="OUTPUT_MATERIAL" loc="590, 116" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="200.0" loc="-613, 301" />
+ <node type="VALUE" value="1.79999" loc="-791, 101" />
+ <node type="TEX_COORD" loc="-988, 301" />
+ </nodes>
+ <links>
+ <link to="9" input="0" from="0" output="0" />
+ <link to="1" input="1" from="5" output="0" />
+ <link to="0" input="1" from="1" output="0" />
+ <link to="1" input="2" from="6" output="0" />
+ <link to="4" input="0" from="7" output="0" />
+ <link to="1" input="0" from="4" output="0" />
+ <link to="0" input="2" from="2" output="0" />
+ <link to="0" input="0" from="3" output="0" />
+ <link to="7" input="0" from="10" output="1" />
+ <link to="7" input="1" from="8" output="0" />
+ <link to="10" input="1" from="11" output="0" />
+ <link to="8" input="0" from="11" output="0" />
+ <link to="10" input="0" from="12" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/malachite.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/malachite.jpg
new file mode 100644
index 0000000..98f79b6
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/malachite.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/polished_haematite.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/polished_haematite.bcm
new file mode 100644
index 0000000..a9e5699
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/polished_haematite.bcm
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.16230, 0.15524, 0.16953)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="1054, 111" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.02451, 0.02451, 0.02451, 1.0)" roughness="0.0" loc="-197, 192" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.0, 0.0, 0.0, 1.0)" roughness="0.0" loc="-198, 48" />
+ <node type="MIX_SHADER" fac="0.75" loc="115, 181" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.07092, 0.16557, 0.28448, 1.0)" color2="rgba(0.31448, 0.09621, 0.09221, 1.0)" loc="-454, 211" />
+ <node type="TEX_VORONOI" coloring="CELLS" scale="50.0" loc="-736, 301" />
+ <node type="MIX_SHADER" fac="0.10000" loc="814, 122" />
+ <node type="LAYER_WEIGHT" blend="0.5" loc="519, 339" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.57559, 0.57559, 0.57559, 1.0)" roughness="0.0" loc="519, -99" />
+ <node type="MIX_SHADER" fac="0.30000" loc="519, 159" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.22966, 0.22966, 0.22966, 1.0)" roughness="0.10000" loc="115, -17" />
+ <node type="RGB" custom_color="rgb(0.24929, 0.58200, 1.0)" label="Fleck Color" color="rgba(0.07092, 0.16557, 0.28448, 1.0)" loc="-1162, 583" />
+ <node type="VALUE" label="Fleck Scale" value="50.0" loc="-1156, 98" />
+ <node type="RGB" custom_color="rgb(1.0, 0.30594, 0.29320)" label="Fleck Color" color="rgba(0.31448, 0.09621, 0.09221, 1.0)" loc="-1167, 388" />
+ <node type="VALUE" label="Bloom Size" value="0.10000" loc="-738, -90" />
+ <node type="RGB" label="Bloom Color" color="rgba(0.22966, 0.22966, 0.22966, 1.0)" loc="-982, 21" />
+ <node type="VALUE" label="Fresnel" value="0.5" loc="-872, 638" />
+ <node type="VALUE" label="Roughness" value="0.01999" loc="-652, -178" />
+ <node type="VALUE" label="Fleck Amount" value="0.75" loc="-1158, 192" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="6" output="0" />
+ <link to="3" input="1" from="1" output="0" />
+ <link to="4" input="0" from="5" output="1" />
+ <link to="1" input="0" from="4" output="0" />
+ <link to="9" input="1" from="3" output="0" />
+ <link to="3" input="2" from="2" output="0" />
+ <link to="6" input="1" from="9" output="0" />
+ <link to="6" input="2" from="8" output="0" />
+ <link to="6" input="0" from="7" output="0" />
+ <link to="9" input="2" from="10" output="0" />
+ <link to="3" input="0" from="18" output="0" />
+ <link to="4" input="1" from="11" output="0" />
+ <link to="4" input="2" from="13" output="0" />
+ <link to="5" input="1" from="12" output="0" />
+ <link to="10" input="0" from="15" output="0" />
+ <link to="7" input="0" from="16" output="0" />
+ <link to="10" input="1" from="14" output="0" />
+ <link to="8" input="1" from="17" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/polished_haematite.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/polished_haematite.jpg
new file mode 100644
index 0000000..8ac973c
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/polished_haematite.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/veined_marble_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/veined_marble_osl.bcm
new file mode 100644
index 0000000..d5b7976
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/veined_marble_osl.bcm
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="191, 353" />
+ <node type="MIX_SHADER" fac="0.5" loc="-40, 356" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" vector="Vector(0.0, 0.0, 0.0)" diffuseamt="0.80000" diffusecolor="rgba(1.0, 1.0, 1.0, 1.0)" specularamt="0.20000" roughness="0.00499" specularcolor="rgba(1.0, 1.0, 1.0, 1.0)" veinfreq="1.0" veinlevels="2.0" veincolor="rgba(0.20000, 0.15000, 0.07999, 1.0)" warpfreq="1.0" warping="0.5" sharpness="8.0" loc="-1048, 442" />
+ <node type="TEX_NOISE" scale="20.0" detail="2.0" distortion="50.0" loc="-552, 240" />
+ <node type="MAPPING" translation="Vector(1.0, 0.0, 1.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(1.0, 1.0, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1157, 30" />
+ <node type="TEX_COORD" dupli="False" loc="-1406, -1" />
+ <node type="TEX_WAVE" wave="RINGS" scale="0.5" distortion="0.10000" detail="2.0" detail_scale="1.0" loc="-752, -30" />
+ <node type="TEX_MUSGRAVE" musgrave="FBM" scale="1.0" detail="2.0" dimension="2.0" lacunarity="1.0" offset="0.0" gain="1.0" loc="-531, -23" />
+ <node type="SCRIPT" mode="INTERNAL" script="1" vector="Vector(0.0, 0.0, 0.0)" diffuseamt="0.89999" diffusecolor="rgba(0.0, 0.0, 0.0, 1.0)" specularamt="0.20000" roughness="0.10000" specularcolor="rgba(0.56471, 0.56471, 0.56471, 1.0)" veinfreq="0.69998" veinlevels="1.60000" veincolor="rgba(0.65837, 0.61720, 0.0, 1.0)" warpfreq="0.60000" warping="0.69998" sharpness="6.0" loc="-255, 252" />
+ </nodes>
+ <links>
+ <link to="1" input="1" from="2" output="0" />
+ <link to="0" input="0" from="1" output="0" />
+ <link to="1" input="2" from="8" output="0" />
+ <link to="7" input="0" from="6" output="0" />
+ <link to="3" input="0" from="6" output="0" />
+ <link to="8" input="2" from="3" output="1" />
+ <link to="8" input="1" from="3" output="0" />
+ <link to="6" input="0" from="4" output="0" />
+ <link to="8" input="0" from="4" output="0" />
+ <link to="4" input="0" from="5" output="3" />
+ <link to="2" input="0" from="5" output="3" />
+ <link to="8" input="8" from="7" output="0" />
+ </links>
+ <scripts>
+ <script name="LGVeinedMarble.osl" id="0">
+<br />/*<br /> * veinedmarble.sl -- surface shader for a nice veined marble.<br /> *<br /> * DESCRIPTION:<br /> * Makes solid marble texture with strong veins. The "veincolor" parameter<br /> * controls the color of the veins. The background color is given by the<br /> * surface color (Cs).<br /> * <br /> * PARAMETERS:<br /> * Ka, Kd, Ks, roughness, specularcolor - same as plastic<br /> * veinfreq - controls fhe lowest frequency of the color veins<br /> * veinlevels - how many "levels" of vein tendrills it has<br /> * warpfreq - lowest frequency of the turbulent warping in the marble<br /> * warping - controls how much turbulent warping there will be<br /> * veincolor - the color of the veins<br /> * sharpness - controls how sharp or fuzzy the veins are (higher = sharper)<br /> *<br /> *<br /> * AUTHOR: Larry Gritz, the George Washington University<br /> * email: gritz AT seas DOT gwu DOT edu <br /> *<br /> * HISTORY:<br /> *<br /> * last modified 29 Jun 1994 by Larry Gritz<br /> * 2012-12-19 converted to blender osl shader by Shane Ambler<br /> *<br /> */<br /><br /><br />#include "stdosl.h"<br /><br /><br />shader LGVeinedMarble (<br /> point Vector = P,<br /> float DiffuseAmt = 0.8,<br /> color DiffuseColor = color(1.0),<br /> float SpecularAmt = 0.2,<br /> float Roughness = 0.005,<br /> color SpecularColor = color(1.0),<br /> float VeinFreq = 1.0,<br /> float VeinLevels = 2.0,<br /> color VeinColor = color(0.2, 0.15, 0.08),<br /> float WarpFreq = 1.0,<br /> float Warping = 0.5,<br /> float Sharpness = 8.0,<br /> output closure color BSDF = diffuse(N) )<br />{<br />#define snoise(x) (2*noise(x)-1)<br /> color Ct;<br /> point Nf;<br /> point PP, offset;<br /> float i, turb, freq, j;<br /> float turbsum;<br /><br /> PP = transform ("shader", Vector);<br /><br /> /* perturb the lookup */<br /> freq = 1;<br /> offset = 0;<br /> for (i = 0; i < 6; i += 1) {<br /> offset += 2 * Warping * ( noise (WarpFreq * freq * PP) - 0.5) / freq;<br /> freq *= 2;<br /> }<br /> PP += offset;<br /><br /> /* Now calculate the veining function for the lookup area */<br /> turbsum = 0; freq = 1;<br /> PP *= VeinFreq;<br /> for (i = 0; i < VeinLevels; i += 1) {<br /> turb = abs (snoise (PP));<br /> turb = pow (smoothstep (0.8, 1, 1 - turb), Sharpness) / freq;<br /> turbsum += (1-turbsum) * turb;<br /> freq *= 3;<br /> PP *= 3;<br /> }<br /><br /> Ct = mix (DiffuseColor, VeinColor, turbsum);<br /><br /> Nf = normalize(N);<br /> BSDF = Ct * DiffuseAmt * diffuse(Nf);<br /> BSDF += SpecularColor * SpecularAmt * microfacet_beckmann(Nf,Roughness);<br />}<br /><br /><br />
+ </script>
+ <script name="LGVeinedMarble.osl.002" id="1">
+<br />/*<br /> * veinedmarble.sl -- surface shader for a nice veined marble.<br /> *<br /> * DESCRIPTION:<br /> * Makes solid marble texture with strong veins. The "veincolor" parameter<br /> * controls the color of the veins. The background color is given by the<br /> * surface color (Cs).<br /> * <br /> * PARAMETERS:<br /> * Ka, Kd, Ks, roughness, specularcolor - same as plastic<br /> * veinfreq - controls fhe lowest frequency of the color veins<br /> * veinlevels - how many "levels" of vein tendrills it has<br /> * warpfreq - lowest frequency of the turbulent warping in the marble<br /> * warping - controls how much turbulent warping there will be<br /> * veincolor - the color of the veins<br /> * sharpness - controls how sharp or fuzzy the veins are (higher = sharper)<br /> *<br /> *<br /> * AUTHOR: Larry Gritz, the George Washington University<br /> * email: gritz AT seas DOT gwu DOT edu <br /> *<br /> * HISTORY:<br /> *<br /> * last modified 29 Jun 1994 by Larry Gritz<br /> * 2012-12-19 converted to blender osl shader by Shane Ambler<br /> *<br /> */<br /><br /><br />#include "stdosl.h"<br /><br /><br />shader LGVeinedMarble (<br /> point Vector = P,<br /> float DiffuseAmt = 0.8,<br /> color DiffuseColor = color(1.0),<br /> float SpecularAmt = 0.2,<br /> float Roughness = 0.005,<br /> color SpecularColor = color(1.0),<br /> float VeinFreq = 1.0,<br /> float VeinLevels = 2.0,<br /> color VeinColor = color(0.2, 0.15, 0.08),<br /> float WarpFreq = 1.0,<br /> float Warping = 0.5,<br /> float Sharpness = 8.0,<br /> output closure color BSDF = diffuse(N) )<br />{<br />#define snoise(x) (2*noise(x)-1)<br /> color Ct;<br /> point Nf;<br /> point PP, offset;<br /> float i, turb, freq, j;<br /> float turbsum;<br /><br /> PP = transform ("shader", Vector);<br /><br /> /* perturb the lookup */<br /> freq = 1;<br /> offset = 0;<br /> for (i = 0; i < 6; i += 1) {<br /> offset += 2 * Warping * ( noise (WarpFreq * freq * PP) - 0.5) / freq;<br /> freq *= 2;<br /> }<br /> PP += offset;<br /><br /> /* Now calculate the veining function for the lookup area */<br /> turbsum = 0; freq = 1;<br /> PP *= VeinFreq;<br /> for (i = 0; i < VeinLevels; i += 1) {<br /> turb = abs (snoise (PP));<br /> turb = pow (smoothstep (0.8, 1, 1 - turb), Sharpness) / freq;<br /> turbsum += (1-turbsum) * turb;<br /> freq *= 3;<br /> PP *= 3;<br /> }<br /><br /> Ct = mix (DiffuseColor, VeinColor, turbsum);<br /><br /> Nf = normalize(N);<br /> BSDF = Ct * DiffuseAmt * diffuse(Nf);<br /> BSDF += SpecularColor * SpecularAmt * microfacet_beckmann(Nf,Roughness);<br />}<br /><br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/veined_marble_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/veined_marble_osl.jpg
new file mode 100644
index 0000000..2bbf03b
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/stones/veined_marble_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber.bcm
new file mode 100644
index 0000000..53e8e0d
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber.bcm
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.19176, 0.19176, 0.19176)" sample_lamp="True">
+ <nodes>
+ <node type="TEX_WAVE" wave="BANDS" scale="80.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-482, 181" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-108, 105" />
+ <node type="TEX_COORD" loc="-1132, -8" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(3.0, 1.5, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-711, 160" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 1.57079)" scale="Vector(1.0, 2.0, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-747, -45" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(4.0, 1.0, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-751, -228" />
+ <node type="TEX_WAVE" wave="BANDS" scale="30.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-462, -29" />
+ <node type="BSDF_GLOSSY" distribution="GGX" color="rgba(0.69505, 0.69505, 0.69505, 1.0)" roughness="0.20000" loc="-101, 252" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.04176, 0.04176, 0.04176, 1.0)" color2="rgba(0.00326, 0.00326, 0.00326, 1.0)" loc="-244, 330" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="-103, 351" />
+ <node type="FRESNEL" ior="1.45000" loc="-101, 437" />
+ <node type="MIX_SHADER" fac="0.5" loc="101, 382" />
+ <node type="ADD_SHADER" loc="291, 346" />
+ <node type="OUTPUT_MATERIAL" loc="514, 280" />
+ <node type="BSDF_VELVET" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" sigma="0.20000" loc="95, 256" />
+ <node type="LAYER_WEIGHT" blend="0.5" loc="-426, 298" />
+ <node type="TEX_WAVE" wave="BANDS" scale="80.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-531, -248" />
+ <node type="TEX_CHECKER" color1="rgba(0.80000, 0.80000, 0.80000, 1.0)" color2="rgba(0.20000, 0.20000, 0.20000, 1.0)" scale="100.0" loc="289, 148" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-3, -147" />
+ <node type="TEX_WAVE" wave="BANDS" scale="30.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-264, -66" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Checker Scale" value="100.0" loc="-1003, 385" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.5, 0.5)" label="Large Scale" value="25.0" loc="-1080, 295" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.80000, 0.80000)" label="Small Scale" value="200.0" loc="-1090, 198" />
+ </nodes>
+ <links>
+ <link to="11" input="1" from="9" output="0" />
+ <link to="8" input="0" from="15" output="1" />
+ <link to="9" input="0" from="8" output="0" />
+ <link to="12" input="0" from="11" output="0" />
+ <link to="11" input="0" from="10" output="0" />
+ <link to="13" input="0" from="12" output="0" />
+ <link to="11" input="2" from="7" output="0" />
+ <link to="12" input="1" from="14" output="0" />
+ <link to="13" input="2" from="17" output="0" />
+ <link to="0" input="0" from="4" output="0" />
+ <link to="4" input="0" from="2" output="2" />
+ <link to="3" input="0" from="2" output="2" />
+ <link to="16" input="0" from="5" output="0" />
+ <link to="5" input="0" from="2" output="2" />
+ <link to="6" input="0" from="5" output="0" />
+ <link to="19" input="0" from="4" output="0" />
+ <link to="1" input="1" from="0" output="0" />
+ <link to="1" input="2" from="6" output="0" />
+ <link to="18" input="1" from="19" output="0" />
+ <link to="18" input="2" from="16" output="0" />
+ <link to="17" input="2" from="18" output="0" />
+ <link to="17" input="0" from="3" output="0" />
+ <link to="17" input="1" from="1" output="0" />
+ <link to="6" input="1" from="21" output="0" />
+ <link to="19" input="1" from="21" output="0" />
+ <link to="0" input="1" from="22" output="0" />
+ <link to="16" input="1" from="22" output="0" />
+ <link to="17" input="3" from="20" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber.jpg
new file mode 100644
index 0000000..013709e
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber_glossy.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber_glossy.bcm
new file mode 100644
index 0000000..ba15bda
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber_glossy.bcm
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.19999, 0.19999, 0.19999)" sample_lamp="True">
+ <nodes>
+ <node type="LAYER_WEIGHT" blend="0.5" loc="-356, 72" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.21049, 0.21049, 0.21049, 1.0)" color2="rgba(0.00326, 0.00326, 0.00326, 1.0)" loc="-186, 88" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="-58, 96" />
+ <node type="BSDF_VELVET" color="rgba(0.53048, 0.53048, 0.53048, 1.0)" sigma="0.10000" loc="-65, 0" />
+ <node type="MIX_SHADER" fac="0.5" loc="113, 161" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.15031, 0.15031, 0.15031, 1.0)" roughness="0.05000" loc="117, 26" />
+ <node type="MIX_SHADER" fac="0.5" loc="293, 86" />
+ <node type="OUTPUT_MATERIAL" loc="476, 82" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(3.0, 1.5, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1471, 150" />
+ <node type="TEX_WAVE" wave="BANDS" scale="80.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-1242, 171" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-868, 95" />
+ <node type="TEX_COORD" loc="-1892, -18" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 1.57079)" scale="Vector(1.0, 2.0, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1507, -55" />
+ <node type="MAPPING" hide="True" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(4.0, 1.0, 1.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1511, -238" />
+ <node type="TEX_WAVE" wave="BANDS" scale="30.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-1222, -39" />
+ <node type="TEX_WAVE" wave="BANDS" scale="80.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-1291, -258" />
+ <node type="TEX_WAVE" wave="BANDS" scale="30.0" distortion="0.0" detail="2.0" detail_scale="1.0" loc="-1024, -76" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Checker Scale" value="100.0" loc="-1763, 375" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.5, 0.5)" label="Large Scale" value="25.0" loc="-1840, 285" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.80000, 0.80000)" label="Small Scale" value="200.0" loc="-1850, 188" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-816, -98" />
+ <node type="TEX_CHECKER" color1="rgba(0.80000, 0.80000, 0.80000, 1.0)" color2="rgba(0.20000, 0.20000, 0.20000, 1.0)" scale="100.0" loc="-577, 152" />
+ </nodes>
+ <links>
+ <link to="1" input="0" from="0" output="1" />
+ <link to="2" input="0" from="1" output="0" />
+ <link to="4" input="1" from="2" output="0" />
+ <link to="6" input="1" from="4" output="0" />
+ <link to="7" input="0" from="6" output="0" />
+ <link to="6" input="2" from="5" output="0" />
+ <link to="4" input="2" from="3" output="0" />
+ <link to="9" input="0" from="12" output="0" />
+ <link to="12" input="0" from="11" output="2" />
+ <link to="8" input="0" from="11" output="2" />
+ <link to="15" input="0" from="13" output="0" />
+ <link to="13" input="0" from="11" output="2" />
+ <link to="14" input="0" from="13" output="0" />
+ <link to="16" input="0" from="12" output="0" />
+ <link to="10" input="1" from="9" output="0" />
+ <link to="10" input="2" from="14" output="0" />
+ <link to="20" input="1" from="16" output="0" />
+ <link to="20" input="2" from="15" output="0" />
+ <link to="21" input="2" from="20" output="0" />
+ <link to="21" input="0" from="8" output="0" />
+ <link to="21" input="1" from="10" output="0" />
+ <link to="14" input="1" from="18" output="0" />
+ <link to="16" input="1" from="18" output="0" />
+ <link to="9" input="1" from="19" output="0" />
+ <link to="15" input="1" from="19" output="0" />
+ <link to="21" input="3" from="17" output="0" />
+ <link to="0" input="0" from="21" output="0" />
+ <link to="4" input="0" from="21" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber_glossy.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber_glossy.jpg
new file mode 100644
index 0000000..2d2d243
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/carbon_fiber_glossy.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/polystyrene_foam.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/polystyrene_foam.bcm
new file mode 100644
index 0000000..94a6f79
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/polystyrene_foam.bcm
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.94999, 0.97200, 1.0)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="717, 99" />
+ <node type="FRESNEL" ior="1.15999" loc="-90, 264" />
+ <node type="MIX_SHADER" fac="0.0" loc="-93, 175" />
+ <node type="BSDF_TRANSLUCENT" color="rgba(0.85499, 0.87512, 0.89999, 1.0)" loc="-332, 92" />
+ <node type="MATH" hide="True" operation="MULTIPLY" use_clamp="False" value1="16.0" value2="0.03999" loc="543, -7" />
+ <node type="TEX_VORONOI" coloring="INTENSITY" scale="20.0" loc="-329, -135" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.85499, 0.87512, 0.89999, 1.0)" roughness="0.0" loc="-333, 198" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.85499, 0.87512, 0.89999, 1.0)" roughness="0.77999" loc="-90, 47" />
+ <node type="RGB" custom_color="rgb(0.89999, 0.89999, 0.89999)" label="Color" color="rgba(0.85500, 0.87512, 0.89999, 1.0)" loc="-935, 174" />
+ <node type="TEX_NOISE" scale="20.0" detail="0.0" distortion="0.0" loc="-714, 73" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="20.0" loc="-899, -71" />
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="0.20000" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.85000, 0.85000, 0.85000, 1.0)" loc="-497, 283" />
+ <node type="MATH" hide="True" operation="DIVIDE" use_clamp="False" value1="-16.0" value2="0.03999" loc="81, -76" />
+ <node type="VALTORGB" interpolation="LINEAR" fac="0.5" stops="2" stop1="0.00909|rgba(1.0, 1.0, 1.0, 1.0)" stop2="0.24545|rgba(1.0, 1.0, 1.0, 0.60000)" loc="88, -132" />
+ <node type="MIX_SHADER" fac="0.20000" loc="399, 152" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="14" output="0" />
+ <link to="14" input="2" from="7" output="0" />
+ <link to="14" input="0" from="1" output="0" />
+ <link to="14" input="1" from="2" output="0" />
+ <link to="2" input="2" from="3" output="0" />
+ <link to="2" input="1" from="6" output="0" />
+ <link to="13" input="0" from="5" output="1" />
+ <link to="5" input="1" from="10" output="0" />
+ <link to="3" input="0" from="8" output="0" />
+ <link to="12" input="1" from="10" output="0" />
+ <link to="4" input="1" from="13" output="1" />
+ <link to="4" input="0" from="12" output="0" />
+ <link to="0" input="2" from="4" output="0" />
+ <link to="9" input="1" from="10" output="0" />
+ <link to="7" input="0" from="8" output="0" />
+ <link to="11" input="1" from="8" output="0" />
+ <link to="6" input="0" from="11" output="0" />
+ <link to="11" input="0" from="9" output="1" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/polystyrene_foam.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/polystyrene_foam.jpg
new file mode 100644
index 0000000..45b1d1e
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/polystyrene_foam.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/rubber.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/rubber.bcm
new file mode 100644
index 0000000..1c08cfa
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/rubber.bcm
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.02120, 0.02120, 0.02120)" sample_lamp="True">
+ <nodes>
+ <node type="BSDF_TRANSLUCENT" color="rgba(1.0, 1.0, 1.0, 1.0)" loc="-178, 225" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.06305, 0.06305, 0.06305, 1.0)" roughness="0.0" loc="-186, 341" />
+ <node type="RGB" color="rgba(0.01164, 0.01164, 0.01164, 1.0)" loc="-551, 376" />
+ <node type="OUTPUT_MATERIAL" loc="300, 300" />
+ <node type="ADD_SHADER" loc="43, 316" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.20000" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(1.0, 1.0, 1.0, 1.0)" loc="-354, 254" />
+ </nodes>
+ <links>
+ <link to="4" input="0" from="1" output="0" />
+ <link to="4" input="1" from="0" output="0" />
+ <link to="1" input="0" from="2" output="0" />
+ <link to="5" input="1" from="2" output="0" />
+ <link to="3" input="0" from="4" output="0" />
+ <link to="0" input="0" from="5" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/rubber.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/rubber.jpg
new file mode 100644
index 0000000..737661e
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/synthetic/rubber.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/denim.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/denim.bcm
new file mode 100644
index 0000000..d912f5f
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/denim.bcm
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.27171, 0.51361, 0.98764)" sample_lamp="True">
+ <nodes>
+ <node type="RGB" custom_color="rgb(0.66071, 0.73312, 1.0)" label="Denim Color" color="rgba(0.03543, 0.15026, 0.37318, 1.0)" loc="-732, 193" />
+ <node type="TEX_COORD" hide="True" loc="-528, 124" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.30000, 0.30000)" label="Denim Scale" value="40.0" loc="-710, -60" />
+ <node type="TEX_WAVE" hide="True" wave="BANDS" scale="100.0" distortion="0.0" detail="0.0" detail_scale="1.0" loc="-129, -52" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="447, 60" />
+ <node type="OUTPUT_MATERIAL" loc="738, 0" />
+ <node type="BRIGHTCONTRAST" hide="True" color="rgba(1.0, 1.0, 1.0, 1.0)" bright="0.40000" contrast="-0.40000" loc="-202, 146" />
+ <node type="TEX_NOISE" hide="True" scale="100.0" detail="2.0" distortion="0.0" loc="-246, 90" />
+ <node type="MIX_RGB" hide="True" blend_type="MIX" use_clamp="False" fac="0.80000" color1="rgba(0.82981, 0.86596, 1.0, 1.0)" color2="rgba(0.06378, 0.15115, 0.47318, 1.0)" loc="36, 135" />
+ <node type="MIX_RGB" hide="True" blend_type="MIX" use_clamp="False" fac="0.80000" color1="rgba(0.52075, 0.62256, 1.0, 1.0)" color2="rgba(0.06378, 0.15115, 0.47318, 1.0)" loc="259, 92" />
+ <node type="MATH" hide="True" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="2.0" loc="-398, 18" />
+ </nodes>
+ <links>
+ <link to="3" input="0" from="1" output="2" />
+ <link to="5" input="0" from="4" output="0" />
+ <link to="7" input="0" from="1" output="2" />
+ <link to="8" input="2" from="0" output="0" />
+ <link to="6" input="0" from="0" output="0" />
+ <link to="10" input="0" from="2" output="0" />
+ <link to="3" input="1" from="2" output="0" />
+ <link to="7" input="1" from="10" output="0" />
+ <link to="4" input="0" from="9" output="0" />
+ <link to="5" input="2" from="3" output="1" />
+ <link to="9" input="2" from="8" output="0" />
+ <link to="8" input="1" from="6" output="0" />
+ <link to="9" input="1" from="0" output="0" />
+ <link to="9" input="0" from="7" output="1" />
+ <link to="8" input="0" from="3" output="1" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/denim.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/denim.jpg
new file mode 100644
index 0000000..3e1136d
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/denim.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/hessian_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/hessian_osl.bcm
new file mode 100644
index 0000000..56b2d6c
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/hessian_osl.bcm
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="546, 298" />
+ <node type="MIX_SHADER" fac="0.20000" loc="326, 327" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="122, 305" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="127, 154" />
+ <node type="TEX_MAGIC" depth="3" scale="10.0" distortion="1.0" loc="-649, -209" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" warpcolor="rgba(0.80000, 0.0, 0.0, 1.0)" weftcolor="rgba(0.0, 0.80000, 0.0, 1.0)" skip="3" underrun="2" overrun="2" warpwidth="0.89999" weftwidth="0.59999" coordinates="Vector(0.0, 0.0, 0.0)" loc="-106, 239" />
+ <node type="VALTORGB" interpolation="LINEAR" fac="0.5" stops="3" stop1="0.0|rgba(0.45888, 0.27226, 0.26589, 1.0)" stop2="0.5|rgba(0.5, 0.22469, 0.15275, 1.0)" stop3="1.0|rgba(1.0, 1.0, 1.0, 1.0)" loc="-418, -82" />
+ <node type="TEX_MUSGRAVE" musgrave="FBM" scale="1.0" detail="2.0" dimension="2.0" lacunarity="1.0" offset="0.0" gain="1.0" loc="-1061, -50" />
+ <node type="VALTORGB" interpolation="LINEAR" fac="0.5" stops="3" stop1="0.0|rgba(0.69454, 0.56581, 0.30919, 1.0)" stop2="0.5|rgba(0.5, 0.41093, 0.17475, 1.0)" stop3="1.0|rgba(1.0, 1.0, 1.0, 1.0)" loc="-850, -3" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(50.0, 50.0, 50.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-591, 277" />
+ <node type="TEX_COORD" dupli="False" loc="-1268, 50" />
+ </nodes>
+ <links>
+ <link to="1" input="1" from="2" output="0" />
+ <link to="0" input="0" from="1" output="0" />
+ <link to="0" input="2" from="5" output="2" />
+ <link to="2" input="0" from="5" output="0" />
+ <link to="3" input="0" from="8" output="0" />
+ <link to="3" input="2" from="5" output="1" />
+ <link to="1" input="2" from="3" output="0" />
+ <link to="6" input="0" from="4" output="1" />
+ <link to="8" input="0" from="7" output="1" />
+ <link to="5" input="1" from="8" output="0" />
+ <link to="5" input="7" from="9" output="0" />
+ <link to="5" input="0" from="6" output="0" />
+ <link to="9" input="0" from="10" output="2" />
+ <link to="7" input="0" from="10" output="2" />
+ </links>
+ <scripts>
+ <script name="fabric.osl.000" id="0">
+<br /><br /><br /><br />// greatest common divisor<br />int gcd(int A, int B){<br /> int a=A, b=B;<br /> if (a == 0) { return b; }<br /> while (b != 0) {<br /> if (a > b) {<br /> a = a - b;<br /> } else {<br /> b = b - a;<br /> }<br /> }<br /> return a;<br />}<br /><br />// smallest common multiple (assumes a, b > 0 )<br />int scm(int a, int b){ return a*b/gcd(a,b); }<br /><br />shader weave(<br /> color WarpColor = color(0.8,0,0),<br /> color WeftColor = color(0,0.8,0),<br /> int skip = 1,<br /> int underrun = 1,<br /> int overrun = 1,<br /> float WarpWidth = 0.8,<br /> float WeftWidth = 0.8,<br /> vector Coordinates = 0,<br /> output color Color = 0,<br /> output int Index = 0,<br /> output float Dist = 0<br />)<br />{<br /> int ny = underrun + overrun;<br /> int nx = scm(skip,ny);<br /> <br /> float x = mod(Coordinates[0],1.0);<br /> float y = mod(Coordinates[1],1.0);<br /> <br /> int ix = int(floor(x*nx));<br /> int iy = int(floor(y*ny));<br /><br /> float cx = mod(x*nx,1.0);<br /> float cy = mod(y*ny,1.0);<br /> <br /> int top;<br /> top = ((iy+skip*ix)%ny) < overrun;<br /><br /> float lx = (1-WarpWidth)/2;<br /> float hx = 1-lx;<br /> float ly = (1-WeftWidth)/2;<br /> float hy = 1-lx;<br /><br /> if (top) {<br /> if ( cx > lx && cx < hx ){<br /> Index = 1;<br /> Color = WarpColor;<br /> Dist = abs(0.5-cx);<br /> } else if (cy > ly && cy < hy ){<br /> Index = 2;<br /> Color = WeftColor;<br /> Dist = abs(0.5-cy);<br /> }<br /> } else {<br /> if (cy > ly && cy < hy ){<br /> Index = 2;<br /> Color = WeftColor;<br /> Dist = abs(0.5-cy);<br /> } else if ( cx > lx && cx < hx ){<br /> Index = 1;<br /> Color = WarpColor;<br /> Dist = abs(0.5-cx);<br /> }<br /> } <br />}<br /><br /> <br /> <br /> <br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/hessian_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/hessian_osl.jpg
new file mode 100644
index 0000000..ff904f9
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/hessian_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/velvet_edged.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/velvet_edged.bcm
new file mode 100644
index 0000000..00c1064
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/velvet_edged.bcm
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.07842, 0.72156)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="242, 136" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.5" loc="-253, 254" />
+ <node type="LAYER_WEIGHT" blend="0.80000" loc="-448, 227" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.01166, 0.0, 0.80000, 1.0)" roughness="0.0" loc="-444, 17" />
+ <node type="MIX_SHADER" fac="0.5" loc="-20, 136" />
+ <node type="BSDF_VELVET" color="rgba(0.80000, 0.07875, 0.71977, 1.0)" sigma="1.0" loc="-475, 114" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="4" output="0" />
+ <link to="4" input="0" from="1" output="0" />
+ <link to="1" input="0" from="2" output="0" />
+ <link to="4" input="1" from="5" output="0" />
+ <link to="4" input="2" from="3" output="0" />
+ <link to="1" input="1" from="2" output="1" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/velvet_edged.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/velvet_edged.jpg
new file mode 100644
index 0000000..b3d5cc0
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/velvet_edged.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_osl.bcm
new file mode 100644
index 0000000..44f467e
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_osl.bcm
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_RGB" blend_type="SCREEN" use_clamp="False" fac="0.15000" color1="rgba(0.29999, 0.11030, 0.09969, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-245, 168" />
+ <node type="MIX_RGB" blend_type="SCREEN" use_clamp="False" fac="0.15000" color1="rgba(0.5, 0.39131, 0.19054, 1.0)" color2="rgba(0.5, 0.5, 0.5, 1.0)" loc="-244, 364" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 0.0)" scale="Vector(50.0, 50.0, 50.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-541, 439" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.80000, 0.80000, 0.80000, 1.0)" roughness="0.0" loc="232, 423" />
+ <node type="OUTPUT_MATERIAL" loc="843, 297" />
+ <node type="MIX_SHADER" fac="0.5" loc="634, 332" />
+ <node type="MIX_SHADER" fac="0.15999" loc="424, 408" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.80000, 0.61282, 0.55566, 1.0)" roughness="0.20000" loc="396, 264" />
+ <node type="MATH" operation="POWER" use_clamp="False" value1="0.5" value2="0.5" loc="475, 107" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="0.5" value2="0.5" loc="311, 102" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="650, 142" />
+ <node type="TEX_COORD" dupli="False" loc="-764, 427" />
+ <node type="TEX_NOISE" scale="545.0" detail="2.0" distortion="5.0" loc="-477, 122" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" warpcolor="rgba(0.80000, 0.0, 0.0, 1.0)" weftcolor="rgba(0.0, 0.80000, 0.0, 1.0)" skip="1" underrun="2" overrun="1" warpwidth="0.80000" weftwidth="0.79999" coordinates="Vector(0.0, 0.0, 0.0)" loc="-37, 410" />
+ </nodes>
+ <links>
+ <link to="2" input="0" from="11" output="2" />
+ <link to="0" input="2" from="12" output="1" />
+ <link to="1" input="2" from="12" output="1" />
+ <link to="13" input="1" from="0" output="0" />
+ <link to="13" input="0" from="1" output="0" />
+ <link to="13" input="7" from="2" output="0" />
+ <link to="4" input="0" from="5" output="0" />
+ <link to="5" input="1" from="6" output="0" />
+ <link to="6" input="1" from="3" output="0" />
+ <link to="3" input="0" from="13" output="0" />
+ <link to="5" input="2" from="7" output="0" />
+ <link to="4" input="2" from="10" output="0" />
+ <link to="10" input="0" from="8" output="0" />
+ <link to="8" input="0" from="9" output="0" />
+ <link to="10" input="1" from="12" output="1" />
+ <link to="9" input="1" from="13" output="2" />
+ </links>
+ <scripts>
+ <script name="MAweave.osl" id="0">
+/*<br /> weave shader by Michel J. Anders (c)2012<br /> license: cc-by-sa<br /> http://blenderthings.blogspot.com.au/2012/12/a-fabric-osl-shader-for-blender-cycles.html<br />*/<br /><br />#include "stdosl.h"<br /><br />// greatest common divisor<br />int gcd(int A, int B){<br /> int a=A, b=B;<br /> if (a == 0) { return b; }<br /> while (b != 0) {<br /> if (a > b) {<br /> a = a - b;<br /> } else {<br /> b = b - a;<br /> }<br /> }<br /> return a;<br />}<br /><br />// smallest common multiple (assumes a, b > 0 )<br />int scm(int a, int b){ return a*b/gcd(a,b); }<br /><br />shader MAweave(<br /> color WarpColor = color(0.8,0,0),<br /> color WeftColor = color(0,0.8,0),<br /> int skip = 1,<br /> int underrun = 1,<br /> int overrun = 1,<br /> float WarpWidth = 0.8,<br /> float WeftWidth = 0.8,<br /> vector Coordinates = 0,<br /> output color Color = 0,<br /> output int Index = 0,<br /> output float Dist = 0)<br />{<br /> int ny = underrun + overrun;<br /> int nx = scm(skip,ny);<br /> <br /> float x = mod(Coordinates[0],1.0);<br /> float y = mod(Coordinates[1],1.0);<br /> <br /> int ix = int(floor(x*nx));<br /> int iy = int(floor(y*ny));<br /> <br /> float cx = mod(x*nx,1.0);<br /> float cy = mod(y*ny,1.0);<br /> <br /> int top;<br /> top = ((iy+skip*ix)%ny) < overrun;<br /> <br /> float lx = (1-WarpWidth)/2;<br /> float hx = 1-lx;<br /> float ly = (1-WeftWidth)/2;<br /> float hy = 1-lx;<br /> <br /> if (top) {<br /> if ( cx > lx && cx < hx ){<br /> Index = 1;<br /> Color = WarpColor;<br /> Dist = abs(0.5-cx);<br /> } else if (cy > ly && cy < hy ){<br /> Index = 2;<br /> Color = WeftColor;<br /> Dist = abs(0.5-cy);<br /> }<br /> } else {<br /> if (cy > ly && cy < hy ){<br /> Index = 2;<br /> Color = WeftColor;<br /> Dist = abs(0.5-cy); <br /> } else if ( cx > lx && cx < hx ){<br /> Index = 1;<br /> Color = WarpColor;<br /> Dist = abs(0.5-cx); <br /> }<br /> }<br />}<br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_osl.jpg
new file mode 100644
index 0000000..2e2c27e
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_test.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_test.bcm
new file mode 100644
index 0000000..81930e1
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_test.bcm
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_SHADER" fac="0.02999" loc="1649, 550" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(0.79909, 0.67243, 0.60382, 1.0)" roughness="0.40000" loc="1451, 489" />
+ <node type="MIX_SHADER" fac="0.69999" loc="1452, 608" />
+ <node type="BSDF_VELVET" color="rgba(0.79909, 0.67243, 0.60382, 1.0)" sigma="0.89999" loc="1243, 532" />
+ <node type="BSDF_DIFFUSE" color="rgba(0.79909, 0.67058, 0.60566, 1.0)" roughness="0.69998" loc="1239, 630" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.79909, 0.51714, 0.32036, 1.0)" color2="rgba(0.0, 0.0, 0.0, 1.0)" loc="1011, 555" />
+ <node type="MATH" operation="MINIMUM" use_clamp="False" value1="0.5" value2="0.5" loc="434, 428" />
+ <node type="VALTORGB" interpolation="EASE" fac="0.5" stops="12" stop1="0.0|rgba(1.0, 1.0, 1.0, 0.0)" stop2="0.11362|rgba(1.0, 1.0, 1.0, 0.50182)" stop3="0.18181|rgba(1.0, 1.0, 1.0, 0.00234)" stop4="0.21363|rgba(1.0, 1.0, 1.0, 0.02219)" stop5="0.27272|rgba(1.0, 1.0, 1.0, 0.0)" stop6="0.34545|rgba(1.0, 1.0, 1.0, 0.58626)" stop7="0.41817|rgba(1.0, 1.0, 1.0, 0.02921)" stop8="0.51362|rgba(1.0, 1.0, 1.0, 0.0)" stop9="0.64090|rgba(1.0, 1.0, 1.0, 0.03826)" stop10="0.74545|rgba(1.0, 1.0, 1.0, 1.0)" stop11="0.85453|rgba(1.0, 1.0, 1.0, 0.02249)" stop12="1.0|rgba(1.0, 1.0, 1.0, 0.0)" loc="-140, 400" />
+ <node type="VALTORGB" interpolation="EASE" fac="0.5" stops="10" stop1="0.0|rgba(1.0, 1.0, 1.0, 0.0)" stop2="0.17272|rgba(1.0, 1.0, 1.0, 0.73825)" stop3="0.29998|rgba(1.0, 1.0, 1.0, 0.0)" stop4="0.34999|rgba(1.0, 1.0, 1.0, 0.02642)" stop5="0.43180|rgba(1.0, 1.0, 1.0, 0.05547)" stop6="0.57271|rgba(1.0, 1.0, 1.0, 0.72980)" stop7="0.72272|rgba(1.0, 1.0, 1.0, 0.03361)" stop8="0.81818|rgba(1.0, 1.0, 1.0, 0.0)" stop9="0.91817|rgba(1.0, 1.0, 1.0, 0.32451)" stop10="1.0|rgba(1.0, 1.0, 1.0, 0.0)" loc="-140, 196" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="-2.0" loc="150, 222" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="291, 322" />
+ <node type="MATH" operation="DIVIDE" use_clamp="False" value1="0.5" value2="3.0" loc="838, 562" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="2.0" loc="645, 522" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.20000" loc="1049, 184" />
+ <node type="OUTPUT_MATERIAL" loc="1966, 237" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="0.5" value2="0.5" loc="-236, 531" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="30.09999" loc="-913, 464" />
+ <node type="TEX_NOISE" scale="5.0" detail="0.99998" distortion="0.0" loc="-1531, 185" />
+ <node type="TEX_COORD" loc="-1720, 315" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="30.09999" value2="10.0" loc="-1712, 109" />
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="0.99000" color1="rgba(0.5, 0.5, 0.5, 1.0)" color2="rgba(0.0, 0.0, 0.0, 1.0)" loc="-1350, 220" />
+ <node type="SEPRGB" image="rgba(0.80000, 0.80000, 0.80000, 1.0)" loc="-1068, 269" />
+ <node type="VECT_MATH" operation="ADD" vector1="Vector(0.5, 0.5, 0.5)" vector2="Vector(0.5, 0.5, 0.5)" loc="-1212, 292" />
+ <node type="MATH" operation="ROUND" use_clamp="False" value1="0.5" value2="0.0" loc="-641, 604" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="-787, 602" />
+ <node type="MATH" operation="SUBTRACT" use_clamp="False" value1="0.5" value2="0.5" loc="-279, 176" />
+ <node type="MATH" operation="ROUND" use_clamp="False" value1="0.5" value2="0.0" loc="-433, 323" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="-600, 341" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="30.09999" loc="-753, 159" />
+ <node type="MATH" operation="ADD" use_clamp="False" value1="0.5" value2="0.5" loc="-902, 159" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="10.0" loc="-1945, 425" />
+ </nodes>
+ <links>
+ <link to="14" input="0" from="0" output="0" />
+ <link to="14" input="2" from="13" output="0" />
+ <link to="9" input="0" from="8" output="1" />
+ <link to="2" input="2" from="3" output="0" />
+ <link to="2" input="1" from="4" output="0" />
+ <link to="10" input="0" from="7" output="1" />
+ <link to="10" input="1" from="9" output="0" />
+ <link to="13" input="0" from="6" output="0" />
+ <link to="6" input="1" from="10" output="0" />
+ <link to="6" input="0" from="7" output="1" />
+ <link to="0" input="2" from="1" output="0" />
+ <link to="17" input="0" from="18" output="2" />
+ <link to="20" input="1" from="17" output="0" />
+ <link to="22" input="0" from="18" output="2" />
+ <link to="22" input="1" from="20" output="0" />
+ <link to="21" input="0" from="22" output="0" />
+ <link to="17" input="1" from="19" output="0" />
+ <link to="0" input="1" from="2" output="0" />
+ <link to="7" input="0" from="15" output="0" />
+ <link to="8" input="0" from="25" output="0" />
+ <link to="29" input="1" from="21" output="1" />
+ <link to="4" input="0" from="5" output="0" />
+ <link to="3" input="0" from="5" output="0" />
+ <link to="1" input="0" from="5" output="0" />
+ <link to="11" input="0" from="12" output="0" />
+ <link to="5" input="0" from="11" output="0" />
+ <link to="12" input="0" from="6" output="0" />
+ <link to="16" input="0" from="21" output="0" />
+ <link to="15" input="0" from="23" output="0" />
+ <link to="15" input="1" from="16" output="0" />
+ <link to="23" input="0" from="24" output="0" />
+ <link to="24" input="0" from="16" output="0" />
+ <link to="28" input="0" from="29" output="0" />
+ <link to="25" input="0" from="26" output="0" />
+ <link to="25" input="1" from="28" output="0" />
+ <link to="26" input="0" from="27" output="0" />
+ <link to="27" input="0" from="28" output="0" />
+ <link to="19" input="0" from="30" output="0" />
+ <link to="16" input="1" from="30" output="0" />
+ <link to="29" input="0" from="21" output="0" />
+ </links>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_test.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_test.jpg
new file mode 100644
index 0000000..bbda283
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/textiles/weave_test.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/parquete_tile_osl.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/parquete_tile_osl.bcm
new file mode 100644
index 0000000..2a4ebdc
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/parquete_tile_osl.bcm
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.80000, 0.80000, 0.80000)" sample_lamp="True">
+ <nodes>
+ <node type="OUTPUT_MATERIAL" loc="-75, 344" />
+ <node type="TEX_COORD" dupli="False" loc="-524, 318" />
+ <node type="SCRIPT" mode="INTERNAL" script="0" vector="Vector(0.0, 0.0, 0.0)" diffuseamt="0.75" specularamt="0.25" roughness="0.125" specularcolor="rgba(1.0, 1.0, 1.0, 1.0)" ringscale="25.0" grainscale="55.0" grainy="1.0" wavy="0.07999" texturescale="15.0" lightwood="rgba(0.56999, 0.29199, 0.125, 1.0)" darkwood="rgba(0.27500, 0.15000, 0.05999, 1.0)" groovecolor="rgba(0.05000, 0.03999, 0.01499, 1.0)" plankspertile="4" plankwidth="0.20000" plankvary="0.60000" groovewidth="0.10000" loc="-333, 353" />
+ </nodes>
+ <links>
+ <link to="0" input="0" from="2" output="0" />
+ <link to="2" input="0" from="1" output="2" />
+ </links>
+ <scripts>
+ <script name="DWParqueteTile.osl" id="0">
+/*<br /> * DWParquetTile.sl -- yet another surface shader for wood<br /> *-was:<br /> * parquet_plank.sl -- another surface shader for wood.<br /> *<br /> * DESCRIPTION:<br /> * Makes texture of wooden planks in s-t space. This wood looks rather<br /> * like oak plank parquet floor tiles. The actual wood and plank pattern<br /> * is based on my "planks" shader. This shader works best if "s" and "t"<br /> * units are both the same size in world space.<br /> *<br /> * PARAMETERS:<br /> * Ka, Kd, Ks, specular, roughness - work just like the plastic shader<br /> * txtscale - overall scaling factor for the texture<br /> * plankwidth - width of each plank (in terms of s/t)<br /> * plankspertile - number of planks in each parquet tile<br /> * ringscale - scaling for the ring spacing<br /> * grainscale - scaling for the fine grain<br /> * groovewidth - width of the grooves between the planks (in terms of s/t)<br /> * lightwood, darkwood - surface colors for the wood itself<br /> * groovecolor - the color of the "grooves" between the planks<br /> * plankvary - controls how much wood color varies from plank to plank<br /> * grainy - relative graininess (0 = no fine grain)<br /> * wavy - relative wavyness of the ring pattern<br /> *<br /> * ANTIALIASING: this shader does a pretty good job of antialiasing itself,<br /> * even with low sampling densities.<br /> *<br /> * AUTHOR: written by Larry Gritz, the George Washington University<br /> * email: gritz AT seas DOT gwu DOT edu <br /> * snail: Dept. of EE & CS<br /> * 801 22nd St. NW, Rm. T-624-G<br /> * Washington, DC 20052<br /> *<br /> * HISTORY:<br /> * 10 Feb 1995 - written by Larry Gritz, based on my "plank" shader.<br /> * 10 Feb 1995 - modified by wave to change the name<br /> * 18 Dec 2012 - converted to blender osl shader by Shane Ambler<br /> *<br /> * last modified 10 Feb 1995 by wave<br /> * <br /> *<br /> * modified again by Dan Weeks <dan AT mango DOT sfasu DOT edu > on 08 Dec 1996<br /> * - made one plank per tile like the flooring in our lab<br /> * - comments appear where changes are made<br /> * - many thanks to Larry Gritz and wave for creating the original<br /> *<br /> * modified by Shane Ambler 18 Dec 2012<br /> * - convert to work as blender osl shader<br /> * - capitalise various user visible variable names<br /> * - remove Ka - no ambient interaction calculated within shader<br /> * - rename Kd to DiffuseAmt<br /> * - rename Ks to SpecularAmt<br /> * - rename txtscale to TextureScale<br /> * - change PlanksPerTile to an int<br /> */<br /><br /><br /><br />/*<br /> * changed:<br /> * - name from LGParquetPlank to DWParquetTile<br /> * - ringscale from 15 to 25<br /> * - grainscale from 60 to 55<br /> * - plankspertile from 4 to 1<br /> * - plankwidth from .05 to .2<br /> */<br /> <br />#include "stdosl.h"<br /><br />shader DWParquetTile (<br /> point Vector = P,<br /> float DiffuseAmt = 0.75 ,<br /> float SpecularAmt = 0.15,<br /> float Roughness = 0.025,<br /> color SpecularColor = color(1.0),<br /> float RingScale = 25.0,<br /> float GrainScale = 55.0,<br /> float Grainy = 1.0,<br /> float Wavy = 0.08,<br /> float TextureScale = 5.0,<br /> color LightWood = color (0.57, 0.292, 0.125),<br /> color DarkWood = color (0.275, 0.15, 0.06),<br /> color GrooveColor = color (0.05, 0.04, 0.015),<br /> int PlanksPerTile = 1,<br /> float PlankWidth = 0.2,<br /> float PlankVary = 0.6,<br /> float GrooveWidth = 0.1,<br /> output closure color BSDF = diffuse(N) )<br />{<br />#define snoise(x) (2 * noise((x)) - 1)<br />#define boxstep(a,b,x) (clamp(((x)-(a))/((b)-(a)),0,1))<br />#define MINFILTERWIDTH 1.0e-7<br /><br /> float su = Vector[0];<br /> float tv = Vector[1];<br /> float r, r2;<br /> point Nf;<br /> float whichrow, whichplank;<br /> float swidth, twidth, fwidth, ss, tt, w, h, fade, ttt;<br /> color Ct, woodcolor;<br /> float groovy;<br /> float PGWIDTH, PGHEIGHT, GWF, GHF;<br /> float tilewidth, whichtile, tmp, planklength;<br /><br /> PGWIDTH = PlankWidth+GrooveWidth;<br /> planklength = PGWIDTH * PlanksPerTile - GrooveWidth;<br /> PGHEIGHT = planklength+GrooveWidth;<br /> GWF = GrooveWidth*0.05/PGWIDTH;<br /> GHF = GrooveWidth*0.05/PGHEIGHT;<br /><br /> /* Determine how wide in s-t space one pixel projects to */<br /> swidth = (max (abs(Dx(su)*su) + abs(Dy(su)*tv), MINFILTERWIDTH) / PGWIDTH) * TextureScale;<br /> twidth = (max (abs(Dx(tv)*su) + abs(Dy(tv)*tv), MINFILTERWIDTH) / PGHEIGHT) * TextureScale;<br /> fwidth = max(swidth,twidth);<br /><br /> ss = (TextureScale * su) / PGWIDTH;<br /> whichrow = floor (ss);<br /> tt = (TextureScale * tv) / PGHEIGHT;<br /> whichplank = floor(tt);<br /> if (mod (whichrow/PlanksPerTile + whichplank, 2) >= 1) {<br /> ss = TextureScale * tv / PGWIDTH;<br /> whichrow = floor (ss);<br /> tt = TextureScale * su / PGHEIGHT;<br /> whichplank = floor(tt);<br /> tmp = swidth; swidth = twidth; twidth = tmp;<br /> } <br /> ss -= whichrow;<br /> tt -= whichplank;<br /> whichplank += 20*(whichrow+10);<br /><br /> /*<br /> * Figure out where the grooves are. The value groovy is 0 where there<br /> * are grooves, 1 where the wood grain is visible. Do some simple<br /> * antialiasing.<br /> */<br /> if (swidth >= 1)<br /> w = 1 - 2*GWF;<br /> else {<br /> w = clamp (boxstep(GWF-swidth,GWF,ss), max(1-GWF/swidth,0), 1)<br /> - clamp (boxstep(1-GWF-swidth,1-GWF,ss), 0, 2*GWF/swidth);<br /> }<br /> if (twidth >= 1)<br /> h = 1 - 2*GHF;<br /> else {<br /> h = clamp (boxstep(GHF-twidth,GHF,tt), max(1-GHF/twidth,0),1)<br /> - clamp (boxstep(1-GHF-twidth,1-GHF,tt), 0, 2*GHF/twidth);<br /> }<br /> /* This would be the non-antialiased version:<br /> * w = step (GWF,ss) - step(1-GWF,ss);<br /> * h = step (GHF,tt) - step(1-GHF,tt);<br /> */<br /> groovy = w*h;<br /><br /><br /> /*<br /> * Add the ring patterns<br /> */<br /> fade = smoothstep (1/RingScale, 8/RingScale, fwidth);<br /> if (fade < 0.999) {<br /> ttt = tt/4+whichplank/28.38 + Wavy * noise (8*ss, tt/4);<br /> r = RingScale * noise (ss-whichplank, ttt);<br /> r -= floor (r);<br /> r = 0.3 + 0.7 * smoothstep(0.2, 0.55, r) * (1 - smoothstep(0.75, 0.8, r));<br /> r = (1-fade)*r + 0.65*fade;<br /><br /> /*<br /> * Multiply the ring pattern by the fine grain<br /> */<br /> fade = smoothstep (2/GrainScale, 8/GrainScale, fwidth);<br /> if (fade < 0.999) {<br /> r2 = 1.3 - noise (ss*GrainScale, (tt*GrainScale/4));<br /> r2 = Grainy * r2*r2 + (1-Grainy);<br /> r *= (1-fade)*r2 + (0.75*fade);<br /> }<br /> else<br /> r *= 0.75;<br /> }<br /> else<br /> r = 0.4875;<br /> <br /><br /> /* Mix the light and dark wood according to the grain pattern */<br /> woodcolor = mix (LightWood, DarkWood, r);<br /><br /> /* Add plank-to-plank variation in overall color */<br /> woodcolor *= (1-PlankVary/2 + PlankVary * noise (whichplank+0.5));<br /><br /> Ct = mix (GrooveColor, woodcolor, groovy);<br /> Nf = normalize(N);<br /> BSDF = Ct * DiffuseAmt * diffuse(Nf);<br /><br /> BSDF += SpecularColor * SpecularAmt * microfacet_beckmann(Nf,Roughness);<br />}<br /><br />
+ </script>
+ </scripts>
+</material>
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/parquete_tile_osl.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/parquete_tile_osl.jpg
new file mode 100644
index 0000000..82169a5
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/parquete_tile_osl.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/polished_walnut.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/polished_walnut.bcm
new file mode 100644
index 0000000..60d5be2
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/polished_walnut.bcm
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.14084, 0.05520, 0.03290)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="1.0" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.0, 0.0, 0.0, 1.0)" loc="-131, 606" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.23573, 0.23573, 0.23573, 1.0)" loc="-266, 606" />
+ <node type="LAYER_WEIGHT" blend="0.02999" loc="7, 606" />
+ <node type="MIX_SHADER" fac="0.64398" loc="263, 447" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.75" loc="7, 447" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.13197, 0.04244, 0.02085, 1.0)" color2="rgba(0.04010, 0.01503, 0.00737, 1.0)" loc="-266, 447" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.88691, 0.84328, 1.0)" roughness="0.34999" loc="7, 298" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.00200" loc="7, 162" />
+ <node type="TEX_WAVE" wave="RINGS" scale="0.69998" distortion="700.0" detail="4.0" detail_scale="0.25" loc="-474, 672" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.25" loc="-635, 505" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.69998" loc="-771, 557" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="5.0" loc="-809, 281" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="1.0" loc="-1140, 300" />
+ <node type="TEX_COORD" loc="-1490, 554" />
+ <node type="OUTPUT_MATERIAL" loc="460, 390" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 1.74532)" scale="Vector(2.0, 0.40000, 10.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1266, 611" />
+ <node type="TEX_WAVE" wave="BANDS" scale="5.0" distortion="30.0" detail="4.42378" detail_scale="5.0" loc="-563, 348" />
+ </nodes>
+ <links>
+ <link to="5" input="0" from="16" output="1" />
+ <link to="7" input="0" from="16" output="1" />
+ <link to="16" input="0" from="15" output="0" />
+ <link to="15" input="0" from="13" output="0" />
+ <link to="3" input="2" from="6" output="0" />
+ <link to="14" input="0" from="3" output="0" />
+ <link to="3" input="1" from="4" output="0" />
+ <link to="3" input="0" from="2" output="1" />
+ <link to="14" input="2" from="7" output="0" />
+ <link to="8" input="0" from="15" output="0" />
+ <link to="1" input="0" from="8" output="1" />
+ <link to="4" input="0" from="0" output="0" />
+ <link to="0" input="2" from="5" output="0" />
+ <link to="9" input="0" from="12" output="0" />
+ <link to="8" input="4" from="9" output="0" />
+ <link to="10" input="0" from="12" output="0" />
+ <link to="8" input="1" from="10" output="0" />
+ <link to="11" input="0" from="12" output="0" />
+ <link to="16" input="4" from="11" output="0" />
+ <link to="16" input="1" from="11" output="0" />
+ <link to="0" input="1" from="1" output="0" />
+ </links>
+</material>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/polished_walnut.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/polished_walnut.jpg
new file mode 100644
index 0000000..e4bcae1
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/polished_walnut.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.bcm
new file mode 100644
index 0000000..853b7f6
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.bcm
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.59719, 0.43964, 0.25415)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.71174, 0.58495, 0.47878, 1.0)" loc="-266, 606" />
+ <node type="LAYER_WEIGHT" blend="0.00498" loc="7, 606" />
+ <node type="MIX_SHADER" fac="0.64398" loc="263, 447" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.80000" loc="7, 447" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.83196, 0.60834, 0.35504, 1.0)" color2="rgba(0.61368, 0.48484, 0.29545, 1.0)" loc="-266, 447" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.88691, 0.84328, 1.0)" roughness="0.89999" loc="7, 298" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.02999" loc="7, 162" />
+ <node type="TEX_WAVE" wave="RINGS" scale="0.69998" distortion="750.0" detail="4.0" detail_scale="0.25" loc="-474, 672" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.27000" loc="-635, 505" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.69998" loc="-771, 557" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="5.09997" loc="-809, 281" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="1.0" loc="-1140, 300" />
+ <node type="TEX_COORD" loc="-1490, 554" />
+ <node type="OUTPUT_MATERIAL" loc="460, 390" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 1.74532)" scale="Vector(2.0, 0.40000, 10.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1266, 611" />
+ <node type="TEX_WAVE" wave="BANDS" scale="5.0" distortion="30.0" detail="4.42378" detail_scale="5.0" loc="-563, 348" />
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="0.80000" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.0, 0.0, 0.0, 1.0)" loc="-131, 606" />
+ </nodes>
+ <links>
+ <link to="4" input="0" from="15" output="1" />
+ <link to="6" input="0" from="15" output="1" />
+ <link to="15" input="0" from="14" output="0" />
+ <link to="14" input="0" from="12" output="0" />
+ <link to="2" input="2" from="5" output="0" />
+ <link to="13" input="0" from="2" output="0" />
+ <link to="2" input="1" from="3" output="0" />
+ <link to="2" input="0" from="1" output="1" />
+ <link to="13" input="2" from="6" output="0" />
+ <link to="7" input="0" from="14" output="0" />
+ <link to="0" input="0" from="7" output="1" />
+ <link to="3" input="0" from="16" output="0" />
+ <link to="8" input="0" from="11" output="0" />
+ <link to="7" input="4" from="8" output="0" />
+ <link to="9" input="0" from="11" output="0" />
+ <link to="7" input="1" from="9" output="0" />
+ <link to="10" input="0" from="11" output="0" />
+ <link to="15" input="4" from="10" output="0" />
+ <link to="15" input="1" from="10" output="0" />
+ <link to="16" input="2" from="0" output="0" />
+ <link to="16" input="1" from="4" output="0" />
+ </links>
+</material>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.jpg
new file mode 100644
index 0000000..991bcf8
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.jpg differ
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_walnut.bcm b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_walnut.bcm
new file mode 100644
index 0000000..207a053
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_walnut.bcm
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<material view_color="rgb(0.06847, 0.02518, 0.01520)" sample_lamp="True">
+ <nodes>
+ <node type="MIX_RGB" blend_type="MULTIPLY" use_clamp="False" fac="1.0" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.0, 0.0, 0.0, 1.0)" loc="-131, 606" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(1.0, 1.0, 1.0, 1.0)" color2="rgba(0.23573, 0.23573, 0.23573, 1.0)" loc="-266, 606" />
+ <node type="LAYER_WEIGHT" blend="0.00999" loc="7, 606" />
+ <node type="MIX_SHADER" fac="0.64398" loc="263, 447" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 1.0, 1.0, 1.0)" roughness="0.80000" loc="7, 447" />
+ <node type="MIX_RGB" blend_type="MIX" use_clamp="False" fac="0.5" color1="rgba(0.13197, 0.04244, 0.02085, 1.0)" color2="rgba(0.04010, 0.01503, 0.00737, 1.0)" loc="-266, 447" />
+ <node type="BSDF_GLOSSY" distribution="BECKMANN" color="rgba(1.0, 0.88691, 0.84328, 1.0)" roughness="0.69998" loc="7, 298" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.02999" loc="7, 162" />
+ <node type="TEX_WAVE" wave="RINGS" scale="0.69998" distortion="700.0" detail="4.0" detail_scale="0.25" loc="-474, 672" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.25" loc="-635, 505" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="0.69998" loc="-771, 557" />
+ <node type="MATH" operation="MULTIPLY" use_clamp="False" value1="0.5" value2="5.0" loc="-809, 281" />
+ <node type="VALUE" custom_color="rgb(1.0, 0.10000, 0.10000)" label="Scale" value="1.0" loc="-1140, 300" />
+ <node type="TEX_COORD" loc="-1490, 554" />
+ <node type="OUTPUT_MATERIAL" loc="460, 390" />
+ <node type="MAPPING" translation="Vector(0.0, 0.0, 0.0)" rotation="Vector(0.0, 0.0, 1.74532)" scale="Vector(2.0, 0.40000, 10.0)" use_min="False" use_max="False" vector="Vector(0.0, 0.0, 0.0)" loc="-1266, 611" />
+ <node type="TEX_WAVE" wave="BANDS" scale="5.0" distortion="30.0" detail="4.42378" detail_scale="5.0" loc="-563, 348" />
+ </nodes>
+ <links>
+ <link to="5" input="0" from="16" output="1" />
+ <link to="7" input="0" from="16" output="1" />
+ <link to="16" input="0" from="15" output="0" />
+ <link to="15" input="0" from="13" output="0" />
+ <link to="3" input="2" from="6" output="0" />
+ <link to="14" input="0" from="3" output="0" />
+ <link to="3" input="1" from="4" output="0" />
+ <link to="3" input="0" from="2" output="1" />
+ <link to="14" input="2" from="7" output="0" />
+ <link to="8" input="0" from="15" output="0" />
+ <link to="1" input="0" from="8" output="1" />
+ <link to="4" input="0" from="0" output="0" />
+ <link to="0" input="2" from="5" output="0" />
+ <link to="9" input="0" from="12" output="0" />
+ <link to="8" input="4" from="9" output="0" />
+ <link to="10" input="0" from="12" output="0" />
+ <link to="8" input="1" from="10" output="0" />
+ <link to="11" input="0" from="12" output="0" />
+ <link to="16" input="4" from="11" output="0" />
+ <link to="16" input="1" from="11" output="0" />
+ <link to="0" input="1" from="1" output="0" />
+ </links>
+</material>
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_walnut.jpg b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_walnut.jpg
new file mode 100644
index 0000000..98c2699
Binary files /dev/null and b/release/scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_walnut.jpg differ
diff --git a/build_files/scons/config/Modules/__init__.py b/release/scripts/addons_contrib/online_mat_lib/material-library/mat_lib_preview_image.jpg
similarity index 100%
copy from build_files/scons/config/Modules/__init__.py
copy to release/scripts/addons_contrib/online_mat_lib/material-library/mat_lib_preview_image.jpg
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/my-materials/read-me.txt b/release/scripts/addons_contrib/online_mat_lib/material-library/my-materials/read-me.txt
new file mode 100644
index 0000000..33b816b
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/my-materials/read-me.txt
@@ -0,0 +1 @@
+This is the folder location for your personal saved materials.
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/peter.cassetta.info/release/cycles/revision_data.ini b/release/scripts/addons_contrib/online_mat_lib/material-library/peter.cassetta.info/release/cycles/revision_data.ini
new file mode 100644
index 0000000..cac98a4
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/peter.cassetta.info/release/cycles/revision_data.ini
@@ -0,0 +1 @@
+revision=001
diff --git a/release/scripts/addons_contrib/online_mat_lib/material-library/peter.cassetta.info/testing/cycles/revision_data.ini b/release/scripts/addons_contrib/online_mat_lib/material-library/peter.cassetta.info/testing/cycles/revision_data.ini
new file mode 100644
index 0000000..cac98a4
--- /dev/null
+++ b/release/scripts/addons_contrib/online_mat_lib/material-library/peter.cassetta.info/testing/cycles/revision_data.ini
@@ -0,0 +1 @@
+revision=001
diff --git a/release/scripts/addons_contrib/oscurart_futurism.py b/release/scripts/addons_contrib/oscurart_futurism.py
new file mode 100644
index 0000000..0b06cd8
--- /dev/null
+++ b/release/scripts/addons_contrib/oscurart_futurism.py
@@ -0,0 +1,150 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Futurism",
+ "author": "Oscurart",
+ "version": (1, 2),
+ "blender": (2, 63, 0),
+ "location": "Object > Futurism",
+ "description": "Adds a new Mesh Object",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Object/Oscurart_Futurism",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "unc=detail&aid=31911",
+ "category": "Add Mesh"}
+
+
+import bpy
+
+def object_osc_futurism (self, context,STEP, HOLD):
+ ACTOBJ=bpy.context.active_object # OBJETO ACTIVO
+ FS=bpy.context.scene.frame_start # FRAME START
+ FE=bpy.context.scene.frame_end # FRAME END
+ OBJLIST=[] # LISTA PARA OBJETOS ????
+ FC=FS # FRAME CURRENT
+ OBJNUMBER=1 # SUFIJO DE NUMERO PARA OBJETOS
+ STEPINC=0 # NUMERO PARA EVALUAR LOS PASOS
+ bpy.context.scene.frame_set(FS) # SETEO EL FRAME CURRENT
+ OBACT = bpy.context.active_object # SETEO EL OBJETO ACTIVO
+
+ ## CREO EMPTY
+ bpy.ops.object.add()
+ bpy.context.active_object.name = "FuturismContainer"
+ EMPTY = bpy.context.active_object
+
+ # SUMO PARAMETERS AL EMPTY
+ EMPTY["FUTURISM_HOLDIN"] = 0
+ EMPTY["FUTURISM_HOLDOUT"] = 0
+
+ bpy.context.scene.objects.active = OBACT # RECUPERO OBJETO ACTIVO
+
+ for OBJETO in range((FE+1)-FS):
+ if STEPINC == STEP:
+ # CREO UN MESH A PARTIR DE OBJETO
+ MESH=ACTOBJ.to_mesh(bpy.context.scene, True, 'PREVIEW')
+ # CREO OBJETO
+ OBJECT=bpy.data.objects.new(ACTOBJ.name[:3]+str(FC), MESH)
+ # CONECTO A LA ESCENA
+ bpy.context.scene.objects.link(OBJECT)
+ # SETEO FRAME CURRENT
+ bpy.context.scene.frame_set(FC)
+ # MARCO EXPRESIONES PARA VIEW
+ OBJECT.driver_add("hide")
+ OBJECT.animation_data.drivers[0].driver.variables.new()
+ OBJECT.animation_data.drivers[0].driver.variables.new()
+ OBJECT.animation_data.drivers[0].driver.variables.new()
+ OBJECT.animation_data.drivers[0].driver.expression= "False if frame >= %s+var_001 and frame <= %s+var_002 else True" % (str(FC),str(FC+HOLD))
+ OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].id_type = 'SCENE'
+ OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].id= bpy.context.scene
+ OBJECT.animation_data.drivers[0].driver.variables[0].targets[0].data_path = "current_frame"
+ OBJECT.animation_data.drivers[0].driver.variables[1].targets[0].id_type = 'OBJECT'
+ OBJECT.animation_data.drivers[0].driver.variables[1].targets[0].id= EMPTY
+ OBJECT.animation_data.drivers[0].driver.variables[1].targets[0].data_path = '["FUTURISM_HOLDIN"]'
+ OBJECT.animation_data.drivers[0].driver.variables[2].targets[0].id_type = 'OBJECT'
+ OBJECT.animation_data.drivers[0].driver.variables[2].targets[0].id= EMPTY
+ OBJECT.animation_data.drivers[0].driver.variables[2].targets[0].data_path = '["FUTURISM_HOLDOUT"]'
+
+ # MARCO EXPRESIONES PARA RENDER
+ OBJECT.driver_add("hide_render")
+ OBJECT.animation_data.drivers[1].driver.variables.new()
+ OBJECT.animation_data.drivers[1].driver.variables.new()
+ OBJECT.animation_data.drivers[1].driver.variables.new()
+ OBJECT.animation_data.drivers[1].driver.expression= "False if frame >= %s+5 and frame <= %s else True" % (str(FC),str(FC+HOLD))
+ OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].id_type = 'SCENE'
+ OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].id= bpy.context.scene
+ OBJECT.animation_data.drivers[1].driver.variables[0].targets[0].data_path = "current_frame"
+ OBJECT.animation_data.drivers[1].driver.variables[1].targets[0].id_type = 'OBJECT'
+ OBJECT.animation_data.drivers[1].driver.variables[1].targets[0].id= EMPTY
+ OBJECT.animation_data.drivers[1].driver.variables[1].targets[0].data_path = '["FUTURISM_HOLDIN"]'
+ OBJECT.animation_data.drivers[1].driver.variables[2].targets[0].id_type = 'OBJECT'
+ OBJECT.animation_data.drivers[1].driver.variables[2].targets[0].id= EMPTY
+ OBJECT.animation_data.drivers[1].driver.variables[2].targets[0].data_path = '["FUTURISM_HOLDOUT"]'
+ # RESETEO STEPINC
+ STEPINC=0
+ # COPIAMOS S R T
+ OBJECT.matrix_world=ACTOBJ.matrix_world
+ #EMPARENTO
+ OBJECT.parent=EMPTY
+ # AVANZO STEP Y FRAME
+ FC+=1
+ STEPINC+=1
+
+# CLASE PARA OPERADOR
+class Oscurart_futurism (bpy.types.Operator):
+ bl_idname = "object.duplicate_futurism"
+ bl_label = "Duplicate Futurism"
+ bl_description = "Duplicate object per frame"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ scale = bpy.props.IntProperty(name='Step',default=1, min=1, max=1000)
+
+ hold = bpy.props.IntProperty(name='Hold', default=0, min=0)
+
+ @classmethod
+ def poll(cls, context):
+ return(bpy.context.active_object.type == "MESH" )
+
+ def execute(self, context):
+ object_osc_futurism(self, context, self.scale, self.hold)
+
+ return {'FINISHED'}
+
+
+# Registration
+
+def add_osc_futurism_button(self, context):
+ self.layout.operator(
+ Oscurart_futurism.bl_idname,
+ text="Futurism",
+ icon="PLUGIN")
+
+
+def register():
+ bpy.utils.register_class(Oscurart_futurism)
+ bpy.types.VIEW3D_MT_object.append(add_osc_futurism_button)
+
+
+def unregister():
+ bpy.utils.unregister_class(Oscurart_futurism)
+ bpy.types.VIEW3D_MT_object.remove(add_osc_futurism_button)
+
+
+if __name__ == '__main__':
+ register()
diff --git a/release/scripts/addons_contrib/oscurart_mesh_thread.py b/release/scripts/addons_contrib/oscurart_mesh_thread.py
new file mode 100644
index 0000000..99c116e
--- /dev/null
+++ b/release/scripts/addons_contrib/oscurart_mesh_thread.py
@@ -0,0 +1,103 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Make Thread Mesh",
+ "author": "Oscurart",
+ "version": (1,0),
+ "blender": (2, 59, 0),
+ "api": 4000,
+ "location": "Add > Mesh > Thread",
+ "description": "Make a thread.",
+ "warning": "",
+ "wiki_url": "oscurart.blogspot.com",
+ "tracker_url": "",
+ "category": "Object"}
+
+
+
+import math
+import bpy
+
+
+def func_osc_screw(self, STRETCH,TURNS,DIAMETER,RESOLUTION):
+ # DATA PARA EL MESH
+ me = bpy.data.meshes.new("threadData")
+ obj = bpy.data.objects.new("Thread", me)
+ bpy.context.scene.objects.link(obj)
+
+ # VARIABLES
+ vertexlist=[]
+ facelist=[]
+ facereset=0
+ CANTDIV=360/RESOLUTION
+ ESPACIODIV=STRETCH/(TURNS+2+RESOLUTION)
+
+ # PARA CADA VERTICE EN EL RANGO DESDE CERO A LENGTH
+ for vertice in range(0,TURNS+2+RESOLUTION):
+ # SUMA EN LA LISTA UN VERTICE
+ vertexlist.append((math.sin(math.radians(vertice*CANTDIV))*DIAMETER,vertice*ESPACIODIV,math.cos(math.radians(vertice*CANTDIV))*DIAMETER))
+ if vertice > RESOLUTION:
+ facelist.append((vertice-(RESOLUTION),vertice-((RESOLUTION)+1),vertice-1,vertice))
+
+ # CONECTO OBJETO
+ me.from_pydata(vertexlist,[],facelist)
+ me.update()
+
+
+
+class oscMakeScrew (bpy.types.Operator):
+
+ bl_idname = "mesh.primitive_thread_oscurart"
+ bl_label = "Add Mesh Thread"
+ bl_description = "Create a Thread"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ resolution = bpy.props.IntProperty (name="Resolution",default=10,min=3,max=1000)
+ stretch = bpy.props.FloatProperty (name="Stretch",default=1,min=0.000001,max=1000)
+ turns = bpy.props.IntProperty (name="Turns Steps",default=19,min=0)
+ diameter = bpy.props.FloatProperty (name="Diameter",default=1,min=0,max=1000)
+
+
+
+ def execute(self, context):
+ func_osc_screw(self, self.stretch,self.turns,self.diameter,self.resolution)
+ return {'FINISHED'}
+
+
+# Registration
+
+def add_screw_list(self, context):
+ self.layout.operator(
+ "mesh.primitive_thread_oscurart",
+ text="Thread",
+ icon="PLUGIN")
+
+def register():
+ bpy.types.INFO_MT_mesh_add.append(add_screw_list)
+ bpy.utils.register_class(oscMakeScrew)
+
+
+def unregister():
+ bpy.types.INFO_MT_mesh_add.remove(add_screw_list)
+ bpy.utils.unregister_class(oscMakeScrew)
+
+
+if __name__ == '__main__':
+ register()
+
diff --git a/release/scripts/addons_contrib/oscurart_tools.py b/release/scripts/addons_contrib/oscurart_tools.py
new file mode 100644
index 0000000..e1413f9
--- /dev/null
+++ b/release/scripts/addons_contrib/oscurart_tools.py
@@ -0,0 +1,2397 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Oscurart Tools",
+ "author": "Oscurart, CodemanX",
+ "version": (3,0),
+ "blender": (2, 63, 0),
+ "location": "View3D > Tools > Oscurart Tools",
+ "description": "Tools for objects, render, shapes, and files.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Oscurart_Tools",
+ "tracker_url": "",
+ "category": "Object"}
+
+import bpy
+import math
+import sys
+import os
+import stat
+import bmesh
+import time
+import random
+
+#r07
+
+## CREA PANELES EN TOOLS
+
+# VARIABLES DE ENTORNO
+bpy.types.Scene.osc_object_tools = bpy.props.BoolProperty(default=False)
+bpy.types.Scene.osc_mesh_tools = bpy.props.BoolProperty(default=False)
+bpy.types.Scene.osc_shapes_tools = bpy.props.BoolProperty(default=False)
+bpy.types.Scene.osc_render_tools = bpy.props.BoolProperty(default=False)
+bpy.types.Scene.osc_files_tools = bpy.props.BoolProperty(default=False)
+bpy.types.Scene.osc_overrides_tools = bpy.props.BoolProperty(default=False)
+
+# PANEL DE CONTROL
+class OscPanelControl(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Oscurart Tools"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self,context):
+ active_obj = context.active_object
+ layout = self.layout
+
+ col = layout.column(align=1)
+ col.prop(bpy.context.scene, "osc_object_tools", text="Object", icon="OBJECT_DATAMODE")
+ col.prop(bpy.context.scene, "osc_mesh_tools", text="Mesh", icon="EDITMODE_HLT")
+ col.prop(bpy.context.scene, "osc_shapes_tools", text="Shapes", icon="SHAPEKEY_DATA")
+ col.prop(bpy.context.scene, "osc_render_tools", text="Render", icon="SCENE")
+ col.prop(bpy.context.scene, "osc_files_tools", text="Files", icon="IMASEL")
+ col.prop(bpy.context.scene, "osc_overrides_tools", text="Overrides", icon="GREASEPENCIL")
+
+
+# POLLS
+class OscPollObject():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.osc_object_tools
+
+
+class OscPollMesh():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.osc_mesh_tools
+
+
+class OscPollShapes():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.osc_shapes_tools
+
+class OscPollRender():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.osc_render_tools
+
+class OscPollFiles():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.osc_files_tools
+
+class OscPollOverrides():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene.osc_overrides_tools
+
+
+## PANELES
+class OscPanelObject(OscPollObject, bpy.types.Panel):
+ bl_idname = "Oscurart Object Tools"
+ bl_label = "Object Tools"
+
+ def draw(self, context):
+ active_obj = context.active_object
+ layout = self.layout
+ col = layout.column(align=1)
+ row = col.row()
+
+ colrow = col.row(align=1)
+ colrow.operator("objects.relink_objects_between_scenes", icon="LINKED")
+ colrow.operator("objects.copy_objects_groups_layers", icon="LINKED")
+ colrow = col.row(align=1)
+ colrow.prop(bpy.context.scene, "SearchAndSelectOt", text="")
+ colrow.operator("object.search_and_select_osc", icon="ZOOM_SELECTED")
+ colrow = col.row(align=1)
+ colrow.prop(bpy.context.scene, "RenameObjectOt", text="")
+ colrow.operator("object.rename_objects_osc", icon="SHORTDISPLAY")
+ col.operator("object.duplicate_object_symmetry_osc", icon="OBJECT_DATAMODE", text="Duplicate Symmetry")
+ col.operator("object.distribute_osc", icon="OBJECT_DATAMODE", text="Distribute")
+ colrow = col.row(align=1)
+ colrow.operator("object.modifiers_remove_osc", icon="MODIFIER", text="Remove Modifiers")
+ colrow.operator("object.modifiers_apply_osc", icon="MODIFIER", text="Apply Modifiers")
+
+
+class OscPanelMesh(OscPollMesh, bpy.types.Panel):
+ bl_idname = "Oscurart Mesh Tools"
+ bl_label = "Mesh Tools"
+
+ def draw(self, context):
+ active_obj = context.active_object
+ layout = self.layout
+ col = layout.column(align=1)
+ row = col.row()
+
+ col.operator("mesh.select_side_osc", icon="VERTEXSEL")
+ colrow=col.row(align=1)
+ colrow.operator("mesh.resym_save_map", icon="UV_SYNC_SELECT")
+ colrow=col.row(align=1)
+ colrow.operator("mesh.resym_mesh", icon="UV_SYNC_SELECT", text="Resym Mesh")
+ colrow.operator("mesh.resym_vertex_weights_osc", icon="UV_SYNC_SELECT")
+ colrow=col.row(align=1)
+ colrow.operator("mesh.reconst_osc", icon="UV_SYNC_SELECT")
+ colrow=col.row(align=1)
+ colrow.operator("file.export_groups_osc", icon='GROUP_VCOL')
+ colrow.operator("file.import_groups_osc", icon='GROUP_VCOL')
+
+
+class OscPanelShapes(OscPollShapes, bpy.types.Panel):
+ bl_idname = "Oscurart Shapes Tools"
+ bl_label = "Shapes Tools"
+
+ def draw(self, context):
+ active_obj = context.active_object
+ layout = self.layout
+ col = layout.column(align=1)
+ row = col.row()
+
+ col.operator("object.shape_key_to_objects_osc", icon="OBJECT_DATAMODE")
+ col.operator("mesh.create_lmr_groups_osc", icon="GROUP_VERTEX")
+ col.operator("mesh.split_lr_shapes_osc", icon="SHAPEKEY_DATA")
+ colrow=col.row()
+ colrow.operator("mesh.create_symmetrical_layout_osc", icon="SETTINGS")
+ colrow.operator("mesh.create_asymmetrical_layout_osc", icon="SETTINGS")
+
+class OscPanelRender(OscPollRender, bpy.types.Panel):
+ bl_idname = "Oscurart Render Tools"
+ bl_label = "Render Tools"
+
+ def draw(self, context):
+ active_obj = context.active_object
+ layout = self.layout
+ col = layout.column(align=1)
+ row = col.row()
+
+ col.operator("file.create_batch_maker_osc", icon="LINENUMBERS_ON", text="Make Render Batch")
+ colrow = col.row()
+ col.operator("file.create_batch_python", icon="LINENUMBERS_ON", text="Make Python Batch")
+ colrow = col.row()
+ colrow.operator("render.render_all_scenes_osc", icon="RENDER_STILL", text="All Scenes").frametype=False
+ colrow.operator("render.render_all_scenes_osc", icon="RENDER_STILL", text="> Frame").frametype=True
+ colrow = col.row()
+ colrow.operator("render.render_current_scene_osc", icon="RENDER_STILL", text="Active Scene").frametype=False
+ colrow.operator("render.render_current_scene_osc", icon="RENDER_STILL", text="> Frame").frametype=True
+
+
+ colrow = col.row(align=1)
+ colrow.prop(bpy.context.scene, "rcPARTS", text="Render Crop Parts")
+ colrow.operator("render.render_crop_osc", icon="RENDER_REGION")
+
+ col = layout.column(align=1)
+ colrow = col.row(align=1)
+ colrow.prop(bpy.context.scene, "use_render_scene", text="")
+ colrow.operator("render.render_selected_scenes_osc", icon="RENDER_STILL", text="Selected Scenes").frametype=False
+ colrow.operator("render.render_selected_scenes_osc", icon="RENDER_STILL", text="> Fame").frametype=True
+
+
+
+class OscPanelFiles(OscPollFiles, bpy.types.Panel):
+ bl_idname = "Oscurart Files Tools"
+ bl_label = "Files Tools"
+
+ def draw(self, context):
+ active_obj = context.active_object
+ layout = self.layout
+ col = layout.column(align=1)
+
+ colrow = col.row()
+ colrow.operator("file.save_incremental_osc", icon="NEW")
+ colrow.operator("image.reload_images_osc", icon="IMAGE_COL")
+ col = layout.column(align=1)
+ colrow = col.row(align=1)
+ colrow.prop(bpy.context.scene, "oscSearchText", text="")
+ colrow.prop(bpy.context.scene, "oscReplaceText", text="")
+ col.operator("file.replace_file_path_osc", icon="SHORTDISPLAY")
+
+
+class OscPanelOverrides(OscPollOverrides, bpy.types.Panel):
+ bl_idname = "Oscurart Overrides"
+ bl_label = "Overrides Tools"
+
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+
+ col = layout.box().column(align=1)
+
+ colrow = col.row()
+ col.operator("render.overrides_set_list", text="Create Override List", icon="GREASEPENCIL")
+ col.label(text="Active Scene: " + bpy.context.scene.name)
+ col.label(text="Example: [[Group,Material]]")
+ col.prop(bpy.context.scene, '["OVERRIDE"]', text="")
+ col.operator("render.check_overrides", text="Check List", icon="ZOOM_ALL")
+ col.operator("render.overrides_on", text="On / Off", icon="QUIT")
+
+ boxcol=layout.box().column(align=1)
+ boxcol.label(text="Danger Zone")
+ boxcolrow=boxcol.row()
+ boxcolrow.operator("render.apply_overrides", text="Apply Overrides", icon="ERROR")
+ boxcolrow.operator("render.restore_overrides", text="Restore Overrides", icon="ERROR")
+
+
+
+
+
+##---------------------------RELOAD IMAGES------------------
+
+class reloadImages (bpy.types.Operator):
+ bl_idname = "image.reload_images_osc"
+ bl_label = "Reload Images"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+ for imgs in bpy.data.images:
+ imgs.reload()
+ return {'FINISHED'}
+
+##-----------------------------RECONST---------------------------
+
+def defReconst(self, OFFSET):
+
+ ##EDIT
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+
+ ##SETEO VERTEX MODE
+ bpy.context.tool_settings.mesh_select_mode = (True, False, False)
+
+ OBJETO = bpy.context.active_object
+ OBDATA = bmesh.from_edit_mesh(OBJETO.data)
+ OBDATA.select_flush(False)
+
+ ## IGUALO VERTICES CERCANOS A CERO
+ for vertice in OBDATA.verts[:]:
+ if abs(vertice.co[0]) < OFFSET:
+ vertice.co[0] = 0
+
+ ##BORRA IZQUIERDA
+ bpy.ops.mesh.select_all(action="DESELECT")
+
+ for vertices in OBDATA.verts[:]:
+ if vertices.co[0] < 0:
+ vertices.select = 1
+
+ ## BORRA COMPONENTES
+ bpy.ops.mesh.delete()
+ ## SUMA MIRROR
+ bpy.ops.object.modifier_add(type='MIRROR')
+ ## SELECCIONO TODOS LOS COMPONENTES
+ bpy.ops.mesh.select_all(action="SELECT")
+ ## CREO UV TEXTURE DEL SIMETRICO
+ bpy.ops.mesh.uv_texture_add()
+ ## SETEO VARIABLE CON LA CANTIDAD DE UVS, RESTO UNO Y LE DOY UN NOMBRE
+ LENUVLISTSIM = len(bpy.data.objects[OBJETO.name].data.uv_textures)
+ LENUVLISTSIM = LENUVLISTSIM - 1
+ OBJETO.data.uv_textures[LENUVLISTSIM:][0].name = "SYMMETRICAL"
+ ## UNWRAP
+ bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=0)
+ ## MODO OBJETO
+ bpy.ops.object.mode_set(mode="OBJECT", toggle= False)
+ ## APLICO MIRROR
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Mirror")
+ ## VUELVO A EDIT MODE
+ bpy.ops.object.mode_set(mode="EDIT", toggle= False)
+ OBDATA = bmesh.from_edit_mesh(OBJETO.data)
+ OBDATA.select_flush(0)
+ ## CREO UV TEXTURE DEL ASIMETRICO
+ bpy.ops.mesh.uv_texture_add()
+ ## SETEO VARIABLE CON LA CANTIDAD DE UVS, RESTO UNO Y LE DOY UN NOMBRE
+ LENUVLISTASIM = len(OBJETO.data.uv_textures)
+ LENUVLISTASIM = LENUVLISTASIM - 1
+ OBJETO.data.uv_textures[LENUVLISTASIM:][0].name = "ASYMMETRICAL"
+ ## SETEO UV ACTIVO
+ OBJETO.data.uv_textures.active = OBJETO.data.uv_textures["ASYMMETRICAL"]
+ ## UNWRAP
+ bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=False, use_subsurf_data=0)
+
+
+class reConst (bpy.types.Operator):
+ bl_idname = "mesh.reconst_osc"
+ bl_label = "ReConst Mesh"
+ bl_options = {"REGISTER", "UNDO"}
+ OFFSET=bpy.props.FloatProperty(name="Offset", default=0.001, min=-0, max=0.1)
+
+ def execute(self,context):
+ defReconst(self, self.OFFSET)
+ return {'FINISHED'}
+
+## -----------------------------------SELECT LEFT---------------------
+def side (self, nombre, offset):
+
+ bpy.ops.object.mode_set(mode="EDIT", toggle=0)
+
+ OBJECT = bpy.context.active_object
+ ODATA = bmesh.from_edit_mesh(OBJECT.data)
+ MODE = bpy.context.mode
+
+
+ ##SETEO VERTEX MODE
+
+ bpy.context.tool_settings.mesh_select_mode = (True, False, False)
+
+ ## DESELECCIONA TODO
+ for VERTICE in ODATA.verts[:]:
+ VERTICE.select = False
+
+ if nombre == False:
+ ## CONDICION QUE SI EL VERTICE ES MENOR A 0 LO SELECCIONA
+ for VERTICES in ODATA.verts[:]:
+ if VERTICES.co[0] < (offset):
+ VERTICES.select = 1
+ else:
+ ## CONDICION QUE SI EL VERTICE ES MENOR A 0 LO SELECCIONA
+ for VERTICES in ODATA.verts[:]:
+ if VERTICES.co[0] > (offset):
+ VERTICES.select = 1
+
+ ODATA.select_flush(False)
+
+ bpy.ops.object.mode_set(mode="EDIT", toggle=0)
+
+
+class SelectMenor (bpy.types.Operator):
+ bl_idname = "mesh.select_side_osc"
+ bl_label = "Select Side"
+ bl_options = {"REGISTER", "UNDO"}
+
+ side = bpy.props.BoolProperty(name="Greater than zero", default=False)
+ offset = bpy.props.FloatProperty(name="Offset", default=0)
+ def execute(self,context):
+
+ side(self, self.side, self.offset)
+
+ return {'FINISHED'}
+
+
+##-----------------------------------CREATE SHAPES----------------
+
+def DefSplitShapes(self,ACTIVESHAPE,LAYOUTCOMPAT):
+ #PASO A OBJECT MODE
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ ## VARIABLES
+ ACTOBJ=bpy.context.active_object
+ LENKB=len(ACTOBJ.data.shape_keys.key_blocks)
+ INDEX=ACTOBJ.active_shape_key_index
+
+ ## RECORTO NOMBRES
+ if not LAYOUTCOMPAT:
+ for SHAPE in ACTOBJ.data.shape_keys.key_blocks:
+ if len(SHAPE.name) > 7:
+ SHAPE.name=SHAPE.name[:8]
+
+ if ACTIVESHAPE:
+ print(INDEX)
+ ACTOBJ.active_shape_key_index=INDEX
+ AS=ACTOBJ.active_shape_key
+ AS.value=1
+ bpy.ops.object.shape_key_add(from_mix=True)
+ ACTOBJ.data.shape_keys.key_blocks[-1].name=AS.name[:8]+"_L"
+ ACTOBJ.data.shape_keys.key_blocks[-1].vertex_group="_L"
+ bpy.ops.object.shape_key_add(from_mix=True)
+ ACTOBJ.data.shape_keys.key_blocks[-1].name=AS.name[:8]+"_R"
+ ACTOBJ.data.shape_keys.key_blocks[-1].vertex_group="_R"
+ bpy.ops.object.shape_key_clear()
+
+ else:
+ ## DUPLICO SHAPES Y CONECTO GRUPO
+ for SHAPE in ACTOBJ.data.shape_keys.key_blocks[1:]:
+ SHAPE.value=1
+ bpy.ops.object.shape_key_add(from_mix=True)
+ ACTOBJ.data.shape_keys.key_blocks[-1].name=SHAPE.name[:8]+"_L"
+ ACTOBJ.data.shape_keys.key_blocks[-1].vertex_group="_L"
+ bpy.ops.object.shape_key_add(from_mix=True)
+ ACTOBJ.data.shape_keys.key_blocks[-1].name=SHAPE.name[:8]+"_R"
+ ACTOBJ.data.shape_keys.key_blocks[-1].vertex_group="_R"
+ bpy.ops.object.shape_key_clear()
+ ACTOBJ.active_shape_key_index=INDEX
+
+
+class CreaShapes(bpy.types.Operator):
+ bl_idname = "mesh.split_lr_shapes_osc"
+ bl_label = "Split LR Shapes"
+ bl_options = {"REGISTER", "UNDO"}
+
+ @classmethod
+ def poll(cls, context):
+ return context.object is not None
+
+ activeshape=bpy.props.BoolProperty(name="Only Active Shape", default=False)
+ layoutcompat=bpy.props.BoolProperty(name="Layout Compatible", default=False)
+
+ def execute(self, context):
+
+ DefSplitShapes(self,self.activeshape,self.layoutcompat)
+
+ return {'FINISHED'}
+
+##----------------------------SHAPES LAYOUT-----------------------
+
+class CreaShapesLayout(bpy.types.Operator):
+ bl_idname = "mesh.create_symmetrical_layout_osc"
+ bl_label = "Symmetrical Layout"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self, context):
+
+ SEL_OBJ= bpy.context.active_object
+ LISTA_KEYS = bpy.context.active_object.data.shape_keys.key_blocks[1:]
+
+
+ ##MODOS
+ EDITMODE = "bpy.ops.object.mode_set(mode='EDIT')"
+ OBJECTMODE = "bpy.ops.object.mode_set(mode='OBJECT')"
+ POSEMODE = "bpy.ops.object.mode_set(mode='POSE')"
+
+ ##INDICE DE DRIVERS
+ varindex = 0
+
+ ##CREA NOMBRES A LA ARMATURE
+ amt = bpy.data.armatures.new("ArmatureData")
+ ob = bpy.data.objects.new("RIG_LAYOUT_"+SEL_OBJ.name, amt)
+
+ ##LINK A LA ESCENA
+ scn = bpy.context.scene
+ scn.objects.link(ob)
+ scn.objects.active = ob
+ ob.select = True
+
+ ## CREO DATA PARA SLIDERS
+ ## creo data para los contenedores
+ verticess = [(-1,1,0),(1,1,0),(1,-1,0),(-1,-1,0)]
+ edgess = [(0,1),(1,2),(2,3),(3,0)]
+ mesh = bpy.data.meshes.new("%s_data_container" % (SEL_OBJ))
+ object = bpy.data.objects.new("GRAPHIC_CONTAINER", mesh)
+ bpy.context.scene.objects.link(object)
+ mesh.from_pydata(verticess,edgess,[])
+
+ gx = 0
+ gy = 0
+
+
+ for keyblock in LISTA_KEYS:
+ if keyblock.name[-2:] != "_L":
+ if keyblock.name[-2:] != "_R":
+
+ ## OBJETO ACTIVO
+ scn.objects.active = ob
+ eval(EDITMODE)
+
+ ##CREA HUESOS
+ bone = amt.edit_bones.new(keyblock.name)
+ bone.head = (gx,0,0)
+ bone.tail = (gx,0,1)
+
+ bonectrl = amt.edit_bones.new(keyblock.name+"_CTRL")
+ bonectrl.head = (gy,0,0)
+ bonectrl.tail = (gy,0,0.2)
+
+ ##EMPARENTA HUESOS
+ ## EMPARENTO
+ ob.data.edit_bones[bonectrl.name].parent = ob.data.edit_bones[bone.name]
+ bpy.context.scene.objects.active = ob
+
+ for SIDE in ["L","R"]:
+ ##LE HAGO UNA VARIABLE
+ DR = SEL_OBJ.data.shape_keys.key_blocks[keyblock.name+"_"+SIDE].driver_add("value")
+ if SIDE == "L":
+ DR.driver.expression = "var+var_001"
+ else:
+ DR.driver.expression = "-var+var_001"
+ VAR1 = DR.driver.variables.new()
+ VAR2 = DR.driver.variables.new()
+
+ VAR1.targets[0].id = ob
+ VAR1.type = 'TRANSFORMS'
+ VAR1.targets[0].bone_target = bonectrl.name
+ VAR1.targets[0].transform_space = "LOCAL_SPACE"
+ VAR1.targets[0].transform_type = "LOC_X"
+ VAR2.targets[0].id = ob
+ VAR2.type = 'TRANSFORMS'
+ VAR2.targets[0].bone_target = bonectrl.name
+ VAR2.targets[0].transform_space = "LOCAL_SPACE"
+ VAR2.targets[0].transform_type = "LOC_Y"
+
+ eval(POSEMODE)
+
+ ## SETEO ICONOS
+ ob.pose.bones[keyblock.name].custom_shape = object
+ ob.pose.bones[keyblock.name+"_CTRL"].custom_shape = object
+ CNS = ob.pose.bones[keyblock.name+"_CTRL"].constraints.new(type='LIMIT_LOCATION')
+ CNS.min_x = -1
+ CNS.use_min_x = 1
+ CNS.min_z = 0
+ CNS.use_min_z = 1
+ CNS.min_y = -1
+ CNS.use_min_y = 1
+ CNS.max_x = 1
+ CNS.use_max_x = 1
+ CNS.max_z = 0
+ CNS.use_max_z = 1
+ CNS.max_y = 1
+ CNS.use_max_y = 1
+ CNS.owner_space = "LOCAL"
+ CNS.use_transform_limit = True
+
+ eval(OBJECTMODE)
+ ## creo tipografias
+ bpy.ops.object.text_add(location=(gx,0,0))
+ gx = gx+2.2
+ gy = gy+2.2
+ texto = bpy.context.object
+
+ texto.data.body = keyblock.name
+ texto.name = "TEXTO_"+keyblock.name
+
+ texto.rotation_euler[0] = math.pi/2
+ texto.location.x = -1
+ texto.location.z = -1
+ texto.data.size = .2
+
+ CNS = texto.constraints.new(type="COPY_LOCATION")
+ CNS.target = ob
+ CNS.subtarget = ob.pose.bones[keyblock.name].name
+ CNS.use_offset = True
+
+
+
+ return {'FINISHED'}
+
+##----------------------------CREATE LMR GROUPS-------------------
+def createLMRGroups(self, FACTORVG, ADDVG):
+ ## SETEO VERTEX MODE EDIT
+ bpy.context.window.screen.scene.tool_settings.mesh_select_mode = (True, False, False)
+
+ ## VARIABLES
+ ACTOBJ=bpy.context.active_object
+ bpy.ops.object.mode_set(mode="EDIT", toggle=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode="OBJECT")
+ GRUPOS=["_L","_R"]
+ MIRRORINDEX=0
+
+ for LADO in GRUPOS:
+ if MIRRORINDEX == 0:
+ ## SUMO DOS VG
+ bpy.ops.object.vertex_group_add()
+ ## ASIGNO TODOS LOS VERTICES AL GRUPO
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.object.vertex_group_assign(new=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False)
+ ## SETEO VALORES
+ for VERTICE in ACTOBJ.data.vertices:
+ VERTICE.groups[-1].weight=(VERTICE.co[0]*FACTORVG)+ADDVG
+ ## RENOMBRO
+ ACTOBJ.vertex_groups[-1].name=LADO
+
+ else:
+ ## SUMO DOS VG
+ bpy.ops.object.vertex_group_add()
+ ## ASIGNO TODOS LOS VERTICES AL GRUPO
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.object.vertex_group_assign(new=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False)
+ ## SETEO VALORES
+ for VERTICE in ACTOBJ.data.vertices:
+ VERTICE.groups[-1].weight=(-VERTICE.co[0]*FACTORVG)+ADDVG
+ ## RENOMBRO
+ ACTOBJ.vertex_groups[-1].name=LADO
+ ## CAMBIO MIRROR INDEX
+ MIRRORINDEX+=1
+
+ ## SETEO GRUPO ACTIVO
+ ACTOBJ.vertex_groups.active_index=len(ACTOBJ.vertex_groups)
+
+
+class CreaGrupos(bpy.types.Operator):
+ bl_idname = "mesh.create_lmr_groups_osc"
+ bl_label = "Create Mix groups"
+ bl_description = "Create Mix groups"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ FACTORVG= bpy.props.FloatProperty(name="Factor", default=1, min=0, max=1000)
+ ADDVG= bpy.props.FloatProperty(name="Addition", default=.5, min=0, max=1000)
+
+ def execute(self, context):
+
+ createLMRGroups(self, self.FACTORVG, self.ADDVG)
+
+ return {'FINISHED'}
+
+
+
+##-------------------------------- RENDER ALL SCENES ----------------------------
+
+
+def defRenderAll (frametype):
+ LISTMAT=[]
+ SCENES=bpy.data.scenes[:]
+ ACTSCENE=bpy.context.scene
+ FC=bpy.context.scene.frame_current
+ FS=bpy.context.scene.frame_start
+ FE=bpy.context.scene.frame_end
+ print("---------------------")
+ ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
+ for OBJECT in bpy.data.objects[:]:
+ SLOTLIST=[]
+ try:
+ if OBJECT.type=="MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ for SLOT in OBJECT.material_slots[:]:
+ SLOTLIST.append(SLOT.material)
+
+ LISTMAT.append((OBJECT,SLOTLIST))
+
+ except:
+ pass
+ for SCENE in SCENES:
+ PROPTOLIST=list(eval(SCENE['OVERRIDE']))
+ CURSC= SCENE.name
+ PATH = SCENE.render.filepath
+ ENDPATH = PATH
+ FILEPATH=bpy.data.filepath
+ # CAMBIO SCENE
+ bpy.context.window.screen.scene=SCENE
+ if frametype == True:
+ bpy.context.scene.frame_start=FC
+ bpy.context.scene.frame_end=FC
+ bpy.context.scene.frame_end=FC
+ bpy.context.scene.frame_start=FC
+ ## SETEO MATERIALES DE OVERRIDES
+ try:
+ for OVERRIDE in PROPTOLIST:
+ for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
+ if OBJECT.type == "MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ for SLOT in OBJECT.material_slots[:]:
+ SLOT.material=bpy.data.materials[OVERRIDE[1]]
+ except:
+ pass
+ SCENENAME=os.path.basename(FILEPATH.rpartition(".")[0])
+ LAYERLIST=[]
+ for layer in SCENE.render.layers:
+ if layer.use == 1:
+ LAYERLIST.append(layer)
+ for layers in LAYERLIST:
+ for rl in LAYERLIST:
+ rl.use= 0
+ print("SCENE: "+CURSC)
+ print("LAYER: "+layers.name)
+ print("OVERRIDE: "+str(PROPTOLIST))
+ SCENE.render.filepath = "%s/%s/%s/%s/%s_%s_%s_" % (PATH,SCENENAME,CURSC,layers.name,SCENENAME,SCENE.name,layers.name)
+ SCENE.render.layers[layers.name].use = 1
+ bpy.ops.render.render(animation=True, write_still=True, layer=layers.name, scene= SCENE.name)
+ print("DONE")
+ print("---------------------")
+
+ ## REESTABLECE LOS LAYERS
+ for layer in LAYERLIST:
+ layer.use = 1
+ ## RESTAURA EL PATH FINAL
+ SCENE.render.filepath = ENDPATH
+ #RESTAURO MATERIALES DE OVERRIDES
+ for OBJECT in LISTMAT:
+ SLOTIND=0
+ try:
+ for SLOT in OBJECT[1]:
+ OBJECT[0].material_slots[SLOTIND].material=SLOT
+ SLOTIND+=1
+ except:
+ print("OUT OF RANGE")
+ # RESTAURO FRAMES
+ if frametype == True:
+ SCENE.frame_start=FS
+ SCENE.frame_end=FE
+ SCENE.frame_end=FE
+ SCENE.frame_start=FS
+ # RESTAURO SCENE
+ bpy.context.window.screen.scene=ACTSCENE
+
+
+class renderAll (bpy.types.Operator):
+ bl_idname="render.render_all_scenes_osc"
+ bl_label="Render All Scenes"
+
+ frametype=bpy.props.BoolProperty(default=False)
+
+
+ def execute(self,context):
+ defRenderAll(self.frametype)
+ return {'FINISHED'}
+
+
+
+##--------------------------------RENDER SELECTED SCENES----------------------------
+
+
+bpy.types.Scene.use_render_scene = bpy.props.BoolProperty()
+
+
+def defRenderSelected(frametype):
+ ACTSCENE = bpy.context.scene
+ LISTMAT = []
+ SCENES = bpy.data.scenes[:]
+ FC = bpy.context.scene.frame_current
+ FS = bpy.context.scene.frame_start
+ FE = bpy.context.scene.frame_end
+ ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
+ for OBJECT in bpy.data.objects[:]:
+ SLOTLIST=[]
+ try:
+ if OBJECT.type == "MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ for SLOT in OBJECT.material_slots[:]:
+ SLOTLIST.append(SLOT.material)
+
+ LISTMAT.append((OBJECT,SLOTLIST))
+ except:
+ pass
+ for SCENE in SCENES:
+ if SCENE.use_render_scene:
+ PROPTOLIST = list(eval(SCENE['OVERRIDE']))
+ CURSC = SCENE.name
+ PATH = SCENE.render.filepath
+ ENDPATH = PATH
+ FILEPATH = bpy.data.filepath
+ print("---------------------")
+ # CAMBIO SCENE
+ bpy.context.window.screen.scene = SCENE
+ if frametype == True:
+ bpy.context.scene.frame_start = FC
+ bpy.context.scene.frame_end = FC
+ bpy.context.scene.frame_end = FC
+ bpy.context.scene.frame_start = FC
+ ## SETEO MATERIALES DE OVERRIDES
+ try:
+ for OVERRIDE in PROPTOLIST:
+ for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
+ if OBJECT.type == "MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ for SLOT in OBJECT.material_slots[:]:
+ SLOT.material=bpy.data.materials[OVERRIDE[1]]
+ except:
+ pass
+ SCENENAME=os.path.basename(FILEPATH.rpartition(".")[0])
+ LAYERLIST=[]
+ for layer in SCENE.render.layers:
+ if layer.use == 1:
+ LAYERLIST.append(layer)
+ for layers in LAYERLIST:
+ for rl in LAYERLIST:
+ rl.use= 0
+ print("SCENE: "+CURSC)
+ print("LAYER: "+layers.name)
+ print("OVERRIDE: "+str(PROPTOLIST))
+ SCENE.render.filepath = "%s/%s/%s/%s/%s_%s_%s_" % (PATH,SCENENAME,CURSC,layers.name,SCENENAME,SCENE.name,layers.name)
+ SCENE.render.layers[layers.name].use = 1
+ bpy.ops.render.render(animation=True, layer=layers.name, write_still=True, scene= SCENE.name)
+ print("DONE")
+ print("---------------------")
+ ## REESTABLECE LOS LAYERS
+ for layer in LAYERLIST:
+ layer.use = 1
+ ## RESTAURA EL PATH FINAL
+ SCENE.render.filepath = ENDPATH
+ #RESTAURO MATERIALES DE OVERRIDES
+ for OBJECT in LISTMAT:
+ SLOTIND = 0
+ try:
+ for SLOT in OBJECT[1]:
+ OBJECT[0].material_slots[SLOTIND].material = SLOT
+ SLOTIND += 1
+ except:
+ print("OUT OF RANGE")
+ # RESTAURO FRAMES
+ if frametype == True:
+ SCENE.frame_start = FS
+ SCENE.frame_end = FE
+ SCENE.frame_end = FE
+ SCENE.frame_start = FS
+ # RESTAURO SCENE
+ bpy.context.window.screen.scene = ACTSCENE
+
+
+class renderSelected (bpy.types.Operator):
+ bl_idname="render.render_selected_scenes_osc"
+ bl_label="Render Selected Scenes"
+
+ frametype=bpy.props.BoolProperty(default=False)
+
+ def execute(self,context):
+ defRenderSelected(self.frametype)
+ return {'FINISHED'}
+
+
+
+
+##--------------------------------RENDER CURRENT SCENE----------------------------
+
+
+def defRenderCurrent (frametype):
+ LISTMAT = []
+ SCENE = bpy.context.scene
+ FC = bpy.context.scene.frame_current
+ FS = bpy.context.scene.frame_start
+ FE = bpy.context.scene.frame_end
+
+ print("---------------------")
+ ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
+ for OBJECT in bpy.data.objects[:]:
+ SLOTLIST = []
+ try:
+ if OBJECT.type == "MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ for SLOT in OBJECT.material_slots[:]:
+ SLOTLIST.append(SLOT.material)
+ LISTMAT.append((OBJECT,SLOTLIST))
+ except:
+ pass
+ PROPTOLIST = list(eval(SCENE['OVERRIDE']))
+ CURSC = SCENE.name
+ PATH = SCENE.render.filepath
+ ENDPATH = PATH
+ FILEPATH = bpy.data.filepath
+ if frametype == True:
+ bpy.context.scene.frame_start = FC
+ bpy.context.scene.frame_end = FC
+ bpy.context.scene.frame_end = FC
+ bpy.context.scene.frame_start = FC
+ ## SETEO MATERIALES DE OVERRIDES
+ try:
+ for OVERRIDE in PROPTOLIST:
+ for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
+ if OBJECT.type == "MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ for SLOT in OBJECT.material_slots[:]:
+ SLOT.material = bpy.data.materials[OVERRIDE[1]]
+ except:
+ pass
+ SCENENAME=os.path.basename(FILEPATH.rpartition(".")[0])
+ LAYERLIST=[]
+ for layer in SCENE.render.layers:
+ if layer.use == 1:
+ LAYERLIST.append(layer)
+ for layers in LAYERLIST:
+ for rl in LAYERLIST:
+ rl.use= 0
+ print("SCENE: "+CURSC)
+ print("LAYER: "+layers.name)
+ print("OVERRIDE: "+str(PROPTOLIST))
+ SCENE.render.filepath = "%s/%s/%s/%s/%s_%s_%s_" % (PATH,SCENENAME,CURSC,layers.name,SCENENAME,SCENE.name,layers.name)
+ SCENE.render.layers[layers.name].use = 1
+ bpy.ops.render.render(animation=True, layer=layers.name, write_still=1, scene= SCENE.name)
+ print("DONE")
+ print("---------------------")
+ ## REESTABLECE LOS LAYERS
+ for layer in LAYERLIST:
+ layer.use = 1
+ ## RESTAURA EL PATH FINAL
+ SCENE.render.filepath = ENDPATH
+ #RESTAURO MATERIALES DE OVERRIDES
+ for OBJECT in LISTMAT:
+ SLOTIND = 0
+ try:
+ for SLOT in OBJECT[1]:
+ OBJECT[0].material_slots[SLOTIND].material=SLOT
+ SLOTIND += 1
+ except:
+ print("FUERA DE RANGO")
+ # RESTAURO FRAMES
+ if frametype == True:
+ SCENE.frame_start = FS
+ SCENE.frame_end = FE
+ SCENE.frame_end = FE
+ SCENE.frame_start = FS
+
+
+class renderCurrent (bpy.types.Operator):
+ bl_idname="render.render_current_scene_osc"
+ bl_label="Render Current Scene"
+
+ frametype=bpy.props.BoolProperty(default=False)
+
+ def execute(self,context):
+
+ defRenderCurrent(self.frametype)
+
+ return {'FINISHED'}
+
+
+##--------------------------RENDER CROP----------------------
+## CREO DATA PARA EL SLIDER
+bpy.types.Scene.rcPARTS = bpy.props.IntProperty(default=0, min=2, max=50, step=1)
+
+def OscRenderCropFunc():
+ SCENENAME = os.path.split(bpy.data.filepath)[-1].partition(".")[0]
+ PARTS = bpy.context.scene.rcPARTS
+ CHUNKYSIZE = 1/PARTS
+ FILEPATH = bpy.context.scene.render.filepath
+ bpy.context.scene.render.use_border = True
+ bpy.context.scene.render.use_crop_to_border = True
+ for PART in range(PARTS):
+ bpy.context.scene.render.border_min_y = PART*CHUNKYSIZE
+ bpy.context.scene.render.border_max_y = (PART*CHUNKYSIZE)+CHUNKYSIZE
+ bpy.context.scene.render.filepath = "%s_part%s" % (os.path.join(FILEPATH,SCENENAME,bpy.context.scene.name,SCENENAME),PART)
+ bpy.ops.render.render(animation=False, write_still=True)
+
+ #RESTORE
+ bpy.context.scene.render.filepath = FILEPATH
+
+class renderCrop (bpy.types.Operator):
+ bl_idname="render.render_crop_osc"
+ bl_label="Render Crop: Render!"
+ def execute(self,context):
+ OscRenderCropFunc()
+ return {'FINISHED'}
+
+
+##------------------------ SEARCH AND SELECT ------------------------
+
+## SETEO VARIABLE DE ENTORNO
+bpy.types.Scene.SearchAndSelectOt = bpy.props.StringProperty(default="Object name initials")
+
+
+class SearchAndSelectOt(bpy.types.Operator):
+ bl_idname = "object.search_and_select_osc"
+ bl_label = "Search And Select"
+ bl_options = {"REGISTER", "UNDO"}
+
+ start = bpy.props.BoolProperty(name="Start With", default=True)
+ count = bpy.props.BoolProperty(name="Contain", default=True)
+ end = bpy.props.BoolProperty(name="End", default=True)
+
+ def execute(self, context):
+ for objeto in bpy.context.scene.objects:
+ variableNombre = bpy.context.scene.SearchAndSelectOt
+ if self.start:
+ if objeto.name.startswith(variableNombre):
+ objeto.select = True
+ if self.count:
+ if objeto.name.count(variableNombre):
+ objeto.select = True
+ if self.end:
+ if objeto.name.count(variableNombre):
+ objeto.select = True
+ return {'FINISHED'}
+
+##-------------------------RENAME OBJECTS----------------------------------
+
+## CREO VARIABLE
+bpy.types.Scene.RenameObjectOt = bpy.props.StringProperty(default="Type here")
+
+class renameObjectsOt (bpy.types.Operator):
+ bl_idname = "object.rename_objects_osc"
+ bl_label = "Rename Objects"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+ ## LISTA
+ listaObj = bpy.context.selected_objects[:]
+ for objeto in listaObj:
+ objeto.name = bpy.context.scene.RenameObjectOt
+ return {'FINISHED'}
+
+
+##-------------------------RESYM VG----------------------------------
+
+
+
+class resymVertexGroups (bpy.types.Operator):
+ bl_idname = "mesh.resym_vertex_weights_osc"
+ bl_label = "Resym Vertex Weights"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+
+ OBACTIVO = bpy.context.active_object
+ VGACTIVO = OBACTIVO.vertex_groups.active.index
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ BM = bmesh.from_edit_mesh(bpy.context.object.data)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.vertex_group_select()
+ SELVER=[VERT.index for VERT in BM.verts[:] if VERT.select]
+
+ if sys.platform.startswith("w"):
+ SYSBAR = "\\"
+ else:
+ SYSBAR = "/"
+
+ FILEPATH=bpy.data.filepath
+ ACTIVEFOLDER=FILEPATH.rpartition(SYSBAR)[0]
+ ENTFILEPATH= "%s%s%s_%s_SYM_TEMPLATE.xml" % (ACTIVEFOLDER, SYSBAR, bpy.context.scene.name, bpy.context.object.name)
+ XML=open(ENTFILEPATH ,mode="r")
+
+ SYMAP = eval(XML.readlines()[0])
+
+
+ # SUMO LOS VERTICES QUE NO EXISTEN EN EL VG
+ INL = [VERT for VERT in SYMAP if SYMAP[VERT] in SELVER if VERT!= SYMAP[VERT]]
+ bpy.ops.mesh.select_all(action='DESELECT')
+
+ for VERT in INL:
+ BM.verts[VERT].select = True
+ bpy.ops.object.vertex_group_assign(new=False)
+
+
+ # PASO A WEIGHT Y SETEO LOS VALORES
+ bpy.ops.object.mode_set(mode='WEIGHT_PAINT')
+ for VERT in INL:
+ print(VERT)
+ i = 0
+ for GRA in OBACTIVO.data.vertices[SYMAP[VERT]].groups[:]:
+ if GRA.group == VGACTIVO:
+ print (i)
+ EM = i
+ i+=1
+ a = 0
+ for GRA in OBACTIVO.data.vertices[VERT].groups[:]:
+ if GRA.group == VGACTIVO:
+ print (a)
+ REC = a
+ a+=1
+
+ OBACTIVO.data.vertices[VERT].groups[REC].weight = OBACTIVO.data.vertices[SYMAP[VERT]].groups[EM].weight
+
+
+ XML.close()
+ SYMAP.clear()
+
+
+ print("===============(JOB DONE)=============")
+ return {'FINISHED'}
+
+
+##------------------------ SHAPES LAYOUT SYMMETRICA ------------------------
+
+
+class CreateLayoutAsymmetrical(bpy.types.Operator):
+ bl_idname = "mesh.create_asymmetrical_layout_osc"
+ bl_label = "Asymmetrical Layout"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self, context):
+
+ SEL_OBJ= bpy.context.active_object
+ LISTA_KEYS = bpy.context.active_object.data.shape_keys.key_blocks[1:]
+
+ ##MODOS
+ EDITMODE = "bpy.ops.object.mode_set(mode='EDIT')"
+ OBJECTMODE = "bpy.ops.object.mode_set(mode='OBJECT')"
+ POSEMODE = "bpy.ops.object.mode_set(mode='POSE')"
+
+ ##CREA NOMBRES A LA ARMATURE
+ amtas = bpy.data.armatures.new("ArmatureData")
+ obas = bpy.data.objects.new("RIG_LAYOUT_"+SEL_OBJ.name, amtas)
+
+ ##LINK A LA ESCENA
+ scn = bpy.context.scene
+ scn.objects.link(obas)
+ scn.objects.active = obas
+ obas.select = True
+
+ ## CREO DATA PARA SLIDERS
+ ## creo data para los contenedores
+ verticess = [(-.1,1,0),(.1,1,0),(.1,0,0),(-.1,0,0)]
+ edgess = [(0,1),(1,2),(2,3),(3,0)]
+ mesh = bpy.data.meshes.new("%s_data_container" % (SEL_OBJ))
+ object = bpy.data.objects.new("GRAPHIC_CONTAINER_AS", mesh)
+ bpy.context.scene.objects.link(object)
+ mesh.from_pydata(verticess,edgess,[])
+
+ eval(EDITMODE)
+ gx = 0
+ gy = 0
+
+ for keyblock in LISTA_KEYS:
+ if keyblock.name[-2:] != "_L":
+ if keyblock.name[-2:] != "_R":
+ ## OBJETO ACTIVO
+ scn.objects.active = obas
+ eval(EDITMODE)
+
+ ##CREA HUESOS
+ bone = amtas.edit_bones.new(keyblock.name)
+ bone.head = (gx,0,0)
+ bone.tail = (gx,0,1)
+
+ bonectrl = amtas.edit_bones.new(keyblock.name+"_CTRL")
+ bonectrl.head = (gy,0,0)
+ bonectrl.tail = (gy,0,0.2)
+
+ ##EMPARENTA HUESOS
+ ## EMPARENTO
+ obas.data.edit_bones[bonectrl.name].parent = obas.data.edit_bones[bone.name]
+ bpy.context.scene.objects.active = obas
+
+ ##DESELECCIONA (modo edit)
+ bpy.ops.armature.select_all(action="DESELECT")
+
+ ##CREA DRIVERS Y LOS CONECTA
+ DR1 = keyblock.driver_add("value")
+ DR1.driver.expression = "var"
+ VAR2 = DR1.driver.variables.new()
+ VAR2.targets[0].id = obas
+ VAR2.targets[0].bone_target = bonectrl.name
+ VAR2.type = 'TRANSFORMS'
+ VAR2.targets[0].transform_space = "LOCAL_SPACE"
+ VAR2.targets[0].transform_type = "LOC_Y"
+
+ eval(POSEMODE)
+
+ ## SETEO ICONOS
+ obas.pose.bones[keyblock.name].custom_shape = object
+ obas.pose.bones[keyblock.name+"_CTRL"].custom_shape = object
+
+ ## SETEO CONSTRAINTS
+
+ bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones.active = bpy.data.objects["RIG_LAYOUT_"+SEL_OBJ.name].data.bones[keyblock.name+"_CTRL"]
+ ## SUMO CONSTRAINT
+ eval(POSEMODE)
+ CNS = obas.pose.bones[keyblock.name+"_CTRL"].constraints.new(type='LIMIT_LOCATION')
+ CNS.min_x = 0
+ CNS.use_min_x = 1
+ CNS.min_z = 0
+ CNS.use_min_z = 1
+ CNS.min_y = 0
+ CNS.use_min_y = 1
+
+ CNS.max_x = 0
+ CNS.use_max_x = 1
+ CNS.max_z = 0
+ CNS.use_max_z = 1
+ CNS.max_y = 1
+ CNS.use_max_y = 1
+
+ CNS.owner_space = "LOCAL"
+ CNS.use_transform_limit = True
+
+ ## PARA QUE EL TEXTO FUNCIONE PASAMOS A OBJECT MODE
+ eval(OBJECTMODE)
+
+ ## TEXTOS
+ ## creo tipografias
+ bpy.ops.object.text_add(location=(0,0,0))
+ gx = gx+2.2
+ gy = gy+2.2
+ texto = bpy.context.object
+ texto.data.body = keyblock.name
+ texto.name = "TEXTO_"+keyblock.name
+
+ texto.rotation_euler[0] = math.pi/2
+ texto.location.x = -.15
+ texto.location.z = -.15
+ texto.data.size = .2
+
+ CNS = texto.constraints.new(type="COPY_LOCATION")
+ CNS.target = obas
+ CNS.subtarget = obas.pose.bones[keyblock.name].name
+ CNS.use_offset = True
+
+
+
+ return {'FINISHED'}
+
+
+##------------------------ SAVE INCREMENTAL ------------------------
+
+class saveIncremental(bpy.types.Operator):
+ bl_idname = "file.save_incremental_osc"
+ bl_label = "Save Incremental File"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self, context):
+
+ # SI POSEE _V
+ filepath = bpy.data.filepath
+
+ if filepath.count("_v"):
+ strnum = filepath.rpartition("_v")[-1].rpartition(".blend")[0]
+ intnum = int(strnum)
+ modnum = strnum.replace(str(intnum),str(intnum+1))
+ output = filepath.replace(strnum,modnum)
+ bpy.ops.wm.save_as_mainfile(filepath=output)
+
+ else:
+ output = filepath.rpartition(".blend")[0]+"_v01"
+ bpy.ops.wm.save_as_mainfile(filepath=output)
+
+ return {'FINISHED'}
+
+##------------------------ REPLACE FILE PATHS ------------------------
+
+bpy.types.Scene.oscSearchText = bpy.props.StringProperty(default="Search Text")
+bpy.types.Scene.oscReplaceText = bpy.props.StringProperty(default="Replace Text")
+
+class replaceFilePath(bpy.types.Operator):
+ bl_idname = "file.replace_file_path_osc"
+ bl_label = "Replace File Path"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self, context):
+ TEXTSEARCH = bpy.context.scene.oscSearchText
+ TEXTREPLACE = bpy.context.scene.oscReplaceText
+
+ for image in bpy.data.images:
+ image.filepath = image.filepath.replace(TEXTSEARCH,TEXTREPLACE)
+
+ return {'FINISHED'}
+
+
+##------------------------ DUPLICATE OBJECTS SYMMETRY ------------------------
+
+def duplicateSymmetrical (self, disconect):
+ for objeto in bpy.context.selected_objects:
+
+ OBSEL = objeto
+
+ #DESELECT AND SELECT OBJETO
+ bpy.ops.object.select_all(action='DESELECT')
+ objeto.select = 1
+ bpy.context.scene.objects.active = objeto
+
+ #DUPLICA
+ bpy.ops.object.duplicate(linked=1)
+
+ #OBJETO ACTIVO
+ OBDUP=bpy.context.active_object
+
+ print(OBDUP)
+
+ #SUMA DRIVER
+ OBDUP.driver_add("location")
+
+ ## LOCATIONS
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[0].driver.expression = "-var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[0].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[0].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[0].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[0].driver.variables[0].targets[0].transform_type = 'LOC_X'
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[1].driver.expression = "var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[1].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[1].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[1].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[1].driver.variables[0].targets[0].transform_type = 'LOC_Y'
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[2].driver.expression = "var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[2].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[2].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[2].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[2].driver.variables[0].targets[0].transform_type = 'LOC_Z'
+
+ ## SCALE
+ OBDUP.driver_add("scale")
+
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[3].driver.expression = "-var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[3].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[3].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[3].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[3].driver.variables[0].targets[0].transform_type = 'SCALE_X'
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[4].driver.expression = "var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[4].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[4].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[4].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[4].driver.variables[0].targets[0].transform_type = 'SCALE_Y'
+
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[5].driver.expression = "var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[5].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[5].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[5].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[5].driver.variables[0].targets[0].transform_type = 'SCALE_Z'
+
+
+ ## ROTATION
+ OBDUP.driver_add("rotation_euler")
+
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[6].driver.expression = "var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[6].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[6].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[6].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[6].driver.variables[0].targets[0].transform_type = 'ROT_X'
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[7].driver.expression = "-var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[7].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[7].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[7].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[7].driver.variables[0].targets[0].transform_type = 'ROT_Y'
+
+
+ #EXPRESION
+ OBDUP.animation_data.drivers[8].driver.expression = "-var"
+ #CREA VARIABLE
+ OBDUP.animation_data.drivers[8].driver.variables.new()
+ #MODIFICO VARIABLE
+ OBDUP.animation_data.drivers[8].driver.variables[0].type = "TRANSFORMS"
+ OBDUP.animation_data.drivers[8].driver.variables[0].targets[0].id = objeto
+ OBDUP.animation_data.drivers[8].driver.variables[0].targets[0].transform_type = 'ROT_Z'
+
+ if disconect != True:
+ bpy.ops.object.make_single_user(obdata=True, object=True)
+ bpy.context.active_object.driver_remove("location")
+ bpy.context.active_object.driver_remove("rotation_euler")
+ bpy.context.active_object.driver_remove("scale")
+
+
+class oscDuplicateSymmetricalOp (bpy.types.Operator):
+ bl_idname = "object.duplicate_object_symmetry_osc"
+ bl_label = "Oscurart Duplicate Symmetrical"
+ bl_options = {"REGISTER", "UNDO"}
+
+ desconecta = bpy.props.BoolProperty(name="Keep Connection", default=True)
+
+ def execute(self,context):
+
+ duplicateSymmetrical(self, self.desconecta)
+
+ return {'FINISHED'}
+
+
+##---------------------------BATCH MAKER------------------
+
+
+def defoscBatchMaker(TYPE):
+ # REVISO SISTEMA
+ if sys.platform.startswith("w"):
+ print("PLATFORM: WINDOWS")
+ SYSBAR = "\\"
+ EXTSYS = ".bat"
+ QUOTES = '"'
+ else:
+ print("PLATFORM:LINUX")
+ SYSBAR = "/"
+ EXTSYS = ".sh"
+ QUOTES = ''
+
+ # CREO VARIABLES
+ FILENAME = bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0]
+ BINDIR = bpy.app[4]
+ SHFILE = bpy.data.filepath.rpartition(SYSBAR)[0] + SYSBAR + FILENAME + EXTSYS
+ FILEBATCH = open(SHFILE,"w")
+
+ # SI ES LINUX LE DOY PERMISOS CHMOD
+ if EXTSYS == ".sh":
+ try:
+ os.chmod(SHFILE, stat.S_IRWXU)
+ except:
+ print("** Oscurart Batch maker can not modify the permissions.")
+
+ # DEFINO ARCHIVO DE BATCH
+ FILEBATCH.writelines("%s%s%s -b %s -x 1 -o %s -P %s%s.py -s %s -e %s -a" % (QUOTES,BINDIR,QUOTES,bpy.data.filepath,bpy.context.scene.render.filepath,bpy.data.filepath.rpartition(SYSBAR)[0]+SYSBAR,TYPE,str(bpy.context.scene.frame_start),str(bpy.context.scene.frame_end)) )
+ FILEBATCH.close()
+
+
+ # DEFINO LOS ARCHIVOS DE SCRIPT
+
+ RLATFILE = "%s%sosRlat.py" % (bpy.data.filepath.rpartition(SYSBAR)[0] , SYSBAR )
+ if not os.path.isfile(RLATFILE):
+ FILESC = open(RLATFILE,"w")
+ if EXTSYS == ".sh":
+ try:
+ os.chmod(RLATFILE, stat.S_IRWXU)
+ except:
+ print("** Oscurart Batch maker can not modify the permissions.")
+ FILESC.writelines("import bpy \nbpy.ops.render.render_all_scenes_osc()\nbpy.ops.wm.quit_blender()")
+ FILESC.close()
+ else:
+ print("The All Python files Skips: Already exist!")
+
+ RSLATFILE = "%s%sosRSlat.py" % (bpy.data.filepath.rpartition(SYSBAR)[0] , SYSBAR)
+ if not os.path.isfile(RSLATFILE):
+ FILESSC = open(RSLATFILE,"w")
+ if EXTSYS == ".sh":
+ try:
+ os.chmod(RSLATFILE, stat.S_IRWXU)
+ except:
+ print("** Oscurart Batch maker can not modify the permissions.")
+ FILESSC.writelines("import bpy \nbpy.ops.render.render_selected_scenes_osc()\nbpy.ops.wm.quit_blender()")
+ FILESSC.close()
+ else:
+ print("The Selected Python files Skips: Already exist!")
+
+class oscBatchMaker (bpy.types.Operator):
+ bl_idname = "file.create_batch_maker_osc"
+ bl_label = "Make render batch"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ type = bpy.props.EnumProperty(
+ name="Render Mode",
+ description="Select Render Mode.",
+ items=(('osRlat', "All Scenes", "Render All Layers At Time"),
+ ('osRSlat', "Selected Scenes", "Render Only The Selected Scenes")),
+ default='osRlat',
+ )
+
+
+ def execute(self,context):
+ defoscBatchMaker(self.type)
+ return {'FINISHED'}
+
+
+##---------------------------REMOVE MODIFIERS Y APPLY MODIFIERS------------------
+
+class oscRemModifiers (bpy.types.Operator):
+ bl_idname = "object.modifiers_remove_osc"
+ bl_label = "Remove modifiers"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+ for objeto in bpy.context.selected_objects:
+ for modificador in objeto.modifiers:
+ print(modificador.type)
+ bpy.context.scene.objects.active=objeto
+ bpy.ops.object.modifier_remove(modifier=modificador.name)
+ return {'FINISHED'}
+
+class oscApplyModifiers (bpy.types.Operator):
+ bl_idname = "object.modifiers_apply_osc"
+ bl_label = "Apply modifiers"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+ for objeto in bpy.context.selected_objects:
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.context.scene.objects.active=objeto
+ objeto.select = True
+ if objeto.data.users >= 2:
+ bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', object=True, obdata=True, material=False, texture=False, animation=False)
+ for modificador in objeto.modifiers:
+ try:
+ bpy.ops.object.modifier_apply(apply_as="DATA", modifier=modificador.name)
+ except:
+ bpy.ops.object.modifier_remove(modifier=modificador.name)
+ print("* Modifier %s skipping apply" % (modificador.name))
+
+ return {'FINISHED'}
+
+
+##---------------------------SHAPES TO OBJECTS------------------
+
+class ShapeToObjects (bpy.types.Operator):
+ bl_idname = "object.shape_key_to_objects_osc"
+ bl_label = "Shapes To Objects"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+ OBJACT=bpy.context.active_object
+ for SHAPE in OBJACT.data.shape_keys.key_blocks[:]:
+ print(SHAPE.name)
+ bpy.ops.object.shape_key_clear()
+ SHAPE.value=1
+ mesh=OBJACT.to_mesh(bpy.context.scene, True, 'PREVIEW')
+ object=bpy.data.objects.new(SHAPE.name, mesh)
+ bpy.context.scene.objects.link(object)
+ return {'FINISHED'}
+
+
+##--------------------------OVERRIDES-----------------------------
+
+## PARA ESCENAS NUEVAS
+
+class OverridesOp (bpy.types.Operator):
+ bl_idname = "render.overrides_set_list"
+ bl_label = "Overrides set list"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+ for scene in bpy.data.scenes[:]:
+ try:
+ scene['OVERRIDE']
+ except:
+ scene['OVERRIDE']="[]"
+ return {'FINISHED'}
+
+
+###------------------------IMPORT EXPORT GROUPS--------------------
+
+class OscExportVG (bpy.types.Operator):
+ bl_idname = "file.export_groups_osc"
+ bl_label = "Export Groups"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+
+ OBSEL=bpy.context.active_object
+
+ if os.sys.platform.count("win"):
+ print("WINDOWS")
+ BAR = "\\"
+ else:
+ print("LINUX")
+ BAR = "/"
+ # VARIABLES
+ FILEPATH = bpy.data.filepath
+ FILE = open(FILEPATH.rpartition(BAR)[0] + BAR+OBSEL.name + ".xml", mode = "w")
+ VERTLIST = []
+
+ LENVER = len(OBSEL.data.vertices)
+
+ for VG in OBSEL.vertex_groups:
+ BONELIST = []
+ for VERTICE in range(0,LENVER):
+ try:
+ BONELIST.append((VERTICE,VG.weight(VERTICE),VG.name,))
+ except:
+ pass
+ VERTLIST.append(BONELIST)
+
+ ## CREO LA LISTA CON LOS NOMBRES DE LOS GRUPOS
+ NAMEGROUPLIST=[]
+ for VG in OBSEL.vertex_groups:
+ NAMEGROUPLIST.append(VG.name)
+
+ ## AGREGO LOS NOMBRES A LA LISTA
+ VERTLIST.append(NAMEGROUPLIST)
+
+ ## GUARDO Y CIERRO
+ FILE.writelines(str(VERTLIST))
+ FILE.close()
+
+ ## ---- CREO OTRO ARCHIVO PARA LA DATA ----
+ # VARIABLES
+ FILEPATH = bpy.data.filepath
+ FILE = open(FILEPATH.rpartition(BAR)[0] + BAR + OBSEL.name + "_DATA.xml", mode = "w")
+
+ DATAVER = []
+
+ for VERT in OBSEL.data.vertices[:]:
+ TEMP = 0
+ VGTEMP = 0
+ LISTVGTEMP = []
+
+ for GROUP in VERT.groups[:]:
+ LISTVGTEMP.append((GROUP.group,VGTEMP))
+ VGTEMP += 1
+
+ LISTVGTEMP=sorted(LISTVGTEMP)
+ for GROUP in VERT.groups[:]:
+ DATAVER.append((VERT.index,TEMP,VERT.groups[LISTVGTEMP[TEMP][1]].weight))
+ TEMP += 1
+
+
+ ## GUARDO Y CIERRO
+ FILE.writelines(str(DATAVER))
+ FILE.close()
+
+ return {'FINISHED'}
+
+class OscImportVG (bpy.types.Operator):
+ bl_idname = "file.import_groups_osc"
+ bl_label = "Import Groups"
+ bl_options = {"REGISTER", "UNDO"}
+ def execute(self,context):
+
+ OBSEL = bpy.context.active_object
+ # AVERIGUO EL SISTEMA
+ if os.sys.platform.count("win"):
+ print("WINDOWS")
+ BAR = "\\"
+ else:
+ print("LINUX")
+ BAR = "/"
+ # VARIABLES
+ FILEPATH = bpy.data.filepath
+ FILE = open(FILEPATH.rpartition(BAR)[0] + BAR + OBSEL.name + ".xml", mode="r")
+ VERTLIST = FILE.readlines(0)
+ VERTLIST = eval(VERTLIST[0])
+ VERTLISTR = VERTLIST[:-1]
+ GROUPLIST = VERTLIST[-1:]
+ VGINDEX = 0
+
+ ## MODO OBJECT
+ bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+ for GROUP in GROUPLIST[0]:
+ #CREO GRUPO
+ bpy.ops.object.vertex_group_add()
+ #CAMBIO NOMBRE
+ OBSEL.vertex_groups[-1].name=GROUP
+
+
+
+ for VG in OBSEL.vertex_groups[:]:
+ # SETEO VG
+ bpy.ops.object.vertex_group_set_active(group=VG.name)
+ # EDIT
+ bpy.ops.object.mode_set(mode='EDIT')
+ # DESELECT
+ bpy.ops.mesh.select_all(action='DESELECT')
+ # OBJECT
+ bpy.ops.object.mode_set(mode='OBJECT')
+ # SELECCIONO LOS VERTICES
+ for VERTI in VERTLISTR[VG.index]:
+ OBSEL.data.vertices[VERTI[0]].select=1
+ ## SETEO EL VALOR DEL PESO
+ bpy.context.tool_settings.vertex_group_weight=1
+ # EDIT
+ bpy.ops.object.mode_set(mode='EDIT')
+ ## ASIGNO
+ bpy.ops.object.vertex_group_assign(new=False)
+
+ # CIERRO
+ FILE.close()
+
+
+ ## ----------- LEVANTO DATA ----
+ # VARIABLES
+ FILEPATH = bpy.data.filepath
+ FILE = open(FILEPATH.rpartition(BAR)[0]+BAR+OBSEL.name+"_DATA.xml", mode="r")
+ DATAPVER = FILE.readlines(0)
+ DATAPVER = eval(DATAPVER[0])
+
+ # PASO A MODO OBJECT
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ #for VERT in DATAPVER:
+ for VERT in DATAPVER:
+ OBSEL.data.vertices[VERT[0]].groups[VERT[1]].weight = VERT[2]
+
+ # CIERRO
+ FILE.close()
+
+
+ # PASO A MODO PINTURA DE PESO
+ bpy.ops.object.mode_set(mode='WEIGHT_PAINT')
+ return {'FINISHED'}
+
+
+## ------------------------------------ RELINK OBJECTS--------------------------------------
+
+
+def relinkObjects (self):
+
+ LISTSCENE=[]
+
+ for SCENE in bpy.data.scenes[:]:
+ if bpy.selection_osc[-1] in SCENE.objects[:]:
+ LISTSCENE.append(SCENE)
+
+ OBJECTS = bpy.selection_osc[:-1]
+ ACTOBJ = bpy.selection_osc[-1]
+ OBJSEL = bpy.selection_osc[:]
+
+ ## REMUEVO ESCENA ACTIVA
+ LISTSCENE.remove(bpy.context.scene)
+
+ ## DESELECT
+ bpy.ops.object.select_all(action='DESELECT')
+
+ ## SELECT
+ for OBJETO in OBJECTS:
+ if OBJETO.users != len(bpy.data.scenes):
+ print(OBJETO.name)
+ OBJETO.select = True
+
+ ## LINK
+ for SCENE in LISTSCENE:
+ bpy.ops.object.make_links_scene(scene=SCENE.name)
+
+ # REESTABLEZCO SELECCION
+ bpy.context.scene.objects.active=ACTOBJ
+ for OBJ in OBJSEL:
+ OBJ.select=True
+
+class OscRelinkObjectsBetween (bpy.types.Operator):
+ bl_idname = "objects.relink_objects_between_scenes"
+ bl_label = "Relink Objects Between Scenes"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ def execute (self, context):
+ relinkObjects(self)
+ return {'FINISHED'}
+
+
+## ------------------------------------ COPY GROUPS AND LAYERS--------------------------------------
+
+
+def CopyObjectGroupsAndLayers (self):
+
+ OBSEL=bpy.selection_osc[:]
+ GLOBALLAYERS=list(OBSEL[-1].layers[:])
+ ACTSCENE=bpy.context.scene
+ GROUPS=OBSEL[-1].users_group
+ ACTOBJ=OBSEL[-1]
+
+ for OBJECT in OBSEL[:-1]:
+ for scene in bpy.data.scenes[:]:
+
+ # SI EL OBJETO ACTIVO ESTA EN LA ESCENA
+ if ACTOBJ in scene.objects[:] and OBJECT in scene.objects[:]:
+ scene.object_bases[OBJECT.name].layers[:] = scene.object_bases[ACTOBJ.name].layers[:]
+ elif ACTOBJ not in scene.objects[:] and OBJECT in scene.objects[:]:
+ scene.object_bases[OBJECT.name].layers[:] = list(GLOBALLAYERS)
+
+ # REMUEVO DE TODO GRUPO
+ for GROUP in bpy.data.groups[:]:
+ if GROUP in OBJECT.users_group[:]:
+ GROUP.objects.unlink(OBJECT)
+
+ # INCLUYO OBJETO EN GRUPOS
+ for GROUP in GROUPS:
+ GROUP.objects.link(OBJECT)
+
+ bpy.context.window.screen.scene = ACTSCENE
+ bpy.context.scene.objects.active=ACTOBJ
+
+class OscCopyObjectGAL (bpy.types.Operator):
+ bl_idname = "objects.copy_objects_groups_layers"
+ bl_label = "Copy Groups And Layers"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ def execute (self, context):
+ CopyObjectGroupsAndLayers (self)
+ return {'FINISHED'}
+
+
+## ------------------------------------ APPLY AND RESTORE OVERRIDES --------------------------------------
+
+def DefOscApplyOverrides(self):
+ LISTMAT = []
+ PROPTOLIST = list(eval(bpy.context.scene['OVERRIDE']))
+ # REVISO SISTEMA
+ if sys.platform.startswith("w"):
+ print("PLATFORM: WINDOWS")
+ SYSBAR = "\\"
+ else:
+ print("PLATFORM:LINUX")
+ SYSBAR = "/"
+ FILEPATH=bpy.data.filepath
+ ACTIVEFOLDER=FILEPATH.rpartition(SYSBAR)[0]
+ ENTFILEPATH= "%s%s%s_OVERRIDE.xml" % (ACTIVEFOLDER, SYSBAR, bpy.context.scene.name)
+ XML=open(ENTFILEPATH ,mode="w")
+ ## GUARDO MATERIALES DE OBJETOS EN GRUPOS
+
+ LISTMAT = { OBJ : [SLOT.material for SLOT in OBJ.material_slots[:]] for OBJ in bpy.data.objects[:] if OBJ.type == "MESH" or OBJ.type == "META" or OBJ.type == "CURVE" }
+
+
+ for OVERRIDE in PROPTOLIST:
+ for OBJECT in bpy.data.groups[OVERRIDE[0]].objects[:]:
+ if OBJECT.type == "MESH" or OBJECT.type == "META" or OBJECT.type == "CURVE":
+ if len(OBJECT.material_slots) > 0:
+ for SLOT in OBJECT.material_slots[:]:
+ SLOT.material = bpy.data.materials[OVERRIDE[1]]
+ else:
+ print ("* %s have not Material Slots" % (OBJECT.name))
+
+
+ XML.writelines(str(LISTMAT))
+ XML.close()
+
+
+def DefOscRestoreOverrides(self):
+ # REVISO SISTEMA
+ if sys.platform.startswith("w"):
+ #print("PLATFORM: WINDOWS")
+ SYSBAR="\\"
+ else:
+ #print("PLATFORM:LINUX")
+ SYSBAR="/"
+
+ FILEPATH = bpy.data.filepath
+ ACTIVEFOLDER = FILEPATH.rpartition(SYSBAR)[0]
+ ENTFILEPATH = "%s%s%s_OVERRIDE.xml" % (ACTIVEFOLDER, SYSBAR, bpy.context.scene.name)
+ XML = open(ENTFILEPATH, mode="r")
+ RXML = XML.readlines(0)
+
+ LISTMAT = dict(eval(RXML[0]))
+
+ # RESTAURO MATERIALES DE OVERRIDES
+
+ for OBJ in LISTMAT:
+ if OBJ.type == "MESH" or OBJ.type == "META" or OBJ.type == "CURVE":
+ SLOTIND = 0
+ for SLOT in LISTMAT[OBJ]:
+ OBJ.material_slots[SLOTIND].material = SLOT
+ SLOTIND += 1
+
+ # CIERRO
+ XML.close()
+
+
+## HAND OPERATOR
+class OscApplyOverrides(bpy.types.Operator):
+ bl_idname = "render.apply_overrides"
+ bl_label = "Apply Overrides in this Scene"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ def execute (self, context):
+ DefOscApplyOverrides(self)
+ return {'FINISHED'}
+
+class OscRestoreOverrides(bpy.types.Operator):
+ bl_idname = "render.restore_overrides"
+ bl_label = "Restore Overrides in this Scene"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ def execute (self, context):
+ DefOscRestoreOverrides(self)
+ return {'FINISHED'}
+
+
+OVERRIDESSTATUS = False
+
+
+class OscOverridesOn(bpy.types.Operator):
+ bl_idname = "render.overrides_on"
+ bl_label = "Turn On Overrides"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def execute (self, context):
+
+ global OVERRIDESSTATUS
+
+ if OVERRIDESSTATUS == False:
+ bpy.app.handlers.render_pre.append(DefOscApplyOverrides)
+ bpy.app.handlers.render_post.append(DefOscRestoreOverrides)
+ OVERRIDESSTATUS = True
+ print("Overrides on!")
+ else:
+ bpy.app.handlers.render_pre.remove(DefOscApplyOverrides)
+ bpy.app.handlers.render_post.remove(DefOscRestoreOverrides)
+ OVERRIDESSTATUS = False
+ print("Overrides off!")
+ return {'FINISHED'}
+
+
+
+## ------------------------------------ CHECK OVERRIDES --------------------------------------
+
+class OscCheckOverrides (bpy.types.Operator):
+ bl_idname = "render.check_overrides"
+ bl_label = "Check Overrides"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ def execute (self, context):
+ GROUPI = False
+ GLOBAL = 0
+ GLOBALERROR = 0
+
+ print("==== STARTING CHECKING ====")
+ print("")
+
+ for SCENE in bpy.data.scenes[:]:
+ MATLIST = []
+ MATI = False
+
+ for MATERIAL in bpy.data.materials[:]:
+ MATLIST.append(MATERIAL.name)
+
+ GROUPLIST=[]
+ for GROUP in bpy.data.groups[:]:
+ if GROUP.users > 0:
+ GROUPLIST.append(GROUP.name)
+
+ print(" %s Scene is checking" % (SCENE.name))
+
+ for OVERRIDE in list(eval(SCENE['OVERRIDE'])):
+ # REVISO OVERRIDES EN GRUPOS
+ if OVERRIDE[0] in GROUPLIST:
+ pass
+ else:
+ print("** %s group are in conflict." % (OVERRIDE[0]))
+ GROUPI = True
+ GLOBALERROR += 1
+ # REVISO OVERRIDES EN GRUPOS
+ if OVERRIDE[1] in MATLIST:
+ pass
+ else:
+ print("** %s material are in conflict." % (OVERRIDE[1]))
+ MATI = True
+ GLOBALERROR += 1
+
+ if MATI is False:
+ print("-- Materials are ok.")
+ else:
+ GLOBAL+=1
+ if GROUPI is False:
+ print("-- Groups are ok.")
+ else:
+ GLOBAL+=1
+
+ if GLOBAL < 1:
+ self.report({'INFO'}, "Materials And Groups are Ok")
+ if GLOBALERROR > 0:
+ self.report({'WARNING'}, "Override Error: Look in the Console")
+ print("")
+
+ return {'FINISHED'}
+
+
+## ------------------------------------ SELECTION --------------------------------------
+bpy.selection_osc=[]
+
+def select_osc():
+ if bpy.context.mode == "OBJECT":
+ obj = bpy.context.object
+ sel = len(bpy.context.selected_objects)
+
+ if sel == 0:
+ bpy.selection_osc=[]
+ else:
+ if sel == 1:
+ bpy.selection_osc=[]
+ bpy.selection_osc.append(obj)
+ elif sel > len(bpy.selection_osc):
+ for sobj in bpy.context.selected_objects:
+ if (sobj in bpy.selection_osc) == False:
+ bpy.selection_osc.append(sobj)
+
+ elif sel < len(bpy.selection_osc):
+ for it in bpy.selection_osc:
+ if (it in bpy.context.selected_objects) == False:
+ bpy.selection_osc.remove(it)
+
+class OscSelection(bpy.types.Header):
+ bl_label = "Selection Osc"
+ bl_space_type = "VIEW_3D"
+
+ def __init__(self):
+ select_osc()
+
+ def draw(self, context):
+ """
+ layout = self.layout
+ row = layout.row()
+ row.label("Sels: "+str(len(bpy.selection_osc)))
+ """
+
+
+## ------------------------------------ RESYM MESH--------------------------------------
+
+
+def reSymSave (self):
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ BM = bmesh.from_edit_mesh(bpy.context.object.data)
+
+ L = {VERT.index : [VERT.co[0],VERT.co[1],VERT.co[2]] for VERT in BM.verts[:] if VERT.co[0] < 0.0001}
+ R = {VERT.index : [-VERT.co[0],VERT.co[1],VERT.co[2]] for VERT in BM.verts[:] if VERT.co[0] > -0.0001}
+
+ SYMAP = {VERTL : VERTR for VERTR in R for VERTL in L if R[VERTR] == L[VERTL] }
+
+ if sys.platform.startswith("w"):
+ SYSBAR = "\\"
+ else:
+ SYSBAR = "/"
+
+ FILEPATH=bpy.data.filepath
+ ACTIVEFOLDER=FILEPATH.rpartition(SYSBAR)[0]
+ ENTFILEPATH= "%s%s%s_%s_SYM_TEMPLATE.xml" % (ACTIVEFOLDER, SYSBAR, bpy.context.scene.name, bpy.context.object.name)
+ XML=open(ENTFILEPATH ,mode="w")
+
+ XML.writelines(str(SYMAP))
+ XML.close()
+ SYMAP.clear()
+
+def reSymMesh (self, SELECTED, SIDE):
+
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ BM = bmesh.from_edit_mesh(bpy.context.object.data)
+
+ if sys.platform.startswith("w"):
+ SYSBAR = "\\"
+ else:
+ SYSBAR = "/"
+
+ FILEPATH=bpy.data.filepath
+ ACTIVEFOLDER=FILEPATH.rpartition(SYSBAR)[0]
+ ENTFILEPATH= "%s%s%s_%s_SYM_TEMPLATE.xml" % (ACTIVEFOLDER, SYSBAR, bpy.context.scene.name, bpy.context.object.name)
+ XML=open(ENTFILEPATH ,mode="r")
+
+ SYMAP = eval(XML.readlines()[0])
+
+ if SIDE == "+-":
+ if SELECTED:
+ for VERT in SYMAP:
+ if BM.verts[SYMAP[VERT]].select:
+ if VERT == SYMAP[VERT]:
+ BM.verts[VERT].co[0] = 0
+ BM.verts[VERT].co[1] = BM.verts[SYMAP[VERT]].co[1]
+ BM.verts[VERT].co[2] = BM.verts[SYMAP[VERT]].co[2]
+ else:
+ BM.verts[VERT].co[0] = -BM.verts[SYMAP[VERT]].co[0]
+ BM.verts[VERT].co[1] = BM.verts[SYMAP[VERT]].co[1]
+ BM.verts[VERT].co[2] = BM.verts[SYMAP[VERT]].co[2]
+ else:
+ for VERT in SYMAP:
+ if VERT == SYMAP[VERT]:
+ BM.verts[VERT].co[0] = 0
+ BM.verts[VERT].co[1] = BM.verts[SYMAP[VERT]].co[1]
+ BM.verts[VERT].co[2] = BM.verts[SYMAP[VERT]].co[2]
+ else:
+ BM.verts[VERT].co[0] = -BM.verts[SYMAP[VERT]].co[0]
+ BM.verts[VERT].co[1] = BM.verts[SYMAP[VERT]].co[1]
+ BM.verts[VERT].co[2] = BM.verts[SYMAP[VERT]].co[2]
+ else:
+ if SELECTED:
+ for VERT in SYMAP:
+ if BM.verts[VERT].select:
+ if VERT == SYMAP[VERT]:
+ BM.verts[SYMAP[VERT]].co[0] = 0
+ BM.verts[SYMAP[VERT]].co[1] = BM.verts[VERT].co[1]
+ BM.verts[SYMAP[VERT]].co[2] = BM.verts[VERT].co[2]
+ else:
+ BM.verts[SYMAP[VERT]].co[0] = -BM.verts[VERT].co[0]
+ BM.verts[SYMAP[VERT]].co[1] = BM.verts[VERT].co[1]
+ BM.verts[SYMAP[VERT]].co[2] = BM.verts[VERT].co[2]
+ else:
+ for VERT in SYMAP:
+ if VERT == SYMAP[VERT]:
+ BM.verts[SYMAP[VERT]].co[0] = 0
+ BM.verts[SYMAP[VERT]].co[1] = BM.verts[VERT].co[1]
+ BM.verts[SYMAP[VERT]].co[2] = BM.verts[VERT].co[2]
+ else:
+ BM.verts[SYMAP[VERT]].co[0] = -BM.verts[VERT].co[0]
+ BM.verts[SYMAP[VERT]].co[1] = BM.verts[VERT].co[1]
+ BM.verts[SYMAP[VERT]].co[2] = BM.verts[VERT].co[2]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ XML.close()
+ SYMAP.clear()
+
+
+class OscResymSave (bpy.types.Operator):
+ bl_idname = "mesh.resym_save_map"
+ bl_label = "Resym save XML Map"
+ bl_options = {"REGISTER", "UNDO"}
+
+
+ def execute (self, context):
+ reSymSave(self)
+ return {'FINISHED'}
+
+class OscResymMesh (bpy.types.Operator):
+ bl_idname = "mesh.resym_mesh"
+ bl_label = "Resym save Apply XML"
+ bl_options = {"REGISTER", "UNDO"}
+
+ selected=bpy.props.BoolProperty(default=False, name="Only Selected")
+
+ side = bpy.props.EnumProperty(
+ name="Side_",
+ description="Select Side.",
+ items=(('+-', "+X to -X", "+X to -X"),
+ ('-+', "-X to +X", "-X to +X")),
+ default='+-',
+ )
+
+ def execute (self, context):
+ reSymMesh(self, self.selected,self.side)
+ return {'FINISHED'}
+
+##=============== DISTRIBUTE ======================
+
+
+def ObjectDistributeOscurart (self, X, Y, Z):
+ if len(bpy.selection_osc[:]) > 1:
+ # VARIABLES
+ dif = bpy.selection_osc[-1].location-bpy.selection_osc[0].location
+ chunkglobal = dif/(len(bpy.selection_osc[:])-1)
+ chunkx = 0
+ chunky = 0
+ chunkz = 0
+ deltafst = bpy.selection_osc[0].location
+
+ #ORDENA
+ for OBJECT in bpy.selection_osc[:]:
+ if X: OBJECT.location.x=deltafst[0]+chunkx
+ if Y: OBJECT.location[1]=deltafst[1]+chunky
+ if Z: OBJECT.location.z=deltafst[2]+chunkz
+ chunkx+=chunkglobal[0]
+ chunky+=chunkglobal[1]
+ chunkz+=chunkglobal[2]
+ else:
+ self.report({'ERROR'}, "Selection is only 1!")
+
+class DialogDistributeOsc(bpy.types.Operator):
+ bl_idname = "object.distribute_osc"
+ bl_label = "Distribute Objects"
+ Boolx = bpy.props.BoolProperty(name="X")
+ Booly = bpy.props.BoolProperty(name="Y")
+ Boolz = bpy.props.BoolProperty(name="Z")
+
+ def execute(self, context):
+ ObjectDistributeOscurart(self, self.Boolx,self.Booly,self.Boolz)
+ return {'FINISHED'}
+ def invoke(self, context, event):
+ self.Boolx = True
+ self.Booly = True
+ self.Boolz = True
+ return context.window_manager.invoke_props_dialog(self)
+
+##--------------------------------- OVERRIDES PANEL ----------------------------------
+
+class OscOverridesGUI(bpy.types.Panel):
+ bl_label = "Oscurart Material Overrides"
+ bl_idname = "Oscurart Overrides List"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "render"
+ def draw(self,context):
+
+ layout = self.layout
+ col = layout.column(align=1)
+ colrow = col.row(align=1)
+ colrow.operator("render.overrides_add_slot", icon = "ZOOMIN")
+ colrow.operator("render.overrides_remove_slot", icon = "ZOOMOUT")
+ col.operator("render.overrides_transfer", icon = "SHORTDISPLAY")
+ i = 0
+ for m in bpy.context.scene.ovlist:
+ colrow = col.row(align=1)
+ colrow.prop_search(m, "grooverride", bpy.data, "groups", text= "")
+ colrow.prop_search(m, "matoverride", bpy.data, "materials", text= "")
+ if i != len(bpy.context.scene.ovlist)-1:
+ pa = colrow.operator("ovlist.move_down", text="", icon="TRIA_DOWN")
+ pa.index = i
+ if i > 0:
+ p = colrow.operator("ovlist.move_up", text="", icon="TRIA_UP")
+ p.index = i
+ pb = colrow.operator("ovlist.kill", text="", icon="X")
+ pb.index = i
+ i+=1
+
+class OscOverridesUp (bpy.types.Operator):
+ bl_idname = 'ovlist.move_up'
+ bl_label = 'Move Override up'
+ bl_options = {'INTERNAL'}
+
+ index = bpy.props.IntProperty(min=0)
+
+ @classmethod
+ def poll(self,context):
+ return len(context.scene.ovlist)
+ def execute(self,context):
+ ovlist = context.scene.ovlist
+ ovlist.move(self.index,self.index-1)
+
+ return {'FINISHED'}
+
+class OscOverridesDown (bpy.types.Operator):
+ bl_idname = 'ovlist.move_down'
+ bl_label = 'Move Override down'
+ bl_options = {'INTERNAL'}
+
+ index = bpy.props.IntProperty(min=0)
+
+ @classmethod
+ def poll(self,context):
+ return len(context.scene.ovlist)
+ def execute(self,context):
+ ovlist = context.scene.ovlist
+ ovlist.move(self.index,self.index+1)
+ return {'FINISHED'}
+
+class OscOverridesKill (bpy.types.Operator):
+ bl_idname = 'ovlist.kill'
+ bl_label = 'Kill Override'
+ bl_options = {'INTERNAL'}
+
+ index = bpy.props.IntProperty(min=0)
+
+ @classmethod
+ def poll(self,context):
+ return len(context.scene.ovlist)
+ def execute(self,context):
+ ovlist = context.scene.ovlist
+ ovlist.remove(self.index)
+ return {'FINISHED'}
+
+
+class OscOverridesProp(bpy.types.PropertyGroup):
+ matoverride = bpy.props.StringProperty()
+ grooverride = bpy.props.StringProperty()
+
+bpy.utils.register_class(OscOverridesGUI)
+bpy.utils.register_class(OscOverridesProp)
+bpy.types.Scene.ovlist = bpy.props.CollectionProperty(type=OscOverridesProp)
+
+
+class OscTransferOverrides (bpy.types.Operator):
+ """Tooltip"""
+ bl_idname = "render.overrides_transfer"
+ bl_label = "Transfer Overrides"
+
+ def execute(self, context):
+ # CREO LISTA
+ OSCOV = [[OVERRIDE.grooverride,OVERRIDE.matoverride]for OVERRIDE in bpy.context.scene.ovlist[:] if OVERRIDE.matoverride != "" if OVERRIDE.grooverride != ""]
+
+ bpy.context.scene["OVERRIDE"] = str(OSCOV)
+ return {'FINISHED'}
+
+class OscAddOverridesSlot (bpy.types.Operator):
+ """Tooltip"""
+ bl_idname = "render.overrides_add_slot"
+ bl_label = "Add Override Slot"
+
+ def execute(self, context):
+ prop = bpy.context.scene.ovlist.add()
+ prop.matoverride = ""
+ prop.grooverride = ""
+ return {'FINISHED'}
+
+class OscRemoveOverridesSlot (bpy.types.Operator):
+ """Tooltip"""
+ bl_idname = "render.overrides_remove_slot"
+ bl_label = "Remove Override Slot"
+
+ def execute(self, context):
+ bpy.context.scene.ovlist.remove(len(bpy.context.scene.ovlist)-1)
+ return {'FINISHED'}
+
+bpy.utils.register_class(OscTransferOverrides)
+bpy.utils.register_class(OscAddOverridesSlot)
+bpy.utils.register_class(OscRemoveOverridesSlot)
+
+## --------------------------------------PYTHON BATCH--------------------------------------------------------
+def defoscPythonBatchMaker(BATCHTYPE,SIZE):
+ # REVISO SISTEMA
+ if sys.platform.startswith("w"):
+ print("PLATFORM: WINDOWS")
+ SYSBAR = "\\"
+ EXTSYS = ".bat"
+ QUOTES = '"'
+ else:
+ print("PLATFORM:LINUX")
+ SYSBAR = "/"
+ EXTSYS = ".sh"
+ QUOTES = ''
+
+ # CREO VARIABLES
+ FILENAME = bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0]
+ SHFILE = "%s%s%s_PythonSecureBatch.py" % (bpy.data.filepath.rpartition(SYSBAR)[0],SYSBAR,FILENAME)
+ BATCHLOCATION = "%s%s%s%s" % (bpy.data.filepath.rpartition(SYSBAR)[0],SYSBAR,FILENAME,EXTSYS)
+
+ FILEBATCH = open(SHFILE,"w")
+
+ if EXTSYS == ".bat":
+ BATCHLOCATION=BATCHLOCATION.replace("\\","/")
+
+ # SI EL OUTPUT TIENE DOBLE BARRA LA REEMPLAZO
+ FRO=bpy.context.scene.render.filepath
+ if bpy.context.scene.render.filepath.count("//"):
+ FRO=bpy.context.scene.render.filepath.replace("//", bpy.data.filepath.rpartition(SYSBAR)[0]+SYSBAR)
+ if EXTSYS == ".bat":
+ FRO=FRO.replace("\\","/")
+
+
+
+ #CREO BATCH
+ bpy.ops.file.create_batch_maker_osc(type=BATCHTYPE)
+
+ SCRIPT = "import os \nREPITE= True \nBAT= '%s'\nSCENENAME ='%s' \nDIR='%s%s' \ndef RENDER():\n os.system(BAT) \ndef CLEAN():\n global REPITE\n FILES = [root+'/'+FILE for root, dirs, files in os.walk(os.getcwd()) if len(files) > 0 for FILE in files if FILE.count('~') == False]\n RESPUESTA=False\n for FILE in FILES:\n if os.path.getsize(FILE) < %s:\n os.remove(FILE)\n RESPUESTA= True\n if RESPUESTA:\n REPITE=True\n else:\n REPITE=False\nREPITE=True\nwhile REPITE:\n global REPITE\n REPITE=False\n RENDER()\n os.chdir(DIR)\n CLEAN()" % (BATCHLOCATION,FILENAME,FRO,FILENAME,SIZE)
+
+
+ # DEFINO ARCHIVO DE BATCH
+ FILEBATCH.writelines(SCRIPT)
+ FILEBATCH.close()
+
+
+ # ARCHIVO CALL
+ CALLFILENAME = bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0]
+ CALLFILE = "%s%s%s_CallPythonSecureBatch%s" % (bpy.data.filepath.rpartition(SYSBAR)[0],SYSBAR,CALLFILENAME,EXTSYS)
+ CALLFILEBATCH = open(CALLFILE,"w")
+
+ SCRIPT = "python %s" % (SHFILE)
+ CALLFILEBATCH.writelines(SCRIPT)
+ CALLFILEBATCH.close()
+
+ if EXTSYS == ".sh":
+ try:
+ os.chmod(CALLFILE, stat.S_IRWXU)
+ os.chmod(SHFILE, stat.S_IRWXU)
+ except:
+ print("** Oscurart Batch maker can not modify the permissions.")
+
+
+
+class oscPythonBatchMaker (bpy.types.Operator):
+ bl_idname = "file.create_batch_python"
+ bl_label = "Make Batch Python"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ size = bpy.props.IntProperty(name="Size in Bytes", default=10, min=0)
+
+ type = bpy.props.EnumProperty(
+ name="Render Mode",
+ description="Select Render Mode.",
+ items=(('osRlat', "All Scenes", "Render All Layers At Time"),
+ ('osRSlat', "Selected Scenes", "Render Only The Selected Scenes")),
+ default='osRlat',
+ )
+
+ def execute(self,context):
+ defoscPythonBatchMaker(self.type, self.size)
+ return {'FINISHED'}
+
+##======================================================================================FIN DE SCRIPTS
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/particle_hair_lab.py b/release/scripts/addons_contrib/particle_hair_lab.py
new file mode 100644
index 0000000..100db79
--- /dev/null
+++ b/release/scripts/addons_contrib/particle_hair_lab.py
@@ -0,0 +1,1503 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Grass Lab",
+ "author": "Ondrej Raha(lokhorn), meta-androcto",
+ "version": (0,5),
+ "blender": (2, 60, 0),
+ "location": "View3D > Tool Shelf > Grass Preset Panel",
+ "description": "Creates particle grass with material",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Object/Hair_Lab",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=30238",
+ "category": "Object"}
+
+
+import bpy
+from bpy.props import *
+
+# Returns the action we want to take
+def getActionToDo(obj):
+ if not obj or obj.type != 'MESH':
+ return 'NOT_OBJ_DO_NOTHING'
+ elif obj.type == 'MESH':
+ return 'GENERATE'
+ else:
+ return "DO_NOTHING"
+
+# TO DO
+"""
+class saveSelectionPanel(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+ bl_label = "Selection Save"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_context = "particlemode"
+
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+
+ col.operator("save.selection", text="Save Selection 1")
+"""
+######GRASS########################
+class grassLabPanel(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Grass Lab"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ active_obj = bpy.context.active_object
+ active_scn = bpy.context.scene.name
+ layout = self.layout
+ col = layout.column(align=True)
+
+ WhatToDo = getActionToDo(active_obj)
+
+
+ if WhatToDo == "GENERATE":
+ col.operator("grass.generate_grass", text="Create grass")
+
+ col.prop(context.scene, "grass_type")
+ else:
+ col.label(text="Select mesh object")
+
+ if active_scn == "TestgrassScene":
+ col.operator("grass.switch_back", text="Switch back to scene")
+ else:
+ col.operator("grass.test_scene", text="Create Test Scene")
+
+# TO DO
+"""
+class saveSelection(bpy.types.Operator):
+ bl_idname = "save.selection"
+ bl_label = "Save Selection"
+ bl_description = "Save selected particles"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+
+ return {'FINISHED'}
+"""
+class testScene1(bpy.types.Operator):
+ bl_idname = "grass.switch_back"
+ bl_label = "Switch back to scene"
+ bl_description = "If you want keep this scene, switch scene in info window"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ scene = bpy.context.scene
+ bpy.data.scenes.remove(scene)
+
+ return {'FINISHED'}
+
+
+class testScene2(bpy.types.Operator):
+ bl_idname = "grass.test_scene"
+ bl_label = "Create test scene"
+ bl_description = "You can switch scene in info panel"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+# add new scene
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ scene.name = "TestgrassScene"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("grassWorld")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+
+# add text
+ bpy.ops.object.text_add(location=(-0.292,0,-0.152), rotation =(1.571,0,0))
+ text = bpy.context.active_object
+ text.scale = (0.05,0.05,0.05)
+ text.data.body = "Grass Lab"
+
+# add material to text
+ textMaterial = bpy.data.materials.new('textMaterial')
+ text.data.materials.append(textMaterial)
+ textMaterial.use_shadeless = True
+
+# add camera
+ bpy.ops.object.camera_add(location = (0,-1,0),rotation = (1.571,0,0))
+ cam = bpy.context.active_object.data
+ cam.lens = 50
+ cam.draw_size = 0.1
+
+# add spot lamp
+ bpy.ops.object.lamp_add(type="SPOT", location = (-0.7,-0.5,0.3), rotation =(1.223,0,-0.960))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Key Light"
+ lamp1.energy = 1.5
+ lamp1.distance = 1.5
+ lamp1.shadow_buffer_soft = 5
+ lamp1.shadow_buffer_size = 8192
+ lamp1.shadow_buffer_clip_end = 1.5
+ lamp1.spot_blend = 0.5
+
+# add spot lamp2
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.7,-0.6,0.1), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Fill Light"
+ lamp2.color = (0.874,0.874,1)
+ lamp2.energy = 0.5
+ lamp2.distance = 1.5
+ lamp2.shadow_buffer_soft = 5
+ lamp2.shadow_buffer_size = 4096
+ lamp2.shadow_buffer_clip_end = 1.5
+ lamp2.spot_blend = 0.5
+
+# light Rim
+ """
+ # add spot lamp3
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
+ lamp3 = bpy.context.active_object.data
+ lamp3.name = "Rim Light"
+ lamp3.color = (0.194,0.477,1)
+ lamp3.energy = 3
+ lamp3.distance = 1.5
+ lamp3.shadow_buffer_soft = 5
+ lamp3.shadow_buffer_size = 4096
+ lamp3.shadow_buffer_clip_end = 1.5
+ lamp3.spot_blend = 0.5
+ """
+# add sphere
+# add sphere
+ bpy.ops.mesh.primitive_uv_sphere_add(size=0.1)
+ bpy.ops.object.shade_smooth()
+
+ return {'FINISHED'}
+
+
+class Generategrass(bpy.types.Operator):
+ bl_idname = "grass.generate_grass"
+ bl_label = "Generate grass"
+ bl_description = "Create a grass"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+# Make variable that is the current .blend file main data blocks
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+ scene = context.scene
+
+######################################################################
+########################Test screen grass########################
+ if scene.grass_type == '0':
+
+###############Create New Material##################
+# add new material
+ grassMaterial = bpy.data.materials.new('greengrassMat')
+ ob.data.materials.append(grassMaterial)
+
+#Material settings
+ grassMaterial.preview_render_type = "HAIR"
+ grassMaterial.diffuse_color = (0.09710, 0.288, 0.01687)
+ grassMaterial.specular_color = (0.604, 0.465, 0.136)
+ grassMaterial.specular_intensity = 0.3
+ grassMaterial.ambient = 0
+ grassMaterial.use_cubic = True
+ grassMaterial.use_transparency = True
+ grassMaterial.alpha = 0
+ grassMaterial.use_transparent_shadows = True
+ #strand
+ grassMaterial.strand.use_blender_units = True
+ grassMaterial.strand.root_size = 0.00030
+ grassMaterial.strand.tip_size = 0.00010
+ grassMaterial.strand.size_min = 0.7
+ grassMaterial.strand.width_fade = 0.1
+ grassMaterial.strand.shape = 0.061
+ grassMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ grassTex = bpy.data.textures.new("greengrassTex", type='BLEND')
+ grassTex.use_preview_alpha = True
+ grassTex.use_color_ramp = True
+ ramp = grassTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.114,0.375,0.004025,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.267,0.155,0.02687,0]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.281,0.598,0.03157,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.119,0.528,0.136,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.247,0.713,0.006472,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.01943,0.163,0.01242,0.64]
+
+# add texture to material
+ MTex = grassMaterial.texture_slots.add()
+ MTex.texture = grassTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+
+############### Create Particles ##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ grassParticles = bpy.context.object.particle_systems.active
+ grassParticles.name = "greengrassPar"
+ grassParticles.settings.type = "HAIR"
+ grassParticles.settings.use_advanced_hair = True
+ grassParticles.settings.count = 500
+ grassParticles.settings.normal_factor = 0.05
+ grassParticles.settings.factor_random = 0.001
+ grassParticles.settings.use_dynamic_rotation = True
+
+ grassParticles.settings.material = NumberOfMaterials
+
+ grassParticles.settings.use_strand_primitive = True
+ grassParticles.settings.use_hair_bspline = True
+ grassParticles.settings.render_step = 5
+ grassParticles.settings.length_random = 0.5
+ grassParticles.settings.draw_step = 5
+# children
+ grassParticles.settings.rendered_child_count = 50
+ grassParticles.settings.child_type = "INTERPOLATED"
+ grassParticles.settings.child_length = 0.250
+ grassParticles.settings.create_long_hair_children = True
+ grassParticles.settings.clump_shape = 0.074
+ grassParticles.settings.clump_factor = 0.55
+ grassParticles.settings.roughness_endpoint = 0.080
+ grassParticles.settings.roughness_end_shape = 0.80
+ grassParticles.settings.roughness_2 = 0.043
+ grassParticles.settings.roughness_2_size = 0.230
+
+
+######################################################################
+###################### Field Grass ########################
+ if scene.grass_type == '1':
+###############Create New Material##################
+# add new material
+ grassMaterial = bpy.data.materials.new('fieldgrassMat')
+ ob.data.materials.append(grassMaterial)
+
+#Material settings
+ grassMaterial.preview_render_type = "HAIR"
+ grassMaterial.diffuse_color = (0.229, 0.800, 0.010)
+ grassMaterial.specular_color = (0.010, 0.06072, 0.000825)
+ grassMaterial.specular_intensity = 0.3
+ grassMaterial.specular_hardness = 100
+ grassMaterial.use_specular_ramp = True
+
+ ramp = grassMaterial.specular_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.0356,0.0652,0.009134,0]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.352,0.750,0.231,1]
+ rampElement1 = rampElements.new(0.255)
+ rampElement1.color = [0.214,0.342,0.0578,0.31]
+ rampElement2 = rampElements.new(0.594)
+ rampElement2.color = [0.096,0.643,0.0861,0.72]
+
+ grassMaterial.ambient = 0
+ grassMaterial.use_cubic = True
+ grassMaterial.use_transparency = True
+ grassMaterial.alpha = 0
+ grassMaterial.use_transparent_shadows = True
+ #strand
+ grassMaterial.strand.use_blender_units = True
+ grassMaterial.strand.root_size = 0.00030
+ grassMaterial.strand.tip_size = 0.00015
+ grassMaterial.strand.size_min = 0.450
+ grassMaterial.strand.width_fade = 0.1
+ grassMaterial.strand.shape = 0.02
+ grassMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ grassTex = bpy.data.textures.new("feildgrassTex", type='BLEND')
+ grassTex.name = "feildgrassTex"
+ grassTex.use_preview_alpha = True
+ grassTex.use_color_ramp = True
+ ramp = grassTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.01467,0.005307,0.00316,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.0272,0.01364,0.01013,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.04445,0.02294,0.01729,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.04092,0.0185,0.01161,0.64]
+
+# add texture to material
+ MTex = grassMaterial.texture_slots.add()
+ MTex.texture = grassTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ grassParticles = bpy.context.object.particle_systems.active
+ grassParticles.name = "fieldgrassPar"
+ grassParticles.settings.type = "HAIR"
+ grassParticles.settings.use_emit_random = True
+ grassParticles.settings.use_even_distribution = True
+ grassParticles.settings.use_advanced_hair = True
+ grassParticles.settings.count = 2000
+#Particle settings Velocity
+ grassParticles.settings.normal_factor = 0.060
+ grassParticles.settings.factor_random = 0.045
+ grassParticles.settings.use_dynamic_rotation = False
+ grassParticles.settings.brownian_factor = 0.070
+ grassParticles.settings.damping = 0.160
+ grassParticles.settings.material = NumberOfMaterials
+ # strands
+ grassParticles.settings.use_strand_primitive = True
+ grassParticles.settings.use_hair_bspline = True
+ grassParticles.settings.render_step = 7
+ grassParticles.settings.length_random = 1.0
+ grassParticles.settings.draw_step = 2
+# children
+ grassParticles.settings.child_type = "INTERPOLATED"
+ grassParticles.settings.child_length = 0.160
+ grassParticles.settings.create_long_hair_children = False
+ grassParticles.settings.clump_factor = 0.000
+ grassParticles.settings.clump_shape = 0.000
+ grassParticles.settings.roughness_endpoint = 0.000
+ grassParticles.settings.roughness_end_shape = 1
+ grassParticles.settings.roughness_2 = 0.200
+ grassParticles.settings.roughness_2_size = 0.230
+
+
+######################################################################
+########################Short Clumpped grass##########################
+ elif scene.grass_type == '2':
+###############Create New Material##################
+# add new material
+ grassMaterial = bpy.data.materials.new('clumpygrassMat')
+ ob.data.materials.append(grassMaterial)
+
+#Material settings
+ grassMaterial.preview_render_type = "HAIR"
+ grassMaterial.diffuse_color = (0.01504, 0.05222, 0.007724)
+ grassMaterial.specular_color = (0.02610, 0.196, 0.04444)
+ grassMaterial.specular_intensity = 0.5
+ grassMaterial.specular_hardness = 100
+ grassMaterial.ambient = 0
+ grassMaterial.use_cubic = True
+ grassMaterial.use_transparency = True
+ grassMaterial.alpha = 0
+ grassMaterial.use_transparent_shadows = True
+#strand
+ grassMaterial.strand.use_blender_units = True
+ grassMaterial.strand.root_size = 0.000315
+ grassMaterial.strand.tip_size = 0.00020
+ grassMaterial.strand.size_min = 0.2
+ grassMaterial.strand.width_fade = 0.1
+ grassMaterial.strand.shape = -0.900
+ grassMaterial.strand.blend_distance = 0.001
+
+# add texture
+ grassTex = bpy.data.textures.new("clumpygrasstex", type='BLEND')
+ grassTex.use_preview_alpha = True
+ grassTex.use_color_ramp = True
+ ramp = grassTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.004025,0.002732,0.002428,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.141,0.622,0.107,0.2]
+ rampElement1 = rampElements.new(0.202)
+ rampElement1.color = [0.01885,0.2177,0.01827,0.65]
+ rampElement2 = rampElements.new(0.499)
+ rampElement2.color = [0.114,0.309,0.09822,0.87]
+ rampElement3 = rampElements.new(0.828)
+ rampElement3.color = [0.141,0.427,0.117,0.64]
+
+# add texture to material
+ MTex = grassMaterial.texture_slots.add()
+ MTex.texture = grassTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ grassParticles = bpy.context.object.particle_systems.active
+ grassParticles.name = "clumpygrass"
+ grassParticles.settings.type = "HAIR"
+ grassParticles.settings.use_advanced_hair = True
+ grassParticles.settings.hair_step = 2
+ grassParticles.settings.count = 250
+ grassParticles.settings.normal_factor = 0.0082
+ grassParticles.settings.tangent_factor = 0.001
+ grassParticles.settings.tangent_phase = 0.250
+ grassParticles.settings.factor_random = 0.001
+ grassParticles.settings.use_dynamic_rotation = True
+
+ grassParticles.settings.material = NumberOfMaterials
+
+ grassParticles.settings.use_strand_primitive = True
+ grassParticles.settings.use_hair_bspline = True
+ grassParticles.settings.render_step = 3
+ grassParticles.settings.length_random = 0.3
+ grassParticles.settings.draw_step = 3
+# children
+ grassParticles.settings.child_type = "INTERPOLATED"
+ grassParticles.settings.child_length = 0.667
+ grassParticles.settings.child_length_threshold = 0.111
+ grassParticles.settings.rendered_child_count = 200
+ grassParticles.settings.virtual_parents = 1
+ grassParticles.settings.clump_factor = 0.425
+ grassParticles.settings.clump_shape = -0.999
+ grassParticles.settings.roughness_endpoint = 0.003
+ grassParticles.settings.roughness_end_shape = 5
+
+
+
+ return {'FINISHED'}
+
+####
+######### HAIR LAB ##########
+####
+class HairLabPanel(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Hair Lab"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ active_obj = bpy.context.active_object
+ active_scn = bpy.context.scene.name
+ layout = self.layout
+ col = layout.column(align=True)
+
+ WhatToDo = getActionToDo(active_obj)
+
+
+ if WhatToDo == "GENERATE":
+ col.operator("hair.generate_hair", text="Create Hair")
+
+ col.prop(context.scene, "hair_type")
+ else:
+ col.label(text="Select mesh object")
+
+ if active_scn == "TestHairScene":
+ col.operator("hair.switch_back", text="Switch back to scene")
+ else:
+ col.operator("hair.test_scene", text="Create Test Scene")
+
+# TO DO
+"""
+class saveSelection(bpy.types.Operator):
+ bl_idname = "save.selection"
+ bl_label = "Save Selection"
+ bl_description = "Save selected particles"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+
+ return {'FINISHED'}
+"""
+class testScene3(bpy.types.Operator):
+ bl_idname = "hair.switch_back"
+ bl_label = "Switch back to scene"
+ bl_description = "If you want keep this scene, switch scene in info window"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ scene = bpy.context.scene
+ bpy.data.scenes.remove(scene)
+
+ return {'FINISHED'}
+
+
+class testScene4(bpy.types.Operator):
+ bl_idname = "hair.test_scene"
+ bl_label = "Create test scene"
+ bl_description = "You can switch scene in info panel"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+# add new scene
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ scene.name = "TestHairScene"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("HairWorld")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+
+# add text
+ bpy.ops.object.text_add(location=(-0.292,0,-0.152), rotation =(1.571,0,0))
+ text = bpy.context.active_object
+ text.scale = (0.05,0.05,0.05)
+ text.data.body = "Hair Lab"
+
+# add material to text
+ textMaterial = bpy.data.materials.new('textMaterial')
+ text.data.materials.append(textMaterial)
+ textMaterial.use_shadeless = True
+
+# add camera
+ bpy.ops.object.camera_add(location = (0,-1,0),rotation = (1.571,0,0))
+ cam = bpy.context.active_object.data
+ cam.lens = 50
+ cam.draw_size = 0.1
+
+# add spot lamp
+ bpy.ops.object.lamp_add(type="SPOT", location = (-0.7,-0.5,0.3), rotation =(1.223,0,-0.960))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Key Light"
+ lamp1.energy = 1.5
+ lamp1.distance = 1.5
+ lamp1.shadow_buffer_soft = 5
+ lamp1.shadow_buffer_size = 8192
+ lamp1.shadow_buffer_clip_end = 1.5
+ lamp1.spot_blend = 0.5
+
+# add spot lamp2
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.7,-0.6,0.1), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Fill Light"
+ lamp2.color = (0.874,0.874,1)
+ lamp2.energy = 0.5
+ lamp2.distance = 1.5
+ lamp2.shadow_buffer_soft = 5
+ lamp2.shadow_buffer_size = 4096
+ lamp2.shadow_buffer_clip_end = 1.5
+ lamp2.spot_blend = 0.5
+
+# light Rim
+ """
+ # add spot lamp3
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
+ lamp3 = bpy.context.active_object.data
+ lamp3.name = "Rim Light"
+ lamp3.color = (0.194,0.477,1)
+ lamp3.energy = 3
+ lamp3.distance = 1.5
+ lamp3.shadow_buffer_soft = 5
+ lamp3.shadow_buffer_size = 4096
+ lamp3.shadow_buffer_clip_end = 1.5
+ lamp3.spot_blend = 0.5
+ """
+# add sphere
+ bpy.ops.mesh.primitive_uv_sphere_add(size=0.1)
+ bpy.ops.object.shade_smooth()
+ return {'FINISHED'}
+
+
+class GenerateHair(bpy.types.Operator):
+ bl_idname = "hair.generate_hair"
+ bl_label = "Generate Hair"
+ bl_description = "Create a Hair"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+# Make variable that is the current .blend file main data blocks
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+ scene = context.scene
+
+######################################################################
+########################Long Red Straight Hair########################
+ if scene.hair_type == '0':
+
+###############Create New Material##################
+# add new material
+ hairMaterial = bpy.data.materials.new('LongRedStraightHairMat')
+ ob.data.materials.append(hairMaterial)
+
+#Material settings
+ hairMaterial.preview_render_type = "HAIR"
+ hairMaterial.diffuse_color = (0.287, 0.216, 0.04667)
+ hairMaterial.specular_color = (0.604, 0.465, 0.136)
+ hairMaterial.specular_intensity = 0.3
+ hairMaterial.ambient = 0
+ hairMaterial.use_cubic = True
+ hairMaterial.use_transparency = True
+ hairMaterial.alpha = 0
+ hairMaterial.use_transparent_shadows = True
+#strand
+ hairMaterial.strand.use_blender_units = True
+ hairMaterial.strand.root_size = 0.00030
+ hairMaterial.strand.tip_size = 0.00010
+ hairMaterial.strand.size_min = 0.7
+ hairMaterial.strand.width_fade = 0.1
+ hairMaterial.strand.shape = 0.061
+ hairMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ hairTex = bpy.data.textures.new("LongRedStraightHairTex", type='BLEND')
+ hairTex.use_preview_alpha = True
+ hairTex.use_color_ramp = True
+ ramp = hairTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.114,0.05613,0.004025,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.267,0.155,0.02687,0]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.281,0.168,0.03157,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.288,0.135,0.006242,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.247,0.113,0.006472,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.253,0.09919,0.01242,0.64]
+
+# add texture to material
+ MTex = hairMaterial.texture_slots.add()
+ MTex.texture = hairTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ hairParticles = bpy.context.object.particle_systems.active
+ hairParticles.name = "LongRedStraightHairPar"
+ hairParticles.settings.type = "HAIR"
+ hairParticles.settings.use_advanced_hair = True
+ hairParticles.settings.count = 500
+ hairParticles.settings.normal_factor = 0.05
+ hairParticles.settings.factor_random = 0.001
+ hairParticles.settings.use_dynamic_rotation = True
+
+ hairParticles.settings.material = NumberOfMaterials
+
+ hairParticles.settings.use_strand_primitive = True
+ hairParticles.settings.use_hair_bspline = True
+ hairParticles.settings.render_step = 5
+ hairParticles.settings.length_random = 0.5
+ hairParticles.settings.draw_step = 5
+# children
+ hairParticles.settings.child_type = "INTERPOLATED"
+ hairParticles.settings.create_long_hair_children = True
+ hairParticles.settings.clump_factor = 0.55
+ hairParticles.settings.roughness_endpoint = 0.005
+ hairParticles.settings.roughness_end_shape = 5
+ hairParticles.settings.roughness_2 = 0.003
+ hairParticles.settings.roughness_2_size = 0.230
+
+
+######################################################################
+########################Long Brown Curl Hair##########################
+ if scene.hair_type == '1':
+###############Create New Material##################
+# add new material
+ hairMaterial = bpy.data.materials.new('LongBrownCurlHairMat')
+ ob.data.materials.append(hairMaterial)
+
+#Material settings
+ hairMaterial.preview_render_type = "HAIR"
+ hairMaterial.diffuse_color = (0.662, 0.518, 0.458)
+ hairMaterial.specular_color = (0.351, 0.249, 0.230)
+ hairMaterial.specular_intensity = 0.3
+ hairMaterial.specular_hardness = 100
+ hairMaterial.use_specular_ramp = True
+
+ ramp = hairMaterial.specular_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.0356,0.0152,0.009134,0]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.352,0.250,0.231,1]
+ rampElement1 = rampElements.new(0.255)
+ rampElement1.color = [0.214,0.08244,0.0578,0.31]
+ rampElement2 = rampElements.new(0.594)
+ rampElement2.color = [0.296,0.143,0.0861,0.72]
+
+ hairMaterial.ambient = 0
+ hairMaterial.use_cubic = True
+ hairMaterial.use_transparency = True
+ hairMaterial.alpha = 0
+ hairMaterial.use_transparent_shadows = True
+#strand
+ hairMaterial.strand.use_blender_units = True
+ hairMaterial.strand.root_size = 0.00030
+ hairMaterial.strand.tip_size = 0.00015
+ hairMaterial.strand.size_min = 0.450
+ hairMaterial.strand.width_fade = 0.1
+ hairMaterial.strand.shape = 0.02
+ hairMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ hairTex = bpy.data.textures.new("HairTex", type='BLEND')
+ hairTex.name = "LongBrownCurlHairTex"
+ hairTex.use_preview_alpha = True
+ hairTex.use_color_ramp = True
+ ramp = hairTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.01467,0.005307,0.00316,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.0272,0.01364,0.01013,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.04445,0.02294,0.01729,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.04092,0.0185,0.01161,0.64]
+
+# add texture to material
+ MTex = hairMaterial.texture_slots.add()
+ MTex.texture = hairTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ hairParticles = bpy.context.object.particle_systems.active
+ hairParticles.name = "LongBrownCurlHairPar"
+ hairParticles.settings.type = "HAIR"
+ hairParticles.settings.use_advanced_hair = True
+ hairParticles.settings.count = 500
+ hairParticles.settings.normal_factor = 0.05
+ hairParticles.settings.factor_random = 0.001
+ hairParticles.settings.use_dynamic_rotation = True
+
+ hairParticles.settings.material = NumberOfMaterials
+
+ hairParticles.settings.use_strand_primitive = True
+ hairParticles.settings.use_hair_bspline = True
+ hairParticles.settings.render_step = 7
+ hairParticles.settings.length_random = 0.5
+ hairParticles.settings.draw_step = 5
+# children
+ hairParticles.settings.child_type = "INTERPOLATED"
+ hairParticles.settings.create_long_hair_children = True
+ hairParticles.settings.clump_factor = 0.523
+ hairParticles.settings.clump_shape = 0.383
+ hairParticles.settings.roughness_endpoint = 0.002
+ hairParticles.settings.roughness_end_shape = 5
+ hairParticles.settings.roughness_2 = 0.003
+ hairParticles.settings.roughness_2_size = 2
+
+ hairParticles.settings.kink = "CURL"
+ hairParticles.settings.kink_amplitude = 0.007597
+ hairParticles.settings.kink_frequency = 6
+ hairParticles.settings.kink_shape = 0.4
+ hairParticles.settings.kink_flat = 0.8
+
+
+######################################################################
+########################Short Dark Hair##########################
+ elif scene.hair_type == '2':
+###############Create New Material##################
+# add new material
+ hairMaterial = bpy.data.materials.new('ShortDarkHairMat')
+ ob.data.materials.append(hairMaterial)
+
+#Material settings
+ hairMaterial.preview_render_type = "HAIR"
+ hairMaterial.diffuse_color = (0.560, 0.536, 0.506)
+ hairMaterial.specular_color = (0.196, 0.177, 0.162)
+ hairMaterial.specular_intensity = 0.5
+ hairMaterial.specular_hardness = 100
+ hairMaterial.ambient = 0
+ hairMaterial.use_cubic = True
+ hairMaterial.use_transparency = True
+ hairMaterial.alpha = 0
+ hairMaterial.use_transparent_shadows = True
+#strand
+ hairMaterial.strand.use_blender_units = True
+ hairMaterial.strand.root_size = 0.0002
+ hairMaterial.strand.tip_size = 0.0001
+ hairMaterial.strand.size_min = 0.3
+ hairMaterial.strand.width_fade = 0.1
+ hairMaterial.strand.shape = 0
+ hairMaterial.strand.blend_distance = 0.001
+
+# add texture
+ hairTex = bpy.data.textures.new("ShortDarkHair", type='BLEND')
+ hairTex.use_preview_alpha = True
+ hairTex.use_color_ramp = True
+ ramp = hairTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.004025,0.002732,0.002428,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.141,0.122,0.107,0.2]
+ rampElement1 = rampElements.new(0.202)
+ rampElement1.color = [0.01885,0.0177,0.01827,0.65]
+ rampElement2 = rampElements.new(0.499)
+ rampElement2.color = [0.114,0.109,0.09822,0.87]
+ rampElement3 = rampElements.new(0.828)
+ rampElement3.color = [0.141,0.127,0.117,0.64]
+
+# add texture to material
+ MTex = hairMaterial.texture_slots.add()
+ MTex.texture = hairTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ hairParticles = bpy.context.object.particle_systems.active
+ hairParticles.name = "ShortDarkHair"
+ hairParticles.settings.type = "HAIR"
+ hairParticles.settings.use_advanced_hair = True
+ hairParticles.settings.hair_step = 2
+ hairParticles.settings.count = 450
+ hairParticles.settings.normal_factor = 0.007
+ hairParticles.settings.factor_random = 0.001
+ hairParticles.settings.use_dynamic_rotation = True
+
+ hairParticles.settings.material = NumberOfMaterials
+
+ hairParticles.settings.use_strand_primitive = True
+ hairParticles.settings.use_hair_bspline = True
+ hairParticles.settings.render_step = 3
+ hairParticles.settings.length_random = 0.3
+ hairParticles.settings.draw_step = 3
+# children
+ hairParticles.settings.child_type = "INTERPOLATED"
+ hairParticles.settings.rendered_child_count = 200
+ hairParticles.settings.virtual_parents = 1
+ hairParticles.settings.clump_factor = 0.425
+ hairParticles.settings.clump_shape = 0.1
+ hairParticles.settings.roughness_endpoint = 0.003
+ hairParticles.settings.roughness_end_shape = 5
+
+
+
+ return {'FINISHED'}
+####
+######## FUR LAB ########
+####
+
+class FurLabPanel(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Fur Lab"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ active_obj = bpy.context.active_object
+ active_scn = bpy.context.scene.name
+ layout = self.layout
+ col = layout.column(align=True)
+
+ WhatToDo = getActionToDo(active_obj)
+
+
+ if WhatToDo == "GENERATE":
+ col.operator("fur.generate_fur", text="Create Fur")
+
+ col.prop(context.scene, "fur_type")
+ else:
+ col.label(text="Select mesh object")
+
+ if active_scn == "TestFurScene":
+ col.operator("hair.switch_back", text="Switch back to scene")
+ else:
+ col.operator("fur.test_scene", text="Create Test Scene")
+
+# TO DO
+"""
+class saveSelection(bpy.types.Operator):
+ bl_idname = "save.selection"
+ bl_label = "Save Selection"
+ bl_description = "Save selected particles"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+
+ return {'FINISHED'}
+"""
+class testScene5(bpy.types.Operator):
+ bl_idname = "fur.switch_back"
+ bl_label = "Switch back to scene"
+ bl_description = "If you want keep this scene, switch scene in info window"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+ scene = bpy.context.scene
+ bpy.data.scenes.remove(scene)
+
+ return {'FINISHED'}
+
+
+class testScene6(bpy.types.Operator):
+ bl_idname = "fur.test_scene"
+ bl_label = "Create test scene"
+ bl_description = "You can switch scene in info panel"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+# add new scene
+ bpy.ops.scene.new(type="NEW")
+ scene = bpy.context.scene
+ scene.name = "TestFurScene"
+# render settings
+ render = scene.render
+ render.resolution_x = 1920
+ render.resolution_y = 1080
+ render.resolution_percentage = 50
+# add new world
+ world = bpy.data.worlds.new("FurWorld")
+ scene.world = world
+ world.use_sky_blend = True
+ world.use_sky_paper = True
+ world.horizon_color = (0.004393,0.02121,0.050)
+ world.zenith_color = (0.03335,0.227,0.359)
+
+# add text
+ bpy.ops.object.text_add(location=(-0.292,0,-0.152), rotation =(1.571,0,0))
+ text = bpy.context.active_object
+ text.scale = (0.05,0.05,0.05)
+ text.data.body = "Fur Lab"
+
+# add material to text
+ textMaterial = bpy.data.materials.new('textMaterial')
+ text.data.materials.append(textMaterial)
+ textMaterial.use_shadeless = True
+
+# add camera
+ bpy.ops.object.camera_add(location = (0,-1,0),rotation = (1.571,0,0))
+ cam = bpy.context.active_object.data
+ cam.lens = 50
+ cam.draw_size = 0.1
+
+# add spot lamp
+ bpy.ops.object.lamp_add(type="SPOT", location = (-0.7,-0.5,0.3), rotation =(1.223,0,-0.960))
+ lamp1 = bpy.context.active_object.data
+ lamp1.name = "Key Light"
+ lamp1.energy = 1.5
+ lamp1.distance = 1.5
+ lamp1.shadow_buffer_soft = 5
+ lamp1.shadow_buffer_size = 8192
+ lamp1.shadow_buffer_clip_end = 1.5
+ lamp1.spot_blend = 0.5
+
+# add spot lamp2
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.7,-0.6,0.1), rotation =(1.571,0,0.785))
+ lamp2 = bpy.context.active_object.data
+ lamp2.name = "Fill Light"
+ lamp2.color = (0.874,0.874,1)
+ lamp2.energy = 0.5
+ lamp2.distance = 1.5
+ lamp2.shadow_buffer_soft = 5
+ lamp2.shadow_buffer_size = 4096
+ lamp2.shadow_buffer_clip_end = 1.5
+ lamp2.spot_blend = 0.5
+
+# light Rim
+ """
+ # add spot lamp3
+ bpy.ops.object.lamp_add(type="SPOT", location = (0.191,0.714,0.689), rotation =(0.891,0,2.884))
+ lamp3 = bpy.context.active_object.data
+ lamp3.name = "Rim Light"
+ lamp3.color = (0.194,0.477,1)
+ lamp3.energy = 3
+ lamp3.distance = 1.5
+ lamp3.shadow_buffer_soft = 5
+ lamp3.shadow_buffer_size = 4096
+ lamp3.shadow_buffer_clip_end = 1.5
+ lamp3.spot_blend = 0.5
+ """
+# add sphere
+ bpy.ops.mesh.primitive_uv_sphere_add(size=0.1)
+ bpy.ops.object.shade_smooth()
+ return {'FINISHED'}
+
+
+class GenerateFur(bpy.types.Operator):
+ bl_idname = "fur.generate_fur"
+ bl_label = "Generate Fur"
+ bl_description = "Create a Fur"
+ bl_register = True
+ bl_undo = True
+
+ def execute(self, context):
+# Make variable that is the current .blend file main data blocks
+ blend_data = context.blend_data
+ ob = bpy.context.active_object
+ scene = context.scene
+
+######################################################################
+########################Short Fur########################
+ if scene.fur_type == '0':
+
+###############Create New Material##################
+# add new material
+ furMaterial = bpy.data.materials.new('Fur 1')
+ ob.data.materials.append(furMaterial)
+
+#Material settings
+ furMaterial.preview_render_type = "HAIR"
+ furMaterial.diffuse_color = (0.287, 0.216, 0.04667)
+ furMaterial.specular_color = (0.604, 0.465, 0.136)
+ furMaterial.specular_intensity = 0.3
+ furMaterial.ambient = 0
+ furMaterial.use_cubic = True
+ furMaterial.use_transparency = True
+ furMaterial.alpha = 0
+ furMaterial.use_transparent_shadows = True
+#strand
+ furMaterial.strand.use_blender_units = True
+ furMaterial.strand.root_size = 0.00030
+ furMaterial.strand.tip_size = 0.00010
+ furMaterial.strand.size_min = 0.7
+ furMaterial.strand.width_fade = 0.1
+ furMaterial.strand.shape = 0.061
+ furMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ furTex = bpy.data.textures.new("Fur1Tex", type='BLEND')
+ furTex.use_preview_alpha = True
+ furTex.use_color_ramp = True
+ ramp = furTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.114,0.05613,0.004025,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.267,0.155,0.02687,0]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.281,0.168,0.03157,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.288,0.135,0.006242,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.247,0.113,0.006472,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.253,0.09919,0.01242,0.64]
+
+# add texture to material
+ MTex = furMaterial.texture_slots.add()
+ MTex.texture = furTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ furParticles = bpy.context.object.particle_systems.active
+ furParticles.name = "Fur1Par"
+ furParticles.settings.type = "HAIR"
+ furParticles.settings.use_advanced_hair = True
+ furParticles.settings.count = 500
+ furParticles.settings.normal_factor = 0.05
+ furParticles.settings.factor_random = 0.001
+ furParticles.settings.use_dynamic_rotation = True
+
+ furParticles.settings.material = NumberOfMaterials
+
+ furParticles.settings.use_strand_primitive = True
+ furParticles.settings.use_hair_bspline = True
+ furParticles.settings.render_step = 5
+ furParticles.settings.length_random = 0.5
+ furParticles.settings.draw_step = 5
+# children
+ furParticles.settings.child_type = "INTERPOLATED"
+ furParticles.settings.child_length = 0.134
+ furParticles.settings.create_long_hair_children = True
+ furParticles.settings.clump_factor = 0.55
+ furParticles.settings.roughness_endpoint = 0.005
+ furParticles.settings.roughness_end_shape = 5
+ furParticles.settings.roughness_2 = 0.003
+ furParticles.settings.roughness_2_size = 0.230
+
+
+######################################################################
+########################Dalmation Fur##########################
+ if scene.fur_type == '1':
+###############Create New Material##################
+# add new material
+ furMaterial = bpy.data.materials.new('Fur2Mat')
+ ob.data.materials.append(furMaterial)
+
+#Material settings
+ furMaterial.preview_render_type = "HAIR"
+ furMaterial.diffuse_color = (0.300, 0.280, 0.280)
+ furMaterial.specular_color = (1.0, 1.0, 1.0)
+ furMaterial.specular_intensity = 0.500
+ furMaterial.specular_hardness = 50
+
+ furMaterial.ambient = 0
+ furMaterial.use_cubic = True
+ furMaterial.use_transparency = True
+ furMaterial.alpha = 0
+ furMaterial.use_transparent_shadows = True
+#strand
+ furMaterial.strand.use_blender_units = True
+ furMaterial.strand.root_size = 0.00030
+ furMaterial.strand.tip_size = 0.00010
+ furMaterial.strand.size_min = 0.7
+ furMaterial.strand.width_fade = 0.1
+ furMaterial.strand.shape = 0.061
+ furMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ furTex = bpy.data.textures.new("Fur2Tex", type='BLEND')
+ furTex.name = "Fur2"
+ furTex.use_preview_alpha = True
+ furTex.use_color_ramp = True
+ ramp = furTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [1.0,1.0,1.0,1.0]
+ rampElements[1].position = 1
+ rampElements[1].color = [1.0,1.0,1.0,0.0]
+ rampElement1 = rampElements.new(0.116)
+ rampElement1.color = [1.0,1.0,1.0,1.0]
+
+
+# add texture to material
+ MTex = furMaterial.texture_slots.add()
+ MTex.texture = furTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+# add texture 2
+ furTex = bpy.data.textures.new("Fur2bTex", type='CLOUDS')
+ furTex.name = "Fur2b"
+ furTex.use_preview_alpha = False
+ furTex.cloud_type = "COLOR"
+ furTex.noise_type = "HARD_NOISE"
+ furTex.noise_scale = 0.06410
+ furTex.use_color_ramp = True
+ ramp = furTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [1.0,1.0,1.0, 1.0]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.0,0.0,0.0,1.0]
+ rampElement1 = rampElements.new(0.317)
+ rampElement1.color = [1.0,1.0,1.0,1.0]
+ rampElement2 = rampElements.new(0.347)
+ rampElement2.color = [0.0,0.0,0.0,1.0]
+
+# add texture 2 to material
+ MTex = furMaterial.texture_slots.add()
+ MTex.texture = furTex
+ MTex.texture_coords = "GLOBAL"
+ MTex.use_map_alpha = True
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ furParticles = bpy.context.object.particle_systems.active
+ furParticles.name = "Fur2Par"
+ furParticles.settings.type = "HAIR"
+ furParticles.settings.use_advanced_hair = True
+ furParticles.settings.count = 500
+ furParticles.settings.normal_factor = 0.05
+ furParticles.settings.factor_random = 0.001
+ furParticles.settings.use_dynamic_rotation = True
+
+ furParticles.settings.material = NumberOfMaterials
+
+ furParticles.settings.use_strand_primitive = True
+ furParticles.settings.use_hair_bspline = True
+ furParticles.settings.render_step = 5
+ furParticles.settings.length_random = 0.5
+ furParticles.settings.draw_step = 5
+# children
+ furParticles.settings.child_type = "INTERPOLATED"
+ furParticles.settings.child_length = 0.07227
+ furParticles.settings.create_long_hair_children = True
+ furParticles.settings.clump_factor = 0.55
+ furParticles.settings.roughness_endpoint = 0.005
+ furParticles.settings.roughness_end_shape = 5
+ furParticles.settings.roughness_2 = 0.003
+ furParticles.settings.roughness_2_size = 0.230
+
+######################################################################
+########################Spotted_fur##########################
+ elif scene.fur_type == '2':
+
+###############Create New Material##################
+# add new material
+ furMaterial = bpy.data.materials.new('Fur3Mat')
+ ob.data.materials.append(furMaterial)
+
+#Material settings
+ furMaterial.preview_render_type = "HAIR"
+ furMaterial.diffuse_color = (0.300, 0.280, 0.280)
+ furMaterial.specular_color = (1.0, 1.0, 1.0)
+ furMaterial.specular_intensity = 0.500
+ furMaterial.specular_hardness = 50
+ furMaterial.use_specular_ramp = True
+
+ ramp = furMaterial.specular_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.0356,0.0152,0.009134,0]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.352,0.250,0.231,1]
+ rampElement1 = rampElements.new(0.255)
+ rampElement1.color = [0.214,0.08244,0.0578,0.31]
+ rampElement2 = rampElements.new(0.594)
+ rampElement2.color = [0.296,0.143,0.0861,0.72]
+
+ furMaterial.ambient = 0
+ furMaterial.use_cubic = True
+ furMaterial.use_transparency = True
+ furMaterial.alpha = 0
+ furMaterial.use_transparent_shadows = True
+#strand
+ furMaterial.strand.use_blender_units = True
+ furMaterial.strand.root_size = 0.00030
+ furMaterial.strand.tip_size = 0.00015
+ furMaterial.strand.size_min = 0.450
+ furMaterial.strand.width_fade = 0.1
+ furMaterial.strand.shape = 0.02
+ furMaterial.strand.blend_distance = 0.001
+
+
+# add texture
+ furTex = bpy.data.textures.new("Fur3Tex", type='BLEND')
+ furTex.name = "Fur3"
+ furTex.use_preview_alpha = True
+ furTex.use_color_ramp = True
+ ramp = furTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.01467,0.005307,0.00316,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.0272,0.01364,0.01013,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.04445,0.02294,0.01729,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.04092,0.0185,0.01161,0.64]
+
+# add texture to material
+ MTex = furMaterial.texture_slots.add()
+ MTex.texture = furTex
+ MTex.texture_coords = "STRAND"
+ MTex.use_map_alpha = True
+
+# add texture 2
+ furTex = bpy.data.textures.new("Fur3bTex", type='CLOUDS')
+ furTex.name = "Fur3b"
+ furTex.use_preview_alpha = True
+ furTex.cloud_type = "COLOR"
+ furTex.use_color_ramp = True
+ ramp = furTex.color_ramp
+ rampElements = ramp.elements
+ rampElements[0].position = 0
+ rampElements[0].color = [0.009721,0.006049,0.003677,0.38]
+ rampElements[1].position = 1
+ rampElements[1].color = [0.04231,0.02029,0.01444,0.16]
+ rampElement1 = rampElements.new(0.111)
+ rampElement1.color = [0.01467,0.005307,0.00316,0.65]
+ rampElement2 = rampElements.new(0.366)
+ rampElement2.color = [0.0272,0.01364,0.01013,0.87]
+ rampElement3 = rampElements.new(0.608)
+ rampElement3.color = [0.04445,0.02294,0.01729,0.8]
+ rampElement4 = rampElements.new(0.828)
+ rampElement4.color = [0.04092,0.0185,0.01161,0.64]
+
+# add texture 2 to material
+ MTex = furMaterial.texture_slots.add()
+ MTex.texture = furTex
+ MTex.texture_coords = "GLOBAL"
+ MTex.use_map_alpha = False
+
+###############Create Particles##################
+# Add new particle system
+
+ NumberOfMaterials = 0
+ for i in ob.data.materials:
+ NumberOfMaterials +=1
+
+
+ bpy.ops.object.particle_system_add()
+#Particle settings setting it up!
+ furParticles = bpy.context.object.particle_systems.active
+ furParticles.name = "Fur3Par"
+ furParticles.settings.type = "HAIR"
+ furParticles.settings.use_advanced_hair = True
+ furParticles.settings.count = 500
+ furParticles.settings.normal_factor = 0.05
+ furParticles.settings.factor_random = 0.001
+ furParticles.settings.use_dynamic_rotation = True
+
+ furParticles.settings.material = NumberOfMaterials
+
+ furParticles.settings.use_strand_primitive = True
+ furParticles.settings.use_hair_bspline = True
+ furParticles.settings.render_step = 5
+ furParticles.settings.length_random = 0.5
+ furParticles.settings.draw_step = 5
+# children
+ furParticles.settings.child_type = "INTERPOLATED"
+ furParticles.settings.child_length = 0.134
+ furParticles.settings.create_long_hair_children = True
+ furParticles.settings.clump_factor = 0.55
+ furParticles.settings.roughness_endpoint = 0.005
+ furParticles.settings.roughness_end_shape = 5
+ furParticles.settings.roughness_2 = 0.003
+ furParticles.settings.roughness_2_size = 0.230
+
+ return {'FINISHED'}
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.Scene.grass_type = EnumProperty(
+ name="Type",
+ description="Select the type of grass",
+ items=[("0","Green Grass","Generate particle grass"),
+ ("1","Grassy Field","Generate particle grass"),
+ ("2","Clumpy Grass","Generate particle grass"),
+
+ ],
+ default='0')
+ bpy.types.Scene.hair_type = EnumProperty(
+ name="Type",
+ description="Select the type of hair",
+ items=[("0","Long Red Straight Hair","Generate particle Hair"),
+ ("1","Long Brown Curl Hair","Generate particle Hair"),
+ ("2","Short Dark Hair","Generate particle Hair"),
+
+ ],
+ default='0')
+ bpy.types.Scene.fur_type = EnumProperty(
+ name="Type",
+ description="Select the type of fur",
+ items=[("0","Short Fur","Generate particle Fur"),
+ ("1","Dalmation","Generate particle Fur"),
+ ("2","Fur3","Generate particle Fur"),
+
+ ],
+ default='0')
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ del bpy.types.Scene.hair_type
+
+if __name__ == "__main__":
+ register()
+
+
+
diff --git a/release/scripts/addons_contrib/presets/interface_theme/3ds_max.xml b/release/scripts/addons_contrib/presets/interface_theme/3ds_max.xml
new file mode 100644
index 0000000..041c942
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/3ds_max.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#708faa"
+ inner="#c4c4c4ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#708faa"
+ inner="#c3c3c3ff"
+ inner_sel="#ddae64ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#535353"
+ inner="#d1d1d1ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="25">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#747474"
+ inner="#a2a2a2ff"
+ inner_sel="#bbb8a3ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#708faa"
+ inner="#d0d0d0ff"
+ inner_sel="#64717dff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#708faa"
+ inner="#c4c4c4ff"
+ inner_sel="#999999ff"
+ item="#708faaff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#747474"
+ inner="#b4b4b4ff"
+ inner_sel="#999999ff"
+ item="#c9c9c9ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#191919"
+ inner="#d1d1d1ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#464646"
+ inner="#aeaeaeff"
+ inner_sel="#464646ff"
+ item="#6d8da6ff"
+ text="#000000"
+ text_sel="#cccccc"
+ show_shaded="TRUE"
+ shadetop="15"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#3f3f3fff"
+ inner_sel="#536a7e26"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#424242"
+ inner="#b4b4b4ff"
+ inner_sel="#2d2d2dff"
+ item="#646464ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="30">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#8897a4ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#708faa"
+ inner="#708faa26"
+ inner_sel="#646464b4"
+ item="#a9a9a9ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#000000"
+ inner="#bebebeff"
+ inner_sel="#646464b4"
+ item="#444444ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#d8c555aa"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#f0eb64"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#505050"
+ wire="#000000"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#fa3f00"
+ object_active="#ffffff"
+ object_grouped="#104010"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#5454f0"
+ vertex_select="#ae6060"
+ vertex_size="3"
+ edge_select="#ff3d3d"
+ edge_seam="#e69632"
+ edge_sharp="#ff2020"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ face="#a8a8a84d"
+ face_select="#ae606066"
+ face_dot="#883737"
+ facedot_size="2"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#000080"
+ extra_face_area="#002000"
+ editmesh_active="#fcf8ff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#737373"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b457"
+ button_title="#494949"
+ button_text="#494949"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#505050"
+ window_sliders="#969696"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ lastsel_point="#ffffff"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="3"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#737373"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#b4b4b4"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#d7ae6d"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#0f0f0f"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#b4b4b4"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#757575"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#b4b4b4"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#505050"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#60c040"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#737373"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#b4b4b4"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#5454f0"
+ vertex_select="#d00000"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#7c00003c"
+ face_dot="#ff0000"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#b4b4b4ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#757575"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#404040"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#949494"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b442"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#404040"
+ selected_text="#c67777"
+ cursor="#ff0000"
+ syntax_builtin="#800050"
+ syntax_special="#5f5f00"
+ syntax_comment="#006432"
+ syntax_string="#640000"
+ syntax_numbers="#0000c8">
+ <space>
+ <ThemeSpaceGeneric back="#d1d1d1"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#505050"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#999999"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#000000"
+ wire_select="#ffffff"
+ selected_text="#7f7070"
+ node_backdrop="#9b9b9ba0"
+ in_out_node="#faa044"
+ converter_node="#deaf66"
+ operator_node="#9e733e"
+ group_node="#3c753c"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#737373"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b42f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#82878c">
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#fff1e1"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#000000"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#b4b4b4"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#737373"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b4b4b4"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#b4b4b4ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/default.xml b/release/scripts/addons_contrib/presets/interface_theme/default.xml
new file mode 100644
index 0000000..aeacd7f
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/default.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#000000"
+ inner="#464646ff"
+ inner_sel="#5680c2ff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="25">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#000000"
+ inner="#464646ff"
+ inner_sel="#464646ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#191919"
+ inner="#b4b4b4ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#191919"
+ inner="#b4b4b4ff"
+ inner_sel="#999999ff"
+ item="#808080ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#191919"
+ inner="#808080ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#000000"
+ inner="#464646ff"
+ inner_sel="#464646ff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#cccccc"
+ show_shaded="TRUE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#3f3f3fff"
+ inner_sel="#5680c2ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#5680c2ff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="38"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#323232"
+ inner="#505050b4"
+ inner_sel="#646464b4"
+ item="#808080ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#000000"
+ inner="#bebebeff"
+ inner_sel="#646464b4"
+ item="#444444ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#5680c2ff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#f0eb64"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#404040"
+ wire="#000000"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#f15800"
+ object_active="#ffaa40"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ edge_select="#ffa000"
+ edge_seam="#db2512"
+ edge_sharp="#00ffff"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ face="#00000012"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="4"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#000080"
+ extra_face_area="#002000"
+ editmesh_active="#ffffff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#393939"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#72727257"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#5e5e5e"
+ window_sliders="#969696"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#ffffff"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="4"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#ff8c19"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#4c4c4c"
+ title="#000000"
+ text="#fafafa"
+ text_hi="#0f0f0f"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#5e5e5e"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#60c040"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#727272ff"
+ preview_stitch_face="#7f7f0033"
+ preview_stitch_edge="#ff00ff33"
+ preview_stitch_vert="#0000ff33"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#353535"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#404040"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#747474"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#72727242"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#404040"
+ selected_text="#c67777"
+ cursor="#ff0000"
+ syntax_builtin="#800050"
+ syntax_special="#5f5f00"
+ syntax_comment="#006432"
+ syntax_string="#640000"
+ syntax_numbers="#0000c8">
+ <space>
+ <ThemeSpaceGeneric back="#999999"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#5b5b5b"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#000000"
+ wire_select="#ffffff"
+ selected_text="#7f7070"
+ node_backdrop="#9b9b9ba0"
+ in_out_node="#646464"
+ converter_node="#686a75"
+ operator_node="#6c696f"
+ group_node="#69756e"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#393939"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272722f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#646464"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#82878c">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#393939"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/maya.xml b/release/scripts/addons_contrib/presets/interface_theme/maya.xml
new file mode 100644
index 0000000..283fe1c
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/maya.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#191919"
+ inner="#2c2c2cff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#8f8f8f"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#000000"
+ inner="#292929ff"
+ inner_sel="#678db2ff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#191919"
+ inner="#131313ff"
+ inner_sel="#333230ff"
+ item="#678db2ff"
+ text="#dddddd"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="25">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#000000"
+ inner="#2b2b2bff"
+ inner_sel="#464646ff"
+ item="#ffffffff"
+ text="#888284"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#525252"
+ inner="#222222ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#191919"
+ inner="#535353ff"
+ inner_sel="#999999ff"
+ item="#808080ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#191919"
+ inner="#696969ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#000000"
+ inner="#777777ff"
+ inner_sel="#464646ff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#cccccc"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#3f3f3fff"
+ inner_sel="#656969ff"
+ item="#ffffffff"
+ text="#dddddd"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#000000"
+ inner="#444444ff"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#658aaeff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="38"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#323232"
+ inner="#505050b4"
+ inner_sel="#646464b4"
+ item="#808080ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#000000"
+ inner="#bebebeff"
+ inner_sel="#646464b4"
+ item="#444444ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#5680c2ff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#f0eb64"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#7f7f7f"
+ wire="#64dcff"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#f15800"
+ object_active="#43ffa3"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#cc1b23"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ edge_select="#ffa000"
+ edge_seam="#db2512"
+ edge_sharp="#ff2020"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ face="#00000012"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="4"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#000080"
+ extra_face_area="#002000"
+ editmesh_active="#ffffff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#576471"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#444444"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#44444457"
+ button_title="#ffffff"
+ button_text="#ffffff"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#5e5e5e"
+ window_sliders="#969696"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#ffffff"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="3"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#ff8c19"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#4c4c4c"
+ title="#000000"
+ text="#fafafa"
+ text_hi="#0f0f0f"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#5e5e5e"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#60c040"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#727272ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#353535"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#404040"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#747474"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#72727242"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#444444"
+ title="#dddddd"
+ text="#dddddd"
+ text_hi="#ffffff"
+ header="#444444"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#404040"
+ selected_text="#c67777"
+ cursor="#ff0000"
+ syntax_builtin="#800050"
+ syntax_special="#5f5f00"
+ syntax_comment="#006432"
+ syntax_string="#640000"
+ syntax_numbers="#0000c8">
+ <space>
+ <ThemeSpaceGeneric back="#999999"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#000000"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#737373"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#444444"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#000000"
+ wire_select="#ffffff"
+ selected_text="#7f7070"
+ node_backdrop="#9b9b9ba0"
+ in_out_node="#646464"
+ converter_node="#686a75"
+ operator_node="#6c696f"
+ group_node="#69756e"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#393939"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272722f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#646464"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#356c1a"
+ selected_highlight="#446e1c">
+ <space>
+ <ThemeSpaceGeneric back="#444444"
+ title="#000000"
+ text="#dddddd"
+ text_hi="#ffffff"
+ header="#444444"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#444444"
+ header_text="#dddddd"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#444444"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#576471"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#3a3a3a"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#444444ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/modo.xml b/release/scripts/addons_contrib/presets/interface_theme/modo.xml
new file mode 100644
index 0000000..9eccbff
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/modo.xml
@@ -0,0 +1,974 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#000000"
+ inner="#979999ff"
+ inner_sel="#646464ff"
+ item="#000000ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#191919"
+ inner="#606060ff"
+ inner_sel="#f49c1cff"
+ item="#000000ff"
+ text="#f1f1f1"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#000000"
+ inner="#464646ff"
+ inner_sel="#f49c1cff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#93a56f"
+ inner="#999999ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#fdfdfd"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="25">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#000000"
+ inner="#686868ff"
+ inner_sel="#f49c1cff"
+ item="#000000ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#302e2e"
+ inner="#999999ff"
+ inner_sel="#f49c1cff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#191919"
+ inner="#9098a0ff"
+ inner_sel="#f49c1cff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#191919"
+ inner="#b4b4b4ff"
+ inner_sel="#999999ff"
+ item="#9098a0ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#191919"
+ inner="#464646ff"
+ inner_sel="#646464ff"
+ item="#000000ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#000000"
+ inner="#606060ff"
+ inner_sel="#f49c1cff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#606060ff"
+ inner_sel="#f49c1cff"
+ item="#ffffffff"
+ text="#888888"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#000000"
+ inner="#606060e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#f49c1cff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="38"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#323232"
+ inner="#505050b4"
+ inner_sel="#646464b4"
+ item="#606060ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#000000"
+ inner="#bebebeff"
+ inner_sel="#646464b4"
+ item="#444444ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#f49c1cff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#c9ce20"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#5b6672"
+ wire="#000000"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#f15800"
+ object_active="#ff8c19"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ edge_select="#ffa000"
+ edge_seam="#db2512"
+ edge_sharp="#ff2020"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ face="#00000012"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="4"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#002000"
+ extra_face_area="#000080"
+ editmesh_active="#ffffff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGradient title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#48484857"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ <gradients>
+ <ThemeGradientColors show_grad="TRUE"
+ gradient="#3a3e47"
+ high_gradient="#838790">
+ </ThemeGradientColors>
+ </gradients>
+ </ThemeSpaceGradient>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#5b6672"
+ window_sliders="#969696"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#000000"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="3"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#ff8c19"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#fafafa"
+ text_hi="#0f0f0f"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#726f6dff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5b6672"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#5b6672"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#60c040"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#727272ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#5b6672"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#72727242"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#484848"
+ title="#000000"
+ text="#000000"
+ text_hi="#000000"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#dff5ff"
+ button="#727272ff"
+ button_title="#3f3a2f"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#404040"
+ selected_text="#c67777"
+ cursor="#ff0000"
+ syntax_builtin="#800050"
+ syntax_symbols="#4c4c4c"
+ syntax_special="#5f5f00"
+ syntax_preprocessor="#32008c"
+ syntax_reserved="#8c3c00"
+ syntax_comment="#006432"
+ syntax_string="#640000"
+ syntax_numbers="#0000c8">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#5b6672"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#000000"
+ wire_select="#ffffff"
+ selected_text="#7f7070"
+ node_backdrop="#9b9b9ba0"
+ in_out_node="#646464"
+ converter_node="#686a75"
+ operator_node="#6c696f"
+ group_node="#69756e"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272722f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#82878c">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#0e0e0e"
+ text="#000000"
+ text_hi="#f49c1c"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#070707"
+ button_text="#000000"
+ button_text_hi="#fdfcff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#c8c6c9"
+ text="#888884"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#888888"
+ header_text_hi="#ffffff"
+ button="#725864ff"
+ button_title="#f1c2d8"
+ button_text="#f0f0f0"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#484848"
+ title="#000000"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#fdffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#40464e"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#202020"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/pinkified.xml b/release/scripts/addons_contrib/presets/interface_theme/pinkified.xml
new file mode 100644
index 0000000..7179ed2
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/pinkified.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#191919"
+ inner="#0c0c0cff"
+ inner_sel="#ff1d4aff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#676767"
+ inner="#4d4d4dff"
+ inner_sel="#ff1d4aff"
+ item="#ffffffff"
+ text="#d8d8d8"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#343434"
+ inner="#0c0c0cff"
+ inner_sel="#ff1d4aff"
+ item="#ffffffff"
+ text="#b1b1b1"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="6"
+ shadedown="2">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#1a1a1a"
+ inner="#0d0d0dff"
+ inner_sel="#ff1d4aff"
+ item="#414141ff"
+ text="#686868"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-59"
+ shadedown="3">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#000000"
+ inner="#1b1b1bff"
+ inner_sel="#000000ff"
+ item="#ff002eff"
+ text="#808080"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-14"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#343434"
+ inner="#3e3e3eff"
+ inner_sel="#ff1d4aff"
+ item="#1a1a1aff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="27"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#343434"
+ inner="#0c0c0cff"
+ inner_sel="#ff1d4aff"
+ item="#5a5a5aff"
+ text="#757575"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="9"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#343434"
+ inner="#33141bff"
+ inner_sel="#ff1d4aff"
+ item="#800f26ff"
+ text="#f7f7f7"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-16"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#343434"
+ inner="#00000066"
+ inner_sel="#ff1d4aff"
+ item="#ffffffff"
+ text="#999999"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#343434"
+ inner="#2a2a2aff"
+ inner_sel="#ff1d4aff"
+ item="#000000ff"
+ text="#dddddd"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="12"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#0c0c0cff"
+ inner_sel="#ff1d4aff"
+ item="#ffffffff"
+ text="#b6b6b6"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#3f3e3e"
+ inner="#0c0c0cd0"
+ inner_sel="#414141ff"
+ item="#232323ff"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="4"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#222222"
+ inner="#0c0c0c4e"
+ inner_sel="#ff1d4aff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="8"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#111111"
+ inner="#00000080"
+ inner_sel="#000000ff"
+ item="#4d4d4d33"
+ text="#bababa"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="12"
+ shadedown="12">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#5d001a"
+ inner="#000000ff"
+ inner_sel="#686868ff"
+ item="#be0037ff"
+ text="#ffffff"
+ text_sel="#ff1d4a"
+ show_shaded="FALSE"
+ shadetop="100"
+ shadedown="-88">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#4e4e4e"
+ inner="#c69e9e00"
+ inner_sel="#4d262eff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-12"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#194a00"
+ inner_anim_sel="#287700"
+ inner_key="#ffdf44"
+ inner_key_sel="#b39400"
+ inner_driven="#b566ff"
+ inner_driven_sel="#ce99ff"
+ blend="1">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#181818"
+ wire="#505050"
+ lamp="#977f491e"
+ speaker="#a63904"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#d1687d"
+ object_active="#ff0034"
+ object_grouped="#127112"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#9a001f"
+ vertex_select="#ff0034"
+ vertex_size="4"
+ edge_select="#b30025"
+ edge_seam="#ff0000"
+ edge_sharp="#7bff00"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ face="#ffffff0c"
+ face_select="#e8142f2c"
+ face_dot="#ac0023"
+ facedot_size="4"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#f0ff40"
+ extra_edge_len="#200000"
+ extra_face_angle="#008200"
+ extra_face_area="#0000ff"
+ editmesh_active="#ff5edece"
+ normal="#27ffff"
+ vertex_normal="#2361dd"
+ bone_solid="#424242"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#a0a0a0"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#111111"
+ title="#c7c7c7"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#757575"
+ header_text_hi="#ffffff"
+ button="#16161657"
+ button_title="#cccccc"
+ button_text="#6a6a6a"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#1d1d1d"
+ window_sliders="#3b3b3b"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ff004b"
+ vertex_size="3"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#000000"
+ frame_current="#99112c"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff004b"
+ handle_vertex_size="3"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#4c5966"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#232323"
+ title="#ffffff"
+ text="#828282"
+ text_hi="#ffffff"
+ header="#232323"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#232323ff"
+ button_title="#ffffff"
+ button_text="#757575"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#232323"
+ list_title="#8d7878"
+ list_text="#cccccc"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#88172d"
+ scrollbar="#242424"
+ scroll_handle="#373737"
+ active_file="#ff004b"
+ active_file_text="#ffffff">
+ <space>
+ <ThemeSpaceGeneric back="#161616"
+ title="#ffffff"
+ text="#fafafa"
+ text_hi="#ffffff"
+ header="#161616"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#161616ff"
+ button_title="#eaeaea"
+ button_text="#dddddd"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#181818"
+ list_title="#9b9b9b"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#99112c">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#0b0b0b"
+ value_sliders="#000000"
+ view_sliders="#898989"
+ channels="#676767"
+ channels_selected="#ff8099"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff7500"
+ frame_current="#99112c"
+ dopesheet_channel="#39434d"
+ dopesheet_subchannel="#15171a"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#2a2a2a"
+ title="#ffffff"
+ text="#828282"
+ text_hi="#ffffff"
+ header="#2a2a2a"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#2a2a2aff"
+ button_title="#ffffff"
+ button_text="#636363"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#2a2a2a"
+ list_title="#ffffff"
+ list_text="#b3b3b3"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#f73c00"
+ vertex_select="#df0041"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#ff1d4a1a"
+ face_dot="#ff3d1d"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#0707075e"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#1a1a1a"
+ title="#ffffff"
+ text="#9c9c9c"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#272727"
+ header_text_hi="#ffffff"
+ button="#070707ff"
+ button_title="#ffffff"
+ button_text="#bebebe"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#414141"
+ window_sliders="#6d6d6d"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#675379"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#e270a6"
+ transition_strip="#b33d59"
+ meta_strip="#6d9183"
+ frame_current="#99112c"
+ keyframe="#ff9f00"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#171717"
+ title="#ffffff"
+ text="#757575"
+ text_hi="#ffffff"
+ header="#171717"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#17171742"
+ button_title="#ffffff"
+ button_text="#979797"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#1a1a1a"
+ title="#aeaeae"
+ text="#999999"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#757575"
+ header_text_hi="#ffffff"
+ button="#1e1e1eff"
+ button_title="#414141"
+ button_text="#4e4e4e"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#0a0a0a"
+ selected_text="#561423"
+ cursor="#ffffff"
+ syntax_builtin="#ff009a"
+ syntax_special="#ffff00"
+ syntax_comment="#00ff7a"
+ syntax_string="#f20000"
+ syntax_numbers="#0088ff">
+ <space>
+ <ThemeSpaceGeneric back="#050505"
+ title="#ffffff"
+ text="#a9a9a9"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#f2f2f2"
+ header_text_hi="#ffffff"
+ button="#1a1a1aff"
+ button_title="#d0d0d0"
+ button_text="#ffffff"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#343434"
+ frame_current="#ff1d4a">
+ <space>
+ <ThemeSpaceGeneric back="#232323"
+ title="#757575"
+ text="#757575"
+ text_hi="#ffffff"
+ header="#232323"
+ header_text="#828282"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#0d0d0d"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#ff0000"
+ wire_select="#ffe500"
+ selected_text="#ffdddd"
+ node_backdrop="#454545ae"
+ in_out_node="#d9003a"
+ converter_node="#00465d"
+ operator_node="#d87200"
+ group_node="#26960e"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#111111"
+ title="#ffffff"
+ text="#ffffff"
+ text_hi="#565656"
+ header="#111111"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#0c0c0c2f"
+ button_title="#ffffff"
+ button_text="#bebebe"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#ffffff"
+ list_text="#343434"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#272727"
+ title="#ffffff"
+ text="#9d9d9d"
+ text_hi="#ffffff"
+ header="#272727"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#111111ff"
+ button_title="#ffffff"
+ button_text="#ffffff"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#870027">
+ <space>
+ <ThemeSpaceGeneric back="#232323"
+ title="#ffffff"
+ text="#939393"
+ text_hi="#ffffff"
+ header="#232323"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#585858ff"
+ button_title="#ffffff"
+ button_text="#8f8f8f"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#090909"
+ title="#ffffff"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#222222"
+ header_text="#999999"
+ header_text_hi="#cbcbcb"
+ button="#161616ff"
+ button_title="#0d0d0d"
+ button_text="#0d0d0d"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#1a1a1a"
+ title="#f2f2f2"
+ text="#686868"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#414141"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#ff336e"
+ line_input="#a4a4a4"
+ line_info="#ffd600"
+ line_error="#00df62"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#828282"
+ text="#828282"
+ text_hi="#ffffff"
+ header="#1a1a1a"
+ header_text="#ffffff"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#ffffff"
+ button_text="#343434"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#3c3c3c"
+ marker="#f68026"
+ active_marker="#ffe6ea"
+ selected_marker="#ff2550"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0b22"
+ path_after="#007dff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="6"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#232323"
+ title="#6b6b6b"
+ text="#888888"
+ text_hi="#ffffff"
+ header="#232323"
+ header_text="#aaaaaa"
+ header_text_hi="#ffffff"
+ button="#0b0b0bff"
+ button_title="#adadad"
+ button_text="#888888"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/softblend.xml b/release/scripts/addons_contrib/presets/interface_theme/softblend.xml
new file mode 100644
index 0000000..58c96b0
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/softblend.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#5f5e5c"
+ inner="#7b7978ff"
+ inner_sel="#95adc1ff"
+ item="#979594ff"
+ text="#1a1a1a"
+ text_sel="#1a1a1a"
+ show_shaded="TRUE"
+ shadetop="-2"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#a6a4a2"
+ inner="#aaa8a6ff"
+ inner_sel="#a19f9dff"
+ item="#a19f9dff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-6">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#aaa8a6"
+ inner="#a8a6a4ff"
+ inner_sel="#95adc1ff"
+ item="#aaa8a6ff"
+ text="#1a1a1a"
+ text_sel="#1a1a1a"
+ show_shaded="TRUE"
+ shadetop="-2"
+ shadedown="1">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#aaa8a6"
+ inner="#a6a4a2ff"
+ inner_sel="#f1e593ff"
+ item="#c2b876ff"
+ text="#242424"
+ text_sel="#242424"
+ show_shaded="TRUE"
+ shadetop="-2"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#acaaa8"
+ inner="#a5a3a1ff"
+ inner_sel="#ccc9c7ff"
+ item="#000000ff"
+ text="#676767"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="-2"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#aaa8a6"
+ inner="#a8a6a4ff"
+ inner_sel="#95adc1ff"
+ item="#aaa8a6ff"
+ text="#1c1c1c"
+ text_sel="#1a1a1a"
+ show_shaded="TRUE"
+ shadetop="-3"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#050505"
+ inner="#353432ff"
+ inner_sel="#353432ff"
+ item="#222222ff"
+ text="#efefef"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#050505"
+ inner="#353432ff"
+ inner_sel="#353432ff"
+ item="#1f1f1fff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#9f9d9b"
+ inner="#aaa8a6ff"
+ inner_sel="#aaa8a6ff"
+ item="#ccccccff"
+ text="#474747"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="6">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#aaa8a6"
+ inner="#aaa8a6ff"
+ inner_sel="#b0aeacff"
+ item="#8e8c8bff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="-4"
+ shadedown="3">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#474747"
+ inner="#aaa8a6ff"
+ inner_sel="#aaa8a6ff"
+ item="#ccccccff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#474747"
+ inner="#aaa8a6ff"
+ inner_sel="#aaa8a6ff"
+ item="#ccccccff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#474747"
+ inner="#00000000"
+ inner_sel="#aaa8a6ff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-10"
+ shadedown="10">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#82807f"
+ inner="#a4a2a0ff"
+ inner_sel="#aaa8a6ff"
+ item="#a2a19fff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="4"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#474747"
+ inner="#aaa8a6ff"
+ inner_sel="#aaa8a6ff"
+ item="#96c78eff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="3"
+ shadedown="-3">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#8c8a88"
+ inner="#f1e59333"
+ inner_sel="#fff29c9a"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#adb4c7"
+ inner_anim_sel="#c4cee0"
+ inner_key="#c0bb83"
+ inner_key_sel="#dad37d"
+ inner_driven="#c69cb1"
+ inner_driven_sel="#ecaacd"
+ blend="1">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#6e6e6e"
+ wire="#242424"
+ lamp="#ffe56666"
+ speaker="#000000"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#88fca7"
+ object_active="#ffffff"
+ object_grouped="#63bd87"
+ object_grouped_active="#ffffff"
+ transform="#ffffff"
+ vertex="#343434"
+ vertex_select="#ff2f7a"
+ vertex_size="4"
+ edge_select="#f3f3f3"
+ edge_seam="#f0703b"
+ edge_sharp="#49a1ec"
+ edge_crease="#eb3bdd"
+ edge_facesel="#272727"
+ face="#838383ff"
+ face_select="#949494ff"
+ face_dot="#52f27e"
+ facedot_size="3"
+ nurb_uline="#a3a3a3"
+ nurb_vline="#803060"
+ nurb_sel_uline="#ffffff"
+ nurb_sel_vline="#f090a0"
+ act_spline="#c36c8c"
+ handle_free="#cccccc"
+ handle_auto="#30b6e5"
+ handle_vect="#afafaf"
+ handle_align="#e277b1"
+ handle_sel_free="#ffffff"
+ handle_sel_auto="#ffffff"
+ handle_sel_vect="#ffffff"
+ handle_sel_align="#ffffff"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#cccccc"
+ extra_face_area="#cccccc"
+ editmesh_active="#ffffff00"
+ normal="#9cfcc8"
+ vertex_normal="#68a1db"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#53c03b"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#918f8d"
+ title="#ffffff"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a657"
+ button_title="#313131"
+ button_text="#222222"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#8f8f8f"
+ window_sliders="#4d4d4d"
+ channels_region="#4d4d4d"
+ vertex="#575757"
+ vertex_select="#ffffff"
+ vertex_size="3"
+ handle_free="#252525"
+ handle_auto="#696969"
+ handle_vect="#191919"
+ handle_align="#1d1d1d"
+ handle_sel_free="#ececec"
+ handle_sel_auto="#d4d4d4"
+ handle_sel_vect="#ffffff"
+ handle_sel_align="#f3f3f3"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ lastsel_point="#000000"
+ frame_current="#a1ff8c"
+ handle_vertex="#525252"
+ handle_vertex_select="#f1f1f1"
+ handle_vertex_size="6"
+ channel_group="#8a9dac"
+ active_channels_group="#95adc1"
+ dopesheet_channel="#aaa8a6"
+ dopesheet_subchannel="#aaa8a6">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#000000"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#333333"
+ button_text="#222222"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#aaa8a6"
+ list_title="#676767"
+ list_text="#222222"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#f1e593"
+ scrollbar="#4d4b4d"
+ scroll_handle="#8c8a88"
+ active_file="#f1e593"
+ active_file_text="#ffffff">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#ffffff"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#afafaf"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#222222"
+ button_text="#cccccc"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#aaa8a6"
+ list_title="#3a3a3a"
+ list_text="#7f7f7f"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#a39f9c"
+ view_sliders="#4d4d4d"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#000000"
+ strips_selected="#60c040"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#a3ff96">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#000000"
+ text="#333333"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#a3a3a3"
+ header_text_hi="#cccccc"
+ button="#aaa8a6ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#aaa8a6"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#7f7f7f"
+ value_sliders="#000000"
+ view_sliders="#333333"
+ channels="#9baeb9"
+ channels_selected="#91ccb3"
+ channel_group="#8a9dac"
+ active_channels_group="#95adc1"
+ long_key="#0c0a0a"
+ long_key_selected="#ecfc37"
+ frame_current="#a3ff96"
+ dopesheet_channel="#9baeb9"
+ dopesheet_subchannel="#aaa8a6"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#ffffff"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#111111"
+ button_text="#111111"
+ button_text_hi="#a3a3a3">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#aaa8a6"
+ list_title="#cccccc"
+ list_text="#222222"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#000000"
+ vertex_select="#ffffff"
+ vertex_size="3"
+ face="#00000032"
+ face_select="#ffffff3c"
+ face_dot="#ffffff"
+ facedot_size="2"
+ editmesh_active="#ffffff80"
+ scope_back="#aaa8a6ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#2d2d2d"
+ title="#000000"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#383838"
+ button_text="#222222"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#afafaf"
+ window_sliders="#777777"
+ movie_strip="#87a4c3"
+ movieclip_strip="#20208f"
+ image_strip="#c99ac0"
+ scene_strip="#91b1a0"
+ audio_strip="#e0d2a0"
+ effect_strip="#be8c76"
+ transition_strip="#d9777a"
+ meta_strip="#91918d"
+ frame_current="#a3ff96"
+ keyframe="#ffeb89"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#000000"
+ text="#333333"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#a3a3a3"
+ header_text_hi="#ffffff"
+ button="#aaa8a642"
+ button_title="#111111"
+ button_text="#111111"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#222222"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#222222"
+ header_text_hi="#000000"
+ button="#aaa8a6ff"
+ button_title="#222222"
+ button_text="#222222"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#a3a3a3"
+ selected_text="#f1e593"
+ cursor="#54da70"
+ syntax_builtin="#3162b2"
+ syntax_special="#ca0c97"
+ syntax_comment="#535353"
+ syntax_string="#c31736"
+ syntax_numbers="#b62440">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#000000"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#222222"
+ button_text="#333333"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#838383"
+ frame_current="#a3ff96">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#cccccc"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#a3a3a3"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#aeacaa"
+ button_text="#222222"
+ button_text_hi="#a3a3a3">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#222222"
+ wire_select="#ffffff"
+ selected_text="#ffffff"
+ node_backdrop="#d4d4d4ff"
+ in_out_node="#b1d9ff"
+ converter_node="#fffa90"
+ operator_node="#beffcb"
+ group_node="#ffc173"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#a3a3a3"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#333333"
+ header_text_hi="#ffffff"
+ button="#aaa8a62f"
+ button_title="#222222"
+ button_text="#222222"
+ button_text_hi="#c5c5c5">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#4d4d4d"
+ list_title="#383838"
+ list_text="#676767"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#202020"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#111111"
+ button_text="#222222"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#870027">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#ffffff"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#0f0f0f"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#222222"
+ text="#222222"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc3a77"
+ cursor="#9cfcc8">
+ <space>
+ <ThemeSpaceGeneric back="#0c0c0c"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#4d4d4dff"
+ button_title="#131313"
+ button_text="#131313"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#71cd7f"
+ active_marker="#ffffff"
+ selected_marker="#ff2f7a"
+ disabled_marker="#b54636"
+ locked_marker="#7f7f7f"
+ path_before="#22d8d1"
+ path_after="#5a7575"
+ grid="#5e5e5e"
+ frame_current="#a3ff96"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff2f7a"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#aaa8a6"
+ title="#1a1a1a"
+ text="#1a1a1a"
+ text_hi="#ffffff"
+ header="#aaa8a6"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaa8a6ff"
+ button_title="#222222"
+ button_text="#222222"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000004"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/softdefault.xml b/release/scripts/addons_contrib/presets/interface_theme/softdefault.xml
new file mode 100644
index 0000000..74c5b25
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/softdefault.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#000000"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#646464"
+ inner="#727272ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#646464"
+ inner="#6c6c6cff"
+ inner_sel="#6b8cafff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#646464"
+ inner="#727272ff"
+ inner_sel="#dbcc6fff"
+ item="#91874aff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#646464"
+ inner="#727272ff"
+ inner_sel="#838383ff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#646464"
+ inner="#727272ff"
+ inner_sel="#6b8cafff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#606060"
+ inner="#595959ff"
+ inner_sel="#444444ff"
+ item="#3b3b3bff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#606060"
+ inner="#595959ff"
+ inner_sel="#595959ff"
+ item="#494949ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-20"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#646464"
+ inner="#6c6c6cff"
+ inner_sel="#6c6c6cff"
+ item="#4a4a4aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#606060"
+ inner="#727272ff"
+ inner_sel="#6c6c6cff"
+ item="#464646ff"
+ text="#000000"
+ text_sel="#f5f5f5"
+ show_shaded="TRUE"
+ shadetop="-5"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#606060"
+ inner="#3f3f3fff"
+ inner_sel="#727272ff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#505050"
+ inner="#727272ff"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#000000"
+ text_sel="#ececec"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#727272"
+ inner="#00000000"
+ inner_sel="#727272ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-8"
+ shadedown="5">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#6a6a6a"
+ inner="#727272ff"
+ inner_sel="#646464ff"
+ item="#626262ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#727272"
+ inner="#758b69ff"
+ inner_sel="#93af84ff"
+ item="#93af84ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#6b8cafff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#98cc7e"
+ inner_anim_sel="#5aa633"
+ inner_key="#f0ec75"
+ inner_key_sel="#d7d34b"
+ inner_driven="#cf5bff"
+ inner_driven_sel="#ac45d7"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#555555"
+ wire="#000000"
+ lamp="#e3d45966"
+ speaker="#5c6db2"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#ffffff"
+ object_active="#ffffff"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#000000"
+ vertex_select="#ff6424"
+ vertex_size="3"
+ edge_select="#e3e3e3"
+ edge_seam="#db5c3d"
+ edge_sharp="#3a9fff"
+ edge_crease="#cc57b4"
+ edge_facesel="#4b4b4b"
+ face="#00000058"
+ face_select="#0000003c"
+ face_dot="#9bff61"
+ facedot_size="3"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#002000"
+ extra_face_area="#000080"
+ editmesh_active="#ffffff72"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#404040"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#72727257"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#5e5e5e"
+ window_sliders="#969696"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ffffff"
+ vertex_size="5"
+ handle_free="#ffffff"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#ffffff"
+ handle_sel_vect="#6ee854"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#000000"
+ frame_current="#7ec068"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffffff"
+ handle_vertex_size="8"
+ channel_group="#8686b0"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#76879c"
+ dopesheet_subchannel="#8699b0">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#1e1e1e"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7979"
+ active_file="#727272"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#4c4c4c"
+ title="#000000"
+ text="#fafafa"
+ text_hi="#0f0f0f"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#7ec068">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#5e5e5e"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#60c040"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#727272ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#353535"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#404040"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#747474"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#72727242"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#7c7c7c"
+ selected_text="#bdbd8d"
+ cursor="#afff80"
+ syntax_builtin="#ff5353"
+ syntax_special="#92da66"
+ syntax_comment="#ffffff"
+ syntax_string="#f7f185"
+ syntax_numbers="#7dc8c8">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#565656"
+ frame_current="#7ec068">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#000000"
+ wire_select="#ffffff"
+ selected_text="#ffffff"
+ node_backdrop="#858585ff"
+ in_out_node="#b0cae0"
+ converter_node="#b5b1ea"
+ operator_node="#ffa46c"
+ group_node="#d5ffa2"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272722f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#646464"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#82878c">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#e4e585"
+ line_error="#dc6060"
+ cursor="#8bdc66">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#393939"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/toxic.xml b/release/scripts/addons_contrib/presets/interface_theme/toxic.xml
new file mode 100644
index 0000000..8aa87a5
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/toxic.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#0a0a0aff"
+ inner_sel="#84b600ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#79b224ff"
+ inner_sel="#80b200ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#7eb000ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#7cae00ff"
+ item="#191919ff"
+ text="#e4e4e4"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#7aac00ff"
+ item="#ffffffff"
+ text="#c7c7c7"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#78aa00ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#76a800ff"
+ item="#2a2a2aff"
+ text="#929292"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#111111ff"
+ item="#74a600ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#72a400ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#70a200ff"
+ item="#2a2a2aff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#6ea000ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#6c9e00ff"
+ item="#191919ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#6a9c00ff"
+ item="#191919ff"
+ text="#fdfdfd"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#171717ff"
+ inner_sel="#689a00ff"
+ item="#689a00ff"
+ text="#fdfdfd"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#669800ff"
+ item="#191919ff"
+ text="#fdfdfd"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#111111ff"
+ inner_sel="#649600ff"
+ item="#191919ff"
+ text="#fdfdfd"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-100"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#56ff00"
+ inner_anim_sel="#56ff00"
+ inner_key="#fff400"
+ inner_key_sel="#fff400"
+ inner_driven="#629400"
+ inner_driven_sel="#609200"
+ blend="0.1">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#3f3f3f"
+ wire="#888888"
+ lamp="#c1d40028"
+ speaker="#535353"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#3ebe2e"
+ object_active="#97ff22"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#72cfdd"
+ vertex_select="#3cbc2c"
+ vertex_size="3"
+ edge_select="#3cbc2c"
+ edge_seam="#db2512"
+ edge_sharp="#ff2020"
+ edge_crease="#cc0099"
+ edge_facesel="#6b6b6b"
+ face="#73828f12"
+ face_select="#3aba2a3c"
+ face_dot="#95fd20"
+ facedot_size="4"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#7f7f7f"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#3b3b3b"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#ffedf8"
+ extra_face_angle="#00c900"
+ extra_face_area="#fff000"
+ editmesh_active="#ffffff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#5a5a5a"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#0f0f0f"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#00000057"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#262626"
+ window_sliders="#969696"
+ channels_region="#6d6d6d"
+ vertex="#ffffff"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ handle_free="#808080"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#808080"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#808080"
+ frame_current="#336622"
+ handle_vertex="#808080"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="3"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#0d0d0d"
+ title="#5d5d5d"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#1a1a1a"
+ list_title="#000000"
+ list_text="#bbbbbb"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#2f6629"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#b1b1b1"
+ active_file_text="#ffffff">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#181818"
+ list_title="#9e9e9e"
+ list_text="#5d5d5d"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#aa8d8d"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#2f6421">
+ <space>
+ <ThemeSpaceGeneric back="#0d0d0d"
+ title="#585858"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c3c3c3"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#0c0c0c"
+ list_title="#383838"
+ list_text="#d8d8d8"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#212121"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#2a5c1c"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#080808"
+ title="#5d5d5d"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#020202"
+ list_title="#2c2c2c"
+ list_text="#ebebeb"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#0f13bb"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ face="#ffffff0a"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#050505ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#282828"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#2f5f23"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#202020"
+ title="#5d5d5d"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#f3f3f3"
+ header_text_hi="#ffffff"
+ button="#02020242"
+ button_title="#bdbdbd"
+ button_text="#dddddd"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#0e0e0eff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#191919"
+ selected_text="#ffffff"
+ cursor="#ff0000"
+ syntax_builtin="#cf3d99"
+ syntax_special="#969629"
+ syntax_comment="#249d60"
+ syntax_string="#cc3535"
+ syntax_numbers="#3c68ff">
+ <space>
+ <ThemeSpaceGeneric back="#050505"
+ title="#9e9e9e"
+ text="#ebebeb"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#b9b9b9"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#d8d8d8"
+ button_text="#cccccc"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#707070"
+ frame_current="#3fff00">
+ <space>
+ <ThemeSpaceGeneric back="#162c0c"
+ title="#5d5d5d"
+ text="#c7c7c7"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#161616ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#6eafff"
+ wire_select="#0019ff"
+ selected_text="#7f7070"
+ node_backdrop="#202030bc"
+ in_out_node="#273053"
+ converter_node="#113941"
+ operator_node="#0e3157"
+ group_node="#091a07"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#c7c7c7"
+ header_text_hi="#ffffff"
+ button="#0000002f"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#ffffff"
+ list_text="#ffffff"
+ list_text_hi="#b8ffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#070707"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#356c1a"
+ selected_highlight="#446e1c">
+ <space>
+ <ThemeSpaceGeneric back="#070707"
+ title="#9b9b9b"
+ text="#cccccc"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#5d5d5d"
+ text="#9b9b9b"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#adadad"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#cecece"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#0f0f0f"
+ title="#5d5d5d"
+ text="#7d7d7d"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#000000ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#0094af"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#1b501b"
+ handle_vertex="#e2e2e2"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#0d0d0d"
+ title="#5d5d5d"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#000000"
+ header_text="#979797"
+ header_text_hi="#ffffff"
+ button="#070707ff"
+ button_title="#c5c5c5"
+ button_text="#c3c3c3"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#000000ff"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/interface_theme/zbrush.xml b/release/scripts/addons_contrib/presets/interface_theme/zbrush.xml
new file mode 100644
index 0000000..ee8a839
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/interface_theme/zbrush.xml
@@ -0,0 +1,964 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface icon_file=""
+ icon_alpha="1"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#191919"
+ inner="#999999ff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#1f1f1f"
+ inner="#333333ff"
+ inner_sel="#c28d45ff"
+ item="#191919ff"
+ text="#b8b8b8"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#1f1f1f"
+ inner="#333333ff"
+ inner_sel="#c28d45ff"
+ item="#ffffffff"
+ text="#b8b8b8"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#303030"
+ inner="#7a8287ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#1f1f1f"
+ inner="#3b3b3bff"
+ inner_sel="#c28d45ff"
+ item="#ffffffff"
+ text="#b8b8b8"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#1f1f1f"
+ inner="#333333ff"
+ inner_sel="#c28d45ff"
+ item="#191919ff"
+ text="#b8b8b8"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#1f1f1f"
+ inner="#333333ff"
+ inner_sel="#999999ff"
+ item="#727272ff"
+ text="#b8b8b8"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#303030"
+ inner="#606068ff"
+ inner_sel="#91919dff"
+ item="#3a3a3aff"
+ text="#dfdfdf"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-10"
+ shadedown="10">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#2a2a2a"
+ inner="#3e3e3eff"
+ inner_sel="#646464ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="-7">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#151515"
+ inner="#2f2f2fff"
+ inner_sel="#464646ff"
+ item="#777777ff"
+ text="#b8b8b8"
+ text_sel="#cccccc"
+ show_shaded="TRUE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#3f3f3fff"
+ inner_sel="#c28d45ff"
+ item="#ffffffff"
+ text="#b8b8b8"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="25"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#000000"
+ inner="#3b3b3bff"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#b8b8b8"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#c28d45ff"
+ item="#ffffffff"
+ text="#b8b8b8"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="20">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#1c1c1c"
+ inner="#07070719"
+ inner_sel="#646464b4"
+ item="#2e2e2eff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#000000"
+ inner="#bebebeff"
+ inner_sel="#646464b4"
+ item="#444444ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#75582aae"
+ item="#000000ff"
+ text="#e0e0e0"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="0"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#f0eb64"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#353535"
+ wire="#000000"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ empty="#000000"
+ object_selected="#f1f1f1"
+ object_active="#c28d45"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#a8a8a8"
+ vertex_select="#c28d45"
+ vertex_size="3"
+ edge_select="#c28d45"
+ edge_seam="#db2512"
+ edge_sharp="#00ffff"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ face="#00000054"
+ face_select="#81602e73"
+ face_dot="#c28d45"
+ facedot_size="2"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_face_angle="#000080"
+ extra_face_area="#002000"
+ editmesh_active="#ffffff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#2c2e30"
+ title="#000000"
+ text="#b8b8b8"
+ text_hi="#e9e9e9"
+ header="#3b3b3b"
+ header_text="#b9b9b9"
+ header_text_hi="#ffffff"
+ button="#3b3b3b57"
+ button_title="#949494"
+ button_text="#878787"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#4b4b4b"
+ window_sliders="#969696"
+ channels_region="#707070"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_vect="#40c030"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#ffffff"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="4"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996">
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#8b8b8b"
+ text="#848484"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#8b8b8b"
+ button_text="#8b8b8b"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#3b3b3b"
+ list_title="#8b8b8b"
+ list_text="#8b8b8b"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#755729"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#3a3a3a"
+ title="#8b8b8b"
+ text="#cacaca"
+ text_hi="#0f0f0f"
+ header="#3b3b3b"
+ header_text="#8b8b8b"
+ header_text_hi="#ffffff"
+ button="#303030ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#3b3b3b"
+ list_title="#8b8b8b"
+ list_text="#8b8b8b"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#585858"
+ view_sliders="#969696"
+ active_action="#00000000"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#4b4b4b"
+ title="#8b8b8b"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#3b3b3b"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#4b4b4b"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ frame_current="#60c040"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ summary="#00000000">
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#000000"
+ text="#848484"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#aaaaaaff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#3b3b3b"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor vertex="#a8a8a8"
+ vertex_select="#c28d45"
+ vertex_size="3"
+ face="#7c7c7c0a"
+ face_select="#c28d453c"
+ face_dot="#c28d45"
+ facedot_size="3"
+ editmesh_active="#ffffff80"
+ scope_back="#3b3b3bff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#ff8500b2"
+ preview_stitch_vert="#ff85007f"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323">
+ <space>
+ <ThemeSpaceGeneric back="#303030"
+ title="#8b8b8b"
+ text="#8b8b8b"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#8b8b8b"
+ button_text="#8b8b8b"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor grid="#818181"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#8b8b8b"
+ text="#848484"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3b42"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#6d6d6d"
+ text="#b8b8b8"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#b8b8b8"
+ button_text="#b8b8b8"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#404040"
+ selected_text="#c67777"
+ cursor="#ff0000"
+ syntax_builtin="#800050"
+ syntax_special="#5f5f00"
+ syntax_comment="#006432"
+ syntax_string="#640000"
+ syntax_numbers="#0000c8">
+ <space>
+ <ThemeSpaceGeneric back="#4b4b4b"
+ title="#8b8b8b"
+ text="#b8b8b8"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#8b8b8b"
+ button_text="#8b8b8b"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#464646"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#303030"
+ title="#000000"
+ text="#848484"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor node_selected="#ffffff"
+ node_active="#ffffff"
+ wire="#000000"
+ wire_select="#ffffff"
+ selected_text="#7f7070"
+ node_backdrop="#9b9b9ba0"
+ in_out_node="#646464"
+ converter_node="#686a75"
+ operator_node="#6c696f"
+ group_node="#69756e"
+ frame_node="#9a9b9ba0"
+ noodle_curving="5">
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#8b8b8b"
+ text="#8b8b8b"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3b2f"
+ button_title="#8b8b8b"
+ button_text="#8b8b8b"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#8b8b8b"
+ button_text="#8b8b8b"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#245824"
+ selected_highlight="#212844">
+ <space>
+ <ThemeSpaceGeneric back="#3a3a3a"
+ title="#000000"
+ text="#cacaca"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo>
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#000000"
+ header="#3b3b3b"
+ header_text="#8b8b8b"
+ header_text_hi="#000000"
+ button="#3b3b3bff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#000000">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#3b3b3b"
+ title="#000000"
+ text="#b8b8b8"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#b8b8b8"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060">
+ <space>
+ <ThemeSpaceGeneric back="#202020"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#303030"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ grid="#5e5e5e"
+ frame_current="#60c040"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="4"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00">
+ <space>
+ <ThemeSpaceGeneric back="#2c2e30"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#3b3b3b"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#3b3b3bff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+</bpy>
diff --git a/release/scripts/addons_contrib/presets/keyconfig/blender_2012_experimental.py b/release/scripts/addons_contrib/presets/keyconfig/blender_2012_experimental.py
new file mode 100644
index 0000000..068a2ef
--- /dev/null
+++ b/release/scripts/addons_contrib/presets/keyconfig/blender_2012_experimental.py
@@ -0,0 +1,1487 @@
+""" An experimental new keymap for Blender.
+ Work in progress!
+"""
+import bpy
+
+######################
+# Misc configuration
+######################
+DEVELOPER_HOTKEYS = False # Weird hotkeys that only developers use
+MAYA_STYLE_MANIPULATORS = False # Maya-style "QWER" hotkeys for manipulators
+SUBSURF_RELATIVE = True # Make subsurf hotkeys work by relative
+ # shifting instead of absolute setting
+# Left mouse-button select
+bpy.context.user_preferences.inputs.select_mouse = 'LEFT'
+
+# Basic transform keys
+TRANSLATE_KEY = 'F'
+ROTATE_KEY = 'D'
+SCALE_KEY = 'S'
+
+# Specials Menu Key
+SPECIALS_MENU_KEY = 'Q'
+
+
+################################
+# Helper functions and classes
+################################
+class SetManipulator(bpy.types.Operator):
+ """Set's the manipulator mode"""
+ bl_idname = "view3d.manipulator_set"
+ bl_label = "Set Manipulator"
+ mode = bpy.props.EnumProperty(items=[("NONE", "None", ""),
+ ("TRANSLATE", "Translate", ""),
+ ("ROTATE", "Rotate", ""),
+ ("SCALE", "Scale", "")],
+ default="NONE")
+
+ def execute(self, context):
+ if self.mode == "NONE":
+ context.space_data.show_manipulator = False
+ elif self.mode == "TRANSLATE":
+ context.space_data.show_manipulator = True
+ context.space_data.use_manipulator_translate = True
+ context.space_data.use_manipulator_rotate = False
+ context.space_data.use_manipulator_scale = False
+ elif self.mode == "ROTATE":
+ context.space_data.show_manipulator = True
+ context.space_data.use_manipulator_translate = False
+ context.space_data.use_manipulator_rotate = True
+ context.space_data.use_manipulator_scale = False
+ elif self.mode == "SCALE":
+ context.space_data.show_manipulator = True
+ context.space_data.use_manipulator_translate = False
+ context.space_data.use_manipulator_rotate = False
+ context.space_data.use_manipulator_scale = True
+
+ return {'FINISHED'}
+bpy.utils.register_class(SetManipulator)
+
+
+class ModeSwitchMenu(bpy.types.Menu):
+ """ A menu for switching between object modes.
+ """
+ bl_idname = "OBJECT_MT_mode_switch_menu"
+ bl_label = "Switch Mode"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_enum("object.mode_set", "mode")
+bpy.utils.register_class(ModeSwitchMenu)
+
+
+# Temporary work around: Blender does not properly limit the mode switch menu
+# items until the first mode switch (e.g. mesh objects will show pose mode as
+# an option).
+# TODO: file a bug report for this behavior.
+bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+
+class ObjectDeleteNoConfirm(bpy.types.Operator):
+ """Delete selected objects without the confirmation popup"""
+ bl_idname = "object.delete_no_confirm"
+ bl_label = "Delete Objects No Confirm"
+ bl_options = {'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None
+
+ def execute(self, context):
+ bpy.ops.object.delete()
+
+ return {'FINISHED'}
+bpy.utils.register_class(ObjectDeleteNoConfirm)
+
+
+class ShiftSubsurfLevel(bpy.types.Operator):
+ """Shift the subsurf level of the selected objects up or """ \
+ """down by the given amount (has maximum limit, to avoid """ \
+ """going crazy and running out of RAM)"""
+ bl_idname = "object.shift_subsurf_level"
+ bl_label = "Shift Subsurf Level"
+
+ delta = bpy.props.IntProperty(name="Delta", description="Amount to increase/decrease the subsurf level.", default=1)
+ min = bpy.props.IntProperty(name="Minimum", description="The lowest subsurf level to shift to.", default=0)
+ max = bpy.props.IntProperty(name="Maximum", description="The highest subsurf level to shift to.", default=4)
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None
+
+ def execute(self, context):
+ for obj in context.selected_objects:
+ # Find the last subsurf modifier in the stack
+ m = None
+ for mod in obj.modifiers:
+ if mod.type == "SUBSURF":
+ m = mod
+
+ # Add a subsurf modifier if necessary
+ if not m and self.delta > 0:
+ m = obj.modifiers.new(name="Subsurf", type='SUBSURF')
+ m.levels = 0
+
+ # Adjust it's subsurf level
+ if m:
+ if self.delta > 0:
+ if (m.levels + self.delta) <= self.max:
+ m.levels += self.delta
+ elif self.delta < 0:
+ if (m.levels + self.delta) >= self.min:
+ m.levels += self.delta
+ return {'FINISHED'}
+bpy.utils.register_class(ShiftSubsurfLevel)
+
+
+class SetEditMeshSelectMode(bpy.types.Operator):
+ """Set edit mesh select mode (vert, edge, face)"""
+ bl_idname = "view3d.set_edit_mesh_select_mode"
+ bl_label = "Set Edit Mesh Select Mode"
+ mode = bpy.props.EnumProperty(items=[("VERT", "Vertex", ""),
+ ("EDGE", "Edge", ""),
+ ("FACE", "Face", "")],
+ default="VERT")
+ toggle = bpy.props.BoolProperty(name="Toggle", default=False)
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None
+
+ def execute(self, context):
+ if self.mode == "VERT":
+ mode = 0
+ elif self.mode == "EDGE":
+ mode = 1
+ else: # self.mode == "FACE"
+ mode = 2
+
+ select_mode = context.tool_settings.mesh_select_mode
+ if self.toggle:
+ select_mode[mode] = [True, False][select_mode[mode]]
+ else:
+ select_mode[mode] = True
+ for i in range(0,3):
+ if i != mode:
+ select_mode[i] = False
+
+ return {'FINISHED'}
+bpy.utils.register_class(SetEditMeshSelectMode)
+
+
+class MeshDeleteContextual(bpy.types.Operator):
+ """ Deletes mesh elements based on context instead
+ of forcing the user to select from a menu what
+ it should delete.
+ """
+ bl_idname = "mesh.delete_contextual"
+ bl_label = "Mesh Delete Contextual"
+ bl_options = {'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.active_object is not None) and (context.mode == "EDIT_MESH")
+
+ def execute(self, context):
+ select_mode = context.tool_settings.mesh_select_mode
+
+ if select_mode[0]:
+ bpy.ops.mesh.delete(type='VERT')
+ elif select_mode[1] and not select_mode[2]:
+ bpy.ops.mesh.delete(type='EDGE')
+ elif select_mode[2] and not select_mode[1]:
+ bpy.ops.mesh.delete(type='FACE')
+ else:
+ bpy.ops.mesh.delete(type='VERT')
+
+ return {'FINISHED'}
+bpy.utils.register_class(MeshDeleteContextual)
+
+###########
+# Keymaps
+###########
+
+def clear_keymap(kc):
+ """ Clears all the keymaps, so we can start from scratch, building
+ things back up again one-by-one.
+ """
+ # Map Window
+ km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Screen
+ km = kc.keymaps.new('Screen', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Editing this part of the keymap seems
+ # to cause problems, so leaving alone.
+ # Map Screen Editing
+ #km = kc.keymaps.new('Screen Editing', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map View2D
+ km = kc.keymaps.new('View2D', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Frames
+ km = kc.keymaps.new('Frames', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Header
+ km = kc.keymaps.new('Header', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map View2D Buttons List
+ km = kc.keymaps.new('View2D Buttons List', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Property Editor
+ km = kc.keymaps.new('Property Editor', space_type='PROPERTIES', region_type='WINDOW', modal=False)
+
+ # Map Markers
+ km = kc.keymaps.new('Markers', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Animation
+ km = kc.keymaps.new('Animation', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Timeline
+ km = kc.keymaps.new('Timeline', space_type='TIMELINE', region_type='WINDOW', modal=False)
+
+ # Map Outliner
+ km = kc.keymaps.new('Outliner', space_type='OUTLINER', region_type='WINDOW', modal=False)
+
+ # Map 3D View Generic
+ km = kc.keymaps.new('3D View Generic', space_type='VIEW_3D', region_type='WINDOW', modal=False)
+
+ # Map Grease Pencil
+ km = kc.keymaps.new('Grease Pencil', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Face Mask
+ km = kc.keymaps.new('Face Mask', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Pose
+ km = kc.keymaps.new('Pose', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Object Mode
+ km = kc.keymaps.new('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Image Paint
+ km = kc.keymaps.new('Image Paint', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Vertex Paint
+ km = kc.keymaps.new('Vertex Paint', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Weight Paint
+ km = kc.keymaps.new('Weight Paint', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Sculpt
+ km = kc.keymaps.new('Sculpt', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Mesh
+ km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Curve
+ km = kc.keymaps.new('Curve', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Armature
+ km = kc.keymaps.new('Armature', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Metaball
+ km = kc.keymaps.new('Metaball', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Lattice
+ km = kc.keymaps.new('Lattice', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Particle
+ km = kc.keymaps.new('Particle', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Font
+ km = kc.keymaps.new('Font', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Object Non-modal
+ km = kc.keymaps.new('Object Non-modal', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map 3D View
+ km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
+
+ # Map View3D Gesture Circle
+ km = kc.keymaps.new('View3D Gesture Circle', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map Gesture Border
+ km = kc.keymaps.new('Gesture Border', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map Standard Modal Map
+ km = kc.keymaps.new('Standard Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map Animation Channels
+ km = kc.keymaps.new('Animation Channels', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map UV Editor
+ km = kc.keymaps.new('UV Editor', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map Transform Modal Map
+ km = kc.keymaps.new('Transform Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map UV Sculpt
+ km = kc.keymaps.new('UV Sculpt', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Map View3D Fly Modal
+ km = kc.keymaps.new('View3D Fly Modal', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map View3D Rotate Modal
+ km = kc.keymaps.new('View3D Rotate Modal', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map View3D Move Modal
+ km = kc.keymaps.new('View3D Move Modal', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map View3D Zoom Modal
+ km = kc.keymaps.new('View3D Zoom Modal', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Map Graph Editor Generic
+ km = kc.keymaps.new('Graph Editor Generic', space_type='GRAPH_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Graph Editor
+ km = kc.keymaps.new('Graph Editor', space_type='GRAPH_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Image Generic
+ km = kc.keymaps.new('Image Generic', space_type='IMAGE_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Image
+ km = kc.keymaps.new('Image', space_type='IMAGE_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Node Generic
+ km = kc.keymaps.new('Node Generic', space_type='NODE_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Node Editor
+ km = kc.keymaps.new('Node Editor', space_type='NODE_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map File Browser
+ km = kc.keymaps.new('File Browser', space_type='FILE_BROWSER', region_type='WINDOW', modal=False)
+
+ # Map File Browser Main
+ km = kc.keymaps.new('File Browser Main', space_type='FILE_BROWSER', region_type='WINDOW', modal=False)
+
+ # Map File Browser Buttons
+ km = kc.keymaps.new('File Browser Buttons', space_type='FILE_BROWSER', region_type='WINDOW', modal=False)
+
+ # Map Dopesheet
+ km = kc.keymaps.new('Dopesheet', space_type='DOPESHEET_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map NLA Generic
+ km = kc.keymaps.new('NLA Generic', space_type='NLA_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map NLA Channels
+ km = kc.keymaps.new('NLA Channels', space_type='NLA_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map NLA Editor
+ km = kc.keymaps.new('NLA Editor', space_type='NLA_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Text
+ km = kc.keymaps.new('Text', space_type='TEXT_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Sequencer
+ km = kc.keymaps.new('Sequencer', space_type='SEQUENCE_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Logic Editor
+ km = kc.keymaps.new('Logic Editor', space_type='LOGIC_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Console
+ km = kc.keymaps.new('Console', space_type='CONSOLE', region_type='WINDOW', modal=False)
+
+ # Map Clip
+ km = kc.keymaps.new('Clip', space_type='CLIP_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Clip Editor
+ km = kc.keymaps.new('Clip Editor', space_type='CLIP_EDITOR', region_type='WINDOW', modal=False)
+
+ # Map Clip Graph Editor
+ km = kc.keymaps.new('Clip Graph Editor', space_type='CLIP_EDITOR', region_type='WINDOW', modal=False)
+
+
+
+
+
+def MapAdd_Window(kc):
+ """ Window Map
+ """
+ km = kc.keymaps.new('Window', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Quit
+ kmi = km.keymap_items.new('wm.quit_blender', 'Q', 'PRESS', ctrl=True)
+
+ # Operator search menu
+ kmi = km.keymap_items.new('wm.search_menu', 'TAB', 'CLICK')
+
+ # Open
+ kmi = km.keymap_items.new('wm.open_mainfile', 'O', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('wm.link_append', 'O', 'CLICK', ctrl=True, alt=True)
+ kmi = km.keymap_items.new('wm.link_append', 'O', 'CLICK', ctrl=True, shift=True)
+ kmi.properties.link = False
+ kmi = km.keymap_items.new('wm.read_homefile', 'N', 'CLICK', ctrl=True)
+
+ # Save
+ kmi = km.keymap_items.new('wm.save_mainfile', 'S', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('wm.save_as_mainfile', 'S', 'CLICK', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('wm.save_homefile', 'U', 'CLICK', ctrl=True)
+
+ # NDof Device
+ kmi = km.keymap_items.new('wm.call_menu', 'NDOF_BUTTON_MENU', 'PRESS')
+ kmi.properties.name = 'USERPREF_MT_ndof_settings'
+ kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS')
+ kmi.properties.decrease = False
+ kmi.properties.fast = False
+ kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS')
+ kmi.properties.decrease = True
+ kmi.properties.fast = False
+ kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_PLUS', 'PRESS', shift=True)
+ kmi.properties.decrease = False
+ kmi.properties.fast = True
+ kmi = km.keymap_items.new('wm.ndof_sensitivity_change', 'NDOF_BUTTON_MINUS', 'PRESS', shift=True)
+ kmi.properties.decrease = True
+ kmi.properties.fast = True
+
+ # Misc
+ kmi = km.keymap_items.new('wm.window_fullscreen_toggle', 'F11', 'CLICK', alt=True)
+
+ # Development/debugging
+ if DEVELOPER_HOTKEYS:
+ kmi = km.keymap_items.new('wm.redraw_timer', 'T', 'CLICK', ctrl=True, alt=True)
+ kmi = km.keymap_items.new('wm.debug_menu', 'D', 'CLICK', ctrl=True, alt=True)
+
+ # ???
+ kmi = km.keymap_items.new('info.reports_display_update', 'TIMER', 'ANY', any=True)
+
+
+def MapAdd_Screen(kc):
+ """ Screen Map
+ """
+ km = kc.keymaps.new('Screen', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ kmi = km.keymap_items.new('screen.animation_step', 'TIMER0', 'ANY', any=True)
+ kmi = km.keymap_items.new('screen.screen_set', 'RIGHT_ARROW', 'PRESS', ctrl=True)
+ kmi.properties.delta = 1
+ kmi = km.keymap_items.new('screen.screen_set', 'LEFT_ARROW', 'PRESS', ctrl=True)
+ kmi.properties.delta = -1
+ kmi = km.keymap_items.new('screen.screen_full_area', 'UP_ARROW', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('screen.screen_full_area', 'DOWN_ARROW', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('screen.screen_full_area', 'SPACE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('screen.screenshot', 'F3', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('screen.screencast', 'F3', 'PRESS', alt=True)
+ kmi = km.keymap_items.new('screen.region_quadview', 'Q', 'PRESS', ctrl=True, alt=True)
+ kmi = km.keymap_items.new('screen.repeat_history', 'F3', 'PRESS')
+ kmi = km.keymap_items.new('screen.repeat_last', 'R', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('screen.region_flip', 'F5', 'PRESS')
+ kmi = km.keymap_items.new('screen.redo_last', 'F6', 'PRESS')
+ kmi = km.keymap_items.new('script.reload', 'F8', 'PRESS')
+ kmi = km.keymap_items.new('file.execute', 'RET', 'PRESS')
+ kmi = km.keymap_items.new('file.execute', 'NUMPAD_ENTER', 'PRESS')
+ kmi = km.keymap_items.new('file.cancel', 'ESC', 'PRESS')
+ kmi = km.keymap_items.new('ed.undo', 'Z', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('ed.redo', 'Z', 'PRESS', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('ed.undo_history', 'Z', 'PRESS', ctrl=True, alt=True)
+ kmi = km.keymap_items.new('render.render', 'F12', 'PRESS')
+ kmi = km.keymap_items.new('render.render', 'F12', 'PRESS', ctrl=True)
+ kmi.properties.animation = True
+ kmi = km.keymap_items.new('render.view_cancel', 'ESC', 'PRESS')
+ kmi = km.keymap_items.new('render.view_show', 'F11', 'PRESS')
+ kmi = km.keymap_items.new('render.play_rendered_anim', 'F11', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('screen.userpref_show', 'U', 'PRESS', ctrl=True, alt=True)
+
+ # Editing this seems to cause problems.
+ # TODO: file bug report
+ # Screen Editing
+ #km = kc.keymaps.new('Screen Editing', space_type='EMPTY', region_type='WINDOW', modal=False)
+ #
+ #kmi = km.keymap_items.new('screen.actionzone', 'LEFTMOUSE', 'PRESS')
+ #kmi.properties.modifier = 0
+ #kmi = km.keymap_items.new('screen.actionzone', 'LEFTMOUSE', 'PRESS', shift=True)
+ #kmi.properties.modifier = 1
+ #kmi = km.keymap_items.new('screen.actionzone', 'LEFTMOUSE', 'PRESS', ctrl=True)
+ #kmi.properties.modifier = 2
+ #kmi = km.keymap_items.new('screen.area_split', 'NONE', 'ANY')
+ #kmi = km.keymap_items.new('screen.area_join', 'NONE', 'ANY')
+ #kmi = km.keymap_items.new('screen.area_dupli', 'NONE', 'ANY', shift=True)
+ #kmi = km.keymap_items.new('screen.area_swap', 'NONE', 'ANY', ctrl=True)
+ #kmi = km.keymap_items.new('screen.region_scale', 'NONE', 'ANY')
+ #kmi = km.keymap_items.new('screen.area_move', 'LEFTMOUSE', 'PRESS')
+ #kmi = km.keymap_items.new('screen.area_options', 'RIGHTMOUSE', 'PRESS')
+
+
+def MapAdd_View2D(kc):
+ """ View 2D Map
+ """
+ km = kc.keymaps.new('View2D', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ kmi = km.keymap_items.new('view2d.scroller_activate', 'LEFTMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroller_activate', 'MIDDLEMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.pan', 'MIDDLEMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.pan', 'MIDDLEMOUSE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('view2d.pan', 'TRACKPADPAN', 'ANY')
+ kmi = km.keymap_items.new('view2d.scroll_right', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('view2d.scroll_left', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('view2d.scroll_down', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('view2d.scroll_up', 'WHEELUPMOUSE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('view2d.zoom_out', 'WHEELOUTMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.zoom_in', 'WHEELINMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.zoom_out', 'NUMPAD_MINUS', 'PRESS')
+ kmi = km.keymap_items.new('view2d.zoom_in', 'NUMPAD_PLUS', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroll_down', 'WHEELDOWNMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroll_up', 'WHEELUPMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroll_right', 'WHEELDOWNMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroll_left', 'WHEELUPMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.zoom', 'MIDDLEMOUSE', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('view2d.zoom', 'TRACKPADZOOM', 'ANY')
+ kmi = km.keymap_items.new('view2d.zoom_border', 'B', 'PRESS', shift=True)
+
+ # View2D Buttons List
+ km = kc.keymaps.new('View2D Buttons List', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ kmi = km.keymap_items.new('view2d.scroller_activate', 'LEFTMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroller_activate', 'MIDDLEMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.pan', 'MIDDLEMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.pan', 'TRACKPADPAN', 'ANY')
+ kmi = km.keymap_items.new('view2d.scroll_down', 'WHEELDOWNMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroll_up', 'WHEELUPMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view2d.scroll_down', 'PAGE_DOWN', 'PRESS')
+ kmi.properties.page = True
+ kmi = km.keymap_items.new('view2d.scroll_up', 'PAGE_UP', 'PRESS')
+ kmi.properties.page = True
+ kmi = km.keymap_items.new('view2d.zoom', 'MIDDLEMOUSE', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('view2d.zoom', 'TRACKPADZOOM', 'ANY')
+ kmi = km.keymap_items.new('view2d.zoom_out', 'NUMPAD_MINUS', 'PRESS')
+ kmi = km.keymap_items.new('view2d.zoom_in', 'NUMPAD_PLUS', 'PRESS')
+ kmi = km.keymap_items.new('view2d.reset', 'HOME', 'PRESS')
+
+
+def MapAdd_View3D_Global(kc):
+ """ View 3D Global Map
+ """
+ km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
+
+ #-----------------
+ # View navigation
+ #-----------------
+
+ # ???
+ kmi = km.keymap_items.new('view3d.rotate', 'MOUSEROTATE', 'ANY')
+ kmi = km.keymap_items.new('view3d.smoothview', 'TIMER1', 'ANY', any=True)
+
+
+
+ # Basics with mouse
+ kmi = km.keymap_items.new('view3d.rotate', 'MIDDLEMOUSE', 'PRESS')
+ kmi = km.keymap_items.new('view3d.move', 'MIDDLEMOUSE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('view3d.zoom', 'MIDDLEMOUSE', 'PRESS', ctrl=True)
+ #kmi = km.keymap_items.new('view3d.dolly', 'MIDDLEMOUSE', 'PRESS', shift=True, ctrl=True)
+
+ # Basics with mouse wheel
+ kmi = km.keymap_items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
+ kmi.properties.delta = 1
+ kmi = km.keymap_items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
+ kmi.properties.delta = -1
+ kmi = km.keymap_items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
+ kmi.properties.type = 'PANRIGHT'
+ kmi = km.keymap_items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
+ kmi.properties.type = 'PANLEFT'
+ kmi = km.keymap_items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
+ kmi.properties.type = 'PANUP'
+ kmi = km.keymap_items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
+ kmi.properties.type = 'PANDOWN'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
+ kmi.properties.type = 'ORBITLEFT'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
+ kmi.properties.type = 'ORBITRIGHT'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
+ kmi.properties.type = 'ORBITUP'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
+ kmi.properties.type = 'ORBITDOWN'
+
+ # Basics with trackpad
+ kmi = km.keymap_items.new('view3d.rotate', 'TRACKPADPAN', 'ANY', alt=True)
+ kmi = km.keymap_items.new('view3d.move', 'TRACKPADPAN', 'ANY')
+ kmi = km.keymap_items.new('view3d.zoom', 'TRACKPADZOOM', 'ANY')
+
+ # Perspective/ortho
+ kmi = km.keymap_items.new('view3d.view_persportho', 'NUMPAD_5', 'CLICK')
+
+ # Camera view
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_0', 'CLICK')
+ kmi.properties.type = 'CAMERA'
+
+ # Basics with numpad
+ kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_8', 'CLICK')
+ kmi.properties.type = 'ORBITUP'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_2', 'CLICK')
+ kmi.properties.type = 'ORBITDOWN'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_4', 'CLICK')
+ kmi.properties.type = 'ORBITLEFT'
+ kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_6', 'CLICK')
+ kmi.properties.type = 'ORBITRIGHT'
+ kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_8', 'CLICK', ctrl=True)
+ kmi.properties.type = 'PANUP'
+ kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_2', 'CLICK', ctrl=True)
+ kmi.properties.type = 'PANDOWN'
+ kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_4', 'CLICK', ctrl=True)
+ kmi.properties.type = 'PANLEFT'
+ kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_6', 'CLICK', ctrl=True)
+ kmi.properties.type = 'PANRIGHT'
+ kmi = km.keymap_items.new('view3d.zoom', 'NUMPAD_PLUS', 'CLICK')
+ kmi.properties.delta = 1
+ kmi = km.keymap_items.new('view3d.zoom', 'NUMPAD_MINUS', 'CLICK')
+ kmi.properties.delta = -1
+
+ # Zoom in/out alternatives
+ kmi = km.keymap_items.new('view3d.zoom', 'EQUAL', 'CLICK', ctrl=True)
+ kmi.properties.delta = 1
+ kmi = km.keymap_items.new('view3d.zoom', 'MINUS', 'CLICK', ctrl=True)
+ kmi.properties.delta = -1
+
+ # Front/Right/Top/Back/Left/Bottom
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'CLICK')
+ kmi.properties.type = 'FRONT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'CLICK')
+ kmi.properties.type = 'RIGHT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'CLICK')
+ kmi.properties.type = 'TOP'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'CLICK', ctrl=True)
+ kmi.properties.type = 'BACK'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'CLICK', ctrl=True)
+ kmi.properties.type = 'LEFT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'CLICK', ctrl=True)
+ kmi.properties.type = 'BOTTOM'
+
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'MIDDLEMOUSE', 'CLICK', alt=True)
+ kmi.properties.type = 'FRONT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'EVT_TWEAK_M', 'EAST', alt=True)
+ kmi.properties.type = 'RIGHT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'EVT_TWEAK_M', 'NORTH', alt=True)
+ kmi.properties.type = 'TOP'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'MIDDLEMOUSE', 'DOUBLE_CLICK', alt=True)
+ kmi.properties.type = 'BACK'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'EVT_TWEAK_M', 'WEST', alt=True)
+ kmi.properties.type = 'LEFT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'EVT_TWEAK_M', 'SOUTH', alt=True)
+ kmi.properties.type = 'BOTTOM'
+
+ # Selection-aligned Front/Right/Top/Back/Left/Bottom
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'CLICK', shift=True)
+ kmi.properties.type = 'FRONT'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'CLICK', shift=True)
+ kmi.properties.type = 'RIGHT'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'CLICK', shift=True)
+ kmi.properties.type = 'TOP'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'CLICK', shift=True, ctrl=True)
+ kmi.properties.type = 'BACK'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'CLICK', shift=True, ctrl=True)
+ kmi.properties.type = 'LEFT'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'CLICK', shift=True, ctrl=True)
+ kmi.properties.type = 'BOTTOM'
+ kmi.properties.align_active = True
+
+ # NDOF Device
+ kmi = km.keymap_items.new('view3d.ndof_orbit', 'NDOF_BUTTON_MENU', 'ANY')
+ kmi = km.keymap_items.new('view3d.ndof_pan', 'NDOF_BUTTON_MENU', 'ANY', shift=True)
+ kmi = km.keymap_items.new('view3d.view_selected', 'NDOF_BUTTON_FIT', 'PRESS')
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_FRONT', 'PRESS')
+ kmi.properties.type = 'FRONT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_BACK', 'PRESS')
+ kmi.properties.type = 'BACK'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_LEFT', 'PRESS')
+ kmi.properties.type = 'LEFT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_RIGHT', 'PRESS')
+ kmi.properties.type = 'RIGHT'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_TOP', 'PRESS')
+ kmi.properties.type = 'TOP'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_BOTTOM', 'PRESS')
+ kmi.properties.type = 'BOTTOM'
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_FRONT', 'PRESS', shift=True)
+ kmi.properties.type = 'FRONT'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_RIGHT', 'PRESS', shift=True)
+ kmi.properties.type = 'RIGHT'
+ kmi.properties.align_active = True
+ kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_TOP', 'PRESS', shift=True)
+ kmi.properties.type = 'TOP'
+ kmi.properties.align_active = True
+
+ # Fly mode
+ #kmi = km.keymap_items.new('view3d.fly', 'F', 'CLICK', shift=True)
+
+ # Misc
+ kmi = km.keymap_items.new('view3d.view_selected', 'NUMPAD_PERIOD', 'CLICK')
+ kmi = km.keymap_items.new('view3d.view_center_cursor', 'NUMPAD_PERIOD', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('view3d.zoom_camera_1_to_1', 'NUMPAD_ENTER', 'CLICK', shift=True)
+ kmi = km.keymap_items.new('view3d.view_center_camera', 'HOME', 'CLICK')
+ kmi = km.keymap_items.new('view3d.view_all', 'HOME', 'CLICK')
+ kmi.properties.center = False
+ kmi = km.keymap_items.new('view3d.view_all', 'C', 'CLICK', shift=True)
+ kmi.properties.center = True
+
+ #-------------
+ # Manipulator
+ #-------------
+
+ kmi = km.keymap_items.new('view3d.manipulator', 'EVT_TWEAK_L', 'ANY', any=True)
+ kmi.properties.release_confirm = True
+
+ if MAYA_STYLE_MANIPULATORS:
+ kmi = km.keymap_items.new('view3d.manipulator_set', 'Q', 'CLICK')
+ kmi.properties.mode = 'NONE'
+ kmi = km.keymap_items.new('view3d.manipulator_set', TRANSLATE_KEY, 'CLICK')
+ kmi.properties.mode = 'TRANSLATE'
+ kmi = km.keymap_items.new('view3d.manipulator_set', ROTATE_KEY, 'CLICK')
+ kmi.properties.mode = 'ROTATE'
+ kmi = km.keymap_items.new('view3d.manipulator_set', SCALE_KEY, 'CLICK')
+ kmi.properties.mode = 'SCALE'
+ else:
+ kmi = km.keymap_items.new('wm.context_toggle', 'SPACE', 'CLICK', ctrl=True)
+ kmi.properties.data_path = 'space_data.show_manipulator'
+
+ #-----------
+ # Selection
+ #-----------
+
+ # Click select
+ kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK') # Replace
+ kmi.properties.extend = False
+ kmi.properties.deselect = False
+ kmi.properties.toggle = False
+ kmi.properties.center = False
+ kmi.properties.enumerate = False
+ kmi.properties.object = False
+ kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', shift=True) # Extend
+ kmi.properties.extend = True
+ kmi.properties.deselect = False
+ kmi.properties.toggle = False
+ kmi.properties.center = False
+ kmi.properties.enumerate = False
+ kmi.properties.object = False
+ kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', ctrl=True) # Deselect
+ kmi.properties.extend = False
+ kmi.properties.deselect = True
+ kmi.properties.toggle = False
+ kmi.properties.center = False
+ kmi.properties.enumerate = False
+ kmi.properties.object = False
+
+ # Enumerate select
+ kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', alt=True) # Replace
+ kmi.properties.extend = False
+ kmi.properties.center = False
+ kmi.properties.enumerate = True
+ kmi.properties.object = False
+ kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', shift=True, alt=True) # Extend
+ kmi.properties.extend = True
+ kmi.properties.center = False
+ kmi.properties.enumerate = True
+ kmi.properties.object = False
+ kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', ctrl=True, alt=True) # Center (TODO: deselect)
+ kmi.properties.extend = False
+ kmi.properties.center = True
+ kmi.properties.enumerate = True
+ kmi.properties.object = False
+
+ # Border select
+ kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_L', 'ANY') # Replace
+ kmi.properties.extend = False
+ kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_L', 'ANY', shift=True) # Extend
+ kmi.properties.extend = True
+ kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_L', 'ANY', ctrl=True) # Deselect (handled in modal)
+ kmi.properties.extend = False
+
+ # Lasso select
+ kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_L', 'ANY', alt=True) # Replace
+ kmi.properties.extend = False
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_L', 'ANY', alt=True, shift=True) # Extend
+ kmi.properties.extend = True
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_L', 'ANY', alt=True, ctrl=True) # Deselect
+ kmi.properties.extend = False
+ kmi.properties.deselect = True
+
+ # Paint select
+ #kmi = km.keymap_items.new('view3d.select_circle', 'C', 'CLICK')
+
+ #-----------------------
+ # Transforms via hotkey
+ #-----------------------
+
+ # Grab, rotate scale
+ kmi = km.keymap_items.new('transform.translate', TRANSLATE_KEY, 'PRESS')
+ #kmi = km.keymap_items.new('transform.translate', 'EVT_TWEAK_S', 'ANY')
+ kmi = km.keymap_items.new('transform.rotate', ROTATE_KEY, 'PRESS')
+ kmi = km.keymap_items.new('transform.resize', SCALE_KEY, 'PRESS')
+
+ # Mirror, shear, warp, to-sphere
+ #kmi = km.keymap_items.new('transform.mirror', 'M', 'CLICK', ctrl=True)
+ #kmi = km.keymap_items.new('transform.shear', 'S', 'CLICK', shift=True, ctrl=True, alt=True)
+ #kmi = km.keymap_items.new('transform.warp', 'W', 'CLICK', shift=True)
+ #kmi = km.keymap_items.new('transform.tosphere', 'S', 'CLICK', shift=True, alt=True)
+
+ #-------------------------
+ # Transform texture space
+ #-------------------------
+ kmi = km.keymap_items.new('transform.translate', 'T', 'CLICK', shift=True)
+ kmi.properties.texture_space = True
+ kmi = km.keymap_items.new('transform.resize', 'T', 'CLICK', shift=True, alt=True)
+ kmi.properties.texture_space = True
+
+ #------------------
+ # Transform spaces
+ #------------------
+ kmi = km.keymap_items.new('transform.select_orientation', 'SPACE', 'CLICK', alt=True)
+ kmi = km.keymap_items.new('transform.create_orientation', 'SPACE', 'CLICK', ctrl=True, alt=True)
+ kmi.properties.use = True
+
+ #----------
+ # Snapping
+ #----------
+ kmi = km.keymap_items.new('wm.context_toggle', 'TAB', 'CLICK', shift=True)
+ kmi.properties.data_path = 'tool_settings.use_snap'
+ kmi = km.keymap_items.new('transform.snap_type', 'TAB', 'CLICK', shift=True, ctrl=True)
+
+ #---------------
+ # Snapping Menu
+ #---------------
+ kmi = km.keymap_items.new('wm.call_menu', 'S', 'CLICK', shift=True)
+ kmi.properties.name = 'VIEW3D_MT_snap'
+
+ #-----------
+ # 3d cursor
+ #-----------
+ kmi = km.keymap_items.new('view3d.cursor3d', 'ACTIONMOUSE', 'CLICK')
+
+ #-------------------
+ # Toggle local view
+ #-------------------
+ kmi = km.keymap_items.new('view3d.localview', 'NUMPAD_SLASH', 'CLICK')
+
+ #--------
+ # Layers
+ #--------
+ """
+ kmi = km.keymap_items.new('view3d.layers', 'ACCENT_GRAVE', 'CLICK')
+ kmi.properties.nr = 0
+ kmi = km.keymap_items.new('view3d.layers', 'ONE', 'CLICK', any=True)
+ kmi.properties.nr = 1
+ kmi = km.keymap_items.new('view3d.layers', 'TWO', 'CLICK', any=True)
+ kmi.properties.nr = 2
+ kmi = km.keymap_items.new('view3d.layers', 'THREE', 'CLICK', any=True)
+ kmi.properties.nr = 3
+ kmi = km.keymap_items.new('view3d.layers', 'FOUR', 'CLICK', any=True)
+ kmi.properties.nr = 4
+ kmi = km.keymap_items.new('view3d.layers', 'FIVE', 'CLICK', any=True)
+ kmi.properties.nr = 5
+ kmi = km.keymap_items.new('view3d.layers', 'SIX', 'CLICK', any=True)
+ kmi.properties.nr = 6
+ kmi = km.keymap_items.new('view3d.layers', 'SEVEN', 'CLICK', any=True)
+ kmi.properties.nr = 7
+ kmi = km.keymap_items.new('view3d.layers', 'EIGHT', 'CLICK', any=True)
+ kmi.properties.nr = 8
+ kmi = km.keymap_items.new('view3d.layers', 'NINE', 'CLICK', any=True)
+ kmi.properties.nr = 9
+ kmi = km.keymap_items.new('view3d.layers', 'ZERO', 'CLICK', any=True)
+ kmi.properties.nr = 10
+ """
+
+ #------------------
+ # Viewport drawing
+ #------------------
+ kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS')
+ kmi.properties.data_path = 'space_data.viewport_shade'
+ kmi.properties.value_1 = 'SOLID'
+ kmi.properties.value_2 = 'WIREFRAME'
+
+ kmi = km.keymap_items.new('wm.context_menu_enum', 'Z', 'PRESS', alt=True)
+ kmi.properties.data_path = 'space_data.viewport_shade'
+
+ #-------------
+ # Pivot point
+ #-------------
+ kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'CLICK')
+ kmi.properties.data_path = 'space_data.pivot_point'
+ kmi.properties.value = 'BOUNDING_BOX_CENTER'
+ kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'CLICK', ctrl=True)
+ kmi.properties.data_path = 'space_data.pivot_point'
+ kmi.properties.value = 'MEDIAN_POINT'
+ kmi = km.keymap_items.new('wm.context_toggle', 'COMMA', 'CLICK', alt=True)
+ kmi.properties.data_path = 'space_data.use_pivot_point_align'
+ kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'CLICK')
+ kmi.properties.data_path = 'space_data.pivot_point'
+ kmi.properties.value = 'CURSOR'
+ kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'CLICK', ctrl=True)
+ kmi.properties.data_path = 'space_data.pivot_point'
+ kmi.properties.value = 'INDIVIDUAL_ORIGINS'
+ kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'CLICK', alt=True)
+ kmi.properties.data_path = 'space_data.pivot_point'
+ kmi.properties.value = 'ACTIVE_ELEMENT'
+
+ #------
+ # Misc
+ #------
+ kmi = km.keymap_items.new('view3d.clip_border', 'B', 'CLICK', alt=True)
+ kmi = km.keymap_items.new('view3d.zoom_border', 'B', 'CLICK', shift=True)
+ kmi = km.keymap_items.new('view3d.render_border', 'B', 'CLICK', shift=True)
+ kmi = km.keymap_items.new('view3d.camera_to_view', 'NUMPAD_0', 'CLICK', ctrl=True, alt=True)
+ kmi = km.keymap_items.new('view3d.object_as_camera', 'NUMPAD_0', 'CLICK', ctrl=True)
+
+
+def MapAdd_View3D_Object_Nonmodal(kc):
+ """ Object Non-modal Map
+ This essentially applies globally within the 3d view. But technically
+ only when objects are involved (but when are they not...?).
+ """
+ km = kc.keymaps.new('Object Non-modal', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Mode switching
+ kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS')
+ kmi.properties.name = 'OBJECT_MT_mode_switch_menu'
+
+
+def MapAdd_View3D_ObjectMode(kc):
+ """ Object Mode Map
+ """
+ km = kc.keymaps.new('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ # Delete
+ kmi = km.keymap_items.new('object.delete_no_confirm', 'X', 'CLICK')
+ kmi = km.keymap_items.new('object.delete_no_confirm', 'DEL', 'CLICK')
+
+ # Proportional editing
+ kmi = km.keymap_items.new('wm.context_toggle', 'O', 'PRESS')
+ kmi.properties.data_path = 'tool_settings.use_proportional_edit_objects'
+ kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+ kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+
+ # Game engine start
+ kmi = km.keymap_items.new('view3d.game_start', 'P', 'PRESS')
+
+ # Selection
+ kmi = km.keymap_items.new('object.select_all', 'A', 'PRESS')
+ kmi.properties.action = 'TOGGLE'
+ kmi = km.keymap_items.new('object.select_all', 'I', 'PRESS', ctrl=True)
+ kmi.properties.action = 'INVERT'
+ kmi = km.keymap_items.new('object.select_linked', 'L', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('object.select_grouped', 'G', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
+ kmi.properties.direction = 'PARENT'
+ kmi.properties.extend = False
+ kmi = km.keymap_items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
+ kmi.properties.direction = 'PARENT'
+ kmi.properties.extend = True
+ kmi = km.keymap_items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
+ kmi.properties.direction = 'CHILD'
+ kmi.properties.extend = False
+ kmi = km.keymap_items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
+ kmi.properties.direction = 'CHILD'
+ kmi.properties.extend = True
+
+ # Parenting
+ kmi = km.keymap_items.new('object.parent_set', 'P', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('object.parent_no_inverse_set', 'P', 'PRESS', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('object.parent_clear', 'P', 'PRESS', alt=True)
+
+ # Constraints
+ kmi = km.keymap_items.new('object.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('object.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
+
+ # Transforms
+ kmi = km.keymap_items.new('object.location_clear', TRANSLATE_KEY, 'PRESS', alt=True)
+ kmi = km.keymap_items.new('object.rotation_clear', ROTATE_KEY, 'PRESS', alt=True)
+ kmi = km.keymap_items.new('object.scale_clear', SCALE_KEY, 'PRESS', alt=True)
+ kmi = km.keymap_items.new('object.origin_clear', 'O', 'PRESS', alt=True)
+
+ # Hiding
+ kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS') # Hide selected
+ kmi.properties.unselected = False
+ kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', shift=True) # Hide unselected
+ kmi.properties.unselected = True
+ kmi = km.keymap_items.new('object.hide_view_clear', 'H', 'PRESS', alt=True) # Unhide
+
+ #kmi = km.keymap_items.new('object.hide_render_set', 'H', 'PRESS', ctrl=True)
+ #kmi = km.keymap_items.new('object.hide_render_clear', 'H', 'PRESS', ctrl=True, alt=True)
+
+
+ # Layer management
+ kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
+
+ # Add menus
+ kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
+ kmi.properties.name = 'INFO_MT_add'
+ kmi = km.keymap_items.new('wm.call_menu', 'L', 'PRESS', ctrl=True)
+ kmi.properties.name = 'VIEW3D_MT_make_links'
+
+ # Duplication
+ kmi = km.keymap_items.new('object.duplicate_move', 'D', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('object.duplicate_move_linked', 'D', 'PRESS', alt=True)
+ kmi = km.keymap_items.new('object.duplicates_make_real', 'A', 'PRESS', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('wm.call_menu', 'U', 'PRESS')
+ kmi.properties.name = 'VIEW3D_MT_make_single_user'
+
+ # Apply menu
+ kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', ctrl=True)
+ kmi.properties.name = 'VIEW3D_MT_object_apply'
+
+ # Groups
+ kmi = km.keymap_items.new('group.create', 'G', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('group.objects_remove', 'G', 'PRESS', ctrl=True, alt=True)
+ kmi = km.keymap_items.new('group.objects_add_active', 'G', 'PRESS', shift=True, ctrl=True)
+ kmi = km.keymap_items.new('group.objects_remove_active', 'G', 'PRESS', shift=True, alt=True)
+
+ # Make proxy
+ kmi = km.keymap_items.new('object.proxy_make', 'P', 'PRESS', ctrl=True, alt=True)
+
+ # Keyframe insertion
+ kmi = km.keymap_items.new('anim.keyframe_insert_menu', 'I', 'PRESS')
+ kmi = km.keymap_items.new('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
+ kmi = km.keymap_items.new('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
+
+ # Misc
+ kmi = km.keymap_items.new('object.join', 'J', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('object.convert', 'C', 'PRESS', alt=True)
+ kmi = km.keymap_items.new('object.make_local', 'L', 'PRESS')
+ kmi = km.keymap_items.new('wm.call_menu', SPECIALS_MENU_KEY, 'PRESS')
+ kmi.properties.name = 'VIEW3D_MT_object_specials'
+
+ # Subdivision surface shortcuts
+ #kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
+ #kmi.properties.level = 0
+ #kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
+ #kmi.properties.level = 1
+ #kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
+ #kmi.properties.level = 2
+ #kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
+ #kmi.properties.level = 3
+ #kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
+ #kmi.properties.level = 4
+ #kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
+ #kmi.properties.level = 5
+
+
+def MapAdd_View3D_MeshEditMode(kc):
+ """ Mesh Edit Mode Map
+ """
+ km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+ #---------------------------------
+ # Vertex/Edge/Face mode switching
+ #---------------------------------
+ kmi = km.keymap_items.new('view3d.set_edit_mesh_select_mode', 'ONE', 'PRESS')
+ kmi.properties.mode = 'VERT'
+ kmi.properties.toggle = False
+ kmi = km.keymap_items.new('view3d.set_edit_mesh_select_mode', 'TWO', 'PRESS')
+ kmi.properties.mode = 'EDGE'
+ kmi.properties.toggle = False
+ kmi = km.keymap_items.new('view3d.set_edit_mesh_select_mode', 'THREE', 'PRESS')
+ kmi.properties.mode = 'FACE'
+ kmi.properties.toggle = False
+
+ kmi = km.keymap_items.new('view3d.set_edit_mesh_select_mode', 'ONE', 'PRESS', shift=True)
+ kmi.properties.mode = 'VERT'
+ kmi.properties.toggle = True
+ kmi = km.keymap_items.new('view3d.set_edit_mesh_select_mode', 'TWO', 'PRESS', shift=True)
+ kmi.properties.mode = 'EDGE'
+ kmi.properties.toggle = True
+ kmi = km.keymap_items.new('view3d.set_edit_mesh_select_mode', 'THREE', 'PRESS', shift=True)
+ kmi.properties.mode = 'FACE'
+ kmi.properties.toggle = True
+
+ #-----------
+ # Selection
+ #-----------
+
+ # Shortest path
+ kmi = km.keymap_items.new('mesh.select_shortest_path', 'LEFTMOUSE', 'CLICK', alt=True) # Replace
+ # TODO: add, remove
+
+ # Edge loop
+ kmi = km.keymap_items.new('mesh.loop_select', 'LEFTMOUSE', 'DOUBLE_CLICK') # Replace
+ kmi.properties.extend = False
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('mesh.loop_select', 'LEFTMOUSE', 'DOUBLE_CLICK', shift=True) # Add
+ kmi.properties.extend = True
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('mesh.loop_select', 'LEFTMOUSE', 'DOUBLE_CLICK', ctrl=True) # Remove
+ kmi.properties.extend = False
+ kmi.properties.deselect = True
+
+ # Edge ring
+ kmi = km.keymap_items.new('mesh.edgering_select', 'LEFTMOUSE', 'DOUBLE_CLICK', alt=True) # Replace
+ kmi.properties.extend = False
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('mesh.edgering_select', 'LEFTMOUSE', 'DOUBLE_CLICK', alt=True, shift=True) # Add
+ kmi.properties.extend = True
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('mesh.edgering_select', 'LEFTMOUSE', 'DOUBLE_CLICK', alt=True, ctrl=True) # Remove
+ kmi.properties.extend = False
+ kmi.properties.deselect = True
+
+ kmi = km.keymap_items.new('mesh.select_all', 'A', 'PRESS')
+ kmi.properties.action = 'TOGGLE'
+ kmi = km.keymap_items.new('mesh.select_all', 'I', 'CLICK', ctrl=True)
+ kmi.properties.action = 'INVERT'
+ kmi = km.keymap_items.new('mesh.select_more', 'NUMPAD_PLUS', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('mesh.select_less', 'NUMPAD_MINUS', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('mesh.select_non_manifold', 'M', 'CLICK', shift=True, ctrl=True, alt=True)
+ kmi = km.keymap_items.new('mesh.select_linked', 'L', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'CLICK')
+ kmi.properties.deselect = False
+ kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'CLICK', shift=True)
+ kmi.properties.deselect = True
+ kmi = km.keymap_items.new('mesh.faces_select_linked_flat', 'F', 'CLICK', shift=True, ctrl=True, alt=True)
+ kmi = km.keymap_items.new('mesh.select_similar', 'G', 'CLICK', shift=True)
+
+ # Proportional editing
+ kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'CLICK')
+ kmi.properties.data_path = 'tool_settings.proportional_edit'
+ kmi.properties.value_1 = 'DISABLED'
+ kmi.properties.value_2 = 'ENABLED'
+ kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'CLICK', shift=True)
+ kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+ kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'CLICK', alt=True)
+ kmi.properties.data_path = 'tool_settings.proportional_edit'
+ kmi.properties.value_1 = 'DISABLED'
+ kmi.properties.value_2 = 'CONNECTED'
+
+ # Hiding
+ kmi = km.keymap_items.new('mesh.hide', 'H', 'CLICK')
+ kmi.properties.unselected = False
+ kmi = km.keymap_items.new('mesh.hide', 'H', 'CLICK', shift=True)
+ kmi.properties.unselected = True
+ kmi = km.keymap_items.new('mesh.reveal', 'H', 'CLICK', alt=True)
+
+ #-----------------
+ # Create Geometry
+ #-----------------
+
+ # Add Primitive
+ kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
+ kmi.properties.name = 'INFO_MT_mesh_add'
+
+ # Add edge and face / vertex connect
+ kmi = km.keymap_items.new('mesh.edge_face_add', 'C', 'CLICK')
+ kmi = kmi = km.keymap_items.new('mesh.vert_connect', 'C', 'CLICK', shift=True)
+
+ kmi = km.keymap_items.new('mesh.fill', 'C', 'CLICK', alt=True)
+ kmi = km.keymap_items.new('mesh.beautify_fill', 'C', 'CLICK', alt=True, shift=True)
+
+ # Subdivide
+ kmi = km.keymap_items.new('mesh.subdivide', 'W', 'CLICK')
+
+ # Loop cut
+ kmi = km.keymap_items.new('mesh.loopcut_slide', 'T', 'CLICK')
+
+ # Knife
+ kmi = km.keymap_items.new('mesh.knife_tool', 'K', 'CLICK')
+
+ # Extrude
+ kmi = km.keymap_items.new('view3d.edit_mesh_extrude_move_normal', 'E', 'CLICK')
+ kmi = km.keymap_items.new('wm.call_menu', 'E', 'CLICK', alt=True)
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_extrude'
+
+ kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
+ kmi.properties.rotate_source = True
+ kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', shift=True, ctrl=True)
+ kmi.properties.rotate_source = False
+
+ # Inset/Outset
+ kmi = km.keymap_items.new('mesh.inset', 'I', 'CLICK')
+ kmi.properties.use_outset = False
+ kmi = km.keymap_items.new('mesh.inset', 'I', 'CLICK', shift=True)
+ kmi.properties.use_outset = True
+
+ # Bevel
+ kmi = km.keymap_items.new('mesh.bevel', 'B', 'CLICK')
+
+ # Duplicate
+ kmi = km.keymap_items.new('mesh.duplicate_move', 'D', 'CLICK', shift=True)
+
+ # Rip
+ kmi = km.keymap_items.new('mesh.rip_move', 'R', 'CLICK')
+
+ # Split / Separate
+ kmi = km.keymap_items.new('mesh.split', 'Y', 'CLICK')
+ kmi = km.keymap_items.new('mesh.separate', 'Y', 'CLICK', shift=True)
+
+
+ #-----------------
+ # Remove Geometry
+ #-----------------
+
+ # Delete/Dissolve
+ kmi = km.keymap_items.new('mesh.delete_contextual', 'X', 'CLICK')
+ kmi = km.keymap_items.new('mesh.delete_contextual', 'DEL', 'CLICK')
+
+ kmi = km.keymap_items.new('mesh.dissolve', 'X', 'CLICK', shift=True)
+ kmi.properties.use_verts = True
+ kmi = km.keymap_items.new('mesh.dissolve', 'DEL', 'CLICK', shift=True)
+ kmi.properties.use_verts = True
+
+ kmi = km.keymap_items.new('wm.call_menu', 'X', 'CLICK', alt=True)
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
+ kmi = km.keymap_items.new('wm.call_menu', 'DEL', 'CLICK', alt=True)
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
+
+ # Merge/collapse
+ kmi = km.keymap_items.new('mesh.edge_collapse', 'M', 'CLICK')
+ kmi = km.keymap_items.new('mesh.merge', 'M', 'CLICK', alt=True)
+
+ #-----------------
+ # Deform Geometry
+ #-----------------
+
+ # Smooth
+ kmi = km.keymap_items.new('mesh.vertices_smooth', 'W', 'PRESS', shift=True)
+
+ # Shrink / Fatten
+ kmi = km.keymap_items.new('transform.shrink_fatten', 'S', 'CLICK', alt=True)
+
+ #------
+ # Misc
+ #------
+
+ # Vert/edge properties
+ #kmi = km.keymap_items.new('transform.edge_crease', 'E', 'CLICK', shift=True)
+
+ # Tri/quad conversion
+ #kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'CLICK', ctrl=True)
+ #kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'CLICK', shift=True, ctrl=True)
+ #kmi.properties.use_beauty = False
+ #kmi = km.keymap_items.new('mesh.tris_convert_to_quads', 'J', 'CLICK', alt=True)
+
+ # Tool Menus
+ kmi = km.keymap_items.new('wm.call_menu', SPECIALS_MENU_KEY, 'CLICK')
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials'
+ kmi = km.keymap_items.new('wm.call_menu', 'ONE', 'CLICK', alt=True)
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_vertices'
+ kmi = km.keymap_items.new('wm.call_menu', 'TWO', 'CLICK', alt=True)
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_edges'
+ kmi = km.keymap_items.new('wm.call_menu', 'THREE', 'CLICK', alt=True)
+ kmi.properties.name = 'VIEW3D_MT_edit_mesh_faces'
+
+ # UV's
+ kmi = km.keymap_items.new('wm.call_menu', 'U', 'CLICK')
+ kmi.properties.name = 'VIEW3D_MT_uv_map'
+
+ # Calculate normals
+ kmi = km.keymap_items.new('mesh.normals_make_consistent', 'N', 'CLICK', ctrl=True)
+ kmi.properties.inside = False
+ kmi = km.keymap_items.new('mesh.normals_make_consistent', 'N', 'CLICK', shift=True, ctrl=True)
+ kmi.properties.inside = True
+
+ # Subsurf shortcuts
+ if SUBSURF_RELATIVE:
+ kmi = km.keymap_items.new('object.shift_subsurf_level', 'EQUAL', 'PRESS')
+ kmi.properties.delta = 1
+ kmi.properties.max = 4
+ kmi = km.keymap_items.new('object.shift_subsurf_level', 'MINUS', 'PRESS')
+ kmi.properties.delta = -1
+ kmi.properties.min = 0
+ else:
+ kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'CLICK', ctrl=True)
+ kmi.properties.level = 0
+ kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'CLICK', ctrl=True)
+ kmi.properties.level = 1
+ kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'CLICK', ctrl=True)
+ kmi.properties.level = 2
+ kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'CLICK', ctrl=True)
+ kmi.properties.level = 3
+ kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'CLICK', ctrl=True)
+ kmi.properties.level = 4
+ kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'CLICK', ctrl=True)
+ kmi.properties.level = 5
+
+ # Rigging
+ kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'CLICK', ctrl=True)
+ kmi = km.keymap_items.new('wm.call_menu', 'H', 'CLICK', ctrl=True)
+ kmi.properties.name = 'VIEW3D_MT_hook'
+ kmi = km.keymap_items.new('wm.call_menu', 'G', 'CLICK', ctrl=True)
+ kmi.properties.name = 'VIEW3D_MT_vertex_group'
+
+
+def MapAdd_ModalStandard(kc):
+ """ Standard Modal Map
+ Super basic modal stuff that applies globally in Blender.
+ """
+ km = kc.keymaps.new('Standard Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ kmi = km.keymap_items.new_modal('CANCEL', 'ESC', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('APPLY', 'LEFTMOUSE', 'ANY', any=True)
+ kmi = km.keymap_items.new_modal('APPLY', 'RET', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('APPLY', 'NUMPAD_ENTER', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('STEP10', 'LEFT_CTRL', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('STEP10_OFF', 'LEFT_CTRL', 'RELEASE', any=True)
+
+
+def MapAdd_ModalTransform(kc):
+ """ Transform Modal Map
+ Keys for when the user is in a transform mode, such as grab/rotate/scale.
+ """
+ km = kc.keymaps.new('Transform Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ # Cancel
+ kmi = km.keymap_items.new_modal('CANCEL', 'ESC', 'PRESS', any=True)
+
+ # Confirm
+ kmi = km.keymap_items.new_modal('CONFIRM', 'LEFTMOUSE', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('CONFIRM', 'RET', 'CLICK', any=True)
+ kmi = km.keymap_items.new_modal('CONFIRM', 'NUMPAD_ENTER', 'CLICK', any=True)
+
+ # Snapping
+ kmi = km.keymap_items.new_modal('SNAP_TOGGLE', 'TAB', 'PRESS', shift=True)
+ kmi = km.keymap_items.new_modal('SNAP_INV_ON', 'LEFT_CTRL', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('SNAP_INV_OFF', 'LEFT_CTRL', 'RELEASE', any=True)
+ kmi = km.keymap_items.new_modal('SNAP_INV_ON', 'RIGHT_CTRL', 'PRESS', any=True)
+ kmi = km.keymap_items.new_modal('SNAP_INV_OFF', 'RIGHT_CTRL', 'RELEASE', any=True)
+ kmi = km.keymap_items.new_modal('ADD_SNAP', 'A', 'CLICK')
+ kmi = km.keymap_items.new_modal('REMOVE_SNAP', 'A', 'CLICK', alt=True)
+
+ # Proportional edit adjusting
+ kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_UP', 'PAGE_UP', 'PRESS')
+ kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_DOWN', 'PAGE_DOWN', 'PRESS')
+ kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_UP', 'WHEELDOWNMOUSE', 'PRESS')
+ kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_DOWN', 'WHEELUPMOUSE', 'PRESS')
+
+ # Auto-ik adjusting
+ kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_UP', 'PAGE_UP', 'PRESS', shift=True)
+ kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_DOWN', 'PAGE_DOWN', 'PRESS', shift=True)
+ kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_UP', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_DOWN', 'WHEELUPMOUSE', 'PRESS', shift=True)
+
+ # Constraining to axes
+ kmi = km.keymap_items.new_modal('AXIS_X', 'X', 'CLICK')
+ kmi = km.keymap_items.new_modal('AXIS_Y', 'Y', 'CLICK')
+ kmi = km.keymap_items.new_modal('AXIS_Z', 'Z', 'CLICK')
+ kmi = km.keymap_items.new_modal('PLANE_X', 'X', 'CLICK', shift=True)
+ kmi = km.keymap_items.new_modal('PLANE_Y', 'Y', 'CLICK', shift=True)
+ kmi = km.keymap_items.new_modal('PLANE_Z', 'Z', 'CLICK', shift=True)
+
+ # Overrides ("No, really, actually translate") and trackball rotate
+ kmi = km.keymap_items.new_modal('TRANSLATE', TRANSLATE_KEY, 'PRESS')
+ kmi = km.keymap_items.new_modal('ROTATE', ROTATE_KEY, 'PRESS')
+ kmi = km.keymap_items.new_modal('RESIZE', SCALE_KEY, 'PRESS')
+
+
+def MapAdd_ModalBorderSelect(kc):
+ """ Border Select Modal Map
+ Determines behavior when in border select tool.
+ """
+ km = kc.keymaps.new('Gesture Border', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+ kmi = km.keymap_items.new_modal('CANCEL', 'ESC', 'PRESS', any=True)
+
+ kmi = km.keymap_items.new_modal('BEGIN', 'LEFTMOUSE', 'PRESS')
+ kmi = km.keymap_items.new_modal('SELECT', 'LEFTMOUSE', 'RELEASE')
+ kmi = km.keymap_items.new_modal('SELECT', 'LEFTMOUSE', 'RELEASE', shift=True)
+ kmi = km.keymap_items.new_modal('DESELECT', 'LEFTMOUSE', 'RELEASE', ctrl=True)
+
+
+
+
+
+
+
+def MapAdd_FileBrowserGlobal(kc):
+ # Map File Browser
+ km = kc.keymaps.new('File Browser', space_type='FILE_BROWSER', region_type='WINDOW', modal=False)
+
+ kmi = km.keymap_items.new('file.bookmark_toggle', 'N', 'PRESS')
+ kmi = km.keymap_items.new('file.parent', 'P', 'PRESS')
+ kmi = km.keymap_items.new('file.bookmark_add', 'B', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('file.hidedot', 'H', 'PRESS')
+ kmi = km.keymap_items.new('file.previous', 'BACK_SPACE', 'PRESS')
+ kmi = km.keymap_items.new('file.next', 'BACK_SPACE', 'PRESS', shift=True)
+ kmi = km.keymap_items.new('file.directory_new', 'I', 'PRESS')
+ kmi = km.keymap_items.new('file.delete', 'X', 'PRESS')
+ kmi = km.keymap_items.new('file.delete', 'DEL', 'PRESS')
+ kmi = km.keymap_items.new('file.smoothscroll', 'TIMER1', 'ANY', any=True)
+
+def MapAdd_FileBrowserMain(kc):
+ # Map File Browser Main
+ km = kc.keymaps.new('File Browser Main', space_type='FILE_BROWSER', region_type='WINDOW', modal=False)
+
+ kmi = km.keymap_items.new('file.execute', 'LEFTMOUSE', 'DOUBLE_CLICK')
+ kmi.properties.need_active = True
+ kmi = km.keymap_items.new('file.select', 'LEFTMOUSE', 'CLICK')
+ kmi = km.keymap_items.new('file.select', 'LEFTMOUSE', 'CLICK', shift=True)
+ kmi.properties.extend = True
+ kmi = km.keymap_items.new('file.select', 'LEFTMOUSE', 'CLICK', alt=True)
+ kmi.properties.extend = True
+ kmi.properties.fill = True
+ kmi = km.keymap_items.new('file.select_all_toggle', 'A', 'PRESS')
+ kmi = km.keymap_items.new('file.refresh', 'NUMPAD_PERIOD', 'PRESS')
+ kmi = km.keymap_items.new('file.select_border', 'B', 'PRESS')
+ kmi = km.keymap_items.new('file.select_border', 'EVT_TWEAK_L', 'ANY')
+ kmi = km.keymap_items.new('file.rename', 'LEFTMOUSE', 'PRESS', ctrl=True)
+ kmi = km.keymap_items.new('file.highlight', 'MOUSEMOVE', 'ANY', any=True)
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_PLUS', 'PRESS')
+ kmi.properties.increment = 1
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_PLUS', 'PRESS', shift=True)
+ kmi.properties.increment = 10
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
+ kmi.properties.increment = 100
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_MINUS', 'PRESS')
+ kmi.properties.increment = -1
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_MINUS', 'PRESS', shift=True)
+ kmi.properties.increment = -10
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
+ kmi.properties.increment = -100
+
+def MapAdd_FileBrowserButtons(kc):
+ # Map File Browser Buttons
+ km = kc.keymaps.new('File Browser Buttons', space_type='FILE_BROWSER', region_type='WINDOW', modal=False)
+
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_PLUS', 'PRESS')
+ kmi.properties.increment = 1
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_PLUS', 'PRESS', shift=True)
+ kmi.properties.increment = 10
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
+ kmi.properties.increment = 100
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_MINUS', 'PRESS')
+ kmi.properties.increment = -1
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_MINUS', 'PRESS', shift=True)
+ kmi.properties.increment = -10
+ kmi = km.keymap_items.new('file.filenum', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
+ kmi.properties.increment = -100
+
+
+
+
+
+
+
+
+
+wm = bpy.context.window_manager
+kc = wm.keyconfigs.new('Blender 2012 (experimental!)')
+
+clear_keymap(kc)
+
+MapAdd_Window(kc)
+MapAdd_Screen(kc)
+
+MapAdd_View2D(kc)
+
+MapAdd_View3D_Global(kc)
+MapAdd_View3D_Object_Nonmodal(kc)
+MapAdd_View3D_ObjectMode(kc)
+MapAdd_View3D_MeshEditMode(kc)
+
+MapAdd_ModalStandard(kc)
+MapAdd_ModalTransform(kc)
+MapAdd_ModalBorderSelect(kc)
+
+MapAdd_FileBrowserGlobal(kc)
+MapAdd_FileBrowserMain(kc)
+MapAdd_FileBrowserButtons(kc)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/release/scripts/addons_contrib/render_auto_save.py b/release/scripts/addons_contrib/render_auto_save.py
new file mode 100644
index 0000000..438fb04
--- /dev/null
+++ b/release/scripts/addons_contrib/render_auto_save.py
@@ -0,0 +1,137 @@
+#Simplified BSD License
+#
+#Copyright (c) 2012, Florian Meyer
+#tstscr at web.de
+#All rights reserved.
+#
+#Redistribution and use in source and binary forms, with or without
+#modification, are permitted provided that the following conditions are met:
+#
+#1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#################################################################
+bl_info = {
+ "name": "Auto Save Render",
+ "author": "tstscr",
+ "version": (1, 0),
+ "blender": (2, 63, 0),
+ "location": "Rendertab -> Render Panel",
+ "description": "Automatically save the image after rendering",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Render/Auto_Save",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=32491",
+ "category": "Render"}
+###########################################################################
+import bpy
+from bpy.props import BoolProperty, EnumProperty
+from bpy.app.handlers import persistent
+from os.path import dirname, exists, join
+from bpy.path import basename
+from os import mkdir, listdir
+from re import findall
+
+
+ at persistent
+def auto_save_render(scene):
+ if not scene.save_after_render or not bpy.data.filepath:
+ return
+ rndr = scene.render
+ original_format = rndr.image_settings.file_format
+
+ format = rndr.image_settings.file_format = scene.auto_save_format
+ if format == 'OPEN_EXR_MULTILAYER': extension = '.exr'
+ if format == 'JPEG': extension = '.jpg'
+ if format == 'PNG': extension = '.png'
+
+ blendname = basename(bpy.data.filepath).rpartition('.')[0]
+ filepath = dirname(bpy.data.filepath) + '/auto_saves'
+
+ if not exists(filepath):
+ mkdir(filepath)
+
+ if scene.auto_save_subfolders:
+ filepath = join(filepath, blendname)
+ if not exists(filepath):
+ mkdir(filepath)
+
+ #imagefiles starting with the blendname
+ files = [f for f in listdir(filepath) \
+ if f.startswith(blendname) \
+ and f.lower().endswith(('.png', '.jpg', '.jpeg', '.exr'))]
+
+ highest = 0
+ if files:
+ for f in files:
+ #find last numbers in the filename after the blendname
+ suffix = findall('\d+', f.split(blendname)[-1])
+ if suffix:
+ if int(suffix[-1]) > highest:
+ highest = int(suffix[-1])
+
+ save_name = join(filepath, blendname) + '_' + str(highest+1).zfill(3) + extension
+
+ image = bpy.data.images['Render Result']
+ if not image:
+ print('Auto Save: Render Result not found. Image not saved')
+ return
+
+ print('Auto_Save:', save_name)
+ image.save_render(save_name, scene=None)
+
+ rndr.image_settings.file_format = original_format
+
+###########################################################################
+def auto_save_UI(self, context):
+ layout = self.layout
+
+ split=layout.split(percentage=0.66, align=True)
+ row = split.row()
+ row.prop(context.scene, 'save_after_render', text='Auto Save', toggle=False)
+ row.prop(context.scene, 'auto_save_subfolders', toggle=False)
+ #split=layout.split()
+ row=split.row()
+ row.prop(context.scene, 'auto_save_format', text='as', expand=False)
+
+def register():
+ bpy.types.Scene.save_after_render = BoolProperty(
+ name='Save after render',
+ default=True,
+ description='Automatically save rendered images into: //auto_save/')
+ bpy.types.Scene.auto_save_format = EnumProperty(
+ name='Auto Save File Format',
+ description='File Format for the auto saves.',
+ items={
+ ('PNG', 'png', 'Save as png'),
+ ('JPEG', 'jpg', 'Save as jpg'),
+ ('OPEN_EXR_MULTILAYER', 'exr', 'Save as multilayer exr')},
+ default='PNG')
+ bpy.types.Scene.auto_save_subfolders = BoolProperty(
+ name='subfolder',
+ default=False,
+ description='Save into individual subfolders per blend name')
+ bpy.app.handlers.render_post.append(auto_save_render)
+ bpy.types.RENDER_PT_render.append(auto_save_UI)
+
+def unregister():
+ del(bpy.types.Scene.save_after_render)
+ del(bpy.types.Scene.auto_save_format)
+ del(bpy.types.Scene.auto_save_subfolders)
+ bpy.app.handlers.render_post.remove(auto_save_render)
+ bpy.types.RENDER_PT_render.remove(auto_save_UI)
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/render_clay.py b/release/scripts/addons_contrib/render_clay.py
new file mode 100644
index 0000000..2a3f098
--- /dev/null
+++ b/release/scripts/addons_contrib/render_clay.py
@@ -0,0 +1,226 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Clay Render",
+ "author": "Fabio Russo <ruesp83 at libero.it>",
+ "version": (1, 2),
+ "blender": (2, 56, 0),
+ "location": "Render > Clay Render",
+ "description": "This script, applies a temporary material to all objects"\
+ " of the scene.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Clay_Render",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=22971",
+ "category": "Render"}
+
+import bpy
+from bpy.props import BoolProperty
+
+
+def Create_Mat():
+ id = bpy.data.materials.new("Clay_Render")
+ #diffuse
+ id.diffuse_shader = "OREN_NAYAR"
+ id.diffuse_color = 0.800, 0.741, 0.536
+ id.diffuse_intensity = 1
+ id.roughness = 0.909
+ #specular
+ id.specular_shader = "COOKTORR"
+ id.specular_color = 1, 1, 1
+ id.specular_hardness = 10
+ id.specular_intensity = 0.115
+
+
+def Alternative_Clay(self, msg):
+ Find = False
+ AM = None
+ i = 0
+ for mat in bpy.data.materials:
+ if (mat.Mat_Clay) and (not Find):
+ Find = True
+ AM = mat
+ i += 1
+
+ else:
+ if (mat.Mat_Clay):
+ i += 1
+
+ if msg is True:
+ if (i == 1):
+ self.report({'INFO'}, "The material \"" + AM.name + "\" is set "\
+ "as Clay!")
+ else:
+ if (i > 1):
+ self.report({'WARNING'}, "Two or more materials are set as "\
+ "Clay. \"" + AM.name + "\" will be used!")
+
+ return AM
+
+
+def Get_Mat():
+ Mat = bpy.data.materials["Clay_Render"]
+ return Mat
+
+
+def Exist_Mat():
+ if bpy.data.materials.get("Clay_Render"):
+ return True
+
+ else:
+ return False
+
+
+class ClayPinned(bpy.types.Operator):
+ bl_idname = "render.clay_pinned"
+ bl_label = "Clay Pinned"
+ bl_description = "Clay Material Stores"
+
+ def execute(self, context):
+ if bpy.types.Scene.Clay_Pinned:
+ bpy.types.Scene.Clay_Pinned = False
+ else:
+ if bpy.types.Scene.Clay:
+ if bpy.data.materials[0].users == 0:
+ bpy.data.materials.remove(Get_Mat())
+ bpy.types.Scene.Clay_Pinned = True
+
+ else:
+ bpy.types.Scene.Clay_Pinned = True
+
+ return {'FINISHED'}
+
+
+class CheckClay(bpy.types.Operator):
+ bl_idname = "render.clay"
+ bl_label = "Clay Render"
+ bl_description = "Use Clay Render"
+
+ def execute(self, context):
+ if bpy.types.Scene.Clay:
+ #Clay Attivato
+ ac = Alternative_Clay(self, True)
+ if ac is None:
+ if not Exist_Mat():
+ Create_Mat()
+ rl = context.scene.render.layers
+ rl.active.material_override = Get_Mat()
+
+ else:
+ context.scene.render.layers.active.material_override = ac
+
+ bpy.types.Scene.Clay = False
+
+ else:
+ context.scene.render.layers.active.material_override = None
+ if bpy.types.Scene.Clay_Pinned:
+ if bpy.data.materials[0].users == 0:
+ bpy.data.materials.remove(Get_Mat())
+ bpy.types.Scene.Clay = True
+
+ return {'FINISHED'}
+
+
+def draw_clay_render(self, context):
+ ok_clay = not bpy.types.Scene.Clay
+ pin = not bpy.types.Scene.Clay_Pinned
+
+ rnl = context.scene.render.layers.active
+ split = self.layout.split()
+ col = split.column()
+
+ col.operator(CheckClay.bl_idname, emboss=False, icon='CHECKBOX_HLT'\
+ if ok_clay else 'CHECKBOX_DEHLT')
+ col = split.column()
+ if Alternative_Clay(self, False) is None:
+ if Exist_Mat():
+ if (bpy.data.materials[0].users == 0) or (ok_clay):
+ row = col.row(align=True)
+ im = Get_Mat()
+ row.prop(im, "diffuse_color", text="")
+ row.operator(ClayPinned.bl_idname, text="", icon='PINNED'\
+ if pin else 'UNPINNED')
+
+ if ok_clay:
+ row.active = True
+
+ else:
+ row.active = False
+
+ else:
+ col.label('Clay Material applied to an object')
+
+ else:
+ col.label('Custom Material Clay')
+
+ self.layout.separator()
+
+
+def draw_clay_options(self, context):
+ cm = context.material
+ layout = self.layout
+ layout.prop(cm, "Mat_Clay", text="Clay")
+
+
+def draw_clay_warning(self, context):
+ if not bpy.types.Scene.Clay:
+ self.layout.label("Render Clay Enabled", "ERROR")
+
+
+def register():
+ bpy.types.Scene.Clay = BoolProperty(
+ name='Clay Render',
+ description='Use Clay Render',
+ default=False)
+
+ bpy.types.Scene.Clay_Pinned = BoolProperty(
+ name='Clay Pinned',
+ description='Clay Material Stores',
+ default=False)
+
+ bpy.types.Material.Mat_Clay = bpy.props.BoolProperty(
+ name='Use as Clay',
+ description='Use as Clay',
+ default=False)
+
+ bpy.utils.register_class(ClayPinned)
+ bpy.utils.register_class(CheckClay)
+ bpy.types.RENDER_PT_render.prepend(draw_clay_render)
+ bpy.types.MATERIAL_PT_options.append(draw_clay_options)
+ bpy.types.INFO_HT_header.append(draw_clay_warning)
+
+
+def unregister():
+ bpy.context.scene.render.layers.active.material_override = None
+ if (Exist_Mat()) and (bpy.data.materials[0].users == 0):
+ bpy.data.materials.remove(Get_Mat())
+ del bpy.types.Scene.Clay
+ del bpy.types.Scene.Clay_Pinned
+ del bpy.types.Material.Mat_Clay
+ bpy.utils.unregister_class(ClayPinned)
+ bpy.utils.unregister_class(CheckClay)
+ bpy.types.RENDER_PT_render.remove(draw_clay_render)
+ bpy.types.MATERIAL_PT_options.remove(draw_clay_options)
+ bpy.types.INFO_HT_header.remove(draw_clay_warning)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/render_time.py b/release/scripts/addons_contrib/render_time.py
new file mode 100644
index 0000000..d368e54
--- /dev/null
+++ b/release/scripts/addons_contrib/render_time.py
@@ -0,0 +1,172 @@
+# ***** 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 *****
+
+
+bl_info = {
+ "name": "Render Time Estimation",
+ "author": "Jason van Gumster (Fweeb)",
+ "version": (0, 5, 1),
+ "blender": (2, 62, 0),
+ "location": "UV/Image Editor > Properties > Image",
+ "description": "Estimates the time to complete rendering on animations",
+ "warning": "Does not work on OpenGL renders",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Render/Render_Time_Estimation",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=30452&group_id=153&atid=467",
+ "category": "Render"}
+
+
+import bpy, time
+from bpy.app.handlers import persistent
+from datetime import timedelta
+import blf
+
+
+timer = {"average": 0.0, "total": 0.0, "time_start": 0.0, "is_rendering": False, "hud": False}
+
+def set_rendering(scene):
+ timer["is_rendering"] = True
+
+ at persistent
+def unset_rendering(scene):
+ timer["is_rendering"] = False
+
+ at persistent
+def start_timer(scene):
+ set_rendering(scene)
+
+ if scene.frame_current == scene.frame_start:
+ timer["average"] = 0.0
+ timer["total"] = 0.0
+
+ timer["time_start"] = time.time()
+
+ at persistent
+def end_timer(scene):
+ render_time = time.time() - timer["time_start"]
+ timer["total"] += render_time
+ if scene.frame_current == scene.frame_start:
+ timer["average"] = render_time
+ else:
+ timer["average"] = (timer["average"] + render_time) / 2
+
+ print("Total render time: " + str(timedelta(seconds = timer["total"])))
+ print("Estimated completion: " + str(timedelta(seconds = (timer["average"] * (scene.frame_end - scene.frame_current)))))
+
+
+# UI
+
+def image_panel_rendertime(self, context):
+ scene = context.scene
+ layout = self.layout
+
+ if context.space_data.image is not None and context.space_data.image.type == 'RENDER_RESULT':
+ layout.label(text = "Total render time: " + str(timedelta(seconds = timer["total"])))
+
+ if timer["is_rendering"] and scene.frame_current != scene.frame_start:
+ layout.label(text = "Estimated completion: " + str(timedelta(seconds = (timer["average"] * (scene.frame_end - scene.frame_current)))))
+
+def draw_callback_px(self, context):
+ scene = context.scene
+
+ font_id = 0 # XXX, need to find out how best to get this.
+
+ # draw some text
+ blf.position(font_id, 15, 30, 0)
+ blf.size(font_id, 18, 72)
+ blf.enable(font_id, blf.SHADOW)
+ blf.shadow(font_id, 5, 0.0, 0.0, 0.0, 1.0)
+
+ blf.draw(font_id, "Total render time " + str(timedelta(seconds = timer["total"])))
+ if timer["is_rendering"] and scene.frame_current != scene.frame_start:
+ blf.position(font_id, 15, 12, 0)
+ blf.draw(font_id, "Estimated completion: " + str(timedelta(seconds = (timer["average"] * (scene.frame_end - scene.frame_current)))))
+
+ # restore defaults
+ blf.disable(font_id, blf.SHADOW)
+
+class RenderTimeHUD(bpy.types.Operator):
+ bl_idname = "view2d.rendertime_hud"
+ bl_label = "Display Render Times"
+ last_activity = 'NONE'
+
+ def modal(self, context, event):
+ if context.area:
+ context.area.tag_redraw()
+
+ #if event.type in {'ESC'}:
+ if timer["hud"] == False:
+ context.region.callback_remove(self._handle)
+ return {'CANCELLED'}
+
+ return {'PASS_THROUGH'}
+
+ def invoke(self, context, event):
+ if context.area.type == 'IMAGE_EDITOR':
+ if timer["hud"] == False:
+ # Add the region OpenGL drawing callback
+ self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
+ timer["hud"] = True
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ timer["hud"] = False
+ return {'CANCELLED'}
+ else:
+ self.report({'WARNING'}, "UV/Image Editor not found, cannot run operator")
+ return {'CANCELLED'}
+
+def display_hud(self, context):
+ scene = context.scene
+ layout = self.layout
+ layout.operator("view2d.rendertime_hud")
+
+
+# Registration
+
+def register():
+ bpy.app.handlers.render_complete.append(unset_rendering)
+ bpy.app.handlers.render_cancel.append(unset_rendering)
+ bpy.app.handlers.render_pre.append(start_timer)
+ bpy.app.handlers.render_post.append(end_timer)
+ bpy.types.IMAGE_PT_image_properties.append(image_panel_rendertime)
+ bpy.utils.register_class(RenderTimeHUD)
+ bpy.types.IMAGE_HT_header.append(display_hud)
+
+ # Keymapping XXX TODO - This doesn't work for some reason
+ #kc = bpy.context.window_manager.keyconfigs.addon
+ #km = kc.keymaps.new(name = "View 2D", space_type = 'IMAGE_EDITOR')
+ #kmi = km.keymap_items.new("view2d.rendertime_hud", 'E', 'PRESS')
+ #kmi.active = True
+
+def unregister():
+ #kc = bpy.context.window_manager.keyconfigs.addon
+ #km = kc.keymaps["View 2D"]
+ #km.keymap_items.remove(km.keymap_items["view2d.rendertime_hud"])
+
+ bpy.types.IMAGE_HT_header.remove(display_hud)
+ bpy.utils.unregister_class(RenderTimeHUD)
+ bpy.app.handlers.render_pre.remove(start_timer)
+ bpy.app.handlers.render_post.remove(end_timer)
+ bpy.app.handlers.render_cancel.remove(unset_rendering)
+ bpy.app.handlers.render_complete.remove(unset_rendering)
+ bpy.types.IMAGE_PT_image_properties.remove(image_panel_rendertime)
+
+if __name__ == '__main__':
+ register()
diff --git a/release/scripts/addons_contrib/render_to_print.py b/release/scripts/addons_contrib/render_to_print.py
new file mode 100644
index 0000000..2a58c41
--- /dev/null
+++ b/release/scripts/addons_contrib/render_to_print.py
@@ -0,0 +1,346 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+ "name": "Render to Print",
+ "author": "Marco Crippa <thekrypt77 at tiscali.it>, Dealga McArdle",
+ "version": (0, 2),
+ "blender": (2, 58, 0),
+ "location": "Render > Render to Print",
+ "description": "Set the size of the render for a print",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Render/Render to Print",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=24219",
+ "category": "Render"}
+
+
+import math
+import bpy
+from bpy.types import Panel, Operator, Scene, PropertyGroup
+from bpy.props import (IntProperty,
+ FloatProperty,
+ StringProperty,
+ EnumProperty,
+ PointerProperty,
+ )
+
+
+paper_presets = (
+ ("custom_1_1", "custom", ""),
+ ("A0_84.1_118.9", "A0 (84.1x118.9 cm)", ""),
+ ("A1_59.4_84.1", "A1 (59.4x84.1 cm)", ""),
+ ("A2_42.0_59.4", "A2 (42.0x59.4 cm)", ""),
+ ("A3_29.7_42.0", "A3 (29.7 42.0 cm)", ""),
+ ("A4_21.0_29.7", "A4 (21.0x29.7 cm)", ""),
+ ("A5_14.8_21.0", "A5 (14.8x21.0 cm)", ""),
+ ("A6_10.5_14.8", "A6 (10.5x14.8 cm)", ""),
+ ("A7_7.4_10.5", "A7 (7.4x10.5 cm)", ""),
+ ("A8_5.2_7.4", "A8 (5.2x7.4 cm)", ""),
+ ("A9_3.7_5.2", "A9 (3.7x5.2 cm)", ""),
+ ("A10_2.6_3.7", "A10 (2.6x3.7 cm)", ""),
+
+ ("B0_100.0_141.4", "B0 (100.0x141.4 cm)", ""),
+ ("B1_70.7_100.0", "B1 (70.7x100.0 cm)", ""),
+ ("B2_50.0_70.7", "B2 (50.0x70.7 cm)", ""),
+ ("B3_35.3_50.0", "B3 (35.3x50.0 cm)", ""),
+ ("B4_25.0_35.3", "B4 (25.0x35.3 cm)", ""),
+ ("B5_17.6_25.0", "B5 (17.6x25.0 cm)", ""),
+ ("B6_12.5_17.6", "B6 (12.5x17.6 cm)", ""),
+ ("B7_8.8_12.5", "B7 (8.8x12.5 cm)", ""),
+ ("B8_6.2_8.8", "B8 (6.2x8.8 cm)", ""),
+ ("B9_4.4_6.2", "B9 (4.4x6.2 cm)", ""),
+ ("B10_3.1_4.4", "B10 (3.1x4.4 cm)", ""),
+
+ ("C0_91.7_129.7", "C0 (91.7x129.7 cm)", ""),
+ ("C1_64.8_91.7", "C1 (64.8x91.7 cm)", ""),
+ ("C2_45.8_64.8", "C2 (45.8x64.8 cm)", ""),
+ ("C3_32.4_45.8", "C3 (32.4x45.8 cm)", ""),
+ ("C4_22.9_32.4", "C4 (22.9x32.4 cm)", ""),
+ ("C5_16.2_22.9", "C5 (16.2x22.9 cm)", ""),
+ ("C6_11.4_16.2", "C6 (11.4x16.2 cm)", ""),
+ ("C7_8.1_11.4", "C7 (8.1x11.4 cm)", ""),
+ ("C8_5.7_8.1", "C8 (5.7x8.1 cm)", ""),
+ ("C9_4.0_5.7", "C9 (4.0x5.7 cm)", ""),
+ ("C10_2.8_4.0", "C10 (2.8x4.0 cm)", ""),
+
+ ("Letter_21.6_27.9", "Letter (21.6x27.9 cm)", ""),
+ ("Legal_21.6_35.6", "Legal (21.6x35.6 cm)", ""),
+ ("Legal junior_20.3_12.7", "Legal junior (20.3x12.7 cm)", ""),
+ ("Ledger_43.2_27.9", "Ledger (43.2x27.9 cm)", ""),
+ ("Tabloid_27.9_43.2", "Tabloid (27.9x43.2 cm)", ""),
+
+ ("ANSI C_43.2_55.9", "ANSI C (43.2x55.9 cm)", ""),
+ ("ANSI D_55.9_86.4", "ANSI D (55.9x86.4 cm)", ""),
+ ("ANSI E_86.4_111.8", "ANSI E (86.4x111.8 cm)", ""),
+
+ ("Arch A_22.9_30.5", "Arch A (22.9x30.5 cm)", ""),
+ ("Arch B_30.5_45.7", "Arch B (30.5x45.7 cm)", ""),
+ ("Arch C_45.7_61.0", "Arch C (45.7x61.0 cm)", ""),
+ ("Arch D_61.0_91.4", "Arch D (61.0x91.4 cm)", ""),
+ ("Arch E_91.4_121.9", "Arch E (91.4x121.9 cm)", ""),
+ ("Arch E1_76.2_106.7", "Arch E1 (76.2x106.7 cm)", ""),
+ ("Arch E2_66.0_96.5", "Arch E2 (66.0x96.5 cm)", ""),
+ ("Arch E3_68.6_99.1", "Arch E3 (68.6x99.1 cm)", ""),
+ )
+
+
+def paper_enum_parse(idname):
+ tipo, dim_w, dim_h = idname.split("_")
+ return tipo, float(dim_w), float(dim_h)
+
+
+paper_presets_data = {idname: paper_enum_parse(idname)
+ for idname, name, descr in paper_presets}
+
+
+def update_settings_cb(self, context):
+ # annoying workaround for recursive call
+ if update_settings_cb.level is False:
+ update_settings_cb.level = True
+ pixels_from_print(self)
+ update_settings_cb.level = False
+
+update_settings_cb.level = False
+
+
+class RenderPrintSertings(PropertyGroup):
+ unit_from = EnumProperty(
+ name="Set from",
+ description="Set from",
+ items=(
+ ("CM_TO_PIXELS", "CM -> Pixel", "Centermeters to Pixels"),
+ ("PIXELS_TO_CM", "Pixel -> CM", "Pixels to Centermeters")
+ ),
+ default="CM_TO_PIXELS",
+ )
+ orientation = EnumProperty(
+ name="Page Orientation",
+ description="Set orientation",
+ items=(
+ ("Portrait", "Portrait", "Portrait"),
+ ("Landscape", "Landscape", "Landscape")
+ ),
+ default="Portrait",
+ update=update_settings_cb,
+ )
+ preset = EnumProperty(
+ name="Select Preset",
+ description="Select from preset",
+ items=paper_presets,
+ default="custom_1_1",
+ update=update_settings_cb,
+ )
+ dpi = IntProperty(
+ name="DPI",
+ description="Dots per Inch",
+ default=300,
+ min=72, max=1800,
+ update=update_settings_cb,
+ )
+ width_cm = FloatProperty(
+ name="Width",
+ description="Width in CM",
+ default=5.0,
+ min=1.0, max=100000.0,
+ update=update_settings_cb,
+ )
+ height_cm = FloatProperty(
+ name="Height",
+ description="Height in CM",
+ default=3.0,
+ min=1.0, max=100000.0,
+ update=update_settings_cb,
+ )
+ width_px = IntProperty(
+ name="Pixel Width",
+ description="Pixel Width",
+ default=900,
+ min=4, max=10000,
+ update=update_settings_cb,
+ )
+ height_px = IntProperty(
+ name="Pixel Height",
+ description="Pixel Height",
+ default=600,
+ min=4, max=10000,
+ update=update_settings_cb,
+ )
+
+
+def pixels_from_print(ps):
+ tipo, dim_w, dim_h = paper_presets_data[ps.preset]
+
+ if ps.unit_from == "CM_TO_PIXELS":
+ if tipo == "custom":
+ dim_w = ps.width_cm
+ dim_h = ps.height_cm
+ ps.width_cm = dim_w
+ ps.height_cm = dim_h
+ elif tipo != "custom" and ps.orientation == "Landscape":
+ ps.width_cm = dim_h
+ ps.height_cm = dim_w
+ elif tipo != "custom" and ps.orientation == "Portrait":
+ ps.width_cm = dim_w
+ ps.height_cm = dim_h
+
+ ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54)
+ ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54)
+ else:
+ if tipo != "custom" and ps.orientation == "Landscape":
+ ps.width_cm = dim_h
+ ps.height_cm = dim_w
+ ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54)
+ ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54)
+ elif tipo != "custom" and ps.orientation == "Portrait":
+ ps.width_cm = dim_w
+ ps.height_cm = dim_h
+ ps.width_px = math.ceil((ps.width_cm * ps.dpi) / 2.54)
+ ps.height_px = math.ceil((ps.height_cm * ps.dpi) / 2.54)
+
+ ps.width_cm = (ps.width_px / ps.dpi) * 2.54
+ ps.height_cm = (ps.height_px / ps.dpi) * 2.54
+
+
+class RENDER_PT_print(Panel):
+ bl_label = "Render to Print"
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = 'render'
+
+ def draw(self, context):
+
+ layout = self.layout
+ scene = context.scene
+ ps = scene.print_settings
+
+ row = layout.row(align=True)
+ row1 = layout.row(align=True)
+ row2 = layout.row(align=True)
+ row3 = layout.row(align=True)
+ row4 = layout.row(align=True)
+ row5 = layout.row(align=True)
+ row6 = layout.row(align=True)
+ row7 = layout.row(align=True)
+ col = layout.column(align=True)
+
+ row.prop(ps, "unit_from")
+ row1.prop(ps, "orientation")
+ row2.prop(ps, "preset")
+
+ col.separator()
+ row3.prop(ps, "width_cm")
+ row3.separator()
+ row3.prop(ps, "height_cm")
+ col.separator()
+ row4.prop(ps, "dpi")
+ col.separator()
+ row5.prop(ps, "width_px")
+ row5.separator()
+ row5.prop(ps, "height_px")
+
+ col.separator()
+ row6.label("Inch Width: %.2f" % (ps.width_cm / 2.54))
+ row6.label("Inch Height: %.2f" % (ps.height_cm / 2.54))
+ col.separator()
+
+ row7.operator("render.apply_size", icon="RENDER_STILL")
+
+ # this if else deals with hiding UI elements when logic demands it.
+ tipo = paper_presets_data[ps.preset][0]
+
+ if tipo != "custom":
+ row.active = False
+ row.enabled = False
+
+ if ps.unit_from == "CM_TO_PIXELS":
+ row5.active = False
+ row5.enabled = False
+
+ if tipo == "custom":
+ row3.active = True
+ row3.enabled = True
+ row1.active = False
+ row1.enabled = False
+ elif tipo != "custom" and ps.orientation == "Landscape":
+ row3.active = False
+ row3.enabled = False
+ row1.active = True
+ row1.enabled = True
+ elif tipo != "custom" and ps.orientation == "Portrait":
+ row3.active = False
+ row3.enabled = False
+ row1.active = True
+ row1.enabled = True
+ else:
+ row3.active = False
+ row3.enabled = False
+
+ if tipo == "custom":
+ row1.active = False
+ row1.enabled = False
+ elif tipo != "custom" and ps.orientation == "Landscape":
+ row1.active = True
+ row1.enabled = True
+ row5.active = False
+ row5.enabled = False
+ elif tipo != "custom" and ps.orientation == "Portrait":
+ row1.active = True
+ row1.enabled = True
+ row5.active = False
+ row5.enabled = False
+
+
+class RENDER_OT_apply_size(Operator):
+ bl_idname = "render.apply_size"
+ bl_label = "Apply Print to Render"
+ bl_description = "Set the render dimension"
+
+ def execute(self, context):
+
+ scene = context.scene
+ ps = scene.print_settings
+
+ pixels_from_print(ps)
+
+ render = scene.render
+ render.resolution_x = ps.width_px
+ render.resolution_y = ps.height_px
+
+ return {'FINISHED'}
+
+
+def register():
+ bpy.utils.register_class(RENDER_OT_apply_size)
+ bpy.utils.register_class(RENDER_PT_print)
+ bpy.utils.register_class(RenderPrintSertings)
+
+ Scene.print_settings = PointerProperty(type=RenderPrintSertings)
+
+
+def unregister():
+ bpy.utils.unregister_class(RENDER_OT_apply_size)
+ bpy.utils.unregister_class(RENDER_PT_print)
+ bpy.utils.unregister_class(RenderPrintSertings)
+ del Scene.print_settings
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/sequencer_extra_actions/__init__.py b/release/scripts/addons_contrib/sequencer_extra_actions/__init__.py
new file mode 100644
index 0000000..7e6383f
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_extra_actions/__init__.py
@@ -0,0 +1,94 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Extra Sequencer Actions",
+ "author": "Turi Scandurra, Carlos Padial",
+ "version": (3, 6),
+ "blender": (2, 65, 0),
+ "api": 53177,
+ "category": "Sequencer",
+ "location": "Sequencer",
+ "description": "Collection of extra operators to manipulate VSE strips",
+ "wiki_url": "http://wiki.blender.org/index.php/"
+ "Extensions:2.6/Py/Scripts/Sequencer/Extra_Sequencer_Actions",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail"
+ "&aid=30474",
+ "support": "COMMUNITY"}
+
+if "bpy" in locals():
+ import imp
+ imp.reload(operators_extra_actions)
+ imp.reload(ui)
+else:
+ from . import operators_extra_actions
+ from . import ui
+
+import bpy
+import os.path
+from bpy.types import Menu
+from bpy.types import Header
+
+
+# Registration
+def register():
+ bpy.utils.register_module(__name__)
+
+ # Append menu entries
+ bpy.types.SEQUENCER_MT_add.prepend(ui.sequencer_add_menu_func)
+ bpy.types.SEQUENCER_MT_select.prepend(ui.sequencer_select_menu_func)
+ bpy.types.SEQUENCER_MT_strip.prepend(ui.sequencer_strip_menu_func)
+ bpy.types.SEQUENCER_HT_header.append(ui.sequencer_header_func)
+ bpy.types.CLIP_HT_header.append(ui.clip_header_func)
+ bpy.types.CLIP_MT_clip.prepend(ui.clip_clip_menu_func)
+ bpy.types.TIME_MT_frame.prepend(ui.time_frame_menu_func)
+ bpy.types.TIME_HT_header.append(ui.time_header_func)
+
+ # Add keyboard shortcut configuration
+ kc = bpy.context.window_manager.keyconfigs.addon
+ km = kc.keymaps.new(name='Frames')
+ kmi = km.keymap_items.new('screenextra.frame_skip',
+ 'RIGHT_ARROW', 'PRESS', ctrl=True, shift=True)
+ kmi.properties.back = False
+ kmi = km.keymap_items.new('screenextra.frame_skip',
+ 'LEFT_ARROW', 'PRESS', ctrl=True, shift=True)
+ kmi.properties.back = True
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ # Remove menu entries
+ bpy.types.SEQUENCER_MT_add.remove(ui.sequencer_add_menu_func)
+ bpy.types.SEQUENCER_MT_select.remove(ui.sequencer_select_menu_func)
+ bpy.types.SEQUENCER_MT_strip.remove(ui.sequencer_strip_menu_func)
+ bpy.types.SEQUENCER_HT_header.remove(ui.sequencer_header_func)
+ bpy.types.CLIP_HT_header.remove(ui.clip_header_func)
+ bpy.types.CLIP_MT_clip.remove(ui.clip_clip_menu_func)
+ bpy.types.TIME_MT_frame.remove(ui.time_frame_menu_func)
+ bpy.types.TIME_HT_header.remove(ui.time_header_func)
+
+ # Remove keyboard shortcut configuration
+ kc = bpy.context.window_manager.keyconfigs.addon
+ km = kc.keymaps['Frames']
+ km.keymap_items.remove(km.keymap_items['screenextra.frame_skip'])
+ km.keymap_items.remove(km.keymap_items['screenextra.frame_skip'])
+
+
+if __name__ == '__main__':
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/sequencer_extra_actions/exiftool.py b/release/scripts/addons_contrib/sequencer_extra_actions/exiftool.py
new file mode 100644
index 0000000..f42e3f3
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_extra_actions/exiftool.py
@@ -0,0 +1,330 @@
+# -*- coding: utf-8 -*-
+# PyExifTool <http://github.com/smarnach/pyexiftool>
+# Copyright 2012 Sven Marnach
+
+# This file is part of PyExifTool.
+#
+# PyExifTool 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 3 of the License, or
+# (at your option) any later version.
+#
+# PyExifTool 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 PyExifTool. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+PyExifTool is a Python library to communicate with an instance of Phil
+Harvey's excellent ExifTool_ command-line application. The library
+provides the class :py:class:`ExifTool` that runs the command-line
+tool in batch mode and features methods to send commands to that
+program, including methods to extract meta-information from one or
+more image files. Since ``exiftool`` is run in batch mode, only a
+single instance needs to be launched and can be reused for many
+queries. This is much more efficient than launching a separate
+process for every single query.
+
+.. _ExifTool: http://www.sno.phy.queensu.ca/~phil/exiftool/
+
+The source code can be checked out from the github repository with
+
+::
+
+ git clone git://github.com/smarnach/pyexiftool.git
+
+Alternatively, you can download a tarball_. There haven't been any
+releases yet.
+
+.. _tarball: https://github.com/smarnach/pyexiftool/tarball/master
+
+PyExifTool is licenced under GNU GPL version 3 or later.
+
+Example usage::
+
+ import exiftool
+
+ files = ["a.jpg", "b.png", "c.tif"]
+ with exiftool.ExifTool() as et:
+ metadata = et.get_metadata_batch(files)
+ for d in metadata:
+ print("{:20.20} {:20.20}".format(d["SourceFile"],
+ d["EXIF:DateTimeOriginal"]))
+"""
+
+from __future__ import unicode_literals
+
+import sys
+import subprocess
+import os
+import json
+import warnings
+import codecs
+
+try: # Py3k compatibility
+ basestring
+except NameError:
+ basestring = (bytes, str)
+
+executable = "exiftool"
+"""The name of the executable to run.
+
+If the executable is not located in one of the paths listed in the
+``PATH`` environment variable, the full path should be given here.
+"""
+
+# Sentinel indicating the end of the output of a sequence of commands.
+# The standard value should be fine.
+sentinel = b"{ready}"
+
+# The block size when reading from exiftool. The standard value
+# should be fine, though other values might give better performance in
+# some cases.
+block_size = 4096
+
+# This code has been adapted from Lib/os.py in the Python source tree
+# (sha1 265e36e277f3)
+
+
+def _fscodec():
+ encoding = sys.getfilesystemencoding()
+ errors = "strict"
+ if encoding != "mbcs":
+ try:
+ codecs.lookup_error("surrogateescape")
+ except LookupError:
+ pass
+ else:
+ errors = "surrogateescape"
+
+ def fsencode(filename):
+ """
+ Encode filename to the filesystem encoding with 'surrogateescape' error
+ handler, return bytes unchanged. On Windows, use 'strict' error handler
+ if the file system encoding is 'mbcs' (which is the default encoding).
+ """
+ if isinstance(filename, bytes):
+ return filename
+ else:
+ return filename.encode(encoding, errors)
+
+ return fsencode
+
+fsencode = _fscodec()
+del _fscodec
+
+
+class ExifTool(object):
+ """Run the `exiftool` command-line tool and communicate to it.
+
+ You can pass the file name of the ``exiftool`` executable as an
+ argument to the constructor. The default value ``exiftool`` will
+ only work if the executable is in your ``PATH``.
+
+ Most methods of this class are only available after calling
+ :py:meth:`start()`, which will actually launch the subprocess. To
+ avoid leaving the subprocess running, make sure to call
+ :py:meth:`terminate()` method when finished using the instance.
+ This method will also be implicitly called when the instance is
+ garbage collected, but there are circumstance when this won't ever
+ happen, so you should not rely on the implicit process
+ termination. Subprocesses won't be automatically terminated if
+ the parent process exits, so a leaked subprocess will stay around
+ until manually killed.
+
+ A convenient way to make sure that the subprocess is terminated is
+ to use the :py:class:`ExifTool` instance as a context manager::
+
+ with ExifTool() as et:
+ ...
+
+ .. warning:: Note that there is no error handling. Nonsensical
+ options will be silently ignored by exiftool, so there's not
+ much that can be done in that regard. You should avoid passing
+ non-existent files to any of the methods, since this will lead
+ to undefied behaviour.
+
+ .. py:attribute:: running
+
+ A Boolean value indicating whether this instance is currently
+ associated with a running subprocess.
+ """
+
+ def __init__(self, executable_=None):
+ if executable_ is None:
+ self.executable = executable
+ else:
+ self.executable = executable_
+ self.running = False
+
+ def start(self):
+ """Start an ``exiftool`` process in batch mode for this instance.
+
+ This method will issue a ``UserWarning`` if the subprocess is
+ already running. The process is started with the ``-G`` and
+ ``-n`` as common arguments, which are automatically included
+ in every command you run with :py:meth:`execute()`.
+ """
+ if self.running:
+ warnings.warn("ExifTool already running; doing nothing.")
+ return
+ with open(os.devnull, "w") as devnull:
+ self._process = subprocess.Popen(
+ [self.executable, "-stay_open", "True", "-@", "-",
+ "-common_args", "-G", "-u", "-a", "-n"],
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=devnull)
+ self.running = True
+
+ def terminate(self):
+ """Terminate the ``exiftool`` process of this instance.
+
+ If the subprocess isn't running, this method will do nothing.
+ """
+ if not self.running:
+ return
+ self._process.stdin.write(b"-stay_open\nFalse\n")
+ self._process.stdin.flush()
+ self._process.communicate()
+ del self._process
+ self.running = False
+
+ def __enter__(self):
+ self.start()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.terminate()
+
+ def __del__(self):
+ self.terminate()
+
+ def execute(self, *params):
+ """Execute the given batch of parameters with ``exiftool``.
+
+ This method accepts any number of parameters and sends them to
+ the attached ``exiftool`` process. The process must be
+ running, otherwise ``ValueError`` is raised. The final
+ ``-execute`` necessary to actually run the batch is appended
+ automatically; see the documentation of :py:meth:`start()` for
+ the common options. The ``exiftool`` output is read up to the
+ end-of-output sentinel and returned as a raw ``bytes`` object,
+ excluding the sentinel.
+
+ The parameters must also be raw ``bytes``, in whatever
+ encoding exiftool accepts. For filenames, this should be the
+ system's filesystem encoding.
+
+ .. note:: This is considered a low-level method, and should
+ rarely be needed by application developers.
+ """
+ if not self.running:
+ raise ValueError("ExifTool instance not running.")
+ self._process.stdin.write(b"\n".join(params + (b"-execute\n",)))
+ self._process.stdin.flush()
+ output = b""
+ fd = self._process.stdout.fileno()
+ while not output[-32:].strip().endswith(sentinel):
+ output += os.read(fd, block_size)
+ return output.strip()[:-len(sentinel)]
+
+ def execute_json(self, *params):
+ """Execute the given batch of parameters and parse the JSON output.
+
+ This method is similar to :py:meth:`execute()`. It
+ automatically adds the parameter ``-j`` to request JSON output
+ from ``exiftool`` and parses the output. The return value is
+ a list of dictionaries, mapping tag names to the corresponding
+ values. All keys are Unicode strings with the tag names
+ including the ExifTool group name in the format <group>:<tag>.
+ The values can have multiple types. All strings occurring as
+ values will be Unicode strings. Each dictionary contains the
+ name of the file it corresponds to in the key ``"SourceFile"``.
+
+ The parameters to this function must be either raw strings
+ (type ``str`` in Python 2.x, type ``bytes`` in Python 3.x) or
+ Unicode strings (type ``unicode`` in Python 2.x, type ``str``
+ in Python 3.x). Unicode strings will be encoded using
+ system's filesystem encoding. This behaviour means you can
+ pass in filenames according to the convention of the
+ respective Python version – as raw strings in Python 2.x and
+ as Unicode strings in Python 3.x.
+ """
+ params = map(fsencode, params)
+ return json.loads(self.execute(b"-j", *params).decode("utf-8"))
+
+ def get_metadata_batch(self, filenames):
+ """Return all meta-data for the given files.
+
+ The return value will have the format described in the
+ documentation of :py:meth:`execute_json()`.
+ """
+ return self.execute_json(*filenames)
+
+ def get_metadata(self, filename):
+ """Return meta-data for a single file.
+
+ The returned dictionary has the format described in the
+ documentation of :py:meth:`execute_json()`.
+ """
+ return self.execute_json(filename)[0]
+
+ def get_tags_batch(self, tags, filenames):
+ """Return only specified tags for the given files.
+
+ The first argument is an iterable of tags. The tag names may
+ include group names, as usual in the format <group>:<tag>.
+
+ The second argument is an iterable of file names.
+
+ The format of the return value is the same as for
+ :py:meth:`execute_json()`.
+ """
+ # Explicitly ruling out strings here because passing in a
+ # string would lead to strange and hard-to-find errors
+ if isinstance(tags, basestring):
+ raise TypeError("The argument 'tags' must be "
+ "an iterable of strings")
+ if isinstance(filenames, basestring):
+ raise TypeError("The argument 'filenames' must be "
+ "an iterable of strings")
+ params = ["-" + t for t in tags]
+ params.extend(filenames)
+ return self.execute_json(*params)
+
+ def get_tags(self, tags, filename):
+ """Return only specified tags for a single file.
+
+ The returned dictionary has the format described in the
+ documentation of :py:meth:`execute_json()`.
+ """
+ return self.get_tags_batch(tags, [filename])[0]
+
+ def get_tag_batch(self, tag, filenames):
+ """Extract a single tag from the given files.
+
+ The first argument is a single tag name, as usual in the
+ format <group>:<tag>.
+
+ The second argument is an iterable of file names.
+
+ The return value is a list of tag values or ``None`` for
+ non-existent tags, in the same order as ``filenames``.
+ """
+ data = self.get_tags_batch([tag], filenames)
+ result = []
+ for d in data:
+ d.pop("SourceFile")
+ result.append(next(iter(d.values()), None))
+ return result
+
+ def get_tag(self, tag, filename):
+ """Extract a single tag from a single file.
+
+ The return value is the value of the specified tag, or
+ ``None`` if this tag was not found in the file.
+ """
+ return self.get_tag_batch(tag, [filename])[0]
diff --git a/release/scripts/addons_contrib/sequencer_extra_actions/functions.py b/release/scripts/addons_contrib/sequencer_extra_actions/functions.py
new file mode 100644
index 0000000..f52376e
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_extra_actions/functions.py
@@ -0,0 +1,274 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+import os.path
+import operator
+
+from bpy.props import IntProperty
+from bpy.props import FloatProperty
+from bpy.props import EnumProperty
+from bpy.props import BoolProperty
+from bpy.props import StringProperty
+
+
+imb_ext_image = [
+ # IMG
+ ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb",
+ ".rgba", ".tif", ".tiff", ".tx", ".jp2", ".hdr", ".dds",
+ ".dpx", ".cin", ".exr", ".rw2",
+ # IMG QT
+ ".gif", ".psd", ".pct", ".pict", ".pntg", ".qtif"]
+
+
+imb_ext_movie = [
+ ".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v",
+ ".m2t", ".m2ts", ".mts", ".mv", ".avs", ".wmv", ".ogv",
+ ".dv", ".mpeg", ".mpg", ".mpg2", ".vob", ".mkv", ".flv",
+ ".divx", ".xvid", ".mxf"]
+
+movieextdict = [("1", ".avi", ""),
+ ("2", ".flc", ""),
+ ("3", ".mov", ""),
+ ("4", ".movie", ""),
+ ("5", ".mp4", ""),
+ ("6", ".m4v", ""),
+ ("7", ".m2v", ""),
+ ("8", ".m2t", ""),
+ ("9", ".m2ts", ""),
+ ("10", ".mts", ""),
+ ("11", ".mv", ""),
+ ("12", ".avs", ""),
+ ("13", ".wmv", ""),
+ ("14", ".ogv", ""),
+ ("15", ".dv", ""),
+ ("16", ".mpeg", ""),
+ ("17", ".mpg", ""),
+ ("18", ".mpg2", ""),
+ ("19", ".vob", ""),
+ ("20", ".mkv", ""),
+ ("21", ".flv", ""),
+ ("22", ".divx", ""),
+ ("23", ".xvid", ""),
+ ("24", ".mxf", "")]
+
+
+# Functions
+
+def add_marker(context, text):
+ scene = context.scene
+ markers = scene.timeline_markers
+ mark = markers.new(name=text)
+ mark.frame = scene.frame_current
+
+
+def act_strip(context):
+ try:
+ return context.scene.sequence_editor.active_strip
+ except AttributeError:
+ return None
+
+
+def detect_strip_type(filepath):
+ imb_ext_image = [
+ # IMG
+ ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb",
+ ".rgba", ".tif", ".tiff", ".tx", ".jp2", ".hdr", ".dds",
+ ".dpx", ".cin", ".exr",
+ # IMG QT
+ ".gif", ".psd", ".pct", ".pict", ".pntg", ".qtif"]
+
+ imb_ext_movie = [
+ ".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v",
+ ".m2t", ".m2ts", ".mts", ".mv", ".avs", ".wmv", ".ogv", ".ogg",
+ ".dv", ".mpeg", ".mpg", ".mpg2", ".vob", ".mkv", ".flv",
+ ".divx", ".xvid", ".mxf"]
+
+ imb_ext_audio = [
+ ".wav", ".ogg", ".oga", ".mp3", ".mp2", ".ac3", ".aac",
+ ".flac", ".wma", ".eac3", ".aif", ".aiff", ".m4a"]
+
+ extension = os.path.splitext(filepath)[1]
+ extension = extension.lower()
+ if extension in imb_ext_image:
+ type = 'IMAGE'
+ elif extension in imb_ext_movie:
+ type = 'MOVIE'
+ elif extension in imb_ext_audio:
+ type = 'SOUND'
+ else:
+ type = None
+
+ return type
+
+
+def getpathfrombrowser():
+ '''
+ returns path from filebrowser
+ '''
+ scn = bpy.context.scene
+ for a in bpy.context.window.screen.areas:
+ if a.type == 'FILE_BROWSER':
+ params = a.spaces[0].params
+ break
+ try:
+ params
+ except UnboundLocalError:
+ #print("no browser")
+ self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
+ return {'CANCELLED'}
+ path = params.directory
+ return path
+
+
+def getfilepathfrombrowser():
+ '''
+ returns path and file from filebrowser
+ '''
+ scn = bpy.context.scene
+ for a in bpy.context.window.screen.areas:
+ if a.type == 'FILE_BROWSER':
+ params = a.spaces[0].params
+ break
+ try:
+ params
+ except UnboundLocalError:
+ #print("no browser")
+ #self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
+ return {'CANCELLED'}
+
+ if params.filename == '':
+ #print("no file selected")
+ #self.report({'ERROR_INVALID_INPUT'}, 'No file selected')
+ return {'CANCELLED'}
+ path = params.directory
+ filename = params.filename
+ return path, filename
+
+
+def setpathinbrowser(path, file):
+ '''
+ set path and file in the filebrowser
+ '''
+ scn = bpy.context.scene
+ for a in bpy.context.window.screen.areas:
+ if a.type == 'FILE_BROWSER':
+ params = a.spaces[0].params
+ break
+ try:
+ params
+ except UnboundLocalError:
+ #print("no browser")
+ self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
+ return {'CANCELLED'}
+
+ params.directory = path
+ params.filename = file
+ return path, params
+
+
+def sortlist(filelist):
+ '''
+ given a list of tuplas (path, filename) returns a list sorted by filename
+ '''
+ filelist_sorted = sorted(filelist, key=operator.itemgetter(1))
+ return filelist_sorted
+
+# recursive load functions
+
+def onefolder(context, default_recursive_ext):
+ '''
+ returns a list of MOVIE type files from folder selected in file browser
+ '''
+ filelist = []
+ path, filename = getfilepathfrombrowser()
+ extension = filename.rpartition(".")[2]
+ scn = context.scene
+
+ if detect_strip_type(path + filename) == 'MOVIE':
+ if default_recursive_ext == True:
+ for file in os.listdir(path):
+ if file.rpartition(".")[2] == extension:
+ filelist.append((path, file))
+ else:
+ for file in os.listdir(path):
+ filelist.append((path, file))
+ return (filelist)
+
+def recursive(context, default_recursive_ext):
+ '''
+ returns a list of MOVIE type files recursively from file browser
+ '''
+ filelist = []
+ path = getpathfrombrowser()
+ scn = context.scene
+ for i in movieextlist:
+ if i[0] == scn.default_ext:
+ extension = i[1].rpartition(".")[2]
+ #pythonic way to magic:
+ for root, dirs, files in os.walk(path):
+ for f in files:
+ if default_recursive_ext == True:
+ if f.rpartition(".")[2] == extension:
+ filelist.append((root, f))
+ else:
+ filelist.append((root, f))
+ return filelist
+
+
+
+# jump to cut functions
+def triminout(strip, sin, sout):
+ start = strip.frame_start + strip.frame_offset_start
+ end = start + strip.frame_final_duration
+ if end > sin:
+ if start < sin:
+ strip.select_right_handle = False
+ strip.select_left_handle = True
+ bpy.ops.sequencer.snap(frame=sin)
+ strip.select_left_handle = False
+ if start < sout:
+ if end > sout:
+ strip.select_left_handle = False
+ strip.select_right_handle = True
+ bpy.ops.sequencer.snap(frame=sout)
+ strip.select_right_handle = False
+ return {'FINISHED'}
+
+
+#------------ random edit functions...
+
+def randompartition(lst,n,rand):
+ division = len(lst) / float(n)
+ lista = []
+ for i in range(n): lista.append(division)
+ var=0
+ for i in range(n-1):
+ lista[i]+= random.randint(-int(rand*division),int(rand*division))
+ var+=lista[i]
+ if lista[n-1] != len(lst)-var:
+ lista[n-1] = len(lst)-var
+ random.shuffle(lista)
+ division = len(lst) / float(n)
+ count = 0
+ newlist=[]
+ for i in range(n):
+ print(lst[count : int(lista[i]-1)+count])
+ newlist.append([lst[count : int(lista[i]-1)+count]])
+ count += int(lista[i])
+ return newlist
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/sequencer_extra_actions/operators_extra_actions.py b/release/scripts/addons_contrib/sequencer_extra_actions/operators_extra_actions.py
new file mode 100644
index 0000000..9ca54c5
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_extra_actions/operators_extra_actions.py
@@ -0,0 +1,1906 @@
+# ##### 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 LICENSE BLOCK #####
+
+'''
+TODO
+align strip to the left (shift-s + -lenght)
+
+'''
+
+import bpy
+
+import random
+import math
+import os, sys
+
+from bpy.props import IntProperty
+from bpy.props import FloatProperty
+from bpy.props import EnumProperty
+from bpy.props import BoolProperty
+from bpy.props import StringProperty
+
+from . import functions
+from . import exiftool
+
+
+# Initialization
+
+
+def initSceneProperties(context, scn):
+ try:
+ if context.scene.scene_initialized == True:
+ return False
+ except AttributeError:
+ pass
+
+ bpy.types.Scene.default_slide_offset = IntProperty(
+ name='Offset',
+ description='Number of frames to slide',
+ min=-250, max=250,
+ default=0)
+ scn.default_slide_offset = 0
+
+ bpy.types.Scene.default_fade_duration = IntProperty(
+ name='Duration',
+ description='Number of frames to fade',
+ min=1, max=250,
+ default=scn.render.fps)
+ scn.default_fade_duration = scn.render.fps
+
+ bpy.types.Scene.default_fade_amount = FloatProperty(
+ name='Amount',
+ description='Maximum value of fade',
+ min=0.0,
+ max=100.0,
+ default=1.0)
+ scn.default_fade_amount = 1.0
+
+ bpy.types.Scene.default_distribute_offset = IntProperty(
+ name='Offset',
+ description='Number of frames between strip start frames',
+ min=1,
+ max=250,
+ default=2)
+ scn.default_distribute_offset = 2
+
+ bpy.types.Scene.default_distribute_reverse = BoolProperty(
+ name='Reverse Order',
+ description='Reverse the order of selected strips',
+ default=False)
+ scn.default_distribute_reverse = False
+
+ bpy.types.Scene.default_proxy_suffix = StringProperty(
+ name='default proxy suffix',
+ description='default proxy filename suffix',
+ default="-25")
+ scn.default_proxy_suffix = "-25"
+
+ bpy.types.Scene.default_proxy_extension = StringProperty(
+ name='default proxy extension',
+ description='default proxy file extension',
+ default=".mkv")
+ scn.default_proxy_extension = ".mkv"
+
+ bpy.types.Scene.default_proxy_path = StringProperty(
+ name='default proxy path',
+ description='default proxy file path (relative to original file)',
+ default="")
+ scn.default_proxy_path = ""
+
+ bpy.types.Scene.default_build_25 = BoolProperty(
+ name='default_build_25',
+ description='default build_25',
+ default=True)
+ scn.default_build_25 = True
+
+ bpy.types.Scene.default_build_50 = BoolProperty(
+ name='default_build_50',
+ description='default build_50',
+ default=False)
+ scn.default_build_50 = False
+
+ bpy.types.Scene.default_build_75 = BoolProperty(
+ name='default_build_75',
+ description='default build_75',
+ default=False)
+ scn.default_build_75 = False
+
+ bpy.types.Scene.default_build_100 = BoolProperty(
+ name='default_build_100',
+ description='default build_100',
+ default=False)
+ scn.default_build_100 = False
+
+ bpy.types.Scene.default_recursive = BoolProperty(
+ name='Recursive',
+ description='Load in recursive folders',
+ default=False)
+ scn.default_recursive = False
+
+ bpy.types.Scene.default_recursive_ext = BoolProperty(
+ name='Recursive ext',
+ description='Load only clips with selected extension',
+ default=False)
+ scn.default_recursive_ext = False
+
+ bpy.types.Scene.default_recursive_proxies = BoolProperty(
+ name='Recursive proxies',
+ description='Load in recursive folders + proxies',
+ default=False)
+ scn.default_recursive_proxies = False
+
+ bpy.types.Scene.default_ext = EnumProperty(
+ items=functions.movieextdict,
+ name="ext enum",
+ default="3")
+ scn.default_ext = "3"
+
+ bpy.types.Scene.scene_initialized = BoolProperty(
+ name='Init',
+ default=False)
+ scn.scene_initialized = True
+
+ return True
+
+
+# TRIM TIMELINE
+class Sequencer_Extra_TrimTimeline(bpy.types.Operator):
+ bl_label = 'Trim to Timeline Content'
+ bl_idname = 'timeextra.trimtimeline'
+ bl_description = 'Automatically set start and end frames'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return scn.sequence_editor.sequences
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+
+ frame_start = 300000
+ frame_end = -300000
+ for i in seq.sequences:
+ try:
+ if i.frame_final_start < frame_start:
+ frame_start = i.frame_final_start
+ if i.frame_final_end > frame_end:
+ frame_end = i.frame_final_end - 1
+ except AttributeError:
+ pass
+
+ if frame_start != 300000:
+ scn.frame_start = frame_start
+ if frame_end != -300000:
+ scn.frame_end = frame_end
+ return {'FINISHED'}
+
+
+# TRIM TIMELINE TO SELECTION
+class Sequencer_Extra_TrimTimelineToSelection(bpy.types.Operator):
+ bl_label = 'Trim to Selection'
+ bl_idname = 'timeextra.trimtimelinetoselection'
+ bl_description = 'Set start and end frames to selection'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return scn.sequence_editor.sequences
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+
+ frame_start = 300000
+ frame_end = -300000
+ for i in seq.sequences:
+ try:
+ if i.frame_final_start < frame_start and i.select == True:
+ frame_start = i.frame_final_start
+ if i.frame_final_end > frame_end and i.select == True:
+ frame_end = i.frame_final_end - 1
+ except AttributeError:
+ pass
+
+ if frame_start != 300000:
+ scn.frame_start = frame_start
+ if frame_end != -300000:
+ scn.frame_end = frame_end
+ return {'FINISHED'}
+
+
+# SLIDE STRIP
+class Sequencer_Extra_SlideStrip(bpy.types.Operator):
+ bl_label = 'Slide'
+ bl_idname = 'sequencerextra.slide'
+ bl_description = 'Alter in and out points but not duration of a strip'
+ mode = EnumProperty(
+ name='Mode',
+ items=(
+ ('TOSTART', 'Current Frame to Strip Start', ''),
+ ('TOEND', 'Current Frame to Strip End', ''),
+ ('INPUT', 'Input...', '')),
+ default='INPUT',
+ options={'HIDDEN'})
+ bl_options = {'REGISTER', 'UNDO'}
+
+ slide_offset = IntProperty(
+ name='Offset',
+ description='Number of frames to slide',
+ min=-250, max=250,
+ default=0)
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return strip.type in ('MOVIE', 'IMAGE', 'META', 'SCENE')
+ else:
+ return False
+
+ def execute(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ cf = scn.frame_current
+
+ if self.mode == 'TOSTART':
+ sx = strip.frame_final_start - cf
+ elif self.mode == 'TOEND':
+ sx = strip.frame_final_end - cf
+ else:
+ sx = self.slide_offset
+
+ frame_end = strip.frame_start + strip.frame_duration
+ pad_left = strip.frame_final_start - strip.frame_start
+ pad_right = (frame_end - strip.frame_final_end) * -1
+
+ if sx > pad_left:
+ sx = pad_left
+ elif sx < pad_right:
+ sx = pad_right
+
+ strip.frame_start += sx
+ strip.frame_final_start -= sx
+ strip.frame_final_end -= sx
+
+ self.report({'INFO'}, 'Strip slid %d frame(s)' % (sx))
+ scn.default_slide_offset = sx
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ scn = context.scene
+ initSceneProperties(context,scn)
+ self.slide_offset = scn.default_slide_offset
+ if self.mode == 'INPUT':
+ return context.window_manager.invoke_props_dialog(self)
+ else:
+ return self.execute(context)
+
+
+# SLIDE GRAB
+class Sequencer_Extra_SlideGrab(bpy.types.Operator):
+ bl_label = 'Slide Grab'
+ bl_idname = 'sequencerextra.slidegrab'
+ bl_description = 'Alter in and out points but not duration of a strip'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return strip.type in ('MOVIE', 'IMAGE', 'META', 'SCENE')
+ else:
+ return False
+
+ def execute(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+
+ diff = self.prev_x - self.x
+ self.prev_x = self.x
+ sx = int(diff / 2)
+
+ frame_end = strip.frame_start + strip.frame_duration
+ pad_left = strip.frame_final_start - strip.frame_start
+ pad_right = (frame_end - strip.frame_final_end) * -1
+
+ if sx > pad_left:
+ sx = pad_left
+ elif sx < pad_right:
+ sx = pad_right
+
+ strip.frame_start += sx
+ strip.frame_final_start -= sx
+ strip.frame_final_end -= sx
+
+ def modal(self, context, event):
+ if event.type == 'MOUSEMOVE':
+ self.x = event.mouse_x
+ self.execute(context)
+ elif event.type == 'LEFTMOUSE':
+ return {'FINISHED'}
+ elif event.type in ('RIGHTMOUSE', 'ESC'):
+ return {'CANCELLED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ scn = context.scene
+ self.x = event.mouse_x
+ self.prev_x = event.mouse_x
+ self.execute(context)
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+
+# FILE NAME TO STRIP NAME
+class Sequencer_Extra_FileNameToStripName(bpy.types.Operator):
+ bl_label = 'File Name to Selected Strips Name'
+ bl_idname = 'sequencerextra.striprename'
+ bl_description = 'Set strip name to input file name'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return scn.sequence_editor.sequences
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ selection = False
+ for i in seq.sequences:
+ if i.select == True:
+ if i.type == 'IMAGE' and not i.mute:
+ selection = True
+ i.name = i.elements[0].filename
+ if (i.type == 'SOUND' or i.type == 'MOVIE') and not i.mute:
+ selection = True
+ i.name = bpy.path.display_name_from_filepath(i.filepath)
+ if selection == False:
+ self.report({'ERROR_INVALID_INPUT'},
+ 'No image or movie strip selected')
+ return {'CANCELLED'}
+ return {'FINISHED'}
+
+
+# NAVIGATE UP
+class Sequencer_Extra_NavigateUp(bpy.types.Operator):
+ bl_label = 'Navigate Up'
+ bl_idname = 'sequencerextra.navigateup'
+ bl_description = 'Move to Parent Timeline'
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ try:
+ if context.scene.sequence_editor.meta_stack:
+ return True
+ else:
+ return False
+ except:
+ return False
+
+ def execute(self, context):
+ if (functions.act_strip(context)):
+ strip = functions.act_strip(context)
+ seq_type = strip.type
+ if seq_type == 'META':
+ context.scene.sequence_editor.active_strip = None
+
+ bpy.ops.sequencer.meta_toggle()
+ return {'FINISHED'}
+
+
+# RIPPLE DELETE
+class Sequencer_Extra_RippleDelete(bpy.types.Operator):
+ bl_label = 'Ripple Delete'
+ bl_idname = 'sequencerextra.rippledelete'
+ bl_description = 'Delete a strip and shift back following ones'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ #strip = functions.act_strip(context)
+ for strip in context.selected_editable_sequences:
+ cut_frame = strip.frame_final_start
+ next_edit = 300000
+ bpy.ops.sequencer.select_all(action='DESELECT')
+ strip.select = True
+ bpy.ops.sequencer.delete()
+ striplist = []
+ for i in seq.sequences:
+ try:
+ if (i.frame_final_start > cut_frame
+ and not i.mute):
+ if i.frame_final_start < next_edit:
+ next_edit = i.frame_final_start
+ if not i.mute:
+ striplist.append(i)
+ except AttributeError:
+ pass
+
+ if next_edit == 300000:
+ return {'FINISHED'}
+ ripple_length = next_edit - cut_frame
+ for i in range(len(striplist)):
+ str = striplist[i]
+ try:
+ if str.frame_final_start > cut_frame:
+ str.frame_start = str.frame_start - ripple_length
+ except AttributeError:
+ pass
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+
+# RIPPLE CUT
+class Sequencer_Extra_RippleCut(bpy.types.Operator):
+ bl_label = 'Ripple Cut'
+ bl_idname = 'sequencerextra.ripplecut'
+ bl_description = 'Move a strip to buffer and shift back following ones'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ strip = functions.act_strip(context)
+ bpy.ops.sequencer.select_all(action='DESELECT')
+ strip.select = True
+ temp_cf = scn.frame_current
+ scn.frame_current = strip.frame_final_start
+ bpy.ops.sequencer.copy()
+ scn.frame_current = temp_cf
+
+ bpy.ops.sequencerextra.rippledelete()
+ return {'FINISHED'}
+
+
+# INSERT
+class Sequencer_Extra_Insert(bpy.types.Operator):
+ bl_label = 'Insert'
+ bl_idname = 'sequencerextra.insert'
+ bl_description = 'Move active strip to current frame and shift '\
+ 'forward following ones'
+ singlechannel = BoolProperty(
+ name='Single Channel',
+ default=False)
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ strip = functions.act_strip(context)
+ gap = strip.frame_final_duration
+ bpy.ops.sequencer.select_all(action='DESELECT')
+ current_frame = scn.frame_current
+
+ striplist = []
+ for i in seq.sequences:
+ try:
+ if (i.frame_final_start >= current_frame
+ and not i.mute):
+ if self.singlechannel == True:
+ if i.channel == strip.channel:
+ striplist.append(i)
+ else:
+ striplist.append(i)
+ except AttributeError:
+ pass
+ try:
+ bpy.ops.sequencerextra.selectcurrentframe('EXEC_DEFAULT',
+ mode='AFTER')
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Execution Error, '\
+ 'check your Blender version')
+ return {'CANCELLED'}
+
+ for i in range(len(striplist)):
+ str = striplist[i]
+ try:
+ if str.select == True:
+ str.frame_start += gap
+ except AttributeError:
+ pass
+ try:
+ diff = current_frame - strip.frame_final_start
+ strip.frame_start += diff
+ except AttributeError:
+ pass
+
+ strip = functions.act_strip(context)
+ scn.frame_current += strip.frame_final_duration
+ bpy.ops.sequencer.reload()
+
+ return {'FINISHED'}
+
+
+# PLACE FROM FILE BROWSER
+class Sequencer_Extra_PlaceFromFileBrowser(bpy.types.Operator):
+ bl_label = 'Place'
+ bl_idname = 'sequencerextra.placefromfilebrowser'
+ bl_description = 'Place or insert active file from File Browser'
+ insert = BoolProperty(
+ name='Insert',
+ default=False)
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ scn = context.scene
+ for a in context.window.screen.areas:
+ if a.type == 'FILE_BROWSER':
+ params = a.spaces[0].params
+ break
+ try:
+ params
+ except UnboundLocalError:
+ self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
+ return {'CANCELLED'}
+
+ if params.filename == '':
+ self.report({'ERROR_INVALID_INPUT'}, 'No file selected')
+ return {'CANCELLED'}
+
+ path = os.path.join(params.directory, params.filename)
+ frame = context.scene.frame_current
+ strip_type = functions.detect_strip_type(params.filename)
+
+ try:
+ if strip_type == 'IMAGE':
+ image_file = []
+ filename = {"name": params.filename}
+ image_file.append(filename)
+ f_in = scn.frame_current
+ f_out = f_in + scn.render.fps - 1
+ bpy.ops.sequencer.image_strip_add(files=image_file,
+ directory=params.directory, frame_start=f_in,
+ frame_end=f_out, relative_path=False)
+ elif strip_type == 'MOVIE':
+ bpy.ops.sequencer.movie_strip_add(filepath=path,
+ frame_start=frame, relative_path=False)
+ elif strip_type == 'SOUND':
+ bpy.ops.sequencer.sound_strip_add(filepath=path,
+ frame_start=frame, relative_path=False)
+ else:
+ self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
+ return {'CANCELLED'}
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ if self.insert == True:
+ try:
+ striplist = []
+ for i in bpy.context.selected_editable_sequences:
+ if (i.select == True and i.type == "SOUND"):
+ striplist.append(i)
+ bpy.ops.sequencerextra.insert()
+ if striplist[0]:
+ striplist[0].frame_start = frame
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Execution Error, '\
+ 'check your Blender version')
+ return {'CANCELLED'}
+ else:
+ strip = functions.act_strip(context)
+ scn.frame_current += strip.frame_final_duration
+ bpy.ops.sequencer.reload()
+
+ return {'FINISHED'}
+
+
+# SELECT BY TYPE
+class Sequencer_Extra_SelectAllByType(bpy.types.Operator):
+ bl_label = 'All by Type'
+ bl_idname = 'sequencerextra.select_all_by_type'
+ bl_description = 'Select all the strips of the same type'
+ type = EnumProperty(
+ name='Strip Type',
+ items=(
+ ('ACTIVE', 'Same as Active Strip', ''),
+ ('IMAGE', 'Image', ''),
+ ('META', 'Meta', ''),
+ ('SCENE', 'Scene', ''),
+ ('MOVIE', 'Movie', ''),
+ ('SOUND', 'Sound', ''),
+ ('TRANSFORM', 'Transform', ''),
+ ('COLOR', 'Color', '')),
+ default='ACTIVE',
+ )
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return scn.sequence_editor.sequences
+ else:
+ return False
+
+ def execute(self, context):
+ strip_type = self.type
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ active_strip = functions.act_strip(context)
+ if strip_type == 'ACTIVE':
+ if active_strip == None:
+ self.report({'ERROR_INVALID_INPUT'},
+ 'No active strip')
+ return {'CANCELLED'}
+ strip_type = active_strip.type
+
+ striplist = []
+ for i in seq.sequences:
+ try:
+ if (i.type == strip_type
+ and not i.mute):
+ striplist.append(i)
+ except AttributeError:
+ pass
+ for i in range(len(striplist)):
+ str = striplist[i]
+ try:
+ str.select = True
+ except AttributeError:
+ pass
+
+ return {'FINISHED'}
+
+
+# CURRENT-FRAME-AWARE SELECT
+class Sequencer_Extra_SelectCurrentFrame(bpy.types.Operator):
+ bl_label = 'Current-Frame-Aware Select'
+ bl_idname = 'sequencerextra.selectcurrentframe'
+ bl_description = 'Select strips according to current frame'
+ mode = EnumProperty(
+ name='Mode',
+ items=(
+ ('BEFORE', 'Before Current Frame', ''),
+ ('AFTER', 'After Current Frame', ''),
+ ('ON', 'On Current Frame', '')),
+ default='BEFORE',
+ )
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return scn.sequence_editor.sequences
+ else:
+ return False
+
+ def execute(self, context):
+ mode = self.mode
+ scn = context.scene
+ seq = scn.sequence_editor
+ cf = scn.frame_current
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+
+ if mode == 'AFTER':
+ for i in seq.sequences:
+ try:
+ if (i.frame_final_start >= cf
+ and not i.mute):
+ i.select = True
+ except AttributeError:
+ pass
+ elif mode == 'ON':
+ for i in seq.sequences:
+ try:
+ if (i.frame_final_start <= cf
+ and i.frame_final_end > cf
+ and not i.mute):
+ i.select = True
+ except AttributeError:
+ pass
+ else:
+ for i in seq.sequences:
+ try:
+ if (i.frame_final_end < cf
+ and not i.mute):
+ i.select = True
+ except AttributeError:
+ pass
+
+ return {'FINISHED'}
+
+
+# SELECT STRIPS ON SAME CHANNEL
+class Sequencer_Extra_SelectSameChannel(bpy.types.Operator):
+ bl_label = 'Select Strips on the Same Channel'
+ bl_idname = 'sequencerextra.selectsamechannel'
+ bl_description = 'Select strips on the same channel as active one'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ bpy.ops.sequencer.select_active_side(side="LEFT")
+ bpy.ops.sequencer.select_active_side(side="RIGHT")
+
+ return {'FINISHED'}
+
+
+# OPEN IMAGE WITH EXTERNAL EDITOR
+class Sequencer_Extra_EditExternally(bpy.types.Operator):
+ bl_label = 'Open with External Editor'
+ bl_idname = 'sequencerextra.editexternally'
+ bl_description = 'Open with the default external image editor'
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return strip.type == 'IMAGE'
+ else:
+ return False
+
+ def execute(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ base_dir = bpy.path.abspath(strip.directory)
+ strip_elem = strip.strip_elem_from_frame(scn.frame_current)
+ path = base_dir + strip_elem.filename
+
+ try:
+ bpy.ops.image.external_edit(filepath=path)
+ except:
+ self.report({'ERROR_INVALID_INPUT'},
+ 'Please specify an Image Editor in Preferences > File')
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+
+# OPEN IMAGE WITH EDITOR
+class Sequencer_Extra_Edit(bpy.types.Operator):
+ bl_label = 'Open with Editor'
+ bl_idname = 'sequencerextra.edit'
+ bl_description = 'Open with Movie Clip or Image Editor'
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return strip.type in ('MOVIE', 'IMAGE')
+ else:
+ return False
+
+ def execute(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ data_exists = False
+
+ if strip.type == 'MOVIE':
+ path = strip.filepath
+
+ for i in bpy.data.movieclips:
+ if i.filepath == path:
+ data_exists = True
+ data = i
+
+ if data_exists == False:
+ try:
+ data = bpy.data.movieclips.load(filepath=path)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ elif strip.type == 'IMAGE':
+ base_dir = bpy.path.abspath(strip.directory)
+ strip_elem = strip.strip_elem_from_frame(scn.frame_current)
+ elem_name = strip_elem.filename
+ path = base_dir + elem_name
+
+ for i in bpy.data.images:
+ if i.filepath == path:
+ data_exists = True
+ data = i
+
+ if data_exists == False:
+ try:
+ data = bpy.data.images.load(filepath=path)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ if strip.type == 'MOVIE':
+ for a in context.window.screen.areas:
+ if a.type == 'CLIP_EDITOR':
+ a.spaces[0].clip = data
+ elif strip.type == 'IMAGE':
+ for a in context.window.screen.areas:
+ if a.type == 'IMAGE_EDITOR':
+ a.spaces[0].image = data
+
+ return {'FINISHED'}
+
+
+# COPY STRIP PROPERTIES
+class Sequencer_Extra_CopyProperties(bpy.types.Operator):
+ bl_label = 'Copy Properties'
+ bl_idname = 'sequencerextra.copyproperties'
+ bl_description = 'Copy properties of active strip to selected strips'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ prop = EnumProperty(
+ name='Property',
+ items=[
+ # COMMON
+ ('name', 'Name', ''),
+ ('blend_alpha', 'Opacity', ''),
+ ('blend_type', 'Blend Mode', ''),
+ ('animation_offset', 'Input - Trim Duration', ''),
+ # NON-SOUND
+ ('use_translation', 'Input - Image Offset', ''),
+ ('crop', 'Input - Image Crop', ''),
+ ('proxy', 'Proxy / Timecode', ''),
+ ('strobe', 'Filter - Strobe', ''),
+ ('color_multiply', 'Filter - Multiply', ''),
+ ('color_saturation', 'Filter - Saturation', ''),
+ ('deinterlace', 'Filter - De-Interlace', ''),
+ ('flip', 'Filter - Flip', ''),
+ ('float', 'Filter - Convert Float', ''),
+ ('alpha_mode', 'Filter - Alpha Mode', ''),
+ ('reverse', 'Filter - Backwards', ''),
+ # SOUND
+ ('pan', 'Sound - Pan', ''),
+ ('pitch', 'Sound - Pitch', ''),
+ ('volume', 'Sound - Volume', ''),
+ ('cache', 'Sound - Caching', ''),
+ # IMAGE
+ ('directory', 'Image - Directory', ''),
+ # MOVIE
+ ('mpeg_preseek', 'Movie - MPEG Preseek', ''),
+ ('stream_index', 'Movie - Stream Index', ''),
+ # WIPE
+ ('wipe', 'Effect - Wipe', ''),
+ # TRANSFORM
+ ('transform', 'Effect - Transform', ''),
+ # COLOR
+ ('color', 'Effect - Color', ''),
+ # SPEED
+ ('speed', 'Effect - Speed', ''),
+ # MULTICAM
+ ('multicam_source', 'Effect - Multicam Source', ''),
+ # EFFECT
+ ('effect_fader', 'Effect - Effect Fader', ''),
+ ],
+ default='blend_alpha')
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ strip = functions.act_strip(context)
+
+ for i in seq.sequences:
+ if (i.select == True and not i.mute):
+ try:
+ if self.prop == 'name':
+ i.name = strip.name
+ elif self.prop == 'blend_alpha':
+ i.blend_alpha = strip.blend_alpha
+ elif self.prop == 'blend_type':
+ i.blend_type = strip.blend_type
+ elif self.prop == 'animation_offset':
+ i.animation_offset_start = strip.animation_offset_start
+ i.animation_offset_end = strip.animation_offset_end
+ elif self.prop == 'use_translation':
+ i.use_translation = strip.use_translation
+ i.transform.offset_x = strip.transform.offset_x
+ i.transform.offset_y = strip.transform.offset_y
+ elif self.prop == 'crop':
+ i.use_crop = strip.use_crop
+ i.crop.min_x = strip.crop.min_x
+ i.crop.min_y = strip.crop.min_y
+ i.crop.max_x = strip.crop.max_x
+ i.crop.max_y = strip.crop.max_y
+ elif self.prop == 'proxy':
+ i.use_proxy = strip.use_proxy
+ i.use_proxy_custom_file = strip.use_proxy_custom_file
+ p = strip.use_proxy_custom_directory # pep80
+ i.use_proxy_custom_directory = p
+ i.proxy.filepath = strip.proxy.filepath
+ i.proxy.directory = strip.proxy.directory
+ i.proxy.build_25 = strip.proxy.build_25
+ i.proxy.build_50 = strip.proxy.build_50
+ i.proxy.build_75 = strip.proxy.build_75
+ i.proxy.build_100 = strip.proxy.build_100
+ i.proxy.quality = strip.proxy.quality
+ i.proxy.timecode = strip.proxy.timecode
+ elif self.prop == 'strobe':
+ i.strobe = strip.strobe
+ elif self.prop == 'color_multiply':
+ i.color_multiply = strip.color_multiply
+ elif self.prop == 'color_saturation':
+ i.color_saturation = strip.color_saturation
+ elif self.prop == 'deinterlace':
+ i.use_deinterlace = strip.use_deinterlace
+ elif self.prop == 'flip':
+ i.use_flip_x = strip.use_flip_x
+ i.use_flip_y = strip.use_flip_y
+ elif self.prop == 'float':
+ i.use_float = strip.use_float
+ elif self.prop == 'alpha_mode':
+ i.alpha_mode = strip.alpha_mode
+ elif self.prop == 'reverse':
+ i.use_reverse_frames = strip.use_reverse_frames
+ elif self.prop == 'pan':
+ i.pan = strip.pan
+ elif self.prop == 'pitch':
+ i.pitch = strip.pitch
+ elif self.prop == 'volume':
+ i.volume = strip.volume
+ elif self.prop == 'cache':
+ i.use_memory_cache = strip.use_memory_cache
+ elif self.prop == 'directory':
+ i.directory = strip.directory
+ elif self.prop == 'mpeg_preseek':
+ i.mpeg_preseek = strip.mpeg_preseek
+ elif self.prop == 'stream_index':
+ i.stream_index = strip.stream_index
+ elif self.prop == 'wipe':
+ i.angle = strip.angle
+ i.blur_width = strip.blur_width
+ i.direction = strip.direction
+ i.transition_type = strip.transition_type
+ elif self.prop == 'transform':
+ i.interpolation = strip.interpolation
+ i.rotation_start = strip.rotation_start
+ i.use_uniform_scale = strip.use_uniform_scale
+ i.scale_start_x = strip.scale_start_x
+ i.scale_start_y = strip.scale_start_y
+ i.translation_unit = strip.translation_unit
+ i.translate_start_x = strip.translate_start_x
+ i.translate_start_y = strip.translate_start_y
+ elif self.prop == 'color':
+ i.color = strip.color
+ elif self.prop == 'speed':
+ i.use_default_fade = strip.use_default_fade
+ i.speed_factor = strip.speed_factor
+ i.use_as_speed = strip.use_as_speed
+ i.scale_to_length = strip.scale_to_length
+ i.multiply_speed = strip.multiply_speed
+ i.use_frame_blend = strip.use_frame_blend
+ elif self.prop == 'multicam_source':
+ i.multicam_source = strip.multicam_source
+ elif self.prop == 'effect_fader':
+ i.use_default_fade = strip.use_default_fade
+ i.effect_fader = strip.effect_fader
+ except:
+ pass
+
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+
+# FADE IN AND OUT
+class Sequencer_Extra_FadeInOut(bpy.types.Operator):
+ bl_idname = 'sequencerextra.fadeinout'
+ bl_label = 'Fade...'
+ bl_description = 'Fade volume or opacity of active strip'
+ mode = EnumProperty(
+ name='Direction',
+ items=(
+ ('IN', 'Fade In...', ''),
+ ('OUT', 'Fade Out...', ''),
+ ('INOUT', 'Fade In and Out...', '')),
+ default='IN',
+ )
+ bl_options = {'REGISTER', 'UNDO'}
+
+ fade_duration = IntProperty(
+ name='Duration',
+ description='Number of frames to fade',
+ min=1, max=250,
+ default=25)
+ fade_amount = FloatProperty(
+ name='Amount',
+ description='Maximum value of fade',
+ min=0.0,
+ max=100.0,
+ default=1.0)
+
+ @classmethod
+ def poll(cls, context):
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ seq = context.scene.sequence_editor
+ scn = context.scene
+ strip = seq.active_strip
+ tmp_current_frame = context.scene.frame_current
+
+ if strip.type == 'SOUND':
+ if(self.mode) == 'OUT':
+ scn.frame_current = strip.frame_final_end - self.fade_duration
+ strip.volume = self.fade_amount
+ strip.keyframe_insert('volume')
+ scn.frame_current = strip.frame_final_end
+ strip.volume = 0
+ strip.keyframe_insert('volume')
+ elif(self.mode) == 'INOUT':
+ scn.frame_current = strip.frame_final_start
+ strip.volume = 0
+ strip.keyframe_insert('volume')
+ scn.frame_current += self.fade_duration
+ strip.volume = self.fade_amount
+ strip.keyframe_insert('volume')
+ scn.frame_current = strip.frame_final_end - self.fade_duration
+ strip.volume = self.fade_amount
+ strip.keyframe_insert('volume')
+ scn.frame_current = strip.frame_final_end
+ strip.volume = 0
+ strip.keyframe_insert('volume')
+ else:
+ scn.frame_current = strip.frame_final_start
+ strip.volume = 0
+ strip.keyframe_insert('volume')
+ scn.frame_current += self.fade_duration
+ strip.volume = self.fade_amount
+ strip.keyframe_insert('volume')
+
+ else:
+ if(self.mode) == 'OUT':
+ scn.frame_current = strip.frame_final_end - self.fade_duration
+ strip.blend_alpha = self.fade_amount
+ strip.keyframe_insert('blend_alpha')
+ scn.frame_current = strip.frame_final_end
+ strip.blend_alpha = 0
+ strip.keyframe_insert('blend_alpha')
+ elif(self.mode) == 'INOUT':
+ scn.frame_current = strip.frame_final_start
+ strip.blend_alpha = 0
+ strip.keyframe_insert('blend_alpha')
+ scn.frame_current += self.fade_duration
+ strip.blend_alpha = self.fade_amount
+ strip.keyframe_insert('blend_alpha')
+ scn.frame_current = strip.frame_final_end - self.fade_duration
+ strip.blend_alpha = self.fade_amount
+ strip.keyframe_insert('blend_alpha')
+ scn.frame_current = strip.frame_final_end
+ strip.blend_alpha = 0
+ strip.keyframe_insert('blend_alpha')
+ else:
+ scn.frame_current = strip.frame_final_start
+ strip.blend_alpha = 0
+ strip.keyframe_insert('blend_alpha')
+ scn.frame_current += self.fade_duration
+ strip.blend_alpha = self.fade_amount
+ strip.keyframe_insert('blend_alpha')
+
+ scn.frame_current = tmp_current_frame
+
+ scn.default_fade_duration = self.fade_duration
+ scn.default_fade_amount = self.fade_amount
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ scn = context.scene
+ initSceneProperties(context, scn)
+ self.fade_duration = scn.default_fade_duration
+ self.fade_amount = scn.default_fade_amount
+ return context.window_manager.invoke_props_dialog(self)
+
+
+# EXTEND TO FILL
+class Sequencer_Extra_ExtendToFill(bpy.types.Operator):
+ bl_idname = 'sequencerextra.extendtofill'
+ bl_label = 'Extend to Fill'
+ bl_description = 'Extend active strip forward to fill adjacent space'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return True
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ strip = functions.act_strip(context)
+ chn = strip.channel
+ stf = strip.frame_final_end
+ enf = 300000
+
+ for i in seq.sequences:
+ ffs = i.frame_final_start
+ if (i.channel == chn and ffs > stf):
+ if ffs < enf:
+ enf = ffs
+ if enf == 300000 and stf < scn.frame_end:
+ enf = scn.frame_end
+
+ if enf == 300000 or enf == stf:
+ self.report({'ERROR_INVALID_INPUT'}, 'Unable to extend')
+ return {'CANCELLED'}
+ else:
+ strip.frame_final_end = enf
+
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+
+# DISTRIBUTE
+class Sequencer_Extra_Distribute(bpy.types.Operator):
+ bl_idname = 'sequencerextra.distribute'
+ bl_label = 'Distribute...'
+ bl_description = 'Evenly distribute selected strips'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return scn.sequence_editor.sequences
+ else:
+ return False
+
+ def execute(self, context):
+ scn = context.scene
+ seq = scn.sequence_editor
+ seq_all = scn.sequence_editor
+ meta_level = len(seq.meta_stack)
+ if meta_level > 0:
+ seq = seq.meta_stack[meta_level - 1]
+ seq_list = {}
+ first_start = 300000
+ item_num = 0
+ for i in seq.sequences:
+ if i.select == True:
+ seq_list[i.frame_start] = i.name
+ item_num += 1
+ if i.frame_start < first_start:
+ first_start = i.frame_start
+ n = item_num - 1
+ if(self.distribute_reverse):
+ for key in sorted(seq_list.keys()):
+ dest = first_start + (n * self.distribute_offset)
+ seq_all.sequences_all[str(seq_list[key])].frame_start = dest
+ n -= 1
+ else:
+ for key in sorted(seq_list.keys(), reverse=True):
+ dest = first_start + (n * self.distribute_offset)
+ seq_all.sequences_all[str(seq_list[key])].frame_start = dest
+ n -= 1
+
+ scn.default_distribute_offset = self.distribute_offset
+ scn.default_distribute_reverse = self.distribute_reverse
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ scn = context.scene
+ initSceneProperties(context, scn)
+ self.distribute_offset = scn.default_distribute_offset
+ self.distribute_reverse = scn.default_distribute_reverse
+ return context.window_manager.invoke_props_dialog(self)
+
+
+# SKIP ONE SECOND
+class Sequencer_Extra_FrameSkip(bpy.types.Operator):
+ bl_label = 'Skip One Second'
+ bl_idname = 'screenextra.frame_skip'
+ bl_description = 'Skip through the Timeline by one-second increments'
+ bl_options = {'REGISTER', 'UNDO'}
+ back = BoolProperty(
+ name='Back',
+ default=False)
+
+ def execute(self, context):
+ one_second = bpy.context.scene.render.fps
+ if self.back == True:
+ one_second *= -1
+ bpy.ops.screen.frame_offset(delta=one_second)
+ return {'FINISHED'}
+
+
+# JOG/SHUTTLE
+class Sequencer_Extra_JogShuttle(bpy.types.Operator):
+ bl_label = 'Jog/Shuttle'
+ bl_idname = 'sequencerextra.jogshuttle'
+ bl_description = 'Jog through current sequence'
+
+ def execute(self, context):
+ scn = context.scene
+ start_frame = scn.frame_start
+ end_frame = scn.frame_end
+ duration = end_frame - start_frame
+ diff = self.x - self.init_x
+ diff /= 5
+ diff = int(diff)
+ extended_frame = diff + (self.init_current_frame - start_frame)
+ looped_frame = extended_frame % (duration + 1)
+ target_frame = start_frame + looped_frame
+ context.scene.frame_current = target_frame
+
+ def modal(self, context, event):
+ if event.type == 'MOUSEMOVE':
+ self.x = event.mouse_x
+ self.execute(context)
+ elif event.type == 'LEFTMOUSE':
+ return {'FINISHED'}
+ elif event.type in ('RIGHTMOUSE', 'ESC'):
+ return {'CANCELLED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ scn = context.scene
+ self.x = event.mouse_x
+ self.init_x = self.x
+ self.init_current_frame = scn.frame_current
+ self.execute(context)
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+
+# OPEN IN MOVIE CLIP EDITOR FROM FILE BROWSER
+class Clip_Extra_OpenFromFileBrowser(bpy.types.Operator):
+ bl_label = 'Open from File Browser'
+ bl_idname = 'clipextra.openfromfilebrowser'
+ bl_description = 'Load a Movie or Image Sequence from File Browser'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ for a in context.window.screen.areas:
+ if a.type == 'FILE_BROWSER':
+ params = a.spaces[0].params
+ break
+ try:
+ params
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
+ return {'CANCELLED'}
+
+ if params.filename == '':
+ self.report({'ERROR_INVALID_INPUT'}, 'No file selected')
+ return {'CANCELLED'}
+
+ strip = functions.act_strip(context)
+ path = params.directory + params.filename
+ strip_type = functions.detect_strip_type(params.filename)
+ data_exists = False
+
+ if strip_type in ('MOVIE', 'IMAGE'):
+ for i in bpy.data.movieclips:
+ if i.filepath == path:
+ data_exists = True
+ data = i
+
+ if data_exists == False:
+ try:
+ data = bpy.data.movieclips.load(filepath=path)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+ else:
+ self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
+ return {'CANCELLED'}
+
+ for a in context.window.screen.areas:
+ if a.type == 'CLIP_EDITOR':
+ a.spaces[0].clip = data
+
+ return {'FINISHED'}
+
+
+# OPEN IN MOVIE CLIP EDITOR FROM SEQUENCER
+class Clip_Extra_OpenActiveStrip(bpy.types.Operator):
+ bl_label = 'Open Active Strip'
+ bl_idname = 'clipextra.openactivestrip'
+ bl_description = 'Load a Movie or Image Sequence from Sequence Editor'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ scn = context.scene
+ strip = functions.act_strip(context)
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return strip.type in ('MOVIE', 'IMAGE')
+ else:
+ return False
+
+ def execute(self, context):
+ strip = functions.act_strip(context)
+ data_exists = False
+
+ if strip.type == 'MOVIE':
+ path = strip.filepath
+ elif strip.type == 'IMAGE':
+ base_dir = bpy.path.relpath(strip.directory)
+ filename = strip.elements[0].filename
+ path = base_dir + '/' + filename
+ else:
+ self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
+ return {'CANCELLED'}
+
+ for i in bpy.data.movieclips:
+ if i.filepath == path:
+ data_exists = True
+ data = i
+ if data_exists == False:
+ try:
+ data = bpy.data.movieclips.load(filepath=path)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ for a in context.window.screen.areas:
+ if a.type == 'CLIP_EDITOR':
+ a.spaces[0].clip = data
+
+ return {'FINISHED'}
+
+
+# PLACE FROM FILE BROWSER WITH PROXY
+class Sequencer_Extra_PlaceFromFileBrowserProxy(bpy.types.Operator):
+ bl_label = 'Place'
+ bl_idname = 'sequencerextra.placefromfilebrowserproxy'
+ bl_description = 'Place or insert active file from File Browser, '\
+ 'and add proxy file with according suffix and extension'
+ insert = BoolProperty(name='Insert', default=False)
+ build_25 = BoolProperty(name='default_build_25',
+ description='default build_25',
+ default=True)
+ build_50 = BoolProperty(name='default_build_50',
+ description='default build_50',
+ default=True)
+ build_75 = BoolProperty(name='default_build_75',
+ description='default build_75',
+ default=True)
+ build_100 = BoolProperty(name='default_build_100',
+ description='default build_100',
+ default=True)
+ proxy_suffix = StringProperty(
+ name='default proxy suffix',
+ description='default proxy filename suffix',
+ default="-25")
+ proxy_extension = StringProperty(
+ name='default proxy extension',
+ description='default proxy extension',
+ default=".mkv")
+ proxy_path = StringProperty(
+ name='default proxy path',
+ description='default proxy path',
+ default="")
+
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def invoke(self, context, event):
+ scn = context.scene
+ initSceneProperties(context, scn)
+ self.build_25 = scn.default_build_25
+ self.build_50 = scn.default_build_50
+ self.build_75 = scn.default_build_75
+ self.build_100 = scn.default_build_100
+ self.proxy_suffix = scn.default_proxy_suffix
+ self.proxy_extension = scn.default_proxy_extension
+ self.proxy_path = scn.default_proxy_path
+
+ return context.window_manager.invoke_props_dialog(self)
+
+ def execute(self, context):
+ scn = context.scene
+ for a in context.window.screen.areas:
+ if a.type == 'FILE_BROWSER':
+ params = a.spaces[0].params
+ break
+ try:
+ params
+ except UnboundLocalError:
+ self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
+ return {'CANCELLED'}
+
+ if params.filename == '':
+ self.report({'ERROR_INVALID_INPUT'}, 'No file selected (proxy)')
+ return {'CANCELLED'}
+ path = os.path.join(params.directory, params.filename)
+ frame = context.scene.frame_current
+ strip_type = functions.detect_strip_type(params.filename)
+
+ try:
+ if strip_type == 'IMAGE':
+ image_file = []
+ filename = {"name": params.filename}
+ image_file.append(filename)
+ f_in = scn.frame_current
+ f_out = f_in + scn.render.fps - 1
+ bpy.ops.sequencer.image_strip_add(files=image_file,
+ directory=params.directory, frame_start=f_in,
+ frame_end=f_out, relative_path=False)
+ elif strip_type == 'MOVIE':
+ bpy.ops.sequencer.movie_strip_add(filepath=path,
+ frame_start=frame, relative_path=False)
+
+ strip = functions.act_strip(context)
+ strip.use_proxy = True
+
+ # check if proxy exists, otherwise, uncheck proxy custom file
+ proxy_filepath = params.directory + self.proxy_path
+ proxy_filename = params.filename.rpartition(".")[0] + \
+ self.proxy_suffix + self.proxy_extension
+ proxypath = os.path.join(proxy_filepath, proxy_filename)
+ strip.proxy.build_25 = self.build_25
+ strip.proxy.build_50 = self.build_50
+ strip.proxy.build_75 = self.build_75
+ strip.proxy.build_100 = self.build_100
+ #print("----------------", proxypath)
+ if os.path.isfile(proxypath):
+ strip.use_proxy_custom_file = True
+ strip.proxy.filepath = proxypath
+
+ elif strip_type == 'SOUND':
+ bpy.ops.sequencer.sound_strip_add(filepath=path,
+ frame_start=frame, relative_path=False)
+ else:
+ self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
+ return {'CANCELLED'}
+
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file (proxy)')
+ return {'CANCELLED'}
+
+ scn.default_proxy_suffix = self.proxy_suffix
+ scn.default_proxy_extension = self.proxy_extension
+ scn.default_proxy_path = self.proxy_path
+ scn.default_build_25 = self.build_25
+ scn.default_build_50 = self.build_50
+ scn.default_build_75 = self.build_75
+ scn.default_build_100 = self.build_100
+
+ if self.insert == True:
+ try:
+ bpy.ops.sequencerextra.insert()
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Execution Error, '\
+ 'check your Blender version')
+ return {'CANCELLED'}
+ else:
+ strip = functions.act_strip(context)
+ scn.frame_current += strip.frame_final_duration
+ bpy.ops.sequencer.reload()
+
+ return {'FINISHED'}
+
+
+# OPEN IMAGE WITH EDITOR AND create movie clip strip
+class Sequencer_Extra_CreateMovieclip(bpy.types.Operator):
+ bl_label = 'Create a Movieclip from selected strip'
+ bl_idname = 'sequencerextra.createmovieclip'
+ bl_description = 'Create a Movieclip strip from a MOVIE or IMAGE strip'
+
+ """
+ When a movie or image strip is selected, this operator creates a movieclip
+ or find the correspondent movieclip that already exists for this footage,
+ and add a VSE clip strip with same cuts the original strip has.
+ It can convert movie strips and image sequences, both with hard cuts or
+ soft cuts.
+ """
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return strip.type in ('MOVIE', 'IMAGE')
+ else:
+ return False
+
+ def execute(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+
+ if strip.type == 'MOVIE':
+ #print("movie", strip.frame_start)
+ path = strip.filepath
+ #print(path)
+ data_exists = False
+ for i in bpy.data.movieclips:
+ if i.filepath == path:
+ data_exists = True
+ data = i
+ newstrip = None
+ if data_exists == False:
+ try:
+ data = bpy.data.movieclips.load(filepath=path)
+ newstrip = bpy.ops.sequencer.movieclip_strip_add(\
+ replace_sel=True, overlap=False, clip=data.name)
+ newstrip = functions.act_strip(context)
+ newstrip.frame_start = strip.frame_start\
+ - strip.animation_offset_start
+ tin = strip.frame_offset_start + strip.frame_start
+ tout = tin + strip.frame_final_duration
+ #print(newstrip.frame_start, strip.frame_start, tin, tout)
+ functions.triminout(newstrip, tin, tout)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ else:
+ try:
+ newstrip = bpy.ops.sequencer.movieclip_strip_add(\
+ replace_sel=True, overlap=False, clip=data.name)
+ newstrip = functions.act_strip(context)
+ newstrip.frame_start = strip.frame_start\
+ - strip.animation_offset_start
+ # i need to declare the strip this way in order
+ # to get triminout() working
+ clip = bpy.context.scene.sequence_editor.sequences[\
+ newstrip.name]
+ # i cannot change these movie clip attributes via scripts
+ # but it works in the python console...
+ #clip.animation_offset_start = strip.animation.offset_start
+ #clip.animation_offset_end = strip.animation.offset_end
+ #clip.frame_final_duration = strip.frame_final_duration
+ tin = strip.frame_offset_start + strip.frame_start
+ tout = tin + strip.frame_final_duration
+ #print(newstrip.frame_start, strip.frame_start, tin, tout)
+ functions.triminout(clip, tin, tout)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ elif strip.type == 'IMAGE':
+ #print("image")
+ base_dir = bpy.path.abspath(strip.directory)
+ scn.frame_current = strip.frame_start -\
+ strip.animation_offset_start
+ # searching for the first frame of the sequencer. This is mandatory
+ # for hard cutted sequence strips to be correctly converted,
+ # avoiding to create a new movie clip if not needed
+ filename = sorted(os.listdir(base_dir))[0]
+ path = os.path.join(base_dir, filename)
+ #print(path)
+ data_exists = False
+ for i in bpy.data.movieclips:
+ #print(i.filepath, path)
+ if i.filepath == path:
+ data_exists = True
+ data = i
+ #print(data_exists)
+ if data_exists == False:
+ try:
+ data = bpy.data.movieclips.load(filepath=path)
+ newstrip = bpy.ops.sequencer.movieclip_strip_add(\
+ replace_sel=True, overlap=False,\
+ clip=data.name)
+ newstrip = functions.act_strip(context)
+ newstrip.frame_start = strip.frame_start\
+ - strip.animation_offset_start
+ clip = bpy.context.scene.sequence_editor.sequences[\
+ newstrip.name]
+ tin = strip.frame_offset_start + strip.frame_start
+ tout = tin + strip.frame_final_duration
+ #print(newstrip.frame_start, strip.frame_start, tin, tout)
+ functions.triminout(clip, tin, tout)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ else:
+ try:
+ newstrip = bpy.ops.sequencer.movieclip_strip_add(\
+ replace_sel=True, overlap=False, clip=data.name)
+ newstrip = functions.act_strip(context)
+ newstrip.frame_start = strip.frame_start\
+ - strip.animation_offset_start
+ # need to declare the strip this way in order
+ # to get triminout() working
+ clip = bpy.context.scene.sequence_editor.sequences[\
+ newstrip.name]
+ # cannot change this atributes via scripts...
+ # but it works in the python console...
+ #clip.animation_offset_start = strip.animation.offset_start
+ #clip.animation_offset_end = strip.animation.offset_end
+ #clip.frame_final_duration = strip.frame_final_duration
+ tin = strip.frame_offset_start + strip.frame_start
+ tout = tin + strip.frame_final_duration
+ #print(newstrip.frame_start, strip.frame_start, tin, tout)
+ functions.triminout(clip, tin, tout)
+ except:
+ self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
+ return {'CANCELLED'}
+
+ # show the new clip in a movie clip editor, if available.
+ if strip.type == 'MOVIE' or 'IMAGE':
+ for a in context.window.screen.areas:
+ if a.type == 'CLIP_EDITOR':
+ a.spaces[0].clip = data
+
+ return {'FINISHED'}
+
+
+# RECURSIVE LOADER
+
+class Sequencer_Extra_RecursiveLoader(bpy.types.Operator):
+ bl_idname = "sequencerextra.recursiveload"
+ bl_label = "recursive load"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ default_recursive = BoolProperty(
+ name='recursive',
+ description='Load in recursive folders',
+ default=False)
+
+ default_recursive_ext = BoolProperty(
+ name='select by extension',
+ description='Load by extension',
+ default=False)
+
+ default_ext = EnumProperty(
+ items=functions.movieextdict,
+ name="extension",
+ default="3")
+
+ default_recursive_proxies = BoolProperty(
+ name='use proxies',
+ description='Load in recursive folders',
+ default=False)
+ build_25 = BoolProperty(name='default_build_25',
+ description='default build_25',
+ default=True)
+ build_50 = BoolProperty(name='default_build_50',
+ description='default build_50',
+ default=True)
+ build_75 = BoolProperty(name='default_build_75',
+ description='default build_75',
+ default=True)
+ build_100 = BoolProperty(name='default_build_100',
+ description='default build_100',
+ default=True)
+ proxy_suffix = StringProperty(
+ name='default proxy suffix',
+ description='default proxy filename suffix',
+ default="-25")
+ proxy_extension = StringProperty(
+ name='default proxy extension',
+ description='default proxy extension',
+ default=".mkv")
+ proxy_path = StringProperty(
+ name='default proxy path',
+ description='default proxy path',
+ default="")
+
+
+
+ @classmethod
+ def poll(self, context):
+ scn = context.scene
+ if scn and scn.sequence_editor:
+ return (scn.sequence_editor)
+ else:
+ return False
+
+ def invoke(self, context, event):
+ scn = context.scene
+ initSceneProperties(context, scn)
+ self.build_25 = scn.default_build_25
+ self.build_50 = scn.default_build_50
+ self.build_75 = scn.default_build_75
+ self.build_100 = scn.default_build_100
+ self.proxy_suffix = scn.default_proxy_suffix
+ self.proxy_extension = scn.default_proxy_extension
+ self.proxy_path = scn.default_proxy_path
+ self.recursive = scn.default_recursive
+ self.recursive_ext = scn.default_recursive_ext
+ self.recursive_proxies = scn.default_recursive_proxies
+ self.ext = scn.default_ext
+
+ return context.window_manager.invoke_props_dialog(self)
+
+ def loader(self, context, filelist):
+ scn = context.scene
+ if filelist:
+ for i in filelist:
+ functions.setpathinbrowser(i[0], i[1])
+ try:
+ if self.default_recursive_proxies:
+ bpy.ops.sequencerextra.placefromfilebrowserproxy(
+ proxy_suffix=self.proxy_suffix,
+ proxy_extension=self.proxy_extension,
+ proxy_path=self.proxy_path,
+ build_25=self.build_25,
+ build_50=self.build_50,
+ build_75=self.build_75,
+ build_100=self.build_100)
+ else:
+ bpy.ops.sequencerextra.placefromfilebrowser()
+ except:
+ print("Error loading file (recursive loader error): ", i[1])
+ functions.add_marker(context, i[1])
+ #self.report({'ERROR_INVALID_INPUT'}, 'Error loading file ')
+ pass
+
+
+ def execute(self, context):
+ scn = context.scene
+ initSceneProperties(context, scn)
+ if scn["default_recursive"] == True:
+ self.loader(context, functions.sortlist(\
+ functions.recursive(context, self.default_recursive_ext)))
+ else:
+ self.loader(context, functions.sortlist(functions.onefolder(\
+ context, self.default_recursive_ext)))
+ return {'FINISHED'}
+
+
+# READ EXIF DATA
+class Sequencer_Extra_ReadExifData(bpy.types.Operator):
+ # load exifdata from strip to scene['metadata'] property
+ bl_label = 'Read EXIF Data'
+ bl_idname = 'sequencerextra.read_exif'
+ bl_description = 'Load exifdata from strip to metadata property in scene'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ strip = functions.act_strip(context)
+ scn = context.scene
+ if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
+ return (strip.type == 'IMAGE' or 'MOVIE')
+ else:
+ return False
+
+ def execute(self, context):
+ try:
+ exiftool.ExifTool().start()
+ except:
+ self.report({'ERROR_INVALID_INPUT'},
+ 'exiftool not found in PATH')
+ return {'CANCELLED'}
+
+ def getexifdata(strip):
+ def getlist(lista):
+ for root, dirs, files in os.walk(path):
+ for f in files:
+ if "." + f.rpartition(".")[2].lower() \
+ in functions.imb_ext_image:
+ lista.append(f)
+ #if "."+f.rpartition(".")[2] in imb_ext_movie:
+ # lista.append(f)
+ strip.elements
+ lista.sort()
+ return lista
+
+ def getexifvalues(lista):
+ metadata = []
+ with exiftool.ExifTool() as et:
+ try:
+ metadata = et.get_metadata_batch(lista)
+ except UnicodeDecodeError as Err:
+ print(Err)
+ return metadata
+ if strip.type == "IMAGE":
+ path = bpy.path.abspath(strip.directory)
+ if strip.type == "MOVIE":
+ path = bpy.path.abspath(strip.filepath.rpartition("/")[0])
+ os.chdir(path)
+ #get a list of files
+ lista = []
+ for i in strip.elements:
+ lista.append(i.filename)
+ return getexifvalues(lista)
+
+ sce = bpy.context.scene
+ frame = sce.frame_current
+ text = bpy.context.active_object
+ strip = context.scene.sequence_editor.active_strip
+ sce['metadata'] = getexifdata(strip)
+ return {'FINISHED'}
diff --git a/release/scripts/addons_contrib/sequencer_extra_actions/ui.py b/release/scripts/addons_contrib/sequencer_extra_actions/ui.py
new file mode 100644
index 0000000..15d9fa1
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_extra_actions/ui.py
@@ -0,0 +1,189 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+
+
+# UI
+class SEQUENCER_EXTRA_MT_input(bpy.types.Menu):
+ bl_label = "Input"
+
+ def draw(self, context):
+ self.layout.operator_context = 'INVOKE_REGION_WIN'
+ self.layout.operator('sequencerextra.striprename',
+ text='File Name to Strip Name', icon='PLUGIN')
+ self.layout.operator('sequencerextra.editexternally',
+ text='Open with External Editor', icon='PLUGIN')
+ self.layout.operator('sequencerextra.edit',
+ text='Open with Editor', icon='PLUGIN')
+ self.layout.operator('sequencerextra.createmovieclip',
+ text='Create Movieclip strip', icon='PLUGIN')
+
+
+def sequencer_add_menu_func(self, context):
+ self.layout.operator('sequencerextra.recursiveload',
+ text='recursive load from browser', icon='PLUGIN')
+ self.layout.separator()
+
+
+def sequencer_select_menu_func(self, context):
+ self.layout.operator_menu_enum('sequencerextra.select_all_by_type',
+ 'type', text='All by Type', icon='PLUGIN')
+ self.layout.separator()
+ self.layout.operator('sequencerextra.selectcurrentframe',
+ text='Before Current Frame', icon='PLUGIN').mode = 'BEFORE'
+ self.layout.operator('sequencerextra.selectcurrentframe',
+ text='After Current Frame', icon='PLUGIN').mode = 'AFTER'
+ self.layout.operator('sequencerextra.selectcurrentframe',
+ text='On Current Frame', icon='PLUGIN').mode = 'ON'
+ self.layout.separator()
+ self.layout.operator('sequencerextra.selectsamechannel',
+ text='Same Channel', icon='PLUGIN')
+
+
+def sequencer_strip_menu_func(self, context):
+ self.layout.operator('sequencerextra.extendtofill',
+ text='Extend to Fill', icon='PLUGIN')
+ self.layout.operator('sequencerextra.distribute',
+ text='Distribute', icon='PLUGIN')
+ self.layout.operator_menu_enum('sequencerextra.fadeinout',
+ 'mode', text='Fade', icon='PLUGIN')
+ self.layout.operator_menu_enum('sequencerextra.copyproperties',
+ 'prop', icon='PLUGIN')
+ self.layout.operator('sequencerextra.slidegrab',
+ text='Slide Grab', icon='PLUGIN')
+ self.layout.operator_menu_enum('sequencerextra.slide',
+ 'mode', icon='PLUGIN')
+ self.layout.operator('sequencerextra.insert',
+ text='Insert (Single Channel)', icon='PLUGIN').singlechannel = True
+ self.layout.operator('sequencerextra.insert',
+ text='Insert', icon='PLUGIN').singlechannel = False
+ self.layout.operator('sequencerextra.ripplecut',
+ text='Ripple Cut', icon='PLUGIN')
+ self.layout.operator('sequencerextra.rippledelete',
+ text='Ripple Delete', icon='PLUGIN')
+ self.layout.separator()
+
+
+def sequencer_header_func(self, context):
+ self.layout.menu("SEQUENCER_EXTRA_MT_input")
+ if context.space_data.view_type in ('PREVIEW', 'SEQUENCER_PREVIEW'):
+ self.layout.operator('sequencerextra.jogshuttle',
+ text='Jog/Shuttle', icon='NDOF_TURN')
+ if context.space_data.view_type in ('SEQUENCER', 'SEQUENCER_PREVIEW'):
+ self.layout.operator('sequencerextra.navigateup',
+ text='Navigate Up', icon='FILE_PARENT')
+ if context.space_data.view_type in ('SEQUENCER', 'SEQUENCER_PREVIEW'):
+ self.layout.operator('sequencerextra.placefromfilebrowser',
+ text='File Place', icon='TRIA_DOWN').insert = False
+ if context.space_data.view_type in ('SEQUENCER', 'SEQUENCER_PREVIEW'):
+ self.layout.operator('sequencerextra.placefromfilebrowser',
+ text='File Insert', icon='TRIA_RIGHT').insert = True
+ if context.space_data.view_type in ('SEQUENCER', 'SEQUENCER_PREVIEW'):
+ self.layout.operator('sequencerextra.placefromfilebrowserproxy',
+ text='Proxy Place', icon='TRIA_DOWN')
+ if context.space_data.view_type in ('SEQUENCER', 'SEQUENCER_PREVIEW'):
+ self.layout.operator('sequencerextra.placefromfilebrowserproxy',
+ text='Proxy Insert', icon='TRIA_RIGHT').insert = True
+
+
+def time_frame_menu_func(self, context):
+ self.layout.operator('timeextra.trimtimelinetoselection',
+ text='Trim to Selection', icon='PLUGIN')
+ self.layout.operator('timeextra.trimtimeline',
+ text='Trim to Timeline Content', icon='PLUGIN')
+ self.layout.separator()
+ self.layout.operator('screenextra.frame_skip',
+ text='Skip Forward One Second', icon='PLUGIN').back = False
+ self.layout.operator('screenextra.frame_skip',
+ text='Skip Back One Second', icon='PLUGIN').back = True
+ self.layout.separator()
+
+
+def time_header_func(self, context):
+ self.layout.operator('sequencerextra.jogshuttle',
+ text='Jog/Shuttle', icon='NDOF_TURN')
+
+
+def clip_header_func(self, context):
+ self.layout.operator('sequencerextra.jogshuttle',
+ text='Jog/Shuttle', icon='NDOF_TURN')
+
+
+def clip_clip_menu_func(self, context):
+ self.layout.operator('clipextra.openactivestrip',
+ text='Open Active Strip', icon='PLUGIN')
+ self.layout.operator('clipextra.openfromfilebrowser',
+ text='Open from File Browser', icon='PLUGIN')
+ self.layout.separator()
+
+
+class ExifInfoPanel(bpy.types.Panel):
+ """Creates a Panel in the Object properties window"""
+ bl_label = "EXIF Info Panel"
+ bl_space_type = 'SEQUENCE_EDITOR'
+ bl_region_type = 'UI'
+
+ @staticmethod
+ def has_sequencer(context):
+ return (context.space_data.view_type\
+ in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
+
+ @classmethod
+ def poll(cls, context):
+ return cls.has_sequencer(context)
+
+ def draw_header(self, context):
+ layout = self.layout
+ layout.label(text="", icon="NLA")
+
+ def draw(self, context):
+ layout = self.layout
+ sce = context.scene
+ row = layout.row()
+ row.operator("sequencerextra.read_exif")
+ row = layout.row()
+ row.label(text="Exif Data", icon='RENDER_REGION')
+ row = layout.row()
+
+ try:
+ strip = context.scene.sequence_editor.active_strip
+
+ f = strip.frame_start
+ frame = sce.frame_current
+ try:
+ if len(sce['metadata']) == 1:
+ for d in sce['metadata'][0]:
+ split = layout.split(percentage=0.5)
+ col = split.column()
+ row = col.row()
+ col.label(text=d)
+ col = split.column()
+ col.label(str(sce['metadata'][0][d]))
+ else:
+ for d in sce['metadata'][frame - f]:
+ split = layout.split(percentage=0.5)
+ col = split.column()
+ row = col.row()
+ col.label(text=d)
+ col = split.column()
+ col.label(str(sce['metadata'][frame - f][d]))
+ except KeyError:
+ pass
+ except AttributeError:
+ pass
diff --git a/release/scripts/addons_contrib/sequencer_jumptocut.py b/release/scripts/addons_contrib/sequencer_jumptocut.py
new file mode 100644
index 0000000..1e78935
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_jumptocut.py
@@ -0,0 +1,439 @@
+# ##### 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 LICENSE BLOCK #####
+
+
+bl_info = {
+ "name": "Jump to Cut",
+ "author": "Carlos Padial",
+ "version": (5, 0, 2),
+ "blender": (2, 63, 0),
+ "api": 44539,
+ "category": "Sequencer",
+ "location": "Sequencer > UI > Jump to Cut",
+ "description": "Tool collection to help speed up editting and grade videos with blender",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Sequencer/Jump_to_cut",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=24279",}
+
+#
+#
+#
+#-----------------------------------------------------------------------------------------------------
+import bpy
+
+class Jumptocut(bpy.types.Panel):
+ bl_space_type = "SEQUENCE_EDITOR"
+ bl_region_type = "UI"
+ bl_label = "Jump to Cut"
+
+ def draw_header(self, context):
+ layout = self.layout
+ layout.label(text="", icon="NLA")
+
+ def draw(self, context):
+ layout = self.layout
+
+ row=layout.row()
+ split=row.split(percentage=0.5)
+ colL = split.column()
+ colR = split.column()
+ colL.operator("sequencer.jumpprev", icon="PLAY_REVERSE")
+ colR.operator("sequencer.jumpnext", icon='PLAY')
+
+ row=layout.row()
+ split=row.split()
+ colL = split.column()
+ colR = split.column()
+ colL.operator("sequencer.markprev", icon="MARKER_HLT")
+ colR.operator("sequencer.marknext", icon='MARKER_HLT')
+
+ row=layout.row()
+ split=row.split()
+ colL1 = split.column()
+ colL2 = split.column()
+ colL1.operator("sequencer.sourcein", icon="REW")
+ colL2.operator("sequencer.sourceout", icon='FF')
+
+
+ row=layout.row()
+ split=row.split()
+ colR1 = split.column()
+ colR1.operator("sequencer.setinout", icon="ARROW_LEFTRIGHT")
+ row=layout.row()
+ split=row.split(percentage=0.5)
+ colR1 = split.column()
+ colR1.operator("sequencer.triminout", icon="FULLSCREEN_EXIT")
+ colR2 = split.column()
+ colR2.operator("sequencer.setstartend", icon="SETTINGS")
+
+ row=layout.row()
+ split=row.split()
+ colR1 = split.column()
+ colR2 = split.column()
+ colR1.operator("sequencer.metacopy", icon="COPYDOWN")
+ colR2.operator("sequencer.metapaste", icon='PASTEDOWN')
+
+#-----------------------------------------------------------------------------------------------------
+
+class OBJECT_OT_Setinout(bpy.types.Operator):
+ bl_label = "Mark in & out to active strip"
+ bl_idname = "sequencer.setinout"
+ bl_description = "set IN and OUT markers to the active strip limits"
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ markers=scene.timeline_markers
+ seq=scene.sequence_editor
+ if seq:
+ strip= seq.active_strip
+ if strip != None:
+ sin = strip.frame_start + strip.frame_offset_start
+ sout = sin + strip.frame_final_duration
+ if "IN" not in markers:
+ mark=markers.new(name="IN")
+ mark.frame=sin
+ else:
+ mark=markers["IN"]
+ mark.frame=sin
+ if "OUT" not in markers:
+ mark= markers.new(name="OUT")
+ mark.frame=sout
+ else:
+ mark=markers["OUT"]
+ mark.frame=sout
+ return {'FINISHED'}
+
+
+def triminout(strip,sin,sout):
+ start = strip.frame_start+strip.frame_offset_start
+ end = start+strip.frame_final_duration
+ if end > sin:
+ if start < sin:
+ strip.select_right_handle = False
+ strip.select_left_handle = True
+ bpy.ops.sequencer.snap(frame=sin)
+ strip.select_left_handle = False
+ if start < sout:
+ if end > sout:
+ strip.select_left_handle = False
+ strip.select_right_handle = True
+ bpy.ops.sequencer.snap(frame=sout)
+ strip.select_right_handle = False
+ return {'FINISHED'}
+
+
+class OBJECT_OT_Triminout(bpy.types.Operator):
+ bl_label = "Trim to in & out"
+ bl_idname = "sequencer.triminout"
+ bl_description = "trim the selected strip to IN and OUT markers (if exists)"
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ markers=scene.timeline_markers
+ seq=scene.sequence_editor
+ if seq:
+ strip= seq.active_strip
+ if strip != None:
+ if "IN" and "OUT" in markers:
+ sin=markers["IN"].frame
+ sout=markers["OUT"].frame
+ triminout(strip,sin,sout)
+ else:
+ self.report({'WARNING'}, "there is no IN and OUT")
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+def searchprev(j, list):
+ list.sort()
+ list.reverse()
+ for i in list:
+ if i < j:
+ result = i
+ break
+ else: result = j
+ return result
+
+def searchnext(j, list):
+ list.sort()
+ for i in list:
+ if i > j:
+ result = i
+ break
+ else: result = j
+ return result
+
+def geteditpoints(seq):
+ #this create a list of editpoints including strips from
+ # inside metastrips. It reads only 1 level into the metastrip
+ editpoints = []
+ cliplist = []
+ metalist = []
+ if seq:
+ for i in seq.sequences:
+ if i.type == 'META':
+ metalist.append(i)
+ start = i.frame_start + i.frame_offset_start
+ end = start + i.frame_final_duration
+ editpoints.append(start)
+ editpoints.append(end)
+ else:
+ cliplist.append(i)
+ for i in metalist:
+ for j in i.sequences:
+ cliplist.append(j)
+ for i in cliplist:
+ start = i.frame_start + i.frame_offset_start
+ end = start + i.frame_final_duration
+ editpoints.append(start)
+ editpoints.append(end)
+ #print(start," ",end)
+ return editpoints
+
+#JUMP
+class OBJECT_OT_Jumpprev(bpy.types.Operator): #Operator jump previous edit point
+ bl_label = "Cut previous"
+ bl_idname = "sequencer.jumpprev"
+ bl_description = "jump to previous edit point"
+
+ editpoints = []
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ seq=scene.sequence_editor
+ editpoints = geteditpoints(seq)
+ bpy.context.scene.frame_current = searchprev(scene.frame_current, editpoints)
+ return {'FINISHED'}
+
+class OBJECT_OT_Jumpnext(bpy.types.Operator): #Operator jump next edit point
+ bl_label = "Cut next"
+ bl_idname = "sequencer.jumpnext"
+ bl_description = "jump to next edit point"
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ seq=scene.sequence_editor
+ editpoints = geteditpoints(seq)
+ bpy.context.scene.frame_current = searchnext(scene.frame_current, editpoints)
+ last = 0
+ for i in editpoints:
+ if i > last: last = i
+ if bpy.context.scene.frame_current == last:
+ bpy.context.scene.frame_current = last-1
+ self.report({'INFO'},'Last Frame')
+ return {'FINISHED'}
+
+# MARKER
+class OBJECT_OT_Markerprev(bpy.types.Operator):
+ bl_label = "Marker previous"
+ bl_idname = "sequencer.markprev"
+ bl_description = "jump to previous marker"
+
+ def invoke(self, context, event):
+ markerlist = []
+ scene= bpy.context.scene
+ markers = scene.timeline_markers
+ for i in markers: markerlist.append(i.frame)
+ bpy.context.scene.frame_current = searchprev(scene.frame_current, markerlist)
+ return {'FINISHED'}
+
+class OBJECT_OT_Markernext(bpy.types.Operator):
+ bl_label = "Marker next"
+ bl_idname = "sequencer.marknext"
+ bl_description = "jump to next marker"
+
+ def invoke(self, context, event):
+ markerlist = []
+ scene= bpy.context.scene
+ markers = scene.timeline_markers
+ for i in markers: markerlist.append(i.frame)
+ bpy.context.scene.frame_current = searchnext(scene.frame_current, markerlist)
+ return {'FINISHED'}
+
+# SOURCE IN OUT
+
+class OBJECT_OT_Sourcein(bpy.types.Operator): #Operator source in
+ bl_label = "Source IN"
+ bl_idname = "sequencer.sourcein"
+ bl_description = "add a marker named IN"
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ seq = scene.sequence_editor
+ markers=scene.timeline_markers
+ if "OUT" in markers:
+ sout=markers["OUT"]
+ if scene.frame_current <= sout.frame:
+ if "IN" not in markers:
+ sin=markers.new(name="IN")
+ sin.frame=scene.frame_current
+ else:
+ sin=markers["IN"]
+ sin.frame=scene.frame_current
+ #trying to set in after out
+ else:
+ if "IN" not in markers:
+ sin=markers.new(name="IN")
+ sin.frame=sout.frame
+ else:
+ sin=markers["IN"]
+ sin.frame=sout.frame
+ self.report({'WARNING'},'IN after OUT')
+ else:
+ if "IN" not in markers:
+ sin=markers.new(name="IN")
+ sin.frame=scene.frame_current
+ else:
+ sin=markers["IN"]
+ sin.frame=scene.frame_current
+ if seq:
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+class OBJECT_OT_Sourceout(bpy.types.Operator): #Operator source out
+ bl_label = "Source OUT"
+ bl_idname = "sequencer.sourceout"
+ bl_description = "add a marker named OUT"
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ seq = scene.sequence_editor
+ markers=scene.timeline_markers
+ if "IN" in markers:
+ sin=markers["IN"]
+ if scene.frame_current >= sin.frame:
+ if "OUT" not in markers:
+ sout= markers.new(name="OUT")
+ sout.frame=scene.frame_current
+ else:
+ sout=markers["OUT"]
+ sout.frame=scene.frame_current
+ #trying to set out before in
+ else:
+ if "OUT" not in markers:
+ sout= markers.new(name="OUT")
+ sout.frame = sin.frame
+ else:
+ sout=markers["OUT"]
+ sout.frame = sin.frame
+ self.report({'WARNING'}, "OUT before IN")
+ else:
+ sout= markers.new(name="OUT")
+ sout.frame=scene.frame_current
+ if seq:
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+
+
+class OBJECT_OT_Setstartend(bpy.types.Operator): #Operator set start & end
+ bl_label = "set Start & End"
+ bl_idname = "sequencer.setstartend"
+ bl_description = "set Start = In and End = Out"
+
+ def invoke(self, context, event):
+ scene=bpy.context.scene
+ seq = scene.sequence_editor
+ markers=scene.timeline_markers
+ if seq:
+ if "IN" and "OUT" in markers:
+ sin=markers["IN"]
+ sout=markers["OUT"]
+ scene.frame_start = sin.frame
+ scene.frame_end = sout.frame
+ print("change")
+ else:
+ self.report({'WARNING'}, "there is no IN and OUT")
+ bpy.ops.sequencer.reload()
+ return {'FINISHED'}
+
+
+# COPY PASTE
+
+class OBJECT_OT_Metacopy(bpy.types.Operator): #Operator copy source in/out
+ bl_label = "Trim & Meta-Copy"
+ bl_idname = "sequencer.metacopy"
+ bl_description = "make meta from selected strips, trim it to in/out (if available) and copy it to clipboard"
+
+ def invoke(self, context, event):
+ # rehacer
+ scene=bpy.context.scene
+ seq = scene.sequence_editor
+ markers=scene.timeline_markers
+ strip1= seq.active_strip
+ if strip1 != None:
+ if "IN" and "OUT" in markers:
+ sin=markers["IN"].frame
+ sout=markers["OUT"].frame
+ bpy.ops.sequencer.meta_make()
+ strip2= seq.active_strip
+ triminout(strip2,sin,sout)
+ bpy.ops.sequencer.copy()
+ bpy.ops.sequencer.meta_separate()
+ self.report({'INFO'}, "META has been trimed and copied")
+ else:
+ bpy.ops.sequencer.meta_make()
+ bpy.ops.sequencer.copy()
+ bpy.ops.sequencer.meta_separate()
+ self.report({'WARNING'}, "No In & Out!! META has been copied")
+ else:
+ self.report({'ERROR'}, "No strip selected")
+ return {'FINISHED'}
+
+class OBJECT_OT_Metapaste(bpy.types.Operator): #Operator paste source in/out
+ bl_label = "Paste in current Frame"
+ bl_idname = "sequencer.metapaste"
+ bl_description = "paste source from clipboard to current frame"
+
+ def invoke(self, context, event):
+ # rehacer
+ scene=bpy.context.scene
+ bpy.ops.sequencer.paste()
+ bpy.ops.sequencer.snap(frame=scene.frame_current)
+ return {'FINISHED'}
+
+# Registering / Unregister
+
+def register():
+ bpy.utils.register_class(Jumptocut)
+ bpy.utils.register_class(OBJECT_OT_Jumpprev)
+ bpy.utils.register_class(OBJECT_OT_Jumpnext)
+ bpy.utils.register_class(OBJECT_OT_Markerprev)
+ bpy.utils.register_class(OBJECT_OT_Markernext)
+ bpy.utils.register_class(OBJECT_OT_Sourcein)
+ bpy.utils.register_class(OBJECT_OT_Sourceout)
+ bpy.utils.register_class(OBJECT_OT_Metacopy)
+ bpy.utils.register_class(OBJECT_OT_Metapaste)
+ bpy.utils.register_class(OBJECT_OT_Triminout)
+ bpy.utils.register_class(OBJECT_OT_Setinout)
+ bpy.utils.register_class(OBJECT_OT_Setstartend)
+
+def unregister():
+ bpy.utils.unregister_class(Jumptocut)
+ bpy.utils.unregister_class(OBJECT_OT_Jumpprev)
+ bpy.utils.unregister_class(OBJECT_OT_Jumpnext)
+ bpy.utils.unregister_class(OBJECT_OT_Markerprev)
+ bpy.utils.unregister_class(OBJECT_OT_Markernext)
+ bpy.utils.unregister_class(OBJECT_OT_Sourcein)
+ bpy.utils.unregister_class(OBJECT_OT_Sourceout)
+ bpy.utils.unregister_class(OBJECT_OT_Metacopy)
+ bpy.utils.unregister_class(OBJECT_OT_Metapaste)
+ bpy.utils.unregister_class(OBJECT_OT_Triminout)
+ bpy.utils.unregister_class(OBJECT_OT_Setinout)
+ bpy.utils.unregister_class(OBJECT_OT_Setstartend)
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/sequencer_tools/__init__.py b/release/scripts/addons_contrib/sequencer_tools/__init__.py
new file mode 100644
index 0000000..ef43f0a
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_tools/__init__.py
@@ -0,0 +1,120 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Sequencer Tools",
+ "author": "mont29",
+ "version": (0, 0, 1),
+ "blender": (2, 63, 0),
+ "location": "Sequencer menus/UI",
+ "description": "Various Sequencer tools.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Sequencer/Tools",
+ "tracker_url": "projects.blender.org/tracker/index.php?func=detail&aid=31549",
+ "support": 'TESTING',
+ "category": "Sequencer"
+}
+
+
+import bpy
+
+from sequencer_tools.export_strips import SEQExportStrip
+
+
+KEYMAPS = (
+ # First, keymap identifiers (last bool is True for modal km).
+ (("Sequencer", "WINDOW", "SEQUENCE_EDITOR", False), (
+ # Then a tuple of keymap items, defined by a dict of kwargs for
+ # the km new func, and a tuple of tuples (name, val) for ops properties,
+ # if needing non-default values.
+ ({"idname": SEQExportStrip.bl_idname, "type": "P", "value": "PRESS",
+ "shift": True, "ctrl": True},
+ ()),
+ )),
+)
+
+
+def menu_func(self, context):
+ self.layout.operator(SEQExportStrip.bl_idname, text="Export Selected")
+
+
+def find_keymap_items(km, idname):
+ return (i for i in km.keymap_items if i.idname == idname)
+
+
+def update_keymap(activate):
+ # Add.
+ if activate:
+ kconf = bpy.context.window_manager.keyconfigs.addon
+ for km_info, km_items in KEYMAPS:
+ km_name, km_regtype, km_sptype, km_ismodal = km_info
+ kmap = [k for k in kconf.keymaps
+ if k.name == km_name and k.region_type == km_regtype and
+ k.space_type == km_sptype and k.is_modal == km_ismodal]
+ if kmap:
+ kmap = kmap[0]
+ else:
+ kmap = kconf.keymaps.new(km_name, region_type=km_regtype,
+ space_type=km_sptype,
+ modal=km_ismodal)
+ for kmi_kwargs, props in km_items:
+ kmi = kmap.keymap_items.new(**kmi_kwargs)
+ kmi.active = True
+ for prop, val in props:
+ setattr(kmi.properties, prop, val)
+
+ # Remove.
+ else:
+ # XXX We must also clean up user keyconfig, else, if user has
+ # customized one of our shortcut, this customization
+ # remains in memory, and comes back when re-enabling the addon,
+ # causing a sigsev... :/
+ kconfs = bpy.context.window_manager.keyconfigs
+ for kconf in (kconfs.user, kconfs.addon):
+ for km_info, km_items in KEYMAPS:
+ km_name, km_regtype, km_sptype, km_ismodal = km_info
+ kmaps = (k for k in kconf.keymaps
+ if k.name == km_name and
+ k.region_type == km_regtype and
+ k.space_type == km_sptype and
+ k.is_modal == km_ismodal)
+ for kmap in kmaps:
+ for kmi_kwargs, props in km_items:
+ for kmi in find_keymap_items(kmap,
+ kmi_kwargs["idname"]):
+ kmap.keymap_items.remove(kmi)
+ # XXX We won’t remove addons keymaps themselves,
+ # other addons might also use them!
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ bpy.types.SEQUENCER_MT_strip.append(menu_func)
+
+ update_keymap(True)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+ bpy.types.SEQUENCER_MT_strip.remove(menu_func)
+
+ update_keymap(False)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/sequencer_tools/export_strips.py b/release/scripts/addons_contrib/sequencer_tools/export_strips.py
new file mode 100644
index 0000000..5857eb3
--- /dev/null
+++ b/release/scripts/addons_contrib/sequencer_tools/export_strips.py
@@ -0,0 +1,72 @@
+# ##### 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 LICENSE BLOCK #####
+
+import bpy
+from bpy.props import StringProperty
+
+class SEQExportStrip(bpy.types.Operator):
+ """
+ Export (render) selected strips in sequencer
+ """
+ bl_idname = "sequencer.export_strips"
+ bl_label = "Export Strips"
+ filepath = StringProperty(subtype='FILE_PATH')
+
+ def execute(self, context):
+ sce = bpy.context.scene
+ back_filepath = sce.render.filepath
+ back_seq = sce.render.use_sequencer
+ back_start = sce.frame_start
+ back_end = sce.frame_end
+ hidden_seq = []
+
+ sce.render.use_sequencer = True
+ sce.render.filepath = self.filepath
+ seq = sce.sequence_editor
+ start = end = None
+ for strip in seq.sequences_all:
+ if not strip.select:
+ if not strip.mute:
+ strip.mute = True
+ hidden_seq.append(strip)
+ continue
+ if start is None or strip.frame_final_start < start:
+ start = strip.frame_final_start
+ if end is None or strip.frame_final_end < end:
+ end = strip.frame_final_end
+ sce.frame_start = start
+ sce.frame_end = end
+
+ # Non-blocking render!
+ bpy.ops.render.render("INVOKE_DEFAULT", animation=True)
+
+ for strip in hidden_seq:
+ strip.mute = False
+ sce.render.use_sequencer = back_seq
+ sce.render.filepath = back_filepath
+ sce.frame_start = back_start
+ sce.frame_end = back_end
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ if not self.filepath:
+ self.filepath = bpy.context.scene.render.filepath
+ winman = context.window_manager
+ winman.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
diff --git a/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py b/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py
new file mode 100644
index 0000000..88b19cd
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_add_surround_cameras.py
@@ -0,0 +1,247 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Surround Projection Tools",
+ "author": "Cole Ingraham",
+ "location": "View3D > Tool Shelf > Surround Projection panel",
+ "description": "Setup cameras and create rendering scenes for n-screen surround projection.",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Surround_Projection_Tools",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=29266",
+ "version": (0, 1, 2),
+ "blender": (2, 60, 0),
+ "category": "3D View"
+}
+
+import bpy
+from bpy.props import IntProperty
+from bpy.props import BoolProperty
+from math import pi
+import re
+
+CAMERA_ORIGIN_NAME = "CameraOrigin"
+
+# property for how many screens to add
+bpy.types.WindowManager.num_surround_screens = IntProperty(
+ name="Number of screens",
+ description="How many screens to add",
+ default=4,
+ min=3)
+
+# safeguard for removing previous cameras/scenes
+bpy.types.WindowManager.previous_num_surround_screens = IntProperty(
+ name="Previous number of screens",
+ description="used for removing cameras/scenes",
+ default=-1)
+
+# used to enable/disable make/remove scenes and cameras
+bpy.types.WindowManager.surround_screens_init = BoolProperty(
+ name="SurroundScenesInit",
+ default=False)
+
+# GUI panel
+class AddSurroundCamerasPanel(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Surround Projection"
+ bl_options = {'DEFAULT_CLOSED'}
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+
+ row = col.row()
+ row.prop(context.window_manager, "num_surround_screens")
+ row = col.row()
+
+ if context.window_manager.previous_num_surround_screens is not -1:
+ row.operator('objects.remove_surround_cameras', icon='X')
+ else:
+ row.operator('objects.add_surround_cameras', icon='CAMERA_DATA')
+
+ row = col.row()
+
+ if context.window_manager.surround_screens_init is True:
+ row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
+ else:
+ row.operator('scene.add_linked_scenes_for_surround_cameras', icon='SCENE_DATA')
+
+ #col = layout.column(align=True)
+ #row = col.row()
+ #row.operator('objects.remove_surround_cameras', icon='X')
+ #row = col.row()
+ #row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
+
+
+# operator for adding cameras
+class AddSurroundCamerasOperator(bpy.types.Operator):
+ bl_idname = 'objects.add_surround_cameras'
+ bl_label = "Add Cameras"
+ bl_description = "Add n cameras"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.window_manager.previous_num_surround_screens is -1
+
+ def execute(self, context):
+
+ scene = context.scene
+ numScreens = context.window_manager.num_surround_screens
+
+ # add an empty for the camera origin if not already present
+ obj_origin = scene.objects.get(CAMERA_ORIGIN_NAME)
+ if not obj_origin:
+ bpy.ops.object.add()
+ obj_origin = context.active_object
+ obj_origin.name = CAMERA_ORIGIN_NAME
+ obj_origin.location = scene.cursor_location
+
+ for i in range(0,numScreens):
+
+ # add a new camer
+ bpy.ops.object.camera_add()
+
+ # get the current camera
+ cam = context.active_object
+
+ # name the camera
+ cameraName = "Camera" + str(i)
+ cam.name = cameraName
+ cam.data.name = cameraName
+
+ # position camera
+ cam.location = 0,0,0
+ cam.rotation_euler = (pi/2), 0, ((-2*pi)/numScreens) * i
+
+ # set the field of view angle
+ cam.data.angle = (2*pi)/numScreens
+
+ # make the parent of the camera the origin
+ cam.parent = obj_origin
+
+ # sel/activate origin
+ bpy.ops.object.select_all(action='DESELECT')
+ obj_origin.select = True
+ scene.objects.active = obj_origin
+
+ context.window_manager.previous_num_surround_screens = numScreens
+ return {'FINISHED'}
+
+
+# operator for creating new linked scenes for each camera
+class AddSurroundScenesOperator(bpy.types.Operator):
+ bl_idname = 'scene.add_linked_scenes_for_surround_cameras'
+ bl_label = "Make Scenes"
+ bl_description = "Creates new scenes with linked object data for each camera"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
+ return True
+ return False
+
+ def execute(self, context):
+ scene_base = context.scene
+ numScreens = context.window_manager.previous_num_surround_screens
+ sceneName = scene_base.name
+ renderpath = scene_base.render.filepath
+
+ for i in range(0, numScreens):
+
+ thisScene = sceneName + "-Camera" + str(i)
+
+ bpy.ops.scene.new(type='EMPTY')
+ scene_new = context.scene
+ scene_new.name = thisScene
+
+ camera_object = bpy.data.objects["Camera" + str(i)]
+ scene_new.camera = camera_object
+ scene_new.background_set = scene_base
+
+ # not essential but nice to have the camera in the scene
+ scene_new.objects.link(camera_object)
+
+ scene_new.render.filepath = renderpath + thisScene
+
+ context.screen.scene = scene_base
+ context.window_manager.surround_screens_init = True
+ return {'FINISHED'}
+
+
+# operator for removing the surround scenes
+class RemoveSurroundScenesOperator(bpy.types.Operator):
+ bl_idname = 'objects.remove_linked_scenes_for_surround_cameras'
+ bl_label = "Remove Scenes"
+ bl_description = "Removes all surround scenes"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.window_manager.surround_screens_init is True
+
+ def execute(self, context):
+ numScreens = context.window_manager.previous_num_surround_screens
+
+ for scene in list(bpy.data.scenes):
+ if re.search("-Camera",scene.name):
+ bpy.data.scenes.remove(scene)
+
+ context.window_manager.surround_screens_init = False
+ return {'FINISHED'}
+
+
+# operator for removing the surround cameras/scenes
+class RemoveSurroundCamerasOperator(bpy.types.Operator):
+ bl_idname = 'objects.remove_surround_cameras'
+ bl_label = "Remove Cameras"
+ bl_description = "Removes all surround cameras"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
+ return True
+ return False
+
+ def execute(self, context):
+
+ scene = context.scene
+
+ # XXX. shouldnt there be some less general way to do this?
+ # like check if they are the child of origin? - campbell
+ for obj in scene.objects[:]:
+ if obj.type == 'CAMERA':
+ scene.objects.unlink(obj)
+
+ context.window_manager.previous_num_surround_screens = -1
+ return {'FINISHED'}
+
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py b/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py
new file mode 100644
index 0000000..c6a882f
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_enhanced_3d_cursor.py
@@ -0,0 +1,5562 @@
+# ***** 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8-80 compliant>
+
+bl_info = {
+ "name": "Enhanced 3D Cursor",
+ "description": "Cursor history and bookmarks; drag/snap cursor.",
+ "author": "dairin0d",
+ "version": (2, 8, 7),
+ "blender": (2, 63, 0),
+ "location": "View3D > Action mouse; F10; Properties panel",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/3D_interaction/Enhanced_3D_Cursor",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=28451",
+ "category": "3D View"}
+#============================================================================#
+
+"""
+ATTENTION:
+somewhere around 45447 revision object.ray_cast() starts conflicting with
+mesh.update(calc_tessface=True) -- at least when invoked within one
+operator cycle, object.ray_cast() crashes if object's tessfaces were
+update()d earlier in the code. However, not update()ing the meshes
+seems to work fine -- ray_cast() does its job, and it's possible to
+access tessfaces afterwards.
+mesh.calc_tessface() -- ? crashes too
+
+Seems like now axes are stored in columns instead of rows.
+Perhaps it's better to write utility functions to create/decompose
+matrices from/to 3D-vector axes and a translation component
+
+Breakdown:
+ Addon registration
+ Keymap utils
+ Various utils (e.g. find_region)
+ OpenGL; drawing utils
+ Non-undoable data storage
+ Cursor utils
+ Stick-object
+ Cursor monitor
+ Addon's GUI
+ Addon's properties
+ Addon's operators
+ ID Block emulator
+ Mesh cache
+ Snap utils
+ View3D utils
+ Transform orientation / coordinate system utils
+ Generic transform utils
+ Main operator
+ ...
+.
+
+First step is to re-make the cursor addon (make something usable first).
+CAD tools should be done without the hassle.
+
+TODO:
+ strip trailing space? (one of campbellbarton's commits did that)
+
+ IDEAS:
+ - implement 'GIMBAL' orientation (euler axes)
+ - mini-Z-buffer in the vicinity of mouse coords (using raycasts)
+ - an orientation that points towards cursor
+ (from current selection to cursor)
+ - user coordinate systems (using e.g. empties to store different
+ systems; when user switches to such UCS, origin will be set to
+ "cursor", cursor will be sticked to the empty, and a custom
+ transform orientation will be aligned with the empty)
+ - "Stick" transform orientation that is always aligned with the
+ object cursor is "sticked" to?
+ - make 'NORMAL' system also work for bones?
+ - user preferences? (stored in a file)
+ - create spline/edge_mesh from history?
+ - API to access history/bookmarks/operators from other scripts?
+ - Snap selection to bookmark?
+ - Optimize
+ - Clean up code, move to several files?
+ LATER:
+ ISSUES:
+ Limitations:
+ - I need to emulate in Python some things that Blender doesn't
+ currently expose through API:
+ - obtaining matrix of predefined transform orientation
+ - obtaining position of pivot
+ For some kinds of information (e.g. active vertex/edge,
+ selected meta-elements), there is simply no workaround.
+ - Snapping to vertices/edges works differently than in Blender.
+ First of all, iteration over all vertices/edges of all
+ objects along the ray is likely to be very slow.
+ Second, it's more human-friendly to snap to visible
+ elements (or at least with approximately known position).
+ - In editmode I have to exit-and-enter it to get relevant
+ information about current selection. Thus any operator
+ would automatically get applied when you click on 3D View.
+ Mites:
+ QUESTIONS:
+==============================================================================
+Borrowed code/logic:
+- space_view3d_panel_measure.py (Buerbaum Martin "Pontiac"):
+ - OpenGL state storing/restoring; working with projection matrices.
+"""
+
+import bpy
+import bgl
+import blf
+import bmesh
+
+from mathutils import Vector, Matrix, Quaternion, Euler
+
+from mathutils.geometry import (intersect_line_sphere,
+ intersect_ray_tri,
+ barycentric_transform,
+ tessellate_polygon,
+ intersect_line_line,
+ intersect_line_plane,
+ )
+
+from bpy_extras.view3d_utils import (region_2d_to_location_3d,
+ location_3d_to_region_2d,
+ )
+
+import math
+import time
+
+# ====== MODULE GLOBALS / CONSTANTS ====== #
+tmp_name = chr(0x10ffff) # maximal Unicode value
+epsilon = 0.000001
+
+# ====== SET CURSOR OPERATOR ====== #
+class EnhancedSetCursor(bpy.types.Operator):
+ """Cursor history and bookmarks; drag/snap cursor."""
+ bl_idname = "view3d.cursor3d_enhanced"
+ bl_label = "Enhanced Set Cursor"
+
+ key_char_map = {
+ 'PERIOD':".", 'NUMPAD_PERIOD':".",
+ 'MINUS':"-", 'NUMPAD_MINUS':"-",
+ 'EQUAL':"+", 'NUMPAD_PLUS':"+",
+ #'E':"e", # such big/small numbers aren't useful
+ 'ONE':"1", 'NUMPAD_1':"1",
+ 'TWO':"2", 'NUMPAD_2':"2",
+ 'THREE':"3", 'NUMPAD_3':"3",
+ 'FOUR':"4", 'NUMPAD_4':"4",
+ 'FIVE':"5", 'NUMPAD_5':"5",
+ 'SIX':"6", 'NUMPAD_6':"6",
+ 'SEVEN':"7", 'NUMPAD_7':"7",
+ 'EIGHT':"8", 'NUMPAD_8':"8",
+ 'NINE':"9", 'NUMPAD_9':"9",
+ 'ZERO':"0", 'NUMPAD_0':"0",
+ 'SPACE':" ",
+ 'SLASH':"/", 'NUMPAD_SLASH':"/",
+ 'NUMPAD_ASTERIX':"*",
+ }
+
+ key_coordsys_map = {
+ 'LEFT_BRACKET':-1,
+ 'RIGHT_BRACKET':1,
+ 'J':'VIEW',
+ 'K':"Surface",
+ 'L':'LOCAL',
+ 'B':'GLOBAL',
+ 'N':'NORMAL',
+ 'M':"Scaled",
+ }
+
+ key_pivot_map = {
+ 'H':'ACTIVE',
+ 'U':'CURSOR',
+ 'I':'INDIVIDUAL',
+ 'O':'CENTER',
+ 'P':'MEDIAN',
+ }
+
+ key_snap_map = {
+ 'C':'INCREMENT',
+ 'V':'VERTEX',
+ 'E':'EDGE',
+ 'F':'FACE',
+ }
+
+ key_tfm_mode_map = {
+ 'G':'MOVE',
+ 'R':'ROTATE',
+ 'S':'SCALE',
+ }
+
+ key_map = {
+ "confirm":{'ACTIONMOUSE'}, # also 'RET' ?
+ "cancel":{'SELECTMOUSE', 'ESC'},
+ "free_mouse":{'F10'},
+ "make_normal_snapshot":{'W'},
+ "make_tangential_snapshot":{'Q'},
+ "use_absolute_coords":{'A'},
+ "snap_to_raw_mesh":{'D'},
+ "use_object_centers":{'T'},
+ "precision_up":{'PAGE_UP'},
+ "precision_down":{'PAGE_DOWN'},
+ "move_caret_prev":{'LEFT_ARROW'},
+ "move_caret_next":{'RIGHT_ARROW'},
+ "move_caret_home":{'HOME'},
+ "move_caret_end":{'END'},
+ "change_current_axis":{'TAB', 'RET', 'NUMPAD_ENTER'},
+ "prev_axis":{'UP_ARROW'},
+ "next_axis":{'DOWN_ARROW'},
+ "remove_next_character":{'DEL'},
+ "remove_last_character":{'BACK_SPACE'},
+ "copy_axes":{'C'},
+ "paste_axes":{'V'},
+ "cut_axes":{'X'},
+ }
+
+ gizmo_factor = 0.15
+ click_period = 0.25
+
+ angle_grid_steps = {True:1.0, False:5.0}
+ scale_grid_steps = {True:0.01, False:0.1}
+
+ # ====== OPERATOR METHOD OVERLOADS ====== #
+ @classmethod
+ def poll(cls, context):
+ area_types = {'VIEW_3D',} # also: IMAGE_EDITOR ?
+ return (context.area.type in area_types) and \
+ (context.region.type == "WINDOW")
+
+ def modal(self, context, event):
+ context.area.tag_redraw()
+ return self.try_process_input(context, event)
+
+ def invoke(self, context, event):
+ # Attempt to launch the monitor
+ if bpy.ops.view3d.cursor3d_monitor.poll():
+ bpy.ops.view3d.cursor3d_monitor()
+
+ # Don't interfere with these modes when only mouse is pressed
+ if ('SCULPT' in context.mode) or ('PAINT' in context.mode):
+ if "MOUSE" in event.type:
+ return {'CANCELLED'}
+
+ CursorDynamicSettings.active_transform_operator = self
+
+ tool_settings = context.tool_settings
+
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ settings_scene = context.scene.cursor_3d_tools_settings
+
+ self.setup_keymaps(context, event)
+
+ # Coordinate System Utility
+ self.particles, self.csu = gather_particles(context=context)
+ self.particles = [View3D_Cursor(context)]
+
+ self.csu.source_pos = self.particles[0].get_location()
+ self.csu.source_rot = self.particles[0].get_rotation()
+ self.csu.source_scale = self.particles[0].get_scale()
+
+ # View3D Utility
+ self.vu = ViewUtility(context.region, context.space_data,
+ context.region_data)
+
+ # Snap Utility
+ self.su = SnapUtility(context)
+
+ # turn off view locking for the duration of the operator
+ self.view_pos = self.vu.get_position(True)
+ self.vu.set_position(self.vu.get_position(), True)
+ self.view_locks = self.vu.get_locks()
+ self.vu.set_locks({})
+
+ # Initialize runtime states
+ self.initiated_by_mouse = ("MOUSE" in event.type)
+ self.free_mouse = not self.initiated_by_mouse
+ self.use_object_centers = False
+ self.axes_values = ["", "", ""]
+ self.axes_coords = [None, None, None]
+ self.axes_eval_success = [True, True, True]
+ self.allowed_axes = [True, True, True]
+ self.current_axis = 0
+ self.caret_pos = 0
+ self.coord_format = "{:." + str(settings.free_coord_precision) + "f}"
+ self.transform_mode = 'MOVE'
+ self.init_xy_angle_distance(context, event)
+
+ self.click_start = time.time()
+ if not self.initiated_by_mouse:
+ self.click_start -= self.click_period
+
+ self.stick_obj_name = settings_scene.stick_obj_name
+ self.stick_obj_pos = settings_scene.stick_obj_pos
+
+ # Initial run
+ self.try_process_input(context, event, True)
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+ def cancel(self, context):
+ for particle in self.particles:
+ particle.revert()
+
+ set_stick_obj(context.scene, self.stick_obj_name, self.stick_obj_pos)
+
+ self.finalize(context)
+ return {'CANCELLED'}
+
+ # ====== CLEANUP/FINALIZE ====== #
+ def finalize(self, context):
+ # restore view locking
+ self.vu.set_locks(self.view_locks)
+ self.vu.set_position(self.view_pos, True)
+
+ self.cleanup(context)
+
+ # This is to avoid "blinking" of
+ # between-history-positions line
+ settings = find_settings()
+ history = settings.history
+ # make sure the most recent history entry is displayed
+ history.curr_id = 0
+ history.last_id = 0
+
+ # Ensure there are no leftovers from draw_callback
+ context.area.tag_redraw()
+
+ return {'FINISHED'}
+
+ def cleanup(self, context):
+ self.particles = None
+ self.csu = None
+ self.vu = None
+ if self.su is not None:
+ self.su.dispose()
+ self.su = None
+
+ CursorDynamicSettings.active_transform_operator = None
+
+ # ====== USER INPUT PROCESSING ====== #
+ def setup_keymaps(self, context, event=None):
+ self.key_map = self.key_map.copy()
+
+ # There is no such event as 'ACTIONMOUSE',
+ # it's always 'LEFTMOUSE' or 'RIGHTMOUSE'
+ if event:
+ if event.type == 'LEFTMOUSE':
+ self.key_map["confirm"] = {'LEFTMOUSE'}
+ self.key_map["cancel"] = {'RIGHTMOUSE', 'ESC'}
+ elif event.type == 'RIGHTMOUSE':
+ self.key_map["confirm"] = {'RIGHTMOUSE'}
+ self.key_map["cancel"] = {'LEFTMOUSE', 'ESC'}
+ else:
+ event = None
+ if event is None:
+ select_mouse = context.user_preferences.inputs.select_mouse
+ if select_mouse == 'RIGHT':
+ self.key_map["confirm"] = {'LEFTMOUSE'}
+ self.key_map["cancel"] = {'RIGHTMOUSE', 'ESC'}
+ else:
+ self.key_map["confirm"] = {'RIGHTMOUSE'}
+ self.key_map["cancel"] = {'LEFTMOUSE', 'ESC'}
+
+ # Use user-defined "free mouse" key, if it exists
+ wm = context.window_manager
+ if '3D View' in wm.keyconfigs.user.keymaps:
+ km = wm.keyconfigs.user.keymaps['3D View']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'view3d.cursor3d_enhanced':
+ if kmi.map_type == 'KEYBOARD':
+ self.key_map["free_mouse"] = {kmi.type,}
+ break
+
+ def try_process_input(self, context, event, initial_run=False):
+ try:
+ return self.process_input(context, event, initial_run)
+ except:
+ # If anything fails, at least dispose the resources
+ self.cleanup(context)
+ raise
+
+ def process_input(self, context, event, initial_run=False):
+ wm = context.window_manager
+ v3d = context.space_data
+
+ if event.type in self.key_map["confirm"]:
+ if self.free_mouse:
+ finished = (event.value == 'PRESS')
+ else:
+ finished = (event.value == 'RELEASE')
+
+ if finished:
+ return self.finalize(context)
+
+ if event.type in self.key_map["cancel"]:
+ return self.cancel(context)
+
+ tool_settings = context.tool_settings
+
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ make_snapshot = False
+ tangential_snapshot = False
+
+ if event.value == 'PRESS':
+ if event.type in self.key_map["free_mouse"]:
+ if self.free_mouse and (not initial_run):
+ # confirm if pressed second time
+ return self.finalize(context)
+ else:
+ self.free_mouse = True
+
+ if event.type in self.key_tfm_mode_map:
+ new_mode = self.key_tfm_mode_map[event.type]
+
+ if self.transform_mode != new_mode:
+ # snap cursor to its initial state
+ if new_mode != 'MOVE':
+ for particle in self.particles:
+ initial_matrix = particle.get_initial_matrix()
+ particle.set_matrix(initial_matrix)
+ # reset intial mouse position
+ self.init_xy_angle_distance(context, event)
+
+ self.transform_mode = new_mode
+
+ if event.type in self.key_map["make_normal_snapshot"]:
+ make_snapshot = True
+ tangential_snapshot = False
+
+ if event.type in self.key_map["make_tangential_snapshot"]:
+ make_snapshot = True
+ tangential_snapshot = True
+
+ if event.type in self.key_map["snap_to_raw_mesh"]:
+ tool_settings.use_snap_self = \
+ not tool_settings.use_snap_self
+
+ if (not event.alt) and (event.type in {'X', 'Y', 'Z'}):
+ axis_lock = [(event.type == 'X') != event.shift,
+ (event.type == 'Y') != event.shift,
+ (event.type == 'Z') != event.shift]
+
+ if self.allowed_axes != axis_lock:
+ self.allowed_axes = axis_lock
+ else:
+ self.allowed_axes = [True, True, True]
+
+ if event.type in self.key_map["use_absolute_coords"]:
+ tfm_opts.use_relative_coords = \
+ not tfm_opts.use_relative_coords
+
+ self.update_origin_projection(context)
+
+ incr = 0
+ if event.type in self.key_map["change_current_axis"]:
+ incr = (-1 if event.shift else 1)
+ elif event.type in self.key_map["next_axis"]:
+ incr = 1
+ elif event.type in self.key_map["prev_axis"]:
+ incr = -1
+
+ if incr != 0:
+ self.current_axis = (self.current_axis + incr) % 3
+ self.caret_pos = len(self.axes_values[self.current_axis])
+
+ incr = 0
+ if event.type in self.key_map["precision_up"]:
+ incr = 1
+ elif event.type in self.key_map["precision_down"]:
+ incr = -1
+
+ if incr != 0:
+ settings.free_coord_precision += incr
+ self.coord_format = "{:." + \
+ str(settings.free_coord_precision) + "f}"
+
+ if (event.type == 'ZERO') and event.ctrl:
+ self.snap_to_system_origin()
+ else:
+ self.process_axis_input(event)
+
+ if event.alt:
+ jc = (", " if tfm_opts.use_comma_separator else "\t")
+ if event.type in self.key_map["copy_axes"]:
+ wm.clipboard = jc.join(self.get_axes_text(True))
+ elif event.type in self.key_map["cut_axes"]:
+ wm.clipboard = jc.join(self.get_axes_text(True))
+ self.set_axes_text("\t\t\t")
+ elif event.type in self.key_map["paste_axes"]:
+ if jc == "\t":
+ self.set_axes_text(wm.clipboard, True)
+ else:
+ jc = jc.strip()
+ ttext = ""
+ brackets = 0
+ for c in wm.clipboard:
+ if c in "[{(":
+ brackets += 1
+ elif c in "]})":
+ brackets -= 1
+ if (brackets == 0) and (c == jc):
+ c = "\t"
+ ttext += c
+ self.set_axes_text(ttext, True)
+
+ if event.type in self.key_coordsys_map:
+ new_orientation = self.key_coordsys_map[event.type]
+ self.csu.set_orientation(new_orientation)
+
+ self.update_origin_projection(context)
+
+ if event.ctrl:
+ self.snap_to_system_origin()
+
+ if event.type in self.key_map["use_object_centers"]:
+ v3d.use_pivot_point_align = not v3d.use_pivot_point_align
+
+ if event.type in self.key_pivot_map:
+ self.csu.set_pivot(self.key_pivot_map[event.type])
+
+ self.update_origin_projection(context)
+
+ if event.ctrl:
+ self.snap_to_system_origin(force_pivot=True)
+
+ if (not event.alt) and (event.type in self.key_snap_map):
+ snap_element = self.key_snap_map[event.type]
+ if tool_settings.snap_element == snap_element:
+ if snap_element == 'VERTEX':
+ snap_element = 'VOLUME'
+ elif snap_element == 'VOLUME':
+ snap_element = 'VERTEX'
+ tool_settings.snap_element = snap_element
+ # end if
+
+ if initial_run or (('MOVE' not in event.type) and \
+ ('TIMER' not in event.type)):
+ use_snap = (tool_settings.use_snap != event.ctrl)
+ if use_snap:
+ snap_type = tool_settings.snap_element
+ else:
+ snap_type = None
+
+ axes_coords = [None, None, None]
+ if self.transform_mode == 'MOVE':
+ for i in range(3):
+ if self.axes_coords[i] is not None:
+ axes_coords[i] = self.axes_coords[i]
+ elif not self.allowed_axes[i]:
+ axes_coords[i] = 0.0
+
+ self.su.set_modes(
+ interpolation=tfm_opts.snap_interpolate_normals_mode,
+ use_relative_coords=tfm_opts.use_relative_coords,
+ editmode=tool_settings.use_snap_self,
+ snap_type=snap_type,
+ snap_align=tool_settings.use_snap_align_rotation,
+ axes_coords=axes_coords,
+ )
+
+ self.do_raycast = ("MOUSE" in event.type)
+ self.grid_substep = event.shift
+ self.modify_surface_orientation = (len(self.particles) == 1)
+ self.xy = Vector((event.mouse_region_x, event.mouse_region_y))
+
+ self.use_object_centers = v3d.use_pivot_point_align
+
+ if event.type == 'MOUSEMOVE':
+ self.update_transform_mousemove()
+
+ if self.transform_mode == 'MOVE':
+ transform_func = self.transform_move
+ elif self.transform_mode == 'ROTATE':
+ transform_func = self.transform_rotate
+ elif self.transform_mode == 'SCALE':
+ transform_func = self.transform_scale
+
+ for particle in self.particles:
+ transform_func(particle)
+
+ if make_snapshot:
+ self.make_normal_snapshot(context.scene, tangential_snapshot)
+
+ return {'RUNNING_MODAL'}
+
+ def update_origin_projection(self, context):
+ r = context.region
+ rv3d = context.region_data
+
+ origin = self.csu.get_origin()
+ # prehaps not projection, but intersection with plane?
+ self.origin_xy = location_3d_to_region_2d(r, rv3d, origin)
+ if self.origin_xy is None:
+ self.origin_xy = Vector((r.width / 2, r.height / 2))
+
+ self.delta_xy = (self.start_xy - self.origin_xy).to_3d()
+ self.prev_delta_xy = self.delta_xy
+
+ def init_xy_angle_distance(self, context, event):
+ self.start_xy = Vector((event.mouse_region_x, event.mouse_region_y))
+
+ self.update_origin_projection(context)
+
+ # Distinction between angles has to be made because
+ # angles can go beyond 360 degrees (we cannot snap
+ # to increment the original ones).
+ self.raw_angles = [0.0, 0.0, 0.0]
+ self.angles = [0.0, 0.0, 0.0]
+ self.scales = [1.0, 1.0, 1.0]
+
+ def update_transform_mousemove(self):
+ delta_xy = (self.xy - self.origin_xy).to_3d()
+
+ n_axes = sum(int(v) for v in self.allowed_axes)
+ if n_axes == 1:
+ # rotate using angle as value
+ rd = self.prev_delta_xy.rotation_difference(delta_xy)
+ offset = -rd.angle * round(rd.axis[2])
+
+ sys_matrix = self.csu.get_matrix()
+
+ i_allowed = 0
+ for i in range(3):
+ if self.allowed_axes[i]:
+ i_allowed = i
+
+ view_dir = self.vu.get_direction()
+ if view_dir.dot(sys_matrix[i_allowed][:3]) < 0:
+ offset = -offset
+
+ for i in range(3):
+ if self.allowed_axes[i]:
+ self.raw_angles[i] += offset
+ elif n_axes == 2:
+ # rotate using XY coords as two values
+ offset = (delta_xy - self.prev_delta_xy) * (math.pi / 180.0)
+
+ if self.grid_substep:
+ offset *= 0.1
+ else:
+ offset *= 0.5
+
+ j = 0
+ for i in range(3):
+ if self.allowed_axes[i]:
+ self.raw_angles[i] += offset[1 - j]
+ j += 1
+ elif n_axes == 3:
+ # rotate around view direction
+ rd = self.prev_delta_xy.rotation_difference(delta_xy)
+ offset = -rd.angle * round(rd.axis[2])
+
+ view_dir = self.vu.get_direction()
+
+ sys_matrix = self.csu.get_matrix()
+
+ try:
+ view_dir = sys_matrix.inverted().to_3x3() * view_dir
+ except:
+ # this is some degenerate system
+ pass
+ view_dir.normalize()
+
+ rot = Matrix.Rotation(offset, 3, view_dir)
+
+ matrix = Euler(self.raw_angles, 'XYZ').to_matrix()
+ matrix.rotate(rot)
+
+ euler = matrix.to_euler('XYZ')
+ self.raw_angles[0] += clamp_angle(euler.x - self.raw_angles[0])
+ self.raw_angles[1] += clamp_angle(euler.y - self.raw_angles[1])
+ self.raw_angles[2] += clamp_angle(euler.z - self.raw_angles[2])
+
+ scale = delta_xy.length / self.delta_xy.length
+ if self.delta_xy.dot(delta_xy) < 0:
+ scale *= -1
+ for i in range(3):
+ if self.allowed_axes[i]:
+ self.scales[i] = scale
+
+ self.prev_delta_xy = delta_xy
+
+ def transform_move(self, particle):
+ src_matrix = particle.get_matrix()
+ initial_matrix = particle.get_initial_matrix()
+
+ matrix = self.su.snap(
+ self.xy, src_matrix, initial_matrix,
+ self.do_raycast, self.grid_substep,
+ self.vu, self.csu,
+ self.modify_surface_orientation,
+ self.use_object_centers)
+
+ particle.set_matrix(matrix)
+
+ def rotate_matrix(self, matrix):
+ sys_matrix = self.csu.get_matrix()
+
+ try:
+ matrix = sys_matrix.inverted() * matrix
+ except:
+ # this is some degenerate system
+ pass
+
+ # Blender's order of rotation [in local axes]
+ rotation_order = [2, 1, 0]
+
+ # Seems that 4x4 matrix cannot be rotated using rotate() ?
+ sys_matrix3 = sys_matrix.to_3x3()
+
+ for i in range(3):
+ j = rotation_order[i]
+ axis = sys_matrix3[j]
+ angle = self.angles[j]
+
+ rot = angle_axis_to_quat(angle, axis)
+ # this seems to be buggy too
+ #rot = Matrix.Rotation(angle, 3, axis)
+
+ sys_matrix3 = rot.to_matrix() * sys_matrix3
+ # sys_matrix3.rotate has a bug? or I don't understand how it works?
+ #sys_matrix3.rotate(rot)
+
+ for i in range(3):
+ sys_matrix[i][:3] = sys_matrix3[i]
+
+ matrix = sys_matrix * matrix
+
+ return matrix
+
+ def transform_rotate(self, particle):
+ grid_step = self.angle_grid_steps[self.grid_substep]
+ grid_step *= (math.pi / 180.0)
+
+ for i in range(3):
+ if self.axes_values[i] and self.axes_eval_success[i]:
+ self.raw_angles[i] = self.axes_coords[i] * (math.pi / 180.0)
+
+ self.angles[i] = self.raw_angles[i]
+
+ if self.su.implementation.snap_type == 'INCREMENT':
+ for i in range(3):
+ self.angles[i] = round_step(self.angles[i], grid_step)
+
+ initial_matrix = particle.get_initial_matrix()
+ matrix = self.rotate_matrix(initial_matrix)
+
+ particle.set_matrix(matrix)
+
+ def scale_matrix(self, matrix):
+ sys_matrix = self.csu.get_matrix()
+
+ try:
+ matrix = sys_matrix.inverted() * matrix
+ except:
+ # this is some degenerate system
+ pass
+
+ for i in range(3):
+ sys_matrix[i] *= self.scales[i]
+
+ matrix = sys_matrix * matrix
+
+ return matrix
+
+ def transform_scale(self, particle):
+ grid_step = self.scale_grid_steps[self.grid_substep]
+
+ for i in range(3):
+ if self.axes_values[i] and self.axes_eval_success[i]:
+ self.scales[i] = self.axes_coords[i]
+
+ if self.su.implementation.snap_type == 'INCREMENT':
+ for i in range(3):
+ self.scales[i] = round_step(self.scales[i], grid_step)
+
+ initial_matrix = particle.get_initial_matrix()
+ matrix = self.scale_matrix(initial_matrix)
+
+ particle.set_matrix(matrix)
+
+ def set_axis_input(self, axis_id, axis_val):
+ if axis_val == self.axes_values[axis_id]:
+ return
+
+ self.axes_values[axis_id] = axis_val
+
+ if len(axis_val) == 0:
+ self.axes_coords[axis_id] = None
+ self.axes_eval_success[axis_id] = True
+ else:
+ try:
+ #self.axes_coords[axis_id] = float(eval(axis_val, {}, {}))
+ self.axes_coords[axis_id] = \
+ float(eval(axis_val, math.__dict__))
+ self.axes_eval_success[axis_id] = True
+ except:
+ self.axes_eval_success[axis_id] = False
+
+ def snap_to_system_origin(self, force_pivot=False):
+ if self.transform_mode == 'MOVE':
+ pivot = self.csu.get_pivot_name(raw=force_pivot)
+ p = self.csu.get_origin(relative=False, pivot=pivot)
+ m = self.csu.get_matrix()
+ try:
+ p = m.inverted() * p
+ except:
+ # this is some degenerate system
+ pass
+ for i in range(3):
+ self.set_axis_input(i, str(p[i]))
+ elif self.transform_mode == 'ROTATE':
+ for i in range(3):
+ self.set_axis_input(i, "0")
+ elif self.transform_mode == 'SCALE':
+ for i in range(3):
+ self.set_axis_input(i, "1")
+
+ def get_axes_values(self, as_string=False):
+ if self.transform_mode == 'MOVE':
+ localmat = CursorDynamicSettings.local_matrix
+ raw_axes = localmat.translation
+ elif self.transform_mode == 'ROTATE':
+ raw_axes = Vector(self.angles) * (180.0 / math.pi)
+ elif self.transform_mode == 'SCALE':
+ raw_axes = Vector(self.scales)
+
+ axes_values = []
+ for i in range(3):
+ if as_string and self.axes_values[i]:
+ value = self.axes_values[i]
+ elif self.axes_eval_success[i] and \
+ (self.axes_coords[i] is not None):
+ value = self.axes_coords[i]
+ else:
+ value = raw_axes[i]
+ if as_string:
+ value = self.coord_format.format(value)
+ axes_values.append(value)
+
+ return axes_values
+
+ def get_axes_text(self, offset=False):
+ axes_values = self.get_axes_values(as_string=True)
+
+ axes_text = []
+ for i in range(3):
+ j = i
+ if offset:
+ j = (i + self.current_axis) % 3
+
+ axes_text.append(axes_values[j])
+
+ return axes_text
+
+ def set_axes_text(self, text, offset=False):
+ if "\n" in text:
+ text = text.replace("\r", "")
+ else:
+ text = text.replace("\r", "\n")
+ text = text.replace("\n", "\t")
+ #text = text.replace(",", ".") # ???
+
+ axes_text = text.split("\t")
+ for i in range(min(len(axes_text), 3)):
+ j = i
+ if offset:
+ j = (i + self.current_axis) % 3
+ self.set_axis_input(j, axes_text[i])
+
+ def process_axis_input(self, event):
+ axis_id = self.current_axis
+ axis_val = self.axes_values[axis_id]
+
+ if event.type in self.key_map["remove_next_character"]:
+ if event.ctrl:
+ # clear all
+ for i in range(3):
+ self.set_axis_input(i, "")
+ self.caret_pos = 0
+ return
+ else:
+ axis_val = axis_val[0:self.caret_pos] + \
+ axis_val[self.caret_pos + 1:len(axis_val)]
+ elif event.type in self.key_map["remove_last_character"]:
+ if event.ctrl:
+ # clear current
+ axis_val = ""
+ else:
+ axis_val = axis_val[0:self.caret_pos - 1] + \
+ axis_val[self.caret_pos:len(axis_val)]
+ self.caret_pos -= 1
+ elif event.type in self.key_map["move_caret_next"]:
+ self.caret_pos += 1
+ if event.ctrl:
+ snap_chars = ".-+*/%()"
+ i = self.caret_pos
+ while axis_val[i:i + 1] not in snap_chars:
+ i += 1
+ self.caret_pos = i
+ elif event.type in self.key_map["move_caret_prev"]:
+ self.caret_pos -= 1
+ if event.ctrl:
+ snap_chars = ".-+*/%()"
+ i = self.caret_pos
+ while axis_val[i - 1:i] not in snap_chars:
+ i -= 1
+ self.caret_pos = i
+ elif event.type in self.key_map["move_caret_home"]:
+ self.caret_pos = 0
+ elif event.type in self.key_map["move_caret_end"]:
+ self.caret_pos = len(axis_val)
+ elif event.type in self.key_char_map:
+ # Currently accessing event.ascii seems to crash Blender
+ c = self.key_char_map[event.type]
+ if event.shift:
+ if c == "8":
+ c = "*"
+ elif c == "5":
+ c = "%"
+ elif c == "9":
+ c = "("
+ elif c == "0":
+ c = ")"
+ axis_val = axis_val[0:self.caret_pos] + c + \
+ axis_val[self.caret_pos:len(axis_val)]
+ self.caret_pos += 1
+
+ self.caret_pos = min(max(self.caret_pos, 0), len(axis_val))
+
+ self.set_axis_input(axis_id, axis_val)
+
+ # ====== DRAWING ====== #
+ def gizmo_distance(self, pos):
+ rv3d = self.vu.region_data
+ if rv3d.view_perspective == 'ORTHO':
+ dist = rv3d.view_distance
+ else:
+ view_pos = self.vu.get_viewpoint()
+ view_dir = self.vu.get_direction()
+ dist = (pos - view_pos).dot(view_dir)
+ return dist
+
+ def gizmo_scale(self, pos):
+ return self.gizmo_distance(pos) * self.gizmo_factor
+
+ def check_v3d_local(self, context):
+ csu_v3d = self.csu.space_data
+ v3d = context.space_data
+ if csu_v3d.local_view:
+ return csu_v3d != v3d
+ return v3d.local_view
+
+ def draw_3d(self, context):
+ if self.check_v3d_local(context):
+ return
+
+ if time.time() < (self.click_start + self.click_period):
+ return
+
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ initial_matrix = self.particles[0].get_initial_matrix()
+
+ sys_matrix = self.csu.get_matrix()
+ if tfm_opts.use_relative_coords:
+ sys_matrix.translation = initial_matrix.translation.copy()
+ sys_origin = sys_matrix.to_translation()
+ dest_point = self.particles[0].get_location()
+
+ if self.is_normal_visible():
+ p0, x, y, z, _x, _z = \
+ self.get_normal_params(tfm_opts, dest_point)
+
+ # use theme colors?
+ #ThemeView3D.normal
+ #ThemeView3D.vertex_normal
+
+ bgl.glDisable(bgl.GL_LINE_STIPPLE)
+
+ if settings.draw_N:
+ bgl.glColor4f(0, 1, 1, 1)
+ draw_arrow(p0, _x, y, z) # Z (normal)
+ if settings.draw_T1:
+ bgl.glColor4f(1, 0, 1, 1)
+ draw_arrow(p0, y, _z, x) # X (1st tangential)
+ if settings.draw_T2:
+ bgl.glColor4f(1, 1, 0, 1)
+ draw_arrow(p0, _z, x, y) # Y (2nd tangential)
+
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
+
+ if settings.draw_N:
+ bgl.glColor4f(0, 1, 1, 0.25)
+ draw_arrow(p0, _x, y, z) # Z (normal)
+ if settings.draw_T1:
+ bgl.glColor4f(1, 0, 1, 0.25)
+ draw_arrow(p0, y, _z, x) # X (1st tangential)
+ if settings.draw_T2:
+ bgl.glColor4f(1, 1, 0, 0.25)
+ draw_arrow(p0, _z, x, y) # Y (2nd tangential)
+
+ if settings.draw_guides:
+ p0 = dest_point
+ try:
+ p00 = sys_matrix.inverted() * p0
+ except:
+ # this is some degenerate system
+ p00 = p0.copy()
+
+ axes_line_params = [
+ (Vector((0, p00.y, p00.z)), (1, 0, 0)),
+ (Vector((p00.x, 0, p00.z)), (0, 1, 0)),
+ (Vector((p00.x, p00.y, 0)), (0, 0, 1)),
+ ]
+
+ for i in range(3):
+ p1, color = axes_line_params[i]
+ p1 = sys_matrix * p1
+ constrained = (self.axes_coords[i] is not None) or \
+ (not self.allowed_axes[i])
+ alpha = (0.25 if constrained else 1.0)
+ draw_line_hidden_depth(p0, p1, color, \
+ alpha, alpha, False, True)
+
+ # line from origin to cursor
+ p0 = sys_origin
+ p1 = dest_point
+
+ bgl.glEnable(bgl.GL_LINE_STIPPLE)
+ bgl.glColor4f(1, 1, 0, 1)
+
+ draw_line_hidden_depth(p0, p1, (1, 1, 0), 1.0, 0.5, True, True)
+
+ if settings.draw_snap_elements:
+ sui = self.su.implementation
+ if sui.potential_snap_elements and (sui.snap_type == 'EDGE'):
+ bgl.glDisable(bgl.GL_LINE_STIPPLE)
+
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
+
+ bgl.glLineWidth(2)
+ bgl.glColor4f(0, 0, 1, 0.5)
+
+ bgl.glBegin(bgl.GL_LINE_LOOP)
+ for p in sui.potential_snap_elements:
+ bgl.glVertex3f(p[0], p[1], p[2])
+ bgl.glEnd()
+ elif sui.potential_snap_elements and (sui.snap_type == 'FACE'):
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
+
+ bgl.glColor4f(0, 1, 0, 0.5)
+
+ co = sui.potential_snap_elements
+ tris = tessellate_polygon([co])
+ bgl.glBegin(bgl.GL_TRIANGLES)
+ for tri in tris:
+ for vi in tri:
+ p = co[vi]
+ bgl.glVertex3f(p[0], p[1], p[2])
+ bgl.glEnd()
+
+ def draw_2d(self, context):
+ if self.check_v3d_local(context):
+ return
+
+ r = context.region
+ rv3d = context.region_data
+
+ settings = find_settings()
+
+ if settings.draw_snap_elements:
+ sui = self.su.implementation
+
+ snap_points = []
+ if sui.potential_snap_elements and \
+ (sui.snap_type in {'VERTEX', 'VOLUME'}):
+ snap_points.extend(sui.potential_snap_elements)
+ if sui.extra_snap_points:
+ snap_points.extend(sui.extra_snap_points)
+
+ if snap_points:
+ bgl.glEnable(bgl.GL_BLEND)
+
+ bgl.glPointSize(5)
+ bgl.glColor4f(1, 0, 0, 0.5)
+
+ bgl.glBegin(bgl.GL_POINTS)
+ for p in snap_points:
+ p = location_3d_to_region_2d(r, rv3d, p)
+ if p is not None:
+ bgl.glVertex2f(p[0], p[1])
+ bgl.glEnd()
+
+ bgl.glPointSize(1)
+
+ if self.transform_mode == 'MOVE':
+ return
+
+ bgl.glEnable(bgl.GL_LINE_STIPPLE)
+
+ bgl.glLineWidth(1)
+
+ bgl.glColor4f(0, 0, 0, 1)
+ draw_line_2d(self.origin_xy, self.xy)
+
+ bgl.glDisable(bgl.GL_LINE_STIPPLE)
+
+ line_width = 3
+ bgl.glLineWidth(line_width)
+
+ L = 12.0
+ arrow_len = 6.0
+ arrow_width = 8.0
+ arrow_space = 5.0
+
+ Lmax = arrow_space * 2 + L * 2 + line_width
+
+ pos = self.xy.to_2d()
+ normal = self.prev_delta_xy.to_2d().normalized()
+ dist = self.prev_delta_xy.length
+ tangential = Vector((-normal[1], normal[0]))
+
+ if self.transform_mode == 'ROTATE':
+ n_axes = sum(int(v) for v in self.allowed_axes)
+ if n_axes == 2:
+ bgl.glColor4f(0.4, 0.15, 0.15, 1)
+ for sgn in (-1, 1):
+ n = sgn * Vector((0, 1))
+ p0 = pos + arrow_space * n
+ draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
+
+ bgl.glColor4f(0.11, 0.51, 0.11, 1)
+ for sgn in (-1, 1):
+ n = sgn * Vector((1, 0))
+ p0 = pos + arrow_space * n
+ draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
+ else:
+ bgl.glColor4f(0, 0, 0, 1)
+ for sgn in (-1, 1):
+ n = sgn * tangential
+ if dist < Lmax:
+ n *= dist / Lmax
+ p0 = pos + arrow_space * n
+ draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
+ elif self.transform_mode == 'SCALE':
+ bgl.glColor4f(0, 0, 0, 1)
+ for sgn in (-1, 1):
+ n = sgn * normal
+ p0 = pos + arrow_space * n
+ draw_arrow_2d(p0, n, L, arrow_len, arrow_width)
+
+ bgl.glLineWidth(1)
+
+ def draw_axes_coords(self, context, header_size):
+ if self.check_v3d_local(context):
+ return
+
+ if time.time() < (self.click_start + self.click_period):
+ return
+
+ v3d = context.space_data
+
+ userprefs_view = context.user_preferences.view
+
+ tool_settings = context.tool_settings
+
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ localmat = CursorDynamicSettings.local_matrix
+
+ font_id = 0 # default font
+
+ font_size = 11
+ blf.size(font_id, font_size, 72) # font, point size, dpi
+
+ tet = context.user_preferences.themes[0].text_editor
+
+ # Prepare the table...
+ if self.transform_mode == 'MOVE':
+ axis_prefix = ("D" if tfm_opts.use_relative_coords else "")
+ elif self.transform_mode == 'SCALE':
+ axis_prefix = "S"
+ else:
+ axis_prefix = "R"
+ axis_names = ["X", "Y", "Z"]
+
+ axis_cells = []
+ coord_cells = []
+ #caret_cell = TextCell("_", tet.cursor)
+ caret_cell = TextCell("|", tet.cursor)
+
+ try:
+ axes_text = self.get_axes_text()
+
+ for i in range(3):
+ color = tet.space.text
+ alpha = (1.0 if self.allowed_axes[i] else 0.5)
+ text = axis_prefix + axis_names[i] + " : "
+ axis_cells.append(TextCell(text, color, alpha))
+
+ if self.axes_values[i]:
+ if self.axes_eval_success[i]:
+ color = tet.syntax_numbers
+ else:
+ color = tet.syntax_string
+ else:
+ color = tet.space.text
+ text = axes_text[i]
+ coord_cells.append(TextCell(text, color))
+ except Exception as e:
+ print(e)
+
+ mode_cells = []
+
+ try:
+ snap_type = self.su.implementation.snap_type
+ if snap_type is None:
+ color = tet.space.text
+ elif (not self.use_object_centers) or \
+ (snap_type == 'INCREMENT'):
+ color = tet.syntax_numbers
+ else:
+ color = tet.syntax_special
+ text = tool_settings.snap_element
+ if text == 'VOLUME':
+ text = "BBOX"
+ mode_cells.append(TextCell(text, color))
+
+ if self.csu.tou.is_custom:
+ color = tet.space.text
+ else:
+ color = tet.syntax_builtin
+ text = self.csu.tou.get_title()
+ mode_cells.append(TextCell(text, color))
+
+ color = tet.space.text
+ text = self.csu.get_pivot_name(raw=True)
+ if self.use_object_centers:
+ color = tet.syntax_special
+ mode_cells.append(TextCell(text, color))
+ except Exception as e:
+ print(e)
+
+ hdr_w, hdr_h = header_size
+
+ try:
+ xyz_x_start_min = 12
+ xyz_x_start = xyz_x_start_min
+ mode_x_start = 6
+
+ mode_margin = 4
+ xyz_margin = 16
+ blend_margin = 32
+
+ color = tet.space.back
+ bgl.glColor4f(color[0], color[1], color[2], 1.0)
+ draw_rect(0, 0, hdr_w, hdr_h)
+
+ if tool_settings.use_snap_self:
+ x = hdr_w - mode_x_start
+ y = hdr_h / 2
+ cell = mode_cells[0]
+ x -= cell.w
+ y -= cell.h * 0.5
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+ draw_rect(x, y, cell.w, cell.h, 1, True)
+
+ x = hdr_w - mode_x_start
+ y = hdr_h / 2
+ for cell in mode_cells:
+ cell.draw(x, y, (1, 0.5))
+ x -= (cell.w + mode_margin)
+
+ curr_axis_x_start = 0
+ curr_axis_x_end = 0
+ caret_x = 0
+
+ xyz_width = 0
+ for i in range(3):
+ if i == self.current_axis:
+ curr_axis_x_start = xyz_width
+
+ xyz_width += axis_cells[i].w
+
+ if i == self.current_axis:
+ char_offset = 0
+ if self.axes_values[i]:
+ char_offset = blf.dimensions(font_id,
+ coord_cells[i].text[:self.caret_pos])[0]
+ caret_x = xyz_width + char_offset
+
+ xyz_width += coord_cells[i].w
+
+ if i == self.current_axis:
+ curr_axis_x_end = xyz_width
+
+ xyz_width += xyz_margin
+
+ xyz_width = int(xyz_width)
+ xyz_width_ext = xyz_width + blend_margin
+
+ offset = (xyz_x_start + curr_axis_x_end) - hdr_w
+ if offset > 0:
+ xyz_x_start -= offset
+
+ offset = xyz_x_start_min - (xyz_x_start + curr_axis_x_start)
+ if offset > 0:
+ xyz_x_start += offset
+
+ offset = (xyz_x_start + caret_x) - hdr_w
+ if offset > 0:
+ xyz_x_start -= offset
+
+ # somewhy GL_BLEND should be set right here
+ # to actually draw the box with blending %)
+ # (perhaps due to text draw happened before)
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glShadeModel(bgl.GL_SMOOTH)
+ gl_enable(bgl.GL_SMOOTH, True)
+ color = tet.space.back
+ bgl.glBegin(bgl.GL_TRIANGLE_STRIP)
+ bgl.glColor4f(color[0], color[1], color[2], 1.0)
+ bgl.glVertex2i(0, 0)
+ bgl.glVertex2i(0, hdr_h)
+ bgl.glVertex2i(xyz_width, 0)
+ bgl.glVertex2i(xyz_width, hdr_h)
+ bgl.glColor4f(color[0], color[1], color[2], 0.0)
+ bgl.glVertex2i(xyz_width_ext, 0)
+ bgl.glVertex2i(xyz_width_ext, hdr_h)
+ bgl.glEnd()
+
+ x = xyz_x_start
+ y = hdr_h / 2
+ for i in range(3):
+ cell = axis_cells[i]
+ cell.draw(x, y, (0, 0.5))
+ x += cell.w
+
+ cell = coord_cells[i]
+ cell.draw(x, y, (0, 0.5))
+ x += (cell.w + xyz_margin)
+
+ caret_x -= blf.dimensions(font_id, caret_cell.text)[0] * 0.5
+ caret_cell.draw(xyz_x_start + caret_x, y, (0, 0.5))
+
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glShadeModel(bgl.GL_SMOOTH)
+ gl_enable(bgl.GL_SMOOTH, True)
+ color = tet.space.back
+ bgl.glBegin(bgl.GL_TRIANGLE_STRIP)
+ bgl.glColor4f(color[0], color[1], color[2], 1.0)
+ bgl.glVertex2i(0, 0)
+ bgl.glVertex2i(0, hdr_h)
+ bgl.glVertex2i(xyz_x_start_min, 0)
+ bgl.glColor4f(color[0], color[1], color[2], 0.0)
+ bgl.glVertex2i(xyz_x_start_min, hdr_h)
+ bgl.glEnd()
+
+ except Exception as e:
+ print(e)
+
+ return
+
+ # ====== NORMAL SNAPSHOT ====== #
+ def is_normal_visible(self):
+ if self.csu.tou.get() == "Surface":
+ return True
+
+ if self.use_object_centers:
+ return False
+
+ return self.su.implementation.snap_type \
+ not in {None, 'INCREMENT', 'VOLUME'}
+
+ def get_normal_params(self, tfm_opts, dest_point):
+ surf_matrix = self.csu.get_matrix("Surface")
+ if tfm_opts.use_relative_coords:
+ surf_origin = dest_point
+ else:
+ surf_origin = surf_matrix.to_translation()
+
+ m3 = surf_matrix.to_3x3()
+ p0 = surf_origin
+ scl = self.gizmo_scale(p0)
+
+ # Normal and tangential are not always orthogonal
+ # (e.g. when normal is interpolated)
+ x = (m3 * Vector((1, 0, 0))).normalized()
+ y = (m3 * Vector((0, 1, 0))).normalized()
+ z = (m3 * Vector((0, 0, 1))).normalized()
+
+ _x = z.cross(y)
+ _z = y.cross(x)
+
+ return p0, x * scl, y * scl, z * scl, _x * scl, _z * scl
+
+ def make_normal_snapshot(self, scene, tangential=False):
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ dest_point = self.particles[0].get_location()
+
+ if self.is_normal_visible():
+ p0, x, y, z, _x, _z = \
+ self.get_normal_params(tfm_opts, dest_point)
+
+ snapshot = bpy.data.objects.new("normal_snapshot", None)
+
+ if tangential:
+ m = MatrixCompose(_z, y, x, p0)
+ else:
+ m = MatrixCompose(_x, y, z, p0)
+ snapshot.matrix_world = m
+
+ snapshot.empty_draw_type = 'SINGLE_ARROW'
+ #snapshot.empty_draw_type = 'ARROWS'
+ #snapshot.layers = [True] * 20 # ?
+ scene.objects.link(snapshot)
+#============================================================================#
+
+
+class Particle:
+ pass
+
+class View3D_Cursor(Particle):
+ def __init__(self, context):
+ assert context.space_data.type == 'VIEW_3D'
+ self.v3d = context.space_data
+ self.initial_pos = self.get_location()
+ self.initial_matrix = Matrix.Translation(self.initial_pos)
+
+ def revert(self):
+ self.set_location(self.initial_pos)
+
+ def get_location(self):
+ return get_cursor_location(v3d=self.v3d)
+
+ def set_location(self, value):
+ set_cursor_location(Vector(value), v3d=self.v3d)
+
+ def get_rotation(self):
+ return Quaternion()
+
+ def set_rotation(self, value):
+ pass
+
+ def get_scale(self):
+ return Vector((1.0, 1.0, 1.0))
+
+ def set_scale(self, value):
+ pass
+
+ def get_matrix(self):
+ return Matrix.Translation(self.get_location())
+
+ def set_matrix(self, value):
+ self.set_location(value.to_translation())
+
+ def get_initial_matrix(self):
+ return self.initial_matrix
+
+class View3D_Object(Particle):
+ def __init__(self, obj):
+ self.obj = obj
+
+ def get_location(self):
+ # obj.location seems to be in parent's system...
+ # or even maybe not bounded by constraints %)
+ return self.obj.matrix_world.to_translation()
+
+class View3D_EditMesh_Vertex(Particle):
+ pass
+
+class View3D_EditMesh_Edge(Particle):
+ pass
+
+class View3D_EditMesh_Face(Particle):
+ pass
+
+class View3D_EditSpline_Point(Particle):
+ pass
+
+class View3D_EditSpline_BezierPoint(Particle):
+ pass
+
+class View3D_EditSpline_BezierHandle(Particle):
+ pass
+
+class View3D_EditMeta_Element(Particle):
+ pass
+
+class View3D_EditBone_Bone(Particle):
+ pass
+
+class View3D_EditBone_HeadTail(Particle):
+ pass
+
+class View3D_PoseBone(Particle):
+ pass
+
+class UV_Cursor(Particle):
+ pass
+
+class UV_Vertex(Particle):
+ pass
+
+class UV_Edge(Particle):
+ pass
+
+class UV_Face(Particle):
+ pass
+
+# Other types:
+# NLA / Dopesheet / Graph editor ...
+
+# Particles are used in the following situations:
+# - as subjects of transformation
+# - as reference point(s) for cursor transformation
+# Note: particles 'dragged' by Proportional Editing
+# are a separate issue (they can come and go).
+def gather_particles(**kwargs):
+ context = kwargs.get("context", bpy.context)
+
+ area_type = kwargs.get("area_type", context.area.type)
+
+ scene = kwargs.get("scene", context.scene)
+
+ space_data = kwargs.get("space_data", context.space_data)
+ region_data = kwargs.get("region_data", context.region_data)
+
+ particles = []
+ pivots = {}
+ normal_system = None
+
+ active_element = None
+ cursor_pos = None
+ median = None
+
+ if area_type == 'VIEW_3D':
+ context_mode = kwargs.get("context_mode", context.mode)
+
+ selected_objects = kwargs.get("selected_objects",
+ context.selected_objects)
+
+ active_object = kwargs.get("active_object",
+ context.active_object)
+
+ if context_mode == 'OBJECT':
+ for obj in selected_objects:
+ particle = View3D_Object(obj)
+ particles.append(particle)
+
+ if active_object:
+ active_element = active_object.\
+ matrix_world.to_translation()
+
+ # On Undo/Redo scene hash value is changed ->
+ # -> the monitor tries to update the CSU ->
+ # -> object.mode_set seem to somehow conflict
+ # with Undo/Redo mechanisms.
+ elif active_object and active_object.data and \
+ (context_mode in {
+ 'EDIT_MESH', 'EDIT_METABALL',
+ 'EDIT_CURVE', 'EDIT_SURFACE',
+ 'EDIT_ARMATURE', 'POSE'}):
+
+ m = active_object.matrix_world
+
+ positions = []
+ normal = Vector((0, 0, 0))
+
+ if context_mode == 'EDIT_MESH':
+ bm = bmesh.from_edit_mesh(active_object.data)
+
+ if bm.select_history:
+ elem = bm.select_history[-1]
+ if isinstance(elem, bmesh.types.BMVert):
+ active_element = elem.co.copy()
+ else:
+ active_element = Vector()
+ for v in elem.verts:
+ active_element += v.co
+ active_element *= 1.0 / len(elem.verts)
+
+ for v in bm.verts:
+ if v.select:
+ positions.append(v.co)
+ normal += v.normal
+
+ # mimic Blender's behavior (as of now,
+ # order of selection is ignored)
+ if len(positions) == 2:
+ normal = positions[1] - positions[0]
+ elif len(positions) == 3:
+ a = positions[0] - positions[1]
+ b = positions[2] - positions[1]
+ normal = a.cross(b)
+ elif context_mode == 'EDIT_METABALL':
+ active_elem = active_object.data.elements.active
+ if active_elem:
+ active_element = active_elem.co.copy()
+ active_element = active_object.\
+ matrix_world * active_element
+
+ # Currently there is no API for element.select
+ #for element in active_object.data.elements:
+ # if element.select:
+ # positions.append(element.co)
+ elif context_mode == 'EDIT_ARMATURE':
+ # active bone seems to have the same pivot
+ # as median of the selection
+ '''
+ active_bone = active_object.data.edit_bones.active
+ if active_bone:
+ active_element = active_bone.head + \
+ active_bone.tail
+ active_element = active_object.\
+ matrix_world * active_element
+ '''
+
+ for bone in active_object.data.edit_bones:
+ if bone.select_head:
+ positions.append(bone.head)
+ if bone.select_tail:
+ positions.append(bone.tail)
+ elif context_mode == 'POSE':
+ active_bone = active_object.data.bones.active
+ if active_bone:
+ active_element = active_bone.\
+ matrix_local.translation.to_3d()
+ active_element = active_object.\
+ matrix_world * active_element
+
+ # consider only topmost parents
+ bones = set()
+ for bone in active_object.data.bones:
+ if bone.select:
+ bones.add(bone)
+
+ parents = set()
+ for bone in bones:
+ if not set(bone.parent_recursive).intersection(bones):
+ parents.add(bone)
+
+ for bone in parents:
+ positions.append(bone.matrix_local.translation.to_3d())
+ else:
+ for spline in active_object.data.splines:
+ for point in spline.bezier_points:
+ if point.select_control_point:
+ positions.append(point.co)
+ else:
+ if point.select_left_handle:
+ positions.append(point.handle_left)
+ if point.select_right_handle:
+ positions.append(point.handle_right)
+
+ n = None
+ nL = point.co - point.handle_left
+ nR = point.co - point.handle_right
+ #nL = point.handle_left.copy()
+ #nR = point.handle_right.copy()
+ if point.select_control_point:
+ n = nL + nR
+ elif point.select_left_handle or \
+ point.select_right_handle:
+ n = nL + nR
+ else:
+ if point.select_left_handle:
+ n = -nL
+ if point.select_right_handle:
+ n = nR
+
+ if n is not None:
+ if n.length_squared < epsilon:
+ n = -nL
+ normal += n.normalized()
+
+ for point in spline.points:
+ if point.select:
+ positions.append(point.co)
+
+ if len(positions) != 0:
+ if normal.length_squared < epsilon:
+ normal = Vector((0, 0, 1))
+ normal.rotate(m)
+ normal.normalize()
+
+ if (1.0 - abs(normal.z)) < epsilon:
+ t1 = Vector((1, 0, 0))
+ else:
+ t1 = Vector((0, 0, 1)).cross(normal)
+ t2 = t1.cross(normal)
+ normal_system = MatrixCompose(t1, t2, normal)
+
+ median, bbox_center = calc_median_bbox_pivots(positions)
+ median = m * median
+ bbox_center = m * bbox_center
+
+ # Currently I don't know how to get active mesh element
+ if active_element is None:
+ if context_mode == 'EDIT_ARMATURE':
+ # Somewhy EDIT_ARMATURE has such behavior
+ active_element = bbox_center
+ else:
+ active_element = median
+ else:
+ if active_element is None:
+ active_element = active_object.\
+ matrix_world.to_translation()
+
+ median = active_element
+ bbox_center = active_element
+
+ normal_system = active_object.matrix_world.to_3x3()
+ normal_system.col[0].normalize()
+ normal_system.col[1].normalize()
+ normal_system.col[2].normalize()
+ else:
+ # paint/sculpt, etc.?
+ particle = View3D_Object(active_object)
+ particles.append(particle)
+
+ if active_object:
+ active_element = active_object.\
+ matrix_world.to_translation()
+
+ cursor_pos = get_cursor_location(v3d=space_data)
+
+ #elif area_type == 'IMAGE_EDITOR':
+ # currently there is no way to get UV editor's
+ # offset (and maybe some other parameters
+ # required to implement these operators)
+ #cursor_pos = space_data.uv_editor.cursor_location
+
+ #elif area_type == 'EMPTY':
+ #elif area_type == 'GRAPH_EDITOR':
+ #elif area_type == 'OUTLINER':
+ #elif area_type == 'PROPERTIES':
+ #elif area_type == 'FILE_BROWSER':
+ #elif area_type == 'INFO':
+ #elif area_type == 'SEQUENCE_EDITOR':
+ #elif area_type == 'TEXT_EDITOR':
+ #elif area_type == 'AUDIO_WINDOW':
+ #elif area_type == 'DOPESHEET_EDITOR':
+ #elif area_type == 'NLA_EDITOR':
+ #elif area_type == 'SCRIPTS_WINDOW':
+ #elif area_type == 'TIMELINE':
+ #elif area_type == 'NODE_EDITOR':
+ #elif area_type == 'LOGIC_EDITOR':
+ #elif area_type == 'CONSOLE':
+ #elif area_type == 'USER_PREFERENCES':
+
+ else:
+ print("gather_particles() not implemented for '{}'".\
+ format(area_type))
+ return None, None
+
+ # 'INDIVIDUAL_ORIGINS' is not handled here
+
+ if cursor_pos:
+ pivots['CURSOR'] = cursor_pos.copy()
+
+ if active_element:
+ # in v3d: ACTIVE_ELEMENT
+ pivots['ACTIVE'] = active_element.copy()
+
+ if (len(particles) != 0) and (median is None):
+ positions = (p.get_location() for p in particles)
+ median, bbox_center = calc_median_bbox_pivots(positions)
+
+ if median:
+ # in v3d: MEDIAN_POINT, in UV editor: MEDIAN
+ pivots['MEDIAN'] = median.copy()
+ # in v3d: BOUNDING_BOX_CENTER, in UV editor: CENTER
+ pivots['CENTER'] = bbox_center.copy()
+
+ csu = CoordinateSystemUtility(scene, space_data, region_data, \
+ pivots, normal_system)
+
+ return particles, csu
+
+def calc_median_bbox_pivots(positions):
+ median = None # pos can be 3D or 2D
+ bbox = [None, None]
+
+ n = 0
+ for pos in positions:
+ extend_bbox(bbox, pos)
+ try:
+ median += pos
+ except:
+ median = pos.copy()
+ n += 1
+
+ median = median / n
+ bbox_center = (Vector(bbox[0]) + Vector(bbox[1])) * 0.5
+
+ return median, bbox_center
+
+def extend_bbox(bbox, pos):
+ try:
+ bbox[0] = tuple(min(e0, e1) for e0, e1 in zip(bbox[0], pos))
+ bbox[1] = tuple(max(e0, e1) for e0, e1 in zip(bbox[1], pos))
+ except:
+ bbox[0] = tuple(pos)
+ bbox[1] = tuple(pos)
+
+
+# ====== COORDINATE SYSTEM UTILITY ====== #
+class CoordinateSystemUtility:
+ pivot_name_map = {
+ 'CENTER':'CENTER',
+ 'BOUNDING_BOX_CENTER':'CENTER',
+ 'MEDIAN':'MEDIAN',
+ 'MEDIAN_POINT':'MEDIAN',
+ 'CURSOR':'CURSOR',
+ 'INDIVIDUAL_ORIGINS':'INDIVIDUAL',
+ 'ACTIVE_ELEMENT':'ACTIVE',
+ 'WORLD':'WORLD',
+ 'SURFACE':'SURFACE', # ?
+ 'BOOKMARK':'BOOKMARK',
+ }
+ pivot_v3d_map = {
+ 'CENTER':'BOUNDING_BOX_CENTER',
+ 'MEDIAN':'MEDIAN_POINT',
+ 'CURSOR':'CURSOR',
+ 'INDIVIDUAL':'INDIVIDUAL_ORIGINS',
+ 'ACTIVE':'ACTIVE_ELEMENT',
+ }
+
+ def __init__(self, scene, space_data, region_data, \
+ pivots, normal_system):
+ self.space_data = space_data
+ self.region_data = region_data
+
+ if space_data.type == 'VIEW_3D':
+ self.pivot_map_inv = self.pivot_v3d_map
+
+ self.tou = TransformOrientationUtility(
+ scene, space_data, region_data)
+ self.tou.normal_system = normal_system
+
+ self.pivots = pivots
+
+ # Assigned by caller (for cursor or selection)
+ self.source_pos = None
+ self.source_rot = None
+ self.source_scale = None
+
+ def set_orientation(self, name):
+ self.tou.set(name)
+
+ def set_pivot(self, pivot):
+ self.space_data.pivot_point = self.pivot_map_inv[pivot]
+
+ def get_pivot_name(self, name=None, relative=None, raw=False):
+ pivot = self.pivot_name_map[self.space_data.pivot_point]
+ if raw:
+ return pivot
+
+ if not name:
+ name = self.tou.get()
+
+ if relative is None:
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+ relative = tfm_opts.use_relative_coords
+
+ if relative:
+ pivot = "RELATIVE"
+ elif (name == 'GLOBAL') or (pivot == 'WORLD'):
+ pivot = 'WORLD'
+ elif (name == "Surface") or (pivot == 'SURFACE'):
+ pivot = "SURFACE"
+
+ return pivot
+
+ def get_origin(self, name=None, relative=None, pivot=None):
+ if not pivot:
+ pivot = self.get_pivot_name(name, relative)
+
+ if relative or (pivot == "RELATIVE"):
+ # "relative" parameter overrides "pivot"
+ return self.source_pos
+ elif pivot == 'WORLD':
+ return Vector()
+ elif pivot == "SURFACE":
+ runtime_settings = find_runtime_settings()
+ return Vector(runtime_settings.surface_pos)
+ else:
+ if pivot == 'INDIVIDUAL':
+ pivot = 'MEDIAN'
+
+ #if pivot == 'ACTIVE':
+ # print(self.pivots)
+
+ try:
+ return self.pivots[pivot]
+ except:
+ return Vector()
+
+ def get_matrix(self, name=None, relative=None, pivot=None):
+ if not name:
+ name = self.tou.get()
+
+ matrix = self.tou.get_matrix(name)
+
+ if isinstance(pivot, Vector):
+ pos = pivot
+ else:
+ pos = self.get_origin(name, relative, pivot)
+
+ return to_matrix4x4(matrix, pos)
+
+# ====== TRANSFORM ORIENTATION UTILITIES ====== #
+class TransformOrientationUtility:
+ special_systems = {"Surface", "Scaled"}
+ predefined_systems = {
+ 'GLOBAL', 'LOCAL', 'VIEW', 'NORMAL', 'GIMBAL',
+ "Scaled", "Surface",
+ }
+
+ def __init__(self, scene, v3d, rv3d):
+ self.scene = scene
+ self.v3d = v3d
+ self.rv3d = rv3d
+
+ self.custom_systems = [item for item in scene.orientations \
+ if item.name not in self.special_systems]
+
+ self.is_custom = False
+ self.custom_id = -1
+
+ # This is calculated elsewhere
+ self.normal_system = None
+
+ self.set(v3d.transform_orientation)
+
+ def get(self):
+ return self.transform_orientation
+
+ def get_title(self):
+ if self.is_custom:
+ return self.transform_orientation
+
+ name = self.transform_orientation
+ return name[:1].upper() + name[1:].lower()
+
+ def set(self, name, set_v3d=True):
+ if isinstance(name, int):
+ n = len(self.custom_systems)
+ if n == 0:
+ # No custom systems, do nothing
+ return
+
+ increment = name
+
+ if self.is_custom:
+ # If already custom, switch to next custom system
+ self.custom_id = (self.custom_id + increment) % n
+
+ self.is_custom = True
+
+ name = self.custom_systems[self.custom_id].name
+ else:
+ self.is_custom = name not in self.predefined_systems
+
+ if self.is_custom:
+ self.custom_id = next((i for i, v in \
+ enumerate(self.custom_systems) if v.name == name), -1)
+
+ if name in self.special_systems:
+ # Ensure such system exists
+ self.get_custom(name)
+
+ self.transform_orientation = name
+
+ if set_v3d:
+ self.v3d.transform_orientation = name
+
+ def get_matrix(self, name=None):
+ active_obj = self.scene.objects.active
+
+ if not name:
+ name = self.transform_orientation
+
+ if self.is_custom:
+ matrix = self.custom_systems[self.custom_id].matrix.copy()
+ else:
+ if (name == 'VIEW') and self.rv3d:
+ matrix = self.rv3d.view_rotation.to_matrix()
+ elif name == "Surface":
+ matrix = self.get_custom(name).matrix.copy()
+ elif (name == 'GLOBAL') or (not active_obj):
+ matrix = Matrix().to_3x3()
+ elif (name == 'NORMAL') and self.normal_system:
+ matrix = self.normal_system.copy()
+ else:
+ matrix = active_obj.matrix_world.to_3x3()
+ if name == "Scaled":
+ self.get_custom(name).matrix = matrix
+ else: # 'LOCAL', 'GIMBAL', ['NORMAL'] for now
+ matrix[0].normalize()
+ matrix[1].normalize()
+ matrix[2].normalize()
+
+ return matrix
+
+ def get_custom(self, name):
+ try:
+ return self.scene.orientations[name]
+ except:
+ return create_transform_orientation(
+ self.scene, name, Matrix())
+
+# Is there a less cumbersome way to create transform orientation?
+def create_transform_orientation(scene, name=None, matrix=None):
+ active_obj = scene.objects.active
+ prev_mode = None
+
+ if active_obj:
+ prev_mode = active_obj.mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+ else:
+ bpy.ops.object.add()
+
+ # ATTENTION! This uses context's scene
+ bpy.ops.transform.create_orientation()
+
+ tfm_orient = scene.orientations[-1]
+
+ if name is not None:
+ basename = name
+ i = 1
+ while name in scene.orientations:
+ name = "%s.%03i" % (basename, i)
+ i += 1
+ tfm_orient.name = name
+
+ if matrix:
+ tfm_orient.matrix = matrix.to_3x3()
+
+ if active_obj:
+ bpy.ops.object.mode_set(mode=prev_mode)
+ else:
+ bpy.ops.object.delete()
+
+ return tfm_orient
+
+# ====== VIEW UTILITY CLASS ====== #
+class ViewUtility:
+ methods = dict(
+ get_locks = lambda: {},
+ set_locks = lambda locks: None,
+ get_position = lambda: Vector(),
+ set_position = lambda: None,
+ get_rotation = lambda: Quaternion(),
+ get_direction = lambda: Vector((0, 0, 1)),
+ get_viewpoint = lambda: Vector(),
+ get_matrix = lambda: Matrix(),
+ get_point = lambda xy, pos: \
+ Vector((xy[0], xy[1], 0)),
+ get_ray = lambda xy: tuple(
+ Vector((xy[0], xy[1], 0)),
+ Vector((xy[0], xy[1], 1)),
+ False),
+ )
+
+ def __init__(self, region, space_data, region_data):
+ self.region = region
+ self.space_data = space_data
+ self.region_data = region_data
+
+ if space_data.type == 'VIEW_3D':
+ self.implementation = View3DUtility(
+ region, space_data, region_data)
+ else:
+ self.implementation = None
+
+ if self.implementation:
+ for name in self.methods:
+ setattr(self, name,
+ getattr(self.implementation, name))
+ else:
+ for name, value in self.methods.items():
+ setattr(self, name, value)
+
+class View3DUtility:
+ lock_types = {"lock_cursor":False, "lock_object":None, "lock_bone":""}
+
+ # ====== INITIALIZATION / CLEANUP ====== #
+ def __init__(self, region, space_data, region_data):
+ self.region = region
+ self.space_data = space_data
+ self.region_data = region_data
+
+ # ====== GET VIEW MATRIX AND ITS COMPONENTS ====== #
+ def get_locks(self):
+ v3d = self.space_data
+ return {k:getattr(v3d, k) for k in self.lock_types}
+
+ def set_locks(self, locks):
+ v3d = self.space_data
+ for k in self.lock_types:
+ setattr(v3d, k, locks.get(k, self.lock_types[k]))
+
+ def _get_lock_obj_bone(self):
+ v3d = self.space_data
+
+ obj = v3d.lock_object
+ if not obj:
+ return None, None
+
+ if v3d.lock_bone:
+ try:
+ # this is not tested!
+ if obj.mode == 'EDIT':
+ bone = obj.data.edit_bones[v3d.lock_bone]
+ else:
+ bone = obj.data.bones[v3d.lock_bone]
+ except:
+ bone = None
+
+ return obj, bone
+
+ # TODO: learn how to get these values from
+ # rv3d.perspective_matrix and rv3d.view_matrix ?
+ def get_position(self, no_locks=False):
+ v3d = self.space_data
+ rv3d = self.region_data
+
+ if no_locks:
+ return rv3d.view_location.copy()
+
+ # rv3d.perspective_matrix and rv3d.view_matrix
+ # seem to have some weird translation components %)
+
+ if rv3d.view_perspective == 'CAMERA':
+ p = v3d.camera.matrix_world.to_translation()
+ d = self.get_direction()
+ return p + d * rv3d.view_distance
+ else:
+ if v3d.lock_object:
+ obj, bone = self._get_lock_obj_bone()
+ if bone:
+ return (obj.matrix_world * bone.matrix).to_translation()
+ else:
+ return obj.matrix_world.to_translation()
+ elif v3d.lock_cursor:
+ return get_cursor_location(v3d=v3d)
+ else:
+ return rv3d.view_location.copy()
+
+ def set_position(self, pos, no_locks=False):
+ v3d = self.space_data
+ rv3d = self.region_data
+
+ pos = pos.copy()
+
+ if no_locks:
+ rv3d.view_location = pos
+ return
+
+ if rv3d.view_perspective == 'CAMERA':
+ d = self.get_direction()
+ v3d.camera.matrix_world.translation = pos - d * rv3d.view_distance
+ else:
+ if v3d.lock_object:
+ obj, bone = self._get_lock_obj_bone()
+ if bone:
+ try:
+ bone.matrix.translation = \
+ obj.matrix_world.inverted() * pos
+ except:
+ # this is some degenerate object
+ bone.matrix.translation = pos
+ else:
+ obj.matrix_world.translation = pos
+ elif v3d.lock_cursor:
+ set_cursor_location(pos, v3d=v3d)
+ else:
+ rv3d.view_location = pos
+
+ def get_rotation(self):
+ v3d = self.space_data
+ rv3d = self.region_data
+
+ if rv3d.view_perspective == 'CAMERA':
+ return v3d.camera.matrix_world.to_quaternion()
+ else:
+ return rv3d.view_rotation
+
+ def get_direction(self):
+ # Camera (as well as viewport) looks in the direction of -Z;
+ # Y is up, X is left
+ d = self.get_rotation() * Vector((0, 0, -1))
+ d.normalize()
+ return d
+
+ def get_viewpoint(self):
+ v3d = self.space_data
+ rv3d = self.region_data
+
+ if rv3d.view_perspective == 'CAMERA':
+ return v3d.camera.matrix_world.to_translation()
+ else:
+ p = self.get_position()
+ d = self.get_direction()
+ return p - d * rv3d.view_distance
+
+ def get_matrix(self):
+ m = self.get_rotation().to_matrix()
+ m.resize_4x4()
+ m.translation = self.get_viewpoint()
+ return m
+
+ def get_point(self, xy, pos):
+ region = self.region
+ rv3d = self.region_data
+ return region_2d_to_location_3d(region, rv3d, xy, pos)
+
+ def get_ray(self, xy):
+ region = self.region
+ v3d = self.space_data
+ rv3d = self.region_data
+
+ viewPos = self.get_viewpoint()
+ viewDir = self.get_direction()
+
+ near = viewPos + viewDir * v3d.clip_start
+ far = viewPos + viewDir * v3d.clip_end
+
+ a = region_2d_to_location_3d(region, rv3d, xy, near)
+ b = region_2d_to_location_3d(region, rv3d, xy, far)
+
+ # When viewed from in-scene camera, near and far
+ # planes clip geometry even in orthographic mode.
+ clip = rv3d.is_perspective or (rv3d.view_perspective == 'CAMERA')
+
+ return a, b, clip
+
+# ====== SNAP UTILITY CLASS ====== #
+class SnapUtility:
+ def __init__(self, context):
+ if context.area.type == 'VIEW_3D':
+ v3d = context.space_data
+ shade = v3d.viewport_shade
+ self.implementation = Snap3DUtility(context.scene, shade)
+ self.implementation.update_targets(
+ context.visible_objects, [])
+
+ def dispose(self):
+ self.implementation.dispose()
+
+ def update_targets(self, to_include, to_exclude):
+ self.implementation.update_targets(to_include, to_exclude)
+
+ def set_modes(self, **kwargs):
+ return self.implementation.set_modes(**kwargs)
+
+ def snap(self, *args, **kwargs):
+ return self.implementation.snap(*args, **kwargs)
+
+class SnapUtilityBase:
+ def __init__(self):
+ self.targets = set()
+ # TODO: set to current blend settings?
+ self.interpolation = 'NEVER'
+ self.editmode = False
+ self.snap_type = None
+ self.projection = [None, None, None]
+ self.potential_snap_elements = None
+ self.extra_snap_points = None
+
+ def update_targets(self, to_include, to_exclude):
+ self.targets.update(to_include)
+ self.targets.difference_update(to_exclude)
+
+ def set_modes(self, **kwargs):
+ if "use_relative_coords" in kwargs:
+ self.use_relative_coords = kwargs["use_relative_coords"]
+ if "interpolation" in kwargs:
+ # NEVER, ALWAYS, SMOOTH
+ self.interpolation = kwargs["interpolation"]
+ if "editmode" in kwargs:
+ self.editmode = kwargs["editmode"]
+ if "snap_align" in kwargs:
+ self.snap_align = kwargs["snap_align"]
+ if "snap_type" in kwargs:
+ # 'INCREMENT', 'VERTEX', 'EDGE', 'FACE', 'VOLUME'
+ self.snap_type = kwargs["snap_type"]
+ if "axes_coords" in kwargs:
+ # none, point, line, plane
+ self.axes_coords = kwargs["axes_coords"]
+
+ # ====== CURSOR REPOSITIONING ====== #
+ def snap(self, xy, src_matrix, initial_matrix, do_raycast, \
+ alt_snap, vu, csu, modify_Surface, use_object_centers):
+
+ grid_step = self.grid_steps[alt_snap]
+
+ su = self
+ use_relative_coords = su.use_relative_coords
+ snap_align = su.snap_align
+ axes_coords = su.axes_coords
+ snap_type = su.snap_type
+
+ runtime_settings = find_runtime_settings()
+
+ matrix = src_matrix.to_3x3()
+ pos = src_matrix.to_translation().copy()
+
+ sys_matrix = csu.get_matrix()
+ if use_relative_coords:
+ sys_matrix.translation = initial_matrix.translation.copy()
+
+ # Axes of freedom and line/plane parameters
+ start = Vector(((0 if v is None else v) for v in axes_coords))
+ direction = Vector(((v is not None) for v in axes_coords))
+ axes_of_freedom = 3 - int(sum(direction))
+
+ # do_raycast is False when mouse is not moving
+ if do_raycast:
+ su.hide_bbox(True)
+
+ self.potential_snap_elements = None
+ self.extra_snap_points = None
+
+ set_stick_obj(csu.tou.scene, None)
+
+ raycast = None
+ snap_to_obj = (snap_type != 'INCREMENT') #or use_object_centers
+ snap_to_obj = snap_to_obj and (snap_type is not None)
+ if snap_to_obj:
+ a, b, clip = vu.get_ray(xy)
+ view_dir = vu.get_direction()
+ raycast = su.snap_raycast(a, b, clip, view_dir, csu, alt_snap)
+
+ if raycast:
+ surf_matrix, face_id, obj, orig_obj = raycast
+
+ if not use_object_centers:
+ self.potential_snap_elements = [
+ (obj.matrix_world * obj.data.vertices[vi].co)
+ for vi in obj.data.tessfaces[face_id].vertices
+ ]
+
+ if use_object_centers:
+ self.extra_snap_points = \
+ [obj.matrix_world.to_translation()]
+ elif alt_snap:
+ pse = self.potential_snap_elements
+ n = len(pse)
+ if self.snap_type == 'EDGE':
+ self.extra_snap_points = []
+ for i in range(n):
+ v0 = pse[i]
+ v1 = pse[(i + 1) % n]
+ self.extra_snap_points.append((v0 + v1) / 2)
+ elif self.snap_type == 'FACE':
+ self.extra_snap_points = []
+ v0 = Vector()
+ for v1 in pse:
+ v0 += v1
+ self.extra_snap_points.append(v0 / n)
+
+ if snap_align:
+ matrix = surf_matrix.to_3x3()
+
+ if not use_object_centers:
+ pos = surf_matrix.to_translation()
+ else:
+ pos = orig_obj.matrix_world.to_translation()
+
+ try:
+ local_pos = orig_obj.matrix_world.inverted() * pos
+ except:
+ # this is some degenerate object
+ local_pos = pos
+
+ set_stick_obj(csu.tou.scene, orig_obj.name, local_pos)
+
+ modify_Surface = modify_Surface and \
+ (snap_type != 'VOLUME') and (not use_object_centers)
+
+ # === Update "Surface" orientation === #
+ if modify_Surface:
+ # Use raycast[0], not matrix! If snap_align == False,
+ # matrix will be src_matrix!
+ coordsys = csu.tou.get_custom("Surface")
+ coordsys.matrix = surf_matrix.to_3x3()
+ runtime_settings.surface_pos = pos
+ if csu.tou.get() == "Surface":
+ sys_matrix = to_matrix4x4(matrix, pos)
+ else:
+ if axes_of_freedom == 0:
+ # Constrained in all axes, can't move.
+ pass
+ elif axes_of_freedom == 3:
+ # Not constrained, move in view plane.
+ pos = vu.get_point(xy, pos)
+ else:
+ a, b, clip = vu.get_ray(xy)
+ view_dir = vu.get_direction()
+
+ start = sys_matrix * start
+
+ if axes_of_freedom == 1:
+ direction = Vector((1, 1, 1)) - direction
+ direction.rotate(sys_matrix)
+
+ if axes_of_freedom == 2:
+ # Constrained in one axis.
+ # Find intersection with plane.
+ i_p = intersect_line_plane(a, b, start, direction)
+ if i_p is not None:
+ pos = i_p
+ elif axes_of_freedom == 1:
+ # Constrained in two axes.
+ # Find nearest point to line.
+ i_p = intersect_line_line(a, b, start,
+ start + direction)
+ if i_p is not None:
+ pos = i_p[1]
+ #end if do_raycast
+
+ try:
+ sys_matrix_inv = sys_matrix.inverted()
+ except:
+ # this is some degenerate system
+ sys_matrix_inv = Matrix()
+
+ _pos = sys_matrix_inv * pos
+
+ # don't snap when mouse hasn't moved
+ if (snap_type == 'INCREMENT') and do_raycast:
+ for i in range(3):
+ _pos[i] = round_step(_pos[i], grid_step)
+
+ for i in range(3):
+ if axes_coords[i] is not None:
+ _pos[i] = axes_coords[i]
+
+ if (snap_type == 'INCREMENT') or (axes_of_freedom != 3):
+ pos = sys_matrix * _pos
+
+ res_matrix = to_matrix4x4(matrix, pos)
+
+ CursorDynamicSettings.local_matrix = \
+ sys_matrix_inv * res_matrix
+
+ return res_matrix
+
+class Snap3DUtility(SnapUtilityBase):
+ grid_steps = {False:1.0, True:0.1}
+
+ cube_verts = [Vector((i, j, k))
+ for i in (-1, 1)
+ for j in (-1, 1)
+ for k in (-1, 1)]
+
+ def __init__(self, scene, shade):
+ SnapUtilityBase.__init__(self)
+
+ convert_types = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}
+ self.cache = MeshCache(scene, convert_types)
+
+ # ? seems that dict is enough
+ self.bbox_cache = {}#collections.OrderedDict()
+ self.sys_matrix_key = [0.0] * 9
+
+ bm = prepare_gridbox_mesh(subdiv=2)
+ mesh = bpy.data.meshes.new(tmp_name)
+ bm.to_mesh(mesh)
+ mesh.update(calc_tessface=True)
+ #mesh.calc_tessface()
+
+ self.bbox_obj = self.cache._make_obj(mesh, None)
+ self.bbox_obj.hide = True
+ self.bbox_obj.draw_type = 'WIRE'
+ self.bbox_obj.name = "BoundBoxSnap"
+
+ self.shade_bbox = (shade == 'BOUNDBOX')
+
+ def update_targets(self, to_include, to_exclude):
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+ only_solid = tfm_opts.snap_only_to_solid
+
+ # Ensure this is a set and not some other
+ # type of collection
+ to_exclude = set(to_exclude)
+
+ for target in to_include:
+ if only_solid and ((target.draw_type == 'BOUNDS') \
+ or (target.draw_type == 'WIRE')):
+ to_exclude.add(target)
+
+ SnapUtilityBase.update_targets(self, to_include, to_exclude)
+
+ def dispose(self):
+ self.hide_bbox(True)
+
+ mesh = self.bbox_obj.data
+ bpy.data.objects.remove(self.bbox_obj)
+ bpy.data.meshes.remove(mesh)
+
+ self.cache.clear()
+
+ def hide_bbox(self, hide):
+ if self.bbox_obj.hide == hide:
+ return
+
+ self.bbox_obj.hide = hide
+
+ # We need to unlink bbox until required to show it,
+ # because otherwise outliner will blink each
+ # time cursor is clicked
+ if hide:
+ self.cache.scene.objects.unlink(self.bbox_obj)
+ else:
+ self.cache.scene.objects.link(self.bbox_obj)
+
+ def get_bbox_obj(self, obj, sys_matrix, sys_matrix_inv, is_local):
+ if is_local:
+ bbox = None
+ else:
+ bbox = self.bbox_cache.get(obj, None)
+
+ if bbox is None:
+ m = obj.matrix_world
+ if is_local:
+ sys_matrix = m.copy()
+ try:
+ sys_matrix_inv = sys_matrix.inverted()
+ except Exception:
+ # this is some degenerate system
+ sys_matrix_inv = Matrix()
+ m_combined = sys_matrix_inv * m
+ bbox = [None, None]
+
+ variant = ('RAW' if (self.editmode and
+ (obj.type == 'MESH') and (obj.mode == 'EDIT'))
+ else 'PREVIEW')
+ mesh_obj = self.cache.get(obj, variant, reuse=False)
+ if (mesh_obj is None) or self.shade_bbox or \
+ (obj.draw_type == 'BOUNDS'):
+ if is_local:
+ bbox = [(-1, -1, -1), (1, 1, 1)]
+ else:
+ for p in self.cube_verts:
+ extend_bbox(bbox, m_combined * p.copy())
+ elif is_local:
+ bbox = [mesh_obj.bound_box[0], mesh_obj.bound_box[6]]
+ else:
+ for v in mesh_obj.data.vertices:
+ extend_bbox(bbox, m_combined * v.co.copy())
+
+ bbox = (Vector(bbox[0]), Vector(bbox[1]))
+
+ if not is_local:
+ self.bbox_cache[obj] = bbox
+
+ half = (bbox[1] - bbox[0]) * 0.5
+
+ m = MatrixCompose(half[0], half[1], half[2])
+ m = sys_matrix.to_3x3() * m
+ m.resize_4x4()
+ m.translation = sys_matrix * (bbox[0] + half)
+ self.bbox_obj.matrix_world = m
+
+ return self.bbox_obj
+
+ # TODO: ?
+ # - Sort snap targets according to raycasted distance?
+ # - Ignore targets if their bounding sphere is further
+ # than already picked position?
+ # Perhaps these "optimizations" aren't worth the overhead.
+
+ def raycast(self, a, b, clip, view_dir, is_bbox, \
+ sys_matrix, sys_matrix_inv, is_local, x_ray):
+ # If we need to interpolate normals or snap to
+ # vertices/edges, we must convert mesh.
+ #force = (self.interpolation != 'NEVER') or \
+ # (self.snap_type in {'VERTEX', 'EDGE'})
+ # Actually, we have to always convert, since
+ # we need to get face at least to find tangential.
+ force = True
+ edit = self.editmode
+
+ res = None
+ L = None
+
+ for obj in self.targets:
+ orig_obj = obj
+
+ if obj.name == self.bbox_obj.name:
+ # is there a better check?
+ # ("a is b" doesn't work here)
+ continue
+ if obj.show_x_ray != x_ray:
+ continue
+
+ if is_bbox:
+ obj = self.get_bbox_obj(obj, \
+ sys_matrix, sys_matrix_inv, is_local)
+ elif obj.draw_type == 'BOUNDS':
+ # Outside of BBox, there is no meaningful visual snapping
+ # for such display mode
+ continue
+
+ m = obj.matrix_world.copy()
+ try:
+ mi = m.inverted()
+ except:
+ # this is some degenerate object
+ continue
+ la = mi * a
+ lb = mi * b
+
+ # Bounding sphere check (to avoid unnecesary conversions
+ # and to make ray 'infinite')
+ bb_min = Vector(obj.bound_box[0])
+ bb_max = Vector(obj.bound_box[6])
+ c = (bb_min + bb_max) * 0.5
+ r = (bb_max - bb_min).length * 0.5
+ sec = intersect_line_sphere(la, lb, c, r, False)
+ if sec[0] is None:
+ continue # no intersection with the bounding sphere
+
+ if not is_bbox:
+ # Ensure we work with raycastable object.
+ variant = ('RAW' if (edit and
+ (obj.type == 'MESH') and (obj.mode == 'EDIT'))
+ else 'PREVIEW')
+ obj = self.cache.get(obj, variant, reuse=(not force))
+ if (obj is None) or (not obj.data.polygons):
+ continue # the object has no raycastable geometry
+
+ # If ray must be infinite, ensure that
+ # endpoints are outside of bounding volume
+ if not clip:
+ # Seems that intersect_line_sphere()
+ # returns points in flipped order
+ lb, la = sec
+
+ # Does ray actually intersect something?
+ lp, ln, face_id = obj.ray_cast(la, lb)
+ if face_id == -1:
+ continue
+
+ # transform position to global space
+ p = m * lp
+
+ # This works both for prespective and ortho
+ l = p.dot(view_dir)
+ if (L is None) or (l < L):
+ res = (lp, ln, face_id, obj, p, m, la, lb, orig_obj)
+ L = l
+ #end for
+
+ return res
+
+ # Returns:
+ # Matrix(X -- tangential,
+ # Y -- 2nd tangential,
+ # Z -- normal,
+ # T -- raycasted/snapped position)
+ # Face ID (-1 if not applicable)
+ # Object (None if not applicable)
+ def snap_raycast(self, a, b, clip, view_dir, csu, alt_snap):
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ if self.shade_bbox and tfm_opts.snap_only_to_solid:
+ return None
+
+ # Since introduction of "use object centers",
+ # this check is useless (use_object_centers overrides
+ # even INCREMENT snapping)
+ #if self.snap_type not in {'VERTEX', 'EDGE', 'FACE', 'VOLUME'}:
+ # return None
+
+ # key shouldn't depend on system origin;
+ # for bbox calculation origin is always zero
+ #if csu.tou.get() != "Surface":
+ # sys_matrix = csu.get_matrix().to_3x3()
+ #else:
+ # sys_matrix = csu.get_matrix('LOCAL').to_3x3()
+ sys_matrix = csu.get_matrix().to_3x3()
+ sys_matrix_key = list(c for v in sys_matrix for c in v)
+ sys_matrix_key.append(self.editmode)
+ sys_matrix = sys_matrix.to_4x4()
+ try:
+ sys_matrix_inv = sys_matrix.inverted()
+ except:
+ # this is some degenerate system
+ return None
+
+ if self.sys_matrix_key != sys_matrix_key:
+ self.bbox_cache.clear()
+ self.sys_matrix_key = sys_matrix_key
+
+ # In this context, Volume represents BBox :P
+ is_bbox = (self.snap_type == 'VOLUME')
+ is_local = (csu.tou.get() in \
+ {'LOCAL', "Scaled"})
+
+ res = self.raycast(a, b, clip, view_dir, \
+ is_bbox, sys_matrix, sys_matrix_inv, is_local, True)
+
+ if res is None:
+ res = self.raycast(a, b, clip, view_dir, \
+ is_bbox, sys_matrix, sys_matrix_inv, is_local, False)
+
+ # Occlusion-based edge/vertex snapping will be
+ # too inefficient in Python (well, even without
+ # the occlusion, iterating over all edges/vertices
+ # of each object is inefficient too)
+
+ if not res:
+ return None
+
+ lp, ln, face_id, obj, p, m, la, lb, orig_obj = res
+
+ if is_bbox:
+ self.bbox_obj.matrix_world = m.copy()
+ self.bbox_obj.show_x_ray = orig_obj.show_x_ray
+ self.hide_bbox(False)
+
+ _ln = ln.copy()
+
+ face = obj.data.tessfaces[face_id]
+ L = None
+ t1 = None
+
+ if self.snap_type == 'VERTEX' or self.snap_type == 'VOLUME':
+ for v0 in face.vertices:
+ v = obj.data.vertices[v0]
+ p0 = v.co
+ l = (lp - p0).length_squared
+ if (L is None) or (l < L):
+ p = p0
+ ln = v.normal.copy()
+ #t1 = ln.cross(_ln)
+ L = l
+
+ _ln = ln.copy()
+ '''
+ if t1.length < epsilon:
+ if (1.0 - abs(ln.z)) < epsilon:
+ t1 = Vector((1, 0, 0))
+ else:
+ t1 = Vector((0, 0, 1)).cross(_ln)
+ '''
+ p = m * p
+ elif self.snap_type == 'EDGE':
+ use_smooth = face.use_smooth
+ if self.interpolation == 'NEVER':
+ use_smooth = False
+ elif self.interpolation == 'ALWAYS':
+ use_smooth = True
+
+ for v0, v1 in face.edge_keys:
+ p0 = obj.data.vertices[v0].co
+ p1 = obj.data.vertices[v1].co
+ dp = p1 - p0
+ q = dp.dot(lp - p0) / dp.length_squared
+ if (q >= 0.0) and (q <= 1.0):
+ ep = p0 + dp * q
+ l = (lp - ep).length_squared
+ if (L is None) or (l < L):
+ if alt_snap:
+ p = (p0 + p1) * 0.5
+ q = 0.5
+ else:
+ p = ep
+ if not use_smooth:
+ q = 0.5
+ ln = obj.data.vertices[v1].normal * q + \
+ obj.data.vertices[v0].normal * (1.0 - q)
+ t1 = dp
+ L = l
+
+ p = m * p
+ else:
+ if alt_snap:
+ lp = face.center
+ p = m * lp
+
+ if self.interpolation != 'NEVER':
+ ln = self.interpolate_normal(
+ obj, face_id, lp, la, lb - la)
+
+ # Comment this to make 1st tangential
+ # always lie in the face's plane
+ _ln = ln.copy()
+
+ '''
+ for v0, v1 in face.edge_keys:
+ p0 = obj.data.vertices[v0].co
+ p1 = obj.data.vertices[v1].co
+ dp = p1 - p0
+ q = dp.dot(lp - p0) / dp.length_squared
+ if (q >= 0.0) and (q <= 1.0):
+ ep = p0 + dp * q
+ l = (lp - ep).length_squared
+ if (L is None) or (l < L):
+ t1 = dp
+ L = l
+ '''
+
+ n = ln.copy()
+ n.rotate(m)
+ n.normalize()
+
+ if t1 is None:
+ _ln.rotate(m)
+ _ln.normalize()
+ if (1.0 - abs(_ln.z)) < epsilon:
+ t1 = Vector((1, 0, 0))
+ else:
+ t1 = Vector((0, 0, 1)).cross(_ln)
+ t1.normalize()
+ else:
+ t1.rotate(m)
+ t1.normalize()
+
+ t2 = t1.cross(n)
+ t2.normalize()
+
+ matrix = MatrixCompose(t1, t2, n, p)
+
+ return (matrix, face_id, obj, orig_obj)
+
+ def interpolate_normal(self, obj, face_id, p, orig, ray):
+ face = obj.data.tessfaces[face_id]
+
+ use_smooth = face.use_smooth
+ if self.interpolation == 'NEVER':
+ use_smooth = False
+ elif self.interpolation == 'ALWAYS':
+ use_smooth = True
+
+ if not use_smooth:
+ return face.normal.copy()
+
+ # edge.use_edge_sharp affects smoothness only if
+ # mesh has EdgeSplit modifier
+
+ # ATTENTION! Coords/Normals MUST be copied
+ # (a bug in barycentric_transform implementation ?)
+ # Somewhat strangely, the problem also disappears
+ # if values passed to barycentric_transform
+ # are print()ed beforehand.
+
+ co = [obj.data.vertices[vi].co.copy()
+ for vi in face.vertices]
+
+ normals = [obj.data.vertices[vi].normal.copy()
+ for vi in face.vertices]
+
+ if len(face.vertices) != 3:
+ tris = tessellate_polygon([co])
+ for tri in tris:
+ i0, i1, i2 = tri
+ if intersect_ray_tri(co[i0], co[i1], co[i2], ray, orig):
+ break
+ else:
+ i0, i1, i2 = 0, 1, 2
+
+ n = barycentric_transform(p, co[i0], co[i1], co[i2],
+ normals[i0], normals[i1], normals[i2])
+ n.normalize()
+
+ return n
+
+# ====== CONVERTED-TO-MESH OBJECTS CACHE ====== #
+#============================================================================#
+class ToggleObjectMode:
+ def __init__(self, mode='OBJECT'):
+ if not isinstance(mode, str):
+ mode = ('OBJECT' if mode else None)
+
+ self.mode = mode
+
+ def __enter__(self):
+ if self.mode:
+ edit_preferences = bpy.context.user_preferences.edit
+
+ self.global_undo = edit_preferences.use_global_undo
+ self.prev_mode = bpy.context.object.mode
+
+ if self.prev_mode != self.mode:
+ edit_preferences.use_global_undo = False
+ bpy.ops.object.mode_set(mode=self.mode)
+
+ return self
+
+ def __exit__(self, type, value, traceback):
+ if self.mode:
+ edit_preferences = bpy.context.user_preferences.edit
+
+ if self.prev_mode != self.mode:
+ bpy.ops.object.mode_set(mode=self.prev_mode)
+ edit_preferences.use_global_undo = self.global_undo
+
+class MeshCacheItem:
+ def __init__(self):
+ self.variants = {}
+
+ def __getitem__(self, variant):
+ return self.variants[variant][0]
+
+ def __setitem__(self, variant, conversion):
+ mesh = conversion[0].data
+ #mesh.update(calc_tessface=True)
+ #mesh.calc_tessface()
+ mesh.calc_normals()
+
+ self.variants[variant] = conversion
+
+ def __contains__(self, variant):
+ return variant in self.variants
+
+ def dispose(self):
+ for obj, converted in self.variants.values():
+ if converted:
+ mesh = obj.data
+ bpy.data.objects.remove(obj)
+ bpy.data.meshes.remove(mesh)
+ self.variants = None
+
+class MeshCache:
+ """
+ Keeps a cache of mesh equivalents of requested objects.
+ It is assumed that object's data does not change while
+ the cache is in use.
+ """
+
+ variants_enum = {'RAW', 'PREVIEW', 'RENDER'}
+ variants_normalization = {
+ 'MESH':{},
+ 'CURVE':{},
+ 'SURFACE':{},
+ 'FONT':{},
+ 'META':{'RAW':'PREVIEW'},
+ 'ARMATURE':{'RAW':'PREVIEW', 'RENDER':'PREVIEW'},
+ 'LATTICE':{'RAW':'PREVIEW', 'RENDER':'PREVIEW'},
+ 'EMPTY':{'RAW':'PREVIEW', 'RENDER':'PREVIEW'},
+ 'CAMERA':{'RAW':'PREVIEW', 'RENDER':'PREVIEW'},
+ 'LAMP':{'RAW':'PREVIEW', 'RENDER':'PREVIEW'},
+ 'SPEAKER':{'RAW':'PREVIEW', 'RENDER':'PREVIEW'},
+ }
+ conversible_types = {'MESH', 'CURVE', 'SURFACE', 'FONT',
+ 'META', 'ARMATURE', 'LATTICE'}
+ convert_types = conversible_types
+
+ def __init__(self, scene, convert_types=None):
+ self.scene = scene
+ if convert_types:
+ self.convert_types = convert_types
+ self.cached = {}
+
+ def __del__(self):
+ self.clear()
+
+ def clear(self, expect_zero_users=False):
+ for cache_item in self.cached.values():
+ if cache_item:
+ try:
+ cache_item.dispose()
+ except RuntimeError:
+ if expect_zero_users:
+ raise
+ self.cached.clear()
+
+ def __delitem__(self, obj):
+ cache_item = self.cached.pop(obj, None)
+ if cache_item:
+ cache_item.dispose()
+
+ def __contains__(self, obj):
+ return obj in self.cached
+
+ def __getitem__(self, obj):
+ if isinstance(obj, tuple):
+ return self.get(*obj)
+ return self.get(obj)
+
+ def get(self, obj, variant='PREVIEW', reuse=True):
+ if variant not in self.variants_enum:
+ raise ValueError("Mesh variant must be one of %s" %
+ self.variants_enum)
+
+ # Make sure the variant is proper for this type of object
+ variant = (self.variants_normalization[obj.type].
+ get(variant, variant))
+
+ if obj in self.cached:
+ cache_item = self.cached[obj]
+ try:
+ # cache_item is None if object isn't conversible to mesh
+ return (None if (cache_item is None)
+ else cache_item[variant])
+ except KeyError:
+ pass
+ else:
+ cache_item = None
+
+ if obj.type not in self.conversible_types:
+ self.cached[obj] = None
+ return None
+
+ if not cache_item:
+ cache_item = MeshCacheItem()
+ self.cached[obj] = cache_item
+
+ conversion = self._convert(obj, variant, reuse)
+ cache_item[variant] = conversion
+
+ return conversion[0]
+
+ def _convert(self, obj, variant, reuse=True):
+ obj_type = obj.type
+ obj_mode = obj.mode
+ data = obj.data
+
+ if obj_type == 'MESH':
+ if reuse and ((variant == 'RAW') or (len(obj.modifiers) == 0)):
+ return (obj, False)
+ else:
+ force_objectmode = (obj_mode in {'EDIT', 'SCULPT'})
+ return (self._to_mesh(obj, variant, force_objectmode), True)
+ elif obj_type in {'CURVE', 'SURFACE', 'FONT'}:
+ if variant == 'RAW':
+ bm = bmesh.new()
+ for spline in data.splines:
+ for point in spline.bezier_points:
+ bm.verts.new(point.co)
+ bm.verts.new(point.handle_left)
+ bm.verts.new(point.handle_right)
+ for point in spline.points:
+ bm.verts.new(point.co[:3])
+ return (self._make_obj(bm, obj), True)
+ else:
+ if variant == 'RENDER':
+ resolution_u = data.resolution_u
+ resolution_v = data.resolution_v
+ if data.render_resolution_u != 0:
+ data.resolution_u = data.render_resolution_u
+ if data.render_resolution_v != 0:
+ data.resolution_v = data.render_resolution_v
+
+ result = (self._to_mesh(obj, variant), True)
+
+ if variant == 'RENDER':
+ data.resolution_u = resolution_u
+ data.resolution_v = resolution_v
+
+ return result
+ elif obj_type == 'META':
+ if variant == 'RAW':
+ # To avoid the hassle of snapping metaelements
+ # to themselves, we just create an empty mesh
+ bm = bmesh.new()
+ return (self._make_obj(bm, obj), True)
+ else:
+ if variant == 'RENDER':
+ resolution = data.resolution
+ data.resolution = data.render_resolution
+
+ result = (self._to_mesh(obj, variant), True)
+
+ if variant == 'RENDER':
+ data.resolution = resolution
+
+ return result
+ elif obj_type == 'ARMATURE':
+ bm = bmesh.new()
+ if obj_mode == 'EDIT':
+ for bone in data.edit_bones:
+ head = bm.verts.new(bone.head)
+ tail = bm.verts.new(bone.tail)
+ bm.edges.new((head, tail))
+ elif obj_mode == 'POSE':
+ for bone in obj.pose.bones:
+ head = bm.verts.new(bone.head)
+ tail = bm.verts.new(bone.tail)
+ bm.edges.new((head, tail))
+ else:
+ for bone in data.bones:
+ head = bm.verts.new(bone.head_local)
+ tail = bm.verts.new(bone.tail_local)
+ bm.edges.new((head, tail))
+ return (self._make_obj(bm, obj), True)
+ elif obj_type == 'LATTICE':
+ bm = bmesh.new()
+ for point in data.points:
+ bm.verts.new(point.co_deform)
+ return (self._make_obj(bm, obj), True)
+
+ def _to_mesh(self, obj, variant, force_objectmode=False):
+ tmp_name = chr(0x10ffff) # maximal Unicode value
+
+ with ToggleObjectMode(force_objectmode):
+ if variant == 'RAW':
+ mesh = obj.to_mesh(self.scene, False, 'PREVIEW')
+ else:
+ mesh = obj.to_mesh(self.scene, True, variant)
+ mesh.name = tmp_name
+
+ return self._make_obj(mesh, obj)
+
+ def _make_obj(self, mesh, src_obj):
+ tmp_name = chr(0x10ffff) # maximal Unicode value
+
+ if isinstance(mesh, bmesh.types.BMesh):
+ bm = mesh
+ mesh = bpy.data.meshes.new(tmp_name)
+ bm.to_mesh(mesh)
+
+ tmp_obj = bpy.data.objects.new(tmp_name, mesh)
+
+ if src_obj:
+ tmp_obj.matrix_world = src_obj.matrix_world
+
+ # This is necessary for correct bbox display # TODO
+ # (though it'd be better to change the logic in the raycasting)
+ tmp_obj.show_x_ray = src_obj.show_x_ray
+
+ tmp_obj.dupli_faces_scale = src_obj.dupli_faces_scale
+ tmp_obj.dupli_frames_end = src_obj.dupli_frames_end
+ tmp_obj.dupli_frames_off = src_obj.dupli_frames_off
+ tmp_obj.dupli_frames_on = src_obj.dupli_frames_on
+ tmp_obj.dupli_frames_start = src_obj.dupli_frames_start
+ tmp_obj.dupli_group = src_obj.dupli_group
+ #tmp_obj.dupli_list = src_obj.dupli_list
+ tmp_obj.dupli_type = src_obj.dupli_type
+
+ # Make Blender recognize object as having geometry
+ # (is there a simpler way to do this?)
+ self.scene.objects.link(tmp_obj)
+ self.scene.update()
+ # We don't need this object in scene
+ self.scene.objects.unlink(tmp_obj)
+
+ return tmp_obj
+
+#============================================================================#
+
+# A base class for emulating ID-datablock behavior
+class PseudoIDBlockBase(bpy.types.PropertyGroup):
+ # TODO: use normal metaprogramming?
+
+ @staticmethod
+ def create_props(type, name, options={'ANIMATABLE'}):
+ def active_update(self, context):
+ # necessary to avoid recursive calls
+ if self._self_update[0]:
+ return
+
+ if self._dont_rename[0]:
+ return
+
+ if len(self.collection) == 0:
+ return
+
+ # prepare data for renaming...
+ old_key = (self.enum if self.enum else self.collection[0].name)
+ new_key = (self.active if self.active else "Untitled")
+
+ if old_key == new_key:
+ return
+
+ old_item = None
+ new_item = None
+ existing_names = []
+
+ for item in self.collection:
+ if (item.name == old_key) and (not new_item):
+ new_item = item
+ elif (item.name == new_key) and (not old_item):
+ old_item = item
+ else:
+ existing_names.append(item.name)
+ existing_names.append(new_key)
+
+ # rename current item
+ new_item.name = new_key
+
+ if old_item:
+ # rename other item if it has that name
+ name = new_key
+ i = 1
+ while name in existing_names:
+ name = "{}.{:0>3}".format(new_key, i)
+ i += 1
+ old_item.name = name
+
+ # update the enum
+ self._self_update[0] += 1
+ self.update_enum()
+ self._self_update[0] -= 1
+ # end def
+
+ def enum_update(self, context):
+ # necessary to avoid recursive calls
+ if self._self_update[0]:
+ return
+
+ self._dont_rename[0] = True
+ self.active = self.enum
+ self._dont_rename[0] = False
+
+ self.on_item_select()
+ # end def
+
+ collection = bpy.props.CollectionProperty(
+ type=type)
+ active = bpy.props.StringProperty(
+ name="Name",
+ description="Name of the active {}".format(name),
+ options=options,
+ update=active_update)
+ enum = bpy.props.EnumProperty(
+ items=[],
+ name="Choose",
+ description="Choose {}".format(name),
+ default=set(),
+ options={'ENUM_FLAG'},
+ update=enum_update)
+
+ return collection, active, enum
+ # end def
+
+ def add(self, name="", **kwargs):
+ if not name:
+ name = 'Untitled'
+ _name = name
+
+ existing_names = [item.name for item in self.collection]
+ i = 1
+ while name in existing_names:
+ name = "{}.{:0>3}".format(_name, i)
+ i += 1
+
+ instance = self.collection.add()
+ instance.name = name
+
+ for key, value in kwargs.items():
+ setattr(instance, key, value)
+
+ self._self_update[0] += 1
+ self.active = name
+ self.update_enum()
+ self._self_update[0] -= 1
+
+ return instance
+
+ def remove(self, key):
+ if isinstance(key, int):
+ i = key
+ else:
+ i = self.indexof(key)
+
+ # Currently remove() ignores non-existing indices...
+ # In the case this behavior changes, we have the try block.
+ try:
+ self.collection.remove(i)
+ except:
+ pass
+
+ self._self_update[0] += 1
+ if len(self.collection) != 0:
+ i = min(i, len(self.collection) - 1)
+ self.active = self.collection[i].name
+ else:
+ self.active = ""
+ self.update_enum()
+ self._self_update[0] -= 1
+
+ def get_item(self, key=None):
+ if key is None:
+ i = self.indexof(self.active)
+ elif isinstance(key, int):
+ i = key
+ else:
+ i = self.indexof(key)
+
+ try:
+ return self.collection[i]
+ except:
+ return None
+
+ def indexof(self, key):
+ return next((i for i, v in enumerate(self.collection) \
+ if v.name == key), -1)
+
+ # Which is more Pythonic?
+
+ #for i, item in enumerate(self.collection):
+ # if item.name == key:
+ # return i
+ #return -1 # non-existing index
+
+ def update_enum(self):
+ names = []
+ items = []
+ for item in self.collection:
+ names.append(item.name)
+ items.append((item.name, item.name, ""))
+
+ prop_class, prop_params = type(self).enum
+ prop_params["items"] = items
+ if len(items) == 0:
+ prop_params["default"] = set()
+ prop_params["options"] = {'ENUM_FLAG'}
+ else:
+ # Somewhy active may be left from previous times,
+ # I don't want to dig now why that happens.
+ if self.active not in names:
+ self.active = items[0][0]
+ prop_params["default"] = self.active
+ prop_params["options"] = set()
+
+ # Can this cause problems? In the near future, shouldn't...
+ type(self).enum = (prop_class, prop_params)
+ #type(self).enum = bpy.props.EnumProperty(**prop_params)
+
+ if len(items) != 0:
+ self.enum = self.active
+
+ def on_item_select(self):
+ pass
+
+ data_name = ""
+ op_new = ""
+ op_delete = ""
+ icon = 'DOT'
+
+ def draw(self, context, layout):
+ if len(self.collection) == 0:
+ if self.op_new:
+ layout.operator(self.op_new, icon=self.icon)
+ else:
+ layout.label(
+ text="({})".format(self.data_name),
+ icon=self.icon)
+ return
+
+ row = layout.row(align=True)
+ row.prop_menu_enum(self, "enum", text="", icon=self.icon)
+ row.prop(self, "active", text="")
+ if self.op_new:
+ row.operator(self.op_new, text="", icon='ZOOMIN')
+ if self.op_delete:
+ row.operator(self.op_delete, text="", icon='X')
+# end class
+#============================================================================#
+# ===== PROPERTY DEFINITIONS ===== #
+
+# ===== TRANSFORM EXTRA OPTIONS ===== #
+class TransformExtraOptionsProp(bpy.types.PropertyGroup):
+ use_relative_coords = bpy.props.BoolProperty(
+ name="Relative coordinates",
+ description="Consider existing transformation as the starting point",
+ default=True)
+ snap_interpolate_normals_mode = bpy.props.EnumProperty(
+ items=[('NEVER', "Never", "Don't interpolate normals"),
+ ('ALWAYS', "Always", "Always interpolate normals"),
+ ('SMOOTH', "Smoothness-based", "Interpolate normals only "\
+ "for faces with smooth shading"),],
+ name="Normal interpolation",
+ description="Normal interpolation mode for snapping",
+ default='SMOOTH')
+ snap_only_to_solid = bpy.props.BoolProperty(
+ name="Snap only to soild",
+ description="Ignore wireframe/non-solid objects during snapping",
+ default=False)
+ snap_element_screen_size = bpy.props.IntProperty(
+ name="Snap distance",
+ description="Radius in pixels for snapping to edges/vertices",
+ default=8,
+ min=2,
+ max=64)
+ use_comma_separator = bpy.props.BoolProperty(
+ name="Use comma separator",
+ description="Use comma separator when copying/pasting"\
+ "coordinate values (instead of Tab character)",
+ default=True,
+ options={'HIDDEN'})
+
+# ===== 3D VECTOR LOCATION ===== #
+class LocationProp(bpy.types.PropertyGroup):
+ pos = bpy.props.FloatVectorProperty(
+ name="xyz", description="xyz coords",
+ options={'HIDDEN'}, subtype='XYZ')
+
+# ===== HISTORY ===== #
+def update_history_max_size(self, context):
+ settings = find_settings()
+
+ history = settings.history
+
+ prop_class, prop_params = type(history).current_id
+ old_max = prop_params["max"]
+
+ size = history.max_size
+ try:
+ int_size = int(size)
+ int_size = max(int_size, 0)
+ int_size = min(int_size, history.max_size_limit)
+ except:
+ int_size = old_max
+
+ if old_max != int_size:
+ prop_params["max"] = int_size
+ type(history).current_id = (prop_class, prop_params)
+
+ # also: clear immediately?
+ for i in range(len(history.entries) - 1, int_size, -1):
+ history.entries.remove(i)
+
+ if str(int_size) != size:
+ # update history.max_size if it's not inside the limits
+ history.max_size = str(int_size)
+
+def update_history_id(self, context):
+ scene = bpy.context.scene
+
+ settings = find_settings()
+ history = settings.history
+
+ pos = history.get_pos()
+ if pos is not None:
+ # History doesn't depend on view (?)
+ cursor_pos = get_cursor_location(scene=scene)
+
+ if CursorHistoryProp.update_cursor_on_id_change:
+ # Set cursor position anyway (we're changing v3d's
+ # cursor, which may be separate from scene's)
+ # This, however, should be done cautiously
+ # from scripts, since, e.g., CursorMonitor
+ # can supply wrong context -> cursor will be set
+ # in a different view than required
+ set_cursor_location(pos, v3d=context.space_data)
+
+ if pos != cursor_pos:
+ if (history.current_id == 0) and (history.last_id <= 1):
+ history.last_id = 1
+ else:
+ history.last_id = history.curr_id
+ history.curr_id = history.current_id
+
+class CursorHistoryProp(bpy.types.PropertyGroup):
+ max_size_limit = 500
+
+ update_cursor_on_id_change = True
+
+ show_trace = bpy.props.BoolProperty(
+ name="Trace",
+ description="Show history trace",
+ default=False)
+ max_size = bpy.props.StringProperty(
+ name="Size",
+ description="History max size",
+ default=str(50),
+ update=update_history_max_size)
+ current_id = bpy.props.IntProperty(
+ name="Index",
+ description="Current position in cursor location history",
+ default=50,
+ min=0,
+ max=50,
+ update=update_history_id)
+ entries = bpy.props.CollectionProperty(
+ type=LocationProp)
+
+ curr_id = bpy.props.IntProperty(options={'HIDDEN'})
+ last_id = bpy.props.IntProperty(options={'HIDDEN'})
+
+ def get_pos(self, id = None):
+ if id is None:
+ id = self.current_id
+
+ id = min(max(id, 0), len(self.entries) - 1)
+
+ if id < 0:
+ # history is empty
+ return None
+
+ return self.entries[id].pos
+
+ # for updating the upper bound on file load
+ def update_max_size(self):
+ prop_class, prop_params = type(self).current_id
+ # self.max_size expected to be always a correct integer
+ prop_params["max"] = int(self.max_size)
+ type(self).current_id = (prop_class, prop_params)
+
+ def draw_trace(self, context):
+ bgl.glColor4f(0.75, 1.0, 0.75, 1.0)
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ for entry in self.entries:
+ p = entry.pos
+ bgl.glVertex3f(p[0], p[1], p[2])
+ bgl.glEnd()
+
+ def draw_offset(self, context):
+ bgl.glShadeModel(bgl.GL_SMOOTH)
+
+ tfm_operator = CursorDynamicSettings.active_transform_operator
+
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+
+ if tfm_operator:
+ p = tfm_operator.particles[0]. \
+ get_initial_matrix().to_translation()
+ else:
+ p = self.get_pos(self.last_id)
+ bgl.glColor4f(1.0, 0.75, 0.5, 1.0)
+ bgl.glVertex3f(p[0], p[1], p[2])
+
+ p = get_cursor_location(v3d=context.space_data)
+ bgl.glColor4f(1.0, 1.0, 0.25, 1.0)
+ bgl.glVertex3f(p[0], p[1], p[2])
+
+ bgl.glEnd()
+
+# ===== BOOKMARK ===== #
+class BookmarkProp(bpy.types.PropertyGroup):
+ name = bpy.props.StringProperty(
+ name="name", description="bookmark name",
+ options={'HIDDEN'})
+ pos = bpy.props.FloatVectorProperty(
+ name="xyz", description="xyz coords",
+ options={'HIDDEN'}, subtype='XYZ')
+
+class BookmarkIDBlock(PseudoIDBlockBase):
+ # Somewhy instance members aren't seen in update()
+ # callbacks... but class members are.
+ _self_update = [0]
+ _dont_rename = [False]
+
+ data_name = "Bookmark"
+ op_new = "scene.cursor_3d_new_bookmark"
+ op_delete = "scene.cursor_3d_delete_bookmark"
+ icon = 'CURSOR'
+
+ collection, active, enum = PseudoIDBlockBase.create_props(
+ BookmarkProp, "Bookmark")
+
+class NewCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_new_bookmark"
+ bl_label = "New Bookmark"
+ bl_description = "Add a new bookmark"
+
+ name = bpy.props.StringProperty(
+ name="Name",
+ description="Name of the new bookmark",
+ default="Mark")
+
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def execute(self, context):
+ settings = find_settings()
+ library = settings.libraries.get_item()
+ if not library:
+ return {'CANCELLED'}
+
+ bookmark = library.bookmarks.add(name=self.name)
+
+ cusor_pos = get_cursor_location(v3d=context.space_data)
+
+ try:
+ bookmark.pos = library.convert_from_abs(context.space_data,
+ cusor_pos, True)
+ except Exception as exc:
+ self.report({'ERROR_INVALID_CONTEXT'}, exc.args[0])
+ return {'CANCELLED'}
+
+ return {'FINISHED'}
+
+class DeleteCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_delete_bookmark"
+ bl_label = "Delete Bookmark"
+ bl_description = "Delete active bookmark"
+
+ def execute(self, context):
+ settings = find_settings()
+ library = settings.libraries.get_item()
+ if not library:
+ return {'CANCELLED'}
+
+ name = library.bookmarks.active
+
+ library.bookmarks.remove(key=name)
+
+ return {'FINISHED'}
+
+class OverwriteCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_overwrite_bookmark"
+ bl_label = "Overwrite"
+ bl_description = "Overwrite active bookmark "\
+ "with the current cursor location"
+
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def execute(self, context):
+ settings = find_settings()
+ library = settings.libraries.get_item()
+ if not library:
+ return {'CANCELLED'}
+
+ bookmark = library.bookmarks.get_item()
+ if not bookmark:
+ return {'CANCELLED'}
+
+ cusor_pos = get_cursor_location(v3d=context.space_data)
+
+ try:
+ bookmark.pos = library.convert_from_abs(context.space_data,
+ cusor_pos, True)
+ except Exception as exc:
+ self.report({'ERROR_INVALID_CONTEXT'}, exc.args[0])
+ return {'CANCELLED'}
+
+ CursorDynamicSettings.recalc_csu(context, 'PRESS')
+
+ return {'FINISHED'}
+
+class RecallCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_recall_bookmark"
+ bl_label = "Recall"
+ bl_description = "Move cursor to the active bookmark"
+
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def execute(self, context):
+ settings = find_settings()
+ library = settings.libraries.get_item()
+ if not library:
+ return {'CANCELLED'}
+
+ bookmark = library.bookmarks.get_item()
+ if not bookmark:
+ return {'CANCELLED'}
+
+ try:
+ bookmark_pos = library.convert_to_abs(context.space_data,
+ bookmark.pos, True)
+ set_cursor_location(bookmark_pos, v3d=context.space_data)
+ except Exception as exc:
+ self.report({'ERROR_INVALID_CONTEXT'}, exc.args[0])
+ return {'CANCELLED'}
+
+ CursorDynamicSettings.recalc_csu(context)
+
+ return {'FINISHED'}
+
+class SwapCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_swap_bookmark"
+ bl_label = "Swap"
+ bl_description = "Swap cursor position with the active bookmark"
+
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def execute(self, context):
+ settings = find_settings()
+ library = settings.libraries.get_item()
+ if not library:
+ return {'CANCELLED'}
+
+ bookmark = library.bookmarks.get_item()
+ if not bookmark:
+ return {'CANCELLED'}
+
+ cusor_pos = get_cursor_location(v3d=context.space_data)
+
+ try:
+ bookmark_pos = library.convert_to_abs(context.space_data,
+ bookmark.pos, True)
+
+ set_cursor_location(bookmark_pos, v3d=context.space_data)
+
+ bookmark.pos = library.convert_from_abs(context.space_data,
+ cusor_pos, True,
+ use_history=False)
+ except Exception as exc:
+ self.report({'ERROR_INVALID_CONTEXT'}, exc.args[0])
+ return {'CANCELLED'}
+
+ CursorDynamicSettings.recalc_csu(context)
+
+ return {'FINISHED'}
+
+# Will this be used?
+class SnapSelectionToCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_snap_selection_to_bookmark"
+ bl_label = "Snap Selection"
+ bl_description = "Snap selection to the active bookmark"
+
+# Will this be used?
+class AddEmptyAtCursor3DBookmark(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_add_empty_at_bookmark"
+ bl_label = "Add Empty"
+ bl_description = "Add new Empty at the active bookmark"
+
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def execute(self, context):
+ settings = find_settings()
+ library = settings.libraries.get_item()
+ if not library:
+ return {'CANCELLED'}
+
+ bookmark = library.bookmarks.get_item()
+ if not bookmark:
+ return {'CANCELLED'}
+
+ try:
+ matrix = library.get_matrix(use_history=False,
+ v3d=context.space_data, warn=True)
+ bookmark_pos = matrix * bookmark.pos
+ except Exception as exc:
+ self.report({'ERROR_INVALID_CONTEXT'}, exc.args[0])
+ return {'CANCELLED'}
+
+ name = "{}.{}".format(library.name, bookmark.name)
+ obj = bpy.data.objects.new(name, None)
+ obj.matrix_world = to_matrix4x4(matrix, bookmark_pos)
+ context.scene.objects.link(obj)
+
+ """
+ for sel_obj in list(context.selected_objects):
+ sel_obj.select = False
+ obj.select = True
+ context.scene.objects.active = obj
+
+ # We need this to update bookmark position if
+ # library's system is local/scaled/normal/etc.
+ CursorDynamicSettings.recalc_csu(context, "PRESS")
+ """
+
+ # TODO: exit from editmode? It has separate history!
+ # If we just link object to scene, it will not trigger
+ # addition of new entry to Undo history
+ bpy.ops.ed.undo_push(message="Add Object")
+
+ return {'FINISHED'}
+
+# ===== BOOKMARK LIBRARY ===== #
+class BookmarkLibraryProp(bpy.types.PropertyGroup):
+ name = bpy.props.StringProperty(
+ name="Name", description="Name of the bookmark library",
+ options={'HIDDEN'})
+ bookmarks = bpy.props.PointerProperty(
+ type=BookmarkIDBlock,
+ options={'HIDDEN'})
+ system = bpy.props.EnumProperty(
+ items=[
+ ('GLOBAL', "Global", "Global (absolute) coordinates"),
+ ('LOCAL', "Local", "Local coordinate system, "\
+ "relative to the active object"),
+ ('SCALED', "Scaled", "Scaled local coordinate system, "\
+ "relative to the active object"),
+ ('NORMAL', "Normal", "Normal coordinate system, "\
+ "relative to the selected elements"),
+ ('CONTEXT', "Context", "Current transform orientation; "\
+ "origin depends on selection"),
+ ],
+ default="GLOBAL",
+ name="System",
+ description="Coordinate system in which to store/recall "\
+ "cursor locations",
+ options={'HIDDEN'})
+ offset = bpy.props.BoolProperty(
+ name="Offset",
+ description="Store/recall relative to the last cursor position",
+ default=False,
+ options={'HIDDEN'})
+
+ # Returned None means "operation is not aplicable"
+ def get_matrix(self, use_history, v3d, warn=True, **kwargs):
+ #particles, csu = gather_particles(**kwargs)
+
+ # Ensure we have relevant CSU (Blender will crash
+ # if we use the old one after Undo/Redo)
+ CursorDynamicSettings.recalc_csu(bpy.context)
+
+ csu = CursorDynamicSettings.csu
+
+ if self.offset:
+ # history? or keep separate for each scene?
+ if not use_history:
+ csu.source_pos = get_cursor_location(v3d=v3d)
+ else:
+ settings = find_settings()
+ history = settings.history
+ csu.source_pos = history.get_pos(history.last_id)
+ else:
+ csu.source_pos = Vector()
+
+ active_obj = csu.tou.scene.objects.active
+
+ if self.system == 'GLOBAL':
+ sys_name = 'GLOBAL'
+ pivot = 'WORLD'
+ elif self.system == 'LOCAL':
+ if not active_obj:
+ if warn:
+ raise Exception("There is no active object")
+ return None
+ sys_name = 'LOCAL'
+ pivot = 'ACTIVE'
+ elif self.system == 'SCALED':
+ if not active_obj:
+ if warn:
+ raise Exception("There is no active object")
+ return None
+ sys_name = 'Scaled'
+ pivot = 'ACTIVE'
+ elif self.system == 'NORMAL':
+ if (not active_obj) or ('EDIT' not in active_obj.mode):
+ if warn:
+ raise Exception("Active object must be in Edit mode")
+ return None
+ sys_name = 'NORMAL'
+ pivot = 'MEDIAN' # ?
+ elif self.system == 'CONTEXT':
+ sys_name = None # use current orientation
+ pivot = None
+
+ if active_obj and (active_obj.mode != 'OBJECT'):
+ if len(particles) == 0:
+ pivot = active_obj.matrix_world.to_translation()
+
+ return csu.get_matrix(sys_name, self.offset, pivot)
+
+ def convert_to_abs(self, v3d, pos, warn=False, **kwargs):
+ kwargs.pop("use_history", None)
+ matrix = self.get_matrix(False, v3d, warn, **kwargs)
+ if not matrix:
+ return None
+ return matrix * pos
+
+ def convert_from_abs(self, v3d, pos, warn=False, **kwargs):
+ use_history = kwargs.pop("use_history", True)
+ matrix = self.get_matrix(use_history, v3d, warn, **kwargs)
+ if not matrix:
+ return None
+
+ try:
+ return matrix.inverted() * pos
+ except:
+ # this is some degenerate object
+ return Vector()
+
+ def draw_bookmark(self, context):
+ r = context.region
+ rv3d = context.region_data
+
+ bookmark = self.bookmarks.get_item()
+ if not bookmark:
+ return
+
+ pos = self.convert_to_abs(context.space_data, bookmark.pos)
+ if pos is None:
+ return
+
+ projected = location_3d_to_region_2d(r, rv3d, pos)
+
+ if projected:
+ # Store previous OpenGL settings
+ smooth_prev = gl_get(bgl.GL_SMOOTH)
+
+ bgl.glShadeModel(bgl.GL_SMOOTH)
+ bgl.glLineWidth(2)
+ bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ radius = 6
+ n = 8
+ da = 2 * math.pi / n
+ x, y = projected
+ x, y = int(x), int(y)
+ for i in range(n + 1):
+ a = i * da
+ dx = math.sin(a) * radius
+ dy = math.cos(a) * radius
+ if (i % 2) == 0:
+ bgl.glColor4f(0.0, 1.0, 0.0, 1.0)
+ else:
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+ bgl.glVertex2i(x + int(dx), y + int(dy))
+ bgl.glEnd()
+
+ # Restore previous OpenGL settings
+ gl_enable(bgl.GL_SMOOTH, smooth_prev)
+
+class BookmarkLibraryIDBlock(PseudoIDBlockBase):
+ # Somewhy instance members aren't seen in update()
+ # callbacks... but class members are.
+ _self_update = [0]
+ _dont_rename = [False]
+
+ data_name = "Bookmark Library"
+ op_new = "scene.cursor_3d_new_bookmark_library"
+ op_delete = "scene.cursor_3d_delete_bookmark_library"
+ icon = 'BOOKMARKS'
+
+ collection, active, enum = PseudoIDBlockBase.create_props(
+ BookmarkLibraryProp, "Bookmark Library")
+
+ def on_item_select(self):
+ library = self.get_item()
+ library.bookmarks.update_enum()
+
+class NewCursor3DBookmarkLibrary(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_new_bookmark_library"
+ bl_label = "New Library"
+ bl_description = "Add a new bookmark library"
+
+ name = bpy.props.StringProperty(
+ name="Name",
+ description="Name of the new library",
+ default="Lib")
+
+ def execute(self, context):
+ settings = find_settings()
+
+ settings.libraries.add(name=self.name)
+
+ return {'FINISHED'}
+
+class DeleteCursor3DBookmarkLibrary(bpy.types.Operator):
+ bl_idname = "scene.cursor_3d_delete_bookmark_library"
+ bl_label = "Delete Library"
+ bl_description = "Delete active bookmark library"
+
+ def execute(self, context):
+ settings = find_settings()
+
+ name = settings.libraries.active
+
+ settings.libraries.remove(key=name)
+
+ return {'FINISHED'}
+
+# ===== MAIN PROPERTIES ===== #
+# TODO: ~a bug? Somewhy tooltip shows "Cursor3DToolsSettings.foo"
+# instead of "bpy.types.Screen.cursor_3d_tools_settings.foo"
+class Cursor3DToolsSettings(bpy.types.PropertyGroup):
+ transform_options = bpy.props.PointerProperty(
+ type=TransformExtraOptionsProp,
+ options={'HIDDEN'})
+
+ cursor_visible = bpy.props.BoolProperty(
+ name="Cursor visibility",
+ description="Cursor visibility (causing bugs, commented out)",
+ default=True)
+
+ draw_guides = bpy.props.BoolProperty(
+ name="Guides",
+ description="Display guides",
+ default=True)
+
+ draw_snap_elements = bpy.props.BoolProperty(
+ name="Snap elements",
+ description="Display snap elements",
+ default=True)
+
+ draw_N = bpy.props.BoolProperty(
+ name="Surface normal",
+ description="Display surface normal",
+ default=True)
+
+ draw_T1 = bpy.props.BoolProperty(
+ name="Surface 1st tangential",
+ description="Display 1st surface tangential",
+ default=True)
+
+ draw_T2 = bpy.props.BoolProperty(
+ name="Surface 2nd tangential",
+ description="Display 2nd surface tangential",
+ default=True)
+
+ stick_to_obj = bpy.props.BoolProperty(
+ name="Stick to objects",
+ description="Move cursor along with object it was snapped to",
+ default=True)
+
+ # HISTORY-RELATED
+ history = bpy.props.PointerProperty(
+ type=CursorHistoryProp,
+ options={'HIDDEN'})
+
+ # BOOKMARK-RELATED
+ libraries = bpy.props.PointerProperty(
+ type=BookmarkLibraryIDBlock,
+ options={'HIDDEN'})
+
+ show_bookmarks = bpy.props.BoolProperty(
+ name="Show bookmarks",
+ description="Show active bookmark in 3D view",
+ default=True,
+ options={'HIDDEN'})
+
+ free_coord_precision = bpy.props.IntProperty(
+ name="Coord precision",
+ description="Numer of digits afer comma "\
+ "for displayed coordinate values",
+ default=4,
+ min=0,
+ max=10,
+ options={'HIDDEN'})
+
+class Cursor3DToolsSceneSettings(bpy.types.PropertyGroup):
+ stick_obj_name = bpy.props.StringProperty(
+ name="Stick-to-object name",
+ description="Name of the object to stick cursor to",
+ options={'HIDDEN'})
+ stick_obj_pos = bpy.props.FloatVectorProperty(
+ default=(0.0, 0.0, 0.0),
+ options={'HIDDEN'},
+ subtype='XYZ')
+
+# ===== CURSOR RUNTIME PROPERTIES ===== #
+class CursorRuntimeSettings(bpy.types.PropertyGroup):
+ current_monitor_id = bpy.props.IntProperty(
+ default=0,
+ options={'HIDDEN'})
+
+ surface_pos = bpy.props.FloatVectorProperty(
+ default=(0.0, 0.0, 0.0),
+ options={'HIDDEN'},
+ subtype='XYZ')
+
+class CursorDynamicSettings:
+ local_matrix = Matrix()
+
+ active_transform_operator = None
+
+ csu = None
+
+ active_scene_hash = 0
+
+ @classmethod
+ def recalc_csu(cls, context, event_value=None):
+ scene_hash_changed = (cls.active_scene_hash != hash(context.scene))
+ cls.active_scene_hash = hash(context.scene)
+
+ # Don't recalc if mouse is over some UI panel!
+ # (otherwise, this may lead to applying operator
+ # (e.g. Subdivide) in Edit Mode, even if user
+ # just wants to change some operator setting)
+ clicked = (event_value in {'PRESS', 'RELEASE'}) and \
+ (context.region.type == 'WINDOW')
+
+ if clicked or scene_hash_changed:
+ particles, cls.csu = gather_particles()
+
+#============================================================================#
+# ===== PANELS AND DIALOGS ===== #
+class TransformExtraOptions(bpy.types.Panel):
+ bl_label = "Transform Extra Options"
+ bl_idname = "OBJECT_PT_transform_extra_options"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "UI"
+ #bl_context = "object"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ layout.prop(tfm_opts, "use_relative_coords")
+ layout.prop(tfm_opts, "snap_only_to_solid")
+ layout.prop(tfm_opts, "snap_interpolate_normals_mode", text="")
+ layout.prop(tfm_opts, "use_comma_separator")
+ #layout.prop(tfm_opts, "snap_element_screen_size")
+
+class Cursor3DTools(bpy.types.Panel):
+ bl_label = "3D Cursor Tools"
+ bl_idname = "OBJECT_PT_cursor_3d_tools"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "UI"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ # Attempt to launch the monitor
+ if bpy.ops.view3d.cursor3d_monitor.poll():
+ bpy.ops.view3d.cursor3d_monitor()
+
+ # If addon is enabled by default, the new scene
+ # created on Blender startup will have disabled
+ # standard Cursor3D behavior. However, if user
+ # creates new scene, somehow Cursor3D is active
+ # as if nothing happened xD
+ update_keymap(True)
+ #=============================================#
+
+ settings = find_settings()
+
+ row = layout.split(0.5)
+ #row = layout.row()
+ row.operator("view3d.set_cursor3d_dialog",
+ "Set", 'CURSOR')
+ row = row.split(1 / 3, align=True)
+ #row = row.row(align=True)
+ row.prop(settings, "draw_guides",
+ text="", icon='MANIPUL', toggle=True)
+ row.prop(settings, "draw_snap_elements",
+ text="", icon='EDITMODE_HLT', toggle=True)
+ row.prop(settings, "stick_to_obj",
+ text="", icon='SNAP_ON', toggle=True)
+
+ row = layout.row()
+ #row.label(text="Draw")
+ #row.prop(settings, "cursor_visible", text="", toggle=True,
+ # icon=('RESTRICT_VIEW_OFF' if settings.cursor_visible
+ # else 'RESTRICT_VIEW_ON'))
+ subrow = row.row()
+ subrow.enabled = False
+ subrow.alert = True
+ subrow.prop(settings, "cursor_visible", text="", toggle=True,
+ icon='RESTRICT_VIEW_OFF')
+ row = row.split(1 / 3, align=True)
+ row.prop(settings, "draw_N",
+ text="N", toggle=True, index=0)
+ row.prop(settings, "draw_T1",
+ text="T1", toggle=True, index=1)
+ row.prop(settings, "draw_T2",
+ text="T2", toggle=True, index=2)
+
+ # === HISTORY === #
+ history = settings.history
+ row = layout.row(align=True)
+ row.prop(history, "show_trace", text="", icon='SORTTIME')
+ row = row.split(0.35, True)
+ row.prop(history, "max_size", text="")
+ row.prop(history, "current_id", text="")
+
+ # === BOOKMARK LIBRARIES === #
+ settings.libraries.draw(context, layout)
+
+ library = settings.libraries.get_item()
+
+ if library is None:
+ return
+
+ row = layout.row()
+ row.prop(settings, "show_bookmarks",
+ text="", icon='RESTRICT_VIEW_OFF')
+ row = row.row(align=True)
+ row.prop(library, "system", text="")
+ row.prop(library, "offset", text="",
+ icon='ARROW_LEFTRIGHT')
+
+ # === BOOKMARKS === #
+ library.bookmarks.draw(context, layout)
+
+ if len(library.bookmarks.collection) == 0:
+ return
+
+ row = layout.row()
+ row = row.split(align=True)
+ # PASTEDOWN
+ # COPYDOWN
+ row.operator("scene.cursor_3d_overwrite_bookmark",
+ text="", icon='REC')
+ row.operator("scene.cursor_3d_swap_bookmark",
+ text="", icon='FILE_REFRESH')
+ row.operator("scene.cursor_3d_recall_bookmark",
+ text="", icon='FILE_TICK')
+ row.operator("scene.cursor_3d_add_empty_at_bookmark",
+ text="", icon='EMPTY_DATA')
+ # Not implemented (and maybe shouldn't)
+ #row.operator("scene.cursor_3d_snap_selection_to_bookmark",
+ # text="", icon='SNAP_ON')
+
+class SetCursorDialog(bpy.types.Operator):
+ bl_idname = "view3d.set_cursor3d_dialog"
+ bl_label = "Set 3D Cursor"
+ bl_description = "Set 3D Cursor XYZ values"
+
+ pos = bpy.props.FloatVectorProperty(
+ name="Location",
+ description="3D Cursor location in current coordinate system",
+ subtype='XYZ',
+ )
+
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def execute(self, context):
+ scene = context.scene
+
+ # "current system" / "relative" could have changed
+ self.matrix = self.csu.get_matrix()
+
+ pos = self.matrix * self.pos
+ set_cursor_location(pos, v3d=context.space_data)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ scene = context.scene
+
+ cursor_pos = get_cursor_location(v3d=context.space_data)
+
+ particles, self.csu = gather_particles(context=context)
+ self.csu.source_pos = cursor_pos
+
+ self.matrix = self.csu.get_matrix()
+
+ try:
+ self.pos = self.matrix.inverted() * cursor_pos
+ except:
+ # this is some degenerate system
+ self.pos = Vector()
+
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self, width=160)
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = find_settings()
+ tfm_opts = settings.transform_options
+
+ v3d = context.space_data
+
+ col = layout.column()
+ col.prop(self, "pos", text="")
+
+ row = layout.row()
+ row.prop(tfm_opts, "use_relative_coords", text="Relative")
+ row.prop(v3d, "transform_orientation", text="")
+
+class AlignOrientationProperties(bpy.types.PropertyGroup):
+ axes_items = [
+ ('X', 'X', 'X axis'),
+ ('Y', 'Y', 'Y axis'),
+ ('Z', 'Z', 'Z axis'),
+ ('-X', '-X', '-X axis'),
+ ('-Y', '-Y', '-Y axis'),
+ ('-Z', '-Z', '-Z axis'),
+ ]
+
+ axes_items_ = [
+ ('X', 'X', 'X axis'),
+ ('Y', 'Y', 'Y axis'),
+ ('Z', 'Z', 'Z axis'),
+ (' ', ' ', 'Same as source axis'),
+ ]
+
+ def get_orients(self, context):
+ orients = []
+ orients.append(('GLOBAL', "Global", ""))
+ orients.append(('LOCAL', "Local", ""))
+ orients.append(('GIMBAL', "Gimbal", ""))
+ orients.append(('NORMAL', "Normal", ""))
+ orients.append(('VIEW', "View", ""))
+
+ for orientation in context.scene.orientations:
+ name = orientation.name
+ orients.append((name, name, ""))
+
+ return orients
+
+ src_axis = bpy.props.EnumProperty(default='Z', items=axes_items,
+ name="Initial axis")
+ #src_orient = bpy.props.EnumProperty(default='GLOBAL', items=get_orients)
+
+ dest_axis = bpy.props.EnumProperty(default=' ', items=axes_items_,
+ name="Final axis")
+ dest_orient = bpy.props.EnumProperty(items=get_orients,
+ name="Final orientation")
+
+class AlignOrientation(bpy.types.Operator):
+ bl_idname = "view3d.align_orientation"
+ bl_label = "Align Orientation"
+ bl_description = "Rotates active object to match axis of current "\
+ "orientation to axis of another orientation"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ axes_items = [
+ ('X', 'X', 'X axis'),
+ ('Y', 'Y', 'Y axis'),
+ ('Z', 'Z', 'Z axis'),
+ ('-X', '-X', '-X axis'),
+ ('-Y', '-Y', '-Y axis'),
+ ('-Z', '-Z', '-Z axis'),
+ ]
+
+ axes_items_ = [
+ ('X', 'X', 'X axis'),
+ ('Y', 'Y', 'Y axis'),
+ ('Z', 'Z', 'Z axis'),
+ (' ', ' ', 'Same as source axis'),
+ ]
+
+ axes_ids = {'X':0, 'Y':1, 'Z':2}
+
+ def get_orients(self, context):
+ orients = []
+ orients.append(('GLOBAL', "Global", ""))
+ orients.append(('LOCAL', "Local", ""))
+ orients.append(('GIMBAL', "Gimbal", ""))
+ orients.append(('NORMAL', "Normal", ""))
+ orients.append(('VIEW', "View", ""))
+
+ for orientation in context.scene.orientations:
+ name = orientation.name
+ orients.append((name, name, ""))
+
+ return orients
+
+ src_axis = bpy.props.EnumProperty(default='Z', items=axes_items,
+ name="Initial axis")
+ #src_orient = bpy.props.EnumProperty(default='GLOBAL', items=get_orients)
+
+ dest_axis = bpy.props.EnumProperty(default=' ', items=axes_items_,
+ name="Final axis")
+ dest_orient = bpy.props.EnumProperty(items=get_orients,
+ name="Final orientation")
+
+ @classmethod
+ def poll(cls, context):
+ return (context.area.type == 'VIEW_3D') and context.object
+
+ def execute(self, context):
+ wm = context.window_manager
+ obj = context.object
+ scene = context.scene
+ v3d = context.space_data
+ rv3d = context.region_data
+
+ particles, csu = gather_particles(context=context)
+ tou = csu.tou
+ #tou = TransformOrientationUtility(scene, v3d, rv3d)
+
+ aop = wm.align_orientation_properties # self
+
+ src_matrix = tou.get_matrix()
+ src_axes = MatrixDecompose(src_matrix)
+ src_axis_name = aop.src_axis
+ if src_axis_name.startswith("-"):
+ src_axis_name = src_axis_name[1:]
+ src_axis = -src_axes[self.axes_ids[src_axis_name]]
+ else:
+ src_axis = src_axes[self.axes_ids[src_axis_name]]
+
+ tou.set(aop.dest_orient, False)
+ dest_matrix = tou.get_matrix()
+ dest_axes = MatrixDecompose(dest_matrix)
+ if self.dest_axis != ' ':
+ dest_axis_name = aop.dest_axis
+ else:
+ dest_axis_name = src_axis_name
+ dest_axis = dest_axes[self.axes_ids[dest_axis_name]]
+
+ q = src_axis.rotation_difference(dest_axis)
+
+ m = obj.matrix_world.to_3x3()
+ m.rotate(q)
+ m.resize_4x4()
+ m.translation = obj.matrix_world.translation.copy()
+
+ obj.matrix_world = m
+
+ #bpy.ops.ed.undo_push(message="Align Orientation")
+
+ return {'FINISHED'}
+
+ # ATTENTION!
+ # This _must_ be a dialog, because with 'UNDO' option
+ # the last selected orientation may revert to the previous state
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self, width=200)
+
+ def draw(self, context):
+ layout = self.layout
+ wm = context.window_manager
+ aop = wm.align_orientation_properties # self
+ layout.prop(aop, "src_axis")
+ layout.prop(aop, "dest_axis")
+ layout.prop(aop, "dest_orient")
+
+class CopyOrientation(bpy.types.Operator):
+ bl_idname = "view3d.copy_orientation"
+ bl_label = "Copy Orientation"
+ bl_description = "Makes a copy of current orientation"
+
+ def execute(self, context):
+ scene = context.scene
+ v3d = context.space_data
+ rv3d = context.region_data
+
+ particles, csu = gather_particles(context=context)
+ tou = csu.tou
+ #tou = TransformOrientationUtility(scene, v3d, rv3d)
+
+ orient = create_transform_orientation(scene,
+ name=tou.get()+".copy", matrix=tou.get_matrix())
+
+ tou.set(orient.name)
+
+ return {'FINISHED'}
+
+def transform_orientations_panel_extension(self, context):
+ row = self.layout.row()
+ row.operator("view3d.align_orientation", text="Align")
+ row.operator("view3d.copy_orientation", text="Copy")
+
+# ===== CURSOR MONITOR ===== #
+class CursorMonitor(bpy.types.Operator):
+ """Monitor changes in cursor location and write to history"""
+ bl_idname = "view3d.cursor3d_monitor"
+ bl_label = "Cursor Monitor"
+
+ # A class-level variable (it must be accessed from poll())
+ is_running = False
+
+ storage = {}
+
+ @classmethod
+ def poll(cls, context):
+ try:
+ runtime_settings = find_runtime_settings()
+ if not runtime_settings:
+ return False
+
+ # When addon is enabled by default and
+ # user started another new scene, is_running
+ # would still be True
+ return (not CursorMonitor.is_running) or \
+ (runtime_settings.current_monitor_id == 0)
+ except Exception as e:
+ print("Cursor monitor exeption in poll:\n" + str(e))
+ return False
+
+ def modal(self, context, event):
+ try:
+ return self._modal(context, event)
+ except Exception as e:
+ print("Cursor monitor exeption in modal:\n" + str(e))
+ # Remove callbacks at any cost
+ self.cancel(context)
+ #raise
+ return {'CANCELLED'}
+
+ def _modal(self, context, event):
+ runtime_settings = find_runtime_settings()
+
+ # ATTENTION: will this work correctly when another
+ # blend is loaded? (it should, since all scripts
+ # seem to be reloaded in such case)
+ if (runtime_settings is None) or \
+ (self.id != runtime_settings.current_monitor_id):
+ # Another (newer) monitor was launched;
+ # this one should stop.
+ # (OR addon was disabled)
+ return self.cancel(context)
+
+ # Somewhy after addon re-registration
+ # this permanently becomes False
+ CursorMonitor.is_running = True
+
+ if self.update_storage(runtime_settings):
+ # hmm... can this cause flickering of menus?
+ context.area.tag_redraw()
+
+ settings = find_settings()
+
+ # ================== #
+ # Update bookmark enums when addon is initialized.
+ # Since CursorMonitor operator can be called from draw(),
+ # we have to postpone all re-registration-related tasks
+ # (such as redefining the enums).
+ if self.just_initialized:
+ # update the relevant enums, bounds and other options
+ # (is_running becomes False once another scene is loaded,
+ # so this operator gets restarted)
+ settings.history.update_max_size()
+ settings.libraries.update_enum()
+ library = settings.libraries.get_item()
+ if library:
+ library.bookmarks.update_enum()
+
+ self.just_initialized = False
+ # ================== #
+
+ # Seems like recalc_csu() in this place causes trouble
+ # if space type is switched from 3D to e.g. UV
+ '''
+ tfm_operator = CursorDynamicSettings.active_transform_operator
+ if tfm_operator:
+ CursorDynamicSettings.csu = tfm_operator.csu
+ else:
+ CursorDynamicSettings.recalc_csu(context, event.value)
+ '''
+
+ return {'PASS_THROUGH'}
+
+ def update_storage(self, runtime_settings):
+ if CursorDynamicSettings.active_transform_operator:
+ # Don't add to history while operator is running
+ return False
+
+ new_pos = None
+
+ last_locations = {}
+
+ for scene in bpy.data.scenes:
+ # History doesn't depend on view (?)
+ curr_pos = get_cursor_location(scene=scene)
+
+ last_locations[scene.name] = curr_pos
+
+ # Ignore newly-created or some renamed scenes
+ if scene.name in self.last_locations:
+ if curr_pos != self.last_locations[scene.name]:
+ new_pos = curr_pos
+ elif runtime_settings.current_monitor_id == 0:
+ # startup location should be added
+ new_pos = curr_pos
+
+ # Seems like scene.cursor_location is fast enough here
+ # -> no need to resort to v3d.cursor_location.
+ """
+ screen = bpy.context.screen
+ scene = screen.scene
+ v3d = None
+ for area in screen.areas:
+ for space in area.spaces:
+ if space.type == 'VIEW_3D':
+ v3d = space
+ break
+
+ if v3d is not None:
+ curr_pos = get_cursor_location(v3d=v3d)
+
+ last_locations[scene.name] = curr_pos
+
+ # Ignore newly-created or some renamed scenes
+ if scene.name in self.last_locations:
+ if curr_pos != self.last_locations[scene.name]:
+ new_pos = curr_pos
+ """
+
+ self.last_locations = last_locations
+
+ if new_pos is not None:
+ settings = find_settings()
+ history = settings.history
+
+ pos = history.get_pos()
+ if (pos is not None):# and (history.current_id != 0): # ?
+ if pos == new_pos:
+ return False # self.just_initialized ?
+
+ entry = history.entries.add()
+ entry.pos = new_pos
+
+ last_id = len(history.entries) - 1
+ history.entries.move(last_id, 0)
+
+ if last_id > int(history.max_size):
+ history.entries.remove(last_id)
+
+ # make sure the most recent history entry is displayed
+
+ CursorHistoryProp.update_cursor_on_id_change = False
+ history.current_id = 0
+ CursorHistoryProp.update_cursor_on_id_change = True
+
+ history.curr_id = history.current_id
+ history.last_id = 1
+
+ return True
+
+ return False # self.just_initialized ?
+
+ def execute(self, context):
+ print("Cursor monitor: launched")
+
+ runtime_settings = find_runtime_settings()
+
+ self.just_initialized = True
+
+ self.id = 0
+
+ self.last_locations = {}
+
+ # Important! Call update_storage() before assigning
+ # current_monitor_id (used to add startup cursor location)
+ self.update_storage(runtime_settings)
+
+ # Indicate that this is the most recent monitor.
+ # All others should shut down.
+ self.id = runtime_settings.current_monitor_id + 1
+ runtime_settings.current_monitor_id = self.id
+
+ CursorMonitor.is_running = True
+
+ CursorDynamicSettings.recalc_csu(context, 'PRESS')
+
+ # I suppose that cursor position would change
+ # only with user interaction.
+ #self._timer = context.window_manager. \
+ # event_timer_add(0.1, context.window)
+
+ #'''
+ #self._draw_callback_view = context.region.callback_add( \
+ # draw_callback_view, (self, context), 'POST_VIEW')
+ self._draw_callback_view = find_region(context.area).\
+ callback_add(draw_callback_view, \
+ (self, context), 'POST_VIEW')
+ self._draw_callback_px = find_region(context.area).\
+ callback_add(draw_callback_px, \
+ (self, context), 'POST_PIXEL')
+
+ self._draw_header_px = find_region(context.area, 'HEADER').\
+ callback_add(draw_callback_header_px, \
+ (self, context), 'POST_PIXEL')
+ #'''
+
+ # Here we cannot return 'PASS_THROUGH',
+ # or Blender will crash!
+
+ # Currently there seems to be only one window
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+ def cancel(self, context):
+ CursorMonitor.is_running = False
+ #type(self).is_running = False
+
+ # Unregister callbacks...
+ #'''
+ #context.region.callback_remove(self._draw_callback_view)
+ find_region(context.area).callback_remove(self._draw_callback_view)
+ find_region(context.area).callback_remove(self._draw_callback_px)
+
+ find_region(context.area, 'HEADER').\
+ callback_remove(self._draw_header_px)
+ #'''
+
+ return {'CANCELLED'}
+
+
+# ===== MATH / GEOMETRY UTILITIES ===== #
+def to_matrix4x4(orient, pos):
+ if not isinstance(orient, Matrix):
+ orient = orient.to_matrix()
+ m = orient.to_4x4()
+ m.translation = pos.to_3d()
+ return m
+
+def MatrixCompose(*args):
+ size = len(args)
+ m = Matrix.Identity(size)
+ axes = m.col # m.row
+
+ if size == 2:
+ for i in (0, 1):
+ c = args[i]
+ if isinstance(c, Vector):
+ axes[i] = c.to_2d()
+ elif hasattr(c, "__iter__"):
+ axes[i] = Vector(c).to_2d()
+ else:
+ axes[i][i] = c
+ else:
+ for i in (0, 1, 2):
+ c = args[i]
+ if isinstance(c, Vector):
+ axes[i][:3] = c.to_3d()
+ elif hasattr(c, "__iter__"):
+ axes[i][:3] = Vector(c).to_3d()
+ else:
+ axes[i][i] = c
+
+ if size == 4:
+ c = args[3]
+ if isinstance(c, Vector):
+ m.translation = c.to_3d()
+ elif hasattr(c, "__iter__"):
+ m.translation = Vector(c).to_3d()
+
+ return m
+
+def MatrixDecompose(m, res_size=None):
+ size = len(m)
+ axes = m.col # m.row
+ if res_size is None:
+ res_size = size
+
+ if res_size == 2:
+ return (axes[0].to_2d(), axes[1].to_2d())
+ else:
+ x = axes[0].to_3d()
+ y = axes[1].to_3d()
+ z = (axes[2].to_3d() if size > 2 else Vector())
+ if res_size == 3:
+ return (x, y, z)
+
+ t = (m.translation.to_3d() if size == 4 else Vector())
+ if res_size == 4:
+ return (x, y, z, t)
+
+def angle_axis_to_quat(angle, axis):
+ w = math.cos(angle / 2.0)
+ xyz = axis.normalized() * math.sin(angle / 2.0)
+ return Quaternion((w, xyz.x, xyz.y, xyz.z))
+
+def round_step(x, s=1.0):
+ #return math.floor(x * s + 0.5) / s
+ return math.floor(x / s + 0.5) * s
+
+twoPi = 2.0 * math.pi
+def clamp_angle(ang):
+ # Attention! In Python the behaviour is:
+ # -359.0 % 180.0 == 1.0
+ # -359.0 % -180.0 == -179.0
+ ang = (ang % twoPi)
+ return ((ang - twoPi) if (ang > math.pi) else ang)
+
+def prepare_grid_mesh(bm, nx=1, ny=1, sx=1.0, sy=1.0,
+ z=0.0, xyz_indices=(0,1,2)):
+ vertices = []
+ for i in range(nx + 1):
+ x = 2 * (i / nx) - 1
+ x *= sx
+ for j in range(ny + 1):
+ y = 2 * (j / ny) - 1
+ y *= sy
+ pos = (x, y, z)
+ vert = bm.verts.new((pos[xyz_indices[0]],
+ pos[xyz_indices[1]],
+ pos[xyz_indices[2]]))
+ vertices.append(vert)
+
+ nxmax = nx + 1
+ for i in range(nx):
+ i1 = i + 1
+ for j in range(ny):
+ j1 = j + 1
+ verts = [vertices[j + i * nxmax],
+ vertices[j1 + i * nxmax],
+ vertices[j1 + i1 * nxmax],
+ vertices[j + i1 * nxmax]]
+ bm.faces.new(verts)
+ #return
+
+def prepare_gridbox_mesh(subdiv=1):
+ bm = bmesh.new()
+
+ sides = [
+ (-1, (0,1,2)), # -Z
+ (1, (1,0,2)), # +Z
+ (-1, (1,2,0)), # -Y
+ (1, (0,2,1)), # +Y
+ (-1, (2,0,1)), # -X
+ (1, (2,1,0)), # +X
+ ]
+
+ for side in sides:
+ prepare_grid_mesh(bm, nx=subdiv, ny=subdiv,
+ z=side[0], xyz_indices=side[1])
+
+ return bm
+
+# ===== DRAWING UTILITIES ===== #
+class GfxCell:
+ def __init__(self, w, h, color=None, alpha=None, draw=None):
+ self.w = w
+ self.h = h
+
+ self.color = (0, 0, 0, 1)
+ self.set_color(color, alpha)
+
+ if draw:
+ self.draw = draw
+
+ def set_color(self, color=None, alpha=None):
+ if color is None:
+ color = self.color
+ if alpha is None:
+ alpha = (color[3] if len(color) > 3 else self.color[3])
+ self.color = Vector((color[0], color[1], color[2], alpha))
+
+ def prepare_draw(self, x, y, align=(0, 0)):
+ if self.color[3] <= 0.0:
+ return None
+
+ if (align[0] != 0) or (align[1] != 0):
+ x -= self.w * align[0]
+ y -= self.h * align[1]
+
+ x = int(math.floor(x + 0.5))
+ y = int(math.floor(y + 0.5))
+
+ bgl.glColor4f(*self.color)
+
+ return x, y
+
+ def draw(self, x, y, align=(0, 0)):
+ xy = self.prepare_draw(x, y, align)
+ if not xy:
+ return
+
+ draw_rect(xy[0], xy[1], w, h)
+
+class TextCell(GfxCell):
+ font_id = 0
+
+ def __init__(self, text="", color=None, alpha=None, font_id=None):
+ if font_id is None:
+ font_id = TextCell.font_id
+ self.font_id = font_id
+
+ self.set_text(text)
+
+ self.color = (0, 0, 0, 1)
+ self.set_color(color, alpha)
+
+ def set_text(self, text):
+ self.text = str(text)
+ dims = blf.dimensions(self.font_id, self.text)
+ self.w = dims[0]
+ dims = blf.dimensions(self.font_id, "dp") # fontheight
+ self.h = dims[1]
+
+ def draw(self, x, y, align=(0, 0)):
+ xy = self.prepare_draw(x, y, align)
+ if not xy:
+ return
+
+ blf.position(self.font_id, xy[0], xy[1], 0)
+ blf.draw(self.font_id, self.text)
+
+def find_region(area, region_type='WINDOW'):
+ # 'WINDOW', 'HEADER', 'CHANNELS', 'TEMPORARY',
+ # 'UI', 'TOOLS', 'TOOL_PROPS', 'PREVIEW'
+ for region in area.regions:
+ if region.type == region_type:
+ return region
+
+def draw_text(x, y, value, font_id=0, align=(0, 0), font_height=None):
+ value = str(value)
+
+ if (align[0] != 0) or (align[1] != 0):
+ dims = blf.dimensions(font_id, value)
+ if font_height is not None:
+ dims = (dims[0], font_height)
+ x -= dims[0] * align[0]
+ y -= dims[1] * align[1]
+
+ x = int(math.floor(x + 0.5))
+ y = int(math.floor(y + 0.5))
+
+ blf.position(font_id, x, y, 0)
+ blf.draw(font_id, value)
+
+def draw_rect(x, y, w, h, margin=0, outline=False):
+ if w < 0:
+ x += w
+ w = abs(w)
+
+ if h < 0:
+ y += h
+ h = abs(h)
+
+ x = int(x)
+ y = int(y)
+ w = int(w)
+ h = int(h)
+ margin = int(margin)
+
+ if outline:
+ bgl.glBegin(bgl.GL_LINE_LOOP)
+ else:
+ bgl.glBegin(bgl.GL_TRIANGLE_FAN)
+ bgl.glVertex2i(x - margin, y - margin)
+ bgl.glVertex2i(x + w + margin, y - margin)
+ bgl.glVertex2i(x + w + margin, y + h + margin)
+ bgl.glVertex2i(x - margin, y + h + margin)
+ bgl.glEnd()
+
+def append_round_rect(verts, x, y, w, h, rw, rh=None):
+ if rh is None:
+ rh = rw
+
+ if w < 0:
+ x += w
+ w = abs(w)
+
+ if h < 0:
+ y += h
+ h = abs(h)
+
+ if rw < 0:
+ rw = min(abs(rw), w * 0.5)
+ x += rw
+ w -= rw * 2
+
+ if rh < 0:
+ rh = min(abs(rh), h * 0.5)
+ y += rh
+ h -= rh * 2
+
+ n = int(max(rw, rh) * math.pi / 2.0)
+
+ a0 = 0.0
+ a1 = math.pi / 2.0
+ append_oval_segment(verts, x + w, y + h, rw, rh, a0, a1, n)
+
+ a0 = math.pi / 2.0
+ a1 = math.pi
+ append_oval_segment(verts, x + w, y, rw, rh, a0, a1, n)
+
+ a0 = math.pi
+ a1 = 3.0 * math.pi / 2.0
+ append_oval_segment(verts, x, y, rw, rh, a0, a1, n)
+
+ a0 = 3.0 * math.pi / 2.0
+ a1 = math.pi * 2.0
+ append_oval_segment(verts, x, y + h, rw, rh, a0, a1, n)
+
+def append_oval_segment(verts, x, y, rw, rh, a0, a1, n, skip_last=False):
+ nmax = n - 1
+ da = a1 - a0
+ for i in range(n - int(skip_last)):
+ a = a0 + da * (i / nmax)
+ dx = math.sin(a) * rw
+ dy = math.cos(a) * rh
+ verts.append((x + int(dx), y + int(dy)))
+
+def draw_line(p0, p1, c=None):
+ if c is not None:
+ bgl.glColor4f(c[0], c[1], c[2], \
+ (c[3] if len(c) > 3 else 1.0))
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex3f(p0[0], p0[1], p0[2])
+ bgl.glVertex3f(p1[0], p1[1], p1[2])
+ bgl.glEnd()
+
+def draw_line_2d(p0, p1, c=None):
+ if c is not None:
+ bgl.glColor4f(c[0], c[1], c[2], \
+ (c[3] if len(c) > 3 else 1.0))
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex2f(p0[0], p0[1])
+ bgl.glVertex2f(p1[0], p1[1])
+ bgl.glEnd()
+
+def draw_line_hidden_depth(p0, p1, c, a0=1.0, a1=0.5, s0=None, s1=None):
+ bgl.glEnable(bgl.GL_DEPTH_TEST)
+ bgl.glColor4f(c[0], c[1], c[2], a0)
+ if s0 is not None:
+ gl_enable(bgl.GL_LINE_STIPPLE, int(bool(s0)))
+ draw_line(p0, p1)
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
+ if (a1 == a0) and (s1 == s0):
+ return
+ bgl.glColor4f(c[0], c[1], c[2], a1)
+ if s1 is not None:
+ gl_enable(bgl.GL_LINE_STIPPLE, int(bool(s1)))
+ draw_line(p0, p1)
+
+def draw_arrow(p0, x, y, z, n_scl=0.2, ort_scl=0.035):
+ p1 = p0 + z
+
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ bgl.glVertex3f(p0[0], p0[1], p0[2])
+ bgl.glVertex3f(p1[0], p1[1], p1[2])
+ bgl.glEnd()
+
+ p2 = p1 - z * n_scl
+ bgl.glBegin(bgl.GL_TRIANGLE_FAN)
+ bgl.glVertex3f(p1[0], p1[1], p1[2])
+ p3 = p2 + (x + y) * ort_scl
+ bgl.glVertex3f(p3[0], p3[1], p3[2])
+ p3 = p2 + (-x + y) * ort_scl
+ bgl.glVertex3f(p3[0], p3[1], p3[2])
+ p3 = p2 + (-x - y) * ort_scl
+ bgl.glVertex3f(p3[0], p3[1], p3[2])
+ p3 = p2 + (x - y) * ort_scl
+ bgl.glVertex3f(p3[0], p3[1], p3[2])
+ p3 = p2 + (x + y) * ort_scl
+ bgl.glVertex3f(p3[0], p3[1], p3[2])
+ bgl.glEnd()
+
+def draw_arrow_2d(p0, n, L, arrow_len, arrow_width):
+ p1 = p0 + n * L
+ t = Vector((-n[1], n[0]))
+ pA = p1 - n * arrow_len + t * arrow_width
+ pB = p1 - n * arrow_len - t * arrow_width
+
+ bgl.glBegin(bgl.GL_LINES)
+
+ bgl.glVertex2f(p0[0], p0[1])
+ bgl.glVertex2f(p1[0], p1[1])
+
+ bgl.glVertex2f(p1[0], p1[1])
+ bgl.glVertex2f(pA[0], pA[1])
+
+ bgl.glVertex2f(p1[0], p1[1])
+ bgl.glVertex2f(pB[0], pB[1])
+
+ bgl.glEnd()
+
+# Store/restore OpenGL settings and working with
+# projection matrices -- inspired by space_view3d_panel_measure
+# of Buerbaum Martin (Pontiac).
+
+# OpenGl helper functions/data
+gl_state_info = {
+ bgl.GL_MATRIX_MODE:(bgl.GL_INT, 1),
+ bgl.GL_PROJECTION_MATRIX:(bgl.GL_DOUBLE, 16),
+ bgl.GL_LINE_WIDTH:(bgl.GL_FLOAT, 1),
+ bgl.GL_BLEND:(bgl.GL_BYTE, 1),
+ bgl.GL_LINE_STIPPLE:(bgl.GL_BYTE, 1),
+ bgl.GL_COLOR:(bgl.GL_FLOAT, 4),
+ bgl.GL_SMOOTH:(bgl.GL_BYTE, 1),
+ bgl.GL_DEPTH_TEST:(bgl.GL_BYTE, 1),
+ bgl.GL_DEPTH_WRITEMASK:(bgl.GL_BYTE, 1),
+}
+gl_type_getters = {
+ bgl.GL_INT:bgl.glGetIntegerv,
+ bgl.GL_DOUBLE:bgl.glGetFloatv, # ?
+ bgl.GL_FLOAT:bgl.glGetFloatv,
+ #bgl.GL_BYTE:bgl.glGetFloatv, # Why GetFloat for getting byte???
+ bgl.GL_BYTE:bgl.glGetBooleanv, # maybe like that?
+}
+
+def gl_get(state_id):
+ type, size = gl_state_info[state_id]
+ buf = bgl.Buffer(type, [size])
+ gl_type_getters[type](state_id, buf)
+ return (buf if (len(buf) != 1) else buf[0])
+
+def gl_enable(state_id, enable):
+ if enable:
+ bgl.glEnable(state_id)
+ else:
+ bgl.glDisable(state_id)
+
+def gl_matrix_to_buffer(m):
+ tempMat = [m[i][j] for i in range(4) for j in range(4)]
+ return bgl.Buffer(bgl.GL_FLOAT, 16, tempMat)
+
+
+# ===== DRAWING CALLBACKS ===== #
+cursor_save_location = Vector()
+
+def draw_callback_view(self, context):
+ global cursor_save_location
+
+ settings = find_settings()
+ if settings is None:
+ return
+
+ update_stick_to_obj(context)
+
+ if "EDIT" not in context.mode:
+ # It's nice to have bookmark position update interactively
+ # However, this still can be slow if there are many
+ # selected objects
+
+ # ATTENTION!!!
+ # This eats a lot of processor time!
+ #CursorDynamicSettings.recalc_csu(context, 'PRESS')
+ pass
+
+ history = settings.history
+
+ tfm_operator = CursorDynamicSettings.active_transform_operator
+
+ is_drawing = history.show_trace or tfm_operator
+
+ if is_drawing:
+ # Store previous OpenGL settings
+ MatrixMode_prev = gl_get(bgl.GL_MATRIX_MODE)
+ ProjMatrix_prev = gl_get(bgl.GL_PROJECTION_MATRIX)
+ lineWidth_prev = gl_get(bgl.GL_LINE_WIDTH)
+ blend_prev = gl_get(bgl.GL_BLEND)
+ line_stipple_prev = gl_get(bgl.GL_LINE_STIPPLE)
+ color_prev = gl_get(bgl.GL_COLOR)
+ smooth_prev = gl_get(bgl.GL_SMOOTH)
+ depth_test_prev = gl_get(bgl.GL_DEPTH_TEST)
+ depth_mask_prev = gl_get(bgl.GL_DEPTH_WRITEMASK)
+
+ if history.show_trace:
+ bgl.glDepthRange(0.0, 0.9999)
+
+ history.draw_trace(context)
+
+ library = settings.libraries.get_item()
+ if library and library.offset:
+ history.draw_offset(context)
+
+ bgl.glDepthRange(0.0, 1.0)
+
+ if tfm_operator:
+ tfm_operator.draw_3d(context)
+
+ if is_drawing:
+ # Restore previous OpenGL settings
+ bgl.glLineWidth(lineWidth_prev)
+ gl_enable(bgl.GL_BLEND, blend_prev)
+ gl_enable(bgl.GL_LINE_STIPPLE, line_stipple_prev)
+ gl_enable(bgl.GL_SMOOTH, smooth_prev)
+ gl_enable(bgl.GL_DEPTH_TEST, depth_test_prev)
+ bgl.glDepthMask(depth_mask_prev)
+ bgl.glColor4f(color_prev[0],
+ color_prev[1],
+ color_prev[2],
+ color_prev[3])
+
+ cursor_save_location = Vector(bpy.context.space_data.cursor_location)
+ if not settings.cursor_visible:
+ # This is causing problems! See <http://projects.blender.org/
+ # tracker/index.php?func=detail&aid=33197&group_id=9&atid=498>
+ #bpy.context.space_data.cursor_location = Vector([float('nan')] * 3)
+ pass
+
+def draw_callback_header_px(self, context):
+ r = context.region
+
+ tfm_operator = CursorDynamicSettings.active_transform_operator
+ if not tfm_operator:
+ return
+
+ smooth_prev = gl_get(bgl.GL_SMOOTH)
+
+ tfm_operator.draw_axes_coords(context, (r.width, r.height))
+
+ gl_enable(bgl.GL_SMOOTH, smooth_prev)
+
+ bgl.glDisable(bgl.GL_BLEND)
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+
+def draw_callback_px(self, context):
+ global cursor_save_location
+ settings = find_settings()
+ if settings is None:
+ return
+ library = settings.libraries.get_item()
+
+ if not settings.cursor_visible:
+ bpy.context.space_data.cursor_location = cursor_save_location
+
+ tfm_operator = CursorDynamicSettings.active_transform_operator
+
+ if settings.show_bookmarks and library:
+ library.draw_bookmark(context)
+
+ if tfm_operator:
+ tfm_operator.draw_2d(context)
+
+ # restore opengl defaults
+ bgl.glLineWidth(1)
+ bgl.glDisable(bgl.GL_BLEND)
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+
+
+# ===== UTILITY FUNCTIONS ===== #
+
+def update_stick_to_obj(context):
+ settings = find_settings()
+
+ if not settings.stick_to_obj:
+ return
+
+ scene = context.scene
+
+ settings_scene = scene.cursor_3d_tools_settings
+
+ name = settings_scene.stick_obj_name
+
+ try:
+ obj = scene.objects[name]
+ pos = settings_scene.stick_obj_pos
+ pos = obj.matrix_world * pos
+ context.space_data.cursor_location = pos
+ except Exception as e:
+ pass
+
+def get_cursor_location(v3d=None, scene=None):
+ if v3d:
+ pos = v3d.cursor_location
+ elif scene:
+ pos = scene.cursor_location
+
+ return pos.copy()
+
+def set_cursor_location(pos, v3d=None, scene=None):
+ pos = pos.to_3d().copy()
+
+ if v3d:
+ scene = bpy.context.scene
+ # Accessing scene.cursor_location is SLOW
+ # (well, at least assigning to it).
+ # Accessing v3d.cursor_location is fast.
+ v3d.cursor_location = pos
+ elif scene:
+ scene.cursor_location = pos
+
+ set_stick_obj(scene, None)
+
+def set_stick_obj(scene, name=None, pos=None):
+ settings_scene = scene.cursor_3d_tools_settings
+
+ if name:
+ settings_scene.stick_obj_name = name
+ else:
+ settings_scene.stick_obj_name = ""
+
+ if pos is not None:
+ settings_scene.stick_obj_pos = Vector(pos).to_3d()
+
+# WHERE TO STORE SETTINGS:
+# Currently there are two types of ID blocks
+# which properties don't change on Undo/Redo.
+# - WindowManager seems to be unique (at least
+# for majority of situations). However, the
+# properties stored in it are not saved
+# with the blend.
+# - Screen. Properties are saved with blend,
+# but there is some probability that any of
+# the pre-chosen screen names may not exist
+# in the user's blend.
+
+def find_settings():
+ #wm = bpy.data.window_managers[0]
+ #settings = wm.cursor_3d_tools_settings
+
+ screen = bpy.data.screens.get("Default", bpy.data.screens[0])
+ try:
+ settings = screen.cursor_3d_tools_settings
+ except:
+ # addon was unregistered
+ settings = None
+
+ return settings
+
+def find_runtime_settings():
+ wm = bpy.data.window_managers[0]
+ try:
+ runtime_settings = wm.cursor_3d_runtime_settings
+ except:
+ # addon was unregistered
+ runtime_settings = None
+
+ return runtime_settings
+
+# ===== REGISTRATION ===== #
+def find_keymap_items(km, idname):
+ items = []
+ for kmi in km.keymap_items:
+ if kmi.idname == idname:
+ items.append(kmi)
+ return items
+
+def update_keymap(activate):
+ #if activate:
+ # if bpy.ops.view3d.cursor3d_monitor.poll():
+ # bpy.ops.view3d.cursor3d_monitor()
+
+ wm = bpy.context.window_manager
+
+ try:
+ km = wm.keyconfigs.user.keymaps['3D View']
+ except:
+ # wm.keyconfigs.user is empty on Blender startup!
+ if activate:
+ # activate temporary operator
+ km = wm.keyconfigs.active.keymaps['Window']
+ kmi = km.keymap_items.new( \
+ 'wm.enhanced_3d_cursor_registration', \
+ 'MOUSEMOVE', 'ANY')
+ return
+
+ # We need for the enhanced operator to take precedence over
+ # the default cursor3d, but not over the manipulator.
+ # If we add the operator to "addon" keymaps, it will
+ # take precedence over both. If we add it to "user"
+ # keymaps, the default will take precedence.
+ # However, we may just simply turn it off or remove
+ # (depending on what saves with blend).
+
+ items = find_keymap_items(km, 'view3d.cursor3d_enhanced')
+ if activate and (len(items) == 0):
+ kmi = km.keymap_items.new('view3d.cursor3d_enhanced', \
+ 'ACTIONMOUSE', 'PRESS')
+ for key in EnhancedSetCursor.key_map["free_mouse"]:
+ kmi = km.keymap_items.new('view3d.cursor3d_enhanced', \
+ key, 'PRESS')
+ else:
+ if activate:
+ for kmi in items:
+ kmi.active = activate
+ else:
+ for kmi in items:
+ km.keymap_items.remove(kmi)
+
+ for kmi in find_keymap_items(km, 'view3d.cursor3d'):
+ kmi.active = not activate
+
+ try:
+ km = wm.keyconfigs.active.keymaps['3D View']
+ for kmi in find_keymap_items(km, 'view3d.cursor3d'):
+ kmi.active = not activate
+ except KeyError:
+ # seems like in recent builds (after 2.63a)
+ # 'bpy_prop_collection[key]: key "3D View" not found'
+ pass
+
+ try:
+ km = wm.keyconfigs.default.keymaps['3D View']
+ for kmi in find_keymap_items(km, 'view3d.cursor3d'):
+ kmi.active = not activate
+ except KeyError:
+ pass
+
+def register():
+ bpy.utils.register_class(AlignOrientationProperties)
+ bpy.utils.register_class(AlignOrientation)
+ bpy.utils.register_class(CopyOrientation)
+ bpy.types.WindowManager.align_orientation_properties = \
+ bpy.props.PointerProperty(type=AlignOrientationProperties)
+ bpy.types.VIEW3D_PT_transform_orientations.append(
+ transform_orientations_panel_extension)
+
+ bpy.utils.register_class(SetCursorDialog)
+
+ bpy.utils.register_class(NewCursor3DBookmarkLibrary)
+ bpy.utils.register_class(DeleteCursor3DBookmarkLibrary)
+
+ bpy.utils.register_class(NewCursor3DBookmark)
+ bpy.utils.register_class(DeleteCursor3DBookmark)
+ bpy.utils.register_class(OverwriteCursor3DBookmark)
+ bpy.utils.register_class(RecallCursor3DBookmark)
+ bpy.utils.register_class(SwapCursor3DBookmark)
+ bpy.utils.register_class(SnapSelectionToCursor3DBookmark)
+ bpy.utils.register_class(AddEmptyAtCursor3DBookmark)
+
+ bpy.utils.register_class(TransformExtraOptionsProp)
+ bpy.utils.register_class(TransformExtraOptions)
+
+ # View properties panel is already long. Appending something
+ # to it would make it too inconvenient
+ #bpy.types.VIEW3D_PT_view3d_properties.append(draw_cursor_tools)
+ bpy.utils.register_class(Cursor3DTools)
+
+ bpy.utils.register_class(LocationProp)
+ bpy.utils.register_class(CursorHistoryProp)
+
+ bpy.utils.register_class(BookmarkProp)
+ bpy.utils.register_class(BookmarkIDBlock)
+
+ bpy.utils.register_class(BookmarkLibraryProp)
+ bpy.utils.register_class(BookmarkLibraryIDBlock)
+
+ bpy.utils.register_class(Cursor3DToolsSettings)
+
+ bpy.utils.register_class(CursorRuntimeSettings)
+ bpy.utils.register_class(CursorMonitor)
+
+ bpy.utils.register_class(Cursor3DToolsSceneSettings)
+
+ bpy.types.Screen.cursor_3d_tools_settings = \
+ bpy.props.PointerProperty(type=Cursor3DToolsSettings)
+
+ bpy.types.WindowManager.cursor_3d_runtime_settings = \
+ bpy.props.PointerProperty(type=CursorRuntimeSettings)
+
+ bpy.types.Scene.cursor_3d_tools_settings = \
+ bpy.props.PointerProperty(type=Cursor3DToolsSceneSettings)
+
+ bpy.utils.register_class(EnhancedSetCursor)
+
+ bpy.utils.register_class(DelayRegistrationOperator)
+
+ update_keymap(True)
+
+def unregister():
+ # Manually set this to False on unregister
+ CursorMonitor.is_running = False
+
+ update_keymap(False)
+
+ bpy.utils.unregister_class(DelayRegistrationOperator)
+
+ bpy.utils.unregister_class(EnhancedSetCursor)
+
+ if hasattr(bpy.types.Scene, "cursor_3d_tools_settings"):
+ del bpy.types.Scene.cursor_3d_tools_settings
+
+ if hasattr(bpy.types.WindowManager, "cursor_3d_runtime_settings"):
+ del bpy.types.WindowManager.cursor_3d_runtime_settings
+
+ if hasattr(bpy.types.Screen, "cursor_3d_tools_settings"):
+ del bpy.types.Screen.cursor_3d_tools_settings
+
+ bpy.utils.unregister_class(Cursor3DToolsSceneSettings)
+
+ bpy.utils.unregister_class(CursorMonitor)
+ bpy.utils.unregister_class(CursorRuntimeSettings)
+
+ bpy.utils.unregister_class(Cursor3DToolsSettings)
+
+ bpy.utils.unregister_class(BookmarkLibraryIDBlock)
+ bpy.utils.unregister_class(BookmarkLibraryProp)
+
+ bpy.utils.unregister_class(BookmarkIDBlock)
+ bpy.utils.unregister_class(BookmarkProp)
+
+ bpy.utils.unregister_class(CursorHistoryProp)
+ bpy.utils.unregister_class(LocationProp)
+
+ bpy.utils.unregister_class(Cursor3DTools)
+ #bpy.types.VIEW3D_PT_view3d_properties.remove(draw_cursor_tools)
+
+ bpy.utils.unregister_class(TransformExtraOptions)
+ bpy.utils.unregister_class(TransformExtraOptionsProp)
+
+ bpy.utils.unregister_class(NewCursor3DBookmarkLibrary)
+ bpy.utils.unregister_class(DeleteCursor3DBookmarkLibrary)
+
+ bpy.utils.unregister_class(NewCursor3DBookmark)
+ bpy.utils.unregister_class(DeleteCursor3DBookmark)
+ bpy.utils.unregister_class(OverwriteCursor3DBookmark)
+ bpy.utils.unregister_class(RecallCursor3DBookmark)
+ bpy.utils.unregister_class(SwapCursor3DBookmark)
+ bpy.utils.unregister_class(SnapSelectionToCursor3DBookmark)
+ bpy.utils.unregister_class(AddEmptyAtCursor3DBookmark)
+
+ bpy.utils.unregister_class(SetCursorDialog)
+
+ bpy.types.VIEW3D_PT_transform_orientations.remove(
+ transform_orientations_panel_extension)
+ del bpy.types.WindowManager.align_orientation_properties
+ bpy.utils.unregister_class(CopyOrientation)
+ bpy.utils.unregister_class(AlignOrientation)
+ bpy.utils.unregister_class(AlignOrientationProperties)
+
+class DelayRegistrationOperator(bpy.types.Operator):
+ bl_idname = "wm.enhanced_3d_cursor_registration"
+ bl_label = "[Enhanced 3D Cursor] registration delayer"
+
+ _timer = None
+
+ def modal(self, context, event):
+ if (not self.keymap_updated) and \
+ ((event.type == 'TIMER') or ("MOVE" in event.type)):
+ # clean up (we don't need this operator to run anymore)
+ wm = bpy.context.window_manager
+
+ for kcfg in wm.keyconfigs.values():
+ for km in kcfg.keymaps.values():
+ items = find_keymap_items(km,
+ 'wm.enhanced_3d_cursor_registration')
+ for kmi in items:
+ km.keymap_items.remove(kmi)
+
+ """
+ try:
+ # A bug when using Maya keymap presets
+ # (reported by chafouin in BlenderArtists thread)
+ # KeyError: key "Window" not found'
+ # Circumvent for now.
+ km = wm.keyconfigs.active.keymaps['Window']
+ except KeyError:
+ km = None
+
+ if km:
+ items = find_keymap_items(km,
+ 'wm.enhanced_3d_cursor_registration')
+ for kmi in items:
+ km.keymap_items.remove(kmi)
+ """
+
+ update_keymap(True)
+
+ self.keymap_updated = True
+
+ # No, better don't (at least in current version),
+ # since the monitor has dependencies on View3D context.
+ # Attempt to launch the monitor
+ #if bpy.ops.view3d.cursor3d_monitor.poll():
+ # bpy.ops.view3d.cursor3d_monitor()
+
+ return self.cancel(context)
+
+ return {'PASS_THROUGH'}
+
+ def execute(self, context):
+ self.keymap_updated = False
+
+ self._timer = context.window_manager.\
+ event_timer_add(0.1, context.window)
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+ def cancel(self, context):
+ context.window_manager.event_timer_remove(self._timer)
+
+ return {'CANCELLED'}
+
+if __name__ == "__main__":
+ # launched from the Blender text editor
+ try:
+ register()
+ except Exception as e:
+ print(e)
+ raise
diff --git a/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py b/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py
new file mode 100644
index 0000000..fe169c4
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_game_props_visualiser.py
@@ -0,0 +1,198 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+
+bl_info = {
+ "name": "Game Property Visualizer",
+ "author": "Bartius Crouch/Vilem Novak",
+ "version": (2,5),
+ "blender": (2, 53, 0),
+ "location": "View3D > Properties panel > Display tab",
+ "description": "Display the game properties next to selected objects "
+ "in the 3d-view",
+ "warning": "Script is returning errors",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Game_Property_Visualiser",
+ "tracker_url": "http://projects.blender.org/tracker/?func=detail&aid=22607&group_id=153&atid=468",
+ "category": "3D View"}
+
+"""
+Displays game properties next to selected objects(under name)
+
+How to use:
+ just toggle the button 'Visualize game props' in the right side panel
+"""
+
+import bgl
+import blf
+import bpy
+import mathutils
+
+
+# calculate locations and store them as ID property in the mesh
+def calc_callback(self, context):
+ # polling
+ if context.mode == 'EDIT_MESH':
+ return
+
+ # get screen information
+ mid_x = context.region.width/2.0
+ mid_y = context.region.height/2.0
+ width = context.region.width
+ height = context.region.height
+
+ # get matrices
+ view_mat = context.space_data.region_3d.perspective_matrix
+
+ ob_mat = context.active_object.matrix_world
+ total_mat = view_mat*ob_mat
+
+ # calculate location info
+ texts = []
+
+ # uncomment 2 lines below, to enable live updating of the selection
+ #ob=context.active_object
+ for ob in context.selected_objects:
+ locs = []
+ ob_mat = ob.matrix_world
+ total_mat = view_mat*ob_mat
+
+ for p in ob.game.properties:
+ # d = {'data':p.name+':'+str(p.value)}
+ # print (d)
+ locs.append([ mathutils.Vector([0,0,0]).resize_4d()])
+
+
+ for loc in locs:
+
+ vec = loc[0]*total_mat # order is important
+ # dehomogenise
+ vec = mathutils.Vector((vec[0]/vec[3],vec[1]/vec[3],vec[2]/vec[3]))
+ x = int(mid_x + vec[0]*width/2.0)
+ y = int(mid_y + vec[1]*height/2.0)
+ texts+=[x, y]
+
+
+ # store as ID property in mesh
+ #print (texts)
+ context.scene['GamePropsVisualizer'] = texts
+
+
+# draw in 3d-view
+def draw_callback(self, context):
+ # polling
+ if context.mode == 'EDIT_MESH':
+ return
+ # retrieving ID property data
+ try:
+ #print(context.scene['GamePropsVisualizer'])
+ texts = context.scene['GamePropsVisualizer']
+
+ except:
+ return
+ if not texts:
+ return
+
+ # draw
+ i=0
+
+ blf.size(0, 12, 72)
+
+
+ bgl.glColor3f(1.0,1.0,1.0)
+ for ob in bpy.context.selected_objects:
+ for pi,p in enumerate(ob.game.properties):
+ blf.position(0, texts[i], texts[i+1]-(pi+1)*14, 0)
+ if p.type=='FLOAT':
+ t=p.name+': '+ str('%g'% p.value)
+ else:
+ t=p.name+': '+ str(p.value)
+ blf.draw(0, t)
+ i+=2
+
+
+# operator
+class GamePropertyVisualizer(bpy.types.Operator):
+ bl_idname = "view3d.game_props_visualizer"
+ bl_label = "Game Properties Visualizer"
+ bl_description = "Toggle the visualization of game properties"
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode!='EDIT_MESH'
+
+ def modal(self, context, event):
+ context.area.tag_redraw()
+
+ # removal of callbacks when operator is called again
+ #print(context.scene.display_game_properties)
+ if context.scene.display_game_properties == -1:
+ # print('deinit2')
+
+ context.scene.display_game_properties = 0
+ context.region.callback_remove(self.handle1)
+ context.region.callback_remove(self.handle2)
+ context.scene.display_game_properties = 0
+
+ return {'FINISHED'}
+
+ return {'PASS_THROUGH'}
+
+ def invoke(self, context, event):
+ if context.area.type == 'VIEW_3D':
+ print(context.scene.display_game_properties)
+ if context.scene.display_game_properties == 0 or context.scene.display_game_properties == -1:
+ print('init')
+ # operator is called for the first time, start everything
+ context.scene.display_game_properties = 1
+ self.handle1 = context.region.callback_add(calc_callback,
+ (self, context), 'POST_VIEW')
+ self.handle2 = context.region.callback_add(draw_callback,
+ (self, context), 'POST_PIXEL')
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ # operator is called again, stop displaying
+ context.scene.display_game_properties = -1
+ #print(dir(self))
+ #
+ return {'RUNNING_MODAL'}
+ else:
+ self.report({'WARNING'}, "View3D not found, can't run operator")
+ return {'CANCELLED'}
+
+
+# defining the panel
+def menu_func(self, context):
+ col = self.layout.column(align=True)
+ col.operator(GamePropertyVisualizer.bl_idname, text="Visualize game props")
+ self.layout.separator()
+
+
+def register():
+ bpy.types.Scene.display_game_properties = bpy.props.IntProperty(name='Visualize Game Poperties')
+ bpy.types.VIEW3D_PT_view3d_display.prepend(menu_func)
+
+def unregister():
+ del bpy.types.Scene.display_game_properties
+ bpy.types.VIEW3D_PT_view3d_display.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/space_view3d_library_hide.py b/release/scripts/addons_contrib/space_view3d_library_hide.py
new file mode 100644
index 0000000..0633e3f
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_library_hide.py
@@ -0,0 +1,254 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# Script copyright (C) Campbell Barton
+
+bl_info = {
+ "name": "Library Hide",
+ "description": "Hide objects within library dupligroups",
+ "author": "Campbell Barton",
+ "version": (1, 0),
+ "blender": (2, 63, 0),
+ 'location': 'Search: RayCast View Operator',
+ "wiki_url": "",
+ "tracker_url":"",
+ "category": "3D View",
+}
+
+import bpy
+from mathutils import Vector
+from bpy_extras import view3d_utils
+
+LIB_HIDE_TEXT_ID = "blender_hide_objects.py"
+
+LIB_HIDE_TEXT_HEADER = """
+import bpy
+print("running: %r" % __file__)
+def hide(name, lib):
+ obj = bpy.data.objects.get((name, lib))
+ if obj is None:
+ print("hide can't find: %r %r" % (name, lib))
+ else:
+ obj.hide = obj.hide_render = True
+
+"""
+
+def pick_object(context, event, pick_objects, ray_max=10000.0):
+ """Run this function on left mouse, execute the ray cast"""
+ # get the context arguments
+ scene = context.scene
+ region = context.region
+ rv3d = context.region_data
+ coord = event.mouse_region_x, event.mouse_region_y
+
+ # get the ray from the viewport and mouse
+ view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
+ ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
+ ray_target = ray_origin + (view_vector * ray_max)
+
+ scene.cursor_location = ray_target
+
+ def visible_objects_and_duplis():
+ """Loop over (object, matrix) pairs (mesh only)"""
+
+ for obj in context.visible_objects: # scene.objects:
+ if obj.hide:
+ continue
+
+ if obj.type == 'MESH':
+ yield (None, obj, obj.matrix_world.copy())
+
+ if obj.dupli_type != 'NONE':
+ print("DupliInst: %r" % obj)
+ obj.dupli_list_create(scene)
+ # matrix = obj.matrix_world.copy()
+ for dob in obj.dupli_list:
+ obj_dupli = dob.object
+ if not obj_dupli.hide:
+ # print("Dupli: %r" % obj_dupli)
+ if obj_dupli.type == 'MESH':
+ yield (obj, obj_dupli, dob.matrix.copy())
+
+ obj.dupli_list_clear()
+
+ def obj_ray_cast(obj, matrix):
+ """Wrapper for ray casting that moves the ray into object space"""
+
+ # get the ray relative to the object
+ matrix_inv = matrix.inverted()
+ ray_origin_obj = matrix_inv * ray_origin
+ ray_target_obj = matrix_inv * ray_target
+
+ mesh = obj.data
+ if not mesh.polygons:
+ return None, None, None
+
+ hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
+
+ if face_index == -1:
+ hit, normal, face_index = obj.ray_cast(ray_target_obj, ray_origin_obj)
+
+ if face_index != -1:
+ return hit, normal, face_index
+ else:
+ return None, None, None
+
+ # cast rays and find the closest object
+ best_length_squared = ray_max * ray_max
+ best_obj = None
+ best_obj_parent = None
+
+ for obj_parent, obj, matrix in visible_objects_and_duplis():
+ if obj.type == 'MESH':
+ hit, normal, face_index = obj_ray_cast(obj, matrix)
+ if hit is not None:
+ length_squared = (hit - ray_origin).length_squared
+ if length_squared < best_length_squared:
+ best_length_squared = length_squared
+ best_obj = obj
+ best_obj_parent = obj_parent
+
+ # now we have the object under the mouse cursor,
+ # we could do lots of stuff but for the example just select.
+ if best_obj is not None:
+ pick_objects.append((best_obj, best_obj.hide, best_obj.hide_render))
+ best_obj.hide = True
+ best_obj.hide_render = True
+
+ #if best_obj_parent:
+ # best_obj_parent.update_tag(refresh={'OBJECT'})
+ #scene.update()
+ return True
+ else:
+ print("found none")
+ return False
+
+
+def pick_finalize(context, pick_objects):
+ text = bpy.data.texts.get((LIB_HIDE_TEXT_ID, None))
+ if text is None:
+ text = bpy.data.texts.new(LIB_HIDE_TEXT_ID)
+ text.use_module = True
+ is_new = True
+ else:
+ is_new = False
+
+ if is_new:
+ data = []
+
+ data += LIB_HIDE_TEXT_HEADER.split("\n")
+ else:
+ data = text.as_string().split("\n")
+
+ data.append("# ---")
+
+ for pick_obj_tuple in pick_objects:
+
+ pick_obj = pick_obj_tuple[0]
+
+ pick_obj.hide = True
+ pick_obj.hide_render = True
+
+ line = "hide(%r, %s)" % (pick_obj.name, repr(pick_obj.library.filepath) if pick_obj.library is not None else "None")
+ data.append(line)
+
+ text.from_string("\n".join(data))
+
+
+def pick_restore(pick_obj):
+ best_obj, hide, hide_render = pick_obj
+ best_obj.hide = hide
+ best_obj.hide_render = hide_render
+
+
+class ViewOperatorRayCast(bpy.types.Operator):
+ """Modal object selection with a ray cast"""
+ bl_idname = "view3d.modal_operator_raycast"
+ bl_label = "RayCast View Operator"
+
+ _header_text = "Add: LMB, Undo: BackSpace, Finish: Enter"
+
+ def _update_header(self, context):
+ if self.pick_objects:
+ pick_obj = self.pick_objects[-1][0]
+ info_obj = "%s, %s" % (pick_obj.name, pick_obj.library.filepath if pick_obj.library is not None else "None")
+ info = "%s - added: %s" % (ViewOperatorRayCast._header_text, info_obj)
+ else:
+ info = ViewOperatorRayCast._header_text
+
+ context.area.header_text_set(info)
+
+ def modal(self, context, event):
+ if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
+ # allow navigation
+ return {'PASS_THROUGH'}
+ elif event.type == 'LEFTMOUSE':
+ if event.value == 'RELEASE':
+ if pick_object(context, event, self.pick_objects):
+ self._update_header(context)
+ return {'RUNNING_MODAL'}
+ elif event.type == 'BACK_SPACE':
+ if event.value == 'RELEASE':
+ if self.pick_objects:
+ pick_obj = self.pick_objects.pop()
+ pick_restore(pick_obj)
+ self._update_header(context)
+
+ elif event.type in {'RET', 'NUMPAD_ENTER'}:
+ if event.value == 'RELEASE':
+ if self.pick_objects: # avoid enter taking effect on startup
+ pick_finalize(context, self.pick_objects)
+ context.area.header_text_set()
+ self.report({'INFO'}, "Finished")
+ return {'FINISHED'}
+
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
+ if event.value == 'RELEASE':
+ for pick_obj in self.pick_objects:
+ pick_restore(pick_obj)
+ context.area.header_text_set()
+ self.report({'INFO'}, "Cancelled")
+ return {'CANCELLED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ if context.space_data.type == 'VIEW_3D':
+
+ self.pick_objects = []
+ self._update_header(context)
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ self.report({'WARNING'}, "Active space must be a View3d")
+ return {'CANCELLED'}
+
+
+def register():
+ bpy.utils.register_class(ViewOperatorRayCast)
+
+
+def unregister():
+ bpy.utils.unregister_class(ViewOperatorRayCast)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py b/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py
new file mode 100644
index 0000000..d6dabf9
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_manipulator_Menu.py
@@ -0,0 +1,109 @@
+#re creating the functionality of the manipulator menu from 2.49
+
+# ##### 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 LICENSE BLOCK #####
+
+
+bl_info = {
+ "name": "3d View: Manipulator Menu",
+ "author": "MichaelW",
+ "version": (1, 2 ,1),
+ "blender": (2, 61, 0),
+ "location": "View3D > Ctrl Space ",
+ "description": "Menu to change the manipulator type and/or disable it",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/3D_interaction/Manipulator_Menu",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=22092",
+ "category": "3D View"}
+
+
+import bpy
+
+def main(context):
+ bpy.context.space_data.manipulator = False
+
+#class VIEW3D_OT_disable_manipulator(bpy.types.Operator):
+# """"""
+# bl_idname = "VIEW3D_OT_disable_manipulator"
+# bl_label = "disable manipulator"
+#
+# def poll(self, context):
+# return context.active_object != None
+#
+# def execute(self, context):
+# main(context)
+# return {'FINISHED'}
+#
+
+
+class VIEW3D_MT_ManipulatorMenu(bpy.types.Menu):
+ bl_label = "ManipulatorType"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ props = layout.operator("view3d.enable_manipulator",text ='Translate', icon='MAN_TRANS')
+ props.translate = True
+
+ props = layout.operator("view3d.enable_manipulator",text ='Rotate', icon='MAN_ROT')
+ props.rotate = True
+
+ props = layout.operator("view3d.enable_manipulator",text ='Scale', icon='MAN_SCALE')
+ props.scale = True
+ layout.separator()
+
+ props = layout.operator("view3d.enable_manipulator",text ='Combo', icon='MAN_SCALE')
+ props.scale = True
+ props.rotate = True
+ props.translate = True
+
+ layout.separator()
+
+ props = layout.operator("view3d.enable_manipulator",text ='Hide', icon='MAN_SCALE')
+ props.scale = False
+ props.rotate = False
+ props.translate = False
+
+ layout.separator()
+
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ wm = bpy.context.window_manager
+ km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
+ kmi = km.keymap_items.new('wm.call_menu', 'SPACE', 'PRESS', ctrl=True)
+ kmi.properties.name = "VIEW3D_MT_ManipulatorMenu"
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ wm = bpy.context.window_manager
+ km = wm.keyconfigs.addon.keymaps['3D View Generic']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu':
+ if kmi.properties.name == "VIEW3D_MT_ManipulatorMenu":
+ km.keymap_items.remove(kmi)
+ break
+
+if __name__ == "__main__":
+ register
diff --git a/release/scripts/addons_contrib/space_view3d_multiselect_menu.py b/release/scripts/addons_contrib/space_view3d_multiselect_menu.py
new file mode 100644
index 0000000..2702c93
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_multiselect_menu.py
@@ -0,0 +1,121 @@
+#view3d_multiselect_menu.py (c) 2011 Sean Olson (liquidApe)
+#Original Script by: Mariano Hidalgo (uselessdreamer)
+#contributed to by: Crouch, sim88, sam, meta-androcto, and Michael W
+#
+#Tested with r37702
+#
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "3D View: Multiselect Menu",
+ "author": "Sean Olson (liquidApe)",
+ "version": (1, 2),
+ "blender": (2, 61, 0),
+ "location": "View3D > Mouse > Menu ",
+ "warning":"",
+ "description": "Added options for multiselect to the ctrl-tab menu",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/3D_interaction/multiselect_Menu",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=22132",
+ "category": "3D View"}
+
+import bpy
+
+# multiselect menu
+class VIEW3D_MT_Multiselect_Menu(bpy.types.Menu):
+ bl_label = "MultiSelect Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+
+ layout.separator()
+ prop = layout.operator("wm.context_set_value", text="Vertex Select",
+ icon='VERTEXSEL')
+ prop.value = "(True, False, False)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value", text="Edge Select",
+ icon='EDGESEL')
+ prop.value = "(False, True, False)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value", text="Face Select",
+ icon='FACESEL')
+ prop.value = "(False, False, True)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+ layout.separator()
+
+ prop = layout.operator("wm.context_set_value",
+ text="Vertex & Edge Select", icon='EDITMODE_HLT')
+ prop.value = "(True, True, False)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value",
+ text="Vertex & Face Select", icon='ORTHO')
+ prop.value = "(True, False, True)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+
+ prop = layout.operator("wm.context_set_value",
+ text="Edge & Face Select", icon='SNAP_FACE')
+ prop.value = "(False, True, True)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+ layout.separator()
+
+ prop = layout.operator("wm.context_set_value",
+ text="Vertex & Edge & Face Select", icon='SNAP_VOLUME')
+ prop.value = "(True, True, True)"
+ prop.data_path = "tool_settings.mesh_select_mode"
+ layout.separator()
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ #add multiselect keybinding
+ km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
+ kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
+ kmi.properties.name = "VIEW3D_MT_Multiselect_Menu"
+
+ #remove default keybinding
+ km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu':
+ if kmi.properties.name == "VIEW3D_MT_edit_mesh_select_mode":
+ km.keymap_items.remove(kmi)
+ break
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ #remove multiselect keybinding
+ km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
+ for kmi in km.keymap_items:
+ if kmi.idname == 'wm.call_menu':
+ if kmi.properties.name == "VIEW3D_MT_Multiselect_Menu":
+ km.keymap_items.remove(kmi)
+ break
+
+ #replace default keymap
+ km = bpy.context.window_manager.keyconfigs.active.keymaps['Mesh']
+ kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
+ kmi.properties.name = "VIEW3D_MT_edit_mesh_select_mode"
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/space_view3d_objects_panel.py b/release/scripts/addons_contrib/space_view3d_objects_panel.py
new file mode 100644
index 0000000..622f3a9
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_objects_panel.py
@@ -0,0 +1,75 @@
+# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Add Objects Panel",
+ "author": "Murat Egretli (Demohero)",
+ "version": (1,2),
+ "blender": (2, 61, 0),
+ "location": "View3D > Toolbar",
+ "description": "add objects(mesh, curve etc.) from Toolbar",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=22154",
+ "category": "3D View"}
+
+
+import bpy
+
+
+class View3DPanel():
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+
+
+class VIEW3D_PT_add_menu(View3DPanel,bpy.types.Panel):
+ bl_context = "objectmode"
+ bl_label = "Add Objects"
+ bl_options = {"DEFAULT_CLOSED"}
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.menu("INFO_MT_mesh_add", text="Mesh", icon='OUTLINER_OB_MESH')
+ layout.menu("INFO_MT_curve_add", text="Curve", icon='OUTLINER_OB_CURVE')
+ layout.menu("INFO_MT_surface_add", text="Surface", icon='OUTLINER_OB_SURFACE')
+ layout.operator_menu_enum("object.metaball_add", "type", text="Metaball", icon='OUTLINER_OB_META')
+ layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
+ layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP')
+ layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY')
+ layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
+ layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY'
+ layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
+ layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
+ layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
+
+# register the class
+def register():
+ bpy.utils.register_module(__name__)
+
+ pass
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ pass
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/space_view3d_paint_bprojection.py b/release/scripts/addons_contrib/space_view3d_paint_bprojection.py
new file mode 100644
index 0000000..4ddd7db
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_paint_bprojection.py
@@ -0,0 +1,1405 @@
+bl_info = {
+ "name": "BProjection",
+ "description": "Help Clone tool",
+ "author": "kgeogeo",
+ "version": (1, 0),
+ "blender": (2, 63, 0),
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/bprojection",
+ "tracker_url":"http://projects.blender.org/tracker/index.php?func=detail&aid=30521&group_id=153&atid=468",
+ "category": "Paint"}
+
+import bpy
+from bpy.app.handlers import persistent
+from bpy.types import Panel, Operator
+from bpy.props import IntProperty, FloatProperty, BoolProperty, IntVectorProperty, StringProperty, FloatVectorProperty, CollectionProperty
+from bpy_extras import view3d_utils
+import math
+from math import *
+import mathutils
+from mathutils import *
+
+BProjection_Empty = 'Empty for BProjection'
+BProjection_Material = 'Material for BProjection'
+BProjection_Texture = 'Texture for BProjection'
+
+# Main function for align the plan to view
+def align_to_view(context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ rotation = em.custom_rotation
+ scale = em.custom_scale
+ z = em.custom_location.z
+ pos = [em.custom_location.x, em.custom_location.y]
+
+ reg = context.area.regions[4]
+ width = reg.width
+ height = reg.height
+
+ sd = context.space_data
+ r3d = sd.region_3d
+ r3d.update()
+ vr = r3d.view_rotation
+ quat = mathutils.Quaternion((0.0, 0.0, 1.0), math.radians(float(rotation)))
+ v = Vector((pos[0],pos[1],z))
+ v.rotate(vr)
+
+ em = bpy.data.objects[BProjection_Empty]
+ img = bpy.data.textures[BProjection_Texture].image
+ if img and img.size[1] != 0:
+ prop = img.size[0]/img.size[1]
+ else: prop = 1
+
+ if em.custom_linkscale:
+ em.scale = Vector((prop*scale[0], scale[0], 1))
+ else:
+ em.scale = Vector((prop*scale[0], scale[1], 1))
+ pos_cur = em.location - sd.cursor_location
+ rot_cur1 = em.rotation_euler.to_quaternion()
+ em.location = v + ob.location
+ em.rotation_euler = Quaternion.to_euler(vr*quat)
+ if em.custom_c3d:
+ if em.custom_old_scale != em.custom_scale:
+ pos_cur = em.location - sd.cursor_location
+ rot_cur2 = em.rotation_euler.to_quaternion()
+ rot_cur1.invert()
+ pos_cur.rotate(rot_cur1)
+ pos_cur.rotate(rot_cur2)
+ v = em.location - pos_cur
+ sd.cursor_location = v
+
+def applyimage(context):
+ img = bpy.data.textures[BProjection_Texture].image
+ em = bpy.data.objects[BProjection_Empty]
+ ob = context.object
+
+ face = ob.data.polygons
+ uvdata = ob.data.uv_textures.active.data
+
+ for f,d in zip(face,uvdata):
+ if f.select:
+ d.image = img
+
+ align_to_view(context)
+ ob.data.update()
+
+# Function to update the properties
+def update_Location(self, context):
+ align_to_view(context)
+
+def find_uv(context):
+ obj = context.object
+ me = obj.data.vertices
+ vg = obj.vertex_groups
+ l=[]
+ index_uv = 0
+ for face in obj.data.polygons:
+ x=len(face.vertices)
+ for vertex in face.vertices:
+ if len(me[vertex].groups)>0:
+ for g in me[vertex].groups:
+ if vg[g.group].name == 'texture plane':
+ x-=1
+
+
+ if x == 0:
+ l.append([index_uv,len(face.vertices)])
+ index_uv += len(face.vertices)
+ return l
+
+# Function to update the scaleUV
+def update_UVScale(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ v = Vector((em.custom_offsetuv[0]/10 + 0.5, em.custom_offsetuv[1]/10 + 0.5))
+ l = Vector((0.0,0.0))
+ s = em.custom_scaleuv
+ os = em.custom_old_scaleuv
+ scale = s - os
+ l = find_uv(context)
+ for i,j in l:
+ for t in range(j):
+ d = context.object.data.uv_layers.active.data[i+t]
+ vres = v - d.uv
+ d.uv.x = v.x - vres.x/os[0]*s[0]
+ d.uv.y = v.y - vres.y/os[1]*s[1]
+
+ em.custom_old_scaleuv = s
+
+ applyimage(context)
+
+def update_PropUVScale(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ if em.custom_linkscaleuv:
+ em.custom_scaleuv = [em.custom_propscaleuv,em.custom_propscaleuv]
+
+def update_LinkUVScale(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ if em.custom_linkscaleuv:
+ em.custom_propscaleuv = em.custom_scaleuv.x
+ update_PropUVScale(self, context)
+ else:
+ update_UVScale(self, context)
+
+# Function to update the offsetUV
+def update_UVOffset(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ o = em.custom_offsetuv
+ oo = em.custom_old_offsetuv
+ l = find_uv(context)
+ for i,j in l:
+ for t in range(j):
+ d = context.object.data.uv_layers.active.data[i+t]
+ d.uv = [d.uv[0] - oo[0]/10 + o[0]/10, d.uv[1] - oo[1]/10 + o[1]/10]
+ em.custom_old_offsetuv = o
+
+ applyimage(context)
+
+# Function to update the flip horizontal
+def update_FlipUVX(self, context):
+ l = find_uv(context)
+ for i,j in l:
+ for t in range(j):
+ d = context.object.data.uv_layers.active.data[i+t]
+ x = d.uv.x
+ d.uv.x = 1 - x
+
+ applyimage(context)
+
+# Function to update the flip vertical
+def update_FlipUVY(self, context):
+ l = find_uv(context)
+ for i,j in l:
+ for t in range(j):
+ d = context.object.data.uv_layers.active.data[i+t]
+ y = d.uv[1]
+ d.uv[1] = 1 - y
+
+ applyimage(context)
+
+# Function to update
+def update_Rotation(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ if em.custom_rotc3d:
+ angle = em.custom_rotation - em.custom_old_rotation
+ sd = context.space_data
+ vr = sd.region_3d.view_rotation.copy()
+ c = sd.cursor_location - ob.location
+ e = bpy.data.objects[BProjection_Empty].location - ob.location
+ vo = Vector((0.0, 0.0, 1.0))
+ vo.rotate(vr)
+ quat = mathutils.Quaternion(vo, math.radians(angle))
+ v = e-c
+ v.rotate(quat)
+ vr.invert()
+ v.rotate(vr)
+ c.rotate(vr)
+ em.custom_location = c + v
+ else:
+ align_to_view(context)
+
+ em.custom_old_rotation = em.custom_rotation
+
+# Function to update scale
+def update_Scale(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+
+ if em.custom_scac3d:
+ sd = context.space_data
+ r3d = sd.region_3d
+ vr = r3d.view_rotation.copy()
+ vr.invert()
+ e = em.location - ob.location
+ c = sd.cursor_location - ob.location
+ ce = e - c
+
+ s = em.custom_scale
+ os = em.custom_old_scale
+ c.rotate(vr)
+ ce.rotate(vr)
+
+ img = bpy.data.textures[BProjection_Texture].image
+ if img and img.size[1] != 0:
+ prop = img.size[0]/img.size[1]
+ else: prop = 1
+
+ v = Vector((s.x*ce.x/os.x, s.y*ce.y/os.y,0.0))
+ em.custom_location = c + v
+
+
+ else:
+ align_to_view(context)
+
+
+ em.custom_old_scale = em.custom_scale
+
+def update_PropScale(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ if em.custom_linkscale:
+ em.custom_scale = [em.custom_propscale,em.custom_propscale]
+
+def update_LinkScale(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ if em.custom_linkscale:
+ em.custom_propscale = em.custom_scale.x
+ update_PropScale(self, context)
+ else:
+ update_Scale(self, context)
+
+def update_activeviewname(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ if self.custom_active:
+ em.custom_active_view = self.custom_active_view
+
+class custom_props(bpy.types.PropertyGroup):
+ custom_fnlevel = IntProperty(name="Fast navigate level", description="Increase or decrease the SubSurf level, decrease make navigation faster", default=0)
+
+ custom_location = FloatVectorProperty(name="Location", description="Location of the plane",
+ default=(1.0,0,-1.0),
+ subtype = 'XYZ',
+ soft_min = -10,
+ soft_max = 10,
+ step=0.1,
+ size=3)
+
+ custom_rotation = FloatProperty(name="Rotation", description="Rotate the plane",
+ min=-180, max=180, default=0)
+
+ custom_scale = FloatVectorProperty(name="Scales", description="Scale the planes",
+ default=(1.0, 1.0),
+ subtype = 'XYZ',
+ min = 0.1,
+ max = 10,
+ soft_min=0.1,
+ soft_max=10,
+ step=0.1,
+ size=2)
+ custom_propscale = FloatProperty(name="PropScale", description="Scale the Plane",
+ default=1.0,
+ min = 0.1,
+ max = 10,
+ soft_min=0.1,
+ soft_max=10,
+ step=0.1)
+
+ custom_linkscale = BoolProperty(name="linkscale", default=True)
+
+ # UV properties
+ custom_scaleuv = FloatVectorProperty(name="ScaleUV", description="Scale the texture's UV",
+ default=(1.0,1.0),min = 0.01, subtype = 'XYZ', size=2)
+ custom_propscaleuv = FloatProperty(name="PropScaleUV", description="Scale the texture's UV",
+ default=1.0,min = 0.01)
+ custom_offsetuv = FloatVectorProperty(name="OffsetUV", description="Decal the texture's UV",
+ default=(0.0,0.0), subtype = 'XYZ', size=2)
+ custom_linkscaleuv = BoolProperty(name="linkscaleUV", default=True)
+ custom_flipuvx = BoolProperty(name="flipuvx", default=False)
+ custom_flipuvy = BoolProperty(name="flipuvy", default=False)
+
+ # other properties
+ custom_active= BoolProperty(name="custom_active", default=True)
+ custom_expand = BoolProperty(name="expand", default=False)
+
+ custom_active_view = StringProperty(name = "custom_active_view",default = "View",update = update_activeviewname)
+
+ custom_image = StringProperty(name = "custom_image",default = "")
+
+ custom_index = IntProperty()
+
+# Function to create custom properties
+def createcustomprops(context):
+ Ob = bpy.types.Object
+
+ Ob.custom_fnlevel = IntProperty(name="Fast navigate level", description="Increase or decrease the SubSurf level, decrease make navigation faster", default=0)
+
+ # plane properties
+ Ob.custom_location = FloatVectorProperty(name="Location", description="Location of the plane",
+ default = (1.0, 0, -1.0),
+ subtype = 'XYZ',
+ size = 3,
+ step = 0.5,
+ soft_min = -10,
+ soft_max = 10,
+ update = update_Location)
+
+ Ob.custom_rotation = FloatProperty(name="Rotation", description="Rotate the plane",
+ min=-180, max=180, default=0,update = update_Rotation)
+
+ Ob.custom_old_rotation = FloatProperty(name="old_Rotation", description="Old Rotate the plane",
+ min=-180, max=180, default=0)
+
+ Ob.custom_scale = FloatVectorProperty(name="Scales", description="Scale the planes",
+ subtype = 'XYZ',
+ default=(1.0, 1.0),
+ min = 0.1,
+ max = 10,
+ soft_min = 0.1,
+ soft_max = 10,
+ size=2,
+ step=0.5,
+ update = update_Scale)
+
+ Ob.custom_propscale = FloatProperty(name="PropScale", description="Scale the Plane",
+ default = 1.0,
+ min = 0.1,
+ soft_min = 0.1,
+ soft_max = 10,
+ step = 0.5,
+ update = update_PropScale)
+
+ Ob.custom_old_scale = FloatVectorProperty(name="old_Scales", description="Old Scale the planes",
+ subtype = 'XYZ', default=(1.0, 1.0),min = 0.1, size=2)
+
+ Ob.custom_linkscale = BoolProperty(name="linkscale", default=True, update = update_LinkScale)
+
+
+ Ob.custom_sub = IntProperty(name="Subdivide", description="Number of subdivision of the plane",
+ min=0, max=20, default=0)
+
+ # UV properties
+ Ob.custom_scaleuv = FloatVectorProperty(name="ScaleUV", description="Scale the texture's UV",
+ default = (1.0,1.0),
+ soft_min = 0.01,
+ soft_max = 100,
+ min = 0.01,
+ subtype = 'XYZ',
+ size = 2,
+ update = update_UVScale)
+
+ Ob.custom_propscaleuv = FloatProperty(name="PropScaleUV", description="Scale the texture's UV",
+ default = 1.0,
+ soft_min = 0.01,
+ soft_max = 100,
+ min = 0.01,
+ update = update_PropUVScale)
+
+ Ob.custom_old_scaleuv = FloatVectorProperty(name="old_ScaleUV", description="Scale the texture's UV",
+ default=(1.0,1.0),min = 0.01, subtype = 'XYZ', size=2)
+ Ob.custom_offsetuv = FloatVectorProperty(name="OffsetUV", description="Decal the texture's UV",
+ default=(0.0,0.0), subtype = 'XYZ', size=2,update = update_UVOffset)
+ Ob.custom_old_offsetuv = FloatVectorProperty(name="old_OffsetUV", description="Decal the texture's UV",
+ default=(0.0,0.0), subtype = 'XYZ', size=2)
+ Ob.custom_linkscaleuv = BoolProperty(name="linkscaleUV", default=True, update = update_LinkUVScale)
+ Ob.custom_flipuvx = BoolProperty(name="flipuvx", default=False, update = update_FlipUVX)
+ Ob.custom_flipuvy = BoolProperty(name="flipuvy", default=False, update = update_FlipUVY)
+
+ # other properties
+ Ob.custom_c3d = BoolProperty(name="c3d", default=True)
+ Ob.custom_rotc3d = BoolProperty(name="rotc3d", default=False)
+ Ob.custom_scac3d = BoolProperty(name="scac3d", default=False)
+ Ob.custom_expand = BoolProperty(name="expand", default=True)
+ Ob.custom_active_view = StringProperty(name = "custom_active_view",default = "View")
+ try:
+ Ob.custom_active_object = StringProperty(name = "custom_active_object",default = context.object.name)
+ except:
+ Ob.custom_active_object = StringProperty(name = "custom_active_object",default = 'debut')
+ Ob.custom_props = CollectionProperty(type = custom_props)
+
+# Function to remove custom properties
+def removecustomprops():
+ list_prop = ['custom_location', 'custom_rotation', 'custom_old_rotation', 'custom_scale', 'custom_old_scale', 'custom_c3d',
+ 'custom_rotc3d', 'custom_scaleuv', 'custom_flipuvx', 'custom_flipuvy', 'custom_linkscale',
+ 'custom_linkscaleuv', 'custom_old_scaleuv', 'custom_offsetuv', 'custom_old_offsetuv', 'custom_scac3d', 'custom_sub',
+ 'custom_expand', 'custom_active_view', 'custom_propscaleuv', 'custom_props', 'custom_propscale']
+ for prop in list_prop:
+ try:
+ del bpy.data.objects[BProjection_Empty][prop]
+ except:
+ pass
+
+def clear_props(context):
+ em = bpy.data.objects[BProjection_Empty]
+ em.custom_scale = [1,1]
+ em.custom_rotation = 0
+ em.custom_scaleuv =[1.0,1.0]
+ em.custom_offsetuv =[0.0,0.0]
+ em.custom_propscaleuv = 1.0
+ em.custom_propscale = 1.0
+ if em.custom_flipuvx == True:
+ em.custom_flipuvx = False
+ if em.custom_flipuvy == True:
+ em.custom_flipuvy = False
+
+# Oprerator Class to create view
+class CreateView(Operator):
+ bl_idname = "object.create_view"
+ bl_label = "Create a new view"
+
+ def execute(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ new_props = em.custom_props.add()
+ em.custom_active_view = new_props.custom_active_view
+ ob.data.shape_keys.key_blocks[ob.active_shape_key_index].mute = True
+ bpy.ops.object.shape_key_add(from_mix = False)
+ ob.data.shape_keys.key_blocks[ob.active_shape_key_index].value = 1.0
+ new_props.custom_index = len(em.custom_props)-1
+ bpy.ops.object.active_view(index = new_props.custom_index)
+ return {'FINISHED'}
+
+# Oprerator Class to copy view
+class SaveView(Operator):
+ bl_idname = "object.save_view"
+ bl_label = "copy the view"
+
+ index = IntProperty(default = 0)
+
+ def execute(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ prop = em.custom_props[self.index]
+ prop.custom_rotation = em.custom_rotation
+ prop.custom_scale = em.custom_scale
+ prop.custom_linkscale = em.custom_linkscale
+ prop.custom_scaleuv = em.custom_scaleuv
+ prop.custom_propscale = em.custom_propscale
+ prop.custom_offsetuv = em.custom_offsetuv
+ prop.custom_linkscaleuv = em.custom_linkscaleuv
+ prop.custom_propscaleuv = em.custom_propscaleuv
+ prop.custom_flipuvx = em.custom_flipuvx
+ prop.custom_flipuvy = em.custom_flipuvy
+ try:
+ prop.custom_image = bpy.data.textures[BProjection_Texture].image.name
+ except:
+ pass
+
+ return {'FINISHED'}
+
+# Oprerator Class to copy view
+class PasteView(Operator):
+ bl_idname = "object.paste_view"
+ bl_label = "paste the view"
+
+ index = IntProperty(default = 0)
+
+ def execute(self, context):
+ em = bpy.data.objects[BProjection_Empty]
+ tmp_scac3d = em.custom_scac3d
+ tmp_rotc3d = em.custom_rotc3d
+ em.custom_scac3d = False
+ em.custom_rotc3d = False
+ prop = em.custom_props[self.index]
+ em.custom_linkscale = prop.custom_linkscale
+ em.custom_offsetuv = prop.custom_offsetuv
+ em.custom_linkscaleuv = prop.custom_linkscaleuv
+ em.custom_scaleuv = prop.custom_scaleuv
+ em.custom_propscaleuv = prop.custom_propscaleuv
+ em.custom_rotation = prop.custom_rotation
+ em.custom_scale = prop.custom_scale
+ em.custom_propscale = prop.custom_propscale
+ if prop.custom_image != '':
+ if bpy.data.textures[BProjection_Texture].image.name != prop.custom_image:
+ bpy.data.textures[BProjection_Texture].image = bpy.data.images[prop.custom_image]
+ applyimage(context)
+ if em.custom_flipuvx != prop.custom_flipuvx:
+ em.custom_flipuvx = prop.custom_flipuvx
+ if em.custom_flipuvy != prop.custom_flipuvy:
+ em.custom_flipuvy = prop.custom_flipuvy
+ em.custom_scac3d = tmp_scac3d
+ em.custom_rotc3d = tmp_rotc3d
+ return {'FINISHED'}
+
+# Oprerator Class to remove view
+class RemoveView(Operator):
+ bl_idname = "object.remove_view"
+ bl_label = "Rmeove the view"
+
+ index = IntProperty(default = 0)
+
+ def execute(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+
+ ob.active_shape_key_index = self.index + 1
+ bpy.ops.object.shape_key_remove()
+
+ if em.custom_props[self.index].custom_active:
+ if len(em.custom_props) > 0:
+ bpy.ops.object.active_view(index = self.index-1)
+ if self.index == 0 and len(em.custom_props) > 1:
+ bpy.ops.object.active_view(index = 1)
+
+ em.custom_props.remove(self.index)
+
+ if len(em.custom_props) == 0:
+ clear_props(context)
+
+ bpy.ops.object.create_view()
+
+ i=0
+ for item in em.custom_props:
+ item.custom_index = i
+ i+=1
+
+ for item in (item for item in em.custom_props if item.custom_active):
+ ob.active_shape_key_index = item.custom_index+1
+
+ return {'FINISHED'}
+
+# Oprerator Class to copy view
+class ActiveView(Operator):
+ bl_idname = "object.active_view"
+ bl_label = "Active the view"
+
+ index = IntProperty(default = 0)
+
+ def execute(self, context):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ for item in (item for item in em.custom_props if item.custom_active == True):
+ bpy.ops.object.save_view(index = item.custom_index)
+ item.custom_active = False
+ em.custom_props[self.index].custom_active = True
+ em.custom_active_view = em.custom_props[self.index].custom_active_view
+ ob.active_shape_key_index = self.index + 1
+
+ for i in ob.data.shape_keys.key_blocks:
+ i.mute = True
+
+ ob.data.shape_keys.key_blocks[ob.active_shape_key_index].mute = False
+
+ bpy.ops.object.paste_view(index = self.index)
+
+ return {'FINISHED'}
+
+# Draw Class to show the panel
+class BProjection(Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "BProjection"
+
+ @classmethod
+ def poll(cls, context):
+ return (context.image_paint_object or context.sculpt_object)
+
+ def draw(self, context):
+ layout = self.layout
+ if BProjection_Empty in [ob.name for ob in bpy.data.objects]:
+ tex = bpy.data.textures[BProjection_Texture]
+
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ if ob == bpy.data.objects[em.custom_active_object]:
+ col = layout.column(align =True)
+ col.operator("object.removebprojectionplane", text="Remove BProjection plane")
+
+ try:
+ matBProjection = bpy.data.materials[BProjection_Material]
+ except:
+ matBProjection = None
+
+ box = layout.box()
+
+ row = box.row()
+ if not em.custom_expand:
+ row.prop(em, "custom_expand", text = "", icon="TRIA_RIGHT", emboss=False)
+ row.label(text= 'Paint Object: '+ ob.name)
+ else:
+ row.prop(em, "custom_expand", text = "" , icon="TRIA_DOWN", emboss=False)
+ row.label(text= 'Paint Object: '+ ob.name)
+
+ if ob == bpy.data.objects[em.custom_active_object]:
+ col = box.column(align =True)
+ col.template_ID(tex, "image", open="image.open")
+ row = box.row(align=True)
+ row.operator('object.applyimage', text="Apply image", icon = 'FILE_TICK')
+ row.prop(em, "custom_c3d",text="", icon='CURSOR')
+ row = box.row(align =True)
+ row.label(text="Location:")
+ row = box.row(align =True)
+ row.prop(em,'custom_location', text='')
+ row = box.row(align =True)
+ row.prop(em,'custom_rotation')
+ row.prop(em,'custom_rotc3d',text="",icon='MANIPUL')
+ row = box.row(align =True)
+ row.label(text="Scale:")
+ row = box.row(align =True)
+ if em.custom_linkscale :
+ row.prop(em, "custom_propscale",text="")
+ row.prop(em, "custom_linkscale",text="",icon='LINKED')
+ else:
+ row.prop(em,'custom_scale',text='')
+ row.prop(em, "custom_linkscale",text="",icon='UNLINKED')
+ row.prop(em,'custom_scac3d',text="",icon='MANIPUL')
+ row = box.row(align =True)
+ row.label(text="UV's Offset:")
+ row = box.row(align =True)
+ row.prop(em,'custom_offsetuv',text='')
+ row.prop(em, "custom_flipuvx",text="",icon='ARROW_LEFTRIGHT')
+ row.prop(em, "custom_flipuvy",text="",icon='FULLSCREEN_ENTER')
+ row = box.row(align =True)
+ row.label(text="UV's Scale:")
+ row = box.row(align =True)
+ if em.custom_linkscaleuv:
+ row.prop(em,'custom_propscaleuv',text='')
+ row.prop(em, "custom_linkscaleuv",text="",icon='LINKED')
+ else:
+ row.prop(em,'custom_scaleuv',text='')
+ row.prop(em, "custom_linkscaleuv",text="",icon='UNLINKED')
+
+ if matBProjection:
+ row = box.column(align =True)
+ row.prop(matBProjection,'alpha', slider = True)
+ row = box.column(align =True)
+
+ row.prop(ob,"custom_fnlevel")
+ row = box.column(align =True)
+
+
+ if ob == bpy.data.objects[em.custom_active_object]:
+ for item in em.custom_props:
+ box = layout.box()
+ row = box.row()
+ if item.custom_active:
+ row.operator("object.active_view",text = "", icon='RADIOBUT_ON', emboss = False).index = item.custom_index
+ else:
+ row.operator("object.active_view",text = "", icon='RADIOBUT_OFF', emboss = False).index = item.custom_index
+ row.prop(item, "custom_active_view", text="")
+ row.operator('object.remove_view', text="", icon = 'PANEL_CLOSE', emboss = False).index = item.custom_index
+ row = layout.row()
+ row.operator('object.create_view', text="Create View", icon = 'RENDER_STILL')
+ else:
+ col = box.column(align =True)
+ col.operator("object.change_object", text="Change Object")
+
+ else:
+ ob = context.object
+ col = layout.column(align = True)
+
+ if ob.active_material is None:
+ col.label(text="Add a material first!", icon="ERROR")
+ elif ob.data.uv_textures.active is None:
+ col.label(text="Create UVMap first!!", icon="ERROR")
+ else:
+ col.operator("object.addbprojectionplane", text="Add BProjection plane")
+ col = layout.column(align = True)
+ col.prop(ob, "custom_sub",text="Subdivision level")
+
+
+# Oprerator Class to apply the image to the plane
+class ApplyImage(Operator):
+ bl_idname = "object.applyimage"
+ bl_label = "Apply image"
+
+ def execute(self, context):
+ applyimage(context)
+
+ return {'FINISHED'}
+
+# Oprerator Class to make the 4 or 6 point and scale the plan
+class IntuitiveScale(Operator):
+ bl_idname = "object.intuitivescale"
+ bl_label = "Draw lines"
+
+ def invoke(self, context, event):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ x = event.mouse_region_x
+ y = event.mouse_region_y
+ if len(ob.grease_pencil.layers.active.frames) == 0:
+ bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
+ "is_start":True, "location":(0, 0, 0),
+ "mouse":(x,y), "pressure":1, "time":0}])
+ else:
+ if em.custom_linkscale:
+ nb_point = 4
+ else:
+ nb_point = 6
+
+ if len(ob.grease_pencil.layers.active.frames[0].strokes) < nb_point:
+ bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
+ "is_start":True, "location":(0, 0, 0),
+ "mouse":(x,y), "pressure":1, "time":0}])
+
+ if len(ob.grease_pencil.layers.active.frames[0].strokes) == nb_point:
+ s = ob.grease_pencil.layers.active.frames[0]
+ v1 = s.strokes[1].points[0].co - s.strokes[0].points[0].co
+ if not em.custom_linkscale:
+ v2 = s.strokes[4].points[0].co - s.strokes[3].points[0].co
+ else:
+ v2 = s.strokes[3].points[0].co - s.strokes[2].points[0].co
+ propx = v1.x/v2.x
+ em.custom_scale[0] *= abs(propx)
+
+ if not em.custom_linkscale:
+ v1 = s.strokes[2].points[0].co - s.strokes[0].points[0].co
+ v2 = s.strokes[5].points[0].co - s.strokes[3].points[0].co
+ propy = v1.y/v2.y
+ em.custom_scale[1] *= abs(propy)
+ bpy.ops.gpencil.active_frame_delete()
+
+ return {'FINISHED'}
+
+# Oprerator Class to configure all wath is needed
+class AddBProjectionPlane(Operator):
+ bl_idname = "object.addbprojectionplane"
+ bl_label = "Configure"
+
+ def creatematerial(self, context):
+ if 'Material for BProjection' not in [mat.name for mat in bpy.data.materials]:
+ bpy.data.textures.new(name='Texture for BProjection',type='IMAGE')
+
+ bpy.data.materials.new(name='Material for BProjection')
+
+ matBProjection = bpy.data.materials['Material for BProjection']
+ matBProjection.texture_slots.add()
+ matBProjection.use_shadeless = True
+ matBProjection.use_transparency = True
+ matBProjection.active_texture = bpy.data.textures['Texture for BProjection']
+
+ index = matBProjection.active_texture_index
+ matBProjection.texture_slots[index].texture_coords = 'UV'
+
+ ob = context.object
+ old_index = ob.active_material_index
+ bpy.ops.object.material_slot_add()
+ index = ob.active_material_index
+ ob.material_slots[index].material = bpy.data.materials['Material for BProjection']
+ bpy.ops.object.material_slot_assign()
+ ob.active_material_index = old_index
+ ob.data.update()
+
+ def execute(self, context):
+ if BProjection_Empty not in [ob.name for ob in bpy.data.objects]:
+
+ cm = bpy.context.object.mode
+ '''tmp = context.object
+ for ob in (ob for ob in bpy.data.objects if ob.type == 'MESH' and ob.hide == False and context.scene in ob.users_scene):
+ context.scene.objects.active = ob
+ bpy.ops.object.mode_set(mode = cm, toggle=False)
+
+ context.scene.objects.active = tmp'''
+ bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
+
+ context.space_data.show_relationship_lines = False
+
+ ob = context.object
+
+ bpy.ops.object.add()
+ em = context.object
+ em.name = BProjection_Empty
+
+ context.scene.objects.active = ob
+ ob.select = True
+
+ bpy.ops.object.editmode_toggle()
+
+ bpy.ops.mesh.primitive_plane_add()
+ bpy.ops.object.vertex_group_assign(new = True)
+ ob.vertex_groups.active.name = 'texture plane'
+ bpy.ops.uv.unwrap()
+
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.vertex_group_select()
+
+ bpy.ops.object.editmode_toggle()
+ for i in range(4):
+ ob.data.edges[len(ob.data.edges)-1-i].crease = 1
+ bpy.ops.object.editmode_toggle()
+
+ em.custom_sub = ob.custom_sub
+ if em.custom_sub > 0:
+ bpy.ops.mesh.subdivide(number_cuts = em.custom_sub)
+
+ em.select = True
+ bpy.ops.object.hook_add_selob()
+ em.select = False
+ em.hide = True
+
+ self.creatematerial(context)
+
+
+ bpy.ops.gpencil.data_add()
+ ob.grease_pencil.draw_mode = 'VIEW'
+ bpy.ops.gpencil.layer_add()
+ ob.grease_pencil.layers.active.color = [1.0,0,0]
+
+ bpy.ops.object.editmode_toggle()
+
+ bpy.ops.object.shape_key_add(from_mix = False)
+
+ bpy.ops.object.create_view()
+
+ km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
+ l = ['view3d.rotate','view3d.move','view3d.zoom','view3d.viewnumpad','MOUSE','KEYBOARD','MIDDLEMOUSE','WHEELINMOUSE','WHEELOUTMOUSE','NUMPAD_1','NUMPAD_3','NUMPAD_7']
+ for kmi in km.keymap_items:
+ if kmi.idname in l and kmi.map_type in l and kmi.type in l:
+ try:
+ p = kmi.properties.delta
+ if p == -1 or p == 1:
+ kmi.idname = 'view3d.zoom_view3d'
+ kmi.properties.delta = p
+ except:
+ try:
+ p = kmi.properties.type
+ if kmi.shift == False :
+ kmi.idname = 'view3d.preset_view3d'
+ kmi.properties.view = p
+ except:
+ if kmi.idname == 'view3d.rotate':
+ kmi.idname = 'view3d.rotate_view3d'
+ if kmi.idname == 'view3d.move':
+ kmi.idname = 'view3d.pan_view3d'
+
+ km = context.window_manager.keyconfigs.default.keymaps['Image Paint']
+ kmi = km.keymap_items.new("object.intuitivescale", 'LEFTMOUSE', 'PRESS', shift=True)
+
+ align_to_view(context)
+
+ context.space_data.cursor_location = em.location
+
+ bpy.ops.object.mode_set(mode = cm, toggle=False)
+ bpy.data.objects[BProjection_Empty].custom_active_object = context.object.name
+
+ return {'FINISHED'}
+
+# Oprerator Class to remove what is no more needed
+class RemoveBProjectionPlane(Operator):
+ bl_idname = "object.removebprojectionplane"
+ bl_label = "Configure"
+
+ def removematerial(self, context):
+ ob = context.object
+ i = 0
+
+ for ms in ob.material_slots:
+ if ms.name == BProjection_Material:
+ index = i
+ i+=1
+
+ ob.active_material_index = index
+ bpy.ops.object.material_slot_remove()
+
+ def execute(self, context):
+ try:
+ cm = bpy.context.object.mode
+ bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
+
+ context.space_data.show_relationship_lines = True
+
+ bpy.ops.object.modifier_remove(modifier="Hook-Empty for BProjection")
+
+ self.removematerial(context)
+
+ ob = context.object
+
+ bpy.ops.object.editmode_toggle()
+
+ bpy.ops.mesh.reveal()
+
+ bpy.ops.mesh.select_all(action='DESELECT')
+
+ ob.vertex_groups.active_index = ob.vertex_groups['texture plane'].index
+ bpy.ops.object.vertex_group_select()
+ bpy.ops.mesh.delete()
+ bpy.ops.object.vertex_group_remove()
+
+ bpy.ops.object.editmode_toggle()
+
+ ob.select = False
+
+ em = bpy.data.objects[BProjection_Empty]
+ context.scene.objects.active = em
+ em.hide = False
+ em.select = True
+ bpy.ops.object.delete()
+
+ context.scene.objects.active = ob
+ ob.select = True
+
+ reinitkey()
+
+ '''tmp = context.object
+ for ob in (ob for ob in bpy.data.objects if ob.type == 'MESH' and ob.hide == False and context.scene in ob.users_scene):
+ context.scene.objects.active = ob
+ bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
+
+ context.scene.objects.active = tmp'''
+ ob = context.object
+
+
+ for i in ob.data.shape_keys.key_blocks:
+ bpy.ops.object.shape_key_remove()
+ bpy.ops.object.shape_key_remove()
+
+ bpy.ops.object.mode_set(mode = cm, toggle=False)
+ removecustomprops()
+
+ except:
+ nothing = 0
+
+ return {'FINISHED'}
+
+def reinitkey():
+ km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
+ l = ['view3d.zoom_view3d','view3d.preset_view3d','view3d.rotate_view3d','view3d.pan_view3d','MOUSE','KEYBOARD','MIDDLEMOUSE','WHEELINMOUSE','WHEELOUTMOUSE','NUMPAD_1','NUMPAD_3','NUMPAD_7']
+ for kmi in km.keymap_items:
+ if kmi.idname in l and kmi.map_type in l and kmi.type in l:
+ try:
+ p = kmi.properties.delta
+ if p == -1 or p == 1:
+ kmi.idname = 'view3d.zoom'
+ kmi.properties.delta = p
+ except:
+ try:
+ p = kmi.properties.view
+ if kmi.shift == False :
+ kmi.idname = 'view3d.viewnumpad'
+ kmi.properties.type = p
+ except:
+ if kmi.idname == 'view3d.rotate_view3d':
+ kmi.idname = 'view3d.rotate'
+ if kmi.idname == 'view3d.pan_view3d':
+ kmi.idname = 'view3d.move'
+
+ km = bpy.context.window_manager.keyconfigs.default.keymaps['Image Paint']
+ #to do
+ for kmi in (kmi for kmi in km.keymap_items if kmi.idname in {"object.intuitivescale", }):
+ km.keymap_items.remove(kmi)
+
+# Oprerator Class to remove what is no more needed
+class ChangeObject(Operator):
+ bl_idname = "object.change_object"
+ bl_label = "Change Object"
+
+ def removematerial(self, context):
+ ob = context.object
+ i = 0
+
+ for ms in ob.material_slots:
+ if ms.name == BProjection_Material:
+ index = i
+ i+=1
+
+ ob.active_material_index = index
+ bpy.ops.object.material_slot_remove()
+
+ def execute(self, context):
+ new_ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ context.scene.objects.active = bpy.data.objects[em.custom_active_object]
+ ob = context.object
+ if ob != new_ob:
+ cm = bpy.context.object.mode
+ bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
+
+ bpy.ops.object.modifier_remove(modifier="Hook-Empty for BProjection")
+
+ ob = context.object
+
+ bpy.ops.object.editmode_toggle()
+
+ bpy.ops.mesh.reveal()
+
+ bpy.ops.mesh.select_all(action='DESELECT')
+ ob.vertex_groups.active_index = ob.vertex_groups['texture plane'].index
+ bpy.ops.object.vertex_group_select()
+ lo_b = [ob for ob in bpy.data.objects if ob.type == 'MESH']
+ bpy.ops.mesh.separate(type='SELECTED')
+ lo_a = [ob for ob in bpy.data.objects if ob.type == 'MESH']
+ bpy.ops.object.vertex_group_remove()
+
+ for i in lo_b:
+ lo_a.remove(i)
+ bplane = lo_a[0]
+
+ bpy.ops.object.editmode_toggle()
+
+ self.removematerial(context)
+
+ bpy.ops.object.mode_set(mode = cm, toggle=False)
+
+ shape_index = ob.active_shape_key_index
+
+ for i in ob.data.shape_keys.key_blocks:
+ bpy.ops.object.shape_key_remove()
+ bpy.ops.object.shape_key_remove()
+
+ ob.select = False
+
+ bplane.select = True
+ context.scene.objects.active = bplane
+ for ms in (ms for ms in bplane.material_slots if ms.name != BProjection_Material):
+ bplane.active_material = ms.material
+ bpy.ops.object.material_slot_remove()
+
+ for gs in (gs for gs in bplane.vertex_groups if gs.name != 'texture plane'):
+ bplane.vertex_groups.active_index = gs.index
+ bpy.ops.object.vertex_group_remove()
+
+ context.scene.objects.active = new_ob
+ cm = new_ob.mode
+ bpy.ops.object.mode_set(mode = 'OBJECT', toggle=False)
+ bpy.ops.object.join()
+
+ em.hide = False
+ em.select = True
+ new_ob.select = False
+ bpy.ops.object.location_clear()
+ bpy.ops.object.rotation_clear()
+ bpy.ops.object.scale_clear()
+ context.scene.objects.active = new_ob
+ bpy.ops.object.editmode_toggle()
+ bpy.ops.object.hook_add_selob()
+ bpy.ops.object.editmode_toggle()
+ em.hide = True
+ em.select = False
+ new_ob.select = True
+ em.custom_active_object = new_ob.name
+ tmp = em.custom_c3d
+ em.custom_c3d = False
+ bpy.ops.object.active_view(index = shape_index-1)
+ bpy.ops.object.mode_set(mode = cm, toggle=False)
+
+ sd = context.space_data
+ r3d = sd.region_3d
+ vr = r3d.view_rotation.copy()
+ vr.invert()
+ ob_loc = ob.location.copy()
+ new_ob_loc = new_ob.location.copy()
+ ob_loc.rotate(vr)
+ new_ob_loc.rotate(vr)
+ em.custom_location += Vector((ob_loc.x - new_ob_loc.x, ob_loc.y - new_ob_loc.y, 0.0))
+ em.custom_c3d = tmp
+
+ return {'FINISHED'}
+
+# Oprerator Class to rotate the view3D
+class RotateView3D(Operator):
+ bl_idname = "view3d.rotate_view3d"
+ bl_label = "Rotate the View3D"
+
+ first_mouse = Vector((0,0))
+
+ pan = Vector((0,0))
+
+ key = ['']
+ block = 0
+
+ first_time = True
+ tmp_level = -1
+
+ def vect_sphere(self, context, mx, my):
+ width = context.area.regions[4].width
+ height = context.area.regions[4].height
+
+ if width >= height:
+ ratio = height/width
+
+ x = 2*mx/width
+ y = 2*ratio*my/height
+
+ x = x - 1
+ y = y - ratio
+ else:
+ ratio = width/height
+
+ x = 2*ratio*mx/width
+ y = 2*my/height
+
+ x = x - ratio
+ y = y - 1
+
+ z2 = 1 - x * x - y * y
+ if z2 > 0:
+ z= sqrt(z2)
+ else : z=0
+
+ p = Vector((x, y, z))
+ p.normalize()
+ return p
+
+ def tracball(self, context, mx, my, origine):
+ sd = context.space_data
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+
+ vr_b = sd.region_3d.view_rotation.copy()
+ vr_b.invert()
+ pos_init = sd.region_3d.view_location - origine
+ sd.region_3d.view_location = origine
+
+ v1 = self.vect_sphere(context, self.first_mouse.x, self.first_mouse.y)
+ v2 = self.vect_sphere(context, mx, my)
+
+ axis = Vector.cross(v1,v2);
+ angle = Vector.angle(v1,v2);
+
+ q = Quaternion(axis,-2*angle)
+
+ sd.region_3d.view_rotation *=q
+ sd.region_3d.update()
+
+ vr_a = sd.region_3d.view_rotation.copy()
+ pos_init.rotate(vr_a*vr_b)
+ sd.region_3d.view_location = pos_init + origine
+
+ self.first_mouse = Vector((mx, my))
+
+ def modal(self, context, event):
+ ob = context.object
+ em = bpy.data.objects['Empty for BProjection']
+ reg = context.area.regions[4]
+
+
+ if event.type not in {'MOUSEMOVE','INBETWEEN_MOUSEMOVE'}:
+ self.pan = Vector((event.mouse_region_x, event.mouse_region_y))
+ self.key = [event.type]
+ self.block = 1
+
+ if event.value == 'RELEASE':
+ if self.tmp_level > -1:
+ for sub in context.object.modifiers:
+ if sub.type in ['SUBSURF','MULTIRES']:
+ sub.levels = self.tmp_level
+ return {'FINISHED'}
+
+ if event.type == 'MOUSEMOVE':
+ if self.block == 0:
+ self.tracball(context, event.mouse_region_x, event.mouse_region_y,ob.location)
+ align_to_view(context)
+ #to unlock the camera
+ if self.first_time:
+ rot_ang = context.user_preferences.view.rotation_angle
+ context.user_preferences.view.rotation_angle = 0
+ bpy.ops.view3d.view_orbit(type='ORBITLEFT')
+ context.user_preferences.view.rotation_angle = rot_ang
+ bpy.ops.view3d.view_persportho()
+ bpy.ops.view3d.view_persportho()
+ self.first_time = False
+ else:
+ deltax = event.mouse_region_x - round(self.pan.x)
+ deltay = event.mouse_region_y - round(self.pan.y)
+
+ if 'G' in self.key:
+ sd = context.space_data
+ l = sd.region_3d
+ vr = l.view_rotation.copy()
+ vr.invert()
+
+ v_init = Vector((0.0,0.0,1.0))
+
+ pos = [-deltax,-deltay]
+ v = view3d_utils.region_2d_to_location_3d(context.region, l, pos, v_init)
+ pos = [0,0]
+ vbl = view3d_utils.region_2d_to_location_3d(context.region, l, pos, v_init)
+ loc = vbl - v
+
+ loc.rotate(vr)
+ em.custom_location += loc
+
+ if 'S' in self.key:
+ s = em.custom_scale
+ if em.custom_linkscale:
+ em.custom_propscale += deltax/20
+ else:
+ em.custom_scale = [s[0] + deltax/20, s[1] + deltay/20]
+
+ if 'Z' in self.key:
+ em.custom_location.z+=deltax/10
+
+ if 'R' in self.key:
+ em.custom_rotation+=deltax
+
+ if 'U' in self.key:
+ suv = em.custom_scaleuv
+ if em.custom_linkscaleuv:
+ em.custom_propscaleuv += deltax/50
+ else:
+ em.custom_scaleuv= [suv[0] + deltax/50 , suv[1] + deltay/50]
+
+ if 'Y' in self.key:
+ ouv = em.custom_offsetuv
+ em.custom_offsetuv = [ouv[0] - deltax/50,ouv[1] - deltay/50]
+
+ self.pan = Vector((event.mouse_region_x, event.mouse_region_y))
+
+ if 'C' in self.key:
+ clear_props(context)
+
+ if 'O' in self.key:
+ bpy.ops.object.change_object()
+ return {'RUNNING_MODAL'}
+
+ def execute(self, context):
+ align_to_view(context)
+
+ return{'FINISHED'}
+
+ def invoke(self, context, event):
+ bpy.data.objects['Empty for BProjection']
+ context.window_manager.modal_handler_add(self)
+ self.first_mouse = Vector((event.mouse_region_x,event.mouse_region_y))
+ self.first_time = True
+ for sub in context.object.modifiers:
+ if sub.type in ['SUBSURF', 'MULTIRES']:
+ self.tmp_level = sub.levels
+ if sub.levels - self.tmp_level <0:
+ sub.levels = 0
+ else:
+ sub.levels += bpy.context.object.custom_fnlevel
+ return {'RUNNING_MODAL'}
+
+
+# Oprerator Class to pan the view3D
+class PanView3D(bpy.types.Operator):
+ bl_idname = "view3d.pan_view3d"
+ bl_label = "Pan View3D"
+
+ first_mouse = Vector((0,0))
+ tmp_level = -1
+
+ def modal(self, context, event):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ width = context.area.regions[4].width
+ height = context.area.regions[4].height
+
+ deltax = event.mouse_region_x - self.first_mouse.x
+ deltay = event.mouse_region_y - self.first_mouse.y
+
+ sd = context.space_data
+ r3d = sd.region_3d
+ vr = r3d.view_rotation.copy()
+ vr.invert()
+
+ v_init = Vector((0.0,0.0,1.0))
+
+ pos = [deltax,deltay]
+ v = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
+ pos = [0,0]
+ vbl = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
+ loc = vbl - v
+ sd.region_3d.view_location += loc
+ loc.rotate(vr)
+ em.custom_location += loc
+
+ self.first_mouse.x = event.mouse_region_x
+ self.first_mouse.y = event.mouse_region_y
+
+ if event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':
+ if self.tmp_level > -1:
+ for sub in context.object.modifiers:
+ if sub.type in ['SUBSURF','MULTIRES']:
+ sub.levels = self.tmp_level
+ return {'FINISHED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ bpy.data.objects['Empty for BProjection']
+ context.window_manager.modal_handler_add(self)
+ self.first_mouse.x = event.mouse_region_x
+ self.first_mouse.y = event.mouse_region_y
+ for sub in context.object.modifiers:
+ if sub.type in ['SUBSURF', 'MULTIRES']:
+ self.tmp_level = sub.levels
+ if sub.levels - self.tmp_level <0:
+ sub.levels = 0
+ else:
+ sub.levels += bpy.context.object.custom_fnlevel
+
+ return {'RUNNING_MODAL'}
+
+ def execute(self, context):
+ align_to_view(context)
+
+ return{'FINISHED'}
+
+# Oprerator Class to zoom the view3D
+class ZoomView3D(Operator):
+ bl_idname = "view3d.zoom_view3d"
+ bl_label = "Zoom View3D"
+
+ delta = FloatProperty(
+ name="delta",
+ description="Delta",
+ min=-1.0, max=1,
+ default=1.0)
+
+ def invoke(self, context, event):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ sd = context.space_data
+
+ width = context.area.regions[4].width
+ height = context.area.regions[4].height
+
+ r3d = sd.region_3d
+ v_init = Vector((0.0,0.0,1.0))
+
+ pos = [width,height]
+ vtr_b = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
+ pos = [0,0]
+ vbl_b = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
+ len_b = vtr_b - vbl_b
+
+ bpy.ops.view3d.zoom(delta = self.delta)
+ r3d.update()
+
+ pos = [width,height]
+ vtr_a = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
+ pos = [0,0]
+ vbl_a = view3d_utils.region_2d_to_location_3d(context.region, r3d, pos, v_init)
+ len_a = vtr_a - vbl_a
+
+ fac = len_a.length/len_b.length
+ r3d.view_location -= ob.location
+ r3d.view_location *= fac
+ r3d.view_location += ob.location
+ vres = Vector((em.custom_location.x*fac,em.custom_location.y*fac,em.custom_location.z))
+ em.custom_location = vres
+
+
+ align_to_view(context)
+
+ return {'FINISHED'}
+
+ def execute(self, context):
+ align_to_view(context)
+
+ return{'FINISHED'}
+
+# Oprerator Class to use numpad shortcut
+class PresetView3D(Operator):
+ bl_idname = "view3d.preset_view3d"
+ bl_label = "Preset View3D"
+
+ view = StringProperty(name="View", description="Select the view", default='TOP')
+ def invoke(self, context, event):
+ ob = context.object
+ em = bpy.data.objects[BProjection_Empty]
+ origine = ob.location
+ sd = context.space_data
+
+ vr_b = sd.region_3d.view_rotation.copy()
+ vr_b.invert()
+ pos_init = sd.region_3d.view_location - origine
+ sd.region_3d.view_location = origine
+
+ tmp = context.user_preferences.view.smooth_view
+ context.user_preferences.view.smooth_view = 0
+ bpy.ops.view3d.viewnumpad(type=self.view)
+ align_to_view(context)
+ context.user_preferences.view.smooth_view = tmp
+
+ vr_a = sd.region_3d.view_rotation.copy()
+ pos_init.rotate(vr_a*vr_b)
+ sd.region_3d.view_location = pos_init + origine
+
+ return {'FINISHED'}
+
+ at persistent
+def load_handler(dummy):
+ reinitkey()
+
+def register():
+ bpy.utils.register_module(__name__)
+ createcustomprops(bpy.context)
+ bpy.app.handlers.load_post.append(load_handler)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/space_view3d_quickPrefs.py b/release/scripts/addons_contrib/space_view3d_quickPrefs.py
new file mode 100644
index 0000000..79a7d24
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_quickPrefs.py
@@ -0,0 +1,968 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "QuickPrefs",
+ "author": "Sean Olson",
+ "version": (2,2),
+ "blender": (2, 66, 0),
+ "location": "3DView->Properties Panel (N-Key)",
+ "description": "Add often changed User Preference options to Properties panel.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/3D_interaction/QuickPrefs",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27822",
+ "category": "3D View"}
+
+import os
+
+import bpy
+from bpy.types import Menu, Panel
+from rna_prop_ui import PropertyPanel
+from bpy.app.handlers import persistent
+from bpy.props import (
+ BoolProperty,
+ EnumProperty,
+ FloatProperty,
+ CollectionProperty,
+ IntProperty,
+ StringProperty,
+ PointerProperty
+ )
+
+
+import bpy_extras
+
+#Global Variables
+recursive = False
+renaming = True
+lastindex = 0
+lastname = ""
+debug = 0
+defaultfilepath=os.path.join(bpy.utils.script_paths(subdir="addons")[0], "quickprefpresets")
+
+
+##########################################
+####### Import/Export Functions ##########
+##########################################
+
+#import all grabs all files in the given directory and imports them
+ at persistent
+def gllightpreset_importall():
+ path = bpy.context.scene.quickprefs.gllightpreset_importdirectory
+ directorylisting = os.listdir(path)
+
+ for infile in directorylisting:
+ if not os.path.isdir(infile): #check if the file is a directory
+ if '.preset' in infile: #check that this is a .preset file
+ thefile=os.path.join(path, infile) #join the filename with the path
+ gllightpreset_importsingle(thefile) #import it!
+
+#import single takes a given filename and imports it
+def gllightpreset_importsingle(filename):
+
+ if not os.path.isdir(filename): #check if the file is a directory
+ if '.preset' in filename: #check to make sure this is a preset file
+ readfile=open(filename, 'r')
+
+ name=readfile.readline()
+ name=name[:-1]
+
+ illuminationString0=readfile.readline()
+ illuminationString0=illuminationString0[:-1]
+
+ if illuminationString0=="True":
+ illumination0=True
+ else:
+ illumination0=False
+
+ illuminationString1=readfile.readline()
+ illuminationString1=illuminationString1[:-1]
+ if illuminationString1=="True":
+ illumination1=True
+ else:
+ illumination1=False
+
+ illuminationString2=readfile.readline()
+ illuminationString2=illuminationString2[:-1]
+ if illuminationString2=="True":
+ illumination2=True
+ else:
+ illumination2=False
+
+ #convert strings to booleans
+
+ str=readfile.readline()
+ strArray=str.split()
+ direction0x=strArray[0]
+ direction0y=strArray[1]
+ direction0z=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ direction1x=strArray[0]
+ direction1y=strArray[1]
+ direction1z=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ direction2x=strArray[0]
+ direction2y=strArray[1]
+ direction2z=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ diffuse0r=strArray[0]
+ diffuse0g=strArray[1]
+ diffuse0b=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ diffuse1r=strArray[0]
+ diffuse1g=strArray[1]
+ diffuse1b=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ diffuse2r=strArray[0]
+ diffuse2g=strArray[1]
+ diffuse2b=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ spec0r=strArray[0]
+ spec0g=strArray[1]
+ spec0b=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ spec1r=strArray[0]
+ spec1g=strArray[1]
+ spec1b=strArray[2]
+
+ str=readfile.readline()
+ strArray=str.split()
+ spec2r=strArray[0]
+ spec2g=strArray[1]
+ spec2b=strArray[2]
+
+ #set the variables
+ system=bpy.context.user_preferences.system
+ system.solid_lights[0].use=illumination0
+ system.solid_lights[1].use=illumination1
+ system.solid_lights[2].use=illumination2
+
+ system.solid_lights[0].direction = (float(direction0x), float(direction0y), float(direction0z))
+ system.solid_lights[1].direction = (float(direction1x), float(direction1y), float(direction1z))
+ system.solid_lights[2].direction = (float(direction2x), float(direction2y), float(direction2z))
+
+ system.solid_lights[0].diffuse_color=(float(diffuse0r), float(diffuse0g), float(diffuse0b))
+ system.solid_lights[1].diffuse_color=(float(diffuse1r), float(diffuse1g), float(diffuse1b))
+ system.solid_lights[2].diffuse_color=(float(diffuse2r), float(diffuse2g), float(diffuse2b))
+
+ system.solid_lights[0].specular_color=(float(spec0r), float(spec0g), float(spec0b))
+ system.solid_lights[1].specular_color=(float(spec1r), float(spec1g), float(spec1b))
+ system.solid_lights[2].specular_color=(float(spec2r), float(spec2g), float(spec2b))
+ gllightpreset_add(name)
+ gllightpreset_save()
+
+#Export all exports the entire contents of your presets list to the given file
+ at persistent
+def gllightpreset_exportall(context):
+ for i in range(len(bpy.context.scene.quickprefs.gllightpreset)):
+ gllightpreset_exportsingle(i, True)
+
+
+def gllightpreset_exportsingle(index, multiimport):
+ scn=bpy.context.scene.quickprefs
+ name=scn.gllightpreset[index].name
+
+ illuminatedBool0=scn.gllightpreset[index].illuminated0
+ illuminatedBool1=scn.gllightpreset[index].illuminated1
+ illuminatedBool2=scn.gllightpreset[index].illuminated2
+
+ #illuminations
+ if illuminatedBool0==True:
+ illuminated0="True"
+ else:
+ illuminated0="False"
+
+ if illuminatedBool1==True:
+ illuminated1="True"
+ else:
+ illuminated1="False"
+
+ if illuminatedBool2==True:
+ illuminated2="True"
+ else:
+ illuminated2="False"
+
+ #direction light0
+ dirx=str(scn.gllightpreset[index].direction0[0])
+ diry=str(scn.gllightpreset[index].direction0[1])
+ dirz=str(scn.gllightpreset[index].direction0[2])
+ direction0=dirx + " " + diry + " " + dirz + " "
+
+ #direction light1
+ dirx=str(scn.gllightpreset[index].direction1[0])
+ diry=str(scn.gllightpreset[index].direction1[1])
+ dirz=str(scn.gllightpreset[index].direction1[2])
+ direction1=dirx + " " + diry + " " + dirz + " "
+
+ #direction light2
+ dirx=str(scn.gllightpreset[index].direction2[0])
+ diry=str(scn.gllightpreset[index].direction2[1])
+ dirz=str(scn.gllightpreset[index].direction2[2])
+ direction2=dirx + " " + diry + " " + dirz + " "
+
+ #diffuse light0
+ difr=str(scn.gllightpreset[index].diffuse0[0])
+ difg=str(scn.gllightpreset[index].diffuse0[1])
+ difb=str(scn.gllightpreset[index].diffuse0[2])
+ diffuse0=difr + " " + difg + " " + difb + " "
+
+ #diffuse light1
+ difr=str(scn.gllightpreset[index].diffuse1[0])
+ difg=str(scn.gllightpreset[index].diffuse1[1])
+ difb=str(scn.gllightpreset[index].diffuse1[2])
+ diffuse1=difr + " " + difg + " " + difb + " "
+
+ #diffuse light2
+ difr=str(scn.gllightpreset[index].diffuse2[0])
+ difg=str(scn.gllightpreset[index].diffuse2[1])
+ difb=str(scn.gllightpreset[index].diffuse2[2])
+ diffuse2=difr + " " + difg + " " + difb + " "
+
+ #specular light 0
+ specr=str(scn.gllightpreset[index].specular0[0])
+ specg=str(scn.gllightpreset[index].specular0[1])
+ specb=str(scn.gllightpreset[index].specular0[2])
+ specular0=specr + " " + specg + " " + specb + " "
+
+ #specular light 1
+ specr=str(scn.gllightpreset[index].specular1[0])
+ specg=str(scn.gllightpreset[index].specular1[1])
+ specb=str(scn.gllightpreset[index].specular1[2])
+ specular1=specr + " " + specg + " " + specb + " "
+
+ #specular light 2
+ specr=str(scn.gllightpreset[index].specular2[0])
+ specg=str(scn.gllightpreset[index].specular2[1])
+ specb=str(scn.gllightpreset[index].specular2[2])
+ specular2=specr + " " + specg + " " + specb + " "
+
+ printstring=name+"\n"
+ printstring+=illuminated0 +"\n"+ illuminated1 +"\n"+ illuminated2+"\n"
+ printstring+=direction0 +"\n"+ direction1 +"\n"+ direction2 +"\n"
+ printstring+=diffuse0+"\n"+diffuse1 +"\n"+ diffuse2 +"\n"
+ printstring+=specular0+"\n"+specular1+"\n"+specular2+"\n"
+
+ if multiimport==True:
+ filepath = scn.gllightpreset_exportdirectory
+ else:
+ filepath = scn.gllightpreset_exportfile
+
+ if not os.path.exists(filepath):
+ os.mkdir(filepath)
+ filepath=os.path.join(filepath, (name+".preset"))
+ writefile = open(filepath, 'w')
+ writefile.write(printstring)
+
+##########################################
+####### General Presets Functions #######
+##########################################
+
+def gllightpreset_addPresets():
+
+ system=bpy.context.user_preferences.system
+
+ system.solid_lights[0].use=True
+ system.solid_lights[1].use=True
+ system.solid_lights[2].use=True
+
+ system.solid_lights[0].direction = (-0.8920, 0.3000, 0.8999)
+ system.solid_lights[1].direction = (0.5880, 0.4600, 0.2480)
+ system.solid_lights[2].direction = (0.2159, -0.3920, -0.2159)
+
+ system.solid_lights[0].diffuse_color=(0.8000, 0.8000, 0.8000)
+ system.solid_lights[1].diffuse_color=(0.4980, 0.5000, 0.6000)
+ system.solid_lights[2].diffuse_color=(0.7980, 0.8379, 1.0)
+
+ system.solid_lights[0].specular_color=(0.5, 0.5, 0.5)
+ system.solid_lights[1].specular_color=(0.2000, 0.2, 0.2)
+ system.solid_lights[2].specular_color=(0.0659, 0.0, 0.0)
+ gllightpreset_add("(Default)")
+ gllightpreset_save()
+
+ system.solid_lights[0].use=True
+ system.solid_lights[1].use=True
+ system.solid_lights[2].use=True
+
+ system.solid_lights[0].direction = (-0.3207, 0.4245, 0.8466)
+ system.solid_lights[1].direction = (0.4259, -0.0555, 0.9030)
+ system.solid_lights[2].direction = (-0.4485, 0.2400, -0.8609)
+
+ system.solid_lights[0].diffuse_color=(0.4292, 0.0457, 0.0457)
+ system.solid_lights[1].diffuse_color=(0.7873, 0.4424, 0.2893)
+ system.solid_lights[2].diffuse_color=(0.7483, 0.7168, 0.6764)
+
+ system.solid_lights[0].specular_color=(0.2000, 0.2000, 0.2000)
+ system.solid_lights[1].specular_color=(0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color=(0.0, 0.0, 0.0)
+ gllightpreset_add("Orange Clay")
+ gllightpreset_save()
+
+ system.solid_lights[0].use=True
+ system.solid_lights[1].use=True
+ system.solid_lights[2].use=True
+
+ system.solid_lights[0].direction=(-0.06666, 0.8222, 0.5652)
+ system.solid_lights[1].direction=(-0.8555, 0.1111, 0.5056)
+ system.solid_lights[2].direction=(0.9000, 0.1555, 0.4071)
+
+ system.solid_lights[0].diffuse_color=(0.1000, 0.1000, 0.1000)
+ system.solid_lights[1].diffuse_color=(1.0, 0.9734, 0.8713)
+ system.solid_lights[2].diffuse_color=(0.7835, 0.9215, 1.0)
+
+ system.solid_lights[0].specular_color=(0.0, 0.0, 0.0)
+ system.solid_lights[1].specular_color=(0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color=(0.0, 0.0, 0.0)
+ gllightpreset_add("Softblend")
+ gllightpreset_save()
+
+ system.solid_lights[0].use = True
+ system.solid_lights[1].use = True
+ system.solid_lights[2].use = True
+
+ system.solid_lights[0].direction = (0.3666, 0.2888, 0.8843)
+ system.solid_lights[1].direction = (0.1111, 0.0888, 0.9898)
+ system.solid_lights[2].direction = (-0.5142, 0.5142, -0.6864)
+
+ system.solid_lights[0].diffuse_color = (0.6618, 0.5481, 0.5054)
+ system.solid_lights[1].diffuse_color = (0.3672, 0.2371, 0.1752)
+ system.solid_lights[2].diffuse_color = (1.0, 0.9574, 0.9058)
+
+ system.solid_lights[0].specular_color = (0.4969, 0.4886, 0.4820)
+ system.solid_lights[1].specular_color = (0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color = (1.0, 1.0, 1.0)
+ gllightpreset_add("Skin")
+ gllightpreset_save()
+
+ system.solid_lights[0].use = True
+ system.solid_lights[1].use = False
+ system.solid_lights[2].use = False
+
+ system.solid_lights[0].direction = (0.0111, 0.4000, 0.9164)
+ system.solid_lights[1].direction = (0.1111, 0.0888, 0.9898)
+ system.solid_lights[2].direction = (-0.5142, 0.5142, -0.6864)
+
+ system.solid_lights[0].diffuse_color = (1.0, 0.5912, 0.4148)
+ system.solid_lights[1].diffuse_color = (0.4962, 0.4962, 0.4962)
+ system.solid_lights[2].diffuse_color = (1.0, 0.9574, 0.9058)
+
+ system.solid_lights[0].specular_color = (0.2036, 0.4206, 0.7873)
+ system.solid_lights[1].specular_color = (0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color = (1.0, 1.0, 1.0)
+ gllightpreset_add("Candy")
+ gllightpreset_save();
+
+ system.solid_lights[0].use = True
+ system.solid_lights[1].use = True
+ system.solid_lights[2].use = True
+
+ system.solid_lights[0].direction = (-0.6124, 0.6046, 0.5092)
+ system.solid_lights[1].direction = (0.1627, 0.5271, 0.8340)
+ system.solid_lights[2].direction = (-0.5858, 0.7811, -0.2160)
+
+ system.solid_lights[0].diffuse_color = (0.0, 0.3564, 0.4292)
+ system.solid_lights[1].diffuse_color = (0.7873, 0.0038, 0.7197)
+ system.solid_lights[2].diffuse_color = (0.1994, 0.2014, 0.2330)
+
+ system.solid_lights[0].specular_color = (0.0946, 0.0946, 0.0946)
+ system.solid_lights[1].specular_color = (0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color = (0.0, 0.0, 0.0)
+ gllightpreset_add("Purpleboogers.com")
+ gllightpreset_save();
+
+ system.solid_lights[0].use = True
+ system.solid_lights[1].use = False
+ system.solid_lights[2].use = False
+
+ system.solid_lights[0].direction = (0.0111, 0.4000, 0.9164)
+ system.solid_lights[1].direction = (0.1111, 0.0888, 0.9898)
+ system.solid_lights[2].direction = (-0.5142, 0.5142, -0.6864)
+
+ system.solid_lights[0].diffuse_color = (0.8000, 0.8000, 0.8000)
+ system.solid_lights[1].diffuse_color = (0.4962, 0.4962, 0.4962)
+ system.solid_lights[2].diffuse_color = (1.0, 0.9574, 0.9058)
+
+ system.solid_lights[0].specular_color = (0.4540, 0.4540, 0.4540)
+ system.solid_lights[1].specular_color = (0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color = (1.0, 1.0, 1.0)
+ gllightpreset_add("Dark Gray")
+ gllightpreset_save()
+
+ system.solid_lights[0].use = True
+ system.solid_lights[1].use = False
+ system.solid_lights[2].use = False
+
+ system.solid_lights[0].direction = (0.0333, 0.2444, 0.9690)
+ system.solid_lights[1].direction = (0.1111, 0.08888, 0.9898)
+ system.solid_lights[2].direction = (-0.5142, 0.5142, -0.6864)
+
+ system.solid_lights[0].diffuse_color = (0.8000, 0.6670, 0.6020)
+ system.solid_lights[1].diffuse_color = (0.4962, 0.4962, 0.4962)
+ system.solid_lights[2].diffuse_color = (1.0, 0.9574, 0.9058)
+
+ system.solid_lights[0].specular_color = (0.3281, 0.3281, 0.3281)
+ system.solid_lights[1].specular_color = (0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color = (1.0, 1.0, 1.0)
+ gllightpreset_add("Turntable")
+ gllightpreset_save()
+
+ system.solid_lights[0].use = True
+ system.solid_lights[1].use = True
+ system.solid_lights[2].use = True
+
+ system.solid_lights[0].direction = (-0.2555, 0.5444, 0.7989)
+ system.solid_lights[1].direction = (0.5666, -0.7333, 0.3756)
+ system.solid_lights[2].direction = (-0.5142, 0.5142, -0.6864)
+
+ system.solid_lights[0].diffuse_color = (1.0, 0.9475, 0.3194)
+ system.solid_lights[1].diffuse_color = (0.3851, 0.2978, 0.1612)
+ system.solid_lights[2].diffuse_color = (1.0, 1.0, 1.0)
+
+ system.solid_lights[0].specular_color = (0.2740, 0.2740, 0.2740)
+ system.solid_lights[1].specular_color = (0.0, 0.0, 0.0)
+ system.solid_lights[2].specular_color = (0.0, 0.0, 0.0)
+ gllightpreset_add("Yellow Clay")
+ gllightpreset_save()
+
+##########################################
+####### LightPreset Functions #######
+##########################################
+
+def gllightpreset_name(self, context):
+ global recursive
+ global renaming
+ global lastname
+ if recursive==True: return
+ recursive=True
+
+ tmp=self.name
+ self.name=self.name+"@temporaryname"
+ self.name=gllightpreset_checkname(tmp)
+ tmp=self.name
+ if renaming==True: gllightpreset_rename(lastname, tmp)
+ #gllightpreset_sort()
+
+ recursive=False
+
+def gllightpreset_checkname(name):
+ collection=bpy.context.scene.quickprefs.gllightpreset
+ if name=="": name="Preset"
+
+ if not name in collection:
+ return name
+
+ pos = name.rfind(".")
+ if pos==-1:
+ name=name+".001"
+ pos=len(name)-4
+
+ for i in range(1, 1000):
+ nr="00"+str(i)
+ tmp=name[:pos+1]+nr[len(nr)-3:]
+ if not tmp in collection:
+ return tmp
+ return "Preset.???"
+
+def gllightpreset_rename(old, new):
+ for o in bpy.context.scene.quickprefs.objects:
+ if o.get("gllightpreset", "Default")==old:
+ o.gllightpreset=new
+
+ at persistent
+def gllightpreset_index(self, context):
+ global recursive
+ if recursive==True: return
+ recursive=True
+
+ scn=bpy.context.scene.quickprefs
+
+ if scn.gllightpreset_index > len(scn.gllightpreset)-1:
+ scn.gllightpreset_index = len(scn.gllightpreset)-1
+
+ recursive=False
+
+def gllightpreset_add(name=""):
+ global renaming
+ renaming=False
+
+ scn=bpy.context.scene.quickprefs
+
+ entry=scn.gllightpreset.add()
+ bpy.context.scene.quickprefs['gllightpreset_index']=len(scn.gllightpreset)-1
+ entry.name=gllightpreset_checkname(name)
+
+ renaming=True
+ gllightpreset_save()
+
+def gllightpreset_delete():
+ scn=bpy.context.scene
+ index=scn.quickprefs.gllightpreset_index
+ name=scn.quickprefs.gllightpreset[index].name
+
+ for o in scn.objects:
+ if o.get("gllightpreset", "Default")==name:
+ o.gllightpreset="Default"
+
+ scn.quickprefs.gllightpreset.remove(index)
+
+
+def gllightpreset_save():
+ index=bpy.context.scene.quickprefs.gllightpreset_index
+ name=bpy.context.scene.quickprefs.gllightpreset[index].name
+
+ bpy.context.scene.quickprefs.gllightpreset[index].illuminated0 = bpy.context.user_preferences.system.solid_lights[0].use
+ bpy.context.scene.quickprefs.gllightpreset[index].illuminated1 = bpy.context.user_preferences.system.solid_lights[1].use
+ bpy.context.scene.quickprefs.gllightpreset[index].illuminated2 = bpy.context.user_preferences.system.solid_lights[2].use
+
+ bpy.context.scene.quickprefs.gllightpreset[index].direction0 = bpy.context.user_preferences.system.solid_lights[0].direction
+ bpy.context.scene.quickprefs.gllightpreset[index].direction1 = bpy.context.user_preferences.system.solid_lights[1].direction
+ bpy.context.scene.quickprefs.gllightpreset[index].direction2 = bpy.context.user_preferences.system.solid_lights[2].direction
+
+ bpy.context.scene.quickprefs.gllightpreset[index].diffuse0 = bpy.context.user_preferences.system.solid_lights[0].diffuse_color
+ bpy.context.scene.quickprefs.gllightpreset[index].diffuse1 = bpy.context.user_preferences.system.solid_lights[1].diffuse_color
+ bpy.context.scene.quickprefs.gllightpreset[index].diffuse2 = bpy.context.user_preferences.system.solid_lights[2].diffuse_color
+
+ bpy.context.scene.quickprefs.gllightpreset[index].specular0 = bpy.context.user_preferences.system.solid_lights[0].specular_color
+ bpy.context.scene.quickprefs.gllightpreset[index].specular1 = bpy.context.user_preferences.system.solid_lights[1].specular_color
+ bpy.context.scene.quickprefs.gllightpreset[index].specular2 = bpy.context.user_preferences.system.solid_lights[2].specular_color
+
+#select the current light
+def gllightpreset_select():
+ index=bpy.context.scene.quickprefs.gllightpreset_index
+ name=bpy.context.scene.quickprefs.gllightpreset[index].name
+
+ bpy.context.user_preferences.system.solid_lights[0].use=bpy.context.scene.quickprefs.gllightpreset[index].illuminated0
+ bpy.context.user_preferences.system.solid_lights[1].use=bpy.context.scene.quickprefs.gllightpreset[index].illuminated1
+ bpy.context.user_preferences.system.solid_lights[2].use=bpy.context.scene.quickprefs.gllightpreset[index].illuminated2
+
+ bpy.context.user_preferences.system.solid_lights[0].direction=bpy.context.scene.quickprefs.gllightpreset[index].direction0
+ bpy.context.user_preferences.system.solid_lights[1].direction=bpy.context.scene.quickprefs.gllightpreset[index].direction1
+ bpy.context.user_preferences.system.solid_lights[2].direction=bpy.context.scene.quickprefs.gllightpreset[index].direction2
+
+ bpy.context.user_preferences.system.solid_lights[0].diffuse_color=bpy.context.scene.quickprefs.gllightpreset[index].diffuse0
+ bpy.context.user_preferences.system.solid_lights[1].diffuse_color=bpy.context.scene.quickprefs.gllightpreset[index].diffuse1
+ bpy.context.user_preferences.system.solid_lights[2].diffuse_color=bpy.context.scene.quickprefs.gllightpreset[index].diffuse2
+
+ bpy.context.user_preferences.system.solid_lights[0].specular_color=bpy.context.scene.quickprefs.gllightpreset[index].specular0
+ bpy.context.user_preferences.system.solid_lights[1].specular_color=bpy.context.scene.quickprefs.gllightpreset[index].specular1
+ bpy.context.user_preferences.system.solid_lights[2].specular_color=bpy.context.scene.quickprefs.gllightpreset[index].specular2
+
+#sort alphabetically
+def gllightpreset_sort():
+ collection=bpy.context.scene.quickprefs.gllightpreset
+ count=len(collection)
+ for i in range(0, count):
+ for j in range(i+1, count):
+ if collection[i].name > collection[j].name:
+ collection.move(j, i)
+
+#Add default setting
+def gllightpreset_addDefault():
+ print('adding default presets')
+ gllightpreset_addPresets()
+ gllightpreset_sort();
+ bpy.context.scene.quickprefs['gllightpreset_index']=0
+ gllightpreset_select()
+
+##########################################
+####### Persistant functions##############
+##########################################
+#This function decides where to load presets from - The order goes: BPY>File>Defaults
+#@persistent
+def gllightpreset_chooseLoadLocation(context):
+
+ filepath=bpy.context.scene.quickprefs.gllightpreset_importdirectory
+ if len(bpy.context.scene.quickprefs.gllightpreset)==0: #is it in bpy?
+ if not os.path.exists(filepath): #is it in the folder?
+ print('quickprefs: loading default presets')
+ gllightpreset_addDefault() #it's not, add the default
+ else: #the folder exists
+ directorylisting = os.listdir(filepath)
+ if len(directorylisting)==0: #is the folder empty?
+ print('quickprefs: loading default presets')
+ gllightpreset_addDefault() #the folder is empty, add default
+ else: #the folder is not empty
+ print('quickprefs: loading preset folder')
+ gllightpreset_loadpresets(1) #go ahead and load it
+ #print('quickprefs: loading from bpy')
+
+#This function scans for changes of the index of the selected preset and updates the selection if needed
+ at persistent
+def gllightpreset_scan(context):
+ global lastindex
+ if debug==0:
+ if lastindex!=bpy.context.scene.quickprefs.gllightpreset_index:
+ lastindex=bpy.context.scene.quickprefs.gllightpreset_index
+ gllightpreset_select()
+
+#This function loads all the presets from a given folder (stored in bpy)
+ at persistent
+def gllightpreset_loadpresets(context):
+ gllightpreset_importall()
+ bpy.context.scene['gllightpreset_index']=0
+ gllightpreset_select()
+
+##########################################
+####### GUI ##############################
+##########################################
+
+#This function defines the layout of the openGL lamps
+def opengl_lamp_buttons(column, lamp):
+ split = column.split(percentage=0.1)
+
+ split.prop(lamp, "use", text="", icon='OUTLINER_OB_LAMP' if lamp.use else 'LAMP_DATA')
+
+ col = split.column()
+ col.active = lamp.use
+ row = col.row()
+ row.label(text="Diffuse:")
+ row.prop(lamp, "diffuse_color", text="")
+ row = col.row()
+ row.label(text="Specular:")
+ row.prop(lamp, "specular_color", text="")
+
+ col = split.column()
+ col.active = lamp.use
+ col.prop(lamp, "direction", text="")
+
+class gllightpreset(bpy.types.PropertyGroup):
+
+ props=bpy.props
+ name = props.StringProperty(update=gllightpreset_name)
+
+ illuminated0 = props.BoolProperty(default = True)
+ illuminated1 = props.BoolProperty(default = True)
+ illuminated2 = props.BoolProperty(default = True)
+
+ direction0 = props.FloatVectorProperty(name="", default=(-0.8920, 0.3000, 0.8999))
+ direction1 = props.FloatVectorProperty(name="", default=(0.5880, 0.4600, 0.2480))
+ direction2 = props.FloatVectorProperty(name="", default=(0.2159, -0.3920, -0.2159))
+
+ diffuse0 = props.FloatVectorProperty(name="", default=(0.8000, 0.8000, 0.8000))
+ diffuse1 = props.FloatVectorProperty(name="", default=(0.4980, 0.5000, 0.6000))
+ diffuse2 = props.FloatVectorProperty(name="", default=(0.7980, 0.8379, 1.0))
+
+ specular0 = props.FloatVectorProperty(name="", default=(0.5, 0.5, 0.5))
+ specular1 = props.FloatVectorProperty(name="", default=(0.2000, 0.2000, 0.2000))
+ specular2 = props.FloatVectorProperty(name="", default=(0.0659, 0.0, 0.0))
+
+ count = props.IntProperty(name="", default=0)
+ count2 = props.IntProperty(name="", default=0)
+
+class SCENE_OT_gllightpreset(bpy.types.Operator):
+ bl_label ="Preset Action"
+ bl_idname="gllightpreset.action"
+
+ #alias
+
+
+ button=bpy.props.StringProperty(default="")
+
+ def execute(self, context):
+ scn=bpy.context.scene
+ button=self.button
+
+
+ if button=="add":
+ gllightpreset_add()
+ elif button=="delete":
+ if len(scn.quickprefs.gllightpreset)>1:
+ gllightpreset_delete()
+ else:
+ self.report({'INFO'}, "Must have at least 1 Preset")
+
+ elif button=="save":
+ gllightpreset_save()
+ self.report({'INFO'}, "Saved Preset to Blend File.")
+ elif button=="sort": gllightpreset_sort()
+ elif button=="select": gllightpreset_select()
+ elif button=="export":
+ gllightpreset_exportsingle(scn.quickprefs.gllightpreset_index, False)
+ self.report({'INFO'}, "Exported Preset to: "+scn.quickprefs.gllightpreset_exportfile)
+ elif button=="exportall":
+ gllightpreset_exportall(1)
+ self.report({'INFO'}, "Exported Presets to: "+scn.quickprefs.gllightpreset_exportdirectory)
+ elif button=="import":
+ if not os.path.isdir(scn.quickprefs.gllightpreset_importfile):
+ if not scn.quickprefs.gllightpreset_importdirectory=="":
+ gllightpreset_importsingle(scn.quickprefs.gllightpreset_importfile)
+ else:
+ self.report({'INFO'}, "Please choose a valid preset file")
+ else:
+ self.report({'INFO'}, "Please choose a valid preset file")
+ elif button=="importall":
+ gllightpreset_importall()
+ self.report({'INFO'}, "Imported Presets from: "+scn.quickprefs.gllightpreset_importdirectory)
+ elif button=="defaults":
+ gllightpreset_addDefault()
+
+ if scn.quickprefs.gllightpreset_index > len(scn.quickprefs.gllightpreset)-1:
+ scn.quickprefs.gllightpreset_index = len(scn.quickprefs.gllightpreset)-1
+
+ return {"FINISHED"}
+
+#Panel for tools
+class PANEL(bpy.types.Panel):
+ bl_label = 'Quick Preferences'
+ bl_space_type = 'VIEW_3D'
+ bl_context = "render"
+ bl_region_type = 'UI'
+ bl_options = {'DEFAULT_CLOSED'}
+
+
+ def draw(self, context):
+ global lastname
+
+ #aliases
+ scn = bpy.context.scene.quickprefs
+ system = context.user_preferences.system
+ inputs = context.user_preferences.inputs
+ edit = context.user_preferences.edit
+ layout = self.layout
+ split = layout.split()
+
+#Setup the OpenGL lights box
+#Draw the Lights
+ box = layout.box().column(align=False)
+ box.prop(scn,'gllights')
+ if scn.gllights:
+
+ split = box.split(percentage=0.1)
+ split.label()
+ split.label(text="Colors:")
+ split.label(text="Direction:")
+
+ lamp = system.solid_lights[0]
+ opengl_lamp_buttons(box, lamp)
+
+ lamp = system.solid_lights[1]
+ opengl_lamp_buttons(box, lamp)
+
+ lamp = system.solid_lights[2]
+ opengl_lamp_buttons(box, lamp)
+
+ box.separator()
+
+#Draw the selection box
+ split = box.split(percentage=0.7)
+ col = split.row()
+ #original
+ col.template_list("UI_UL_list", "", scn, "gllightpreset", scn, "gllightpreset_index", rows=5, maxrows=5)
+
+#Draw the buttons
+ split = split.split()
+ col = split.column()
+ col.operator("gllightpreset.action", icon="ZOOMIN", text="Add").button="add"
+ col.operator("gllightpreset.action", icon="ZOOMOUT", text="Delete").button="delete"
+ col.operator("gllightpreset.action", icon="FILE_TICK", text="Save to Blend").button="save"
+ col.operator("gllightpreset.action", icon="SORTALPHA", text="Sort").button="sort"
+ col.operator("gllightpreset.action", icon="SHORTDISPLAY", text="Add Defaults").button="defaults"
+ col=box.row()
+ col=col.column()
+#Draw the text box
+ count=len(scn.gllightpreset)
+ if count>0:
+ entry=scn.gllightpreset[scn.gllightpreset_index]
+ lastname=entry.name
+
+ if entry.count==0:
+ col.prop(entry, "name", text="")
+ if entry.count> 0:
+ col.prop(entry, "name", text="")
+ if bpy.context.scene.objects.active != None:
+ name=bpy.context.scene.objects.active.get("gllightpreset", "Default")
+#Draw the import/export part of the box
+ col.prop(scn,'importexport')
+ if scn.importexport:
+ split = box.split(percentage=0.5)
+ col = split.column()
+ col.label("Import Directory or File")
+ col.prop(scn, 'gllightpreset_importfile')
+ col.prop(scn, 'gllightpreset_importdirectory')
+ col.label("Export Directory or File")
+ col.prop(scn, 'gllightpreset_exportfile')
+ col.prop(scn, 'gllightpreset_exportdirectory')
+
+ split = split.split()
+ col = split.column()
+
+ col.label("")
+ col.operator("gllightpreset.action", icon="IMPORT", text="Import File").button="import"
+ col.operator("gllightpreset.action", icon="IMPORT", text="Import All").button="importall"
+ col.label("")
+ col.operator("gllightpreset.action", icon="EXPORT", text="Export Selection").button="export"
+ col.operator("gllightpreset.action", icon="EXPORT", text="Export All").button="exportall"
+
+
+#The second box containing interface options is here
+ #interface options
+ box = layout.box().column(align=True)
+ box.prop(scn,'interface')
+
+
+ if scn.interface:
+ #Select with
+ boxrow=box.row()
+ boxrow.label(text="Select With:")
+ boxrow=box.row()
+ boxrow.prop(inputs, "select_mouse", expand=True)
+
+ #Orbit
+ boxrow=box.row()
+ boxrow.label(text="Orbit Style:")
+ boxrow=box.row()
+ boxrow.prop(inputs, "view_rotate_method", expand=True)
+
+ #continuous grab
+ boxrow=box.row()
+ boxrow.prop(inputs, "use_mouse_continuous")
+
+ #Color Picker
+ boxrow=box.row()
+ boxrow.label(text="Color Picker Type")
+ boxrow=box.row()
+ boxrow.row().prop(system, "color_picker_type", text="")
+
+ #Align To
+ boxrow=box.row()
+ boxrow.label(text="Align New Objects To:")
+ boxrow=box.row()
+ boxrow.prop(edit, "object_align", text="")
+
+##########################################
+####### Registration Functions ############
+##########################################
+class quickprefproperties(bpy.types.PropertyGroup):
+ @classmethod
+ def register(cls):
+ bpy.types.Scene.quickprefs = PointerProperty(
+ name="QuickPrefs Settings",
+ description="QuickPrefs render settings",
+ type=cls,
+ )
+ #strings for file IO
+ cls.gllightpreset_importfile = StringProperty(name = "",
+ subtype='FILE_PATH',
+ default=defaultfilepath
+ )
+
+ cls.gllightpreset_importdirectory = StringProperty(name = "",
+ subtype='FILE_PATH',
+ default=defaultfilepath
+ )
+
+ cls.gllightpreset_exportfile = StringProperty(name = "",
+ subtype='FILE_PATH',
+ default=defaultfilepath
+ )
+
+ cls.gllightpreset_exportdirectory = StringProperty(
+ name = "",
+ subtype='FILE_PATH',
+ default=defaultfilepath
+ )
+
+ cls.gllights = BoolProperty(
+ name='Lights',
+ default=True
+ )
+
+ cls.gllightPresets = BoolProperty(
+ name='GL Light Presets',
+ default=True
+ )
+
+ cls.interface = BoolProperty(
+ name='Interface',
+ default=True
+ )
+
+ cls.importexport = BoolProperty(
+ name='Import/Export',
+ default=True
+ )
+
+ cls.gllights = BoolProperty(
+ name='Lights',
+ default=True
+ )
+
+ #important storage of stuff
+ cls.gllightpreset = CollectionProperty(
+ type=gllightpreset
+ )
+
+ cls.gllightpreset_index = IntProperty(
+ min=0,
+ default=0,
+ update=gllightpreset_index
+ )
+
+ @classmethod
+ def unregister(cls):
+ del bpy.types.Scene.quickprefs
+
+ at persistent
+def setup(s):
+ #let the fun begin!
+ gllightpreset_chooseLoadLocation(1)
+ gllightpreset_scan(bpy.context)
+
+def register():
+ #aliases
+ handler=bpy.app.handlers
+
+ #register classes
+ bpy.utils.register_class(PANEL)
+ bpy.utils.register_class(gllightpreset)
+ bpy.utils.register_class(SCENE_OT_gllightpreset)
+ bpy.utils.register_class(quickprefproperties)
+
+ #handler.scene_update_pre.append(gllightpreset_scan)
+ handler.scene_update_pre.append(setup)
+ #handler.load_post.append(setup) #was crashing blender on new file load - comment for now
+
+
+
+
+# unregistering and removing menus
+def unregister():
+ bpy.utils.unregister_class(PANEL)
+ bpy.utils.unregister_class(gllightpreset)
+ bpy.utils.unregister_class(SCENE_OT_gllightpreset)
+ bpy.utils.unregister_class(quickprefproperties)
+
+
+if __name__ == "__main__":
+ register()
+
diff --git a/release/scripts/addons_contrib/space_view3d_simple_align.py b/release/scripts/addons_contrib/space_view3d_simple_align.py
new file mode 100644
index 0000000..e270053
--- /dev/null
+++ b/release/scripts/addons_contrib/space_view3d_simple_align.py
@@ -0,0 +1,341 @@
+# AlingTools.py (c) 2009, 2010 Gabriel Beaudin (gabhead)
+#
+# ***** 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 *****
+
+bl_info = {
+ "name": "Simple Align",
+ "author": "Gabriel Beaudin (gabhead)",
+ "version": (0,1),
+ "blender": (2, 61, 0),
+ "location": "View3D > Tool Shelf > Simple Align Panel",
+ "description": "Align Selected Objects to Active Object",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/3D interaction/Align_Tools",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=22389",
+ "category": "3D View"}
+
+"""Align Selected Objects"""
+
+import bpy
+
+
+class AlignUi(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Simple Align"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ obj = context.object
+
+ if obj != None:
+ row = layout.row()
+ row.label(text="Active object is: ", icon='OBJECT_DATA')
+ row = layout.row()
+ row.label(obj.name, icon='EDITMODE_HLT')
+
+ layout.separator()
+
+ col = layout.column()
+ col.label(text="Align Loc + Rot:", icon='MANIPUL')
+
+
+ col = layout.column(align=False)
+ col.operator("object.align",text="XYZ")
+
+ col = layout.column()
+ col.label(text="Align Location:", icon='MAN_TRANS')
+
+ col = layout.column_flow(columns=5,align=True)
+ col.operator("object.align_location_x",text="X")
+ col.operator("object.align_location_y",text="Y")
+ col.operator("object.align_location_z",text="Z")
+ col.operator("object.align_location_all",text="All")
+
+ col = layout.column()
+ col.label(text="Align Rotation:", icon='MAN_ROT')
+
+ col = layout.column_flow(columns=5,align=True)
+ col.operator("object.align_rotation_x",text="X")
+ col.operator("object.align_rotation_y",text="Y")
+ col.operator("object.align_rotation_z",text="Z")
+ col.operator("object.align_rotation_all",text="All")
+
+ col = layout.column()
+ col.label(text="Align Scale:", icon='MAN_SCALE')
+
+ col = layout.column_flow(columns=5,align=True)
+ col.operator("object.align_objects_scale_x",text="X")
+ col.operator("object.align_objects_scale_y",text="Y")
+ col.operator("object.align_objects_scale_z",text="Z")
+ col.operator("object.align_objects_scale_all",text="All")
+
+
+##Align all
+def main(context):
+ for i in bpy.context.selected_objects:
+ i.location = bpy.context.active_object.location
+ i.rotation_euler = bpy.context.active_object.rotation_euler
+
+## Align Location
+
+def LocAll(context):
+ for i in bpy.context.selected_objects:
+ i.location = bpy.context.active_object.location
+
+def LocX(context):
+ for i in bpy.context.selected_objects:
+ i.location.x = bpy.context.active_object.location.x
+
+def LocY(context):
+ for i in bpy.context.selected_objects:
+ i.location.y = bpy.context.active_object.location.y
+
+def LocZ(context):
+ for i in bpy.context.selected_objects:
+ i.location.z = bpy.context.active_object.location.z
+
+## Aling Rotation
+def RotAll(context):
+ for i in bpy.context.selected_objects:
+ i.rotation_euler = bpy.context.active_object.rotation_euler
+
+def RotX(context):
+ for i in bpy.context.selected_objects:
+ i.rotation_euler.x = bpy.context.active_object.rotation_euler.x
+
+def RotY(context):
+ for i in bpy.context.selected_objects:
+ i.rotation_euler.y = bpy.context.active_object.rotation_euler.y
+
+def RotZ(context):
+ for i in bpy.context.selected_objects:
+ i.rotation_euler.z = bpy.context.active_object.rotation_euler.z
+## Aling Scale
+def ScaleAll(context):
+ for i in bpy.context.selected_objects:
+ i.scale = bpy.context.active_object.scale
+
+def ScaleX(context):
+ for i in bpy.context.selected_objects:
+ i.scale.x = bpy.context.active_object.scale.x
+
+def ScaleY(context):
+ for i in bpy.context.selected_objects:
+ i.scale.y = bpy.context.active_object.scale.y
+
+def ScaleZ(context):
+ for i in bpy.context.selected_objects:
+ i.scale.z = bpy.context.active_object.scale.z
+
+## Classes
+
+## Align All Rotation And Location
+class AlignOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align"
+ bl_label = "Align Selected To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ main(context)
+ return {'FINISHED'}
+
+#######################Align Location########################
+## Align LocationAll
+class AlignLocationOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_location_all"
+ bl_label = "Align Selected Location To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ LocAll(context)
+ return {'FINISHED'}
+## Align LocationX
+class AlignLocationXOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_location_x"
+ bl_label = "Align Selected Location X To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ LocX(context)
+ return {'FINISHED'}
+## Align LocationY
+class AlignLocationYOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_location_y"
+ bl_label = "Align Selected Location Y To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ LocY(context)
+ return {'FINISHED'}
+## Align LocationZ
+class AlignLocationZOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_location_z"
+ bl_label = "Align Selected Location Z To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ LocZ(context)
+ return {'FINISHED'}
+
+#######################Align Rotation########################
+## Align RotationAll
+class AlignRotationOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_rotation_all"
+ bl_label = "Align Selected Rotation To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ RotAll(context)
+ return {'FINISHED'}
+## Align RotationX
+class AlignRotationXOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_rotation_x"
+ bl_label = "Align Selected Rotation X To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ RotX(context)
+ return {'FINISHED'}
+## Align RotationY
+class AlignRotationYOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_rotation_y"
+ bl_label = "Align Selected Rotation Y To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ RotY(context)
+ return {'FINISHED'}
+## Align RotationZ
+class AlignRotationZOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_rotation_z"
+ bl_label = "Align Selected Rotation Z To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ RotZ(context)
+ return {'FINISHED'}
+#######################Align Scale########################
+## Scale All
+class AlignScaleOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_objects_scale_all"
+ bl_label = "Align Selected Scale To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ ScaleAll(context)
+ return {'FINISHED'}
+## Align ScaleX
+class AlignScaleXOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_objects_scale_x"
+ bl_label = "Align Selected Scale X To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ ScaleX(context)
+ return {'FINISHED'}
+## Align ScaleY
+class AlignScaleYOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_objects_scale_y"
+ bl_label = "Align Selected Scale Y To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ ScaleY(context)
+ return {'FINISHED'}
+## Align ScaleZ
+class AlignScaleZOperator(bpy.types.Operator):
+ """"""
+ bl_idname = "object.align_objects_scale_z"
+ bl_label = "Align Selected Scale Z To Active"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+ ScaleZ(context)
+ return {'FINISHED'}
+
+## registring
+def register():
+ bpy.utils.register_module(__name__)
+
+ pass
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ pass
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/system_cycles_material_text_node.py b/release/scripts/addons_contrib/system_cycles_material_text_node.py
new file mode 100644
index 0000000..68c6032
--- /dev/null
+++ b/release/scripts/addons_contrib/system_cycles_material_text_node.py
@@ -0,0 +1,608 @@
+# system_cycles_material_text_node.py Copyright (C) 5-mar-2012, Silvio Falcinelli
+#
+#
+# special thanks to user blenderartists.org cmomoney
+#
+#
+# Show Information About the Blend.
+# ***** 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 *****
+
+bl_info = {
+ "name": "Cycles Auto Material Texures Node Editor",
+ "author": "Silvio Falcinelli",
+ "version": (0,5),
+ "blender": (2, 62, 0),
+ "api": 44136,
+ "location": "Properties > Material > Automatic Node Editor ",
+ "description": "automatic cycles texture map",
+ "warning": "beta",
+ "wiki_url": 'http://www.rendering3d.net/' \
+ 'scripts/materialedior',
+ "tracker_url": "https://projects.blender.org/tracker/index.php?" \
+ "func=detail&aid=????",
+ "category": "System"}
+
+
+import bpy
+import math
+from math import log
+from math import pow
+from math import exp
+import os.path
+
+
+
+def AutoNodeOff():
+ mats = bpy.data.materials
+ for cmat in mats:
+ cmat.use_nodes=False
+ bpy.context.scene.render.engine='BLENDER_RENDER'
+
+
+def BakingText(tex,mode):
+ print('________________________________________')
+ print('INFO start bake texture ' + tex.name)
+ bpy.ops.object.mode_set(mode='OBJECT')
+ sc=bpy.context.scene
+ tmat=''
+ img=''
+ Robj=bpy.context.active_object
+ for n in bpy.data.materials:
+
+ if n.name=='TMP_BAKING':
+ tmat=n
+
+ if not tmat:
+ tmat = bpy.data.materials.new('TMP_BAKING')
+ tmat.name="TMP_BAKING"
+
+
+ bpy.ops.mesh.primitive_plane_add()
+ tm=bpy.context.active_object
+ tm.name="TMP_BAKING"
+ tm.data.name="TMP_BAKING"
+ bpy.ops.object.select_pattern(extend=False, pattern="TMP_BAKING", case_sensitive=False)
+ sc.objects.active = tm
+ bpy.context.scene.render.engine='BLENDER_RENDER'
+ tm.data.materials.append(tmat)
+ if len(tmat.texture_slots.items()) == 0:
+ tmat.texture_slots.add()
+ tmat.texture_slots[0].texture_coords='UV'
+ tmat.texture_slots[0].use_map_alpha=True
+ tmat.texture_slots[0].texture = tex.texture
+ tmat.texture_slots[0].use_map_alpha=True
+ tmat.texture_slots[0].use_map_color_diffuse=False
+ tmat.use_transparency=True
+ tmat.alpha=0
+ tmat.use_nodes=False
+ tmat.diffuse_color=1,1,1
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.uv.unwrap()
+
+ for n in bpy.data.images:
+ if n.name=='TMP_BAKING':
+ n.user_clear()
+ bpy.data.images.remove(n)
+
+
+ if mode == "ALPHA" and tex.texture.type=='IMAGE':
+ sizeX=tex.texture.image.size[0]
+ sizeY=tex.texture.image.size[1]
+ else:
+ sizeX=600
+ sizeY=600
+ bpy.ops.image.new(name="TMP_BAKING", width=sizeX, height=sizeY, color=(0.0, 0.0, 0.0, 1.0), alpha=True, uv_test_grid=False, float=False)
+ bpy.data.screens['UV Editing'].areas[1].spaces[0].image = bpy.data.images["TMP_BAKING"]
+ sc.render.engine='BLENDER_RENDER'
+ img = bpy.data.images["TMP_BAKING"]
+ img=bpy.data.images.get("TMP_BAKING")
+ img.file_format = "JPEG"
+ if mode == "ALPHA" and tex.texture.type=='IMAGE':
+ img.filepath_raw = tex.texture.image.filepath + "_BAKING.jpg"
+
+ else:
+ img.filepath_raw = tex.texture.name + "_PTEXT.jpg"
+
+ sc.render.bake_type = 'ALPHA'
+ sc.render.use_bake_selected_to_active = True
+ sc.render.use_bake_clear = True
+ bpy.ops.object.bake_image()
+ img.save()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.delete()
+ bpy.ops.object.select_pattern(extend=False, pattern=Robj.name, case_sensitive=False)
+ sc.objects.active = Robj
+ img.user_clear()
+ bpy.data.images.remove(img)
+ bpy.data.materials.remove(tmat)
+
+ print('INFO : end Bake ' + img.filepath_raw )
+ print('________________________________________')
+
+def AutoNode():
+
+ mats = bpy.data.materials
+ sc = bpy.context.scene
+
+ for cmat in mats:
+
+ cmat.use_nodes=True
+ TreeNodes=cmat.node_tree
+ links = TreeNodes.links
+
+ shader=''
+ shmix=''
+ shtsl=''
+ Add_Emission=''
+ Add_Translucent=''
+ Mix_Alpha=''
+ sT=False
+ lock=True
+
+ for n in TreeNodes.nodes:
+ if n.type == 'OUTPUT_MATERIAL':
+ if n.label == 'Lock':
+ lock=False
+
+
+ if lock:
+ for n in TreeNodes.nodes:
+ TreeNodes.nodes.remove(n)
+
+
+
+ if not shader :
+ shader = TreeNodes.nodes.new('BSDF_DIFFUSE')
+ shader.location = 0,470
+
+ shout = TreeNodes.nodes.new('OUTPUT_MATERIAL')
+ shout.location = 200,400
+ links.new(shader.outputs[0],shout.inputs[0])
+
+ textures = cmat.texture_slots
+ sM=True
+
+ for tex in textures:
+ if tex:
+ if tex.use:
+ if tex.use_map_alpha:
+ sM=False
+
+ if sc.EXTRACT_ALPHA:
+
+ if tex.texture.type =='IMAGE' and tex.texture.use_alpha:
+
+ if not os.path.exists(bpy.path.abspath(tex.texture.image.filepath + "_BAKING.jpg")) or sc.EXTRACT_OW:
+
+ BakingText(tex,'ALPHA')
+ else:
+ if not tex.texture.type =='IMAGE':
+
+ if not os.path.exists(bpy.path.abspath(tex.texture.name + "_PTEXT.jpg")) or sc.EXTRACT_OW:
+
+ BakingText(tex,'PTEXT')
+
+
+
+
+
+
+ if cmat.use_transparency and cmat.raytrace_transparency.ior == 1 and not cmat.raytrace_mirror.use and sM:
+ if not shader.type == 'BSDF_TRANSPARENT':
+ print("INFO: Make TRANSPARENT shader node " + cmat.name)
+ TreeNodes.nodes.remove(shader)
+ shader = TreeNodes.nodes.new('BSDF_TRANSPARENT')
+ shader.location = 0,470
+ links.new(shader.outputs[0],shout.inputs[0])
+
+
+
+ if not cmat.raytrace_mirror.use and not cmat.use_transparency:
+ if not shader.type == 'BSDF_DIFFUSE':
+ print("INFO: Make DIFFUSE shader node" + cmat.name)
+ TreeNodes.nodes.remove(shader)
+ shader = TreeNodes.nodes.new('BSDF_DIFFUSE')
+ shader.location = 0,470
+ links.new(shader.outputs[0],shout.inputs[0])
+
+
+
+ if cmat.raytrace_mirror.use and cmat.raytrace_mirror.reflect_factor>0.001 and cmat.use_transparency:
+ if not shader.type == 'BSDF_GLASS':
+ print("INFO: Make GLASS shader node" + cmat.name)
+ TreeNodes.nodes.remove(shader)
+ shader = TreeNodes.nodes.new('BSDF_GLASS')
+ shader.location = 0,470
+ links.new(shader.outputs[0],shout.inputs[0])
+
+
+
+
+ if cmat.raytrace_mirror.use and not cmat.use_transparency and cmat.raytrace_mirror.reflect_factor>0.001 :
+ if not shader.type == 'BSDF_GLOSSY':
+ print("INFO: Make MIRROR shader node" + cmat.name)
+ TreeNodes.nodes.remove(shader)
+ shader = TreeNodes.nodes.new('BSDF_GLOSSY')
+ shader.location = 0,520
+ links.new(shader.outputs[0],shout.inputs[0])
+
+
+
+ if cmat.emit > 0.001 :
+ if not shader.type == 'EMISSION' and not cmat.raytrace_mirror.reflect_factor>0.001 and not cmat.use_transparency:
+ print("INFO: Mix EMISSION shader node" + cmat.name)
+ TreeNodes.nodes.remove(shader)
+ shader = TreeNodes.nodes.new('EMISSION')
+ shader.location = 0,450
+ links.new(shader.outputs[0],shout.inputs[0])
+
+ else:
+ if not Add_Emission:
+ print("INFO: Add EMISSION shader node" + cmat.name)
+ shout.location = 550,330
+ Add_Emission = TreeNodes.nodes.new('ADD_SHADER')
+ Add_Emission.location = 370,490
+
+ shem = TreeNodes.nodes.new('EMISSION')
+ shem.location = 180,380
+
+ links.new(Add_Emission.outputs[0],shout.inputs[0])
+ links.new(shem.outputs[0],Add_Emission.inputs[1])
+ links.new(shader.outputs[0],Add_Emission.inputs[0])
+
+ shem.inputs['Color'].default_value=cmat.diffuse_color.r,cmat.diffuse_color.g,cmat.diffuse_color.b,1
+ shem.inputs['Strength'].default_value=cmat.emit
+
+
+
+
+ if cmat.translucency > 0.001 :
+ print("INFO: Add BSDF_TRANSLUCENT shader node" + cmat.name)
+ shout.location = 770,330
+ Add_Translucent = TreeNodes.nodes.new('ADD_SHADER')
+ Add_Translucent.location = 580,490
+
+ shtsl = TreeNodes.nodes.new('BSDF_TRANSLUCENT')
+ shtsl.location = 400,350
+
+ links.new(Add_Translucent.outputs[0],shout.inputs[0])
+ links.new(shtsl.outputs[0],Add_Translucent.inputs[1])
+
+
+ if Add_Emission:
+ links.new(Add_Emission.outputs[0],Add_Translucent.inputs[0])
+
+ pass
+ else:
+
+ links.new(shader.outputs[0],Add_Translucent.inputs[0])
+ pass
+ shtsl.inputs['Color'].default_value=cmat.translucency, cmat.translucency,cmat.translucency,1
+
+
+
+
+ shader.inputs['Color'].default_value=cmat.diffuse_color.r,cmat.diffuse_color.g,cmat.diffuse_color.b,1
+
+ if shader.type=='BSDF_DIFFUSE':
+ shader.inputs['Roughness'].default_value=cmat.specular_intensity
+
+ if shader.type=='BSDF_GLOSSY':
+ shader.inputs['Roughness'].default_value=1-cmat.raytrace_mirror.gloss_factor
+
+
+ if shader.type=='BSDF_GLASS':
+ shader.inputs['Roughness'].default_value=1-cmat.raytrace_mirror.gloss_factor
+ shader.inputs['IOR'].default_value=cmat.raytrace_transparency.ior
+
+
+ if shader.type=='EMISSION':
+ shader.inputs['Strength'].default_value=cmat.emit
+
+
+
+ textures = cmat.texture_slots
+ for tex in textures:
+ sT=False
+ pText=''
+ if tex:
+ if tex.use:
+ if tex.texture.type=='IMAGE':
+ img = tex.texture.image
+ shtext = TreeNodes.nodes.new('TEX_IMAGE')
+ shtext.location = -200,400
+ shtext.image=img
+ sT=True
+
+
+
+
+
+ if not tex.texture.type=='IMAGE':
+ if sc.EXTRACT_PTEX:
+ print('INFO : Extract Procedural Texture ' )
+
+ if not os.path.exists(bpy.path.abspath(tex.texture.name + "_PTEXT.jpg")) or sc.EXTRACT_OW:
+ BakingText(tex,'PTEX')
+
+ img=bpy.data.images.load(tex.texture.name + "_PTEXT.jpg")
+ shtext = TreeNodes.nodes.new('TEX_IMAGE')
+ shtext.location = -200,400
+ shtext.image=img
+ sT=True
+
+
+ if sT:
+ if tex.use_map_color_diffuse :
+ links.new(shtext.outputs[0],shader.inputs[0])
+
+
+ if tex.use_map_emit:
+ if not Add_Emission:
+ print("INFO: Mix EMISSION + Texure shader node " + cmat.name)
+
+ intensity=0.5+(tex.emit_factor / 2)
+
+ shout.location = 550,330
+ Add_Emission = TreeNodes.nodes.new('ADD_SHADER')
+ Add_Emission.name="Add_Emission"
+ Add_Emission.location = 370,490
+
+ shem = TreeNodes.nodes.new('EMISSION')
+ shem.location = 180,380
+
+ links.new(Add_Emission.outputs[0],shout.inputs[0])
+ links.new(shem.outputs[0],Add_Emission.inputs[1])
+ links.new(shader.outputs[0],Add_Emission.inputs[0])
+
+ shem.inputs['Color'].default_value=cmat.diffuse_color.r,cmat.diffuse_color.g,cmat.diffuse_color.b,1
+ shem.inputs['Strength'].default_value=intensity * 2
+
+ links.new(shtext.outputs[0],shem.inputs[0])
+
+
+ if tex.use_map_mirror:
+ links.new(shader.inputs[0],shtext.outputs[0])
+
+
+ if tex.use_map_translucency:
+ if not Add_Translucent:
+ print("INFO: Add Translucency + Texure shader node " + cmat.name)
+
+ intensity=0.5+(tex.emit_factor / 2)
+
+ shout.location = 550,330
+ Add_Translucent = TreeNodes.nodes.new('ADD_SHADER')
+ Add_Translucent.name="Add_Translucent"
+ Add_Translucent.location = 370,290
+
+ shtsl = TreeNodes.nodes.new('BSDF_TRANSLUCENT')
+ shtsl.location = 180,240
+
+ links.new(shtsl.outputs[0],Add_Translucent.inputs[1])
+
+ if Add_Emission:
+ links.new(Add_Translucent.outputs[0],shout.inputs[0])
+ links.new(Add_Emission.outputs[0],Add_Translucent.inputs[0])
+ pass
+ else:
+ links.new(Add_Translucent.outputs[0],shout.inputs[0])
+ links.new(shader.outputs[0],Add_Translucent.inputs[0])
+
+ links.new(shtext.outputs[0],shtsl.inputs[0])
+
+
+ if tex.use_map_alpha:
+ if not Mix_Alpha:
+ print("INFO: Mix Alpha + Texure shader node " + cmat.name)
+
+ shout.location = 750,330
+ Mix_Alpha = TreeNodes.nodes.new('MIX_SHADER')
+ Mix_Alpha.name="Add_Alpha"
+ Mix_Alpha.location = 570,290
+ sMask = TreeNodes.nodes.new('BSDF_TRANSPARENT')
+ sMask.location = 250,180
+ tMask = TreeNodes.nodes.new('TEX_IMAGE')
+ tMask.location = -200,250
+
+ if tex.texture.type=='IMAGE':
+ if tex.texture.use_alpha:
+ imask=bpy.data.images.load(img.filepath+"_BAKING.jpg")
+ else:
+ imask=bpy.data.images.load(img.filepath)
+ else:
+ imask=bpy.data.images.load(img.name)
+
+
+ tMask.image = imask
+ links.new(Mix_Alpha.inputs[0],tMask.outputs[0])
+ links.new(shout.inputs[0],Mix_Alpha.outputs[0])
+ links.new(sMask.outputs[0],Mix_Alpha.inputs[1])
+
+ if not Add_Emission and not Add_Translucent:
+ links.new(Mix_Alpha.inputs[2],shader.outputs[0])
+
+ if Add_Emission and not Add_Translucent:
+ links.new(Mix_Alpha.inputs[2],Add_Emission.outputs[0])
+
+ if Add_Translucent:
+ links.new(Mix_Alpha.inputs[2],Add_Translucent.outputs[0])
+
+
+
+ if tex.use_map_normal:
+ t = TreeNodes.nodes.new('RGBTOBW')
+ t.location = -0,300
+ links.new(t.outputs[0],shout.inputs[2])
+ links.new(shtext.outputs[0],t.inputs[0])
+ bpy.context.scene.render.engine='CYCLES'
+
+
+class mllock(bpy.types.Operator):
+ bl_idname = "ml.lock"
+ bl_label = "Lock"
+ bl_description = "Safe to overwrite of mssive BL conversion"
+ bl_register = True
+ bl_undo = True
+ @classmethod
+ def poll(cls, context):
+ return True
+ def execute(self, context):
+ cmat=bpy.context.selected_objects[0].active_material
+ TreeNodes=cmat.node_tree
+ links = TreeNodes.links
+ for n in TreeNodes.nodes:
+ if n.type == 'OUTPUT_MATERIAL':
+ if n.label == 'Lock':
+ n.label=''
+ else:
+ n.label='Lock'
+
+
+
+
+ return {'FINISHED'}
+
+
+class mlrefresh(bpy.types.Operator):
+ bl_idname = "ml.refresh"
+ bl_label = "Refresh"
+ bl_description = "Refresh"
+ bl_register = True
+ bl_undo = True
+ @classmethod
+ def poll(cls, context):
+ return True
+ def execute(self, context):
+ AutoNode()
+ return {'FINISHED'}
+
+
+class mlrestore(bpy.types.Operator):
+ bl_idname = "ml.restore"
+ bl_label = "Restore"
+ bl_description = "Restore"
+ bl_register = True
+ bl_undo = True
+ @classmethod
+ def poll(cls, context):
+ return True
+ def execute(self, context):
+ AutoNodeOff()
+ return {'FINISHED'}
+
+from bpy.props import *
+sc = bpy.types.Scene
+sc.EXTRACT_ALPHA= BoolProperty(attr="EXTRACT_ALPHA",default= False)
+sc.EXTRACT_PTEX= BoolProperty(attr="EXTRACT_PTEX",default= False)
+sc.EXTRACT_OW= BoolProperty(attr="Overwrite",default= False)
+
+class OBJECT_PT_scenemassive(bpy.types.Panel):
+ bl_label = "Automatic Massive Material Nodes"
+ bl_space_type = "PROPERTIES"
+ bl_region_type = "WINDOW"
+ bl_context = "material"
+
+
+ def draw(self, context):
+ sc = context.scene
+ t=''
+ lock=''
+ try:
+ cmat=bpy.context.selected_objects[0].active_material
+ t="Material : " + cmat.name
+
+
+ TreeNodes=cmat.node_tree
+ links = TreeNodes.links
+
+
+ lock=False
+
+ for n in TreeNodes.nodes:
+ if n.type == 'OUTPUT_MATERIAL':
+ if n.label == 'Lock':
+ lock=True
+
+
+ except:
+ pass
+
+ ob_cols = []
+ db_cols = []
+ layout = self.layout
+ row = layout.row()
+ row.prop(sc,"EXTRACT_ALPHA",text='Extract Alpha Texture (slow)',icon='FORCE_TEXTURE')
+ row = layout.row()
+ row.prop(sc,"EXTRACT_PTEX",text='Extract Procedural Texture (slow)',icon='FORCE_TEXTURE')
+ row = layout.row()
+ row.prop(sc,"EXTRACT_OW",text='Extract Texture Overwrite')
+ row = layout.row()
+ row = layout.row()
+ l_row = layout.row()
+ ob_cols.append(l_row.column())
+ layout.separator()
+ row = ob_cols[0].row()
+ row.operator("ml.refresh", text='BLENDER > CYCLES', icon='TEXTURE')
+ layout.separator()
+ row = ob_cols[0].row()
+ row.operator("ml.restore", text='BLENDER Mode (Node Off)', icon='MATERIAL')
+ layout.separator()
+ row = ob_cols[0].row()
+ layout.separator()
+ layout.separator()
+ row = ob_cols[0].row()
+ layout.separator()
+ row = ob_cols[0].row()
+
+
+
+ if t:
+ row.label(text=t)
+ row.label(text='', icon='MATERIAL')
+ if lock:
+ row.operator("ml.lock", text="Lock" )
+ else:
+ row.operator("ml.lock", text="UnLock" )
+
+ layout.separator()
+ row = ob_cols[0].row()
+ layout.separator()
+ row = ob_cols[0].row()
+ layout.separator()
+ row = ob_cols[0].row()
+ row.label(text="Ver 0,4 beta blender 2.62 - 2.63 Silvio Falcinelli")
+ layout.separator()
+ row = ob_cols[0].row()
+ row.label(text="wwww.rendering3d.net")
+
+
+
+def register():
+ bpy.utils.register_module(__name__)
+ pass
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ pass
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/addons_contrib/system_keyboard_svg.py b/release/scripts/addons_contrib/system_keyboard_svg.py
new file mode 100644
index 0000000..83c08d0
--- /dev/null
+++ b/release/scripts/addons_contrib/system_keyboard_svg.py
@@ -0,0 +1,273 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# this script creates Keyboard layout images of the current keyboard configuration.
+# the result will be writen to the blender default directory.
+
+# first implementation done by jbakker
+
+bl_info = {
+ "name": "Keyboard Layout (svg)",
+ "author": "Jbakker",
+ "version": (0, 1),
+ "blender": (2, 60, 0),
+ "location": "",
+ "description": "Save the hotkeys as a .svg file (search: Keyboard)",
+ "warning": "may not work in recent svn",
+ "wiki_url": 'http://wiki.blender.org/index.php/Extensions:2.6/Py/' \
+ 'Scripts/System/keymaps_to_svg',
+ "tracker_url": "https://projects.blender.org/tracker/index.php?" \
+ "func==detail&aid=21490",
+ "category": "System"}
+
+import bpy
+
+keyboard = (
+ ('`', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 'ZERO', 'MINUS', 'EQUAL', 'BACKSPACE'),
+ ('TAB', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '(', ')', '\\'),
+ ('CAPSLOCK', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'", 'ENTER'),
+ ('SHIFT', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 'SHIFT'),
+ ('CONTROL', 'OSKEY', 'ALT', 'SPACE', 'ALT', 'OSKEY', 'MENUKEY', 'CONTROL')
+ )
+
+# default dimension of a single key [width, heidgh]
+DEFAULT_KEY_DIMENSION = 100, 100
+# alternative dimensions of specufic keys [keyname,[width, height]]
+ALTERNATIVE_KEY_DIMENSIONS = {
+ 'BACKSPACE': (250, 100),
+ 'TAB': (175, 100),
+ '\\': (175, 100),
+ 'CAPSLOCK': (225, 100),
+ 'ENTER': (240, 100),
+ 'SHIFT': (290, 100),
+ 'CONTROL': (225, 100),
+ 'ALT': (100, 100),
+ 'OSKEY': (100, 100),
+ 'MENUKEY': (100, 100),
+ 'SPACE': (690, 100),
+}
+
+
+def createKeyboard(viewtype):
+ """
+ Creates a keyboard layout (.svg) file of the current configuration for a specific viewtype.
+ example of a viewtype is "VIEW_3D".
+ """
+ for keyconfig in bpy.data.window_managers[0].keyconfigs:
+ kc_map = {}
+ for keymap in keyconfig.keymaps:
+ if keymap.space_type == viewtype:
+ for key in keymap.keymap_items:
+ if key.map_type == 'KEYBOARD':
+ test = 0
+ pre = []
+ cont = ""
+ if key.ctrl:
+ test = test + 1
+ cont = "C"
+ if key.alt:
+ test = test + 2
+ cont = cont + "A"
+ if key.shift:
+ test = test + 4
+ cont = cont + "S"
+ if key.oskey:
+ test = test + 8
+ cont = cont + "O"
+ if len(cont) > 0:
+ cont = "[" + cont + "] "
+ ktype = key.type
+ if ktype not in kc_map:
+ kc_map[ktype] = []
+ kc_map[ktype].append((test, cont + key.name))
+
+ filename = "keyboard_%s.svg" % viewtype
+ print(filename)
+ svgfile = open(filename, "w")
+ svgfile.write("""<?xml version="1.0" standalone="no"?>
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+ """)
+ svgfile.write("""<svg width="2000" height="800" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ """)
+ svgfile.write("""<style>
+ rect {
+ fill:rgb(192,192,192);
+ stroke-width:1;
+ stroke:rgb(0,0,0);
+ }
+ text.header {
+ font-size:xx-large;
+ }
+ text.key {
+ stroke-width:1;
+ stroke:rgb(0,0,0);
+ }
+ text.action {
+ font-size:smaller;
+ }
+ text.add0 {
+ font-size:smaller;
+ fill:rgb(0,0,0)
+ }
+ text.add1 {
+ font-size:smaller;
+ fill:rgb(255,0,0)
+ }
+ text.add2 {
+ font-size:smaller;
+ fill:rgb(0,255,0)
+ }
+ text.add3 {
+ font-size:smaller;
+ fill:rgb(128,128,0)
+ }
+ text.add4 {
+ font-size:smaller;
+ fill:rgb(0,0,255)
+ }
+ text.add5 {
+ font-size:smaller;
+ fill:rgb(128,0,128)
+ }
+ text.add6 {
+ font-size:smaller;
+ fill:rgb(0, 128, 128)
+ }
+ text.add7 {
+ font-size:smaller;
+ fill:rgb(128,128,128)
+ }
+ text.add8 {
+ font-size:smaller;
+ fill:rgb(128,128,128)
+ }
+ text.add9 {
+ font-size:smaller;
+ fill:rgb(255,128,128)
+ }
+ text.add10 {
+ font-size:smaller;
+ fill:rgb(128,255,128)
+ }
+ text.add11 {
+ font-size:smaller;
+ fill:rgb(255,255,128)
+ }
+ text.add12 {
+ font-size:smaller;
+ fill:rgb(128,128,255)
+ }
+ text.add13 {
+ font-size:smaller;
+ fill:rgb(255,128,255)
+ }
+ text.add14 {
+ font-size:smaller;
+ fill:rgb(128,255,255)
+ }
+ text.add15 {
+ font-size:smaller;
+ fill:rgb(255,255,128)
+ }
+ </style>
+ """)
+ svgfile.write("""<text class="header" x="100" y="24">keyboard layout - """ + viewtype + """</text>
+""")
+
+ x = 0
+ xgap = 15
+ ygap = 15
+ y = 32
+ for row in keyboard:
+ x = 0
+ for key in row:
+ width, height = ALTERNATIVE_KEY_DIMENSIONS.get(key, DEFAULT_KEY_DIMENSION)
+ tx = 16
+ ty = 16
+ svgfile.write("""<rect x=\"""" + str(x) +
+ """\" y=\"""" + str(y) +
+ """\" width=\"""" + str(width) +
+ """\" height=\"""" + str(height) +
+ """\" rx="20" ry="20" />
+ """)
+ svgfile.write("""<text class="key" x=\"""" + str(x + tx) +
+ """\" y=\"""" + str(y + ty) +
+ """\" width=\"""" + str(width) +
+ """\" height=\"""" + str(height) + """\">
+ """)
+ svgfile.write(key)
+ svgfile.write("</text>")
+ ty = ty + 16
+ tx = 4
+ if key in kc_map:
+ for a in kc_map[key]:
+ svgfile.write("""<text class="add""" + str(a[0]) +
+ """" x=\"""" + str(x + tx) +
+ """\" y=\"""" + str(y + ty) +
+ """\" width=\"""" + str(width) +
+ """\" height=\"""" + str(height) + """\">
+ """)
+ svgfile.write(a[1])
+ svgfile.write("</text>")
+ ty = ty + 16
+ x = x + width + xgap
+ y = y + 100 + ygap
+ svgfile.write("""</svg>""")
+ svgfile.flush()
+ svgfile.close()
+
+
+class WM_OT_Keyboardlayout(bpy.types.Operator):
+ """
+ Windows manager operator for keyboard leyout export
+ """
+ bl_idname = "wm.keyboardlayout"
+ bl_label = "Keyboard layout (SVG)"
+
+ def execute(self, context):
+ """
+ Iterate over all viewtypes to export the keyboard layout.
+ """
+ for vt in ('VIEW_3D',
+ 'LOGIC_EDITOR',
+ 'NODE_EDITOR',
+ 'CONSOLE',
+ 'GRAPH_EDITOR',
+ 'PROPERTIES',
+ 'SEQUENCE_EDITOR',
+ 'OUTLINER',
+ 'IMAGE_EDITOR',
+ 'TEXT_EDITOR',
+ 'DOPESHEET_EDITOR',
+ 'Window'):
+
+ createKeyboard(vt)
+ return {'FINISHED'}
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/system_project_folder.py b/release/scripts/addons_contrib/system_project_folder.py
new file mode 100644
index 0000000..d791a35
--- /dev/null
+++ b/release/scripts/addons_contrib/system_project_folder.py
@@ -0,0 +1,83 @@
+# system_project_folder.py (c) 2010 Dany Lebel (Axon_D)
+#
+# ***** 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 *****
+
+bl_info = {
+ "name": "Project Folder",
+ "author": "Dany Lebel (Axon_D), Spirou4D",
+ "version": (0,3, 1),
+ "blender": (2, 61, 0),
+ "api": 43260,
+ "location": "Info -> File Menu -> Project Folder",
+ "description": "Open the project folder in a file browser",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/System/Project_Folder",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25910",
+ "category": "System"}
+
+
+import bpy
+import os
+from platform import system as currentOS
+
+
+class ProjectFolder(bpy.types.Operator):
+ """Open the Project Folder in a file Browser"""
+ bl_idname = "file.project_folder"
+ bl_label = "Project Folder"
+
+
+ def execute(self, context):
+ try :
+ path = self.path()
+ except ValueError:
+ self.report({'INFO'}, "No project folder yet")
+ return {'FINISHED'}
+
+ bpy.ops.wm.path_open(filepath=path)
+
+
+ return {'FINISHED'}
+
+ def path(self):
+ filepath = bpy.data.filepath
+ relpath = bpy.path.relpath(filepath)
+ path = filepath[0: -1 * (relpath.__len__() - 2)]
+ return path
+
+
+# Registration
+
+def menu_func(self, context):
+ self.layout.operator(
+ ProjectFolder.bl_idname,
+ text="Project Folder",
+ icon="FILESEL")
+
+def register():
+ bpy.utils.register_class(ProjectFolder)
+ bpy.types.INFO_MT_file.prepend(menu_func)
+
+def unregister():
+ bpy.utils.unregister_class(ProjectFolder)
+ bpy.types.INFO_MT_file.remove(menu_func)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/text_editor_pasteall.py b/release/scripts/addons_contrib/text_editor_pasteall.py
new file mode 100644
index 0000000..a25d535
--- /dev/null
+++ b/release/scripts/addons_contrib/text_editor_pasteall.py
@@ -0,0 +1,221 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "PasteAll",
+ "author": "Dalai Felinto (dfelinto)",
+ "version": (0,7),
+ "blender": (2, 60, 0),
+ "location": "Text editor > Properties panel",
+ "description": "Send your selection or text to www.pasteall.org",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Text_Editor/PasteAll",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=23493",
+ "category": "Text Editor"}
+
+# ########################################################
+# PasteAll.org Text Sender Script
+#
+# Dalai Felinto (dfelinto)
+# blenderecia.orgfree.com
+#
+# Rio de Janeiro - Brasil
+# Vancouver - Canada
+#
+# Original code: 23rd August 2010 (Blender 2.5.3 rev. 31525)
+#
+# Important Note:
+# This script is not official. I did it for fun and for my own usage.
+# And please do not abuse of their generosity - use it wisely (a.k.a no flood).
+#
+# ########################################################
+
+
+import bpy
+import urllib
+import urllib.request
+import webbrowser
+
+class TEXT_PT_pasteall(bpy.types.Panel):
+ bl_space_type = 'TEXT_EDITOR'
+ bl_region_type = 'UI'
+ bl_label = "PasteAll.org"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("text.pasteall", icon='URL')
+ layout.prop(context.scene, "use_webbrowser")
+
+class TEXT_OT_pasteall(bpy.types.Operator):
+ """"""
+ bl_idname = "text.pasteall"
+ bl_label = "PasteAll.org"
+ bl_description = "Send the current text or selection to www.pasteall.org"
+
+ @classmethod
+ def poll(cls, context):
+ if context.area.type != 'TEXT_EDITOR':
+ return False
+ else:
+ return context.space_data.text != None
+
+ def invoke(self, context, event):
+ import webbrowser
+ st = context.space_data
+
+ # get the selected text
+ text = self.get_selected_text(st.text)
+ # if no text is selected send the whole file
+ if text is None: text = st.text.as_string()
+
+ # get the file type based on the extension
+ format = self.get_file_format(st.text)
+
+ # send the text and receive the returned page
+ html = self.send_text(text, format)
+
+ if html is None:
+ self.report({'ERROR'}, "Error in sending the text to the server.")
+ return {'CANCELLED'}
+
+ # get the link of the posted page
+ page = self.get_page(str(html))
+
+ if page is None or page == "":
+ self.report({'ERROR'}, "Error in retrieving the page.")
+ return {'CANCELLED'}
+ else:
+ self.report({'INFO'}, page)
+
+ # store the link in the clipboard
+ bpy.context.window_manager.clipboard = page
+
+ if context.scene.use_webbrowser:
+ try:
+ webbrowser.open_new_tab(page)
+ except:
+ self.report({'WARNING'}, "Error in opening the page %s." % (page))
+
+ return {'FINISHED'}
+
+ def send_text(self, text, format):
+ """"""
+ import urllib
+ url = "http://www.pasteall.org/index.php"
+ values = { 'action' : 'savepaste',
+ 'parent_id' : '0',
+ 'language_id': format,
+ 'code' : text }
+
+ try:
+ data = urllib.parse.urlencode(values).encode()
+ req = urllib.request.Request(url, data)
+ response = urllib.request.urlopen(req)
+ page_source = response.read()
+ except:
+ return None
+ else:
+ return page_source
+
+ def get_page(self, html):
+ """"""
+ id = html.find('directlink')
+ id_begin = id + 12 # hardcoded: directlink">
+ id_end = html[id_begin:].find("</a>")
+
+ if id != -1 and id_end != -1:
+ return html[id_begin:id_begin + id_end]
+ else:
+ return None
+
+ def get_selected_text(self, text):
+ """"""
+ current_line = text.current_line
+ select_end_line = text.select_end_line
+
+ current_character = text.current_character
+ select_end_character = text.select_end_character
+
+ # if there is no selected text return None
+ if current_line == select_end_line:
+ if current_character == select_end_character:
+ return None
+ else:
+ return current_line.body[min(current_character,select_end_character):max(current_character,select_end_character)]
+
+ text_return = None
+ writing = False
+ normal_order = True # selection from top to bottom
+
+ for line in text.lines:
+ if not writing:
+ if line == current_line:
+ text_return = current_line.body[current_character:] + "\n"
+ writing = True
+ continue
+ elif line == select_end_line:
+ text_return = select_end_line.body[select_end_character:] + "\n"
+ writing = True
+ normal_order = False
+ continue
+ else:
+ if normal_order:
+ if line == select_end_line:
+ text_return += select_end_line.body[:select_end_character]
+ break
+ else:
+ text_return += line.body + "\n"
+ continue
+ else:
+ if line == current_line:
+ text_return += current_line.body[:current_character]
+ break
+ else:
+ text_return += line.body + "\n"
+ continue
+
+ return text_return
+
+ def get_file_format(self, text):
+ """Try to guess what is the format based on the file extension"""
+ extensions = {'diff':'24',
+ 'patch':'24',
+ 'py':'62',
+ 'c':'12',
+ 'cpp':'18'}
+
+ type = text.name.split(".")[-1]
+ return extensions.get(type, '0')
+
+def register():
+ bpy.types.Scene.use_webbrowser = bpy.props.BoolProperty(
+ name='Launch Browser',
+ description='Opens the page with the submitted text.',
+ default=True)
+
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ del bpy.types.Scene.use_webbrowser
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
+
+
diff --git a/release/scripts/addons_contrib/text_intellisense.py b/release/scripts/addons_contrib/text_intellisense.py
new file mode 100644
index 0000000..5b93017
--- /dev/null
+++ b/release/scripts/addons_contrib/text_intellisense.py
@@ -0,0 +1,436 @@
+# ***** 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 *****
+
+bl_info = {
+ "name": "Intellisense for Text Editor",
+ "author": "Mackraken",
+ "version": (0, 2),
+ "blender": (2, 60, 0),
+ "api": 41851,
+ "location": "Ctrl + Space at Text Editor",
+ "description": "Adds intellense to the Text Editor",
+ "warning": "Only works with 2.57 intellisense",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Development"}
+
+import bpy
+
+def complete(context):
+ from console import intellisense
+ from console_python import get_console
+
+ sc = context.space_data
+ text = sc.text
+
+ region = context.region
+ for area in context.screen.areas:
+ if area.type=="CONSOLE":
+ region = area.regions[1]
+ break
+
+ console = get_console(hash(region))[0]
+
+ line = text.current_line.body
+ cursor = text.current_character
+
+ result = intellisense.expand(line, cursor, console.locals, bpy.app.debug)
+
+ return result
+
+
+class Intellimenu(bpy.types.Menu):
+ bl_label = ""
+ bl_idname = "IntelliMenu"
+
+ text = ""
+
+ def draw(self, context):
+ layout = self.layout
+ #Very ugly see how can i fix this
+ options = complete(context)
+
+ options = options[2].split(" ")
+ for op in options:
+ layout.operator("text.intellioptions", text=op).text=op
+
+#This operator executes when hits Ctrl+Space at the text editor
+
+class Intellisense(bpy.types.Operator):
+ #"""Tooltip"""
+ bl_idname = "text.intellisense"
+ bl_label = "Text Editor Intellisense"
+
+ text = ""
+
+# @classmethod
+# def poll(cls, context):
+# return context.active_object is not None
+
+ def execute(self, context):
+ sc = context.space_data
+ text = sc.text
+
+ if text.current_character>0:
+ result = complete(context)
+
+ #print(result)
+
+ if result[2]=="":
+ text.current_line.body = result[0]
+ bpy.ops.text.move(type='LINE_END')
+ else:
+ bpy.ops.wm.call_menu(name=Intellimenu.bl_idname)
+
+ return {'FINISHED'}
+
+#this operator completes the line with the options you choose from the menu
+class Intellioptions(bpy.types.Operator):
+ #"""Tooltip"""
+ bl_idname = "text.intellioptions"
+ bl_label = "Intellisense options"
+
+ text = bpy.props.StringProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object is not None
+
+ def execute(self, context):
+ sc = context.space_data
+ text = sc.text
+
+ comp = self.text
+ line = text.current_line.body
+
+ lline = len(line)
+ lcomp = len(comp)
+
+ #intersect text
+ intersect = [-1,-1]
+
+ for i in range(lcomp):
+ val1 = comp[0:i+1]
+
+ for j in range(lline):
+ val2 = line[lline-j-1::]
+ #print(" ",j, val2)
+
+ if val1==val2:
+ intersect = [i, j]
+ break
+
+ if intersect[0]>-1:
+ newline = line[0:lline-intersect[1]-1]+comp
+ else:
+ newline = line + comp
+
+ #print(newline)
+ text.current_line.body = newline
+
+ bpy.ops.text.move(type='LINE_END')
+
+
+ return {'FINISHED'}
+
+def send_console(context, all=0):
+
+ sc = context.space_data
+ text = sc.text
+
+ console = None
+
+ for area in bpy.context.screen.areas:
+ if area.type=="CONSOLE":
+ from console_python import get_console
+
+ console = get_console(hash(area.regions[1]))[0]
+
+ if console==None:
+ return {'FINISHED'}
+
+ if all:
+
+ for l in text.lines:
+ console.push(l.body)
+
+ else:
+ #print(console.prompt)
+ console.push(text.current_line.body)
+
+
+
+
+class TestLine(bpy.types.Operator):
+ #"""Tooltip"""
+ bl_idname = "text.test_line"
+ bl_label = "Test line"
+
+ all = bpy.props.BoolProperty(default=False)
+
+
+# @classmethod
+# def poll(cls, context):
+# return context.active_object is not None
+
+ def execute(self, context):
+ #print("test line")
+
+ #send_console(context, self.all)
+ sc = context.space_data
+ text = sc.text
+
+ line = text.current_line.body
+ console = None
+
+ for area in bpy.context.screen.areas:
+ if area.type=="CONSOLE":
+ from console_python import get_console
+
+ console = get_console(hash(area.regions[1]))[0]
+
+ if console==None:
+ return {'FINISHED'}
+
+ command = ""
+
+ forindex = line.find("for ")
+ if forindex >-1:
+
+ var = line[forindex+4:-1]
+ var = var[0:var.find(" ")]
+ state = line[line.rindex(" ")+1:-1]
+
+ command = var + " = " +state+"[0]"
+
+
+ else:
+ command = line
+
+ #print(command)
+ try:
+ console.push(command)
+ except:
+ pass
+
+ bpy.ops.text.line_break()
+
+
+ return {'FINISHED'}
+class SetBreakPoint(bpy.types.Operator):
+ bl_idname = "text.set_breakpoint"
+ bl_label = "Set Breakpoint"
+
+ def execute(self, context):
+
+ sc = bpy.context.space_data
+ text = sc.text
+
+ line = text.current_line
+ br = " #breakpoint"
+ #print(line.body.find(br))
+ if line.body.find(br)>-1:
+
+ line.body = line.body.replace(br, "")
+ else:
+
+ line.body += br
+
+ return {'FINISHED'}
+
+class Debug(bpy.types.Operator):
+ bl_idname = "text.debug"
+ bl_label = "Debug"
+
+ def execute(self, context):
+
+ binpath = bpy.app.binary_path
+
+ addonspath = binpath[0:binpath.rindex("\\")+1]+str(bpy.app.version[0])+"."+str(bpy.app.version[1])+"\\scripts\\addons\\"
+
+ print(addonspath)
+
+ sc = context.space_data
+ text = sc.text
+
+ br = " #breakpoint"
+
+ filepath = addonspath+"debug.py"
+ file = open(filepath, "w")
+ file.write("import pdb\n")
+
+ for line in text.lines:
+ l = line.body
+
+ if line.body.find(br)>-1:
+ indent = ""
+ for letter in line.body:
+
+ if not letter.isalpha():
+ indent+=letter
+ else:
+ break
+ file.write(l[0:-len(br)]+"\n")
+
+ file.write(indent+"pdb.set_trace()\n")
+
+ else:
+ file.write(line.body+"\n")
+
+
+
+ file.close()
+
+ import pdb
+ import debug
+
+ pdb.runcall("debug")
+
+
+ return {'FINISHED'}
+
+
+class DebugPanel(bpy.types.Panel):
+ bl_label = "Debug"
+ bl_idname = "text.test_line"
+ bl_space_type = "TEXT_EDITOR"
+ bl_region_type = "UI"
+ #bl_context = "object"
+
+ text = bpy.props.StringProperty()
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+
+ text = self.text
+ row = layout.row()
+ row.operator("text.debug", text ="Debug")
+ row = layout.row()
+ row.operator("text.set_breakpoint")
+ row = layout.row()
+ row.operator("text.test_line").all=False
+ row = layout.row()
+ row.operator("text.test_line", text ="Test All").all=True
+
+ row = layout.row()
+ row.label(text="Coming Soon ...")
+
+
+### ASSIGN A KEY
+
+#section = Input section. "Window, Text, ..."
+#name = operator name or wm.call_menu
+#type = key
+#event = keyboard event (Press, release, ...)
+#mods = array containing key modifiers (["ctrl", "alt", "shift"]
+#propvalue = menu name, if name is set to "wm.call_menu"
+#overwrite doesnt work at the moment
+
+def assignKey(section, name, type, event, mods=[],propvalue = "", overwrite=0):
+
+ kconf = bpy.context.window_manager.keyconfigs.active
+
+
+ #check section
+ validsections = [item.name for item in kconf.keymaps]
+ if not section in validsections:
+ print(section + " is not a valid section.")
+ #print(validsections)
+ return False
+
+ #check type
+ type = type.upper()
+ validkeys = [item.identifier for item in bpy.types.KeyMapItem.bl_rna.properties['type'].enum_items]
+ if not type in validkeys:
+ print(type + " is not a valid key.")
+ #print(validkeys)
+ return False
+
+
+ #check event
+ event = event.upper()
+ validevents = [item.identifier for item in bpy.types.KeyMapItem.bl_rna.properties['value'].enum_items]
+ if not event in validevents:
+ print(event + " is not a valid event.")
+ #print(validevents)
+
+ kmap = kconf.keymaps[section]
+
+
+# get mods
+ for i, mod in enumerate(mods):
+ mods[i]= mod.lower()
+
+ #any, shift, ctrl, alt, oskey
+ kmod = [False, False, False, False, False]
+
+ if "any" in mods: kmod[0] = True
+ if "shift" in mods: kmod[1] = True
+ if "ctrl" in mods: kmod[2] = True
+ if "alt" in mods: kmod[3] = True
+ if "oskey" in mods: kmod[4] = True
+
+# #check if key exist
+ kexists = False
+
+ for key in kmap.keymap_items:
+ keymods = [key.any, key.shift, key.ctrl, key.alt, key.oskey]
+ if key.type == type and keymods == kmod:
+ kexists = True
+ print(key,"key exists")
+ break
+
+ if kexists:
+ #overwrite?
+ if overwrite:
+ key.idname=name
+
+ #key.type = type
+
+ else:
+ #create key
+ key = kmap.keymap_items.new(name, type, event, False)
+ key.any = kmod[0]
+ key.shift = kmod[1]
+ key.ctrl = kmod[2]
+ key.alt = kmod[3]
+ key.oskey = kmod[4]
+
+ if propvalue!="": key.properties.name = propvalue
+
+
+
+
+classes = [Intellisense, Intellioptions, Intellimenu, DebugPanel, TestLine, SetBreakPoint, Debug]
+
+def register():
+
+ for c in classes:
+ bpy.utils.register_class(c)
+
+ assignKey("Text", "text.intellisense", "SPACE", "Press", ["ctrl"])
+ assignKey("Text", "text.test_line", "RET", "Press", [],"",1)
+
+def unregister():
+ for c in classes:
+ bpy.utils.unregister_class(c)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/ui_layer_manager.py b/release/scripts/addons_contrib/ui_layer_manager.py
new file mode 100644
index 0000000..553d5df
--- /dev/null
+++ b/release/scripts/addons_contrib/ui_layer_manager.py
@@ -0,0 +1,762 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8 compliant>
+#
+bl_info = {
+ "name": "Layer Management",
+ "author": "Alfonso Annarumma",
+ "version": (1,4),
+ "blender": (2, 63, 0),
+ "location": "View3D > Properties panel > Layer Management",
+ "warning": "",
+ "description": "Display and Edit Layer Name",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/3D_interaction/layer_manager",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"
+ "func=detail&aid=32472",
+ "category": "3D View"}
+
+import bpy
+from bpy.props import StringProperty, BoolProperty, IntProperty, CollectionProperty, BoolVectorProperty
+
+EDIT = ["EDIT_MESH", "EDIT_CURVE", "EDIT_SURFACE", "EDIT_METABALL", "EDIT_TEXT", "EDIT_ARMATURE"]
+
+class LayerGroups(bpy.types.PropertyGroup):
+
+ toggle = BoolProperty(name="",default=False)
+
+ lock = BoolProperty(name="",default=False)
+
+ layer_groups = BoolVectorProperty(name="Layer Groups", default = ([False]*20), size=20, subtype='LAYER')
+
+ # A list of identifiers (colon-separated strings) which property’s controls should be displayed
+ # in a template_list.
+ # Note that the order is respected.
+ #template_list_controls = StringProperty(default="toggle", options={"HIDDEN"})
+
+bpy.utils.register_class(LayerGroups)
+
+bpy.types.Scene.layergroups = CollectionProperty(type=LayerGroups)
+# Unused, but this is needed for the TemplateList to work…
+bpy.types.Scene.layergroups_index = IntProperty(default=-1)
+
+class RemoveLayerGroup(bpy.types.Operator):
+ '''Tooltip'''
+ bl_idname = "object.layergroup_remove"
+ bl_label = "Remove select Layer Group"
+
+ index_group = bpy.props.IntProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene is not None
+
+ def execute(self, context):
+ scene = context.scene
+
+ index_group =self.index_group
+
+ scene.layergroups.remove(index_group)
+
+ scene.layergroups_index= index_group-1
+
+ return {'FINISHED'}
+
+class AddLayerGroup(bpy.types.Operator):
+ '''Tooltip'''
+ bl_idname = "object.layergroup_add"
+ bl_label = "Add select Layer group"
+
+ index = bpy.props.IntProperty()
+ layer = layer = BoolVectorProperty(name="Layer", default = ([False]*20), size=20)
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene is not None
+
+ def execute(self, context):
+
+ scene = context.scene
+ layergroups = scene.layergroups
+
+ index = self.index
+ layer = self.layer
+
+ item = layergroups.add()
+ index_number= str(index)
+
+ if len(index_number)==2:
+ index_number = "0"+index_number
+ if len(index_number)==3:
+ index_number = index_number
+ else:
+ index_number = "00"+index_number
+ item.name= 'LayerGroup.'+index_number
+ #item.use=True
+ scene.layergroups_index= index
+ scene.layergroups[index].layer_groups = layer
+
+ return {'FINISHED'}
+
+class LayerToggle(bpy.types.Operator):
+ '''Visualize this Layer, Shift-Click to select multiple layers'''
+ bl_idname = "object.layertoggle"
+ bl_label = "Visualize this layer"
+
+ #prop definition
+ #layer number
+ layerN = bpy.props.IntProperty()
+ spacecheck = bpy.props.BoolProperty()
+ index_group = bpy.props.IntProperty()
+
+ @classmethod
+
+ def poll(cls, context):
+
+ return context.scene
+
+ def execute(self, context):
+
+ spacecheck = self.spacecheck
+ scene = context.scene
+
+ layerN = self.layerN
+
+ if spacecheck:
+
+ space = context.area.spaces.active
+ else:
+ space = context.scene
+
+ if layerN==-1:
+ index = self.index_group
+ groups = scene.layergroups[index].layer_groups
+ layergroups = scene.layergroups[index]
+
+ layers = space.layers
+ union= [False]*20
+
+ if not layergroups.toggle:
+ for i in range(0,20):
+
+ union[i]= groups[i] or layers[i]
+
+ space.layers=union
+ layergroups.toggle=True
+ else:
+ for i in range(0,20):
+
+ union[i]= not groups[i] and layers[i]
+
+ space.layers=union
+ layergroups.toggle=False
+
+ else:
+
+ if self.shift:
+
+ if space.layers[layerN]:
+ toggle = False
+ else:
+
+ toggle= True
+ space.layers[layerN]=toggle
+
+ else:
+
+ layer = [False]*20
+ layer[layerN]=True
+ space.layers=layer
+
+ if space.layers[layerN]:
+ toggle = False
+
+ return {'FINISHED'}
+ def invoke(self, context, event):
+ self.shift = event.shift
+
+ return self.execute(context)
+
+class MergeSelected(bpy.types.Operator):
+ '''Move Selected Objects in this Layer Shift-Click to select multiple layers'''
+ bl_idname = "object.mergeselected"
+ bl_label = "Merge Selected object in this layer"
+
+ #prop definition
+ #layer number
+ layerN = bpy.props.IntProperty()
+
+ @classmethod
+
+ def poll(cls, context):
+
+ return context.scene
+
+ def execute(self, context):
+
+ layerN = self.layerN
+
+ scene= context.scene
+
+ #cyecle all object in the layer
+
+ for obj in scene.objects:
+
+ if obj.select:
+ visible=False
+
+ for i in range(0,20):
+ if obj.layers[i] and scene.layers[i]:
+ visible=True
+ break
+
+ if visible:
+ if self.shift:
+
+ if obj.layers[layerN]:
+ toggle = False
+ else:
+
+ toggle= True
+ obj.layers[layerN]=toggle
+
+ else:
+
+ layer = [False]*20
+ layer[layerN]=True
+ obj.layers=layer
+
+ if obj.layers[layerN]:
+ toggle = False
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ self.shift = event.shift
+
+ return self.execute(context)
+
+class LockSelected(bpy.types.Operator):
+ '''Loock All Objects on this Layer'''
+ bl_idname = "object.lockselected"
+ bl_label = "Hide Select of Selected"
+
+ #prop definition
+ #layer number
+ layerN = bpy.props.IntProperty()
+
+ #lock status
+ lock = bpy.props.BoolProperty()
+
+ index_group = bpy.props.IntProperty()
+
+ @classmethod
+
+ def poll(cls, context):
+
+ return context.scene
+
+ def execute(self, context):
+
+ scene = context.scene
+ layerN = self.layerN
+ lock =self.lock
+
+ view_3d = context.area.spaces.active
+
+ #check if layer have some thing
+ if view_3d.layers_used[layerN] or layerN==-1:
+
+ #cyecle all object in the layer
+ for obj in context.scene.objects:
+
+ if layerN==-1:
+
+ index = self.index_group
+ groups = scene.layergroups[index].layer_groups
+ layers = obj.layers
+
+ layergroup=[False]*20
+
+ for i in range (0,20):
+ layergroup[i]= layers[i] and groups[i]
+
+ if True in layergroup:
+ obj.hide_select=not lock
+ obj.select=False
+
+ scene.layergroups[index].lock=not lock
+
+ else:
+ if obj.layers[layerN]:
+ obj.hide_select=not lock
+ obj.select=False
+
+ scene.LockLayer[layerN]= not lock
+
+ return {'FINISHED'}
+
+class SelectObjectsLayer(bpy.types.Operator):
+ '''Select All the Objects on this Layer'''
+ bl_idname = "object.selectobjectslayer"
+ bl_label = "Select objects in Layer"
+
+ select_obj = bpy.props.BoolProperty()
+ layerN = bpy.props.IntProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene
+
+ def execute(self, context):
+
+ view_3d = context.area.spaces.active
+ select_obj= self.select_obj
+ layerN = self.layerN
+ scene = context.scene
+ i=0
+ s=0
+ #check if layer have some thing
+ if view_3d.layers_used[layerN]:
+
+ for obj in context.scene.objects:
+
+ if obj.layers[layerN]:
+ i = i+1
+ if obj.layers[layerN] and obj.select:
+ s = s+1
+
+ if s==i:
+ for obj in context.scene.objects:
+
+ if obj.layers[layerN]:
+ obj.select=False
+
+ else:
+ bpy.ops.object.select_by_layer(extend=True, layers=layerN+1)
+
+ return {'FINISHED'}
+
+class AllLayersSelect(bpy.types.Operator):
+ '''Active all Layer in scene'''
+ bl_idname = "scene.layersselect"
+ bl_label = "Select All Layer"
+
+ vis = bpy.props.BoolProperty()
+
+ @classmethod
+ def poll(cls, context):
+ return context.scene
+
+ def execute(self, context):
+
+ scene = context.scene
+ vis = self.vis
+ #store the active layer
+ active = scene.active_layer
+
+ view_3d = context.area.spaces.active
+ #check for lock camera and layer is active
+ if view_3d.lock_camera_and_layers is True:
+ space= scene
+
+ else:
+ space= view_3d
+
+ if not vis:
+ for i in range (0,20):
+
+ #keep selection of active layer
+ if active == i:
+ space.layers[i]= True
+
+ #deselect the other...
+ else:
+ space.layers[i]= False
+
+ else:
+ for i in range (0,20):
+ #select all layer
+ space.layers[i]=True
+
+ #after the cycle, deselect and select the previus active layer
+ space.layers[active]=False
+ space.layers[active]=True
+ return {'FINISHED'}
+
+class LayerName(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Layer Management"
+ bl_idname = "_PT_rig_layers"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ # layer name prop definition
+ bpy.types.Scene.LayerName1 = bpy.props.StringProperty(name="Layer Name", default='layer1')
+ bpy.types.Scene.LayerName2 = bpy.props.StringProperty(name="Layer Name", default='layer2')
+ bpy.types.Scene.LayerName3 = bpy.props.StringProperty(name="Layer Name", default='layer3')
+ bpy.types.Scene.LayerName4 = bpy.props.StringProperty(name="Layer Name", default='layer4')
+ bpy.types.Scene.LayerName5 = bpy.props.StringProperty(name="Layer Name", default='layer5')
+ bpy.types.Scene.LayerName6 = bpy.props.StringProperty(name="Layer Name", default='layer6')
+ bpy.types.Scene.LayerName7 = bpy.props.StringProperty(name="Layer Name", default='layer7')
+ bpy.types.Scene.LayerName8 = bpy.props.StringProperty(name="Layer Name", default='layer8')
+ bpy.types.Scene.LayerName9 = bpy.props.StringProperty(name="Layer Name", default='layer9')
+ bpy.types.Scene.LayerName10 = bpy.props.StringProperty(name="Layer Name", default='layer10')
+ bpy.types.Scene.LayerName11 = bpy.props.StringProperty(name="Layer Name", default='layer11')
+ bpy.types.Scene.LayerName12 = bpy.props.StringProperty(name="Layer Name", default='layer12')
+ bpy.types.Scene.LayerName13 = bpy.props.StringProperty(name="Layer Name", default='layer13')
+ bpy.types.Scene.LayerName14 = bpy.props.StringProperty(name="Layer Name", default='layer14')
+ bpy.types.Scene.LayerName15 = bpy.props.StringProperty(name="Layer Name", default='layer15')
+ bpy.types.Scene.LayerName16 = bpy.props.StringProperty(name="Layer Name", default='layer16')
+ bpy.types.Scene.LayerName17 = bpy.props.StringProperty(name="Layer Name", default='layer17')
+ bpy.types.Scene.LayerName18 = bpy.props.StringProperty(name="Layer Name", default='layer18')
+ bpy.types.Scene.LayerName19 = bpy.props.StringProperty(name="Layer Name", default='layer19')
+ bpy.types.Scene.LayerName20 = bpy.props.StringProperty(name="Layer Name", default='layer20')
+
+ #prop for hide empty
+ bpy.types.Scene.LayerVisibility = bpy.props.BoolProperty(name="Hide empty Layer", default=False)
+
+ #prop for extra option
+ bpy.types.Scene.ExtraOptions = bpy.props.BoolProperty(name="Show extra options", default=True)
+
+ #lock layer status
+ bpy.types.Scene.LockLayer = bpy.props.BoolVectorProperty(name="Lock Layer", default = ([False]*20), size=20)
+
+ #prop for show index
+ bpy.types.Scene.LayerIndex = bpy.props.BoolProperty(name="Show Index", default=False)
+
+ #prop for show classic
+ bpy.types.Scene.Classic = bpy.props.BoolProperty(name="Classic", default=False,description="Use a classic layer selection visibility")
+ #Select object Status
+ bpy.types.Scene.ObjectSelect = bpy.props.BoolVectorProperty(name="Object Select", default = ([True]*20), size=20)
+
+ #toggle for merge
+ #bpy.types.Scene.MergeToggle = bpy.props.BoolVectorProperty(name="Merge Toggle", default = (False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False), size=20)
+
+ @classmethod
+ def poll(self, context):
+ try:
+ return (context.mode not in EDIT)
+ except (AttributeError, KeyError, TypeError):
+ return False
+
+ def draw(self, context):
+
+ scene = context.scene
+
+ view_3d = context.area.spaces.active
+ #check for lock camera and layer is active
+ if view_3d.lock_camera_and_layers is True:
+ space= scene
+ spacecheck=False
+
+ else:
+ space= view_3d
+ spacecheck=True
+
+ #row = layout.row(align=True)
+
+ vis=False
+ allIcon='RESTRICT_VIEW_OFF'
+ allText="Isolate active"
+
+ #check if there is a layer off
+ for layer in space.layers:
+
+ if not layer:
+ vis=True
+ allIcon='RESTRICT_VIEW_ON'
+ allText="All Visible"
+
+ layout = self.layout
+ column = layout.column()
+ row = column.row()
+ col2= row.column()
+
+ #lock camera and layers button
+
+ col2.prop(view_3d, "lock_camera_and_layers", text="")
+
+ #select all
+
+ allView = col2.operator("scene.layersselect", emboss=False, icon=allIcon, text="")
+ allView.vis=vis
+
+ col= row.column()
+ col.alignment='RIGHT'
+ #classic
+ col.prop(scene, "Classic", text="Classic")
+
+ #show extra option checkbox
+
+ col.alignment='RIGHT'
+ col.prop(scene, "ExtraOptions", text="Options")
+
+ col1= row.column()
+
+ #show index
+ col1.prop(scene, "LayerIndex", text="Index")
+
+ # hide empty
+
+ if context.object:
+ col1.alignment='RIGHT'
+ col1.prop(scene, "LayerVisibility", toggle=False, text="Hide Empty")
+
+ ##########
+
+ #list the layer
+ for i in range(0,20):
+
+ #inizializing the icon
+ #lockIcon='UNLOCKED'
+ iconUsed= 'RADIOBUT_OFF'
+ iconAc='NONE'
+ iconLayer='NONE'
+ #selectIcon ='RESTRICT_SELECT_OFF'
+ #inizializing the bool value
+ noitem = False
+
+ active=False
+
+ layer=20
+ scene = context.scene
+
+ extra = scene.ExtraOptions
+
+ layer_used = view_3d.layers_used[i]
+
+ #check the hide empty value
+ if scene.LayerVisibility:
+
+ #find the empty layer
+ if layer_used:
+ #print (i)
+ layer = i
+
+ 'Add ad object to see the layer'
+ else:
+ layer=i
+ #the layer number
+
+ #set icon for lock layer
+ lock = scene.LockLayer[i]
+
+ if lock:
+ lockIcon= 'LOCKED'
+ else:
+ lockIcon= 'UNLOCKED'
+
+ #check if there are Selected obj in the layer
+
+ #check if layer have some thing
+ if layer_used:
+
+ iconUsed= 'LAYER_USED'
+
+ active_object = context.object
+
+ if active_object:
+
+ if context.object.layers[i]:
+
+ active = True
+
+ else:
+ scene.ObjectSelect[i]= True
+
+ if layer ==i:
+
+ #check for active layer and set the icon
+ if view_3d.lock_camera_and_layers:
+
+ if scene.active_layer==layer:
+ iconAc = 'FILE_TICK'
+ noitem = True
+
+ if active:
+ iconUsed = 'LAYER_ACTIVE'
+
+ #set icon for layer view
+ if view_3d.layers[layer]:
+ viewIcon = 'RESTRICT_VIEW_OFF'
+ noitem = True
+ else:
+ viewIcon = 'RESTRICT_VIEW_ON'
+ noitem = False
+
+ row2=column.row(align=True)
+# if space==scene:
+#
+# colb1= row2.column()
+# #layer visibility operator
+# tog = colb1.operator("view3d.layers", text="",icon=viewIcon, emboss=False)
+# tog.nr=layer+1
+# tog.toggle=True
+# viewemboss = True
+
+ iconLayer=viewIcon
+
+ # layer index
+ if scene.LayerIndex:
+
+ col6 = row2.column()
+ col6.scale_x=0.14
+ col6.label(text=str(i+1)+".")
+
+ # visualization
+ classic = scene.Classic
+ if not classic:
+
+ colb2= row2.column()
+ colb2.prop(space, "layers", index=layer, emboss=True, icon=iconLayer, toggle=True, text="")
+ else:
+ colb6 = row2.column()
+ used = colb6.operator("object.layertoggle", text="", icon= iconLayer, emboss=True)
+ used.layerN=i
+ used.spacecheck=spacecheck
+
+ #text prop
+ s = "LayerName"+str(i+1)
+ colb3= row2.column()
+ colb3.prop(scene,s,text="",icon=iconAc)
+
+ if extra:
+
+ #Select by type operator
+ colb4 = row2.column()
+ select = colb4.operator("object.selectobjectslayer", icon='RESTRICT_SELECT_OFF',text="", emboss=True )
+ select.layerN = i
+ #select.select_obj= selobj
+
+ #lock operator
+ colb5 = row2.column()
+ lk = colb5.operator("object.lockselected", text="", emboss=True, icon= lockIcon)
+
+ lk.layerN = i
+ lk.lock=lock
+
+ # #occuped layer
+ # colb6.label(text="", icon=iconUsed)
+
+ #merge layer
+ colb7 = row2.column()
+ merge = colb7.operator("object.mergeselected", text="", emboss=True, icon= iconUsed)
+ merge.layerN=i
+
+ if not scene.LayerVisibility:
+ if i==4 or i==9 or i==14 or i==19:
+ row3 = column.row()
+ row3.separator()
+ if len(scene.objects)==0:
+ layout.label(text='No objects in scene')
+class LayerGroupsUI(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_label = "Layer Groups"
+ bl_idname = "_PT_layer_group"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(self, context):
+ try:
+ return (context.mode not in EDIT)
+ except (AttributeError, KeyError, TypeError):
+ return False
+
+ def draw(self, context):
+
+ scene = context.scene
+ view_3d = context.area.spaces.active
+
+ #check for lock camera and layer is active
+ if view_3d.lock_camera_and_layers is True:
+ space= scene
+ spacecheck = False
+ else:
+ space= view_3d
+ spacecheck = True
+ #######################
+
+ index_group = scene.layergroups_index
+ items =len(scene.layergroups)
+ viewIcon = 'RESTRICT_VIEW_OFF'
+ layout = self.layout
+ row = layout.row()
+ row.template_list(context.scene, "layergroups", context.scene, "layergroups_index", rows=items)
+ col =row.column(align =True)
+ add = col.operator("object.layergroup_add", icon='ZOOMIN', text="")
+ add.index= items
+ add.layer= scene.layers
+ remove = col.operator("object.layergroup_remove", icon='ZOOMOUT', text="")
+ remove.index_group= index_group
+ if index_group >= 0:
+
+ lock=scene.layergroups[index_group].lock
+ toggle = scene.layergroups[index_group].toggle
+ if lock:
+ iconLock= 'LOCKED'
+ else:
+ iconLock='UNLOCKED'
+
+ lk = col.operator("object.lockselected", text="", emboss=True, icon= iconLock)
+ lk.index_group = index_group
+ lk.lock=lock
+ lk.layerN=-1
+
+ #set icon for layer view
+ if toggle:
+ iconLayer = 'RESTRICT_VIEW_OFF'
+ #noitem = True
+ else:
+ iconLayer = 'RESTRICT_VIEW_ON'
+ #noitem = False
+
+ view = col.operator("object.layertoggle", text="", icon= iconLayer, emboss=True)
+ view.index_group = index_group
+ view.layerN=-1
+ view.spacecheck=spacecheck
+
+ layout.prop(scene.layergroups[index_group], "layer_groups", text="", toggle=True)
+ layout.prop(scene.layergroups[index_group], "name", text="Name:")
+
+def register():
+
+ bpy.utils.register_class(AddLayerGroup)
+ bpy.utils.register_class(RemoveLayerGroup)
+ bpy.utils.register_class(LayerGroupsUI)
+ bpy.utils.register_class(AllLayersSelect)
+ bpy.utils.register_class(LayerToggle)
+ bpy.utils.register_class(MergeSelected)
+ bpy.utils.register_class(LayerName)
+ bpy.utils.register_class(LockSelected)
+ bpy.utils.register_class(SelectObjectsLayer)
+
+def unregister():
+ bpy.utils.unregister_class(AddLayerGroup)
+ bpy.utils.unregister_class(RemoveLayerGroup)
+ bpy.utils.unregister_class(LayerGroupsUI)
+ bpy.utils.unregister_class(LayerName)
+ bpy.utils.uregister_class(AllLayersSelect)
+ bpy.utils.unregister_class(LayerToggle)
+ bpy.utils.uregister_class(MergeSelected)
+ bpy.utils.unregister_class(LockSelected)
+ bpy.utils.unregister_class(SelectObjectsLayer)
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/addons_contrib/wetted_mesh.py b/release/scripts/addons_contrib/wetted_mesh.py
new file mode 100644
index 0000000..24e25fa
--- /dev/null
+++ b/release/scripts/addons_contrib/wetted_mesh.py
@@ -0,0 +1,373 @@
+# ##### 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 LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Add Wetted Mesh",
+ "author": "freejack",
+ "version": (0, 2, 1),
+ "blender": (2, 58, 0),
+ "location": "View3D > Tool Shelf > Wetted Mesh Panel",
+ "description": "Adds separated fluid, dry and wetted mesh for selected pair.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
+ "Scripts/Mesh/Wetted_Mesh",
+ "tracker_url": "http://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=27156",
+ "category": "Mesh"}
+
+import bpy
+import collections
+import math
+
+### Tool Panel ###
+class VIEW3D_PT_tools_WettedMesh(bpy.types.Panel):
+ """Wetted Mesh Tool Panel"""
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = 'Wetted Mesh'
+ bl_context = 'objectmode'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+ slcnt = len(context.selected_objects)
+
+ if slcnt != 2:
+ col.label(text = 'Select two mesh objects')
+ col.label(text = 'to generate separated')
+ col.label(text = 'fluid, dry and wetted')
+ col.label(text = 'meshes.')
+ else:
+ (solid, fluid) = getSelectedPair(context)
+ col.label(text = 'solid = '+solid.name)
+ col.label(text = 'fluid = '+fluid.name)
+ col.operator('mesh.primitive_wetted_mesh_add', text='Generate Meshes')
+
+### Operator ###
+class AddWettedMesh(bpy.types.Operator):
+ """Add wetted mesh for selected mesh pair"""
+ bl_idname = "mesh.primitive_wetted_mesh_add"
+ bl_label = "Add Wetted Mesh"
+ bl_options = {'REGISTER', 'UNDO'}
+ statusMessage = ''
+
+ def draw(self, context):
+ layout = self.layout
+ col = layout.column(align=True)
+ col.label(text = self.statusMessage)
+
+ def execute(self, context):
+ # make sure a pair of objects is selected
+ if len(context.selected_objects) != 2:
+ # should not happen if called from tool panel
+ self.report({'WARNING'}, "no mesh pair selected, operation cancelled")
+ return {'CANCELLED'}
+
+ print("add_wetted_mesh begin")
+
+ # super-selected object is solid, other object is fluid
+ (solid, fluid) = getSelectedPair(context)
+ print(" solid = "+solid.name)
+ print(" fluid = "+fluid.name)
+
+ # make a copy of fluid object, convert to mesh if required
+ print(" copy fluid")
+ bpy.ops.object.select_all(action='DESELECT')
+ fluid.select = True
+ context.scene.objects.active = fluid
+ bpy.ops.object.duplicate()
+ bpy.ops.object.convert(target='MESH', keep_original=False)
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+ fluidCopy = context.object
+
+ # substract solid from fluidCopy
+ print(" bool: fluidCopy DIFFERENCE solid")
+ bpy.ops.object.modifier_add(type='BOOLEAN')
+ bop = fluidCopy.modifiers.items()[0]
+ bop[1].operation = 'DIFFERENCE'
+ bop[1].object = solid
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier=bop[0])
+ fluidMinusSolid = fluidCopy
+ fluidMinusSolid.name = "fluidMinusSolid"
+
+ # make a second copy of fluid object
+ print(" copy fluid")
+ bpy.ops.object.select_all(action='DESELECT')
+ fluid.select = True
+ context.scene.objects.active = fluid
+ bpy.ops.object.duplicate()
+ bpy.ops.object.convert(target='MESH', keep_original=False)
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+ fluidCopy = context.object
+
+ # make union from fluidCopy and solid
+ print(" bool: fluidCopy UNION solid")
+ bpy.ops.object.modifier_add(type='BOOLEAN')
+ bop = fluidCopy.modifiers.items()[0]
+ bop[1].operation = 'UNION'
+ bop[1].object = solid
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier=bop[0])
+ fluidUnionSolid = fluidCopy
+ fluidUnionSolid.name = "fluidUnionSolid"
+
+ # index meshes
+ print(" KDTree index fluidMinusSolid")
+ fluidMinusSolidKDT = KDTree(3, fluidMinusSolid.data.vertices)
+ print(" KDTree index fluidUnionSolid")
+ fluidUnionSolidKDT = KDTree(3, fluidUnionSolid.data.vertices)
+ kdtrees = (fluidMinusSolidKDT, fluidUnionSolidKDT)
+
+ # build mesh face sets
+ faceDict = { }
+ vertDict = { }
+
+ print(" processing fluidMinusSolid faces")
+ cacheDict = { }
+ setFMSfaces = set()
+ numFaces = len(fluidUnionSolid.data.faces)
+ i = 0
+ for f in fluidMinusSolid.data.faces:
+ if i % 500 == 0:
+ print(" ", i, " / ", numFaces)
+ i += 1
+ fuid = unifiedFaceId(kdtrees, f, fluidMinusSolid.data.vertices, \
+ faceDict, vertDict, cacheDict)
+ setFMSfaces.add(fuid)
+
+ print(" processing fluidUnionSolid faces")
+ cacheDict = { }
+ setFUSfaces = set()
+ numFaces = len(fluidUnionSolid.data.faces)
+ i = 0
+ for f in fluidUnionSolid.data.faces:
+ if i % 500 == 0:
+ print(" ", i, " / ", numFaces)
+ i += 1
+ fuid = unifiedFaceId(kdtrees, f, fluidUnionSolid.data.vertices, \
+ faceDict, vertDict, cacheDict)
+ setFUSfaces.add(fuid)
+
+ # remove boolean helpers
+ print(" delete helper objects")
+ bpy.ops.object.select_all(action='DESELECT')
+ fluidUnionSolid.select = True
+ fluidMinusSolid.select = True
+ bpy.ops.object.delete()
+
+ # wetted = FMS - FUS
+ print(" set operation FMS diff FUS")
+ setWetFaces = setFMSfaces.difference(setFUSfaces)
+ print(" build wetted mesh")
+ verts, faces = buildMesh(setWetFaces, faceDict, vertDict)
+ print(" create wetted mesh")
+ wetted = createMesh("Wetted", verts, faces)
+
+ # fluid = FMS x FUS
+ print(" set operation FMS intersect FUS")
+ setFluidFaces = setFMSfaces.intersection(setFUSfaces)
+ print(" build fluid mesh")
+ verts, faces = buildMesh(setFluidFaces, faceDict, vertDict)
+ print(" create fluid mesh")
+ fluid = createMesh("Fluid", verts, faces)
+
+ # solid = FUS - FMS
+ print(" set operation FUS diff FMS")
+ setSolidFaces = setFUSfaces.difference(setFMSfaces)
+ print(" build solid mesh")
+ verts, faces = buildMesh(setSolidFaces, faceDict, vertDict)
+ print(" create solid mesh")
+ solid = createMesh("Solid", verts, faces)
+
+ # parent wetted mesh
+ print(" parent mesh")
+ bpy.ops.object.add(type='EMPTY')
+ wettedMesh = context.object
+ solid.select = True
+ fluid.select = True
+ wetted.select = True
+ wettedMesh.select = True
+ bpy.ops.object.parent_set(type='OBJECT')
+ wettedMesh.name = 'WettedMesh'
+
+ print("add_wetted_mesh done")
+ self.statusMessage = 'created '+wettedMesh.name
+
+ return {'FINISHED'}
+
+
+### Registration ###
+def register():
+ bpy.utils.register_class(VIEW3D_PT_tools_WettedMesh)
+ bpy.utils.register_class(AddWettedMesh)
+
+
+def unregister():
+ bpy.utils.unregister_class(VIEW3D_PT_tools_WettedMesh)
+ bpy.utils.unregister_class(AddWettedMesh)
+
+if __name__ == "__main__":
+ register()
+
+
+#
+# KD tree (used to create a geometric index of mesh vertices)
+#
+
+def distance(a, b):
+ return (a-b).length
+
+Node = collections.namedtuple("Node", 'point axis label left right')
+
+class KDTree(object):
+ """A tree for nearest neighbor search in a k-dimensional space.
+
+ For information about the implementation, see
+ http://en.wikipedia.org/wiki/Kd-tree
+
+ Usage:
+ objects is an iterable of (co, index) tuples (so MeshVertex is useable)
+ k is the number of dimensions (=3)
+
+ t = KDTree(k, objects)
+ point, label, distance = t.nearest_neighbor(destination)
+ """
+
+ def __init__(self, k, objects=[]):
+
+ def build_tree(objects, axis=0):
+
+ if not objects:
+ return None
+
+ objects.sort(key=lambda o: o.co[axis])
+ median_idx = len(objects) // 2
+ median_point = objects[median_idx].co
+ median_label = objects[median_idx].index
+
+ next_axis = (axis + 1) % k
+ return Node(median_point, axis, median_label,
+ build_tree(objects[:median_idx], next_axis),
+ build_tree(objects[median_idx + 1:], next_axis))
+
+ self.root = build_tree(list(objects))
+ self.size = len(objects)
+
+
+ def nearest_neighbor(self, destination):
+
+ best = [None, None, float('inf')]
+ # state of search: best point found, its label,
+ # lowest distance
+
+ def recursive_search(here):
+
+ if here is None:
+ return
+ point, axis, label, left, right = here
+
+ here_sd = distance(point, destination)
+ if here_sd < best[2]:
+ best[:] = point, label, here_sd
+
+ diff = destination[axis] - point[axis]
+ close, away = (left, right) if diff <= 0 else (right, left)
+
+ recursive_search(close)
+ if math.fabs(diff) < best[2]:
+ recursive_search(away)
+
+ recursive_search(self.root)
+ return best[0], best[1], best[2]
+
+
+#
+# helper functions
+#
+
+# get super-selected object and other object from selected pair
+def getSelectedPair(context):
+ objA = context.object
+ objB = context.selected_objects[0]
+ if objA == objB:
+ objB = context.selected_objects[1]
+ return (objA, objB)
+
+# get a unified vertex id for given coordinates
+def unifiedVertexId(kdtrees, location, vertDict):
+ eps = 0.0001
+ offset = 0
+ for t in kdtrees:
+ co, index, d = t.nearest_neighbor(location)
+ if d < eps:
+ uvid = offset + index
+ if uvid not in vertDict:
+ vertDict[uvid] = co
+ return uvid
+ offset += t.size
+ return -1
+
+# get a unified face id tuple
+# Stores the ordered face id tuple in faceDict
+# and the used coordinates for vertex id in vertDict.
+# cacheDict caches the unified vertex id (lookup in kdtree is expensive).
+# For each mesh (where the face belongs to) a separate cacheDict is expected.
+def unifiedFaceId(kdtrees, face, vertices, faceDict, vertDict, cacheDict):
+ fids = [ ]
+ for v in face.vertices:
+ uvid = cacheDict.get(v)
+ if uvid == None:
+ uvid = unifiedVertexId(kdtrees, vertices[v].co, vertDict)
+ cacheDict[v] = uvid
+ fids.append(uvid)
+ ofids = tuple(fids)
+ fids.sort()
+ fuid = tuple(fids)
+ if fuid not in faceDict:
+ faceDict[fuid] = ofids
+ return fuid
+
+# build vertex and face array from unified face sets
+def buildMesh(unifiedFaceSet, faceDict, vertDict):
+ verts = [ ]
+ nextV = 0
+ myV = { }
+ faces = [ ]
+ for uf in unifiedFaceSet:
+ of = faceDict[uf]
+ myf = [ ]
+ for uV in of:
+ v = myV.get(uV)
+ if v == None:
+ v = nextV
+ myV[uV] = nextV
+ verts.append(vertDict[uV])
+ nextV += 1
+ myf.append(v)
+ faces.append(myf)
+ return verts, faces
+
+# create mesh object and link to scene
+def createMesh(name, verts, faces):
+ me = bpy.data.meshes.new(name+"Mesh")
+ ob = bpy.data.objects.new(name, me)
+ ob.show_name = True
+ bpy.context.scene.objects.link(ob)
+ me.from_pydata(verts, [], faces)
+ me.update(calc_edges=True)
+ return ob
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 6bf81d7..65ea91c 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -29,7 +29,7 @@ __all__ = (
)
import bpy as _bpy
-
+_user_preferences = _bpy.context.user_preferences
error_duplicates = False
error_encoding = False
@@ -201,7 +201,7 @@ def check(module_name):
:rtype: tuple of booleans
"""
import sys
- loaded_default = module_name in _bpy.context.user_preferences.addons
+ loaded_default = module_name in _user_preferences.addons
mod = sys.modules.get(module_name)
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
@@ -232,6 +232,7 @@ def enable(module_name, default_set=True, persistent=False):
import os
import sys
+ from bpy_restrict_state import RestrictBlend
def handle_error():
import traceback
@@ -259,34 +260,38 @@ def enable(module_name, default_set=True, persistent=False):
# Split registering up into 3 steps so we can undo
# if it fails par way through.
- # 1) try import
- try:
- mod = __import__(module_name)
- mod.__time__ = os.path.getmtime(mod.__file__)
- mod.__addon_enabled__ = False
- except:
- handle_error()
- return None
-
- # 2) try register collected modules
- # removed, addons need to handle own registration now.
-
- # 3) try run the modules register function
- try:
- mod.register()
- except:
- print("Exception in module register(): %r" %
- getattr(mod, "__file__", module_name))
- handle_error()
- del sys.modules[module_name]
- return None
+ # disable the context, using the context at all is
+ # really bad while loading an addon, don't do it!
+ with RestrictBlend():
+
+ # 1) try import
+ try:
+ mod = __import__(module_name)
+ mod.__time__ = os.path.getmtime(mod.__file__)
+ mod.__addon_enabled__ = False
+ except:
+ handle_error()
+ return None
+
+ # 2) try register collected modules
+ # removed, addons need to handle own registration now.
+
+ # 3) try run the modules register function
+ try:
+ mod.register()
+ except:
+ print("Exception in module register(): %r" %
+ getattr(mod, "__file__", module_name))
+ handle_error()
+ del sys.modules[module_name]
+ return None
# * OK loaded successfully! *
if default_set:
# just in case its enabled already
- ext = _bpy.context.user_preferences.addons.get(module_name)
+ ext = _user_preferences.addons.get(module_name)
if not ext:
- ext = _bpy.context.user_preferences.addons.new()
+ ext = _user_preferences.addons.new()
ext.module = module_name
mod.__addon_enabled__ = True
@@ -327,7 +332,7 @@ def disable(module_name, default_set=True):
(module_name, "disabled" if mod is None else "loaded"))
# could be in more then once, unlikely but better do this just in case.
- addons = _bpy.context.user_preferences.addons
+ addons = _user_preferences.addons
if default_set:
while module_name in addons:
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index c7414e8..0f09e82 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -80,6 +80,9 @@ LANGUAGES = (
(34, "Estonian (Eestlane)", "et_EE"),
(35, "Esperanto (Esperanto)", "eo"),
(36, "Spanish from Spain (Español de España)", "es_ES"),
+ (37, "Amharic (አማርኛ)", "am_ET"),
+ (38, "Uzbek (Oʻzbek)", "uz_UZ"),
+ (39, "Uzbek Cyrillic (Ўзбек)", "uz_UZ at cyrillic"),
)
# Name of language file used by Blender to generate translations' menu.
@@ -90,7 +93,7 @@ LANGUAGES_FILE = "languages"
IMPORT_MIN_LEVEL = -1
# Languages in /branches we do not want to import in /trunk currently...
-IMPORT_LANGUAGES_SKIP = {'bg', 'ca', 'fi', 'el', 'ko', 'ne', 'pl', 'ro'}
+IMPORT_LANGUAGES_SKIP = {'am', 'bg', 'fi', 'el', 'et', 'ko', 'ne', 'pl', 'ro', 'uz', 'uz at cyrillic'}
# The comment prefix used in generated messages.txt file.
COMMENT_PREFIX = "#~ "
diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
index fbe405a..3fd039c 100644
--- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
+++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
@@ -188,6 +188,7 @@ dict_uimsgs = {
"occluder",
"passepartout",
"perspectively",
+ "pixelate",
"polygonization",
"selectability",
"slurph",
@@ -195,7 +196,7 @@ dict_uimsgs = {
"symmetrize",
"trackability",
"transmissivity",
- "rasterized", "rasterization",
+ "rasterized", "rasterization", "rasterizer",
"renderer", "renderable", "renderability",
# Abbreviations
@@ -380,11 +381,13 @@ dict_uimsgs = {
"texface",
"timeline", "timelines",
"tosphere",
+ "uilist",
"vcol", "vcols",
"vgroup", "vgroups",
"vinterlace",
"wetmap", "wetmaps",
"wpaint",
+ "uvwarp",
# Algorithm names
"beckmann",
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index d32b69b..69ed431 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -30,6 +30,9 @@ __all__ = (
"display_name",
"display_name_from_filepath",
"ensure_ext",
+ "extensions_image",
+ "extensions_movie",
+ "extensions_audio",
"is_subdir",
"module_names",
"relpath",
@@ -39,6 +42,10 @@ __all__ = (
import bpy as _bpy
import os as _os
+from _bpy_path import (extensions_audio,
+ extensions_movie,
+ extensions_image,
+ )
def abspath(path, start=None, library=None):
"""
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 4ad00eb..25fe6c1 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -57,6 +57,7 @@ import sys as _sys
import addon_utils as _addon_utils
+_user_preferences = _bpy.context.user_preferences
_script_module_dirs = "startup", "modules"
@@ -132,8 +133,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
"""
use_time = _bpy.app.debug_python
- prefs = _bpy.context.user_preferences
-
if use_time:
import time
t_main = time.time()
@@ -150,7 +149,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
# to reload. note that they will only actually reload of the
# modification time changes. This `won't` work for packages so...
# its not perfect.
- for module_name in [ext.module for ext in prefs.addons]:
+ for module_name in [ext.module for ext in _user_preferences.addons]:
_addon_utils.disable(module_name, default_set=False)
def register_module_call(mod):
@@ -218,24 +217,27 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
del _global_loaded_modules[:]
- for base_path in script_paths():
- for path_subdir in _script_module_dirs:
- path = _os.path.join(base_path, path_subdir)
- if _os.path.isdir(path):
- _sys_path_ensure(path)
+ from bpy_restrict_state import RestrictBlend
+
+ with RestrictBlend():
+ for base_path in script_paths():
+ for path_subdir in _script_module_dirs:
+ path = _os.path.join(base_path, path_subdir)
+ if _os.path.isdir(path):
+ _sys_path_ensure(path)
- # only add this to sys.modules, don't run
- if path_subdir == "modules":
- continue
+ # only add this to sys.modules, don't run
+ if path_subdir == "modules":
+ continue
- for mod in modules_from_path(path, loaded_modules):
- test_register(mod)
+ for mod in modules_from_path(path, loaded_modules):
+ test_register(mod)
# deal with addons separately
_addon_utils.reset_all(reload_scripts)
# run the active integration preset
- filepath = preset_find(prefs.inputs.active_keyconfig, "keyconfig")
+ filepath = preset_find(_user_preferences.inputs.active_keyconfig, "keyconfig")
if filepath:
keyconfig_set(filepath)
@@ -264,7 +266,7 @@ def script_path_user():
def script_path_pref():
"""returns the user preference or None"""
- path = _bpy.context.user_preferences.filepaths.script_directory
+ path = _user_preferences.filepaths.script_directory
return _os.path.normpath(path) if path else None
diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py
index b8d0862..7a5d169 100644
--- a/release/scripts/modules/bpy_extras/anim_utils.py
+++ b/release/scripts/modules/bpy_extras/anim_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8-80 compliant>
+# <pep8 compliant>
__all__ = (
"bake_action",
@@ -52,7 +52,7 @@ def bake_action(frame_start,
:type do_pose: bool
:arg do_object: Bake objects.
:type do_object: bool
- :arg do_constraint_clear: Remove constraints.
+ :arg do_constraint_clear: Remove constraints (and do 'visual keying').
:type do_constraint_clear: bool
:arg do_clean: Remove redundant keyframes after baking.
:type do_clean: bool
@@ -65,61 +65,20 @@ def bake_action(frame_start,
"""
# -------------------------------------------------------------------------
- # Helper Functions
+ # Helper Functions and vars
- def pose_frame_info(obj):
- from mathutils import Matrix
+ def pose_frame_info(obj, do_visual_keying):
+ matrix = {}
+ for name, pbone in obj.pose.bones.items():
+ if do_visual_keying:
+ # Get the final transform of the bone in its own local space...
+ matrix[name] = obj.convert_space(pbone, pbone.matrix, 'POSE', 'LOCAL')
+ else:
+ matrix[name] = pbone.matrix_basis.copy()
+ return matrix
- info = {}
-
- pose = obj.pose
-
- pose_items = pose.bones.items()
-
- for name, pbone in pose_items:
- binfo = {}
- bone = pbone.bone
-
- binfo["parent"] = getattr(bone.parent, "name", None)
- binfo["bone"] = bone
- binfo["pbone"] = pbone
- binfo["matrix_local"] = bone.matrix_local.copy()
- try:
- binfo["matrix_local_inv"] = binfo["matrix_local"].inverted()
- except:
- binfo["matrix_local_inv"] = Matrix()
-
- binfo["matrix"] = bone.matrix.copy()
- binfo["matrix_pose"] = pbone.matrix.copy()
- try:
- binfo["matrix_pose_inv"] = binfo["matrix_pose"].inverted()
- except:
- binfo["matrix_pose_inv"] = Matrix()
-
- info[name] = binfo
-
- for name, pbone in pose_items:
- binfo = info[name]
- binfo_parent = binfo.get("parent", None)
- if binfo_parent:
- binfo_parent = info[binfo_parent]
-
- matrix = binfo["matrix_pose"]
- rest_matrix = binfo["matrix_local"]
-
- if binfo_parent:
- matrix = binfo_parent["matrix_pose_inv"] * matrix
- rest_matrix = binfo_parent["matrix_local_inv"] * rest_matrix
-
- binfo["matrix_key"] = rest_matrix.inverted() * matrix
-
- return info
-
- def obj_frame_info(obj):
- info = {}
- # parent = obj.parent
- info["matrix_key"] = obj.matrix_local.copy()
- return info
+ def obj_frame_info(obj, do_visual_keying):
+ return obj.matrix_local.copy() if do_visual_keying else obj.matrix_basis.copy()
# -------------------------------------------------------------------------
# Setup the Context
@@ -127,33 +86,30 @@ def bake_action(frame_start,
# TODO, pass data rather then grabbing from the context!
scene = bpy.context.scene
obj = bpy.context.object
- pose = obj.pose
frame_back = scene.frame_current
- if pose is None:
+ if obj.pose is None:
do_pose = False
- if do_pose is None and do_object is None:
+ if not (do_pose or do_object):
return None
pose_info = []
obj_info = []
+ options = {'INSERTKEY_NEEDED'}
+
frame_range = range(frame_start, frame_end + 1, frame_step)
# -------------------------------------------------------------------------
# Collect transformations
- # could speed this up by applying steps here too...
for f in frame_range:
scene.frame_set(f)
-
if do_pose:
- pose_info.append(pose_frame_info(obj))
+ pose_info.append(pose_frame_info(obj, do_constraint_clear))
if do_object:
- obj_info.append(obj_frame_info(obj))
-
- f += 1
+ obj_info.append(obj_frame_info(obj, do_constraint_clear))
# -------------------------------------------------------------------------
# Create action
@@ -164,57 +120,44 @@ def bake_action(frame_start,
action = bpy.data.actions.new("Action")
atd.action = action
- if do_pose:
- pose_items = pose.bones.items()
- else:
- pose_items = [] # skip
-
# -------------------------------------------------------------------------
# Apply transformations to action
# pose
- for name, pbone in (pose_items if do_pose else ()):
- if only_selected and not pbone.bone.select:
- continue
-
- if do_constraint_clear:
- while pbone.constraints:
- pbone.constraints.remove(pbone.constraints[0])
-
- # create compatible eulers
- euler_prev = None
-
- for f in frame_range:
- f_step = (f - frame_start) // frame_step
- matrix = pose_info[f_step][name]["matrix_key"]
-
- # pbone.location = matrix.to_translation()
- # pbone.rotation_quaternion = matrix.to_quaternion()
- pbone.matrix_basis = matrix
-
- pbone.keyframe_insert("location", -1, f, name)
-
- rotation_mode = pbone.rotation_mode
-
- if rotation_mode == 'QUATERNION':
- pbone.keyframe_insert("rotation_quaternion", -1, f, name)
- elif rotation_mode == 'AXIS_ANGLE':
- pbone.keyframe_insert("rotation_axis_angle", -1, f, name)
- else: # euler, XYZ, ZXY etc
-
- if euler_prev is not None:
- euler = pbone.rotation_euler.copy()
- euler.make_compatible(euler_prev)
- pbone.rotation_euler = euler
- euler_prev = euler
- del euler
-
- pbone.keyframe_insert("rotation_euler", -1, f, name)
-
- if euler_prev is None:
- euler_prev = pbone.rotation_euler.copy()
-
- pbone.keyframe_insert("scale", -1, f, name)
+ if do_pose:
+ for name, pbone in obj.pose.bones.items():
+ if only_selected and not pbone.bone.select:
+ continue
+
+ if do_constraint_clear:
+ while pbone.constraints:
+ pbone.constraints.remove(pbone.constraints[0])
+
+ # create compatible eulers
+ euler_prev = None
+
+ for (f, matrix) in zip(frame_range, pose_info):
+ pbone.matrix_basis = matrix[name].copy()
+
+ pbone.keyframe_insert("location", -1, f, name, options)
+
+ rotation_mode = pbone.rotation_mode
+ if rotation_mode == 'QUATERNION':
+ pbone.keyframe_insert("rotation_quaternion", -1, f, name, options)
+ elif rotation_mode == 'AXIS_ANGLE':
+ pbone.keyframe_insert("rotation_axis_angle", -1, f, name, options)
+ else: # euler, XYZ, ZXY etc
+ if euler_prev is not None:
+ euler = pbone.rotation_euler.copy()
+ euler.make_compatible(euler_prev)
+ pbone.rotation_euler = euler
+ euler_prev = euler
+ del euler
+ else:
+ euler_prev = pbone.rotation_euler.copy()
+ pbone.keyframe_insert("rotation_euler", -1, f, name, options)
+
+ pbone.keyframe_insert("scale", -1, f, name, options)
# object. TODO. multiple objects
if do_object:
@@ -225,18 +168,16 @@ def bake_action(frame_start,
# create compatible eulers
euler_prev = None
- for f in frame_range:
- matrix = obj_info[(f - frame_start) // frame_step]["matrix_key"]
- obj.matrix_local = matrix
+ for (f, matrix) in zip(frame_range, obj_info):
+ obj.matrix_basis = matrix[name]
- obj.keyframe_insert("location", -1, f)
+ obj.keyframe_insert("location", -1, f, options)
rotation_mode = obj.rotation_mode
-
if rotation_mode == 'QUATERNION':
- obj.keyframe_insert("rotation_quaternion", -1, f)
+ obj.keyframe_insert("rotation_quaternion", -1, f, options)
elif rotation_mode == 'AXIS_ANGLE':
- obj.keyframe_insert("rotation_axis_angle", -1, f)
+ obj.keyframe_insert("rotation_axis_angle", -1, f, options)
else: # euler, XYZ, ZXY etc
if euler_prev is not None:
euler = obj.rotation_euler.copy()
@@ -244,15 +185,11 @@ def bake_action(frame_start,
obj.rotation_euler = euler
euler_prev = euler
del euler
-
- obj.keyframe_insert("rotation_euler", -1, f)
-
- if euler_prev is None:
+ else:
euler_prev = obj.rotation_euler.copy()
+ obj.keyframe_insert("rotation_euler", -1, f, options)
- obj.keyframe_insert("scale", -1, f)
-
- scene.frame_set(frame_back)
+ obj.keyframe_insert("scale", -1, f, options)
# -------------------------------------------------------------------------
# Clean
@@ -271,4 +208,6 @@ def bake_action(frame_start,
else:
i += 1
+ scene.frame_set(frame_back)
+
return action
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 46731b8..4e1385c 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -26,7 +26,6 @@ __all__ = (
import bpy
-import mathutils
from bpy.props import BoolProperty, FloatVectorProperty
@@ -80,7 +79,7 @@ def add_object_align_init(context, operator):
rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
rotation.resize_4x4()
else:
- rotation = mathutils.Matrix()
+ rotation = Matrix()
# set the operator properties
if operator:
diff --git a/release/scripts/modules/bpy_restrict_state.py b/release/scripts/modules/bpy_restrict_state.py
new file mode 100644
index 0000000..21c6921
--- /dev/null
+++ b/release/scripts/modules/bpy_restrict_state.py
@@ -0,0 +1,57 @@
+# ##### 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 LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+"""
+This module contains RestrictBlend context manager.
+"""
+
+__all__ = (
+ "RestrictBlend",
+ )
+
+import bpy as _bpy
+
+class _RestrictContext():
+ __slots__ = ()
+ _real_data = _bpy.data
+ @property
+ def window_manager(self):
+ return self._real_data.window_managers[0]
+
+
+class _RestrictData():
+ __slots__ = ()
+
+
+_context_restrict = _RestrictContext()
+_data_restrict = _RestrictData()
+
+
+class RestrictBlend():
+ __slots__ = ("context", "data")
+ def __enter__(self):
+ self.data = _bpy.data
+ self.context = _bpy.context
+ _bpy.data = _data_restrict
+ _bpy.context = _context_restrict
+
+ def __exit__(self, type, value, traceback):
+ _bpy.data = self.data
+ _bpy.context = self.context
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index e42ae43..1c861aa 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -484,6 +484,15 @@ class Text(bpy_types.ID):
if cont.type == 'PYTHON']
)
+class NodeSocket(StructRNA): # , metaclass=RNAMeta
+ __slots__ = ()
+
+ @property
+ def links(self):
+ """List of node links from or to this socket"""
+ return tuple(link for link in self.id_data.links if link.from_socket == self or link.to_socket == self)
+
+
# values are module: [(cls, path, line), ...]
TypeMap = {}
@@ -664,6 +673,10 @@ class Panel(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()
+class UIList(StructRNA, _GenericUI, metaclass=RNAMeta):
+ __slots__ = ()
+
+
class Header(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()
diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py
index e21ccd0..08b60eb 100644
--- a/release/scripts/modules/rna_xml.py
+++ b/release/scripts/modules/rna_xml.py
@@ -265,7 +265,15 @@ def xml2rna(root_xml,
tp_name = 'ARRAY'
# print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type))
- setattr(value, attr, value_xml_coerce)
+ try:
+ setattr(value, attr, value_xml_coerce)
+ except ValueError:
+ # size mismatch
+ val = getattr(value, attr)
+ if len(val) < len(value_xml_coerce):
+ setattr(value, attr, value_xml_coerce[:len(val)])
+ else:
+ setattr(value, attr, list(value_xml_coerce) + list(val)[len(value_xml_coerce):])
# ---------------------------------------------------------------------
# Complex attributes
diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml
index 0a77aa1..18a3e53 100644
--- a/release/scripts/presets/interface_theme/back_to_black.xml
+++ b/release/scripts/presets/interface_theme/back_to_black.xml
@@ -220,16 +220,10 @@
blend="0.1">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#000000ff"
- show_header="FALSE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#222222"
- panel="#a5a5a57f"
wire="#888888"
lamp="#c1d40028"
speaker="#535353"
@@ -288,17 +282,23 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#00000057"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#262626"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#6d6d6d"
vertex="#ffffff"
@@ -331,10 +331,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +355,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#354d66"
- tiles="#343434"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#b1b1b1"
@@ -361,10 +367,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +413,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c3c3c3"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +457,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +503,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +541,23 @@
header="#000000"
header_text="#f3f3f3"
header_text_hi="#ffffff"
- button="#020202"
+ button="#02020242"
button_title="#bdbdbd"
button_text="#dddddd"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#000000"
title="#5d5d5d"
@@ -525,10 +566,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -550,10 +598,17 @@
header="#000000"
header_text="#b9b9b9"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#d8d8d8"
button_text="#cccccc"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +624,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -598,10 +660,17 @@
header="#000000"
header_text="#c7c7c7"
header_text_hi="#ffffff"
- button="#000000"
+ button="#0000002f"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +683,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#a5a5a5">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#070707"
title="#5d5d5d"
@@ -623,10 +692,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +718,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +743,17 @@
header="#000000"
header_text="#adadad"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +768,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -700,10 +797,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#000000"
+ button="#000000ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +836,17 @@
header="#000000"
header_text="#979797"
header_text_hi="#ffffff"
- button="#070707"
+ button="#070707ff"
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml
index 18ae307..5ad7c50 100644
--- a/release/scripts/presets/interface_theme/blender_24x.xml
+++ b/release/scripts/presets/interface_theme/blender_24x.xml
@@ -220,16 +220,10 @@
blend="0.5">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000019"
- show_header="FALSE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#5c5c5c"
- panel="#a5a5a5ff"
wire="#000000"
lamp="#00000028"
speaker="#000000"
@@ -288,17 +282,23 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b457"
button_title="#5a5a5a"
button_text="#5a5a5a"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#818181"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#707070"
vertex="#000000"
@@ -331,10 +331,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +355,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#a0a0d0"
- tiles="#b4b4b4"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#828282"
@@ -361,10 +367,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +413,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +457,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +503,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +541,23 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b442"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#b4b4b4"
title="#000000"
@@ -525,10 +566,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -550,10 +598,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +624,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -598,10 +660,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b42f"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +683,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#a5a5a5">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#b4b4b4"
title="#000000"
@@ -623,10 +692,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +718,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +743,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +768,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -700,10 +797,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +836,17 @@
header="#b4b4b4"
header_text="#000000"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml
index c10eb10..0daadcd 100644
--- a/release/scripts/presets/interface_theme/elsyiun.xml
+++ b/release/scripts/presets/interface_theme/elsyiun.xml
@@ -220,16 +220,10 @@
blend="0.5">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000019"
- show_header="FALSE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#585858"
- panel="#a5a5a57f"
wire="#000000"
lamp="#00000028"
speaker="#000000"
@@ -288,17 +282,23 @@
header="#3b3b3b"
header_text="#b9b9b9"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3b57"
button_title="#979797"
button_text="#979797"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#585858"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#707070"
vertex="#000000"
@@ -331,10 +331,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +355,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#755129"
- tiles="#3b3b3b"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#828282"
@@ -361,10 +367,17 @@
header="#3b3b3b"
header_text="#8b8b8b"
header_text_hi="#ffffff"
- button="#303030"
+ button="#303030ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +413,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +457,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#aaaaaa"
+ button="#aaaaaaff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +503,17 @@
header="#303030"
header_text="#000000"
header_text_hi="#ffffff"
- button="#303030"
+ button="#303030ff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +541,23 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3b42"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#3b3b3b"
title="#979797"
@@ -525,10 +566,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#b8b8b8"
button_text="#b8b8b8"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -550,10 +598,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +624,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -598,10 +660,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3b2f"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +683,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#3b3b3b">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#3b3b3b"
title="#000000"
@@ -623,10 +692,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#8b8b8b"
button_text="#8b8b8b"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +718,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +743,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#000000"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#000000">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +768,17 @@
header="#3b3b3b"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -700,10 +797,17 @@
header="#303030"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +836,17 @@
header="#313131"
header_text="#000000"
header_text_hi="#ffffff"
- button="#3b3b3b"
+ button="#3b3b3bff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml
index ad514bb..932bd52 100644
--- a/release/scripts/presets/interface_theme/hexagon.xml
+++ b/release/scripts/presets/interface_theme/hexagon.xml
@@ -220,16 +220,10 @@
blend="0.5">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000019"
- show_header="TRUE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#5e5e83"
- panel="#a5a5a5ff"
wire="#000000"
lamp="#00000028"
speaker="#000000"
@@ -288,17 +282,23 @@
header="#646875"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717f57"
button_title="#eaeaea"
button_text="#d7d7d7"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#58587c"
- panel="#ffffff"
window_sliders="#969696"
channels_region="#707070"
vertex="#000000"
@@ -331,10 +331,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +355,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#69a5be"
- tiles="#5c606c"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#859cb9"
@@ -361,10 +367,17 @@
header="#5c606c"
header_text="#dddddd"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#d7d7d7"
button_text="#d7d7d7"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +413,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +457,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +503,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#eeeeee"
button_text="#eeeeee"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +541,23 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#64687542"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#828282">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#646875"
title="#ffffff"
@@ -525,10 +566,17 @@
header="#646875"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -550,10 +598,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +624,17 @@
header="#565863"
header_text="#000000"
header_text_hi="#ffffff"
- button="#5a5e6a"
+ button="#5a5e6aff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -598,10 +660,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#6468752f"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +683,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#a5a5a5">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#7c7e88"
title="#000000"
@@ -623,10 +692,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#d7d7d7"
button_text="#d7d7d7"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +718,17 @@
header="#6c717f"
header_text="#000000"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +743,17 @@
header="#646875"
header_text="#dddddd"
header_text_hi="#ffffff"
- button="#b4b4b4"
+ button="#b4b4b4ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +768,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -700,10 +797,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#6c717f"
+ button="#6c717fff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +836,17 @@
header="#5c606c"
header_text="#000000"
header_text_hi="#ffffff"
- button="#646875"
+ button="#646875ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000019"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
index 8f4a42b..8be83cb 100644
--- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
+++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
@@ -220,16 +220,10 @@
blend="0.1">
</ThemeWidgetStateColors>
</wcol_state>
- <panel>
- <ThemePanelColors header="#00000000"
- show_header="TRUE">
- </ThemePanelColors>
- </panel>
</ThemeUserInterface>
</user_interface>
<view_3d>
<ThemeView3D grid="#3c3b37"
- panel="#a5a5a57f"
wire="#93237f"
lamp="#ffffff34"
speaker="#93237f"
@@ -288,17 +282,23 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b3757"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeView3D>
</view_3d>
<graph_editor>
<ThemeGraphEditor grid="#3c3b37"
- panel="#ffffff"
window_sliders="#95948f"
channels_region="#707070"
vertex="#ffffff"
@@ -331,10 +331,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -348,7 +355,6 @@
</graph_editor>
<file_browser>
<ThemeFileBrowser selected_file="#6b395a"
- tiles="#3c3b37"
scrollbar="#a0a0a0"
scroll_handle="#7f7070"
active_file="#eeedeb"
@@ -361,10 +367,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#727272"
+ button="#727272ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -400,10 +413,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -437,10 +457,17 @@
header="#464541"
header_text="#cacaca"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -476,10 +503,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#b1b1b1"
button_text="#b9b9b9"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeImageEditor>
@@ -507,16 +541,23 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b3742"
button_title="#acacac"
button_text="#acacac"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeSequenceEditor>
</sequence_editor>
<properties>
- <ThemeProperties panel="#3c3b37">
+ <ThemeProperties>
<space>
<ThemeSpaceGeneric back="#3c3b37"
title="#acacac"
@@ -525,10 +566,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeProperties>
@@ -550,10 +598,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#191919"
+ button="#191919ff"
button_title="#64645e"
button_text="#95948f"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTextEditor>
@@ -569,10 +624,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#9c9c9c"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeTimeline>
@@ -598,10 +660,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#353430"
+ button="#3534302f"
button_title="#acacac"
button_text="#acacac"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
@@ -614,7 +683,7 @@
</ThemeNodeEditor>
</node_editor>
<logic_editor>
- <ThemeLogicEditor panel="#acacac">
+ <ThemeLogicEditor>
<space>
<ThemeSpaceGeneric back="#29001b"
title="#000000"
@@ -623,10 +692,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#353430"
+ button="#353430ff"
button_title="#7d7d7d"
button_text="#acacac"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeLogicEditor>
@@ -642,10 +718,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#f47421">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeOutliner>
@@ -660,10 +743,17 @@
header="#464541"
header_text="#ffffff"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#eeedeb"
button_text="#eeedeb"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeInfo>
@@ -678,10 +768,17 @@
header="#3c3b37"
header_text="#d3d2cd"
header_text_hi="#ffffff"
- button="#696965"
+ button="#696965ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeUserPreferences>
@@ -700,10 +797,17 @@
header="#464541"
header_text="#acacac"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#000000"
button_text="#000000"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
</ThemeConsole>
@@ -732,10 +836,17 @@
header="#464541"
header_text="#9c9c9c"
header_text_hi="#ffffff"
- button="#3c3b37"
+ button="#3c3b37ff"
button_title="#9c9c9c"
button_text="#ffffff"
button_text_hi="#ffffff">
+ <panelcolors>
+ <ThemePanelColors header="#00000000"
+ back="#72727280"
+ show_header="TRUE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
</ThemeSpaceGeneric>
</space>
<space_list>
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 552247f..63e796e 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -19,7 +19,6 @@
# <pep8-80 compliant>
import bpy
from bpy.types import Operator
-import mathutils
from bpy.props import (FloatProperty,
IntProperty,
@@ -31,9 +30,7 @@ from bpy_extras import object_utils
def add_torus(major_rad, minor_rad, major_seg, minor_seg):
from math import cos, sin, pi
-
- Vector = mathutils.Vector
- Quaternion = mathutils.Quaternion
+ from mathutils import Vector, Quaternion
PI_2 = pi * 2.0
z_axis = 0.0, 0.0, 1.0
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index 902c700..e34e9a9 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -187,17 +187,20 @@ class BakeAction(Operator):
)
only_selected = BoolProperty(
name="Only Selected",
+ description="Only key selected object/bones",
default=True,
)
clear_constraints = BoolProperty(
name="Clear Constraints",
+ description="Remove all constraints from keyed object/bones, and do 'visual' keying",
default=False,
)
bake_types = EnumProperty(
name="Bake Data",
+ description="Which data's transformations to bake",
options={'ENUM_FLAG'},
- items=(('POSE', "Pose", ""),
- ('OBJECT', "Object", ""),
+ items=(('POSE', "Pose", "Bake bones transformations"),
+ ('OBJECT', "Object", "Bake object transformations"),
),
default={'POSE'},
)
@@ -208,12 +211,12 @@ class BakeAction(Operator):
action = anim_utils.bake_action(self.frame_start,
self.frame_end,
- self.step,
- self.only_selected,
- 'POSE' in self.bake_types,
- 'OBJECT' in self.bake_types,
- self.clear_constraints,
- True,
+ frame_step=self.step,
+ only_selected=self.only_selected,
+ do_pose='POSE' in self.bake_types,
+ do_object='OBJECT' in self.bake_types,
+ do_constraint_clear=self.clear_constraints,
+ do_clean=True,
)
if action is None:
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index fb264cb..39e00f9 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -20,7 +20,83 @@
import bpy
from bpy.types import Operator
-from bpy.props import EnumProperty
+from bpy.props import BoolProperty, EnumProperty, StringProperty
+
+# Base class for node 'Add' operators
+class NodeAddOperator():
+ @staticmethod
+ def store_mouse_cursor(context, event):
+ space = context.space_data
+ v2d = context.region.view2d
+
+ # convert mouse position to the View2D for later node placement
+ space.cursor_location = v2d.region_to_view(event.mouse_region_x,
+ event.mouse_region_y)
+
+ def create_node(self, context, node_type):
+ space = context.space_data
+ tree = space.edit_tree
+
+ # select only the new node
+ for n in tree.nodes:
+ n.select = False
+
+ node = tree.nodes.new(type=node_type)
+
+ node.select = True
+ tree.nodes.active = node
+ node.location = space.cursor_location
+ return node
+
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ # needs active node editor and a tree to add nodes to
+ return (space.type == 'NODE_EDITOR' and space.edit_tree)
+
+ # Default invoke stores the mouse position to place the node correctly
+ def invoke(self, context, event):
+ self.store_mouse_cursor(context, event)
+ return self.execute(context)
+
+
+# Simple basic operator for adding a node
+class NODE_OT_add_node(NodeAddOperator, Operator):
+ '''Add a node to the active tree'''
+ bl_idname = "node.add_node"
+ bl_label = "Add Node"
+
+ type = StringProperty(
+ name="Node Type",
+ description="Node type",
+ )
+ # optional group tree parameter for group nodes
+ group_tree = StringProperty(
+ name="Group tree",
+ description="Group node tree name",
+ )
+ use_transform = BoolProperty(
+ name="Use Transform",
+ description="Start transform operator after inserting the node",
+ default = False,
+ )
+ def execute(self, context):
+ node = self.create_node(context, self.type)
+
+ # set the node group tree of a group node
+ if self.properties.is_property_set('group_tree'):
+ node.node_tree = bpy.data.node_groups[self.group_tree]
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ self.store_mouse_cursor(context, event)
+ result = self.execute(context)
+ if self.use_transform and ('FINISHED' in result):
+ return bpy.ops.transform.translate('INVOKE_DEFAULT')
+ else:
+ return result
+
# XXX These node item lists should actually be generated by a callback at
# operator execution time (see node_type_items below),
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 9e449f3..d6a0e30 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -110,6 +110,12 @@ class SelectCamera(Operator):
bl_label = "Select Camera"
bl_options = {'REGISTER', 'UNDO'}
+ extend = BoolProperty(
+ name="Extend",
+ description="Extend the selection",
+ default=False
+ )
+
def execute(self, context):
scene = context.scene
view = context.space_data
@@ -123,6 +129,8 @@ class SelectCamera(Operator):
elif camera.name not in scene.objects:
self.report({'WARNING'}, "Active camera is not in this scene")
else:
+ if not self.extend:
+ bpy.ops.object.select_all(action='DESELECT')
context.scene.objects.active = camera
camera.select = True
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index 727c4ad..7b6013f 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -26,6 +26,7 @@ from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
+
import bmesh
me = obj.data
# script will fail without UVs
@@ -46,12 +47,17 @@ def extend(obj, operator, EXTEND_MODE):
faces = [f for f in bm.faces if f.select and len(f.verts) == 4]
- for f in faces:
- f.tag = False
- f_act.tag = True
-
-
# our own local walker
+ def walk_face_init(faces, f_act):
+ # first tag all faces True (so we dont uvmap them)
+ for f in bm.faces:
+ f.tag = True
+ # then tag faces arg False
+ for f in faces:
+ f.tag = False
+ # tag the active face True since we begin there
+ f_act.tag = True
+
def walk_face(f):
# all faces in this list must be tagged
f.tag = True
@@ -73,6 +79,30 @@ def extend(obj, operator, EXTEND_MODE):
faces_a, faces_b = faces_b, faces_a
faces_b.clear()
+ def walk_edgeloop(l):
+ """
+ Could make this a generic function
+ """
+ e_first = l.edge
+ e = None
+ while True:
+ e = l.edge
+ yield e
+
+ # don't step past non-manifold edges
+ if e.is_manifold:
+ # welk around the quad and then onto the next face
+ l = l.link_loop_radial_next
+ if len(l.face.verts) == 4:
+ l = l.link_loop_next.link_loop_next
+ if l.edge is e_first:
+ break
+ else:
+ break
+ else:
+ break
+
+
def extrapolate_uv(fac,
l_a_outer, l_a_inner,
l_b_outer, l_b_inner):
@@ -119,7 +149,9 @@ def extend(obj, operator, EXTEND_MODE):
l_a_uv = [l[uv_act].uv for l in l_a]
l_b_uv = [l[uv_act].uv for l in l_b]
- if EXTEND_MODE == 'LENGTH':
+ if EXTEND_MODE == 'LENGTH_AVERAGE':
+ fac = edge_lengths[l_b[2].edge.index][0] / edge_lengths[l_a[1].edge.index][0]
+ elif EXTEND_MODE == 'LENGTH':
a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co
@@ -140,6 +172,40 @@ def extend(obj, operator, EXTEND_MODE):
l_a_uv[2], l_a_uv[1],
l_b_uv[2], l_b_uv[1])
+ # -------------------------------------------
+ # Calculate average length per loop if needed
+
+ if EXTEND_MODE == 'LENGTH_AVERAGE':
+ bm.edges.index_update()
+ edge_lengths = [None] * len(bm.edges)
+
+ for f in faces:
+ # we know its a quad
+ l_quad = f.loops[:]
+ l_pair_a = (l_quad[0], l_quad[2])
+ l_pair_b = (l_quad[1], l_quad[3])
+
+ for l_pair in (l_pair_a, l_pair_b):
+ if edge_lengths[l_pair[0].edge.index] is None:
+
+ edge_length_store = [-1.0]
+ edge_length_accum = 0.0
+ edge_length_total = 0
+
+ for l in l_pair:
+ if edge_lengths[l.edge.index] is None:
+ for e in walk_edgeloop(l):
+ if edge_lengths[e.index] is None:
+ edge_lengths[e.index] = edge_length_store
+ edge_length_accum += e.calc_length()
+ edge_length_total += 1
+
+ edge_length_store[0] = edge_length_accum / edge_length_total
+
+ # done with average length
+ # ------------------------
+
+ walk_face_init(faces, f_act)
for f_triple in walk_face(f_act):
apply_uv(*f_triple)
@@ -162,8 +228,10 @@ class FollowActiveQuads(Operator):
name="Edge Length Mode",
description="Method to space UV edge loops",
items=(('EVEN', "Even", "Space all UVs evenly"),
- ('LENGTH', "Length", "Average space UVs edge length of each loop")),
- default='LENGTH',
+ ('LENGTH', "Length", "Average space UVs edge length of each loop"),
+ ('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
+ ),
+ default='LENGTH_AVERAGE',
)
@classmethod
diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
index bfbde2f..e2a820b 100644
--- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py
+++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
@@ -127,13 +127,14 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
col[0] = tone * col[0]
col[1] = tone * col[1]
col[2] = tone * col[2]
-
+ me.update()
return {'FINISHED'}
import bpy
from bpy.types import Operator
from bpy.props import FloatProperty, IntProperty, BoolProperty
+from math import pi
class VertexPaintDirt(Operator):
@@ -156,14 +157,16 @@ class VertexPaintDirt(Operator):
clean_angle = FloatProperty(
name="Highlight Angle",
description="Less than 90 limits the angle used in the tonal range",
- min=0.0, max=180.0,
- default=180.0,
+ min=0.0, max=pi,
+ default=pi,
+ unit="ROTATION",
)
dirt_angle = FloatProperty(
name="Dirt Angle",
description="Less than 90 limits the angle used in the tonal range",
- min=0.0, max=180.0,
+ min=0.0, max=pi,
default=0.0,
+ unit="ROTATION",
)
dirt_only = BoolProperty(
name="Dirt Only",
@@ -171,20 +174,21 @@ class VertexPaintDirt(Operator):
default=False,
)
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.type == 'MESH')
+
def execute(self, context):
import time
from math import radians
- obj = context.object
-
- if not obj or obj.type != 'MESH':
- self.report({'ERROR'}, "Error, no active mesh object, aborting")
- return {'CANCELLED'}
+ obj = context.object
mesh = obj.data
t = time.time()
- ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, radians(self.dirt_angle), radians(self.clean_angle), self.dirt_only)
+ ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, self.dirt_angle, self.clean_angle, self.dirt_only)
print('Dirt calculated in %.6f' % (time.time() - t))
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 105b532..00cc763 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -44,7 +44,7 @@ class MESH_OT_delete_edgeloop(Operator):
mesh = context.object.data
use_mirror_x = mesh.use_mirror_x
mesh.use_mirror_x = False
- if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0):
+ if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0, correct_uv=True):
bpy.ops.mesh.select_more()
bpy.ops.mesh.remove_doubles()
ret = {'FINISHED'}
@@ -1620,7 +1620,7 @@ class WM_OT_addon_disable(Operator):
class WM_OT_theme_install(Operator):
- "Install a theme"
+ "Load and apply a Blender XML theme file"
bl_idname = "wm.theme_install"
bl_label = "Install Theme..."
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index e4be84d..aa1a8a9 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -132,3 +132,9 @@ def register():
def unregister():
bpy.utils.unregister_module(__name__)
+
+# Define a default UIList, when a list does not need any custom drawing...
+class UI_UL_list(bpy.types.UIList):
+ pass
+
+bpy.utils.register_class(UI_UL_list)
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 845beb0..1643210 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -124,7 +124,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
rows = 2
if group:
rows = 5
- row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
+ row.template_list("UI_UL_list", "", pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
col = row.column(align=True)
col.active = (ob.proxy is None)
@@ -184,7 +184,7 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
if poselib:
# list of poses in pose library
row = layout.row()
- row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
+ row.template_list("UI_UL_list", "", poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
# column of operators for active pose
# - goes beside list
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index fdaee6b..a8954a1 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -170,6 +170,8 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
if ob and pchan:
col.label(text="Bone Group:")
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="")
+ col.label(text="Object Children:")
+ col.prop(bone, "use_relative_parent")
col = split.column()
col.label(text="Parent:")
@@ -181,11 +183,11 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
sub = col.column()
sub.active = (bone.parent is not None)
sub.prop(bone, "use_connect")
- sub.prop(bone, "use_inherit_rotation", text="Inherit Rotation")
- sub.prop(bone, "use_inherit_scale", text="Inherit Scale")
+ sub.prop(bone, "use_inherit_rotation")
+ sub.prop(bone, "use_inherit_scale")
sub = col.column()
sub.active = (not bone.parent or not bone.use_connect)
- sub.prop(bone, "use_local_location", text="Local Location")
+ sub.prop(bone, "use_local_location")
class BONE_PT_display(BoneButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 25cecc9..c74560e 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -80,7 +80,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
row = col.row()
if cam.lens_unit == 'MILLIMETERS':
row.prop(cam, "lens")
- elif cam.lens_unit == 'DEGREES':
+ elif cam.lens_unit == 'FOV':
row.prop(cam, "angle")
row.prop(cam, "lens_unit", text="")
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 6125540..5fdb71b 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
@@ -36,8 +36,8 @@ class MESH_MT_vertex_group_specials(Menu):
layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT')
layout.operator("object.vertex_group_remove", icon='X', text="Delete All").all = True
layout.separator()
- layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'SELECT'
- layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'DESELECT'
+ layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'LOCK'
+ layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'UNLOCK'
layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Invert All").action = 'INVERT'
@@ -54,6 +54,53 @@ class MESH_MT_shape_key_specials(Menu):
layout.operator("object.shape_key_add", icon='ZOOMIN', text="New Shape From Mix").from_mix = True
+class MESH_UL_vgroups(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.VertexGroup)
+ vgroup = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(vgroup.name, icon_value=icon)
+ icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
+ layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
+class MESH_UL_shape_keys(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.ShapeKey)
+ obj = active_data
+ key = data
+ key_block = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ split = layout.split(0.66, False)
+ split.label(item.name, icon_value=icon)
+ row = split.row(True)
+ if key_block.mute or (obj.mode == 'EDIT' and not (obj.use_shape_key_edit_mode and obj.type == 'MESH')):
+ row.active = False
+ if not item.relative_key or index > 0:
+ row.prop(key_block, "value", text="", emboss=False)
+ else:
+ row.label("")
+ row.prop(key_block, "mute", text="", emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
+class MESH_UL_uvmaps_vcols(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, (bpy.types.MeshTexturePolyLayer, bpy.types.MeshLoopColorLayer))
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(item.name, icon_value=icon)
+ icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON'
+ layout.prop(item, "active_render", text="", icon=icon, emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
class MeshButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -144,7 +191,8 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
rows = 5
row = layout.row()
- row.template_list(ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
+ row.template_list("MESH_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
+
col = row.column(align=True)
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
@@ -202,7 +250,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
rows = 2
if kb:
rows = 5
- row.template_list(key, "key_blocks", ob, "active_shape_key_index", rows=rows)
+ row.template_list("MESH_UL_shape_keys", "", key, "key_blocks", ob, "active_shape_key_index", rows=rows)
col = row.column()
@@ -282,7 +330,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(me, "uv_textures", me.uv_textures, "active_index", rows=2)
+ col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
@@ -305,7 +353,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
+ col.template_list("MESH_UL_uvmaps_vcols", "vcols", me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
@@ -324,17 +372,20 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- # me = context.mesh
+ obj = context.object
+ me = context.mesh
col = layout.column()
- # sticky has no UI access since 2.49 - we may remove
- '''
- row = col.row(align=True)
- row.operator("mesh.customdata_create_sticky")
- row.operator("mesh.customdata_clear_sticky", icon='X')
- '''
+
col.operator("mesh.customdata_clear_mask", icon='X')
col.operator("mesh.customdata_clear_skin", icon='X')
+ col = layout.column()
+
+ col.enabled = (obj.mode != 'EDIT')
+ col.prop(me, "use_customdata_vertex_bevel")
+ col.prop(me, "use_customdata_edge_bevel")
+ col.prop(me, "use_customdata_edge_crease")
+
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 62461d8..df29f18 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -489,11 +489,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "time")
- col.prop(md, "resolution")
+ col.prop(md, "depth")
+ col.prop(md, "random_seed")
col = split.column()
+ col.prop(md, "resolution")
+ col.prop(md, "size")
col.prop(md, "spatial_size")
- col.prop(md, "depth")
layout.label("Waves:")
@@ -534,7 +536,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
if md.is_cached:
layout.operator("object.ocean_bake", text="Free Bake").free = True
else:
- layout.operator("object.ocean_bake")
+ layout.operator("object.ocean_bake").free = False
split = layout.split()
split.enabled = not md.is_cached
@@ -547,7 +549,15 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Cache path:")
col.prop(md, "filepath", text="")
- #col.prop(md, "bake_foam_fade")
+ split = layout.split()
+ split.enabled = not md.is_cached
+
+ col = split.column()
+ col.active = md.use_foam
+ col.prop(md, "bake_foam_fade")
+
+ col = split.column()
+
def PARTICLE_INSTANCE(self, layout, ob, md):
layout.prop(md, "object")
@@ -1032,5 +1042,47 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def TRIANGULATE(self, layout, ob, md):
layout.prop(md, "use_beauty")
+ def UV_WARP(self, layout, ob, md):
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "center");
+
+ col = split.column()
+ col.label(text="UV Axis:")
+ col.prop(md, "axis_u", text="");
+ col.prop(md, "axis_v", text="");
+
+ split = layout.split()
+ col = split.column()
+ col.label(text="From:")
+ col.prop(md, "object_from", text="")
+
+ col = split.column()
+ col.label(text="To:")
+ col.prop(md, "object_to", text="")
+
+ split = layout.split()
+ col = split.column()
+ obj = md.object_from
+ if obj and obj.type == 'ARMATURE':
+ col.label(text="Bone:")
+ col.prop_search(md, "bone_from", obj.data, "bones", text="")
+
+ col = split.column()
+ obj = md.object_to
+ if obj and obj.type == 'ARMATURE':
+ col.label(text="Bone:")
+ col.prop_search(md, "bone_to", obj.data, "bones", text="")
+
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Vertex Group:")
+ col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+ col = split.column()
+ col.label(text="UV Map:")
+ col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index bf0c9eb..58b6aa6 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -402,14 +402,19 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
layout = self.layout
gs = context.scene.game_settings
-
- row = layout.row()
- row.prop(gs, "use_frame_rate")
- row.prop(gs, "restrict_animation_updates")
-
+ col = layout.column()
+ row = col.row()
+ col = row.column()
+ col.prop(gs, "use_frame_rate")
+ col.prop(gs, "restrict_animation_updates")
+ col.prop(gs, "use_material_caching")
+ col = row.column()
+ col.prop(gs, "use_display_lists")
+ col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'
+
row = layout.row()
- row.prop(gs, "use_display_lists")
-
+ row.prop(gs, "raster_storage")
+
row = layout.row()
row.label("Exit Key")
row.prop(gs, "exit_key", text="", event=True)
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index 208b0a6..9861db3 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -22,7 +22,24 @@
# menus are referenced `as is`
import bpy
-from bpy.types import Menu
+from bpy.types import Menu, UIList
+
+
+class MASK_UL_layers(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MaskLayer)
+ mask = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ split = layout.split()
+ split.label(mask.name, icon_value=icon)
+ row = split.row(align=True)
+ row.prop(mask, "alpha", text="", emboss=False)
+ row.prop(mask, "hide", text="", emboss=False)
+ row.prop(mask, "hide_select", text="", emboss=False)
+ row.prop(mask, "hide_render", text="", emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
class MASK_PT_mask:
@@ -69,8 +86,7 @@ class MASK_PT_layers:
rows = 5 if active_layer else 2
row = layout.row()
- row.template_list(mask, "layers",
- mask, "active_layer_index", rows=rows)
+ row.template_list("MASK_UL_layers", "", mask, "layers", mask, "active_layer_index", rows=rows)
sub = row.column(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 951644d..7e18cf8 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
@@ -69,6 +69,25 @@ class MATERIAL_MT_specials(Menu):
layout.operator("material.paste", icon='PASTEDOWN')
+class MATERIAL_UL_matslots(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MaterialSlot)
+ ob = data
+ slot = item
+ ma = slot.material
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(ma.name if ma else "", icon_value=icon)
+ if ma and not context.scene.render.use_shading_nodes:
+ manode = ma.active_node_material
+ if manode:
+ layout.label("Node %s" % manode.name, icon_value=layout.icon(manode))
+ elif ma.use_nodes:
+ layout.label("Node <none>")
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
class MaterialButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -104,7 +123,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
+ row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=2)
col = row.column(align=True)
col.operator("object.material_slot_add", icon='ZOOMIN', text="")
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 8a668b5..9518074 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -289,6 +289,9 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
row.active = ((ob.parent is not None) and (ob.use_slow_parent))
row.prop(ob, "slow_parent_offset", text="Offset")
+ layout.prop(ob, "extra_recalc_object")
+ layout.prop(ob, "extra_recalc_data")
+
from bl_ui.properties_animviz import (MotionPathButtonsPanel,
OnionSkinButtonsPanel)
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 3f672d2..90dcf59 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -96,7 +96,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2)
+ row.template_list("UI_UL_list", "", ob, "particle_systems", ob.particle_systems, "active_index", rows=2)
col = row.column(align=True)
col.operator("object.particle_system_add", icon='ZOOMIN', text="")
@@ -490,11 +490,13 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
col.prop(part, "integrator", text="")
col.prop(part, "timestep")
sub = col.row()
- if part.adaptive_subframes:
- sub.prop(part, "courant_target", text="Threshold")
- else:
- sub.prop(part, "subframes")
- sub.prop(part, "adaptive_subframes", text="")
+ sub.prop(part, "subframes")
+ supports_courant = part.physics_type == 'FLUID'
+ subsub = sub.row()
+ subsub.enabled = supports_courant
+ subsub.prop(part, "adaptive_subframes", text="")
+ if supports_courant and part.adaptive_subframes:
+ col.prop(part, "courant_target", text="Threshold")
row = layout.row()
row.prop(part, "use_size_deflect")
@@ -504,6 +506,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
fluid = part.fluid
split = layout.split()
+ sub = split.row()
+ sub.prop(fluid, "solver", expand=True)
+
+ split = layout.split()
col = split.column()
col.label(text="Fluid properties:")
@@ -514,13 +520,14 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
col = split.column()
col.label(text="Advanced:")
- sub = col.row()
- sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
- sub.prop(fluid, "factor_repulsion", text="")
+ if fluid.solver == 'DDR':
+ sub = col.row()
+ sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
+ sub.prop(fluid, "factor_repulsion", text="")
- sub = col.row()
- sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
- sub.prop(fluid, "factor_stiff_viscosity", text="")
+ sub = col.row()
+ sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
+ sub.prop(fluid, "factor_stiff_viscosity", text="")
sub = col.row()
sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
@@ -530,27 +537,37 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
sub.prop(fluid, "rest_density", slider=fluid.factor_density)
sub.prop(fluid, "factor_density", text="")
- split = layout.split()
-
- col = split.column()
- col.label(text="Springs:")
- col.prop(fluid, "spring_force", text="Force")
- col.prop(fluid, "use_viscoelastic_springs")
- sub = col.column(align=True)
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "yield_ratio", slider=True)
- sub.prop(fluid, "plasticity", slider=True)
-
- col = split.column()
- col.label(text="Advanced:")
- sub = col.row()
- sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
- sub.prop(fluid, "factor_rest_length", text="")
- col.label(text="")
- sub = col.column()
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "use_initial_rest_length")
- sub.prop(fluid, "spring_frames", text="Frames")
+ if fluid.solver == 'CLASSICAL':
+ # With the classical solver, it is possible to calculate the
+ # spacing between particles when the fluid is at rest. This
+ # makes it easier to set stable initial conditions.
+ particle_volume = part.mass / fluid.rest_density
+ spacing = pow(particle_volume, 1/3)
+ sub = col.row()
+ sub.label(text="Spacing: %g" % spacing)
+
+ elif fluid.solver == 'DDR':
+ split = layout.split()
+
+ col = split.column()
+ col.label(text="Springs:")
+ col.prop(fluid, "spring_force", text="Force")
+ col.prop(fluid, "use_viscoelastic_springs")
+ sub = col.column(align=True)
+ sub.active = fluid.use_viscoelastic_springs
+ sub.prop(fluid, "yield_ratio", slider=True)
+ sub.prop(fluid, "plasticity", slider=True)
+
+ col = split.column()
+ col.label(text="Advanced:")
+ sub = col.row()
+ sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
+ sub.prop(fluid, "factor_rest_length", text="")
+ col.label(text="")
+ sub = col.column()
+ sub.active = fluid.use_viscoelastic_springs
+ sub.prop(fluid, "use_initial_rest_length")
+ sub.prop(fluid, "spring_frames", text="Frames")
elif part.physics_type == 'KEYED':
split = layout.split()
@@ -619,7 +636,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
layout.label(text="Fluid interaction:")
row = layout.row()
- row.template_list(psys, "targets", psys, "active_particle_target_index")
+ row.template_list("UI_UL_list", "", psys, "targets", psys, "active_particle_target_index")
col = row.column()
sub = col.row()
@@ -685,7 +702,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
# Currently boids can only use the first state so these are commented out for now.
#row = layout.row()
- #row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
+ #row.template_list("UI_UL_list", "", boids, "states", boids, "active_boid_state_index", compact="True")
#col = row.row()
#sub = col.row(align=True)
#sub.operator("boid.state_add", icon='ZOOMIN', text="")
@@ -706,7 +723,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
row.label(text="")
row = layout.row()
- row.template_list(state, "rules", state, "active_boid_rule_index")
+ row.template_list("UI_UL_list", "", state, "rules", state, "active_boid_rule_index")
col = row.column()
sub = col.row()
@@ -869,7 +886,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
if part.use_group_count and not part.use_whole_group:
row = layout.row()
- row.template_list(part, "dupli_weights", part, "active_dupliweight_index")
+ row.template_list("UI_UL_list", "", part, "dupli_weights", part, "active_dupliweight_index")
col = row.column()
sub = col.row()
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 405e877..b70ff32 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -85,7 +85,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
layout.context_pointer_set("point_cache", cache)
row = layout.row()
- row.template_list(cache, "point_caches", cache.point_caches, "active_index", rows=2)
+ row.template_list("UI_UL_list", "", cache, "point_caches", cache.point_caches, "active_index", rows=2)
col = row.column(align=True)
col.operator("ptcache.add", icon='ZOOMIN', text="")
col.operator("ptcache.remove", icon='ZOOMOUT', text="")
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
index 1df2936..9393852 100644
--- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
@@ -18,13 +18,34 @@
# <pep8 compliant>
import bpy
-from bpy.types import Panel
+from bpy.types import Panel, UIList
from bl_ui.properties_physics_common import (point_cache_ui,
effector_weights_ui,
)
+class PHYSICS_UL_dynapaint_surfaces(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.DynamicPaintSurface)
+ surf = item
+ sticon = layout.enum_item_icon(surf, "surface_type", surf.surface_type)
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ row = layout.row(align=True)
+ row.label(text="", icon_value=icon)
+ row.label(text=surf.name, icon_value=sticon)
+ row = layout.row(align=True)
+ if surf.use_color_preview:
+ row.prop(surf, "show_preview", text="", emboss=False,
+ icon='RESTRICT_VIEW_OFF' if surf.show_preview else 'RESTRICT_VIEW_ON')
+ row.prop(surf, "is_active", text="")
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ row = layout.row(align=True)
+ row.label(text="", icon_value=icon)
+ row.label(text="", icon_value=sticon)
+
+
class PhysicButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -58,7 +79,8 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
surface = canvas.canvas_surfaces.active
row = layout.row()
- row.template_list(canvas, "canvas_surfaces", canvas.canvas_surfaces, "active_index", rows=2)
+ row.template_list("PHYSICS_UL_dynapaint_surfaces", "", canvas, "canvas_surfaces",
+ canvas.canvas_surfaces, "active_index", rows=2)
col = row.column(align=True)
col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 9814dd7..03b3d41 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -1,4 +1,5 @@
# ##### 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
@@ -18,7 +19,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
class RENDER_MT_presets(Menu):
@@ -42,6 +43,23 @@ class RENDER_MT_framerate_presets(Menu):
draw = Menu.draw_preset
+class RENDER_UL_renderlayers(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.SceneRenderLayer)
+ layer = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(layer.name, icon_value=icon)
+ layout.prop(layer, "use", text="", index=index)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+# else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) {
+# uiItemL(sub, name, icon);
+# uiBlockSetEmboss(block, UI_EMBOSS);
+# uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "use", 0, 0, 0, 0, 0, NULL);
+# }
+
class RenderButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -83,7 +101,7 @@ class RENDER_PT_layers(RenderButtonsPanel, Panel):
rd = scene.render
row = layout.row()
- row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
+ row.template_list("RENDER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
@@ -573,7 +591,7 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
layout.prop(rd, "bake_type")
multires_bake = False
- if rd.bake_type in ['NORMALS', 'DISPLACEMENT']:
+ if rd.bake_type in ['NORMALS', 'DISPLACEMENT', 'AO']:
layout.prop(rd, "use_bake_multires")
multires_bake = rd.use_bake_multires
@@ -591,9 +609,12 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
split = layout.split()
col = split.column()
- col.prop(rd, "use_bake_clear")
- col.prop(rd, "bake_margin")
- col.prop(rd, "bake_quad_split", text="Split")
+ col.prop(rd, "use_bake_to_vertex_color")
+ sub = col.column()
+ sub.active = not rd.use_bake_to_vertex_color
+ sub.prop(rd, "use_bake_clear")
+ sub.prop(rd, "bake_margin")
+ sub.prop(rd, "bake_quad_split", text="Split")
col = split.column()
col.prop(rd, "use_bake_selected_to_active")
@@ -602,11 +623,19 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
sub.prop(rd, "bake_distance")
sub.prop(rd, "bake_bias")
else:
- if rd.bake_type == 'DISPLACEMENT':
- layout.prop(rd, "use_bake_lores_mesh")
+ split = layout.split()
- layout.prop(rd, "use_bake_clear")
- layout.prop(rd, "bake_margin")
+ col = split.column()
+ col.prop(rd, "use_bake_clear")
+ col.prop(rd, "bake_margin")
+
+ if rd.bake_type == 'DISPLACEMENT':
+ col = split.column()
+ col.prop(rd, "use_bake_lores_mesh")
+ if rd.bake_type == 'AO':
+ col = split.column()
+ col.prop(rd, "bake_bias")
+ col.prop(rd, "bake_samples")
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 518b253..66a16da 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -18,10 +18,22 @@
# <pep8 compliant>
import bpy
-from bpy.types import Panel
+from bpy.types import Panel, UIList
from rna_prop_ui import PropertyPanel
+class SCENE_UL_keying_set_paths(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.KeyingSetPath)
+ kspath = item
+ icon = layout.enum_item_icon(kspath, "id_type", kspath.id_type)
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(kspath.data_path, icon_value=icon)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
class SceneButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -107,7 +119,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
+ col.template_list("UI_UL_list", "", scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
col = row.column(align=True)
col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
@@ -151,7 +163,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
row = layout.row()
col = row.column()
- col.template_list(ks, "paths", ks.paths, "active_index", rows=2)
+ col.template_list("SCENE_UL_keying_set_paths", "", ks, "paths", ks.paths, "active_index", rows=2)
col = row.column(align=True)
col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="")
@@ -251,7 +263,6 @@ class SCENE_PT_color_management(Panel):
col.separator()
col.label(text="Render:")
col.template_colormanaged_view_settings(scene, "view_settings")
- col.prop(rd, "use_color_unpremultiply")
col = layout.column()
col.separator()
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index e623d03..6842b32 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from bpy.types import (Brush,
Lamp,
@@ -55,6 +55,22 @@ class TEXTURE_MT_envmap_specials(Menu):
layout.operator("texture.envmap_clear", icon='FILE_REFRESH')
layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH')
+
+class TEXTURE_UL_texslots(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MaterialTextureSlot)
+ ma = data
+ slot = item
+ tex = slot.texture if slot else None
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(tex.name if tex else "", icon_value=icon)
+ if tex and isinstance(item, bpy.types.MaterialTextureSlot):
+ layout.prop(ma, "use_textures", text="", index=index)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
from bl_ui.properties_material import active_node_mat
@@ -142,7 +158,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
if tex_collection:
row = layout.row()
- row.template_list(idblock, "texture_slots", idblock, "active_texture_index", rows=2)
+ row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", idblock, "active_texture_index", rows=2)
col = row.column(align=True)
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
@@ -426,7 +442,6 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
col = split.column()
col.label(text="Alpha:")
- col.prop(tex, "use_alpha", text="Use")
col.prop(tex, "use_calculate_alpha", text="Calculate")
col.prop(tex, "invert_alpha", text="Invert")
col.separator()
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index cb88226..5fc5713 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -19,7 +19,18 @@
# <pep8-80 compliant>
import bpy
-from bpy.types import Panel, Header, Menu
+from bpy.types import Panel, Header, Menu, UIList
+
+
+class CLIP_UL_tracking_objects(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.MovieTrackingObject)
+ tobj = item
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.label(tobj.name, icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA')
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA')
class CLIP_HT_header(Header):
@@ -471,8 +482,7 @@ class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
tracking = sc.clip.tracking
row = layout.row()
- row.template_list(tracking, "objects",
- tracking, "active_object_index", rows=3)
+ row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects", tracking, "active_object_index", rows=3)
sub = row.column(align=True)
@@ -728,7 +738,7 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
layout.active = stab.use_2d_stabilization
row = layout.row()
- row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
+ row.template_list("UI_UL_list", "", stab, "tracks", stab, "active_track_index", rows=3)
sub = row.column(align=True)
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index fdfd431..64ad565 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -433,7 +433,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel):
elem = False
if strip.type == 'IMAGE':
- elem = strip.getStripElem(frame_current)
+ elem = strip.strip_elem_from_frame(frame_current)
elif strip.type == 'MOVIE':
elem = strip.elements[0]
@@ -595,13 +595,14 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
# Current element for the filename
- elem = strip.getStripElem(context.scene.frame_current)
+ elem = strip.strip_elem_from_frame(context.scene.frame_current)
if elem:
split = layout.split(percentage=0.2)
split.label(text="File:")
split.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
layout.prop(strip.colorspace_settings, "name")
+ layout.prop(strip, "alpha_mode")
layout.operator("sequencer.change_path")
@@ -797,7 +798,6 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
col.label(text="Colors:")
col.prop(strip, "color_saturation", text="Saturation")
col.prop(strip, "color_multiply", text="Multiply")
- col.prop(strip, "use_premultiply")
col.prop(strip, "use_float")
@@ -867,6 +867,10 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
#col.active = render.use_sequencer_gl_preview
col.prop(render, "sequencer_gl_preview", text="")
+ row = col.row()
+ row.active = render.sequencer_gl_preview == 'SOLID'
+ row.prop(render, "use_sequencer_gl_textured_solid")
+
class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
bl_label = "View Settings"
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index fa8752c..960a945 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -66,6 +66,7 @@ class TEXT_HT_header(Header):
row.operator("text.run_script")
row = layout.row()
+ row.active = text.name.endswith(".py")
row.prop(text, "use_module")
row = layout.row()
@@ -193,16 +194,35 @@ class TEXT_MT_text(Menu):
layout.operator("text.run_script")
-class TEXT_MT_templates(Menu):
- bl_label = "Templates"
+class TEXT_MT_templates_py(Menu):
+ bl_label = "Python"
+
+ def draw(self, context):
+ self.path_menu(bpy.utils.script_paths("templates_py"),
+ "text.open",
+ {"internal": True},
+ )
+
+
+class TEXT_MT_templates_osl(Menu):
+ bl_label = "Open Shading Language"
def draw(self, context):
- self.path_menu(bpy.utils.script_paths("templates"),
+ self.path_menu(bpy.utils.script_paths("templates_osl"),
"text.open",
{"internal": True},
)
+class TEXT_MT_templates(Menu):
+ bl_label = "Templates"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.menu("TEXT_MT_templates_py")
+ layout.menu("TEXT_MT_templates_osl")
+
+
class TEXT_MT_edit_select(Menu):
bl_label = "Select"
@@ -281,6 +301,7 @@ class TEXT_MT_edit(Menu):
layout.operator("text.jump")
layout.operator("text.properties", text="Find...")
+ layout.operator("text.autocomplete")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 0bb25e9..a9712b1 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -22,6 +22,27 @@ from bpy.types import Header, Menu, Panel
import os
+def ui_style_items(col, context):
+ """ UI Style settings """
+
+ split = col.split()
+
+ col = split.column()
+ col.label(text="Kerning Style:")
+ col.row().prop(context, "font_kerning_style", expand=True)
+ col.prop(context, "points")
+
+ col = split.column()
+ col.label(text="Shadow Offset:")
+ col.prop(context, "shadow_offset_x", text="X")
+ col.prop(context, "shadow_offset_y", text="Y")
+
+ col = split.column()
+ col.prop(context, "shadow")
+ col.prop(context, "shadowalpha")
+ col.prop(context, "shadowcolor")
+
+
def ui_items_general(col, context):
""" General UI Theme Settings (User Interface)
"""
@@ -84,7 +105,7 @@ class USERPREF_HT_header(Header):
userpref = context.user_preferences
layout.operator_context = 'EXEC_AREA'
- layout.operator("wm.save_homefile", text="Save As Default")
+ layout.operator("wm.save_userpref")
layout.operator_context = 'INVOKE_DEFAULT'
@@ -179,7 +200,7 @@ class USERPREF_PT_interface(Panel):
col.prop(view, "show_playback_fps", text="Playback FPS")
col.prop(view, "use_global_scene")
col.prop(view, "object_origin_size")
-
+
col.separator()
col.separator()
col.separator()
@@ -445,6 +466,7 @@ class USERPREF_PT_system(Panel):
col.label(text="Window Draw Method:")
col.prop(system, "window_draw_method", text="")
col.prop(system, "multi_sample", text="")
+ col.prop(system, "use_region_overlap")
col.label(text="Text Draw Options:")
col.prop(system, "use_text_antialiasing")
col.label(text="Textures:")
@@ -491,15 +513,15 @@ class USERPREF_PT_system(Panel):
sub.active = system.use_weight_color_range
sub.template_color_ramp(system, "weight_color_range", expand=True)
- column.separator()
-
- column.prop(system, "use_international_fonts")
- if system.use_international_fonts:
- column.prop(system, "language")
- row = column.row()
- row.label(text="Translate:")
- row.prop(system, "use_translate_interface", text="Interface")
- row.prop(system, "use_translate_tooltips", text="Tooltips")
+ if bpy.app.build_options.international:
+ column.separator()
+ column.prop(system, "use_international_fonts")
+ if system.use_international_fonts:
+ column.prop(system, "language")
+ row = column.row()
+ row.label(text="Translate:")
+ row.prop(system, "use_translate_interface", text="Interface")
+ row.prop(system, "use_translate_tooltips", text="Tooltips")
class USERPREF_MT_interface_theme_presets(Menu):
@@ -685,7 +707,8 @@ class USERPREF_PT_theme(Panel):
col.separator()
ui = theme.user_interface
- col.label("Icons:")
+
+ col.label("Menu Shadow:")
row = col.row()
@@ -694,20 +717,19 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- colsub.row().prop(ui, "icon_file")
+ colsub.row().prop(ui, "menu_shadow_fac")
subsplit = row.split(percentage=0.85)
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- colsub.row().prop(ui, "icon_alpha")
+ colsub.row().prop(ui, "menu_shadow_width")
col.separator()
col.separator()
- ui = theme.user_interface.panel
- col.label("Panels:")
+ col.label("Icons:")
row = col.row()
@@ -716,16 +738,14 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- rowsub = colsub.row()
- rowsub.prop(ui, "show_header")
- rowsub.label()
+ colsub.row().prop(ui, "icon_file")
subsplit = row.split(percentage=0.85)
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- colsub.row().prop(ui, "header")
+ colsub.row().prop(ui, "icon_alpha")
col.separator()
col.separator()
@@ -775,6 +795,21 @@ class USERPREF_PT_theme(Panel):
colsub = padding.column()
colsub = padding.column()
colsub.row().prop(ui, "show_colored_constraints")
+ elif theme.theme_area == 'STYLE':
+ col = split.column()
+
+ style = context.user_preferences.ui_styles[0]
+
+ ui = style.widget
+ col.label(text="Widget:")
+ ui_style_items(col, ui)
+
+ col.separator()
+ col.separator()
+
+ ui = style.widget_label
+ col.label(text="Widget Label:")
+ ui_style_items(col, ui)
else:
self._theme_generic(split, getattr(theme, theme.theme_area.lower()))
@@ -855,6 +890,7 @@ class USERPREF_PT_file(Panel):
col.prop(paths, "recent_files")
col.prop(paths, "use_save_preview_images")
col.label(text="Auto Save:")
+ col.prop(paths, "use_keep_session")
col.prop(paths, "use_auto_save_temporary_files")
sub = col.column()
sub.active = paths.use_auto_save_temporary_files
@@ -1126,7 +1162,8 @@ class USERPREF_PT_addons(Panel):
continue
# Addon UI Code
- box = col.column().box()
+ col_box = col.column()
+ box = col_box.box()
colsub = box.column()
row = colsub.row()
@@ -1189,6 +1226,25 @@ class USERPREF_PT_addons(Panel):
for i in range(4 - tot_row):
split.separator()
+ # Show addon user preferences
+ if is_enabled:
+ addon_preferences = userpref.addons[module_name].preferences
+ if addon_preferences is not None:
+ draw = getattr(addon_preferences, "draw", None)
+ if draw is not None:
+ addon_preferences_class = type(addon_preferences)
+ box_prefs = col_box.box()
+ box_prefs.label("Preferences:")
+ addon_preferences_class.layout = box_prefs
+ try:
+ draw(context)
+ except:
+ import traceback
+ traceback.print_exc()
+ box_prefs.label(text="Error (see console)", icon='ERROR')
+ del addon_preferences_class.layout
+
+
# Append missing scripts
# First collect scripts that are used but have no script file.
module_names = {mod.__name__ for mod, info in addons}
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b1dfc39..8189ee2 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -70,7 +70,8 @@ class VIEW3D_HT_header(Header):
row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
# Occlude geometry
- if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH')):
+ if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
+ (mode == 'WEIGHT_PAINT')):
row.prop(view, "use_occlude_geometry", text="")
# Proportional editing
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 91132a7..3c56ff8 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -854,6 +854,36 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
+class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
+ bl_label = "Topology"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.sculpt_object and context.tool_settings.sculpt)
+
+ def draw(self, context):
+ layout = self.layout
+
+ toolsettings = context.tool_settings
+ sculpt = toolsettings.sculpt
+
+ if context.sculpt_object.use_dynamic_topology_sculpting:
+ layout.operator("sculpt.dynamic_topology_toggle", icon='X', text="Disable Dynamic")
+ else:
+ layout.operator("sculpt.dynamic_topology_toggle", icon='SCULPT_DYNTOPO', text="Enable Dynamic")
+
+ col = layout.column()
+ col.active = context.sculpt_object.use_dynamic_topology_sculpting
+ col.prop(sculpt, "detail_size")
+ col.prop(sculpt, "use_smooth_shading")
+ col.prop(sculpt, "use_edge_collapse")
+ col.operator("sculpt.optimize")
+ col.separator()
+ col.prop(sculpt, "symmetrize_direction")
+ col.operator("sculpt.symmetrize")
+
+
class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
bl_label = "Options"
bl_options = {'DEFAULT_CLOSED'}
@@ -971,6 +1001,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
col.operator("object.vertex_group_transfer_weight", text="Transfer Weights")
col.operator("object.vertex_group_limit_total", text="Limit Total")
col.operator("object.vertex_group_fix", text="Fix Deforms")
+ col.operator("paint.weight_gradient")
class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
@@ -1089,11 +1120,11 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text)
row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
- row = layout.row()
- row.active = (settings.brush.image_tool == 'CLONE')
- row.prop(ipaint, "use_clone_layer", text="Clone")
+ col = layout.column()
+ col.active = (settings.brush.image_tool == 'CLONE')
+ col.prop(ipaint, "use_clone_layer", text="Clone from UV map")
clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
- row.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text)
+ col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text)
layout.prop(ipaint, "seam_bleed")
@@ -1166,7 +1197,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
if pe.type == 'PARTICLES':
if ob.particle_systems:
if len(ob.particle_systems) > 1:
- layout.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2, maxrows=3)
+ layout.template_list("UI_UL_list", "", ob, "particle_systems",
+ ob.particle_systems, "active_index", rows=2, maxrows=3)
ptcache = ob.particle_systems.active.point_cache
else:
@@ -1175,7 +1207,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
ptcache = md.point_cache
if ptcache and len(ptcache.point_caches) > 1:
- layout.template_list(ptcache, "point_caches", ptcache.point_caches, "active_index", rows=2, maxrows=3)
+ layout.template_list("UI_UL_list", "", ptcache, "point_caches", ptcache.point_caches, "active_index",
+ rows=2, maxrows=3)
if not pe.is_editable:
layout.label(text="Point cache must be baked")
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 6ad8737..4f06f8a 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -181,7 +181,7 @@ class BUILTIN_KSI_RotScale(KeyingSetInfo):
# ------------
-# Location
+# VisualLocation
class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
"""
Insert a keyframe on each of the location channels, taking into account
@@ -201,7 +201,7 @@ class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
generate = keyingsets_utils.RKS_GEN_location
-# Rotation
+# VisualRotation
class BUILTIN_KSI_VisualRot(KeyingSetInfo):
"""
Insert a keyframe on each of the rotation channels, taking into account
@@ -221,6 +221,26 @@ class BUILTIN_KSI_VisualRot(KeyingSetInfo):
generate = keyingsets_utils.RKS_GEN_rotation
+# VisualScaling
+class BUILTIN_KSI_VisualScaling(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the scale channels, taking into account
+ effects of constraints and relationships
+ """
+ bl_label = "Visual Scaling"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator - use callback for location
+ generate = keyingsets_utils.RKS_GEN_scaling
+
+
# VisualLocRot
class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
"""
@@ -244,6 +264,80 @@ class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
# rotation
keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+
+# VisualLocScale
+class BUILTIN_KSI_VisualLocScale(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the location and scaling channels,
+ taking into account effects of constraints and relationships
+ """
+ bl_label = "Visual LocScale"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator
+ def generate(self, context, ks, data):
+ # location
+ keyingsets_utils.RKS_GEN_location(self, context, ks, data)
+ # scaling
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+
+
+# VisualLocRotScale
+class BUILTIN_KSI_VisualLocRotScale(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the location, rotation and scaling channels,
+ taking into account effects of constraints and relationships
+ """
+ bl_label = "Visual LocRotScale"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator
+ def generate(self, context, ks, data):
+ # location
+ keyingsets_utils.RKS_GEN_location(self, context, ks, data)
+ # rotation
+ keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+ # scaling
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+
+
+# VisualRotScale
+class BUILTIN_KSI_VisualRotScale(KeyingSetInfo):
+ """
+ Insert a keyframe on each of the rotation and scaling channels,
+ taking into account effects of constraints and relationships
+ """
+ bl_label = "Visual RotScale"
+
+ bl_options = {'INSERTKEY_VISUAL'}
+
+ # poll - use predefined callback for selected bones/objects
+ poll = keyingsets_utils.RKS_POLL_selected_items
+
+ # iterator - use callback for selected bones/objects
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ # generator
+ def generate(self, context, ks, data):
+ # rotation
+ keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+ # scaling
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+
# ------------
diff --git a/release/scripts/templates/addon_add_object.py b/release/scripts/templates/addon_add_object.py
deleted file mode 100644
index a4df5fb..0000000
--- a/release/scripts/templates/addon_add_object.py
+++ /dev/null
@@ -1,92 +0,0 @@
-bl_info = {
- "name": "New Object",
- "author": "Your Name Here",
- "version": (1, 0),
- "blender": (2, 5, 5),
- "location": "View3D > Add > Mesh > New Object",
- "description": "Adds a new Mesh Object",
- "warning": "",
- "wiki_url": "",
- "tracker_url": "",
- "category": "Add Mesh"}
-
-
-import bpy
-from bpy.types import Operator
-from bpy.props import FloatVectorProperty
-from bpy_extras.object_utils import AddObjectHelper, object_data_add
-from mathutils import Vector
-
-
-def add_object(self, context):
- scale_x = self.scale.x
- scale_y = self.scale.y
-
- verts = [Vector((-1 * scale_x, 1 * scale_y, 0)),
- Vector((1 * scale_x, 1 * scale_y, 0)),
- Vector((1 * scale_x, -1 * scale_y, 0)),
- Vector((-1 * scale_x, -1 * scale_y, 0)),
- ]
-
- edges = []
- faces = [[0, 1, 2, 3]]
-
- mesh = bpy.data.meshes.new(name="New Object Mesh")
- mesh.from_pydata(verts, edges, faces)
- # useful for development when the mesh may be invalid.
- # mesh.validate(verbose=True)
- object_data_add(context, mesh, operator=self)
-
-
-class OBJECT_OT_add_object(Operator, AddObjectHelper):
- """Create a new Mesh Object"""
- bl_idname = "mesh.add_object"
- bl_label = "Add Mesh Object"
- bl_options = {'REGISTER', 'UNDO'}
-
- scale = FloatVectorProperty(
- name="scale",
- default=(1.0, 1.0, 1.0),
- subtype='TRANSLATION',
- description="scaling",
- )
-
- def execute(self, context):
-
- add_object(self, context)
-
- return {'FINISHED'}
-
-
-# Registration
-
-def add_object_button(self, context):
- self.layout.operator(
- OBJECT_OT_add_object.bl_idname,
- text="Add Object",
- icon='PLUGIN')
-
-
-# This allows you to right click on a button and link to the manual
-def add_object_manual_map():
- url_manual_prefix = "http://wiki.blender.org/index.php/Doc:2.6/Manual/"
- url_manual_mapping = (
- ("bpy.ops.mesh.add_object", "Modeling/Objects"),
- )
- return url_manual_prefix, url_manual_mapping
-
-
-def register():
- bpy.utils.register_class(OBJECT_OT_add_object)
- bpy.utils.register_manual_map(add_object_manual_map)
- bpy.types.INFO_MT_mesh_add.append(add_object_button)
-
-
-def unregister():
- bpy.utils.unregister_class(OBJECT_OT_add_object)
- bpy.utils.unregister_manual_map(add_object_manual_map)
- bpy.types.INFO_MT_mesh_add.remove(add_object_button)
-
-
-if __name__ == "__main__":
- register()
diff --git a/release/scripts/templates/operator_modal_draw.py b/release/scripts/templates/operator_modal_draw.py
deleted file mode 100644
index f1c4e11..0000000
--- a/release/scripts/templates/operator_modal_draw.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import bpy
-import bgl
-import blf
-
-
-def draw_callback_px(self, context):
- print("mouse points", len(self.mouse_path))
-
- font_id = 0 # XXX, need to find out how best to get this.
-
- # draw some text
- blf.position(font_id, 15, 30, 0)
- blf.size(font_id, 20, 72)
- blf.draw(font_id, "Hello Word " + str(len(self.mouse_path)))
-
- # 50% alpha, 2 pixel width line
- bgl.glEnable(bgl.GL_BLEND)
- bgl.glColor4f(0.0, 0.0, 0.0, 0.5)
- bgl.glLineWidth(2)
-
- bgl.glBegin(bgl.GL_LINE_STRIP)
- for x, y in self.mouse_path:
- bgl.glVertex2i(x, y)
-
- bgl.glEnd()
-
- # restore opengl defaults
- bgl.glLineWidth(1)
- bgl.glDisable(bgl.GL_BLEND)
- bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
-
-
-class ModalDrawOperator(bpy.types.Operator):
- """Draw a line with the mouse"""
- bl_idname = "view3d.modal_operator"
- bl_label = "Simple Modal View3D Operator"
-
- def modal(self, context, event):
- context.area.tag_redraw()
-
- if event.type == 'MOUSEMOVE':
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
-
- elif event.type == 'LEFTMOUSE':
- context.region.callback_remove(self._handle)
- return {'FINISHED'}
-
- elif event.type in {'RIGHTMOUSE', 'ESC'}:
- context.region.callback_remove(self._handle)
- return {'CANCELLED'}
-
- return {'RUNNING_MODAL'}
-
- def invoke(self, context, event):
- if context.area.type == 'VIEW_3D':
- # Add the region OpenGL drawing callback
- # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
- self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
-
- self.mouse_path = []
-
- context.window_manager.modal_handler_add(self)
- return {'RUNNING_MODAL'}
- else:
- self.report({'WARNING'}, "View3D not found, cannot run operator")
- return {'CANCELLED'}
-
-
-def register():
- bpy.utils.register_class(ModalDrawOperator)
-
-
-def unregister():
- bpy.utils.unregister_class(ModalDrawOperator)
-
-if __name__ == "__main__":
- register()
diff --git a/release/scripts/templates_osl/empty_shader.osl b/release/scripts/templates_osl/empty_shader.osl
new file mode 100644
index 0000000..e2c9a4a
--- /dev/null
+++ b/release/scripts/templates_osl/empty_shader.osl
@@ -0,0 +1,6 @@
+
+shader name()
+{
+
+}
+
diff --git a/release/scripts/templates_osl/noise.osl b/release/scripts/templates_osl/noise.osl
new file mode 100644
index 0000000..05cc316
--- /dev/null
+++ b/release/scripts/templates_osl/noise.osl
@@ -0,0 +1,18 @@
+
+shader noise(
+ float Time = 1.0,
+ point Point = P,
+ output float Cell = 0.0,
+ output color Perlin = 0.8,
+ output color UPerlin = 0.8)
+{
+ /* Cell Noise */
+ Cell = noise("cell", Point);
+
+ /* Perlin 4D Noise*/
+ Perlin = noise("perlin", Point, Time);
+
+ /* UPerlin 4D Noise*/
+ UPerlin = noise("uperlin", Point, Time);
+}
+
diff --git a/release/scripts/templates_osl/wireframe.osl b/release/scripts/templates_osl/wireframe.osl
new file mode 100644
index 0000000..00e4506
--- /dev/null
+++ b/release/scripts/templates_osl/wireframe.osl
@@ -0,0 +1,11 @@
+
+#include "oslutil.h"
+
+shader wireframe(
+ float Line_Width = 2.0,
+ int Raster = 1,
+ output float Wire = 0.0)
+{
+ Wire = wireframe("triangles", Line_Width, Raster);
+}
+
diff --git a/release/scripts/templates_py/addon_add_object.py b/release/scripts/templates_py/addon_add_object.py
new file mode 100644
index 0000000..66da6a9
--- /dev/null
+++ b/release/scripts/templates_py/addon_add_object.py
@@ -0,0 +1,92 @@
+bl_info = {
+ "name": "New Object",
+ "author": "Your Name Here",
+ "version": (1, 0),
+ "blender": (2, 65, 0),
+ "location": "View3D > Add > Mesh > New Object",
+ "description": "Adds a new Mesh Object",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Mesh"}
+
+
+import bpy
+from bpy.types import Operator
+from bpy.props import FloatVectorProperty
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+from mathutils import Vector
+
+
+def add_object(self, context):
+ scale_x = self.scale.x
+ scale_y = self.scale.y
+
+ verts = [Vector((-1 * scale_x, 1 * scale_y, 0)),
+ Vector((1 * scale_x, 1 * scale_y, 0)),
+ Vector((1 * scale_x, -1 * scale_y, 0)),
+ Vector((-1 * scale_x, -1 * scale_y, 0)),
+ ]
+
+ edges = []
+ faces = [[0, 1, 2, 3]]
+
+ mesh = bpy.data.meshes.new(name="New Object Mesh")
+ mesh.from_pydata(verts, edges, faces)
+ # useful for development when the mesh may be invalid.
+ # mesh.validate(verbose=True)
+ object_data_add(context, mesh, operator=self)
+
+
+class OBJECT_OT_add_object(Operator, AddObjectHelper):
+ """Create a new Mesh Object"""
+ bl_idname = "mesh.add_object"
+ bl_label = "Add Mesh Object"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ scale = FloatVectorProperty(
+ name="scale",
+ default=(1.0, 1.0, 1.0),
+ subtype='TRANSLATION',
+ description="scaling",
+ )
+
+ def execute(self, context):
+
+ add_object(self, context)
+
+ return {'FINISHED'}
+
+
+# Registration
+
+def add_object_button(self, context):
+ self.layout.operator(
+ OBJECT_OT_add_object.bl_idname,
+ text="Add Object",
+ icon='PLUGIN')
+
+
+# This allows you to right click on a button and link to the manual
+def add_object_manual_map():
+ url_manual_prefix = "http://wiki.blender.org/index.php/Doc:2.6/Manual/"
+ url_manual_mapping = (
+ ("bpy.ops.mesh.add_object", "Modeling/Objects"),
+ )
+ return url_manual_prefix, url_manual_mapping
+
+
+def register():
+ bpy.utils.register_class(OBJECT_OT_add_object)
+ bpy.utils.register_manual_map(add_object_manual_map)
+ bpy.types.INFO_MT_mesh_add.append(add_object_button)
+
+
+def unregister():
+ bpy.utils.unregister_class(OBJECT_OT_add_object)
+ bpy.utils.unregister_manual_map(add_object_manual_map)
+ bpy.types.INFO_MT_mesh_add.remove(add_object_button)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/templates/background_job.py b/release/scripts/templates_py/background_job.py
similarity index 100%
rename from release/scripts/templates/background_job.py
rename to release/scripts/templates_py/background_job.py
diff --git a/release/scripts/templates/batch_export.py b/release/scripts/templates_py/batch_export.py
similarity index 100%
rename from release/scripts/templates/batch_export.py
rename to release/scripts/templates_py/batch_export.py
diff --git a/release/scripts/templates/bmesh_simple.py b/release/scripts/templates_py/bmesh_simple.py
similarity index 100%
rename from release/scripts/templates/bmesh_simple.py
rename to release/scripts/templates_py/bmesh_simple.py
diff --git a/release/scripts/templates/bmesh_simple_editmode.py b/release/scripts/templates_py/bmesh_simple_editmode.py
similarity index 100%
rename from release/scripts/templates/bmesh_simple_editmode.py
rename to release/scripts/templates_py/bmesh_simple_editmode.py
diff --git a/release/scripts/templates/builtin_keyingset.py b/release/scripts/templates_py/builtin_keyingset.py
similarity index 100%
rename from release/scripts/templates/builtin_keyingset.py
rename to release/scripts/templates_py/builtin_keyingset.py
diff --git a/release/scripts/templates/driver_functions.py b/release/scripts/templates_py/driver_functions.py
similarity index 100%
rename from release/scripts/templates/driver_functions.py
rename to release/scripts/templates_py/driver_functions.py
diff --git a/release/scripts/templates/gamelogic.py b/release/scripts/templates_py/gamelogic.py
similarity index 100%
rename from release/scripts/templates/gamelogic.py
rename to release/scripts/templates_py/gamelogic.py
diff --git a/release/scripts/templates/gamelogic_module.py b/release/scripts/templates_py/gamelogic_module.py
similarity index 100%
rename from release/scripts/templates/gamelogic_module.py
rename to release/scripts/templates_py/gamelogic_module.py
diff --git a/release/scripts/templates/gamelogic_simple.py b/release/scripts/templates_py/gamelogic_simple.py
similarity index 100%
rename from release/scripts/templates/gamelogic_simple.py
rename to release/scripts/templates_py/gamelogic_simple.py
diff --git a/release/scripts/templates/operator_file_export.py b/release/scripts/templates_py/operator_file_export.py
similarity index 100%
rename from release/scripts/templates/operator_file_export.py
rename to release/scripts/templates_py/operator_file_export.py
diff --git a/release/scripts/templates/operator_file_import.py b/release/scripts/templates_py/operator_file_import.py
similarity index 100%
rename from release/scripts/templates/operator_file_import.py
rename to release/scripts/templates_py/operator_file_import.py
diff --git a/release/scripts/templates/operator_mesh_add.py b/release/scripts/templates_py/operator_mesh_add.py
similarity index 100%
rename from release/scripts/templates/operator_mesh_add.py
rename to release/scripts/templates_py/operator_mesh_add.py
diff --git a/release/scripts/templates/operator_modal.py b/release/scripts/templates_py/operator_modal.py
similarity index 100%
rename from release/scripts/templates/operator_modal.py
rename to release/scripts/templates_py/operator_modal.py
diff --git a/release/scripts/templates_py/operator_modal_draw.py b/release/scripts/templates_py/operator_modal_draw.py
new file mode 100644
index 0000000..d11ddf0
--- /dev/null
+++ b/release/scripts/templates_py/operator_modal_draw.py
@@ -0,0 +1,79 @@
+import bpy
+import bgl
+import blf
+
+
+def draw_callback_px(self, context):
+ print("mouse points", len(self.mouse_path))
+
+ font_id = 0 # XXX, need to find out how best to get this.
+
+ # draw some text
+ blf.position(font_id, 15, 30, 0)
+ blf.size(font_id, 20, 72)
+ blf.draw(font_id, "Hello Word " + str(len(self.mouse_path)))
+
+ # 50% alpha, 2 pixel width line
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glColor4f(0.0, 0.0, 0.0, 0.5)
+ bgl.glLineWidth(2)
+
+ bgl.glBegin(bgl.GL_LINE_STRIP)
+ for x, y in self.mouse_path:
+ bgl.glVertex2i(x, y)
+
+ bgl.glEnd()
+
+ # restore opengl defaults
+ bgl.glLineWidth(1)
+ bgl.glDisable(bgl.GL_BLEND)
+ bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+
+
+class ModalDrawOperator(bpy.types.Operator):
+ """Draw a line with the mouse"""
+ bl_idname = "view3d.modal_operator"
+ bl_label = "Simple Modal View3D Operator"
+
+ def modal(self, context, event):
+ context.area.tag_redraw()
+
+ if event.type == 'MOUSEMOVE':
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+
+ elif event.type == 'LEFTMOUSE':
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ return {'FINISHED'}
+
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ return {'CANCELLED'}
+
+ return {'RUNNING_MODAL'}
+
+ def invoke(self, context, event):
+ if context.area.type == 'VIEW_3D':
+ # the arguments we pass the the callback
+ args = (self, context)
+ # Add the region OpenGL drawing callback
+ # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
+
+ self.mouse_path = []
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+ else:
+ self.report({'WARNING'}, "View3D not found, cannot run operator")
+ return {'CANCELLED'}
+
+
+def register():
+ bpy.utils.register_class(ModalDrawOperator)
+
+
+def unregister():
+ bpy.utils.unregister_class(ModalDrawOperator)
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/templates/operator_modal_timer.py b/release/scripts/templates_py/operator_modal_timer.py
similarity index 100%
rename from release/scripts/templates/operator_modal_timer.py
rename to release/scripts/templates_py/operator_modal_timer.py
diff --git a/release/scripts/templates/operator_modal_view3d.py b/release/scripts/templates_py/operator_modal_view3d.py
similarity index 100%
rename from release/scripts/templates/operator_modal_view3d.py
rename to release/scripts/templates_py/operator_modal_view3d.py
diff --git a/release/scripts/templates/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
similarity index 100%
rename from release/scripts/templates/operator_modal_view3d_raycast.py
rename to release/scripts/templates_py/operator_modal_view3d_raycast.py
diff --git a/release/scripts/templates/operator_node.py b/release/scripts/templates_py/operator_node.py
similarity index 100%
rename from release/scripts/templates/operator_node.py
rename to release/scripts/templates_py/operator_node.py
diff --git a/release/scripts/templates/operator_simple.py b/release/scripts/templates_py/operator_simple.py
similarity index 100%
rename from release/scripts/templates/operator_simple.py
rename to release/scripts/templates_py/operator_simple.py
diff --git a/release/scripts/templates/operator_uv.py b/release/scripts/templates_py/operator_uv.py
similarity index 100%
rename from release/scripts/templates/operator_uv.py
rename to release/scripts/templates_py/operator_uv.py
diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates_py/script_stub.py
similarity index 100%
rename from release/scripts/templates/script_stub.py
rename to release/scripts/templates_py/script_stub.py
diff --git a/release/scripts/templates_py/ui_list.py b/release/scripts/templates_py/ui_list.py
new file mode 100644
index 0000000..18861f7
--- /dev/null
+++ b/release/scripts/templates_py/ui_list.py
@@ -0,0 +1,78 @@
+import bpy
+
+
+class MATERIAL_UL_matslots_example(bpy.types.UIList):
+ # The draw_item function is called for each item of the collection that is visible in the list.
+ # data is the RNA object containing the collection,
+ # item is the current drawn item of the collection,
+ # icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
+ # have custom icons ID, which are not available as enum items).
+ # active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
+ # active item of the collection).
+ # active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
+ # index is index of the current item in the collection.
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ ob = data
+ slot = item
+ ma = slot.material
+ # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ # You should always start your row layout by a label (icon + text), this will also make the row easily
+ # selectable in the list!
+ # We use icon_value of label, as our given icon is an integer value, not an enum ID.
+ layout.label(ma.name if ma else "", icon_value=icon)
+ # And now we can add other UI stuff...
+ # Here, we add nodes info if this material uses (old!) shading nodes.
+ if ma and not context.scene.render.use_shading_nodes:
+ manode = ma.active_node_material
+ if manode:
+ # The static method UILayout.icon returns the integer value of the icon ID "computed" for the given
+ # RNA object.
+ layout.label("Node %s" % manode.name, icon_value=layout.icon(manode))
+ elif ma.use_nodes:
+ layout.label("Node <none>")
+ else:
+ layout.label("")
+ # 'GRID' layout type should be as compact as possible (typically a single icon!).
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label("", icon_value=icon)
+
+
+# And now we can use this list everywhere in Blender. Here is a small example panel.
+class UIListPanelExample(bpy.types.Panel):
+ """Creates a Panel in the Object properties window"""
+ bl_label = "UIList Panel"
+ bl_idname = "OBJECT_PT_ui_list_example"
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+ bl_context = "object"
+
+ def draw(self, context):
+ layout = self.layout
+
+ obj = context.object
+
+ # template_list now takes two new args.
+ # The first one is the identifier of the registered UIList to use (if you want only the default list,
+ # with no custom draw code, use "UI_UL_list").
+ layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
+
+ # The second one can usually be left as an empty string. It's an additional ID used to distinguish lists in case you
+ # use the same list several times in a given area.
+ layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
+ obj, "active_material_index", type='COMPACT')
+
+
+def register():
+ bpy.utils.register_class(MATERIAL_UL_matslots_example)
+ bpy.utils.register_class(UIListPanelExample)
+
+
+def unregister():
+ bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
+ bpy.utils.unregister_class(UIListPanelExample)
+
+
+if __name__ == "__main__":
+ register()
\ No newline at end of file
diff --git a/release/scripts/templates/ui_menu.py b/release/scripts/templates_py/ui_menu.py
similarity index 100%
rename from release/scripts/templates/ui_menu.py
rename to release/scripts/templates_py/ui_menu.py
diff --git a/release/scripts/templates/ui_menu_simple.py b/release/scripts/templates_py/ui_menu_simple.py
similarity index 100%
rename from release/scripts/templates/ui_menu_simple.py
rename to release/scripts/templates_py/ui_menu_simple.py
diff --git a/release/scripts/templates/ui_panel.py b/release/scripts/templates_py/ui_panel.py
similarity index 100%
rename from release/scripts/templates/ui_panel.py
rename to release/scripts/templates_py/ui_panel.py
diff --git a/release/scripts/templates/ui_panel_simple.py b/release/scripts/templates_py/ui_panel_simple.py
similarity index 100%
rename from release/scripts/templates/ui_panel_simple.py
rename to release/scripts/templates_py/ui_panel_simple.py
diff --git a/source/SConscript b/source/SConscript
index fdd126b..432cfb3 100644
--- a/source/SConscript
+++ b/source/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
SConscript(['blender/SConscript'])
diff --git a/source/blender/SConscript b/source/blender/SConscript
index e1f81f9..bf52f2e 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import sys
diff --git a/source/blender/avi/SConscript b/source/blender/avi/SConscript
index 4d2ce8f..0e46781 100644
--- a/source/blender/avi/SConscript
+++ b/source/blender/avi/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/avi/intern/avi_endian.c b/source/blender/avi/intern/avi_endian.c
index 70add8b..9720d83 100644
--- a/source/blender/avi/intern/avi_endian.c
+++ b/source/blender/avi/intern/avi_endian.c
@@ -49,7 +49,7 @@
#ifdef __BIG_ENDIAN__
/* copied from BLI_endian_switch_inline.h */
-static void invert(int *num)
+static void invert(int *val)
{
int tval = *val;
*val = ((tval >> 24)) |
diff --git a/source/blender/avi/intern/avi_intern.h b/source/blender/avi/intern/avi_intern.h
index c8d54fe..5dc4865 100644
--- a/source/blender/avi/intern/avi_intern.h
+++ b/source/blender/avi/intern/avi_intern.h
@@ -37,9 +37,27 @@
unsigned int GET_FCC (FILE *fp);
unsigned int GET_TCC (FILE *fp);
-#define PUT_FCC(ch4, fp) putc(ch4[0],fp); putc(ch4[1],fp); putc(ch4[2],fp); putc(ch4[3],fp)
-#define PUT_FCCN(num, fp) putc((num>>0)&0377,fp); putc((num>>8)&0377,fp); putc((num>>16)&0377,fp); putc((num>>24)&0377,fp)
-#define PUT_TCC(ch2, fp) putc(ch2[0],fp); putc(ch2[1],fp)
+#define PUT_FCC(ch4, fp) \
+{ \
+ putc(ch4[0], fp); \
+ putc(ch4[1], fp); \
+ putc(ch4[2], fp); \
+ putc(ch4[3], fp); \
+} (void)0
+
+#define PUT_FCCN(num, fp) \
+{ \
+ putc((num >> 0) & 0377, fp); \
+ putc((num >> 8) & 0377, fp); \
+ putc((num >> 16) & 0377, fp); \
+ putc((num >> 24) & 0377, fp); \
+} (void)0
+
+#define PUT_TCC(ch2, fp) \
+{ \
+ putc(ch2[0], fp); \
+ putc(ch2[1], fp); \
+} (void)0
void *avi_format_convert (AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size);
diff --git a/source/blender/avi/intern/avi_mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c
index 396f119..91b8fa5 100644
--- a/source/blender/avi/intern/avi_mjpeg.c
+++ b/source/blender/avi/intern/avi_mjpeg.c
@@ -206,7 +206,7 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign
return 1;
}
-static void Compress_JPEG(int quality, unsigned char *outbuffer, unsigned char *inBuffer, int width, int height, int bufsize)
+static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned char *inBuffer, int width, int height, int bufsize)
{
int i, rowstride;
unsigned int y;
@@ -316,7 +316,8 @@ static int check_and_decode_jpeg(unsigned char *inbuf, unsigned char *outbuf, in
}
}
-static void check_and_compress_jpeg(int quality, unsigned char *outbuf, unsigned char *inbuf, int width, int height, int bufsize)
+static void check_and_compress_jpeg(int quality, unsigned char *outbuf, const unsigned char *inbuf,
+ int width, int height, int bufsize)
{
/* JPEG's are always multiples of 16, extra is ignored in AVI's */
if ((width & 0xF) || (height & 0xF)) {
@@ -379,7 +380,11 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 1");
if (!movie->interlace) {
- check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100, buf, buffer, movie->header->Width, movie->header->Height, bufsize);
+ check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100,
+ buf, buffer,
+ movie->header->Width,
+ movie->header->Height,
+ bufsize);
}
else {
deinterlace(movie->odd_fields, buf, buffer, movie->header->Width, movie->header->Height);
@@ -388,10 +393,18 @@ void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer,
buffer = buf;
buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 2");
- check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100, buf, buffer, movie->header->Width, movie->header->Height / 2, bufsize / 2);
+ check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100,
+ buf, buffer,
+ movie->header->Width,
+ movie->header->Height / 2,
+ bufsize / 2);
*size += numbytes;
numbytes = 0;
- check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100, buf + *size, buffer + (movie->header->Height / 2) * movie->header->Width * 3, movie->header->Width, movie->header->Height / 2, bufsize / 2);
+ check_and_compress_jpeg(movie->streams[stream].sh.Quality / 100,
+ buf + *size, buffer + (movie->header->Height / 2) * movie->header->Width * 3,
+ movie->header->Width,
+ movie->header->Height / 2,
+ bufsize / 2);
}
*size += numbytes;
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 6f348cc..25b55ea 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -37,6 +37,7 @@ struct ColorManagedDisplay;
int BLF_init(int points, int dpi);
void BLF_exit(void);
+void BLF_default_dpi(int dpi);
void BLF_cache_clear(void);
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index 159d4b0..0832907 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -85,8 +85,8 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
/* #define _(msgid) msgid */
#define IFACE_(msgid) msgid
#define TIP_(msgid) msgid
- #define CTX_IFACE_(context, msgid) ((void)context, msgid)
- #define CTX_TIP_(context, msgid) ((void)context, msgid)
+ #define CTX_IFACE_(context, msgid) msgid
+ #define CTX_TIP_(context, msgid) msgid
#endif
/* Helper macro, when we want to define a same msgid for multiple msgctxt...
diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript
index c0591c8..a6ea724 100644
--- a/source/blender/blenfont/SConscript
+++ b/source/blender/blenfont/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 778b6c1..1675676 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -87,6 +87,11 @@ int BLF_init(int points, int dpi)
return blf_font_init();
}
+void BLF_default_dpi(int dpi)
+{
+ global_font_dpi = dpi;
+}
+
void BLF_exit(void)
{
FontBLF *font;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 91ecded..12c0088 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -83,7 +83,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
- gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256);
+ gc->textures = (GLuint *)MEM_mallocN(sizeof(GLuint) * 256, __func__);
gc->ntex = 256;
gc->cur_tex = -1;
gc->x_offs = 0;
@@ -150,7 +150,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
if (gc->cur_tex + 1 > 0)
glDeleteTextures(gc->cur_tex + 1, gc->textures);
- free((void *)gc->textures);
+ MEM_freeN((void *)gc->textures);
MEM_freeN(gc);
}
@@ -178,8 +178,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
gc->p2_height = font->max_tex_size;
tot_mem = gc->p2_width * gc->p2_height;
- buf = (unsigned char *)malloc(tot_mem);
- memset((void *)buf, 0, tot_mem);
+ buf = (unsigned char *)MEM_callocN(tot_mem, __func__);
glGenTextures(1, &gc->textures[gc->cur_tex]);
glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex]));
@@ -189,7 +188,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf);
- free((void *)buf);
+ MEM_freeN((void *)buf);
}
GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
@@ -383,7 +382,7 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
if (gc->cur_tex == -1) {
blf_glyph_cache_texture(font, gc);
gc->x_offs = gc->pad;
- gc->y_offs = gc->pad;
+ gc->y_offs = 0;
}
if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) {
@@ -391,7 +390,7 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
gc->y_offs += gc->max_glyph_height;
if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) {
- gc->y_offs = gc->pad;
+ gc->y_offs = 0;
blf_glyph_cache_texture(font, gc);
}
}
@@ -400,6 +399,19 @@ int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
g->xoff = gc->x_offs;
g->yoff = gc->y_offs;
+ /* prevent glTexSubImage2D from failing if the character
+ * asks for pixels out of bounds, this tends only to happen
+ * with very small sizes (5px high or less) */
+ if (UNLIKELY((g->xoff + g->width) > gc->p2_width)) {
+ g->width -= (g->xoff + g->width) - gc->p2_width;
+ BLI_assert(g->width > 0);
+ }
+ if (UNLIKELY((g->yoff + g->height) > gc->p2_height)) {
+ g->height -= (g->yoff + g->height) - gc->p2_height;
+ BLI_assert(g->height > 0);
+ }
+
+
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 0ed4862..9086799 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -30,6 +30,8 @@
#include "BLF_translation.h" /* own include */
+#include "BLI_utildefines.h"
+
#ifdef WITH_INTERNATIONAL
#include <stdio.h>
@@ -50,7 +52,6 @@
#include "BLI_linklist.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
/* Locale options. */
static const char **locales = NULL;
@@ -99,7 +100,7 @@ static void fill_locales(void)
/* First loop to find highest locale ID */
while (line) {
int t;
- str = (char*) line->link;
+ str = (char *)line->link;
if (str[0] == '#' || str[0] == '\0') {
line = line->next;
continue; /* Comment or void... */
@@ -117,12 +118,12 @@ static void fill_locales(void)
line = lines;
/* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */
if (num_locales > 0) {
- locales = MEM_callocN(num_locales * sizeof(char*), __func__);
+ locales = MEM_callocN(num_locales * sizeof(char *), __func__);
while (line) {
int id;
char *loc, *sep1, *sep2, *sep3;
- str = (char*) line->link;
+ str = (char *)line->link;
if (str[0] == '#' || str[0] == '\0') {
line = line->next;
continue;
@@ -229,7 +230,7 @@ void BLF_lang_set(const char *str)
bl_locale_set(short_locale_utf8);
if (short_locale[0]) {
- MEM_freeN((void*)short_locale_utf8);
+ MEM_freeN((void *)short_locale_utf8);
}
}
@@ -254,9 +255,8 @@ void BLF_lang_free(void)
return;
}
-void BLF_lang_set(const char *str)
+void BLF_lang_set(const char *UNUSED(str))
{
- (void)str;
return;
}
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 617c4cd..f06547f 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -105,6 +105,11 @@ struct PBVH;
* Also, the mface origindex layer indexes mpolys, not mfaces.
*/
+typedef struct DMCoNo {
+ float co[3];
+ float no[3];
+} DMCoNo;
+
typedef struct DMGridAdjacency {
int index[4];
int rotation[4];
@@ -168,6 +173,9 @@ struct DerivedMesh {
float auto_bump_scale;
DMDirtyFlag dirty;
+ /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
+ char cd_flag;
+
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
@@ -603,7 +611,7 @@ void vDM_ColorBand_store(struct ColorBand *coba);
/** Simple function to get me->totvert amount of vertices/normals,
* correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
* In use now by vertex/weight paint and particles */
-float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
+DMCoNo *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
/* */
DerivedMesh *mesh_get_derived_final(struct Scene *scene, struct Object *ob,
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
new file mode 100644
index 0000000..eafaec3
--- /dev/null
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -0,0 +1,42 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_ADDON_H__
+#define __BKE_ADDON_H__
+
+#include "RNA_types.h"
+
+typedef struct bAddonPrefType {
+ /* type info */
+ char idname[64]; // best keep the same size as BKE_ST_MAXNAME
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} bAddonPrefType;
+
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet);
+void BKE_addon_pref_type_add(bAddonPrefType *apt);
+void BKE_addon_pref_type_remove(bAddonPrefType *apt);
+
+void BKE_addon_pref_type_init(void);
+void BKE_addon_pref_type_free(void);
+
+#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index b0f372e..765a00b 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -97,28 +97,28 @@ void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPose
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);
/* get_objectspace_bone_matrix has to be removed still */
-void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed);
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]);
-void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll);
+void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int root, int posed);
+void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]);
+void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll);
/* Common Conversions Between Co-ordinate Spaces */
-void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]);
+void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[4][4], float outmat[4][4]);
void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]);
-void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
+void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan, const float inloc[3], float outloc[3]);
-void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
-void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
+void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
+void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]);
-void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
+void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
-void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat);
-void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat);
+void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], short use_compat);
+void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], short use_comat);
void BKE_pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
void BKE_pchan_calc_mat(struct bPoseChannel *pchan);
/* Get the "pchan to pose" transform matrix. These matrices apply the effects of
* HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */
-void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]);
+void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4]);
/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index e6f3cd3..9c6d26c 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 265
-#define BLENDER_SUBVERSION 0
+#define BLENDER_SUBVERSION 8
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
@@ -52,7 +52,7 @@ extern "C" {
/* can be left blank, otherwise a,b,c... etc with no quotes */
#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
-#define BLENDER_VERSION_CYCLE release
+#define BLENDER_VERSION_CYCLE alpha
extern char versionstr[]; /* from blender.c */
@@ -62,6 +62,7 @@ struct bContext;
struct ReportList;
struct Scene;
struct Main;
+struct ID;
int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *reports);
@@ -72,12 +73,17 @@ int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *r
int BKE_read_file_from_memory(struct bContext *C, char *filebuf, int filelength, struct ReportList *reports);
int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile, struct ReportList *reports);
+int BKE_read_file_userdef(const char *filepath, struct ReportList *reports);
+int BKE_write_file_userdef(const char *filepath, struct ReportList *reports);
+
void free_blender(void);
void initglobals(void);
/* load new userdef from file, exit blender */
void BKE_userdef_free(void);
-
+/* handle changes in userdef */
+void BKE_userdef_state(void);
+
/* set this callback when a UI is running */
void set_blender_test_break_cb(void (*func)(void) );
int blender_test_break(void);
@@ -93,9 +99,15 @@ extern void BKE_reset_undo(void);
extern char *BKE_undo_menu_string(void);
extern void BKE_undo_number(struct bContext *C, int nr);
extern const char *BKE_undo_get_name(int nr, int *active);
-extern void BKE_undo_save_quit(void);
+extern int BKE_undo_save_file(const char *filename);
extern struct Main *BKE_undo_get_main(struct Scene **scene);
+ /* copybuffer */
+void BKE_copybuffer_begin(void);
+void BKE_copybuffer_tag_ID(struct ID *id);
+int BKE_copybuffer_save(char *filename, struct ReportList *reports);
+ int BKE_copybuffer_paste(struct bContext *C, char *libname, struct ReportList *reports);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h
new file mode 100644
index 0000000..16a8b1b
--- /dev/null
+++ b/source/blender/blenkernel/BKE_bpath.h
@@ -0,0 +1,72 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file BKE_bpath.h
+ * \ingroup bke
+ * \attention Based on ghash, difference is ghash is not a fixed size,
+ * so for BPath we don't need to malloc
+ */
+
+#ifndef __BKE_BPATH_H__
+#define __BKE_BPATH_H__
+
+struct ID;
+struct ListBase;
+struct Main;
+struct ReportList;
+
+/* Function that does something with an ID's file path. Should return 1 if the
+ * path has changed, and in that case, should write the result to pathOut. */
+typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src);
+/* Executes 'visit' for each path associated with 'id'. */
+void BKE_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata);
+void BKE_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata);
+void BKE_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata);
+int BKE_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
+
+/* Functions for temp backup/restore of paths, path count must NOT change */
+void *BKE_bpath_list_backup(struct Main *bmain, const int flag);
+void BKE_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle);
+void BKE_bpath_list_free(void *ls_handle);
+
+#define BKE_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */
+#define BKE_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */
+#define BKE_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */
+#define BKE_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg.
+ * sequence strip images and pointcache. in this case only use the first
+ * file, this is needed for directory manipulation functions which might
+ * otherwise modify the same directory multiple times */
+
+/* high level funcs */
+
+/* creates a text file with missing files if there are any */
+void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports);
+void BKE_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports);
+void BKE_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
+void BKE_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
+
+#endif /* __BKE_BPATH_H__ */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index cbffb6c..248fe9c 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -99,6 +99,7 @@ float BKE_brush_unprojected_radius_get(const struct Scene *scene, struct Brush *
void BKE_brush_unprojected_radius_set(struct Scene *scene, struct Brush *brush, float value);
float BKE_brush_alpha_get(const struct Scene *scene, struct Brush *brush);
+void BKE_brush_alpha_set(Scene *scene, struct Brush *brush, float alpha);
float BKE_brush_weight_get(const Scene *scene, struct Brush *brush);
void BKE_brush_weight_set(const Scene *scene, struct Brush *brush, float value);
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 2b2497f..af5e925 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -63,14 +63,12 @@ DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_
/* merge verts */
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap);
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob);
-
/* creates a CDDerivedMesh from the given curve object */
struct DerivedMesh *CDDM_from_curve(struct Object *ob);
/* creates a CDDerivedMesh from the given curve object and specified dispbase */
/* useful for OrcoDM creation for curves with constructive modifiers */
-DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr);
+DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 686a60a..c79dc62 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -108,8 +108,8 @@ typedef struct bConstraintTypeInfo {
} bConstraintTypeInfo;
/* Function Prototypes for bConstraintTypeInfo's */
-bConstraintTypeInfo *constraint_get_typeinfo(struct bConstraint *con);
-bConstraintTypeInfo *get_constraint_typeinfo(int type);
+bConstraintTypeInfo *BKE_constraint_get_typeinfo(struct bConstraint *con);
+bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type);
/* ---------------------------------------------------------------------------- */
/* Useful macros for testing various common flag combinations */
@@ -120,38 +120,38 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type);
/* ---------------------------------------------------------------------------- */
/* Constraint function prototypes */
-void unique_constraint_name(struct bConstraint *con, struct ListBase *list);
+void BKE_unique_constraint_name(struct bConstraint *con, struct ListBase *list);
-void free_constraints(struct ListBase *list);
-void copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
-void relink_constraints(struct ListBase *list);
-void id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
-void free_constraint_data(struct bConstraint *con);
+void BKE_free_constraints(struct ListBase *list);
+void BKE_copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
+void BKE_relink_constraints(struct ListBase *list);
+void BKE_id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
+void BKE_free_constraint_data(struct bConstraint *con);
/* Constraint API function prototypes */
-struct bConstraint *constraints_get_active(struct ListBase *list);
-void constraints_set_active(ListBase *list, struct bConstraint *con);
-struct bConstraint *constraints_findByName(struct ListBase *list, const char *name);
-
-struct bConstraint *add_ob_constraint(struct Object *ob, const char *name, short type);
-struct bConstraint *add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
+struct bConstraint *BKE_constraints_get_active(struct ListBase *list);
+void BKE_constraints_set_active(ListBase *list, struct bConstraint *con);
+struct bConstraint *BKE_constraints_findByName(struct ListBase *list, const char *name);
+
+struct bConstraint *BKE_add_ob_constraint(struct Object *ob, const char *name, short type);
+struct bConstraint *BKE_add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
-int remove_constraint(ListBase *list, struct bConstraint *con);
-void remove_constraints_type(ListBase *list, short type, short last_only);
+int BKE_remove_constraint(ListBase *list, struct bConstraint *con);
+void BKE_remove_constraints_type(ListBase *list, short type, short last_only);
/* Constraints + Proxies function prototypes */
-void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
-short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
+void BKE_extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
+short BKE_proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
-struct bConstraintOb *constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
-void constraints_clear_evalob(struct bConstraintOb *cob);
+struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
+void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
-void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to);
+void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
-void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
-void get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
-void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
+void BKE_get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
+void BKE_get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
+void BKE_solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 22b8f47..285077f 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -185,6 +185,7 @@ enum {
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
ListBase CTX_data_collection_get(const bContext *C, const char *member);
+ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all);
ListBase CTX_data_dir_get(const bContext *C);
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 4736e7b..36733d1 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -39,6 +39,7 @@ extern "C" {
#endif
#include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */
+#include "BLI_utildefines.h"
struct BMesh;
struct ID;
@@ -215,6 +216,8 @@ void CustomData_free_elem(struct CustomData *data, int index, int count);
void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
int *src_indices, float *weights, float *sub_weights,
int count, int dest_index);
+void CustomData_bmesh_interp_n(struct CustomData *data, void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dest_block, int n);
void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
const float *weights, const float *sub_weights, int count,
void *dest_block);
@@ -246,6 +249,8 @@ void *CustomData_get_layer(const struct CustomData *data, int type);
void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
void *CustomData_get_layer_named(const struct CustomData *data, int type,
const char *name);
+int CustomData_get_offset(const struct CustomData *data, int type);
+int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
int CustomData_get_layer_index(const struct CustomData *data, int type);
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n);
@@ -304,7 +309,7 @@ void CustomData_bmesh_free_block(struct CustomData *data, void **block);
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
* blocks of data. the CustomData's must not be compatible */
void CustomData_to_bmesh_block(const struct CustomData *source,
- struct CustomData *dest, int src_index, void **dest_block);
+ struct CustomData *dest, int src_index, void **dest_block, bool use_default_init);
void CustomData_from_bmesh_block(const struct CustomData *source,
struct CustomData *dest, void *src_block, int dest_index);
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 8306da7..ab27421 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -56,6 +56,9 @@ void defvert_remove_group(struct MDeformVert *dvert, struct
void defvert_clear(struct MDeformVert *dvert);
int defvert_find_shared(const struct MDeformVert *dvert_a, const struct MDeformVert *dvert_b);
+void BKE_defvert_array_free(struct MDeformVert *dvert, int totvert);
+void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *src, int totvert);
+
float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 758a2a8..6b986cd 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -83,7 +83,7 @@ void BKE_displist_elem_free(DispList *dl);
DispList *BKE_displist_find_or_create(struct ListBase *lb, int type);
DispList *BKE_displist_find(struct ListBase *lb, int type);
void BKE_displist_normals_add(struct ListBase *lb);
-void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface);
+void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *tottri);
void BKE_displist_free(struct ListBase *lb);
int BKE_displist_has_faces(struct ListBase *lb);
diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h
index c3fa662..433c10b 100644
--- a/source/blender/blenkernel/BKE_fluidsim.h
+++ b/source/blender/blenkernel/BKE_fluidsim.h
@@ -47,7 +47,7 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
int useGlobalCoords, int modifierIndex);
/* bounding box & memory estimate */
-void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4],
+void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[4][4],
float start[3], float size[3]);
void fluid_estimate_memory(struct Object *ob, struct FluidsimSettings *fss, char *value);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index f6276a6..5458568 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -114,7 +114,7 @@ typedef struct Global {
#define G_BACKBUFSEL (1 << 4)
#define G_PICKSEL (1 << 5)
-/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
+/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_FACE_SEL) */
#define G_SCRIPT_AUTOEXEC (1 << 13)
#define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
@@ -149,7 +149,7 @@ enum {
/* #define G_FILE_SHOW_PROFILE (1 << 6) */ /* deprecated */
#define G_FILE_LOCK (1 << 7)
#define G_FILE_SIGN (1 << 8)
-/* #define G_FILE_PUBLISH (1 << 9) */ /* deprecated */
+#define G_FILE_USERPREFS (1 << 9)
#define G_FILE_NO_UI (1 << 10)
/* #define G_FILE_GAME_TO_IPO (1 << 11) */ /* deprecated */
#define G_FILE_GAME_MAT (1 << 12) /* deprecated */
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index a9f6a61..ad3e4bb 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -315,6 +315,8 @@ __attribute__((nonnull))
* the actual struct IDProperty struct either.*/
void IDP_FreeProperty(struct IDProperty *prop);
+void IDP_ClearProperty(IDProperty *prop);
+
/** Unlinks any struct IDProperty<->ID linkage that might be going on.*/
void IDP_UnlinkProperty(struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1f9630d..4996099 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -60,8 +60,10 @@ int BKE_imbuf_alpha_test(struct ImBuf *ibuf);
int BKE_imbuf_write_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const short is_copy);
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames);
-int BKE_add_image_extension(char *string, const char imtype);
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const struct ImageFormatData *im_format, const short use_ext, const short use_frames);
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames);
+int BKE_add_image_extension(char *string, const struct ImageFormatData *im_format);
+int BKE_add_image_extension_from_type(char *string, const char imtype);
char BKE_ftype_to_imtype(const int ftype);
int BKE_imtype_to_ftype(const char imtype);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index d7d75b4..a159cbb 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -59,7 +59,7 @@ void key_curve_position_weights(float t, float data[4], int type);
void key_curve_tangent_weights(float t, float data[4], int type);
void key_curve_normal_weights(float t, float data[4], int type);
-float *do_ob_key(struct Scene *scene, struct Object *ob);
+float *BKE_key_evaluate_object(struct Scene *scene, struct Object *ob, int *r_totelem);
struct Key *BKE_key_from_object(struct Object *ob);
struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 34baa48..a0bebd7 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -59,7 +59,7 @@ void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object
struct DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis);
void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target,
- float orco[3], float vec[3], float mat[][3], int no_rot_axis);
+ float orco[3], float vec[3], float mat[3][3], int no_rot_axis);
void lattice_deform_verts(struct Object *laOb, struct Object *target,
struct DerivedMesh *dm, float (*vertexCos)[3],
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index cfdcf14..1b7b294 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -51,9 +51,10 @@ struct Library;
typedef struct Main {
struct Main *next, *prev;
char name[1024]; /* 1024 = FILE_MAX */
- short versionfile, subversionfile;
+ short versionfile, subversionfile; /* see BLENDER_VERSION, BLENDER_SUBVERSION */
short minversionfile, minsubversionfile;
- int revision; /* svn revision of binary that saved file */
+ int revision; /* svn revision of binary that saved file */
+ short recovered; /* indicate the main->name (file) is the recovered one */
struct Library *curlib;
ListBase scene;
@@ -91,6 +92,8 @@ typedef struct Main {
char id_tag_update[256];
} Main;
+#define MAIN_VERSION_ATLEAST(main, ver, subver) \
+ ((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver)))
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index e53d0ef..3466a91 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -123,6 +123,17 @@ void BKE_mesh_flush_hidden_from_verts(const struct MVert *mvert,
struct MEdge *medge, int totedge,
struct MPoly *mpoly, int totpoly);
+void BKE_mesh_flush_select_from_polys_ex(struct MVert *mvert, const int totvert,
+ struct MLoop *mloop,
+ struct MEdge *medge, const int totedge,
+ const struct MPoly *mpoly, const int totpoly);
+void BKE_mesh_flush_select_from_polys(struct Mesh *me);
+void BKE_mesh_flush_select_from_verts_ex(const struct MVert *mvert, const int totvert,
+ struct MLoop *mloop,
+ struct MEdge *medge, const int totedge,
+ struct MPoly *mpoly, const int totpoly);
+void BKE_mesh_flush_select_from_verts(struct Mesh *me);
+
void BKE_mesh_unlink(struct Mesh *me);
void BKE_mesh_free(struct Mesh *me, int unlink);
struct Mesh *BKE_mesh_add(const char *name);
@@ -132,7 +143,7 @@ void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess
void BKE_mesh_make_local(struct Mesh *me);
void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]);
void BKE_mesh_texspace_calc(struct Mesh *me);
-float *BKE_mesh_orco_verts_get(struct Object *ob);
+float (*BKE_mesh_orco_verts_get(struct Object *ob))[3];
void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert);
int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
struct Mesh *BKE_mesh_from_object(struct Object *ob);
@@ -143,16 +154,10 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot
int *totloop, int *totpoly);
int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly,
- int *_totloop, int *_totpoly, int **orco_index_ptr);
-void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly,
- struct MLoop *mloops, struct MLoopUV *mloopuvs,
- float (*orco)[3], int (*orco_index)[4]);
+ struct MLoopUV **alluv, int *_totloop, int *_totpoly);
+void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv);
void BKE_mesh_from_nurbs(struct Object *ob);
-void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
- int **orco_index_ptr);
void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
-void free_dverts(struct MDeformVert *dvert, int totvert);
-void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
@@ -229,8 +234,6 @@ typedef struct UvElement {
/* Next UvElement corresponding to same vertex */
struct UvElement *next;
/* Face the element belongs to */
- struct BMFace *face;
- /* Index in the editFace of the uv */
struct BMLoop *l;
/* index in loop. */
unsigned short tfindex;
@@ -327,6 +330,8 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData
void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop,
struct MPoly *mp, float angles[]);
+void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 2fa78b3..cc260b8 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -358,8 +358,6 @@ int modifiers_isCorrectableDeformed(struct Object *ob);
void modifier_freeTemporaryData(struct ModifierData *md);
int modifiers_isPreview(struct Object *ob);
-int modifiers_indexInObject(struct Object *ob, struct ModifierData *md);
-
typedef struct CDMaskLink {
struct CDMaskLink *next;
CustomDataMask mask;
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b8f168c..0a2f757 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -557,6 +557,7 @@ struct ShadeResult;
#define SH_NODE_BSDF_REFRACTION 173
#define SH_NODE_TANGENT 174
#define SH_NODE_NORMAL_MAP 175
+#define SH_NODE_HAIR_INFO 176
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 6c9dc0f..bfae1bd 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -76,7 +76,8 @@ void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
void BKE_object_unlink(struct Object *ob);
int BKE_object_exists_check(struct Object *obtest);
-
+int BKE_object_is_in_editmode(struct Object *ob);
+
struct Object *BKE_object_add_only_object(int type, const char *name);
struct Object *BKE_object_add(struct Scene *scene, int type);
void *BKE_object_obdata_add_from_type(int type);
@@ -87,12 +88,12 @@ void BKE_object_make_local(struct Object *ob);
int BKE_object_is_libdata(struct Object *ob);
int BKE_object_obdata_is_libdata(struct Object *ob);
-void BKE_object_scale_to_mat3(struct Object *ob, float mat[][3]);
-void BKE_object_rot_to_mat3(struct Object *ob, float mat[][3], short use_drot);
-void BKE_object_mat3_to_rot(struct Object *ob, float mat[][3], short use_compat);
-void BKE_object_to_mat3(struct Object *ob, float mat[][3]);
-void BKE_object_to_mat4(struct Object *ob, float mat[][4]);
-void BKE_object_apply_mat4(struct Object *ob, float mat[][4], const short use_compat, const short use_parent);
+void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
+void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], short use_drot);
+void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], short use_compat);
+void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
+void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
+void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const short use_compat, const short use_parent);
int BKE_object_pose_context_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index 603cb1f..9dcbb41 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -48,6 +48,7 @@ struct PackedFile *newPackedFile(struct ReportList *reports, const char *filenam
struct PackedFile *newPackedFileMemory(void *mem, int memlen);
void packAll(struct Main *bmain, struct ReportList *reports);
+void packLibraries(struct Main *bmain, struct ReportList *reports);
/* unpack */
char *unpackFile(struct ReportList *reports, const char *abs_name, const char *local_name, struct PackedFile *pf, int how);
@@ -55,6 +56,7 @@ int unpackVFont(struct ReportList *reports, struct VFont *vfont, int how);
int unpackSound(struct Main *bmain, struct ReportList *reports, struct bSound *sound, int how);
int unpackImage(struct ReportList *reports, struct Image *ima, int how);
void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
+int unpackLibraries(struct Main *bmain, struct ReportList *reports);
int writePackedFile(struct ReportList *reports, const char *filename, struct PackedFile *pf, int guimode);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index c452c17..0a4a7f7 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -33,6 +33,7 @@
*/
struct bContext;
+struct BMesh;
struct Brush;
struct MDisps;
struct MeshElemMap;
@@ -92,6 +93,12 @@ typedef struct SculptSession {
/* Mesh connectivity */
const struct MeshElemMap *pmap;
+ /* BMesh for dynamic topology sculpting */
+ struct BMesh *bm;
+ int bm_smooth_shading;
+ /* Undo/redo log for dynamic topology sculpting */
+ struct BMLog *bm_log;
+
/* PBVH acceleration structure */
struct PBVH *pbvh;
int show_diffuse_color;
@@ -121,5 +128,6 @@ typedef struct SculptSession {
void free_sculptsession(struct Object *ob);
void free_sculptsession_deformMats(struct SculptSession *ss);
+void sculptsession_bm_to_me(struct Object *ob, int reorder);
#endif
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index ec03f53..f15ad29 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -20,7 +20,9 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Adaptive time step
+ * Classical SPH
+ * Copyright 2011-2012 AutoCRC
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -58,6 +60,7 @@ struct RNG;
struct SurfaceModifierData;
struct BVHTreeRay;
struct BVHTreeRayHit;
+struct EdgeHash;
#define PARTICLE_P ParticleData * pa; int p
#define LOOP_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++)
@@ -85,6 +88,24 @@ typedef struct ParticleSimulationData {
float courant_num;
} ParticleSimulationData;
+typedef struct SPHData {
+ ParticleSystem *psys[10];
+ ParticleData *pa;
+ float mass;
+ struct EdgeHash *eh;
+ float *gravity;
+ float hfac;
+ /* Average distance to neighbours (other particles in the support domain),
+ for calculating the Courant number (adaptive time step). */
+ int pass;
+ float element_size;
+ float flow[3];
+
+ /* Integrator callbacks. This allows different SPH implementations. */
+ void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
+ void (*density_cb) (void *rangedata_v, int index, float squared_dist);
+} SPHData;
+
typedef struct ParticleTexture {
float ivel; /* used in reset */
float time, life, exist, size; /* used in init */
@@ -247,7 +268,7 @@ void BKE_particlesettings_free(struct ParticleSettings *part);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
void psys_free(struct Object *ob, struct ParticleSystem *psys);
-void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset);
+void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
@@ -283,12 +304,16 @@ float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel);
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
+void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata);
+void psys_sph_finalise(struct SPHData *sphdata);
+void psys_sph_density(struct BVHTree *tree, struct SPHData* data, float co[3], float vars[2]);
+
/* for anim.c */
void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part,
struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa,
float uv[2], float orco[3]);
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa,
- struct ParticleCacheKey *cache, float mat[][4], float *scale);
+ struct ParticleCacheKey *cache, float mat[4][4], float *scale);
ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
void psys_threads_free(ParticleThread *threads);
@@ -322,9 +347,9 @@ void psys_free_children(struct ParticleSystem *psys);
void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity);
void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]);
-void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
-void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
-void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
+void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
+void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
+void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
float psys_get_dietime_from_cache(struct PointCache *cache, int index);
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
new file mode 100644
index 0000000..709db7e
--- /dev/null
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -0,0 +1,329 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_PBVH_H__
+#define __BKE_PBVH_H__
+
+/** \file BKE_pbvh.h
+ * \ingroup bke
+ * \brief A BVH for high poly meshes.
+ */
+
+#include "BLI_bitmap.h"
+#include "BLI_ghash.h"
+#include "BLI_utildefines.h"
+
+/* Needed for BMesh functions used in the PBVH iterator macro */
+#include "bmesh.h"
+
+struct CCGElem;
+struct CCGKey;
+struct CustomData;
+struct DMFlagMat;
+struct DMGridAdjacency;
+struct GHash;
+struct MFace;
+struct MVert;
+struct PBVH;
+struct PBVHNode;
+
+typedef struct PBVH PBVH;
+typedef struct PBVHNode PBVHNode;
+
+typedef struct {
+ float (*co)[3];
+} PBVHProxyNode;
+
+/* Callbacks */
+
+/* returns 1 if the search should continue from this node, 0 otherwise */
+typedef int (*BKE_pbvh_SearchCallback)(PBVHNode *node, void *data);
+
+typedef void (*BKE_pbvh_HitCallback)(PBVHNode *node, void *data);
+typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin);
+
+/* Building */
+
+PBVH *BKE_pbvh_new(void);
+void BKE_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
+ int totface, int totvert, struct CustomData *vdata);
+void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
+ struct DMGridAdjacency *gridadj, int totgrid,
+ struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
+ unsigned int **grid_hidden);
+void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
+ struct BMLog *log);
+
+void BKE_pbvh_free(PBVH *bvh);
+
+/* Hierarchical Search in the BVH, two methods:
+ * - for each hit calling a callback
+ * - gather nodes in an array (easy to multithread) */
+
+void BKE_pbvh_search_callback(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitCallback hcb, void *hit_data);
+
+void BKE_pbvh_search_gather(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ PBVHNode ***array, int *tot);
+
+/* Raycast
+ * the hit callback is called for all leaf nodes intersecting the ray;
+ * it's up to the callback to find the primitive within the leaves that is
+ * hit first */
+
+void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
+ const float ray_start[3], const float ray_normal[3],
+ int original);
+
+int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
+ const float ray_start[3], const float ray_normal[3],
+ float *dist);
+
+/* Drawing */
+
+void BKE_pbvh_node_draw(PBVHNode *node, void *data);
+void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
+ int (*setMaterial)(int, void *attribs), int wireframe);
+
+/* PBVH Access */
+typedef enum {
+ PBVH_FACES,
+ PBVH_GRIDS,
+ PBVH_BMESH
+} PBVHType;
+
+PBVHType BKE_pbvh_type(const PBVH *bvh);
+
+/* multires hidden data, only valid for type == PBVH_GRIDS */
+unsigned int **BKE_pbvh_grid_hidden(const PBVH *bvh);
+
+/* multires level, only valid for type == PBVH_GRIDS */
+void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+
+/* Only valid for type == PBVH_BMESH */
+BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
+void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
+
+typedef enum {
+ PBVH_Subdivide = 1,
+ PBVH_Collapse = 2,
+} PBVHTopologyUpdateMode;
+int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius);
+
+/* Node Access */
+
+typedef enum {
+ PBVH_Leaf = 1,
+
+ PBVH_UpdateNormals = 2,
+ PBVH_UpdateBB = 4,
+ PBVH_UpdateOriginalBB = 8,
+ PBVH_UpdateDrawBuffers = 16,
+ PBVH_UpdateRedraw = 32,
+
+ PBVH_RebuildDrawBuffers = 64,
+ PBVH_FullyHidden = 128,
+
+ PBVH_UpdateTopology = 256,
+} PBVHNodeFlags;
+
+void BKE_pbvh_node_mark_update(PBVHNode *node);
+void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node);
+void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+void BKE_pbvh_node_mark_topology_update(PBVHNode *node);
+
+void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
+ int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
+ struct CCGElem ***grid_elems, struct DMGridAdjacency **gridadj);
+void BKE_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node,
+ int *uniquevert, int *totvert);
+void BKE_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
+ int **vert_indices, struct MVert **verts);
+
+void BKE_pbvh_node_get_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_node_get_original_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
+
+float BKE_pbvh_node_get_tmin(PBVHNode *node);
+
+/* test if AABB is at least partially inside the planes' volume */
+int BKE_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
+/* test if AABB is at least partially outside the planes' volume */
+int BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
+
+struct GHash *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node);
+struct GHash *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node);
+void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node);
+void BKE_pbvh_bmesh_after_stroke(PBVH *bvh);
+
+/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
+
+void BKE_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
+void BKE_pbvh_redraw_BB(PBVH * bvh, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
+void BKE_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
+ struct DMGridAdjacency *gridadj, void **gridfaces,
+ struct DMFlagMat *flagmats, unsigned int **grid_hidden);
+
+/* Layer displacement */
+
+/* Get the node's displacement layer, creating it if necessary */
+float *BKE_pbvh_node_layer_disp_get(PBVH *pbvh, PBVHNode *node);
+
+/* If the node has a displacement layer, free it and set to null */
+void BKE_pbvh_node_layer_disp_free(PBVHNode *node);
+
+/* vertex deformer */
+float (*BKE_pbvh_get_vertCos(struct PBVH *pbvh))[3];
+void BKE_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
+int BKE_pbvh_isDeformed(struct PBVH *pbvh);
+
+/* Vertex Iterator */
+
+/* this iterator has quite a lot of code, but it's designed to:
+ * - allow the compiler to eliminate dead code and variables
+ * - spend most of the time in the relatively simple inner loop */
+
+/* note: PBVH_ITER_ALL does not skip hidden vertices,
+ * PBVH_ITER_UNIQUE does */
+#define PBVH_ITER_ALL 0
+#define PBVH_ITER_UNIQUE 1
+
+typedef struct PBVHVertexIter {
+ /* iteration */
+ int g;
+ int width;
+ int height;
+ int gx;
+ int gy;
+ int i;
+
+ /* grid */
+ struct CCGElem **grids;
+ struct CCGElem *grid;
+ struct CCGKey *key;
+ BLI_bitmap *grid_hidden, gh;
+ int *grid_indices;
+ int totgrid;
+ int gridsize;
+
+ /* mesh */
+ struct MVert *mverts;
+ int totvert;
+ int *vert_indices;
+ float *vmask;
+
+ /* bmesh */
+ struct GHashIterator bm_unique_verts;
+ struct GHashIterator bm_other_verts;
+ struct CustomData *bm_vdata;
+
+ /* result: these are all computed in the macro, but we assume
+ * that compiler optimization's will skip the ones we don't use */
+ struct MVert *mvert;
+ struct BMVert *bm_vert;
+ float *co;
+ short *no;
+ float *fno;
+ float *mask;
+} PBVHVertexIter;
+
+#ifdef _MSC_VER
+#pragma warning (disable:4127) // conditional expression is constant
+#endif
+
+void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
+ PBVHVertexIter *vi, int mode);
+
+#define BKE_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
+ pbvh_vertex_iter_init(bvh, node, &vi, mode); \
+ \
+ for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \
+ if (vi.grids) { \
+ vi.width = vi.gridsize; \
+ vi.height = vi.gridsize; \
+ vi.grid = vi.grids[vi.grid_indices[vi.g]]; \
+ if (mode == PBVH_ITER_UNIQUE) \
+ vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \
+ } \
+ else { \
+ vi.width = vi.totvert; \
+ vi.height = 1; \
+ } \
+ \
+ for (vi.gy = 0; vi.gy < vi.height; vi.gy++) { \
+ for (vi.gx = 0; vi.gx < vi.width; vi.gx++, vi.i++) { \
+ if (vi.grid) { \
+ vi.co = CCG_elem_co(vi.key, vi.grid); \
+ vi.fno = CCG_elem_no(vi.key, vi.grid); \
+ vi.mask = vi.key->has_mask ? CCG_elem_mask(vi.key, vi.grid) : NULL; \
+ vi.grid = CCG_elem_next(vi.key, vi.grid); \
+ if (vi.gh) { \
+ if (BLI_BITMAP_GET(vi.gh, vi.gy * vi.gridsize + vi.gx)) \
+ continue; \
+ } \
+ } \
+ else if (vi.mverts) { \
+ vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
+ if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
+ continue; \
+ vi.co = vi.mvert->co; \
+ vi.no = vi.mvert->no; \
+ if (vi.vmask) \
+ vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
+ } \
+ else { \
+ if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
+ BLI_ghashIterator_step(&vi.bm_unique_verts); \
+ } \
+ else { \
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_other_verts); \
+ BLI_ghashIterator_step(&vi.bm_other_verts); \
+ } \
+ if (mode == PBVH_ITER_UNIQUE && \
+ BM_elem_flag_test(vi.bm_vert, BM_ELEM_HIDDEN)) \
+ continue; \
+ vi.co = vi.bm_vert->co; \
+ vi.fno = vi.bm_vert->no; \
+ vi.mask = CustomData_bmesh_get(vi.bm_vdata, \
+ vi.bm_vert->head.data, \
+ CD_PAINT_MASK); \
+ }
+
+#define BKE_pbvh_vertex_iter_end \
+ } \
+ } \
+ }
+
+void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
+void BKE_pbvh_node_free_proxies(PBVHNode *node);
+PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node);
+void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***nodes, int *totnode);
+
+//void BKE_pbvh_node_BB_reset(PBVHNode *node);
+//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
+
+void pbvh_show_diffuse_color_set(PBVH *bvh, int show_diffuse_color);
+
+#endif /* __BKE_PBVH_H__ */
+
diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h
index e0eb8c0..99e6075 100644
--- a/source/blender/blenkernel/BKE_property.h
+++ b/source/blender/blenkernel/BKE_property.h
@@ -47,6 +47,7 @@ void BKE_bproperty_object_set(struct Object *ob, struct bProperty *
// int BKE_bproperty_cmp(struct bProperty *prop, const char *str);
void BKE_bproperty_set(struct bProperty *prop, const char *str);
void BKE_bproperty_add(struct bProperty *prop, const char *str);
-void BKE_bproperty_set_valstr(struct bProperty *prop, char *str);
+/* should really be called '_get_valstr()' or '_as_string()' */
+void BKE_bproperty_set_valstr(struct bProperty *prop, char str[MAX_PROPSTRING]);
#endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 4d69a01..e659954 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -35,6 +35,7 @@ extern "C" {
#endif
#include "DNA_windowmanager_types.h"
+#include "BLI_utildefines.h"
/* Reporting Information and Errors
*
@@ -72,7 +73,10 @@ void BKE_reports_print(ReportList *reports, ReportType level);
Report *BKE_reports_last_displayable(ReportList *reports);
int BKE_reports_contain(ReportList *reports, ReportType level);
-
+
+bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header);
+bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 9927c7a..6447b2a 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -47,7 +47,7 @@ struct RenderData;
struct SceneRenderLayer;
struct Scene;
struct Text;
-struct Text;
+struct Main;
#define SCE_COPY_NEW 0
#define SCE_COPY_EMPTY 1
@@ -67,7 +67,7 @@ void free_avicodecdata(struct AviCodecData *acd);
void free_qtcodecdata(struct QuicktimeCodecData *acd);
void BKE_scene_free(struct Scene *sce);
-struct Scene *BKE_scene_add(const char *name);
+struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
/* base functions */
struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 8aa08be..3c6f886 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -46,6 +46,7 @@ struct bContext;
struct bContextDataResult;
struct bScreen;
struct uiLayout;
+struct uiList;
struct uiMenuItem;
struct wmKeyConfig;
struct wmNotifier;
@@ -181,6 +182,23 @@ typedef struct PanelType {
ExtensionRNA ext;
} PanelType;
+/* uilist types */
+
+/* draw an item in the uiList */
+typedef void (*uiListDrawItemFunc)(struct uiList *, struct bContext *, struct uiLayout *, struct PointerRNA *,
+ struct PointerRNA *, int, struct PointerRNA *, const char *, int);
+
+typedef struct uiListType {
+ struct uiListType *next, *prev;
+
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+
+ uiListDrawItemFunc draw_item;
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} uiListType;
+
/* header types */
typedef struct HeaderType {
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 88294cb..e3d9c51 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -363,7 +363,7 @@ struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seq
struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
/* view3d draw callback, run when not in background view */
-typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, char[256]);
+typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, int, char[256]);
extern SequencerDrawView sequencer_view3d_cb;
/* copy/paste */
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index d1332ba..61d82e6 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -121,7 +121,8 @@ typedef struct ShrinkwrapCalcData {
} ShrinkwrapCalcData;
-void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
+void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts);
/*
* This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:
@@ -130,9 +131,12 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object
* then the input (vert, dir, BVHTreeRayHit) must be defined in ob1 coordinates space
* and the BVHTree must be built in ob2 coordinate space.
*
- * Thus it provides an easy way to cast the same ray across several trees (where each tree was built on its own coords space)
+ * Thus it provides an easy way to cast the same ray across several trees
+ * (where each tree was built on its own coords space)
*/
-int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata);
+int normal_projection_project_vertex(char options, const float vert[3], const float dir[3],
+ const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback, void *userdata);
/*
* NULL initializers to local data
@@ -142,6 +146,4 @@ int normal_projection_project_vertex(char options, const float *vert, const floa
#define NULL_BVHTreeRayHit {NULL, }
#define NULL_BVHTreeNearest {0, }
-
-#endif
-
+#endif /* __BKE_SHRINKWRAP_H__ */
diff --git a/source/blender/blenkernel/BKE_suggestions.h b/source/blender/blenkernel/BKE_suggestions.h
index 9b61d91..c36a2d6 100644
--- a/source/blender/blenkernel/BKE_suggestions.h
+++ b/source/blender/blenkernel/BKE_suggestions.h
@@ -75,7 +75,7 @@ short texttool_text_is_active(Text *text);
/* Suggestions */
void texttool_suggest_add(const char *name, char type);
-void texttool_suggest_prefix(const char *prefix);
+void texttool_suggest_prefix(const char *prefix, const int prefix_len);
void texttool_suggest_clear(void);
SuggItem *texttool_suggest_first(void);
SuggItem *texttool_suggest_last(void);
diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h
index dea5e72..9462822 100644
--- a/source/blender/blenkernel/BKE_tessmesh.h
+++ b/source/blender/blenkernel/BKE_tessmesh.h
@@ -80,12 +80,11 @@ typedef struct BMEditMesh {
/*temp variables for x-mirror editing*/
int mirror_cdlayer; /* -1 is invalid */
- int mirr_free_arrays;
} BMEditMesh;
-void BMEdit_RecalcTessellation(BMEditMesh *tm);
+void BMEdit_RecalcTessellation(BMEditMesh *em);
BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate);
-BMEditMesh *BMEdit_Copy(BMEditMesh *tm);
+BMEditMesh *BMEdit_Copy(BMEditMesh *em);
BMEditMesh *BMEdit_FromObject(struct Object *ob);
void BMEdit_Free(BMEditMesh *em);
void BMEdit_UpdateLinkedCustomData(BMEditMesh *em);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index accac86..1e3dd42 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -106,6 +106,7 @@ int text_check_delim(const char ch);
int text_check_digit(const char ch);
int text_check_identifier(const char ch);
int text_check_whitespace(const char ch);
+int text_find_identifier_start(const char *str, int i);
enum {
TXT_MOVE_LINE_UP = -1,
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2da9b40..aca06a1 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -58,6 +58,7 @@ set(SRC
intern/CCGSubSurf.c
intern/DerivedMesh.c
intern/action.c
+ intern/addon.c
intern/anim.c
intern/anim_sys.c
intern/armature.c
@@ -65,6 +66,7 @@ set(SRC
intern/bmfont.c
intern/boids.c
intern/booleanops_mesh.c
+ intern/bpath.c
intern/brush.c
intern/bullet.c
intern/bvhutils.c
@@ -101,9 +103,9 @@ set(SRC
intern/lamp.c
intern/lattice.c
intern/library.c
+ intern/mask.c
intern/mask_evaluate.c
intern/mask_rasterize.c
- intern/mask.c
intern/material.c
intern/mball.c
intern/mesh.c
@@ -121,6 +123,8 @@ set(SRC
intern/paint.c
intern/particle.c
intern/particle_system.c
+ intern/pbvh.c
+ intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
intern/report.c
@@ -147,9 +151,10 @@ set(SRC
intern/world.c
intern/writeavi.c
intern/writeframeserver.c
-
+
BKE_DerivedMesh.h
BKE_action.h
+ BKE_addon.h
BKE_anim.h
BKE_animsys.h
BKE_armature.h
@@ -159,6 +164,7 @@ set(SRC
BKE_bmfont_types.h
BKE_boids.h
BKE_booleanops_mesh.h
+ BKE_bpath.h
BKE_brush.h
BKE_bullet.h
BKE_bvhutils.h
@@ -209,6 +215,7 @@ set(SRC
BKE_packedFile.h
BKE_paint.h
BKE_particle.h
+ BKE_pbvh.h
BKE_pointcache.h
BKE_property.h
BKE_report.h
@@ -234,9 +241,11 @@ set(SRC
BKE_world.h
BKE_writeavi.h
BKE_writeframeserver.h
+
depsgraph_private.h
nla_private.h
intern/CCGSubSurf.h
+ intern/pbvh_intern.h
)
add_definitions(-DGLEW_STATIC)
@@ -250,7 +259,7 @@ endif()
if(WITH_BULLET)
list(APPEND INC_SYS
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
)
add_definitions(-DUSE_BULLET)
endif()
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 22be2f7..0286172 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import os
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d09bea0..dde1d58 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -47,10 +47,10 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_array.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
+#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_displist.h"
#include "BKE_key.h"
@@ -313,6 +313,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type
CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numPolys);
+ dm->cd_flag = source->cd_flag;
+
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
@@ -483,11 +485,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
totedge = tmp.totedge = dm->getNumEdges(dm);
totloop = tmp.totloop = dm->getNumLoops(dm);
totpoly = tmp.totpoly = dm->getNumPolys(dm);
+ tmp.totface = 0;
CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
+ me->cd_flag = dm->cd_flag;
if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
KeyBlock *kb;
@@ -538,9 +542,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
}
/* yes, must be before _and_ after tessellate */
- mesh_update_customdata_pointers(&tmp, TRUE);
+ mesh_update_customdata_pointers(&tmp, false);
- BKE_mesh_tessface_calc(&tmp);
+ /* since 2.65 caller must do! */
+ // BKE_mesh_tessface_calc(&tmp);
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
@@ -857,30 +862,27 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
return dm;
}
-static float *get_editbmesh_orco_verts(BMEditMesh *em)
+static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
{
BMIter iter;
BMVert *eve;
- float *orco;
- int a, totvert;
+ float (*orco)[3];
+ int i;
/* these may not really be the orco's, but it's only for preview.
* could be solver better once, but isn't simple */
-
- totvert = em->bm->totvert;
- orco = MEM_mallocN(sizeof(float) * 3 * totvert, "BMEditMesh Orco");
+ orco = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "BMEditMesh Orco");
- eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
- for (a = 0; eve; eve = BM_iter_step(&iter), a += 3) {
- copy_v3_v3(orco + a, eve->co);
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ copy_v3_v3(orco[i], eve->co);
}
return orco;
}
/* orco custom data layer */
-static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
+static float (*get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free))[3]
{
*free = 0;
@@ -889,9 +891,9 @@ static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free
*free = 1;
if (em)
- return (float(*)[3])get_editbmesh_orco_verts(em);
+ return get_editbmesh_orco_verts(em);
else
- return (float(*)[3])BKE_mesh_orco_verts_get(ob);
+ return BKE_mesh_orco_verts_get(ob);
}
else if (layer == CD_CLOTH_ORCO) {
/* apply shape key for cloth, this should really be solved
@@ -1343,6 +1345,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
int has_multires = mmd != NULL, multires_applied = 0;
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
+ int sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
(scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
@@ -1410,7 +1413,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if (!modifier_isEnabled(scene, md, required_mode)) continue;
if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
- if (mti->type == eModifierTypeType_OnlyDeform) {
+ if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
if (!deformedVerts)
deformedVerts = mesh_getVertexCos(me, &numVerts);
@@ -1421,7 +1424,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
/* grab modifiers until index i */
- if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
+ if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index))
break;
}
@@ -1468,9 +1471,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
modifier_setError(md, "Modifier requires original data, bad stack position");
continue;
}
- if (sculpt_mode && (!has_multires || multires_applied)) {
+ if (sculpt_mode &&
+ (!has_multires || multires_applied || ob->sculpt->bm))
+ {
int unsupported = 0;
+ if (sculpt_dyntopo)
+ unsupported = TRUE;
+
if (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
unsupported |= mti->type != eModifierTypeType_OnlyDeform;
@@ -1666,7 +1674,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
/* grab modifiers until index i */
- if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
+ if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index))
break;
if (sculpt_mode && md->type == eModifierType_Multires)
@@ -1815,17 +1823,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
BLI_linklist_free((LinkNode *)datamasks, NULL);
}
-float (*editbmesh_get_vertex_cos(BMEditMesh * em, int *numVerts_r))[3]
+float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3]
{
- int i, numVerts = *numVerts_r = em->bm->totvert;
- float (*cos)[3];
BMIter iter;
BMVert *eve;
+ float (*cos)[3];
+ int i;
+
+ *numVerts_r = em->bm->totvert;
- cos = MEM_mallocN(sizeof(float) * 3 * numVerts, "vertexcos");
+ cos = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "vertexcos");
- eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
- for (i = 0; eve; eve = BM_iter_step(&iter), i++) {
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
copy_v3_v3(cos[i], eve->co);
}
@@ -2312,20 +2321,19 @@ DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
static void make_vertexcosnos__mapFunc(void *userData, int index, const float co[3],
const float no_f[3], const short no_s[3])
{
- float *vec = userData;
-
- vec += 6 * index;
+ DMCoNo *co_no = &((DMCoNo *)userData)[index];
/* check if we've been here before (normal should not be 0) */
- if (vec[3] || vec[4] || vec[5]) return;
+ if (!is_zero_v3(co_no->no)) {
+ return;
+ }
- copy_v3_v3(vec, co);
- vec += 3;
+ copy_v3_v3(co_no->co, co);
if (no_f) {
- copy_v3_v3(vec, no_f);
+ copy_v3_v3(co_no->no, no_f);
}
else {
- normal_short_to_float_v3(vec, no_s);
+ normal_short_to_float_v3(co_no->no, no_s);
}
}
@@ -2334,29 +2342,29 @@ static void make_vertexcosnos__mapFunc(void *userData, int index, const float co
/* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */
/* in use now by vertex/weight paint and particle generating */
-float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
+DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
{
Mesh *me = ob->data;
DerivedMesh *dm;
- float *vertexcosnos;
+ DMCoNo *vertexcosnos;
/* lets prevent crashing... */
if (ob->type != OB_MESH || me->totvert == 0)
return NULL;
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
- vertexcosnos = MEM_callocN(6 * sizeof(float) * me->totvert, "vertexcosnos map");
+ vertexcosnos = MEM_callocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
if (dm->foreachMappedVert) {
dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos);
}
else {
- float *fp = vertexcosnos;
+ DMCoNo *v_co_no = vertexcosnos;
int a;
- for (a = 0; a < me->totvert; a++, fp += 6) {
- dm->getVertCo(dm, a, fp);
- dm->getVertNo(dm, a, fp + 3);
+ for (a = 0; a < me->totvert; a++, v_co_no++) {
+ dm->getVertCo(dm, a, v_co_no->co);
+ dm->getVertNo(dm, a, v_co_no->no);
}
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index dd27cc7..63e12df 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -43,7 +43,6 @@
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -544,7 +543,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon)
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
/* TODO: rename this argument... */
if (copycon) {
- copy_constraints(&listb, &pchan->constraints, TRUE); // copy_constraints NULLs listb
+ BKE_copy_constraints(&listb, &pchan->constraints, TRUE); // BKE_copy_constraints NULLs listb
pchan->constraints = listb;
pchan->mpath = NULL; /* motion paths should not get copied yet... */
}
@@ -622,7 +621,7 @@ void BKE_pose_channel_free(bPoseChannel *pchan)
pchan->mpath = NULL;
}
- free_constraints(&pchan->constraints);
+ BKE_free_constraints(&pchan->constraints);
if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
@@ -712,7 +711,7 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
pchan->iklinweight = pchan_from->iklinweight;
/* constraints */
- copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
+ BKE_copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
/* id-properties */
if (pchan->prop) {
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
new file mode 100644
index 0000000..7f475cd
--- /dev/null
+++ b/source/blender/blenkernel/intern/addon.c
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_string.h"
+
+#include "BKE_addon.h" /* own include */
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "BLF_translation.h"
+
+#include "MEM_guardedalloc.h"
+
+static GHash *global_addonpreftype_hash = NULL;
+
+
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet)
+{
+ if (idname[0]) {
+ bAddonPrefType *apt;
+
+ apt = BLI_ghash_lookup(global_addonpreftype_hash, idname);
+ if (apt) {
+ return apt;
+ }
+
+ if (!quiet) {
+ printf("search for unknown addon-pref '%s'\n", idname);
+ }
+ }
+ else {
+ if (!quiet) {
+ printf("search for empty addon-pref");
+ }
+ }
+
+ return NULL;
+}
+
+void BKE_addon_pref_type_add(bAddonPrefType *apt)
+{
+ BLI_ghash_insert(global_addonpreftype_hash, (void *)apt->idname, apt);
+}
+
+void BKE_addon_pref_type_remove(bAddonPrefType *apt)
+{
+ BLI_ghash_remove(global_addonpreftype_hash, (void *)apt->idname, NULL, (GHashValFreeFP)MEM_freeN);
+}
+
+void BKE_addon_pref_type_init(void)
+{
+ BLI_assert(global_addonpreftype_hash == NULL);
+ global_addonpreftype_hash = BLI_ghash_str_new(__func__);
+}
+
+void BKE_addon_pref_type_free(void)
+{
+ BLI_ghash_free(global_addonpreftype_hash, NULL, (GHashValFreeFP)MEM_freeN);
+ global_addonpreftype_hash = NULL;
+}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 9a2462e..4058809 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -76,7 +76,7 @@
/* --------------------- */
/* forward declarations */
-static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4],
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4],
int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag);
/* ******************************************************************** */
@@ -706,7 +706,7 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
#define DUPLILIST_FOR_RENDER 2
#define DUPLILIST_ANIMATED 4
-static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay,
+static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[4][4], int lay,
int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag)
{
DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject");
@@ -930,7 +930,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
}
}
-static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR],
+static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR],
int level, short flag)
{
Object *ob, *ob_iter;
@@ -1054,7 +1054,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
dm->release(dm);
}
-static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR],
+static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR],
int level, short flag)
{
Object *ob, *ob_iter;
@@ -1240,7 +1240,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
dm->release(dm);
}
-static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys,
+static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4],
+ int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys,
int level, short flag)
{
GroupObject *go;
@@ -1479,7 +1480,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
/* blender internal needs this to be set to dupligroup to render
* groups correctly, but we don't want this hack for cycles */
- if(dupli_type_hack && GS(id->name) == ID_GR)
+ if (dupli_type_hack && GS(id->name) == ID_GR)
dupli_type = OB_DUPLIGROUP;
/* to give ipos in object correct offset */
@@ -1635,7 +1636,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persiste
/* ------------- */
-static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4],
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4],
int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag)
{
if ((ob->transflag & OB_DUPLI) == 0)
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 1970df5..ad14dee 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -640,7 +639,7 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info
}
}
-static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[][3])
+static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[3][3])
{
Mat4 *b_bone = pdef_info->b_bone_mats;
float (*mat)[4] = b_bone[0].mat;
@@ -722,7 +721,7 @@ float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3
}
}
-static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3])
+static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[3][3], float mat[3][3])
{
float wmat[3][3];
@@ -736,7 +735,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem
}
static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float vec[3], DualQuat *dq,
- float mat[][3], const float co[3])
+ float mat[3][3], const float co[3])
{
Bone *bone = pchan->bone;
float fac, contrib = 0.0;
@@ -783,7 +782,7 @@ static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, f
}
static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float vec[3], DualQuat *dq,
- float mat[][3], const float co[3], float *contrib)
+ float mat[3][3], const float co[3], float *contrib)
{
float cop[3], bbonemat[3][3];
DualQuat bbonedq;
@@ -1089,7 +1088,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
/* ************ END Armature Deform ******************* */
-void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int UNUSED(root),
+void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int UNUSED(root),
int UNUSED(posed))
{
copy_m4_m4(M_accumulatedMatrix, bone->arm_mat);
@@ -1098,7 +1097,7 @@ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][
/* **************** Space to Space API ****************** */
/* Convert World-Space Matrix to Pose-Space Matrix */
-void BKE_armature_mat_world_to_pose(Object *ob, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[4][4])
{
float obmat[4][4];
@@ -1132,7 +1131,7 @@ void BKE_armature_loc_world_to_pose(Object *ob, const float inloc[3], float outl
/* Simple helper, computes the offset bone matrix.
* offs_bone = yoffs(b-1) + root(b) + bonemat(b).
* Not exported, as it is only used in this file currently... */
-static void get_offset_bone_mat(Bone *bone, float offs_bone[][4])
+static void get_offset_bone_mat(Bone *bone, float offs_bone[4][4])
{
if (!bone->parent)
return;
@@ -1164,7 +1163,7 @@ static void get_offset_bone_mat(Bone *bone, float offs_bone[][4])
* pose-channel into its local space (i.e. 'visual'-keyframing).
* (note: I don't understand that, so I keep it :p --mont29).
*/
-void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4])
+void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4])
{
Bone *bone, *parbone;
bPoseChannel *parchan;
@@ -1253,7 +1252,7 @@ void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float l
/* Convert Pose-Space Matrix to Bone-Space Matrix.
* NOTE: this cannot be used to convert to pose-space transforms of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
-void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4];
@@ -1269,7 +1268,7 @@ void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float
}
/* Convert Bone-Space Matrix to Pose-Space Matrix. */
-void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4];
@@ -1298,7 +1297,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl
copy_v3_v3(outloc, nLocMat[3]);
}
-void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
@@ -1316,7 +1315,7 @@ void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inm
}
/* same as BKE_object_mat3_to_rot() */
-void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat)
+void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], short use_compat)
{
switch (pchan->rotmode) {
case ROT_MODE_QUAT:
@@ -1335,7 +1334,7 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat
/* Apply a 4x4 matrix to the pose bone,
* similar to BKE_object_apply_mat4() */
-void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
+void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], short use_compat)
{
float rot[3][3];
mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
@@ -1345,7 +1344,7 @@ void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
/* Remove rest-position effects from pose-transform for obtaining
* 'visual' transformation of pose-channel.
* (used by the Visual-Keyframing stuff) */
-void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4])
+void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4])
{
float imat[4][4];
@@ -1425,7 +1424,7 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float
* *************************************************************************** */
/* Computes vector and roll based on a rotation.
* "mat" must contain only a rotation, and no scaling. */
-void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll)
+void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll)
{
if (r_vec) {
copy_v3_v3(r_vec, mat[1]);
@@ -1444,7 +1443,7 @@ void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll)
/* Calculates the rest matrix of a bone based
* On its vector and a roll around that vector */
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3])
+void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
{
float nor[3], axis[3], target[3] = {0, 1, 0};
float theta;
@@ -1621,15 +1620,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
* 2. copy proxy-pchan's constraints on-to new
* 3. add extracted local constraints back on top
*
- * Note for copy_constraints: when copying constraints, disable 'do_extern' otherwise
- * we get the libs direct linked in this blend. */
- extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
- copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
+ * Note for BKE_copy_constraints: when copying constraints, disable 'do_extern' otherwise
+ * we get the libs direct linked in this blend.
+ */
+ BKE_extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
+ BKE_copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2427,15 +2427,15 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float
/* prepare PoseChannel for Constraint solving
* - makes a copy of matrix, and creates temporary struct to use
*/
- cob = constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
+ cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
/* Solve PoseChannel's Constraints */
- solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
+ BKE_solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
/* cleanup after Constraint Solving
* - applies matrix back to pchan, and frees temporary struct used
*/
- constraints_clear_evalob(cob);
+ BKE_constraints_clear_evalob(cob);
/* prevent constraints breaking a chain */
if (pchan->bone->flag & BONE_CONNECTED) {
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index f0d201e..11ae242 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -54,9 +54,9 @@
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
+#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
@@ -65,6 +65,7 @@
#include "IMB_moviecache.h"
#include "BKE_blender.h"
+#include "BKE_bpath.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
@@ -80,8 +81,11 @@
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BKE_sound.h"
+
#include "RE_pipeline.h"
+#include "BLF_api.h"
+
#include "BLO_undofile.h"
#include "BLO_readfile.h"
#include "BLO_writefile.h"
@@ -179,7 +183,7 @@ static void clean_paths(Main *main)
{
Scene *scene;
- BLI_bpath_traverse_main(main, clean_paths_visit_cb, BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL);
+ BKE_bpath_traverse_main(main, clean_paths_visit_cb, BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL);
for (scene = main->scene.first; scene; scene = scene->id.next) {
BLI_clean(scene->r.pic);
@@ -230,6 +234,9 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* but use new Scene pointer */
curscene = bfd->curscene;
if (curscene == NULL) curscene = bfd->main->scene.first;
+ /* empty file, we add a scene to make Blender work */
+ if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty");
+
/* and we enforce curscene to be in current screen */
if (curscreen) curscreen->scene = curscene; /* can run in bgmode */
@@ -270,7 +277,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
G.fileflags = bfd->fileflags;
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
- CTX_data_scene_set(C, bfd->curscreen->scene);
+ CTX_data_scene_set(C, bfd->curscene);
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
CTX_wm_menu_set(C, NULL);
@@ -280,7 +287,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
if (CTX_data_scene(C) == NULL) {
/* in case we don't even have a local scene, add one */
if (!G.main->scene.first)
- BKE_scene_add("Scene");
+ BKE_scene_add(G.main, "Scene");
CTX_data_scene_set(C, G.main->scene.first);
CTX_wm_screen(C)->scene = CTX_data_scene(C);
@@ -310,23 +317,38 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
if (G.main->versionfile < 250)
do_versions_ipos_to_animato(G.main);
- if (recover && bfd->filename[0] && G.relbase_valid) {
+ G.main->recovered = 0;
+
+ /* startup.blend or recovered startup */
+ if (bfd->filename[0] == 0) {
+ G.main->name[0] = 0;
+ }
+ else if (recover && G.relbase_valid) {
/* in case of autosave or quit.blend, use original filename instead
* use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */
filepath = bfd->filename;
+ G.main->recovered = 1;
+
+ /* these are the same at times, should never copy to the same location */
+ if (G.main->name != filepath)
+ BLI_strncpy(G.main->name, filepath, FILE_MAX);
}
-#if 0
- else if (!G.relbase_valid) {
- /* otherwise, use an empty string as filename, rather than <memory2> */
- filepath = "";
- }
-#endif
- /* these are the same at times, should never copy to the same location */
- if (G.main->name != filepath)
- BLI_strncpy(G.main->name, filepath, FILE_MAX);
-
/* baseflags, groups, make depsgraph, etc */
+ /* first handle case if other windows have different scenes visible */
+ if (mode == 0) {
+ wmWindowManager *wm = G.main->wm.first;
+
+ if (wm) {
+ wmWindow *win;
+
+ for (win = wm->windows.first; win; win = win->next) {
+ if (win->screen && win->screen->scene) /* zealous check... */
+ if (win->screen->scene != CTX_data_scene(C))
+ BKE_scene_set_background(G.main, win->screen->scene);
+ }
+ }
+ }
BKE_scene_set_background(G.main, CTX_data_scene(C));
if (mode != 'u') {
@@ -335,7 +357,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
MEM_freeN(bfd);
- (void)curscene; /* quiet warning */
}
static int handle_subversion_warning(Main *main, ReportList *reports)
@@ -366,6 +387,7 @@ void BKE_userdef_free(void)
wmKeyMap *km;
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
+ bAddon *addon, *addon_next;
for (km = U.user_keymaps.first; km; km = km->next) {
for (kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
@@ -386,11 +408,27 @@ void BKE_userdef_free(void)
BLI_freelistN(&km->items);
}
+ for (addon = U.addons.first; addon; addon = addon_next) {
+ addon_next = addon->next;
+ if (addon->prop) {
+ IDP_FreeProperty(addon->prop);
+ MEM_freeN(addon->prop);
+ }
+ MEM_freeN(addon);
+ }
+
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
BLI_freelistN(&U.user_keymaps);
- BLI_freelistN(&U.addons);
+}
+
+/* handle changes in settings that need recalc */
+void BKE_userdef_state(void)
+{
+ BLF_default_dpi(U.pixelsize * U.dpi);
+ U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
+
}
int BKE_read_file(bContext *C, const char *filepath, ReportList *reports)
@@ -439,14 +477,57 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *report
BlendFileData *bfd;
bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports);
- if (bfd)
+ if (bfd) {
+ /* remove the unused screens and wm */
+ while (bfd->main->wm.first)
+ BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first);
+ while (bfd->main->screen.first)
+ BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first);
+
setup_app_data(C, bfd, "<memory1>");
+ }
else
BKE_reports_prepend(reports, "Loading failed: ");
return (bfd ? 1 : 0);
}
+/* only read the userdef from a .blend */
+int BKE_read_file_userdef(const char *filepath, ReportList *reports)
+{
+ BlendFileData *bfd;
+ int retval = 0;
+
+ bfd = BLO_read_from_file(filepath, reports);
+ if (bfd->user) {
+ retval = BKE_READ_FILE_OK_USERPREFS;
+
+ /* only here free userdef themes... */
+ BKE_userdef_free();
+
+ U = *bfd->user;
+ MEM_freeN(bfd->user);
+ }
+ free_main(bfd->main);
+ MEM_freeN(bfd);
+
+ return retval;
+}
+
+/* only write the userdef in a .blend */
+int BKE_write_file_userdef(const char *filepath, ReportList *reports)
+{
+ Main *mainb = MEM_callocN(sizeof(Main), "empty main");
+ int retval = 0;
+
+ if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports, NULL)) {
+ retval = 1;
+ }
+
+ MEM_freeN(mainb);
+
+ return retval;
+}
/* ***************** testing for break ************* */
@@ -728,48 +809,39 @@ char *BKE_undo_menu_string(void)
return menu;
}
-/* saves quit.blend */
-void BKE_undo_save_quit(void)
+/* saves .blend using undo buffer, returns 1 == success */
+int BKE_undo_save_file(const char *filename)
{
UndoElem *uel;
MemFileChunk *chunk;
- char str[FILE_MAX];
const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL;
int file;
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
- return;
+ return 0;
}
uel = curundo;
if (uel == NULL) {
fprintf(stderr, "No undo buffer to save recovery file\n");
- return;
- }
-
- /* no undo state to save */
- if (undobase.first == undobase.last) {
- return;
+ return 0;
}
- /* save the undo state as quit.blend */
- BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend");
-
/* first try create the file, if it exists call without 'O_CREAT',
* to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
errno = 0;
- file = BLI_open(str, flag, 0666);
+ file = BLI_open(filename, flag, 0666);
if (file == -1) {
if (errno == EEXIST) {
errno = 0;
- file = BLI_open(str, flag & ~O_CREAT, 0666);
+ file = BLI_open(filename, flag & ~O_CREAT, 0666);
}
}
if (file == -1) {
fprintf(stderr, "Unable to save '%s': %s\n",
- str, errno ? strerror(errno) : "Unknown error opening file");
- return;
+ filename, errno ? strerror(errno) : "Unknown error opening file");
+ return 0;
}
for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) {
@@ -777,16 +849,15 @@ void BKE_undo_save_quit(void)
break;
}
}
-
+
close(file);
if (chunk) {
fprintf(stderr, "Unable to save '%s': %s\n",
- str, errno ? strerror(errno) : "Unknown error writing file");
- }
- else {
- printf("Saved session recovery to '%s'\n", str);
+ filename, errno ? strerror(errno) : "Unknown error writing file");
+ return 0;
}
+ return 1;
}
/* sets curscene */
@@ -806,3 +877,131 @@ Main *BKE_undo_get_main(Scene **scene)
return mainp;
}
+/* ************** copy paste .blend, partial saves ********** */
+
+/* assumes data is in G.main */
+
+void BKE_copybuffer_begin(void)
+{
+ /* set all id flags to zero; */
+ flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0);
+}
+
+void BKE_copybuffer_tag_ID(ID *id)
+{
+ id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
+}
+
+static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid)
+{
+ if (vid) {
+ ID *id = vid;
+ id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
+ }
+}
+
+/* frees main in end */
+int BKE_copybuffer_save(char *filename, ReportList *reports)
+{
+ Main *mainb = MEM_callocN(sizeof(Main), "copybuffer");
+ ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
+ int a, retval;
+
+ BLO_main_expander(copybuffer_doit);
+ BLO_expand_main(NULL, G.main);
+
+ /* move over all tagged blocks */
+ set_listbasepointers(G.main, fromarray);
+ a = set_listbasepointers(mainb, lbarray);
+ while (a--) {
+ ID *id, *nextid;
+ ListBase *lb1 = lbarray[a], *lb2 = fromarray[a];
+
+ for (id = lb2->first; id; id = nextid) {
+ nextid = id->next;
+ if (id->flag & LIB_DOIT) {
+ BLI_remlink(lb2, id);
+ BLI_addtail(lb1, id);
+ }
+ }
+ }
+
+
+ /* save the buffer */
+ retval = BLO_write_file(mainb, filename, 0, reports, NULL);
+
+ /* move back the main, now sorted again */
+ set_listbasepointers(G.main, lbarray);
+ a = set_listbasepointers(mainb, fromarray);
+ while (a--) {
+ ID *id;
+ ListBase *lb1 = lbarray[a], *lb2 = fromarray[a];
+
+ while (lb2->first) {
+ id = lb2->first;
+ BLI_remlink(lb2, id);
+ BLI_addtail(lb1, id);
+ id_sort_by_name(lb1, id);
+ }
+ }
+
+ MEM_freeN(mainb);
+
+ /* set id flag to zero; */
+ flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0);
+
+ return retval;
+}
+
+/* return success (1) */
+int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Main *mainl = NULL;
+ Library *lib;
+ BlendHandle *bh;
+
+ bh = BLO_blendhandle_from_file(libname, reports);
+
+ if (bh == NULL) {
+ /* error reports will have been made by BLO_blendhandle_from_file() */
+ return 0;
+ }
+
+ BKE_scene_base_deselect_all(scene);
+
+ /* tag everything, all untagged data can be made local
+ * its also generally useful to know what is new
+ *
+ * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
+
+ /* here appending/linking starts */
+ mainl = BLO_library_append_begin(bmain, &bh, libname);
+
+ BLO_library_append_all(mainl, bh);
+
+ BLO_library_append_end(C, mainl, &bh, 0, 0);
+
+ /* mark all library linked objects to be updated */
+ recalc_all_library_objects(bmain);
+ IMB_colormanagement_check_file_config(bmain);
+
+ /* append, rather than linking */
+ lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
+ BKE_library_make_local(bmain, lib, 1);
+
+ /* important we unset, otherwise these object wont
+ * link into other scenes from this blend file */
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
+
+ /* recreate dependency graph to include new objects */
+ DAG_scene_sort(bmain, scene);
+ DAG_ids_flush_update(bmain, 0);
+
+ BLO_blendhandle_close(bh);
+ /* remove library... */
+
+ return 1;
+}
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index 0495e72..fc83b24 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -65,8 +65,8 @@ void printfGlyph(bmGlyph * glyph)
printf(" advan: %3d reser: %3d\n", glyph->advance, glyph->reserved);
}
-#define MAX2(x,y) ((x) > (y) ? (x) : (y))
-#define MAX3(x,y,z) MAX2(MAX2((x), (y)), (z))
+#define MAX2(x, y) ((x) > (y) ? (x) : (y))
+#define MAX3(x, y, z) (MAX2(MAX2((x), (y)), (z)))
void calcAlpha(ImBuf * ibuf)
{
diff --git a/source/blender/blenkernel/intern/booleanops_mesh.c b/source/blender/blenkernel/intern/booleanops_mesh.c
index 461b945..f53a89f 100644
--- a/source/blender/blenkernel/intern/booleanops_mesh.c
+++ b/source/blender/blenkernel/intern/booleanops_mesh.c
@@ -56,7 +56,7 @@ CSG_DestroyBlenderMeshInternals(
CSG_MeshDescriptor *mesh
) {
/* Free face and vertex iterators. */
- FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));
+ FreeMeshDescriptors(&(mesh->m_face_iterator), &(mesh->m_vertex_iterator));
}
@@ -138,7 +138,7 @@ CSG_AddMeshToBlender(
if (mesh == NULL) return 0;
if (mesh->base == NULL) return 0;
- invert_m4_m4(inv_mat,mesh->base->object->obmat);
+ invert_m4_m4(inv_mat, mesh->base->object->obmat);
/* Create a new blender mesh object - using 'base' as
* a template for the new object. */
@@ -191,7 +191,7 @@ CSG_PerformOp(
default : op_type = e_csg_intersection;
}
- output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
+ output->m_descriptor = CSG_DescibeOperands(bool_op, mesh1->m_descriptor, mesh2->m_descriptor);
output->base = mesh1->base;
if (output->m_descriptor.user_face_vertex_data_size) {
@@ -228,8 +228,8 @@ CSG_PerformOp(
/* get the ouput mesh descriptors. */
- CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
- CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
+ CSG_OutputFaceDescriptor(bool_op, &(output->m_face_iterator));
+ CSG_OutputVertexDescriptor(bool_op, &(output->m_vertex_iterator));
output->m_destroy_func = CSG_DestroyCSGMeshInternals;
return 1;
@@ -242,20 +242,20 @@ NewBooleanMeshTest(
int op_type
) {
- CSG_MeshDescriptor m1,m2,output;
- CSG_MeshDescriptor output2,output3;
+ CSG_MeshDescriptor m1, m2, output;
+ CSG_MeshDescriptor output2, output3;
- if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
+ if (!MakeCSGMeshFromBlenderBase(base, &m1)) {
return 0;
}
- if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
+ if (!MakeCSGMeshFromBlenderBase(base_select, &m2)) {
return 0;
}
- CSG_PerformOp(&m1,&m2,1,&output);
- CSG_PerformOp(&m1,&m2,2,&output2);
- CSG_PerformOp(&m1,&m2,3,&output3);
+ CSG_PerformOp(&m1, &m2, 1, &output);
+ CSG_PerformOp(&m1, &m2, 2, &output2);
+ CSG_PerformOp(&m1, &m2, 3, &output3);
if (!CSG_AddMeshToBlender(&output)) {
return 0;
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
new file mode 100644
index 0000000..bb610ed
--- /dev/null
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -0,0 +1,729 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Campbell barton, Alex Fraser
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/bpath.c
+ * \ingroup bli
+ */
+
+/* TODO,
+ * currently there are some cases we don't support.
+ * - passing output paths to the visitor?, like render out.
+ * - passing sequence strips with many images.
+ * - passing directory paths - visitors don't know which path is a dir or a file.
+ * */
+
+#include <sys/stat.h>
+
+#include <string.h>
+#include <assert.h>
+
+/* path/file handling stuff */
+#ifndef WIN32
+# include <dirent.h>
+# include <unistd.h>
+#else
+# include <io.h>
+# include "BLI_winstuff.h"
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_object_fluidsim.h"
+#include "DNA_object_force.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_text_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_vfont_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_smoke_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_font.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_report.h"
+#include "BKE_sequencer.h"
+#include "BKE_image.h" /* so we can check the image's type */
+
+#include "BKE_bpath.h" /* own include */
+
+static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
+{
+ ReportList *reports = (ReportList *)userdata;
+
+ if (!BLI_exists(path_src)) {
+ BKE_reportf(reports, RPT_WARNING, "Path '%s' not found", path_src);
+ }
+
+ return FALSE;
+}
+
+/* high level function */
+void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports)
+{
+ BKE_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BKE_BPATH_TRAVERSE_ABS, reports);
+}
+
+typedef struct BPathRemap_Data {
+ const char *basedir;
+ ReportList *reports;
+
+ int count_tot;
+ int count_changed;
+ int count_failed;
+} BPathRemap_Data;
+
+static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char *path_src)
+{
+ BPathRemap_Data *data = (BPathRemap_Data *)userdata;
+
+ data->count_tot++;
+
+ if (BLI_path_is_rel(path_src)) {
+ return FALSE; /* already relative */
+ }
+ else {
+ strcpy(path_dst, path_src);
+ BLI_path_rel(path_dst, data->basedir);
+ if (BLI_path_is_rel(path_dst)) {
+ data->count_changed++;
+ }
+ else {
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
+ data->count_failed++;
+ }
+ return TRUE;
+ }
+}
+
+void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports)
+{
+ BPathRemap_Data data = {NULL};
+
+ if (basedir[0] == '\0') {
+ printf("%s: basedir='', this is a bug\n", __func__);
+ return;
+ }
+
+ data.basedir = basedir;
+ data.reports = reports;
+
+ BKE_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data);
+
+ BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
+ "Total files %d | Changed %d | Failed %d",
+ data.count_tot, data.count_changed, data.count_failed);
+}
+
+static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char *path_src)
+{
+ BPathRemap_Data *data = (BPathRemap_Data *)userdata;
+
+ data->count_tot++;
+
+ if (BLI_path_is_rel(path_src) == FALSE) {
+ return FALSE; /* already absolute */
+ }
+ else {
+ strcpy(path_dst, path_src);
+ BLI_path_abs(path_dst, data->basedir);
+ if (BLI_path_is_rel(path_dst) == FALSE) {
+ data->count_changed++;
+ }
+ else {
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
+ data->count_failed++;
+ }
+ return TRUE;
+ }
+}
+
+/* similar to BKE_bpath_relative_convert - keep in sync! */
+void BKE_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports)
+{
+ BPathRemap_Data data = {NULL};
+
+ if (basedir[0] == '\0') {
+ printf("%s: basedir='', this is a bug\n", __func__);
+ return;
+ }
+
+ data.basedir = basedir;
+ data.reports = reports;
+
+ BKE_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data);
+
+ BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
+ "Total files %d | Changed %d | Failed %d",
+ data.count_tot, data.count_changed, data.count_failed);
+}
+
+/**
+ * find this file recursively, use the biggest file so thumbnails don't get used by mistake
+ * \param filename_new: the path will be copied here, caller must initialize as empty string.
+ * \param dirname: subdir to search
+ * \param filename: set this filename
+ * \param filesize: filesize for the file
+ *
+ * \returns found: 1/0.
+ */
+#define MAX_RECUR 16
+static int findFileRecursive(char *filename_new,
+ const char *dirname,
+ const char *filename,
+ int *filesize,
+ int *recur_depth)
+{
+ /* file searching stuff */
+ DIR *dir;
+ struct dirent *de;
+ struct stat status;
+ char path[FILE_MAX];
+ int size;
+ int found = FALSE;
+
+ dir = opendir(dirname);
+
+ if (dir == NULL)
+ return found;
+
+ if (*filesize == -1)
+ *filesize = 0; /* dir opened fine */
+
+ while ((de = readdir(dir)) != NULL) {
+
+ if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0)
+ continue;
+
+ BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);
+
+ if (stat(path, &status) != 0)
+ continue; /* cant stat, don't bother with this file, could print debug info here */
+
+ if (S_ISREG(status.st_mode)) { /* is file */
+ if (strncmp(filename, de->d_name, FILE_MAX) == 0) { /* name matches */
+ /* open the file to read its size */
+ size = status.st_size;
+ if ((size > 0) && (size > *filesize)) { /* find the biggest file */
+ *filesize = size;
+ BLI_strncpy(filename_new, path, FILE_MAX);
+ found = TRUE;
+ }
+ }
+ }
+ else if (S_ISDIR(status.st_mode)) { /* is subdir */
+ if (*recur_depth <= MAX_RECUR) {
+ (*recur_depth)++;
+ found |= findFileRecursive(filename_new, path, filename, filesize, recur_depth);
+ (*recur_depth)--;
+ }
+ }
+ }
+ closedir(dir);
+ return found;
+}
+
+typedef struct BPathFind_Data {
+ const char *basedir;
+ char searchdir[FILE_MAX];
+ ReportList *reports;
+} BPathFind_Data;
+
+static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char *path_src)
+{
+ BPathFind_Data *data = (BPathFind_Data *)userdata;
+ char filename_new[FILE_MAX];
+
+ int filesize = -1;
+ int recur_depth = 0;
+ int found;
+
+ filename_new[0] = '\0';
+
+ found = findFileRecursive(filename_new,
+ data->searchdir, BLI_path_basename((char *)path_src),
+ &filesize, &recur_depth);
+
+ if (filesize == -1) { /* could not open dir */
+ BKE_reportf(data->reports, RPT_WARNING,
+ "Could not open directory '%s'",
+ BLI_path_basename(data->searchdir));
+ return FALSE;
+ }
+ else if (found == FALSE) {
+ BKE_reportf(data->reports, RPT_WARNING,
+ "Could not find '%s' in '%s'",
+ BLI_path_basename((char *)path_src), data->searchdir);
+ return FALSE;
+ }
+ else {
+ BLI_strncpy(path_dst, filename_new, FILE_MAX);
+ return TRUE;
+ }
+}
+
+void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports)
+{
+ struct BPathFind_Data data = {NULL};
+
+ data.reports = reports;
+ BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir));
+
+ BKE_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data);
+}
+
+/* Run a visitor on a string, replacing the contents of the string as needed. */
+static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *absbase, void *userdata)
+{
+ char path_src_buf[FILE_MAX];
+ const char *path_src;
+ char path_dst[FILE_MAX];
+
+ if (absbase) {
+ BLI_strncpy(path_src_buf, path, sizeof(path_src_buf));
+ BLI_path_abs(path_src_buf, absbase);
+ path_src = path_src_buf;
+ }
+ else {
+ path_src = path;
+ }
+
+ if (visit_cb(userdata, path_dst, path_src)) {
+ BLI_strncpy(path, path_dst, FILE_MAX);
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
+ char path_file[FILE_MAXFILE],
+ BPathVisitor visit_cb,
+ const char *absbase,
+ void *userdata)
+{
+ char path_src[FILE_MAX];
+ char path_dst[FILE_MAX];
+
+ BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file);
+
+ if (absbase) {
+ BLI_path_abs(path_src, absbase);
+ }
+
+ if (visit_cb(userdata, path_dst, (const char *)path_src)) {
+ BLI_split_dirfile(path_dst, path_dir, path_file, FILE_MAXDIR, FILE_MAXFILE);
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *absbase, void *userdata)
+{
+ char path_src_buf[FILE_MAX];
+ const char *path_src;
+ char path_dst[FILE_MAX];
+
+ if (absbase) {
+ BLI_strncpy(path_src_buf, *path, sizeof(path_src_buf));
+ BLI_path_abs(path_src_buf, absbase);
+ path_src = path_src_buf;
+ }
+ else {
+ path_src = *path;
+ }
+
+ if (visit_cb(userdata, path_dst, path_src)) {
+ MEM_freeN((*path));
+ (*path) = BLI_strdup(path_dst);
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+/* Run visitor function 'visit' on all paths contained in 'id'. */
+void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
+{
+ const char *absbase = (flag & BKE_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
+
+ if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) {
+ return;
+ }
+
+ switch (GS(id->name)) {
+ case ID_IM:
+ {
+ Image *ima;
+ ima = (Image *)id;
+ if (ima->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
+ if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ break;
+ }
+ case ID_BR:
+ {
+ Brush *brush = (Brush *)id;
+ if (brush->icon_filepath[0]) {
+ rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data);
+ }
+ break;
+ }
+ case ID_OB:
+ {
+ Object *ob = (Object *)id;
+ ModifierData *md;
+ ParticleSystem *psys;
+
+#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \
+ { \
+ PointCache *cache; \
+ for (cache = (ptcaches).first; cache; cache = cache->next) { \
+ if (cache->flag & PTCACHE_DISK_CACHE) { \
+ rewrite_path_fixed(cache->path, \
+ visit_cb, \
+ absbase, \
+ bpath_user_data); \
+ } \
+ } \
+ } (void)0
+
+ /* do via modifiers instead */
+#if 0
+ if (ob->fluidsimSettings) {
+ rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data);
+ }
+#endif
+
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Fluidsim) {
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
+ if (fluidmd->fss) {
+ rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ else if (md->type == eModifierType_Smoke) {
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
+ BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]);
+ }
+ }
+ else if (md->type == eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData *) md;
+ BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches);
+ }
+ else if (md->type == eModifierType_Ocean) {
+ OceanModifierData *omd = (OceanModifierData *) md;
+ rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data);
+ }
+ }
+
+ if (ob->soft) {
+ BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches);
+ }
+
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ BPATH_TRAVERSE_POINTCACHE(psys->ptcaches);
+ }
+
+#undef BPATH_TRAVERSE_POINTCACHE
+
+ break;
+ }
+ case ID_SO:
+ {
+ bSound *sound = (bSound *)id;
+ if (sound->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
+ rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data);
+ }
+ break;
+ }
+ case ID_TXT:
+ if (((Text *)id)->name) {
+ rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data);
+ }
+ break;
+ case ID_VF:
+ {
+ VFont *vfont = (VFont *)id;
+ if (vfont->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
+ if (BKE_vfont_is_builtin(vfont) == FALSE) {
+ rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ break;
+ }
+ case ID_MA:
+ {
+ Material *ma = (Material *)id;
+ bNodeTree *ntree = ma->nodetree;
+
+ if (ntree) {
+ bNode *node;
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_SCRIPT) {
+ NodeShaderScript *nss = (NodeShaderScript *)node->storage;
+ rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ }
+ break;
+ }
+ case ID_NT:
+ {
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNode *node;
+
+ if (ntree->type == NTREE_SHADER) {
+ /* same as lines above */
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_SCRIPT) {
+ NodeShaderScript *nss = (NodeShaderScript *)node->storage;
+ rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ }
+ break;
+ }
+ case ID_TE:
+ {
+ Tex *tex = (Tex *)id;
+ if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) {
+ rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data);
+ }
+ break;
+ }
+ case ID_SCE:
+ {
+ Scene *scene = (Scene *)id;
+ if (scene->ed) {
+ Sequence *seq;
+
+ SEQ_BEGIN(scene->ed, seq)
+ {
+ if (SEQ_HAS_PATH(seq)) {
+ if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM)) {
+ rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name,
+ visit_cb, absbase, bpath_user_data);
+ }
+ else if (seq->type == SEQ_TYPE_IMAGE) {
+ /* might want an option not to loop over all strips */
+ StripElem *se = seq->strip->stripdata;
+ int len = MEM_allocN_len(se) / sizeof(*se);
+ int i;
+
+ if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) {
+ /* only operate on one path */
+ len = MIN2(1, len);
+ }
+
+ for (i = 0; i < len; i++, se++) {
+ rewrite_path_fixed_dirfile(seq->strip->dir, se->name,
+ visit_cb, absbase, bpath_user_data);
+ }
+ }
+ else {
+ /* simple case */
+ rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data);
+ }
+ }
+
+ }
+ SEQ_END
+ }
+ break;
+ }
+ case ID_ME:
+ {
+ Mesh *me = (Mesh *)id;
+ if (me->ldata.external) {
+ rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data);
+ }
+ break;
+ }
+ case ID_LI:
+ {
+ Library *lib = (Library *)id;
+ /* keep packedfile paths always relative to the blend */
+ if (lib->packedfile == NULL) {
+ if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
+ BKE_library_filepath_set(lib, lib->name);
+ }
+ }
+ break;
+ }
+ case ID_MC:
+ {
+ MovieClip *clip = (MovieClip *)id;
+ rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data);
+ break;
+ }
+ default:
+ /* Nothing to do for other IDs that don't contain file paths. */
+ break;
+ }
+}
+
+void BKE_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
+{
+ ID *id;
+ for (id = lb->first; id; id = id->next) {
+ BKE_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data);
+ }
+}
+
+void BKE_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
+{
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a = set_listbasepointers(bmain, lbarray);
+ while (a--) {
+ BKE_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data);
+ }
+}
+
+/* Rewrites a relative path to be relative to the main file - unless the path is
+ * absolute, in which case it is not altered. */
+int BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src)
+{
+ /* be sure there is low chance of the path being too short */
+ char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+ const char *base_new = ((char **)pathbase_v)[0];
+ const char *base_old = ((char **)pathbase_v)[1];
+
+ if (BLI_path_is_rel(base_old)) {
+ printf("%s: error, old base path '%s' is not absolute.\n",
+ __func__, base_old);
+ return FALSE;
+ }
+
+ /* Make referenced file absolute. This would be a side-effect of
+ * BLI_cleanup_file, but we do it explicitly so we know if it changed. */
+ BLI_strncpy(filepath, path_src, FILE_MAX);
+ if (BLI_path_abs(filepath, base_old)) {
+ /* Path was relative and is now absolute. Remap.
+ * Important BLI_cleanup_dir runs before the path is made relative
+ * because it wont work for paths that start with "//../" */
+ BLI_cleanup_file(base_new, filepath);
+ BLI_path_rel(filepath, base_new);
+ BLI_strncpy(path_dst, filepath, FILE_MAX);
+ return TRUE;
+ }
+ else {
+ /* Path was not relative to begin with. */
+ return FALSE;
+ }
+}
+
+
+/* -------------------------------------------------------------------- */
+/**
+ * Backup/Restore/Free functions,
+ * \note These functions assume the data won't chane order.
+ */
+
+struct PathStore {
+ struct PathStore *next, *prev;
+} PathStore;
+
+static int bpath_list_append(void *userdata, char *UNUSED(path_dst), const char *path_src)
+{
+ /* store the path and string in a single alloc */
+ ListBase *ls = userdata;
+ size_t path_size = strlen(path_src) + 1;
+ struct PathStore *path_store = MEM_mallocN(sizeof(PathStore) + path_size, __func__);
+ char *filepath = (char *)(path_store + 1);
+
+ memcpy(filepath, path_src, path_size);
+ BLI_addtail(ls, path_store);
+ return FALSE;
+}
+
+static int bpath_list_restore(void *userdata, char *path_dst, const char *path_src)
+{
+ /* assume ls->first wont be NULL because the number of paths can't change!
+ * (if they do caller is wrong) */
+ ListBase *ls = userdata;
+ struct PathStore *path_store = ls->first;
+ const char *filepath = (char *)(path_store + 1);
+ int ret;
+
+ if (strcmp(path_src, filepath) == 0) {
+ ret = FALSE;
+ }
+ else {
+ BLI_strncpy(path_dst, filepath, FILE_MAX);
+ ret = TRUE;
+ }
+
+ BLI_freelinkN(ls, path_store);
+ return ret;
+}
+
+/* return ls_handle */
+void *BKE_bpath_list_backup(Main *bmain, const int flag)
+{
+ ListBase *ls = MEM_callocN(sizeof(ListBase), __func__);
+
+ BKE_bpath_traverse_main(bmain, bpath_list_append, flag, ls);
+
+ return ls;
+}
+
+void BKE_bpath_list_restore(Main *bmain, const int flag, void *ls_handle)
+{
+ ListBase *ls = ls_handle;
+
+ BKE_bpath_traverse_main(bmain, bpath_list_restore, flag, ls);
+}
+
+void BKE_bpath_list_free(void *ls_handle)
+{
+ ListBase *ls = ls_handle;
+ BLI_assert(ls->first == NULL); /* assumes we were used */
+ BLI_freelistN(ls);
+ MEM_freeN(ls);
+}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index f310895..aeb0407 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -29,27 +29,15 @@
* \ingroup bke
*/
-
-#include <math.h>
-#include <string.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
-#include "DNA_color_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "WM_types.h"
-#include "RNA_access.h"
-
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_rand.h"
-#include "BLI_utildefines.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
@@ -65,7 +53,6 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
-#include "RE_shader_ext.h"
static void brush_defaults(Brush *brush)
{
@@ -644,8 +631,9 @@ void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
int BKE_brush_size_get(const Scene *scene, Brush *brush)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
-
- return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
+ int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
+
+ return (int)((float)size * U.pixelsize);
}
int BKE_brush_use_locked_size(const Scene *scene, Brush *brush)
@@ -694,7 +682,7 @@ float BKE_brush_unprojected_radius_get(const Scene *scene, Brush *brush)
brush->unprojected_radius;
}
-static void brush_alpha_set(Scene *scene, Brush *brush, float alpha)
+void BKE_brush_alpha_set(Scene *scene, Brush *brush, float alpha)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
@@ -752,315 +740,6 @@ void BKE_brush_scale_size(int *r_brush_size,
(*r_brush_size) = (int)((float)(*r_brush_size) * scale);
}
-/* Brush Painting */
-
-typedef struct BrushPainterCache {
- short enabled;
-
- int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
- short flt; /* need float imbuf? */
- short texonly; /* no alpha, color or fallof, only texture in imbuf */
-
- int lastsize;
- float lastalpha;
- float lastjitter;
-
- ImBuf *ibuf;
- ImBuf *texibuf;
- ImBuf *maskibuf;
-} BrushPainterCache;
-
-struct BrushPainter {
- Scene *scene;
- Brush *brush;
-
- float lastmousepos[2]; /* mouse position of last paint call */
-
- float accumdistance; /* accumulated distance of brush since last paint op */
- float lastpaintpos[2]; /* position of last paint op */
- float startpaintpos[2]; /* position of first paint */
-
- double accumtime; /* accumulated time since last paint op (airbrush) */
- double lasttime; /* time of last update */
-
- float lastpressure;
-
- short firsttouch; /* first paint op */
-
- float startsize;
- float startalpha;
- float startjitter;
- float startspacing;
-
- BrushPainterCache cache;
-};
-
-BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
-{
- BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
-
- painter->brush = brush;
- painter->scene = scene;
- painter->firsttouch = 1;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
-
- painter->startsize = BKE_brush_size_get(scene, brush);
- painter->startalpha = BKE_brush_alpha_get(scene, brush);
- painter->startjitter = brush->jitter;
- painter->startspacing = brush->spacing;
-
- return painter;
-}
-
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
-{
- if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
- ((painter->cache.texonly != texonly) && texonly))
- {
- if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
- if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
- painter->cache.ibuf = painter->cache.maskibuf = NULL;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
- }
-
- if (painter->cache.flt != flt) {
- if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
- painter->cache.texibuf = NULL;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
- }
-
- painter->cache.size = size;
- painter->cache.flt = flt;
- painter->cache.texonly = texonly;
- painter->cache.enabled = 1;
-}
-
-void BKE_brush_painter_free(BrushPainter *painter)
-{
- Brush *brush = painter->brush;
-
- BKE_brush_size_set(painter->scene, brush, painter->startsize);
- brush_alpha_set(painter->scene, brush, painter->startalpha);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
- if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
- if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
- if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
- MEM_freeN(painter);
-}
-
-static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
- int x, int y, int w, int h, int xt, int yt,
- const float pos[2])
-{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- ImBuf *ibuf, *maskibuf, *texibuf;
- float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
- unsigned char *b, *m, *t, *ot = NULL;
- int dotexold, origx = x, origy = y;
- const int radius = BKE_brush_size_get(painter->scene, brush);
-
- xoff = -radius + 0.5f;
- yoff = -radius + 0.5f;
- xoff += (int)pos[0] - (int)painter->startpaintpos[0];
- yoff += (int)pos[1] - (int)painter->startpaintpos[1];
-
- ibuf = painter->cache.ibuf;
- texibuf = painter->cache.texibuf;
- maskibuf = painter->cache.maskibuf;
-
- dotexold = (oldtexibuf != NULL);
-
- /* not sure if it's actually needed or it's a mistake in coords/sizes
- * calculation in brush_painter_fixed_tex_partial_update(), but without this
- * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
- w = min_ii(w, ibuf->x);
- h = min_ii(h, ibuf->y);
-
- if (painter->cache.flt) {
- for (; y < h; y++) {
- bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
- tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
- mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;
-
- if (dotexold)
- otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
-
- for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
- if (dotexold) {
- copy_v3_v3(tf, otf);
- tf[3] = otf[3];
- otf += 4;
- }
- else {
- xy[0] = x + xoff;
- xy[1] = y + yoff;
-
- BKE_brush_sample_tex(scene, brush, xy, tf, 0);
- }
-
- bf[0] = tf[0] * mf[0];
- bf[1] = tf[1] * mf[1];
- bf[2] = tf[2] * mf[2];
- bf[3] = tf[3] * mf[3];
- }
- }
- }
- else {
- for (; y < h; y++) {
- b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
- t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
- m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;
-
- if (dotexold)
- ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
-
- for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
- if (dotexold) {
- t[0] = ot[0];
- t[1] = ot[1];
- t[2] = ot[2];
- t[3] = ot[3];
- ot += 4;
- }
- else {
- xy[0] = x + xoff;
- xy[1] = y + yoff;
-
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
- rgba_float_to_uchar(t, rgba);
- }
-
- b[0] = t[0] * m[0] / 255;
- b[1] = t[1] * m[1] / 255;
- b[2] = t[2] * m[2] / 255;
- b[3] = t[3] * m[3] / 255;
- }
- }
- }
-}
-
-static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, const float pos[2])
-{
- const Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- BrushPainterCache *cache = &painter->cache;
- ImBuf *oldtexibuf, *ibuf;
- int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
- const int diameter = 2 * BKE_brush_size_get(scene, brush);
-
- imbflag = (cache->flt) ? IB_rectfloat : IB_rect;
- if (!cache->ibuf)
- cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
- ibuf = cache->ibuf;
-
- oldtexibuf = cache->texibuf;
- cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
-
- if (oldtexibuf) {
- srcx = srcy = 0;
- destx = (int)painter->lastpaintpos[0] - (int)pos[0];
- desty = (int)painter->lastpaintpos[1] - (int)pos[1];
- w = oldtexibuf->x;
- h = oldtexibuf->y;
-
- IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
- }
- else {
- srcx = srcy = 0;
- destx = desty = 0;
- w = h = 0;
- }
-
- x1 = destx;
- y1 = desty;
- x2 = destx + w;
- y2 = desty + h;
-
- /* blend existing texture in new position */
- if ((x1 < x2) && (y1 < y2))
- brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
-
- if (oldtexibuf)
- IMB_freeImBuf(oldtexibuf);
-
- /* sample texture in new areas */
- if ((0 < x1) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
- if ((x2 < ibuf->x) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
- if ((x1 < x2) && (0 < y1))
- brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
- if ((x1 < x2) && (y2 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
-}
-
-static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
-{
- const Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- BrushPainterCache *cache = &painter->cache;
- MTex *mtex = &brush->mtex;
- int size;
- short flt;
- const int diameter = 2 * BKE_brush_size_get(scene, brush);
- const float alpha = BKE_brush_alpha_get(scene, brush);
-
- if (diameter != cache->lastsize ||
- alpha != cache->lastalpha ||
- brush->jitter != cache->lastjitter)
- {
- if (cache->ibuf) {
- IMB_freeImBuf(cache->ibuf);
- cache->ibuf = NULL;
- }
- if (cache->maskibuf) {
- IMB_freeImBuf(cache->maskibuf);
- cache->maskibuf = NULL;
- }
-
- flt = cache->flt;
- size = (cache->size) ? cache->size : diameter;
-
- if (brush->flag & BRUSH_FIXED_TEX) {
- BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
- brush_painter_fixed_tex_partial_update(painter, pos);
- }
- else
- BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
-
- cache->lastsize = diameter;
- cache->lastalpha = alpha;
- cache->lastjitter = brush->jitter;
- }
- else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
- int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
- int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
-
- if ((dx != 0) || (dy != 0))
- brush_painter_fixed_tex_partial_update(painter, pos);
- }
-}
-
-void BKE_brush_painter_break_stroke(BrushPainter *painter)
-{
- painter->firsttouch = 1;
-}
-
-static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
-{
- if (BKE_brush_use_alpha_pressure(painter->scene, brush))
- brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
- if (BKE_brush_use_size_pressure(painter->scene, brush))
- BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
- if (brush->flag & BRUSH_JITTER_PRESSURE)
- brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
- if (brush->flag & BRUSH_SPACING_PRESSURE)
- brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
-}
-
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
int use_jitter = brush->jitter != 0;
@@ -1088,165 +767,6 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
}
}
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
- void *user, int use_color_correction)
-{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- int totpaintops = 0;
-
- if (pressure == 0.0f) {
- if (painter->lastpressure) // XXX - hack, operator misses
- pressure = painter->lastpressure;
- else
- pressure = 1.0f; /* zero pressure == not using tablet */
- }
- if (painter->firsttouch) {
- /* paint exactly once on first touch */
- painter->startpaintpos[0] = pos[0];
- painter->startpaintpos[1] = pos[1];
-
- brush_pressure_apply(painter, brush, pressure);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, pos, use_color_correction);
- totpaintops += func(user, painter->cache.ibuf, pos, pos);
-
- painter->lasttime = time;
- painter->firsttouch = 0;
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- }
-#if 0
- else if (painter->brush->flag & BRUSH_AIRBRUSH) {
- float spacing, step, paintpos[2], dmousepos[2], len;
- double starttime, curtime = time;
-
- /* compute brush spacing adapted to brush size */
- spacing = brush->rate; //radius*brush->spacing*0.01f;
-
- /* setup starting time, direction vector and accumulated time */
- starttime = painter->accumtime;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumtime += curtime - painter->lasttime;
-
- /* do paint op over unpainted time distance */
- while (painter->accumtime >= spacing) {
- step = (spacing - starttime) * len;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter);
- totpaintops += func(user, painter->cache.ibuf,
- painter->lastpaintpos, paintpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumtime -= spacing;
- starttime -= spacing;
- }
-
- painter->lasttime = curtime;
- }
-#endif
- else {
- float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
- float t, len, press;
- const int radius = BKE_brush_size_get(scene, brush);
-
- /* compute brush spacing adapted to brush radius, spacing may depend
- * on pressure, so update it */
- brush_pressure_apply(painter, brush, painter->lastpressure);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- /* setup starting distance, direction vector and accumulated distance */
- startdistance = painter->accumdistance;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumdistance += len;
-
- if (brush->flag & BRUSH_SPACE) {
- /* do paint op over unpainted distance */
- while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
- step = spacing - startdistance;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- t = step / len;
- press = (1.0f - t) * painter->lastpressure + t * pressure;
- brush_pressure_apply(painter, brush, press);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumdistance -= spacing;
- startdistance -= spacing;
- }
- }
- else {
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
-
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- painter->accumdistance = 0;
- }
-
- /* do airbrush paint ops, based on the number of paint ops left over
- * from regular painting. this is a temporary solution until we have
- * accurate time stamps for mouse move events */
- if (brush->flag & BRUSH_AIRBRUSH) {
- double curtime = time;
- double painttime = brush->rate * totpaintops;
-
- painter->accumtime += curtime - painter->lasttime;
- if (painter->accumtime <= painttime)
- painter->accumtime = 0.0;
- else
- painter->accumtime -= painttime;
-
- while (painter->accumtime >= (double)brush->rate) {
- brush_pressure_apply(painter, brush, pressure);
-
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
- painter->accumtime -= (double)brush->rate;
- }
-
- painter->lasttime = curtime;
- }
- }
-
- painter->lastmousepos[0] = pos[0];
- painter->lastmousepos[1] = pos[1];
- painter->lastpressure = pressure;
-
- brush_alpha_set(scene, brush, painter->startalpha);
- BKE_brush_size_set(scene, brush, painter->startsize);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
- return totpaintops;
-}
-
/* Uses the brush curve control to find a strength value between 0 and 1 */
float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len)
{
@@ -1273,48 +793,6 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len)
return curvemapping_evaluateF(br->curve, 0, p);
}
-/* TODO: should probably be unified with BrushPainter stuff? */
-unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
-{
- unsigned int *texcache = NULL;
- MTex *mtex = &br->mtex;
- TexResult texres = {0};
- int hasrgb, ix, iy;
- int side = half_side * 2;
-
- if (mtex->tex) {
- float x, y, step = 2.0 / side, co[3];
-
- texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
-
- /*do normalized cannonical view coords for texture*/
- for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
- for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
- co[0] = x;
- co[1] = y;
- co[2] = 0.0f;
-
- /* This is copied from displace modifier code */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (hasrgb & TEX_RGB)
- texres.tin = rgb_to_grayscale(&texres.tr);
-
- ((char *)texcache)[(iy * side + ix) * 4] =
- ((char *)texcache)[(iy * side + ix) * 4 + 1] =
- ((char *)texcache)[(iy * side + ix) * 4 + 2] =
- ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
- }
- }
- }
-
- return texcache;
-}
-
/**** Radial Control ****/
struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br)
{
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 54bbe4b..85dd4c6 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -40,12 +40,12 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
#include "BLI_array.h"
#include "BLI_smallhash.h"
#include "BLI_utildefines.h"
#include "BLI_scanfill.h"
+#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
@@ -262,6 +262,17 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
}
+ /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
+ if (!cddm->pbvh && ob->sculpt->bm) {
+ cddm->pbvh = BKE_pbvh_new();
+ cddm->pbvh_draw = TRUE;
+
+ BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
+ ob->sculpt->bm_smooth_shading,
+ ob->sculpt->bm_log);
+ }
+
+
/* always build pbvh from original mesh, and only use it for drawing if
* this derivedmesh is just original mesh. it's the multires subsurf dm
* that this is actually for, to support a pbvh on a modified mesh */
@@ -270,14 +281,14 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
Mesh *me = ob->data;
int deformed = 0;
- cddm->pbvh = BLI_pbvh_new();
+ cddm->pbvh = BKE_pbvh_new();
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
BKE_mesh_tessface_ensure(me);
- BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
+ BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
deformed = ss->modifiers_active || me->key;
@@ -290,7 +301,7 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
totvert = deformdm->getNumVerts(deformdm);
vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
- BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos);
}
}
@@ -310,7 +321,7 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
+ BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
}
static void cdDM_drawVerts(DerivedMesh *dm)
@@ -414,6 +425,14 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
+
+ if (cddm->pbvh && cddm->pbvh_draw &&
+ BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
+ {
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, TRUE);
+
+ return;
+ }
if (GPU_buffer_legacy(dm)) {
DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
@@ -530,7 +549,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
if (dm->numTessFaceData) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
+ BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors,
+ setMaterial, FALSE);
glShadeModel(GL_FLAT);
}
@@ -627,6 +647,23 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
index_mp_to_orig = NULL;
}
+ /* TODO: not entirely correct, but currently dynamic topology will
+ * destroy UVs anyway, so textured display wouldn't work anyway
+ *
+ * this will do more like solid view with lights set up for
+ * textured view, but object itself will be displayed gray
+ * (the same as it'll display without UV maps in textured view)
+ */
+ if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
+ if (dm->numTessFaceData) {
+ glDisable(GL_TEXTURE_2D);
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE);
+ glEnable(GL_TEXTURE_2D);
+ }
+
+ return;
+ }
+
colType = CD_TEXTURE_MCOL;
mcol = dm->getTessFaceDataArray(dm, colType);
if (!mcol) {
@@ -664,8 +701,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
else {
if (nors) {
- nors += 3; continue;
+ nors += 3;
}
+ continue;
}
}
else if (drawParamsMapped) {
@@ -673,8 +711,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
else {
if (nors) {
- nors += 3; continue;
+ nors += 3;
}
+ continue;
}
}
@@ -1704,6 +1743,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
mesh->totloop, mesh->totpoly);
dm->deformedOnly = 1;
+ dm->cd_flag = mesh->cd_flag;
alloctype = CD_REFERENCE;
@@ -1735,49 +1775,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *CDDM_from_curve(Object *ob)
{
- return CDDM_from_curve_displist(ob, &ob->disp, NULL);
-}
-
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
-{
- int *orco_index_ptr = NULL;
- int (*orco_index)[4] = NULL;
- float (*orco)[3] = NULL;
- DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
-
- if (orco_index_ptr) {
- orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
- }
-
- if (orco && orco_index_ptr) {
- const char *uvname = "Orco";
-
- int totpoly = dm->getNumPolys(dm);
-
- MPoly *mpolys = dm->getPolyArray(dm);
- MLoop *mloops = dm->getLoopArray(dm);
-
- MLoopUV *mloopuvs;
-
- CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
- mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname);
-
- BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
- mloops, mloopuvs,
- orco, orco_index);
- }
-
- if (orco_index) {
- MEM_freeN(orco_index);
- }
- if (orco) {
- MEM_freeN(orco);
- }
-
- return dm;
+ return CDDM_from_curve_displist(ob, &ob->disp);
}
-DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
{
DerivedMesh *dm;
CDDerivedMesh *cddm;
@@ -1788,7 +1789,8 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco
int totvert, totedge, totloop, totpoly;
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
- &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+ &totedge, &allloop, &allpoly, NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing mdata. This often happens when curve is empty */
return CDDM_new(0, 0, 0, 0, 0);
@@ -1875,7 +1877,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
bm->totface);
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- BMIter iter, liter;
+ BMIter iter;
BMVert *eve;
BMEdge *eed;
BMFace *efa;
@@ -1887,13 +1889,12 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
int *index, add_orig;
- int has_crease, has_edge_bweight, has_vert_bweight;
CustomDataMask mask;
unsigned int i, j;
- has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
- has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
- has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
dm->deformedOnly = 1;
@@ -1913,7 +1914,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
CD_CALLOC, dm->numLoopData);
CustomData_merge(&bm->pdata, &dm->polyData, mask,
CD_CALLOC, dm->numPolyData);
-
+
/* add tessellation mface layers */
if (use_tessface) {
CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
@@ -1933,8 +1934,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
mv->flag = BM_vert_flag_to_mflag(eve);
- if (has_vert_bweight)
- mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
+ if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
if (add_orig) *index = i;
@@ -1952,11 +1952,6 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
med->v1 = BM_elem_index_get(eed->v1);
med->v2 = BM_elem_index_get(eed->v2);
- if (has_crease)
- med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
- if (has_edge_bweight)
- med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
-
med->flag = BM_edge_flag_to_mflag(eed);
/* handle this differently to editmode switching,
@@ -1967,6 +1962,9 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
}
}
+ if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
+
CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
if (add_orig) *index = i;
}
@@ -2002,7 +2000,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
j = 0;
efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
- BMLoop *l;
+ BMLoop *l_iter;
+ BMLoop *l_first;
MPoly *mp = &mpoly[i];
BM_elem_index_set(efa, i); /* set_inline */
@@ -2011,15 +2010,16 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
mp->flag = BM_face_flag_to_mflag(efa);
mp->loopstart = j;
mp->mat_nr = efa->mat_nr;
-
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- mloop->v = BM_elem_index_get(l->v);
- mloop->e = BM_elem_index_get(l->e);
- CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ mloop->v = BM_elem_index_get(l_iter->v);
+ mloop->e = BM_elem_index_get(l_iter->e);
+ CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
j++;
mloop++;
- }
+ } while ((l_iter = l_iter->next) != l_first);
CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
@@ -2027,6 +2027,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
}
bm->elem_index_dirty &= ~BM_FACE;
+ dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
return dm;
}
@@ -2064,6 +2066,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
numLoops, numPolys);
dm->deformedOnly = source->deformedOnly;
+ dm->cd_flag = source->cd_flag;
dm->dirty = source->dirty;
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f1d73c7..fdd7dc9 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -1153,7 +1153,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
if ( !mface[i].v4 )
continue;
- spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+ spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
if (!spring) {
cloth_free_errorsprings(cloth, edgehash, edgelist);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 4641a02..60bf67e 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -528,7 +528,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
/* extend array */
if (*numobj >= *maxobj) {
*maxobj *= 2;
- *objs= MEM_reallocN(*objs, sizeof(Object*)*(*maxobj));
+ *objs= MEM_reallocN(*objs, sizeof(Object *)*(*maxobj));
}
(*objs)[*numobj] = ob;
@@ -567,7 +567,9 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned
Scene *sce_iter;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
- if (base->lay & self->lay)
+ /* Need to check for active layers, too.
+ Otherwise this check fails if the objects are not on the same layer - DG */
+ if ((base->lay & self->lay) || (base->lay & scene->lay))
add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0, modifier_type);
}
@@ -738,7 +740,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
/* move object to position (step) in time */
for (i = 0; i < numcollobj; i++) {
Object *collob= collobjs[i];
- CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
if (!collmd->bvhtree)
continue;
@@ -758,7 +760,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
// check all collision objects
for (i = 0; i < numcollobj; i++) {
Object *collob= collobjs[i];
- CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
BVHTreeOverlap *overlap = NULL;
unsigned int result = 0;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 97d7508..1a25def 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -96,7 +96,7 @@
/* -------------- Naming -------------- */
/* Find the first available, non-duplicate name for a given constraint */
-void unique_constraint_name(bConstraint *con, ListBase *list)
+void BKE_unique_constraint_name(bConstraint *con, ListBase *list)
{
BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), sizeof(con->name));
}
@@ -105,7 +105,7 @@ void unique_constraint_name(bConstraint *con, ListBase *list)
/* package an object/bone for use in constraint evaluation */
/* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
-bConstraintOb *constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
+bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
{
bConstraintOb *cob;
@@ -169,7 +169,7 @@ bConstraintOb *constraints_make_evalob(Scene *scene, Object *ob, void *subdata,
}
/* cleanup after constraint evaluation */
-void constraints_clear_evalob(bConstraintOb *cob)
+void BKE_constraints_clear_evalob(bConstraintOb *cob)
{
float delta[4][4], imat[4][4];
@@ -219,7 +219,7 @@ void constraints_clear_evalob(bConstraintOb *cob)
* of a matrix from one space to another for constraint evaluation.
* For now, this is only implemented for Objects and PoseChannels.
*/
-void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
+void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to)
{
float diff_mat[4][4];
float imat[4][4];
@@ -242,7 +242,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* use pose-space as stepping stone for other spaces... */
if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -278,7 +278,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -293,7 +293,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -345,7 +345,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
/* ------------ General Target Matrix Tools ---------- */
/* function that sets the given matrix based on given vertex group in mesh */
-static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[][4])
+static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4])
{
DerivedMesh *dm = NULL;
BMEditMesh *em = BMEdit_FromObject(ob);
@@ -441,7 +441,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
}
/* function that sets the given matrix based on given vertex group in lattice */
-static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[][4])
+static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[4][4])
{
Lattice *lt = (Lattice *)ob->data;
@@ -494,12 +494,12 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
/* generic function to get the appropriate matrix for most target cases */
/* The cases where the target can be object data have not been implemented */
-static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[][4], short from, short to, float headtail)
+static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[4][4], short from, short to, float headtail)
{
/* Case OBJECT */
if (!strlen(substring)) {
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
/* Case VERTEXGROUP */
/* Current method just takes the average location of all the points in the
@@ -512,11 +512,11 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
*/
else if (ob->type == OB_MESH) {
contarget_get_mesh_mat(ob, substring, mat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
else if (ob->type == OB_LATTICE) {
contarget_get_lattice_mat(ob, substring, mat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
/* Case BONE */
else {
@@ -549,7 +549,7 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
copy_m4_m4(mat, ob->obmat);
/* convert matrix space as required */
- constraint_mat_convertspace(ob, pchan, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, from, to);
}
}
@@ -890,7 +890,7 @@ static int basis_cross(int n, int m)
}
}
-static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[][3])
+static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[3][3])
{
float n[3];
float u[3]; /* vector specifying the up axis */
@@ -4211,7 +4211,7 @@ static void constraints_init_typeinfo(void)
/* This function should be used for getting the appropriate type-info when only
* a constraint type is known
*/
-bConstraintTypeInfo *get_constraint_typeinfo(int type)
+bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type)
{
/* initialize the type-info list? */
if (CTI_INIT) {
@@ -4236,11 +4236,11 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type)
/* This function should always be used to get the appropriate type-info, as it
* has checks which prevent segfaults in some weird cases.
*/
-bConstraintTypeInfo *constraint_get_typeinfo(bConstraint *con)
+bConstraintTypeInfo *BKE_constraint_get_typeinfo(bConstraint *con)
{
/* only return typeinfo for valid constraints */
if (con)
- return get_constraint_typeinfo(con->type);
+ return BKE_get_constraint_typeinfo(con->type);
else
return NULL;
}
@@ -4252,7 +4252,7 @@ bConstraintTypeInfo *constraint_get_typeinfo(bConstraint *con)
/* ---------- Data Management ------- */
-/* helper function for free_constraint_data() - unlinks references */
+/* helper function for BKE_free_constraint_data() - unlinks references */
static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
{
if (*idpoin && isReference)
@@ -4263,10 +4263,10 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isRe
* be sure to run BIK_clear_data() when freeing an IK constraint,
* unless DAG_scene_sort is called.
*/
-void free_constraint_data(bConstraint *con)
+void BKE_free_constraint_data(bConstraint *con)
{
if (con->data) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti) {
/* perform any special freeing constraint may have */
@@ -4284,13 +4284,13 @@ void free_constraint_data(bConstraint *con)
}
/* Free all constraints from a constraint-stack */
-void free_constraints(ListBase *list)
+void BKE_free_constraints(ListBase *list)
{
bConstraint *con;
/* Free constraint data and also any extra data */
for (con = list->first; con; con = con->next)
- free_constraint_data(con);
+ BKE_free_constraint_data(con);
/* Free the whole list */
BLI_freelistN(list);
@@ -4298,10 +4298,10 @@ void free_constraints(ListBase *list)
/* Remove the specified constraint from the given constraint stack */
-int remove_constraint(ListBase *list, bConstraint *con)
+int BKE_remove_constraint(ListBase *list, bConstraint *con)
{
if (con) {
- free_constraint_data(con);
+ BKE_free_constraint_data(con);
BLI_freelinkN(list, con);
return 1;
}
@@ -4310,7 +4310,7 @@ int remove_constraint(ListBase *list, bConstraint *con)
}
/* Remove all the constraints of the specified type from the given constraint stack */
-void remove_constraints_type(ListBase *list, short type, short last_only)
+void BKE_remove_constraints_type(ListBase *list, short type, short last_only)
{
bConstraint *con, *conp;
@@ -4322,7 +4322,7 @@ void remove_constraints_type(ListBase *list, short type, short last_only)
conp = con->prev;
if (con->type == type) {
- remove_constraint(list, con);
+ BKE_remove_constraint(list, con);
if (last_only)
return;
}
@@ -4335,7 +4335,7 @@ void remove_constraints_type(ListBase *list, short type, short last_only)
static bConstraint *add_new_constraint_internal(const char *name, short type)
{
bConstraint *con = MEM_callocN(sizeof(bConstraint), "Constraint");
- bConstraintTypeInfo *cti = get_constraint_typeinfo(type);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(type);
const char *newName;
/* Set up a generic constraint datablock */
@@ -4385,17 +4385,17 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
* (otherwise unique-naming code will fail, since it assumes element exists in list)
*/
BLI_addtail(list, con);
- unique_constraint_name(con, list);
+ BKE_unique_constraint_name(con, list);
/* if the target list is a list on some PoseChannel belonging to a proxy-protected
* Armature layer, we must tag newly added constraints with a flag which allows them
* to persist after proxy syncing has been done
*/
- if (proxylocked_constraints_owner(ob, pchan))
+ if (BKE_proxylocked_constraints_owner(ob, pchan))
con->flag |= CONSTRAINT_PROXY_LOCAL;
/* make this constraint the active one */
- constraints_set_active(list, con);
+ BKE_constraints_set_active(list, con);
}
/* set type+owner specific immutable settings */
@@ -4419,7 +4419,7 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
/* ......... */
/* Add new constraint for the given bone */
-bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
+bConstraint *BKE_add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
{
if (pchan == NULL)
return NULL;
@@ -4428,14 +4428,14 @@ bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *na
}
/* Add new constraint for the given object */
-bConstraint *add_ob_constraint(Object *ob, const char *name, short type)
+bConstraint *BKE_add_ob_constraint(Object *ob, const char *name, short type)
{
return add_new_constraint(ob, NULL, name, type);
}
/* ......... */
-/* helper for relink_constraints() - call ID_NEW() on every ID reference the constraint has */
+/* helper for BKE_relink_constraints() - call ID_NEW() on every ID reference the constraint has */
static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userdata))
{
/* ID_NEW() expects a struct with inline "id" member as first
@@ -4449,20 +4449,20 @@ static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED
}
/* Reassign links that constraints have to other data (called during file loading?) */
-void relink_constraints(ListBase *conlist)
+void BKE_relink_constraints(ListBase *conlist)
{
/* just a wrapper around ID-loop for just calling ID_NEW() on all ID refs */
- id_loop_constraints(conlist, con_relink_id_cb, NULL);
+ BKE_id_loop_constraints(conlist, con_relink_id_cb, NULL);
}
/* Run the given callback on all ID-blocks in list of constraints */
-void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
+void BKE_id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
{
bConstraint *con;
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti) {
if (cti->id_looper)
@@ -4473,14 +4473,14 @@ void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdat
/* ......... */
-/* helper for copy_constraints(), to be used for making sure that ID's are valid */
+/* helper for BKE_copy_constraints(), to be used for making sure that ID's are valid */
static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userData))
{
if (*idpoin && (*idpoin)->lib)
id_lib_extern(*idpoin);
}
-/* helper for copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
+/* helper for BKE_copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
{
/* increment usercount if this is a reference type */
@@ -4489,7 +4489,7 @@ static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short
}
/* duplicate all of the constraints in a constraint stack */
-void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
+void BKE_copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
{
bConstraint *con, *srccon;
@@ -4497,7 +4497,7 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
BLI_duplicatelist(dst, src);
for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
/* make a new copy of the constraint's data */
con->data = MEM_dupallocN(con->data);
@@ -4524,13 +4524,13 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
/* ......... */
-bConstraint *constraints_findByName(ListBase *list, const char *name)
+bConstraint *BKE_constraints_findByName(ListBase *list, const char *name)
{
return BLI_findstring(list, name, offsetof(bConstraint, name));
}
/* finds the 'active' constraint in a constraint stack */
-bConstraint *constraints_get_active(ListBase *list)
+bConstraint *BKE_constraints_get_active(ListBase *list)
{
bConstraint *con;
@@ -4547,7 +4547,7 @@ bConstraint *constraints_get_active(ListBase *list)
}
/* Set the given constraint as the active one (clearing all the others) */
-void constraints_set_active(ListBase *list, bConstraint *con)
+void BKE_constraints_set_active(ListBase *list, bConstraint *con)
{
bConstraint *c;
@@ -4564,7 +4564,7 @@ void constraints_set_active(ListBase *list, bConstraint *con)
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
-void extract_proxylocal_constraints(ListBase *dst, ListBase *src)
+void BKE_extract_proxylocal_constraints(ListBase *dst, ListBase *src)
{
bConstraint *con, *next;
@@ -4581,7 +4581,7 @@ void extract_proxylocal_constraints(ListBase *dst, ListBase *src)
}
/* Returns if the owner of the constraint is proxy-protected */
-short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
+short BKE_proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
{
/* Currently, constraints can only be on object or bone level */
if (ob && ob->proxy) {
@@ -4610,9 +4610,9 @@ short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
* None of the actual calculations of the matrices should be done here! Also, this function is
* not to be used by any new constraints, particularly any that have multiple targets.
*/
-void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
+void BKE_get_constraint_target_matrix(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintOb *cob;
bConstraintTarget *ct;
@@ -4657,10 +4657,8 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n,
cti->get_constraint_targets(con, &targets);
/* only calculate the target matrix on the first target */
- ct = (bConstraintTarget *)targets.first;
- while (ct && n-- > 0)
- ct = ct->next;
-
+ ct = (bConstraintTarget *)BLI_findlink(&targets, index);
+
if (ct) {
if (cti->get_target_matrix)
cti->get_target_matrix(con, cob, ct, ctime);
@@ -4679,9 +4677,9 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n,
}
/* Get the list of targets required for solving a constraint */
-void get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti && cti->get_constraint_targets) {
bConstraintTarget *ct;
@@ -4711,10 +4709,10 @@ void get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, Li
/* This function is called whenever constraints need to be evaluated. Currently, all
* constraints that can be evaluated are everytime this gets run.
*
- * constraints_make_evalob and constraints_clear_evalob should be called before and
+ * BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
* after running this function, to sort out cob
*/
-void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
float oldmat[4][4];
@@ -4726,7 +4724,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* loop over available constraints, solving and blending them */
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
/* these we can skip completely (invalid constraints...) */
@@ -4746,10 +4744,10 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
copy_m4_m4(oldmat, cob->matrix);
/* move owner matrix into right space */
- constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
/* prepare targets for constraint solving */
- get_constraint_targets_for_solving(con, cob, &targets, ctime);
+ BKE_get_constraint_targets_for_solving(con, cob, &targets, ctime);
/* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
@@ -4764,7 +4762,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* move owner back into worldspace for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0)
- constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
/* Interpolate the enforcement, to blend result of constraint into final owner transform
* - all this happens in worldspace to prevent any weirdness creeping in ([#26014] and [#25725]),
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index ffb9313..a45afa5 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -29,6 +29,7 @@
#include <string.h>
+#include <stdlib.h>
#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -327,10 +328,13 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
- if (C && ctx_data_get((bContext *)C, member, &result) == 1)
+ if (C && ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr.data;
-
- return NULL;
+ }
+ else {
+ return NULL;
+ }
}
static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
@@ -343,6 +347,7 @@ static int ctx_data_pointer_verify(const bContext *C, const char *member, void *
return 1;
}
else if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
*pointer = result.ptr.data;
return 1;
}
@@ -357,6 +362,7 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
*list = result.list;
return 1;
}
@@ -371,10 +377,13 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
- if (ctx_data_get((bContext *)C, member, &result) == 1)
+ if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr;
- else
+ }
+ else {
return PointerRNA_NULL;
+ }
}
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
@@ -399,6 +408,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member)
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
return result.list;
}
else {
@@ -427,11 +437,11 @@ int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListB
return ret;
}
-static void data_dir_add(ListBase *lb, const char *member)
+static void data_dir_add(ListBase *lb, const char *member, const short use_all)
{
LinkData *link;
- if (strcmp(member, "scene") == 0) /* exception */
+ if ((use_all == FALSE) && strcmp(member, "scene") == 0) /* exception */
return;
if (BLI_findstring(lb, member, offsetof(LinkData, data)))
@@ -442,7 +452,13 @@ static void data_dir_add(ListBase *lb, const char *member)
BLI_addtail(lb, link);
}
-ListBase CTX_data_dir_get(const bContext *C)
+/**
+ * \param C Context
+ * \param use_store Use 'C->wm.store'
+ * \param use_rna Use Include the properties from 'RNA_Context'
+ * \param use_all Don't skip values (currently only "scene")
+ */
+ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all)
{
bContextDataResult result;
ListBase lb;
@@ -453,11 +469,33 @@ ListBase CTX_data_dir_get(const bContext *C)
memset(&lb, 0, sizeof(lb));
- if (C->wm.store) {
+ if (use_rna) {
+ char name[256], *nameptr;
+ int namelen;
+
+ PropertyRNA *iterprop;
+ PointerRNA ctx_ptr;
+ RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
+
+ iterprop = RNA_struct_iterator_property(ctx_ptr.type);
+
+ RNA_PROP_BEGIN (&ctx_ptr, itemptr, iterprop)
+ {
+ nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
+ data_dir_add(&lb, name, use_all);
+ if (nameptr) {
+ if (name != nameptr) {
+ MEM_freeN(nameptr);
+ }
+ }
+ }
+ RNA_PROP_END;
+ }
+ if (use_store && C->wm.store) {
bContextStoreEntry *entry;
for (entry = C->wm.store->entries.first; entry; entry = entry->next)
- data_dir_add(&lb, entry->name);
+ data_dir_add(&lb, entry->name, use_all);
}
if ((ar = CTX_wm_region(C)) && ar->type && ar->type->context) {
memset(&result, 0, sizeof(result));
@@ -465,7 +503,7 @@ ListBase CTX_data_dir_get(const bContext *C)
if (result.dir)
for (a = 0; result.dir[a]; a++)
- data_dir_add(&lb, result.dir[a]);
+ data_dir_add(&lb, result.dir[a], use_all);
}
if ((sa = CTX_wm_area(C)) && sa->type && sa->type->context) {
memset(&result, 0, sizeof(result));
@@ -473,7 +511,7 @@ ListBase CTX_data_dir_get(const bContext *C)
if (result.dir)
for (a = 0; result.dir[a]; a++)
- data_dir_add(&lb, result.dir[a]);
+ data_dir_add(&lb, result.dir[a], use_all);
}
if ((sc = CTX_wm_screen(C)) && sc->context) {
bContextDataCallback cb = sc->context;
@@ -482,12 +520,17 @@ ListBase CTX_data_dir_get(const bContext *C)
if (result.dir)
for (a = 0; result.dir[a]; a++)
- data_dir_add(&lb, result.dir[a]);
+ data_dir_add(&lb, result.dir[a], use_all);
}
return lb;
}
+ListBase CTX_data_dir_get(const bContext *C)
+{
+ return CTX_data_dir_get_ex(C, TRUE, FALSE, FALSE);
+}
+
int CTX_data_equals(const char *member, const char *str)
{
return (strcmp(member, str) == 0);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 754a4fb..a9c4a7d 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -36,7 +36,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_bpath.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -68,7 +67,7 @@
/* local */
static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3],
short cox, short coy,
- float *labda, float *mu, float vec[3]);
+ float *lambda, float *mu, float vec[3]);
void BKE_curve_unlink(Curve *cu)
{
@@ -876,7 +875,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv)
-/* coord_array has to be 3*4*resolu*resolv in size, and zero-ed */
+/* coord_array has to be (3 * 4 * resolu * resolv) in size, and zero-ed */
{
BPoint *bp;
float *basisu, *basis, *basisv, *sum, *fp, *in;
@@ -1615,7 +1614,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende
static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3],
short cox, short coy,
- float *labda, float *mu, float vec[3])
+ float *lambda, float *mu, float vec[3])
{
/* return:
* -1: collinear
@@ -1629,22 +1628,22 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c
if (deler == 0.0f)
return -1;
- *labda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]);
- *labda = -(*labda / deler);
+ *lambda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]);
+ *lambda = -(*lambda / deler);
deler = v3[coy] - v4[coy];
if (deler == 0) {
deler = v3[cox] - v4[cox];
- *mu = -(*labda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler;
+ *mu = -(*lambda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler;
}
else {
- *mu = -(*labda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler;
+ *mu = -(*lambda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler;
}
- vec[cox] = *labda * (v2[cox] - v1[cox]) + v1[cox];
- vec[coy] = *labda * (v2[coy] - v1[coy]) + v1[coy];
+ vec[cox] = *lambda * (v2[cox] - v1[cox]) + v1[cox];
+ vec[coy] = *lambda * (v2[coy] - v1[coy]) + v1[coy];
- if (*labda >= 0.0f && *labda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) {
- if (*labda == 0.0f || *labda == 1.0f || *mu == 0.0f || *mu == 1.0f)
+ if (*lambda >= 0.0f && *lambda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) {
+ if (*lambda == 0.0f || *lambda == 1.0f || *mu == 0.0f || *mu == 1.0f)
return 1;
return 2;
}
@@ -1654,7 +1653,7 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c
static short bevelinside(BevList *bl1, BevList *bl2)
{
- /* is bl2 INSIDE bl1 ? with left-right method and "labda's" */
+ /* is bl2 INSIDE bl1 ? with left-right method and "lambda's" */
/* returns '1' if correct hole */
BevPoint *bevp, *prevbevp;
float min, max, vec[3], hvec1[3], hvec2[3], lab, mu;
@@ -1747,7 +1746,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
else
t02 = (saacos(t02)) / 2.0f;
- t02 = (float)sin(t02);
+ t02 = sinf(t02);
if (t02 == 0.0f)
t02 = 1.0f;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index b2f8db0..f3548f7 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2095,6 +2095,23 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
return data->layers[layer_index].data;
}
+int CustomData_get_offset(const CustomData *data, int type)
+{
+ /* get the layer index of the active layer of type */
+ int layer_index = CustomData_get_active_layer_index(data, type);
+ if (layer_index < 0) return -1;
+
+ return data->layers[layer_index].offset;
+}
+
+int CustomData_get_n_offset(const CustomData *data, int type, int n)
+{
+ /* get the layer index of the active layer of type */
+ int layer_index = CustomData_get_layer_index_n(data, type, n);
+ if (layer_index < 0) return -1;
+
+ return data->layers[layer_index].offset;
+}
int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
{
@@ -2104,7 +2121,7 @@ int CustomData_set_layer_name(const CustomData *data, int type, int n, const cha
if (layer_index < 0) return 0;
if (!name) return 0;
- strcpy(data->layers[layer_index].name, name);
+ BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name));
return 1;
}
@@ -2298,34 +2315,46 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
BMIter iter;
CustomData destold;
void *tmp;
- int t;
+ int iter_type;
+ int totelem;
/* copy old layer description so that old data can be copied into
* the new allocation */
destold = *dest;
- if (destold.layers) destold.layers = MEM_dupallocN(destold.layers);
-
- CustomData_merge(source, dest, mask, alloctype, 0);
- dest->pool = NULL;
- CustomData_bmesh_init_pool(dest, 512, htype);
+ if (destold.layers) {
+ destold.layers = MEM_dupallocN(destold.layers);
+ }
switch (htype) {
case BM_VERT:
- t = BM_VERTS_OF_MESH; break;
+ iter_type = BM_VERTS_OF_MESH;
+ totelem = bm->totvert;
+ break;
case BM_EDGE:
- t = BM_EDGES_OF_MESH; break;
+ iter_type = BM_EDGES_OF_MESH;
+ totelem = bm->totedge;
+ break;
case BM_LOOP:
- t = BM_LOOPS_OF_FACE; break;
+ iter_type = BM_LOOPS_OF_FACE;
+ totelem = bm->totloop;
+ break;
case BM_FACE:
- t = BM_FACES_OF_MESH; break;
+ iter_type = BM_FACES_OF_MESH;
+ totelem = bm->totface;
+ break;
default: /* should never happen */
BLI_assert(!"invalid type given");
- t = BM_VERTS_OF_MESH;
+ iter_type = BM_VERTS_OF_MESH;
+ totelem = bm->totvert;
}
- if (t != BM_LOOPS_OF_FACE) {
+ CustomData_merge(source, dest, mask, alloctype, 0);
+ dest->pool = NULL;
+ CustomData_bmesh_init_pool(dest, totelem, htype);
+
+ if (iter_type != BM_LOOPS_OF_FACE) {
/*ensure all current elements follow new customdata layout*/
- BM_ITER_MESH (h, &iter, bm, t) {
+ BM_ITER_MESH (h, &iter, bm, iter_type) {
tmp = NULL;
CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
CustomData_bmesh_free_block(&destold, &h->data);
@@ -2618,6 +2647,19 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
memcpy(dest, source, typeInfo->size);
}
+/**
+ * \param src_blocks must be pointers to the data, offset by layer->offset already.
+ */
+void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dest_block, int n)
+{
+ CustomDataLayer *layer = &data->layers[n];
+ const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+
+ typeInfo->interp(src_blocks, weights, sub_weights, count,
+ (char *)dest_block + layer->offset);
+}
+
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights,
const float *sub_weights, int count, void *dest_block)
{
@@ -2640,36 +2682,47 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w
for (j = 0; j < count; ++j) {
sources[j] = (char *)src_blocks[j] + layer->offset;
}
-
- typeInfo->interp(sources, weights, sub_weights, count,
- (char *)dest_block + layer->offset);
+ CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i);
}
}
if (count > SOURCE_BUF_SIZE) MEM_freeN(sources);
}
-void CustomData_bmesh_set_default(CustomData *data, void **block)
+static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
{
const LayerTypeInfo *typeInfo;
+ int offset = data->layers[n].offset;
+
+ typeInfo = layerType_getInfo(data->layers[n].type);
+
+ if (typeInfo->set_default) {
+ typeInfo->set_default((char *)*block + offset, 1);
+ }
+ else {
+ memset((char *)*block + offset, 0, typeInfo->size);
+ }
+}
+
+void CustomData_bmesh_set_default(CustomData *data, void **block)
+{
int i;
if (*block == NULL)
CustomData_bmesh_alloc_block(data, block);
for (i = 0; i < data->totlayer; ++i) {
- int offset = data->layers[i].offset;
-
- typeInfo = layerType_getInfo(data->layers[i].type);
-
- if (typeInfo->set_default)
- typeInfo->set_default((char *)*block + offset, 1);
- else memset((char *)*block + offset, 0, typeInfo->size);
+ CustomData_bmesh_set_default_n(data, block, i);
}
}
+/**
+ * \param use_default_init initializes data which can't be copied,
+ * typically you'll want to use this if the BM_xxx create function
+ * is called with BM_CREATE_SKIP_CD flag
+ */
void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
- int src_index, void **dest_block)
+ int src_index, void **dest_block, bool use_default_init)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, src_offset;
@@ -2685,11 +2738,14 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
+ if (use_default_init) {
+ CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+ }
dest_i++;
}
/* if there are no more dest layers, we're done */
- if (dest_i >= dest->totlayer) return;
+ if (dest_i >= dest->totlayer) break;
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
@@ -2712,6 +2768,13 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
dest_i++;
}
}
+
+ if (use_default_init) {
+ while (dest_i < dest->totlayer) {
+ CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
+ dest_i++;
+ }
+ }
}
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
@@ -2854,10 +2917,11 @@ void CustomData_validate_layer_name(const CustomData *data, int type, const char
* deleted, so assign the active layer to name
*/
index = CustomData_get_active_layer_index(data, type);
- strcpy(outname, data->layers[index].name);
+ BLI_strncpy(outname, data->layers[index].name, MAX_CUSTOMDATA_LAYER_NAME);
+ }
+ else {
+ BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
}
- else
- strcpy(outname, name);
}
int CustomData_verify_versions(struct CustomData *data, int index)
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 7c13ca3..cea92d5 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -34,6 +34,7 @@
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -337,37 +338,12 @@ void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip
bDeformGroup *defgroup_find_name(Object *ob, const char *name)
{
- /* return a pointer to the deform group with this name
- * or return NULL otherwise.
- */
- bDeformGroup *curdef;
-
- for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
- if (!strcmp(curdef->name, name)) {
- return curdef;
- }
- }
- return NULL;
+ return BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name));
}
int defgroup_name_index(Object *ob, const char *name)
{
- /* Return the location of the named deform group within the list of
- * deform groups. This function is a combination of BLI_findlink and
- * defgroup_find_name. The other two could be called instead, but that
- * require looping over the vertexgroups twice.
- */
- bDeformGroup *curdef;
- int def_nr;
-
- if (name && name[0] != '\0') {
- for (curdef = ob->defbase.first, def_nr = 0; curdef; curdef = curdef->next, def_nr++) {
- if (!strcmp(curdef->name, name))
- return def_nr;
- }
- }
-
- return -1;
+ return (name) ? BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) : -1;
}
/* note, must be freed */
@@ -810,3 +786,43 @@ int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
return -1;
}
+
+/* -------------------------------------------------------------------- */
+/* Defvert Array functions */
+
+void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copycount)
+{
+ /* Assumes dst is already set up */
+ int i;
+
+ if (!src || !dst)
+ return;
+
+ memcpy(dst, src, copycount * sizeof(MDeformVert));
+
+ for (i = 0; i < copycount; i++) {
+ if (src[i].dw) {
+ dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
+ memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
+ }
+ }
+
+}
+
+void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
+{
+ /* Instead of freeing the verts directly,
+ * call this function to delete any special
+ * vert data */
+ int i;
+
+ if (!dvert)
+ return;
+
+ /* Free any special data from the verts */
+ for (i = 0; i < totvert; i++) {
+ if (dvert[i].dw) MEM_freeN(dvert[i].dw);
+ }
+ MEM_freeN(dvert);
+}
+
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 3ed7593..4238956 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -472,7 +472,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -754,7 +754,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* object constraints */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2295,7 +2295,7 @@ static void dag_object_time_update_flags(Object *ob)
if (ob->constraints.first) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2482,30 +2482,51 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
}
-static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay)
+/* struct returned by DagSceneLayer */
+typedef struct DagSceneLayer {
+ struct DagSceneLayer *next, *prev;
+ Scene *scene;
+ unsigned int layer;
+} DagSceneLayer;
+
+/* returns visible scenes with valid DAG */
+static void dag_current_scene_layers(Main *bmain, ListBase *lb)
{
wmWindowManager *wm;
wmWindow *win;
+
+ lb->first = lb->last = NULL;
- /* only one scene supported currently, making more scenes work
- * correctly requires changes beyond just the dependency graph */
-
- *sce = NULL;
- *lay = 0;
-
+ /* if we have a windowmanager, look into windows */
if ((wm = bmain->wm.first)) {
- /* if we have a windowmanager, look into windows */
+
+ flag_listbase_ids(&bmain->scene, LIB_DOIT, 1);
+
for (win = wm->windows.first; win; win = win->next) {
- if (win->screen) {
- if (*sce == NULL) *sce = win->screen->scene;
- *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene);
+ if (win->screen && win->screen->scene->theDag) {
+ Scene *scene = win->screen->scene;
+
+ if (scene->id.flag & LIB_DOIT) {
+ DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
+
+ BLI_addtail(lb, dsl);
+
+ dsl->scene = scene;
+ dsl->layer = BKE_screen_visible_layers(win->screen, scene);
+
+ scene->id.flag &= ~LIB_DOIT;
+ }
}
}
}
else {
/* if not, use the first sce */
- *sce = bmain->scene.first;
- if (*sce) *lay = (*sce)->lay;
+ DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
+
+ BLI_addtail(lb, dsl);
+
+ dsl->scene = bmain->scene.first;
+ dsl->layer = dsl->scene->lay;
/* XXX for background mode, we should get the scene
* from somewhere, for the -S option, but it's in
@@ -2515,29 +2536,36 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay
void DAG_ids_flush_update(Main *bmain, int time)
{
- Scene *sce;
- unsigned int lay;
-
- dag_current_scene_layers(bmain, &sce, &lay);
+ ListBase listbase;
+ DagSceneLayer *dsl;
+
+ /* get list of visible scenes and layers */
+ dag_current_scene_layers(bmain, &listbase);
- if (sce)
- DAG_scene_flush_update(bmain, sce, lay, time);
+ for (dsl = listbase.first; dsl; dsl = dsl->next)
+ DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, time);
+
+ BLI_freelistN(&listbase);
}
void DAG_on_visible_update(Main *bmain, const short do_time)
{
- Scene *scene;
- Base *base;
- Object *ob;
- Group *group;
- GroupObject *go;
- DagNode *node;
- unsigned int lay, oblay;
-
- dag_current_scene_layers(bmain, &scene, &lay);
-
- if (scene && scene->theDag) {
+ ListBase listbase;
+ DagSceneLayer *dsl;
+
+ /* get list of visible scenes and layers */
+ dag_current_scene_layers(bmain, &listbase);
+
+ for (dsl = listbase.first; dsl; dsl = dsl->next) {
+ Scene *scene = dsl->scene;
Scene *sce_iter;
+ Base *base;
+ Object *ob;
+ Group *group;
+ GroupObject *go;
+ DagNode *node;
+ unsigned int lay = dsl->layer, oblay;
+
/* derivedmeshes and displists are not saved to file so need to be
* remade, tag them so they get remade in the scene update loop,
* note armature poses or object matrices are preserved and do not
@@ -2574,6 +2602,8 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
DAG_scene_update_flags(bmain, scene, lay, do_time);
scene->lay_updated |= lay;
}
+
+ BLI_freelistN(&listbase);
/* hack to get objects updating on layer changes */
DAG_id_type_tag(bmain, ID_OB);
@@ -2708,7 +2738,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
for (obt = bmain->object.first; obt; obt = obt->id.next) {
bConstraint *con;
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
CONSTRAINT_TYPE_OBJECTSOLVER))
{
@@ -2758,14 +2788,15 @@ static void dag_id_flush_update(Scene *sce, ID *id)
void DAG_ids_flush_tagged(Main *bmain)
{
+ ListBase listbase;
+ DagSceneLayer *dsl;
ListBase *lbarray[MAX_LIBARRAY];
- Scene *sce;
- unsigned int lay;
int a, do_flush = FALSE;
+
+ /* get list of visible scenes and layers */
+ dag_current_scene_layers(bmain, &listbase);
- dag_current_scene_layers(bmain, &sce, &lay);
-
- if (!sce || !sce->theDag)
+ if (listbase.first == NULL)
return;
/* loop over all ID types */
@@ -2780,7 +2811,10 @@ void DAG_ids_flush_tagged(Main *bmain)
if (id && bmain->id_tag_update[id->name[0]]) {
for (; id; id = id->next) {
if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) {
- dag_id_flush_update(sce, id);
+
+ for (dsl = listbase.first; dsl; dsl = dsl->next)
+ dag_id_flush_update(dsl->scene, id);
+
do_flush = TRUE;
}
}
@@ -2788,8 +2822,12 @@ void DAG_ids_flush_tagged(Main *bmain)
}
/* flush changes to other objects */
- if (do_flush)
- DAG_scene_flush_update(bmain, sce, lay, 0);
+ if (do_flush) {
+ for (dsl = listbase.first; dsl; dsl = dsl->next)
+ DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, 0);
+ }
+
+ BLI_freelistN(&listbase);
}
void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
@@ -2992,7 +3030,7 @@ void DAG_pose_sort(Object *ob)
addtoroot = 0;
}
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 083cb02..643c7b1 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -225,29 +225,48 @@ void BKE_displist_normals_add(ListBase *lb)
}
}
-void BKE_displist_count(ListBase *lb, int *totvert, int *totface)
+void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri)
{
DispList *dl;
- dl = lb->first;
- while (dl) {
+ for (dl = lb->first; dl; dl = dl->next) {
+ int vert_tot = 0;
+ int face_tot = 0;
+ int tri_tot = 0;
+
switch (dl->type) {
case DL_SURF:
- *totvert += dl->nr * dl->parts;
- *totface += (dl->nr - 1) * (dl->parts - 1);
+ {
+ vert_tot = dl->nr * dl->parts;
+ face_tot = (dl->nr - 1) * (dl->parts - 1);
+ tri_tot = face_tot * 2;
break;
+ }
case DL_INDEX3:
+ {
+ vert_tot = dl->nr;
+ face_tot = dl->parts;
+ tri_tot = face_tot;
+ break;
+ }
case DL_INDEX4:
- *totvert += dl->nr;
- *totface += dl->parts;
+ {
+ vert_tot = dl->nr;
+ face_tot = dl->parts;
+ tri_tot = face_tot * 2;
break;
+ }
case DL_POLY:
case DL_SEGM:
- *totvert += dl->nr * dl->parts;
+ {
+ vert_tot = dl->nr * dl->parts;
break;
+ }
}
- dl = dl->next;
+ *totvert += vert_tot;
+ *totface += face_tot;
+ *tottri += tri_tot;
}
}
@@ -487,7 +506,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal)
}
/* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */
- if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) {
+ if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES))) {
if (tot) {
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
@@ -780,7 +799,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
required_mode |= eModifierMode_Editmode;
if (cu->editnurb == NULL) {
- keyVerts = do_ob_key(scene, ob);
+ keyVerts = BKE_key_evaluate_object(scene, ob, &numVerts);
if (keyVerts) {
/* split coords from key data, the latter also includes
@@ -789,7 +808,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
* shape key modifier yet. */
deformedVerts = BKE_curve_keyVertexCos_get(cu, nurb, keyVerts);
originalVerts = MEM_dupallocN(deformedVerts);
- numVerts = BKE_nurbList_verts_count(nurb);
+ BLI_assert(BKE_nurbList_verts_count(nurb) == numVerts);
}
}
@@ -956,7 +975,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
curve_to_filledpoly(cu, nurb, dispbase);
}
- dm = CDDM_from_curve_displist(ob, dispbase, NULL);
+ dm = CDDM_from_curve_displist(ob, dispbase);
CDDM_calc_normals_mapping(dm);
}
@@ -1046,7 +1065,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
/* OrcoDM should be created from underformed disp lists */
BKE_displist_make_curveTypes_forOrco(scene, ob, &disp);
- dm = CDDM_from_curve_displist(ob, &disp, NULL);
+ dm = CDDM_from_curve_displist(ob, &disp);
BKE_displist_free(&disp);
@@ -1466,8 +1485,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
float *cur_data = data;
if (cu->taperobj == NULL) {
- if ( (cu->bevobj != NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
- fac = bevp->radius;
+ fac = bevp->radius;
}
else {
float len, taper_fac;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 77930f6..fff51ab 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -397,7 +397,7 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface)
}
else {
strcpy(surface->output_name, "dp_");
- strcpy(surface->output_name2, surface->output_name);
+ BLI_strncpy(surface->output_name2, surface->output_name, sizeof(surface->output_name2));
surface->flags &= ~MOD_DPAINT_ANTIALIAS;
surface->depth_clamp = 0.0f;
}
@@ -529,7 +529,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
@@ -687,7 +687,7 @@ static void boundInsert(Bounds3D *b, float point[3])
static float getSurfaceDimension(PaintSurfaceData *sData)
{
Bounds3D *mb = &sData->bData->mesh_bounds;
- return MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
+ return max_fff((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
}
static void freeGrid(PaintSurfaceData *data)
@@ -754,14 +754,14 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
/* get dimensions */
sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min);
copy_v3_v3(td, dim);
- min_dim = MAX3(td[0], td[1], td[2]) / 1000.f;
+ min_dim = max_fff(td[0], td[1], td[2]) / 1000.f;
/* deactivate zero axises */
for (i = 0; i < 3; i++) {
if (td[i] < min_dim) { td[i] = 1.0f; axis -= 1; }
}
- if (axis == 0 || MAX3(td[0], td[1], td[2]) < 0.0001f) {
+ if (axis == 0 || max_fff(td[0], td[1], td[2]) < 0.0001f) {
MEM_freeN(grid_bounds);
MEM_freeN(bData->grid);
bData->grid = NULL;
@@ -2689,7 +2689,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG;
#endif
BLI_strncpy(output_file, filename, sizeof(output_file));
- BKE_add_image_extension(output_file, format);
+ BKE_add_image_extension_from_type(output_file, format);
/* Validate output file path */
BLI_path_abs(output_file, G.main->name);
@@ -2839,7 +2839,9 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats)
/*
* Get material diffuse color and alpha (including linked textures) in given coordinates
*/
-static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
+static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb,
+ const float volume_co[3], const float surface_co[3],
+ int faceIndex, short isQuad, DerivedMesh *orcoDm)
{
Material *mat = bMats->mat;
MFace *mface = orcoDm->getTessFaceArray(orcoDm);
@@ -4260,7 +4262,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
if (surface->effect & MOD_DPAINT_EFFECT_DO_SHRINK)
shrink_speed = surface->shrink_speed;
- fastest_effect = MAX3(spread_speed, shrink_speed, average_force);
+ fastest_effect = max_fff(spread_speed, shrink_speed, average_force);
avg_dist = bData->average_dist * CANVAS_REL_SIZE / getSurfaceDimension(sData);
steps = (int)ceil(1.5f * EFF_MOVEMENT_PER_FRAME * fastest_effect / avg_dist * timescale);
@@ -4444,8 +4446,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
float dt, min_dist, damp_factor;
float wave_speed = surface->wave_speed;
double average_dist = 0.0f;
- Bounds3D *mb = &sData->bData->mesh_bounds;
- float canvas_size = MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
+ const float canvas_size = getSurfaceDimension(sData);
float wave_scale = CANVAS_REL_SIZE / canvas_size;
/* allocate memory */
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 321a61c..9157732 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -39,8 +39,8 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
@@ -71,24 +71,24 @@ extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate)
{
- BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), __func__);
+ BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__);
- tm->bm = bm;
+ em->bm = bm;
if (do_tessellate) {
- BMEdit_RecalcTessellation(tm);
+ BMEdit_RecalcTessellation(em);
}
- return tm;
+ return em;
}
-BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
+BMEditMesh *BMEdit_Copy(BMEditMesh *em)
{
- BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), __func__);
- *tm2 = *tm;
+ BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__);
+ *em_copy = *em;
- tm2->derivedCage = tm2->derivedFinal = NULL;
+ em_copy->derivedCage = em_copy->derivedFinal = NULL;
- tm2->bm = BM_mesh_copy(tm->bm);
+ em_copy->bm = BM_mesh_copy(em->bm);
/* The tessellation is NOT calculated on the copy here,
* because currently all the callers of this function use
@@ -97,55 +97,59 @@ BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
* reasons, in that case it makes more sense to do the
* tessellation only when/if that copy ends up getting
* used.*/
- tm2->looptris = NULL;
+ em_copy->looptris = NULL;
- tm2->vert_index = NULL;
- tm2->edge_index = NULL;
- tm2->face_index = NULL;
+ em_copy->vert_index = NULL;
+ em_copy->edge_index = NULL;
+ em_copy->face_index = NULL;
- return tm2;
+ return em_copy;
}
-static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
+static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
{
/* use this to avoid locking pthread for _every_ polygon
* and calling the fill function */
#define USE_TESSFACE_SPEEDUP
- BMesh *bm = tm->bm;
- BMLoop *(*looptris)[3] = NULL;
- BLI_array_declare(looptris);
- BMIter iter, liter;
+ BMesh *bm = em->bm;
+
+ /* this assumes all faces can be scan-filled, which isn't always true,
+ * worst case we over alloc a little which is acceptable */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ const int looptris_tot_prev_alloc = em->looptris ? (MEM_allocN_len(em->looptris) / sizeof(*em->looptris)) : 0;
+
+ BMLoop *(*looptris)[3];
+ BMIter iter;
BMFace *efa;
BMLoop *l;
- int i = 0, j;
+ int i = 0;
ScanFillContext sf_ctx;
#if 0
/* note, we could be clever and re-use this array but would need to ensure
* its realloced at some point, for now just free it */
- if (tm->looptris) MEM_freeN(tm->looptris);
+ if (em->looptris) MEM_freeN(em->looptris);
- /* Use tm->tottri when set, this means no reallocs while transforming,
+ /* Use em->tottri when set, this means no reallocs while transforming,
* (unless scanfill fails), otherwise... */
/* allocate the length of totfaces, avoid many small reallocs,
* if all faces are tri's it will be correct, quads == 2x allocs */
- BLI_array_reserve(looptris, (tm->tottri && tm->tottri < bm->totface * 3) ? tm->tottri : bm->totface);
+ BLI_array_reserve(looptris, (em->tottri && em->tottri < bm->totface * 3) ? em->tottri : bm->totface);
#else
/* this means no reallocs for quad dominant models, for */
- if ( (tm->looptris != NULL) &&
- (tm->tottri != 0) &&
- /* (totrti <= bm->totface * 2) would be fine for all quads,
- * but in case there are some ngons, still re-use the array */
- (tm->tottri <= bm->totface * 3))
+ if ((em->looptris != NULL) &&
+ /* (em->tottri >= looptris_tot)) */
+ /* check against alloc'd size incase we over alloc'd a little */
+ ((looptris_tot_prev_alloc >= looptris_tot) && (looptris_tot_prev_alloc <= looptris_tot * 2)))
{
- looptris = tm->looptris;
+ looptris = em->looptris;
}
else {
- if (tm->looptris) MEM_freeN(tm->looptris);
- BLI_array_reserve(looptris, bm->totface);
+ if (em->looptris) MEM_freeN(em->looptris);
+ looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__);
}
#endif
@@ -161,16 +165,25 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
/* no need to ensure the loop order, we know its ok */
else if (efa->len == 3) {
- BLI_array_grow_one(looptris);
+#if 0
+ int j;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
looptris[i][j] = l;
}
i += 1;
+#else
+ /* more cryptic but faster */
+ BMLoop **l_ptr = looptris[i++];
+ l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
+ l_ptr[1] = l = l->next;
+ l_ptr[2] = l->next;
+#endif
}
else if (efa->len == 4) {
+#if 0
BMLoop *ltmp[4];
+ int j;
BLI_array_grow_items(looptris, 2);
-
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
ltmp[j] = l;
}
@@ -184,11 +197,24 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
looptris[i][1] = ltmp[2];
looptris[i][2] = ltmp[3];
i += 1;
+#else
+ /* more cryptic but faster */
+ BMLoop **l_ptr_a = looptris[i++];
+ BMLoop **l_ptr_b = looptris[i++];
+ (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
+ (l_ptr_a[1] = l = l->next);
+ (l_ptr_a[2] = l_ptr_b[1] = l = l->next);
+ ( l_ptr_b[2] = l->next);
+#endif
}
#endif /* USE_TESSFACE_SPEEDUP */
else {
+ int j;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL;
/* ScanFillEdge *e; */ /* UNUSED */
ScanFillFace *sf_tri;
@@ -197,28 +223,34 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
BLI_scanfill_begin(&sf_ctx);
/* scanfill time */
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
- /*mark order */
- BM_elem_index_set(l, j); /* set_loop */
-
- sf_vert = BLI_scanfill_vert_add(&sf_ctx, l->v->co);
- sf_vert->tmp.p = l;
+ j = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
+ sf_vert->tmp.p = l_iter;
if (sf_vert_last) {
/* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
}
sf_vert_last = sf_vert;
- if (sf_vert_first == NULL) sf_vert_first = sf_vert;
- }
+ if (sf_vert_first == NULL) {
+ sf_vert_first = sf_vert;
+ }
+
+ /*mark order */
+ BM_elem_index_set(l_iter, j++); /* set_loop */
+
+ } while ((l_iter = l_iter->next) != l_first);
/* complete the loop */
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
- BLI_array_grow_items(looptris, totfilltri);
+ BLI_assert(totfilltri <= efa->len - 2);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ BMLoop **l_ptr = looptris[i++];
BMLoop *l1 = sf_tri->v1->tmp.p;
BMLoop *l2 = sf_tri->v2->tmp.p;
BMLoop *l3 = sf_tri->v3->tmp.p;
@@ -227,18 +259,19 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop *, l2, l3); }
if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); }
- looptris[i][0] = l1;
- looptris[i][1] = l2;
- looptris[i][2] = l3;
- i += 1;
+ l_ptr[0] = l1;
+ l_ptr[1] = l2;
+ l_ptr[2] = l3;
}
BLI_scanfill_end(&sf_ctx);
}
}
- tm->tottri = i;
- tm->looptris = looptris;
+ em->tottri = i;
+ em->looptris = looptris;
+
+ BLI_assert(em->tottri <= looptris_tot);
#undef USE_TESSFACE_SPEEDUP
@@ -749,22 +782,18 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
if (poly_prev != GL_ZERO) glEnd();
}
-static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3],
- int has_uv, int has_col)
+static void bmdm_get_tri_uv(BMLoop *ls[3], MLoopUV *luv[3], const int cd_loop_uv_offset)
{
- if (has_uv) {
- luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV);
- luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV);
- luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV);
- }
-
- if (has_col) {
- lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL);
- lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL);
- lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL);
- }
-
+ luv[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_uv_offset);
+ luv[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_uv_offset);
+ luv[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_uv_offset);
+}
+static void bmdm_get_tri_col(BMLoop *ls[3], MLoopCol *lcol[3], const int cd_loop_color_offset)
+{
+ lcol[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_color_offset);
+ lcol[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_color_offset);
+ lcol[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_color_offset);
}
static void emDM_drawFacesTex_common(DerivedMesh *dm,
@@ -780,15 +809,19 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
float (*vertexNos)[3] = bmdm->vertexNos;
BMFace *efa;
MLoopUV *luv[3], dummyluv = {{0}};
- MLoopCol *lcol[3] = {NULL}, dummylcol = {0};
- int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
- int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
+ MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
+ const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+ bool has_uv = (cd_loop_uv_offset != -1);
+ bool has_vcol = (cd_loop_color_offset != -1);
+ int i;
(void) compareDrawOptions;
luv[0] = luv[1] = luv[2] = &dummyluv;
- dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255;
+ // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; /* UNUSED */
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
@@ -800,7 +833,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
for (i = 0; i < em->tottri; i++) {
BMLoop **ls = em->looptris[i];
- MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
+ MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
@@ -808,7 +841,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
efa = ls[0]->f;
- if (has_uv) {
+ if (cd_poly_tex_offset != -1) {
ME_MTEXFACE_CPY(&mtf, tp);
}
@@ -825,25 +858,27 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (!drawSmooth) {
glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]);
glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]);
glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]);
}
else {
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
glTexCoord2fv(luv[0]->uv);
if (lcol[0])
@@ -872,7 +907,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
for (i = 0; i < em->tottri; i++) {
BMLoop **ls = em->looptris[i];
- MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL;
+ MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH);
@@ -880,12 +915,12 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
efa = ls[0]->f;
- if (has_uv) {
+ if (cd_poly_tex_offset != -1) {
ME_MTEXFACE_CPY(&mtf, tp);
}
if (drawParams)
- draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
+ draw_option = drawParams(&mtf, (has_vcol), efa->mat_nr);
else if (drawParamsMapped)
draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
else
@@ -897,46 +932,42 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (!drawSmooth) {
glNormal3fv(efa->no);
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
- if (luv[0])
- glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ glTexCoord2fv(luv[0]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glVertex3fv(ls[0]->v->co);
- if (luv[1])
- glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ glTexCoord2fv(luv[1]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glVertex3fv(ls[1]->v->co);
- if (luv[2])
- glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ glTexCoord2fv(luv[2]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glVertex3fv(ls[2]->v->co);
}
else {
- bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol);
+ if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset);
+ if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset);
- if (luv[0])
- glTexCoord2fv(luv[0]->uv);
- if (lcol[0])
+ glTexCoord2fv(luv[0]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[0]->r));
glNormal3fv(ls[0]->v->no);
glVertex3fv(ls[0]->v->co);
- if (luv[1])
- glTexCoord2fv(luv[1]->uv);
- if (lcol[1])
+ glTexCoord2fv(luv[1]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[1]->r));
glNormal3fv(ls[1]->v->no);
glVertex3fv(ls[1]->v->co);
- if (luv[2])
- glTexCoord2fv(luv[2]->uv);
- if (lcol[2])
+ glTexCoord2fv(luv[2]->uv);
+ if (has_vcol)
glColor3ubv((const GLubyte *)&(lcol[2]->r));
glNormal3fv(ls[2]->v->no);
glVertex3fv(ls[2]->v->co);
@@ -1276,14 +1307,16 @@ static int emDM_getNumPolys(DerivedMesh *dm)
static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
{
+ float *f;
+
copy_v3_v3(vert_r->co, ev->co);
normal_float_to_short_v3(vert_r->no, ev->no);
vert_r->flag = BM_vert_flag_to_mflag(ev);
- if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT) * 255.0f);
+ if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
+ vert_r->bweight = (unsigned char)((*f) * 255.0f);
}
return 1;
@@ -1299,8 +1332,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
return;
}
- // ev = EDBM_vert_at_index(bmdm->tc, index);
- ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
+ ev = bmdm->tc->vert_index[index]; /* should be EDBM_vert_at_index() */
+ // ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
bmvert_to_mvert(bmdm->tc->bm, ev, vert_r);
if (bmdm->vertexCos)
@@ -1312,27 +1345,27 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->tc->bm;
BMEdge *e;
+ float *f;
if (index < 0 || index >= bmdm->te) {
printf("error in emDM_getEdge.\n");
return;
}
- // e = EDBM_edge_at_index(bmdm->tc, index);
- e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
-
- if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) * 255.0f);
- }
-
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE) * 255.0f);
- }
+ e = bmdm->tc->edge_index[index]; /* should be EDBM_edge_at_index() */
+ // e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */
edge_r->flag = BM_edge_flag_to_mflag(e);
edge_r->v1 = BM_elem_index_get(e->v1);
edge_r->v2 = BM_elem_index_get(e->v2);
+
+ if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
+ edge_r->bweight = (unsigned char)((*f) * 255.0f);
+ }
+ if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
+ edge_r->crease = (unsigned char)((*f) * 255.0f);
+ }
}
static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
@@ -1367,7 +1400,7 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
BMesh *bm = bmdm->tc->bm;
BMVert *eve;
BMIter iter;
- const int has_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
if (bmdm->vertexCos) {
int i;
@@ -1377,9 +1410,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
normal_float_to_short_v3(vert_r->no, eve->no);
vert_r->flag = BM_vert_flag_to_mflag(eve);
- if (has_bweight) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
- }
+ if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
+
vert_r++;
}
}
@@ -1389,9 +1421,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
normal_float_to_short_v3(vert_r->no, eve->no);
vert_r->flag = BM_vert_flag_to_mflag(eve);
- if (has_bweight) {
- vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
- }
+ if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
+
vert_r++;
}
}
@@ -1402,24 +1433,20 @@ static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
BMEdge *eed;
BMIter iter;
- const int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
- const int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
+
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (has_bweight) {
- edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
- }
-
- if (has_crease) {
- edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
- }
+ edge_r->v1 = BM_elem_index_get(eed->v1);
+ edge_r->v2 = BM_elem_index_get(eed->v2);
edge_r->flag = BM_edge_flag_to_mflag(eed);
- edge_r->v1 = BM_elem_index_get(eed->v1);
- edge_r->v2 = BM_elem_index_get(eed->v2);
+ if (cd_edge_crease_offset != -1) edge_r->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) edge_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
edge_r++;
}
@@ -1627,6 +1654,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert,
em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface);
+ /* could also get from the objects mesh directly */
+ bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
bmdm->dm.getVertCos = emDM_getVertCos;
bmdm->dm.getMinMax = emDM_getMinMax;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index ec61311..23f3a3a 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -500,8 +500,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
BLI_assert(bezt_last != NULL);
if (include_handles) {
- xminv = MIN3(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
- xmaxv = MAX3(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
+ xminv = min_fff(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
+ xmaxv = max_fff(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
}
else {
xminv = min_ff(xminv, bezt_first->vec[1][0]);
@@ -517,8 +517,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
if ((do_sel_only == FALSE) || BEZSELECTED(bezt)) {
if (include_handles) {
- yminv = MIN4(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
- ymaxv = MAX4(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
+ yminv = min_ffff(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
+ ymaxv = max_ffff(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
}
else {
yminv = min_ff(yminv, bezt->vec[1][1]);
@@ -859,7 +859,7 @@ void testhandles_fcurve(FCurve *fcu, const short use_handle)
short flag = 0;
/* flag is initialized as selection status
- * of beztriple control-points (labelled 0,1,2)
+ * of beztriple control-points (labelled 0, 1, 2)
*/
if (bezt->f2 & SELECT) flag |= (1 << 1); // == 2
if (use_handle == FALSE) {
@@ -1192,7 +1192,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1217,7 +1217,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1288,7 +1288,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
}
else {
/* specially calculate local matrix, since chan_mat is not valid
@@ -1315,7 +1315,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
}
else {
/* transforms to matrix */
@@ -2022,12 +2022,12 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
}
else {
/* bezier interpolation */
- /* v1,v2 are the first keyframe and its 2nd handle */
+ /* (v1, v2) are the first keyframe and its 2nd handle */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
v2[0] = prevbezt->vec[2][0];
v2[1] = prevbezt->vec[2][1];
- /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
+ /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
v3[0] = bezt->vec[0][0];
v3[1] = bezt->vec[0][1];
v4[0] = bezt->vec[1][0];
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 2b393b4..7b007af 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -141,55 +141,34 @@ static void fcm_generator_verify(FModifier *fcm)
switch (data->mode) {
case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
{
+ const int arraysize_new = data->poly_order + 1;
/* arraysize needs to be order+1, so resize if not */
- if (data->arraysize != (data->poly_order + 1)) {
- float *nc;
-
- /* make new coefficients array, and copy over as much data as can fit */
- nc = MEM_callocN(sizeof(float) * (data->poly_order + 1), "FMod_Generator_Coefs");
-
+ if (data->arraysize != arraysize_new) {
if (data->coefficients) {
- if ((int)data->arraysize > (data->poly_order + 1))
- memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order + 1));
- else
- memcpy(nc, data->coefficients, sizeof(float) * data->arraysize);
-
- /* free the old data */
- MEM_freeN(data->coefficients);
+ data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
}
-
- /* set the new data */
- data->coefficients = nc;
- data->arraysize = data->poly_order + 1;
+ else {
+ data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
+ }
+ data->arraysize = arraysize_new;
}
+ break;
}
- break;
-
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */
{
- /* arraysize needs to be 2*order, so resize if not */
- if (data->arraysize != (data->poly_order * 2)) {
- float *nc;
-
- /* make new coefficients array, and copy over as much data as can fit */
- nc = MEM_callocN(sizeof(float) * (data->poly_order * 2), "FMod_Generator_Coefs");
-
+ const int arraysize_new = data->poly_order * 2;
+ /* arraysize needs to be (2 * order), so resize if not */
+ if (data->arraysize != arraysize_new) {
if (data->coefficients) {
- if (data->arraysize > (unsigned int)(data->poly_order * 2))
- memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order * 2));
- else
- memcpy(nc, data->coefficients, sizeof(float) * data->arraysize);
-
- /* free the old data */
- MEM_freeN(data->coefficients);
+ data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
}
-
- /* set the new data */
- data->coefficients = nc;
- data->arraysize = data->poly_order * 2;
+ else {
+ data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
+ }
+ data->arraysize = arraysize_new;
}
+ break;
}
- break;
}
}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index d463474..3e1e551 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -962,9 +962,9 @@ makebreak:
float si, co;
ct = chartransdata + cu->pos;
- si = (float)sin(ct->rot);
- co = (float)cos(ct->rot);
-
+ si = sinf(ct->rot);
+ co = cosf(ct->rot);
+
f = cu->editfont->textcurs[0];
f[0] = cu->fsize * (-0.1f * co + ct->xof);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index a7d0152..755030b 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -183,12 +183,12 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive)
gpl->thickness = 3;
/* auto-name */
- strcpy(gpl->info, name);
+ BLI_strncpy(gpl->info, name, sizeof(gpl->info));
BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
/* make this one the active one */
if (setactive)
- gpencil_layer_setactive(gpd, gpl);
+ gpencil_layer_setactive(gpd, gpl);
/* return layer */
return gpl;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 5dd0f08..3be4766 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -815,6 +815,13 @@ void IDP_FreeProperty(IDProperty *prop)
}
}
+void IDP_ClearProperty(IDProperty *prop)
+{
+ IDP_FreeProperty(prop);
+ prop->data.pointer = NULL;
+ prop->len = prop->totallen = 0;
+}
+
/* Unlinks any IDProperty<->ID linkage that might be going on.
* note: currently unused.*/
void IDP_UnlinkProperty(IDProperty *prop)
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index c4ce17c..2141738 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -68,7 +68,6 @@
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BKE_bmfont.h"
#include "BKE_colortools.h"
@@ -313,10 +312,6 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
break;
ibuf->index = index;
- if (ima->flag & IMA_CM_PREDIVIDE)
- ibuf->flags |= IB_cm_predivide;
- else
- ibuf->flags &= ~IB_cm_predivide;
/* this function accepts (link == NULL) */
BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
@@ -553,6 +548,26 @@ int BKE_image_scale(Image *image, int width, int height)
return (ibuf != NULL);
}
+static void image_init_color_management(Image *ima)
+{
+ ImBuf *ibuf;
+ char name[FILE_MAX];
+
+ BKE_image_user_file_path(NULL, ima, name);
+
+ /* will set input color space to image format default's */
+ ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, ima->colorspace_settings.name);
+
+ if (ibuf) {
+ if (ibuf->flags & IB_alphamode_premul)
+ ima->alpha_mode = IMA_ALPHA_PREMUL;
+ else
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
+
+ IMB_freeImBuf(ibuf);
+ }
+}
+
Image *BKE_image_load(const char *filepath)
{
Image *ima;
@@ -580,6 +595,8 @@ Image *BKE_image_load(const char *filepath)
if (BLI_testextensie_array(filepath, imb_ext_movie))
ima->source = IMA_SRC_MOVIE;
+ image_init_color_management(ima);
+
return ima;
}
@@ -667,7 +684,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
/* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
- ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
return ibuf;
@@ -887,7 +904,7 @@ void BKE_image_free_all_textures(void)
image_free_buffers(ima);
}
}
- /* printf("freed total %d MB\n", totsize/(1024*1024)); */
+ /* printf("freed total %d MB\n", totsize / (1024 * 1024)); */
}
/* except_frame is weak, only works for seqs without offset... */
@@ -938,7 +955,7 @@ int BKE_imtype_to_ftype(const char imtype)
return RADHDR;
#endif
else if (imtype == R_IMF_IMTYPE_PNG)
- return PNG;
+ return PNG | 90;
#ifdef WITH_DDS
else if (imtype == R_IMF_IMTYPE_DDS)
return DDS;
@@ -1120,6 +1137,8 @@ char BKE_imtype_valid_depths(const char imtype)
return R_IMF_CHAN_DEPTH_10;
case R_IMF_IMTYPE_JP2:
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16;
+ case R_IMF_IMTYPE_PNG:
+ return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_16;
/* most formats are 8bit only */
default:
return R_IMF_CHAN_DEPTH_8;
@@ -1166,9 +1185,10 @@ char BKE_imtype_from_arg(const char *imtype_arg)
else return R_IMF_IMTYPE_INVALID;
}
-int BKE_add_image_extension(char *string, const char imtype)
+static int do_add_image_extension(char *string, const char imtype, const ImageFormatData *im_format)
{
const char *extension = NULL;
+ (void)im_format; /* may be unused, depends on build options */
if (imtype == R_IMF_IMTYPE_IRIS) {
if (!BLI_testextensie(string, ".rgb"))
@@ -1233,8 +1253,22 @@ int BKE_add_image_extension(char *string, const char imtype)
}
#ifdef WITH_OPENJPEG
else if (imtype == R_IMF_IMTYPE_JP2) {
- if (!BLI_testextensie(string, ".jp2"))
- extension = ".jp2";
+ if (im_format) {
+ if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
+ if (!BLI_testextensie(string, ".jp2"))
+ extension = ".jp2";
+ }
+ else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
+ if (!BLI_testextensie(string, ".j2c"))
+ extension = ".j2c";
+ }
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
+ }
+ else {
+ if (!BLI_testextensie(string, ".jp2"))
+ extension = ".jp2";
+ }
}
#endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90, R_IMF_IMTYPE_QUICKTIME etc
@@ -1260,11 +1294,22 @@ int BKE_add_image_extension(char *string, const char imtype)
}
}
+int BKE_add_image_extension(char *string, const ImageFormatData *im_format)
+{
+ return do_add_image_extension(string, im_format->imtype, im_format);
+}
+
+int BKE_add_image_extension_from_type(char *string, const char imtype)
+{
+ return do_add_image_extension(string, imtype, NULL);
+}
+
void BKE_imformat_defaults(ImageFormatData *im_format)
{
memset(im_format, 0, sizeof(*im_format));
im_format->planes = R_IMF_PLANES_RGB;
im_format->imtype = R_IMF_IMTYPE_PNG;
+ im_format->depth = R_IMF_CHAN_DEPTH_8;
im_format->quality = 90;
im_format->compress = 90;
@@ -1289,9 +1334,13 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
im_format->imtype = R_IMF_IMTYPE_RADHDR;
#endif
- else if (ftype == PNG)
+ else if (ftype == PNG) {
im_format->imtype = R_IMF_IMTYPE_PNG;
+ if (custom_flags & PNG_16BIT)
+ im_format->depth = R_IMF_CHAN_DEPTH_16;
+ }
+
#ifdef WITH_DDS
else if (ftype == DDS)
im_format->imtype = R_IMF_IMTYPE_DDS;
@@ -1352,6 +1401,13 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
if (ftype & JP2_CINE_48FPS)
im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48;
}
+
+ if (ftype & JP2_JP2)
+ im_format->jp2_codec = R_IMF_JP2_CODEC_JP2;
+ else if (ftype & JP2_J2K)
+ im_format->jp2_codec = R_IMF_JP2_CODEC_J2K;
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in file type");
}
#endif
@@ -1816,8 +1872,12 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
else if (ELEM5(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG, R_IMF_IMTYPE_H264, R_IMF_IMTYPE_THEORA, R_IMF_IMTYPE_XVID)) {
ibuf->ftype = PNG;
- if (imtype == R_IMF_IMTYPE_PNG)
+ if (imtype == R_IMF_IMTYPE_PNG) {
+ if (imf->depth == R_IMF_CHAN_DEPTH_16)
+ ibuf->ftype |= PNG_16BIT;
+
ibuf->ftype |= compress;
+ }
}
#ifdef WITH_DDS
@@ -1907,6 +1967,13 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_48)
ibuf->ftype |= JP2_CINE_48FPS;
}
+
+ if (imf->jp2_codec == R_IMF_JP2_CODEC_JP2)
+ ibuf->ftype |= JP2_JP2;
+ else if (imf->jp2_codec == R_IMF_JP2_CODEC_J2K)
+ ibuf->ftype |= JP2_J2K;
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
}
#endif
else {
@@ -1957,7 +2024,8 @@ int BKE_imbuf_write_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, cons
}
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+static void do_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype,
+ const ImageFormatData *im_format, const short use_ext, const short use_frames)
{
if (string == NULL) return;
BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */
@@ -1967,8 +2035,17 @@ void BKE_makepicstring(char *string, const char *base, const char *relbase, int
BLI_path_frame(string, frame, 4);
if (use_ext)
- BKE_add_image_extension(string, imtype);
+ do_add_image_extension(string, imtype, im_format);
+}
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const ImageFormatData *im_format, const short use_ext, const short use_frames)
+{
+ do_makepicstring(string, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames);
+}
+
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+{
+ do_makepicstring(string, base, relbase, frame, imtype, NULL, use_ext, use_frames);
}
/* used by sequencer too */
@@ -2285,7 +2362,7 @@ void BKE_image_backup_render(Scene *scene, Image *ima)
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
{
const char *colorspace = ima->colorspace_settings.name;
- int predivide = ima->flag & IMA_CM_PREDIVIDE;
+ int predivide = ima->alpha_mode == IMA_ALPHA_PREMUL;
ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
@@ -2317,6 +2394,18 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
}
+static int imbuf_alpha_flags_for_image(Image *ima)
+{
+ int flag = 0;
+
+ if (ima->flag & IMA_IGNORE_ALPHA)
+ flag |= IB_ignore_alpha;
+ else if (ima->alpha_mode == IMA_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ return flag;
+}
+
static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
{
struct ImBuf *ibuf;
@@ -2331,8 +2420,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
BKE_image_user_file_path(iuser, ima, name);
flag = IB_rect | IB_multilayer;
- if (ima->flag & IMA_DO_PREMUL)
- flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
/* read ibuf */
ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
@@ -2491,15 +2579,14 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
/* is there a PackedFile with this image ? */
if (ima->packedfile) {
flag = IB_rect | IB_multilayer;
- if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag,
ima->colorspace_settings.name, "<packed data>");
}
else {
flag = IB_rect | IB_multilayer | IB_metadata;
- if (ima->flag & IMA_DO_PREMUL)
- flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
/* get the right string */
BKE_image_user_frame_calc(iuser, cfra, 0);
@@ -2719,15 +2806,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
ibuf->dither = dither;
- if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
- ibuf->flags |= IB_cm_predivide;
- ima->flag |= IMA_CM_PREDIVIDE;
- }
- else {
- ibuf->flags &= ~IB_cm_predivide;
- ima->flag &= ~IMA_CM_PREDIVIDE;
- }
-
ima->ok = IMA_OK_LOADED;
return ibuf;
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index ad95f09..ccc57a2 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1300,13 +1300,13 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
}
/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
-float *do_ob_key(Scene *scene, Object *ob)
+float *BKE_key_evaluate_object(Scene *scene, Object *ob, int *r_totelem)
{
Key *key = BKE_key_from_object(ob);
KeyBlock *actkb = BKE_keyblock_from_object(ob);
char *out;
int tot = 0, size = 0;
-
+
if (key == NULL || key->block.first == NULL)
return NULL;
@@ -1344,7 +1344,7 @@ float *do_ob_key(Scene *scene, Object *ob)
return NULL;
/* allocate array */
- out = MEM_callocN(size, "do_ob_key out");
+ out = MEM_callocN(size, "BKE_key_evaluate_object out");
/* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
key->from = (ID *)ob->data;
@@ -1383,6 +1383,9 @@ float *do_ob_key(Scene *scene, Object *ob)
else if (ob->type == OB_SURF) do_curve_key(scene, ob, key, out, tot);
}
+ if (r_totelem) {
+ *r_totelem = tot;
+ }
return (float *)out;
}
@@ -1732,7 +1735,7 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
}
/************************* vert coords ************************/
-float (*BKE_key_convert_to_vertcos(Object * ob, KeyBlock * kb))[3]
+float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
{
float (*vertCos)[3], *co;
float *fp = kb->data;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index a15ca7c..fa01e9f 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -89,7 +88,7 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
/* vertex weight groups are just freed all for now */
if (lt->dvert) {
- free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
lt->dvert = NULL;
}
@@ -210,7 +209,7 @@ Lattice *BKE_lattice_copy(Lattice *lt)
if (lt->dvert) {
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
ltn->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(ltn->dvert, lt->dvert, tot);
+ BKE_defvert_array_copy(ltn->dvert, lt->dvert, tot);
}
ltn->editlatt = NULL;
@@ -221,12 +220,12 @@ Lattice *BKE_lattice_copy(Lattice *lt)
void BKE_lattice_free(Lattice *lt)
{
if (lt->def) MEM_freeN(lt->def);
- if (lt->dvert) free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ if (lt->dvert) BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
if (lt->editlatt) {
Lattice *editlt = lt->editlatt->latt;
if (editlt->def) MEM_freeN(editlt->def);
- if (editlt->dvert) free_dverts(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ if (editlt->dvert) BKE_defvert_array_free(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
MEM_freeN(editlt);
MEM_freeN(lt->editlatt);
@@ -753,7 +752,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
/* orco is original not-animated or deformed reference point */
/* result written in vec and mat */
void curve_deform_vector(Scene *scene, Object *cuOb, Object *target,
- float orco[3], float vec[3], float mat[][3], int no_rot_axis)
+ float orco[3], float vec[3], float mat[3][3], int no_rot_axis)
{
CurveDeform cd;
float quat[4];
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 465d5ee..1e6f429 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -71,7 +71,7 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
+#include "BKE_bpath.h"
#include "BKE_animsys.h"
#include "BKE_camera.h"
@@ -136,9 +136,9 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
{
char *bpath_user_data[2] = {bmain->name, lib->filepath};
- BLI_bpath_traverse_id(bmain, id,
- BLI_bpath_relocate_visitor,
- BLI_BPATH_TRAVERSE_SKIP_MULTIFILE,
+ BKE_bpath_traverse_id(bmain, id,
+ BKE_bpath_relocate_visitor,
+ BKE_BPATH_TRAVERSE_SKIP_MULTIFILE,
bpath_user_data);
}
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 2fa928e..73452b2 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
}
/* main scan-fill */
- sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec);
+ sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_HOLES, zvec);
face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
face_index = 0;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index ea31795..bf64bd3 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -52,7 +52,6 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BLI_string.h"
#include "BKE_animsys.h"
@@ -629,11 +628,14 @@ Material *give_current_material(Object *ob, short act)
if (totcolp == NULL || ob->totcol == 0) return NULL;
if (act < 0) {
- printf("no!\n");
+ printf("Negative material index!\n");
}
- if (act > ob->totcol) act = ob->totcol;
- else if (act <= 0) act = 1;
+ /* return NULL for invalid 'act', can happen for mesh face indices */
+ if (act > ob->totcol)
+ return NULL;
+ else if (act <= 0)
+ return NULL;
if (ob->matbits && ob->matbits[act - 1]) { /* in object */
ma = ob->mat[act - 1];
@@ -1235,6 +1237,11 @@ int object_remove_material_slot(Object *ob)
if (*matarar == NULL) return FALSE;
+ /* can happen on face selection in editmode */
+ if (ob->actcol > ob->totcol) {
+ ob->actcol = ob->totcol;
+ }
+
/* we delete the actcol */
mao = (*matarar)[ob->actcol - 1];
if (mao) mao->id.us--;
@@ -1856,7 +1863,7 @@ static void convert_tfacematerial(Main *main, Material *ma)
mat_new = BKE_material_copy(ma);
if (mat_new) {
/* rename the material*/
- strcpy(mat_new->id.name, idname);
+ BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name));
id_us_min((ID *)mat_new);
mat_nr = mesh_addmaterial(me, mat_new);
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 805e77c..b3f71e5 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -50,8 +50,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
-
#include "BKE_global.h"
#include "BKE_main.h"
@@ -1516,7 +1514,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
float in_v /*, out_v*/;
float workp[3];
float dvec[3];
- float tmp_v, workp_v, max_len, len, nx, ny, nz, MAXN;
+ float tmp_v, workp_v, max_len, nx, ny, nz, max_dim;
calc_mballco(ml, in);
in_v = mbproc->function(in[0], in[1], in[2]);
@@ -1575,17 +1573,17 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
ny = abs((out[1] - in[1]) / mbproc->size);
nz = abs((out[2] - in[2]) / mbproc->size);
- MAXN = MAX3(nx, ny, nz);
- if (MAXN != 0.0f) {
- dvec[0] = (out[0] - in[0]) / MAXN;
- dvec[1] = (out[1] - in[1]) / MAXN;
- dvec[2] = (out[2] - in[2]) / MAXN;
+ max_dim = max_fff(nx, ny, nz);
+ if (max_dim != 0.0f) {
+ float len = 0.0f;
+
+ dvec[0] = (out[0] - in[0]) / max_dim;
+ dvec[1] = (out[1] - in[1]) / max_dim;
+ dvec[2] = (out[2] - in[2]) / max_dim;
- len = 0.0;
while (len <= max_len) {
- workp[0] += dvec[0];
- workp[1] += dvec[1];
- workp[2] += dvec[2];
+ add_v3_v3(workp, dvec);
+
/* compute value of implicite function */
tmp_v = mbproc->function(workp[0], workp[1], workp[2]);
/* add cube to the stack, when value of implicite function crosses zero value */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 036f8f5..267cf17 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -46,7 +46,6 @@
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_scanfill.h"
@@ -431,42 +430,6 @@ void BKE_mesh_free(Mesh *me, int unlink)
if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
}
-void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
-{
- /* Assumes dst is already set up */
- int i;
-
- if (!src || !dst)
- return;
-
- memcpy(dst, src, copycount * sizeof(MDeformVert));
-
- for (i = 0; i < copycount; i++) {
- if (src[i].dw) {
- dst[i].dw = MEM_callocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
- memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
- }
- }
-
-}
-
-void free_dverts(MDeformVert *dvert, int totvert)
-{
- /* Instead of freeing the verts directly,
- * call this function to delete any special
- * vert data */
- int i;
-
- if (!dvert)
- return;
-
- /* Free any special data from the verts */
- for (i = 0; i < totvert; i++) {
- if (dvert[i].dw) MEM_freeN(dvert[i].dw);
- }
- MEM_freeN(dvert);
-}
-
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
{
if (free_customdata) {
@@ -732,7 +695,7 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz
if (r_size) copy_v3_v3(r_size, me->size);
}
-float *BKE_mesh_orco_verts_get(Object *ob)
+float (*BKE_mesh_orco_verts_get(Object *ob))[3]
{
Mesh *me = ob->data;
MVert *mvert = NULL;
@@ -749,7 +712,7 @@ float *BKE_mesh_orco_verts_get(Object *ob)
copy_v3_v3(vcos[a], mvert->co);
}
- return (float *)vcos;
+ return vcos;
}
void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert)
@@ -1241,8 +1204,8 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp,
allvert, totvert,
alledge, totedge,
- allloop, allpoly,
- totloop, totpoly, NULL);
+ allloop, allpoly, NULL,
+ totloop, totpoly);
}
/* BMESH: this doesn't calculate all edges from polygons,
@@ -1250,25 +1213,24 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
/* use specified dispbase */
-/* TODO: orco values for non DL_SURF types */
int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
MVert **allvert, int *_totvert,
MEdge **alledge, int *_totedge,
MLoop **allloop, MPoly **allpoly,
- int *_totloop, int *_totpoly,
- int **orco_index_ptr)
+ MLoopUV **alluv,
+ int *_totloop, int *_totpoly)
{
DispList *dl;
Curve *cu;
MVert *mvert;
MPoly *mpoly;
MLoop *mloop;
+ MLoopUV *mloopuv = NULL;
MEdge *medge;
float *data;
int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
int p1, p2, p3, p4, *index;
int conv_polys = 0;
- int (*orco_index)[4] = NULL;
cu = ob->data;
@@ -1315,15 +1277,13 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
*alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge");
*allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop
*allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop");
+
+ if (alluv)
+ *alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv");
/* verts and faces */
vertcount = 0;
- if (orco_index_ptr) {
- *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco");
- orco_index = (int (*)[4]) *orco_index_ptr;
- }
-
dl = dispbase->first;
while (dl) {
int smooth = dl->rt & CU_SMOOTH ? 1 : 0;
@@ -1396,6 +1356,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 3;
mpoly->mat_nr = dl->col;
+ if (mloopuv) {
+ int i;
+
+ for (i = 0; i < 3; i++, mloopuv++) {
+ mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1);
+ mloopuv->uv[1] = 0.0f;
+ }
+ }
+
if (smooth) mpoly->flag |= ME_SMOOTH;
mpoly++;
mloop += 3;
@@ -1445,13 +1414,29 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
mpoly->totloop = 4;
mpoly->mat_nr = dl->col;
- if (orco_index) {
- const int poly_index = mpoly - *allpoly;
- const int p_orco_base = startvert + ((dl->nr + 1) * a) + b;
- orco_index[poly_index][0] = p_orco_base + 1;
- orco_index[poly_index][1] = p_orco_base + dl->nr + 2;
- orco_index[poly_index][2] = p_orco_base + dl->nr + 1;
- orco_index[poly_index][3] = p_orco_base;
+ if (mloopuv) {
+ int orco_sizeu = dl->nr - 1;
+ int orco_sizev = dl->parts - 1;
+ int i;
+
+ /* exception as handled in convertblender.c too */
+ if (dl->flag & DL_CYCL_U) {
+ orco_sizeu++;
+ if (dl->flag & DL_CYCL_V)
+ orco_sizev++;
+ }
+
+ for (i = 0; i < 4; i++, mloopuv++) {
+ /* find uv based on vertex index into grid array */
+ int v = mloop[i].v - startvert;
+
+ mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev;
+ mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu;
+
+ /* cyclic correction */
+ if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f)
+ mloopuv->uv[1] = 1.0f;
+ }
}
if (smooth) mpoly->flag |= ME_SMOOTH;
@@ -1464,7 +1449,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
p1++;
}
}
-
}
dl = dl->next;
@@ -1485,33 +1469,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
}
-MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2])
-{
- r[0] = 0.5f + a[0] * 0.5f;
- r[1] = 0.5f + a[1] * 0.5f;
-}
-
-/**
- * orco is normally from #BKE_curve_make_orco
- */
-void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly,
- MLoop *mloops, MLoopUV *mloopuvs,
- float (*orco)[3], int (*orco_index)[4])
-{
- MPoly *mp;
-
- int i, j;
- for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
- MLoop *ml = mloops + mp->loopstart;
- MLoopUV *mluv = mloopuvs + mp->loopstart;
- for (j = 0; j < mp->totloop; j++, ml++, mluv++) {
- copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]);
- }
- }
-}
-
/* this may fail replacing ob->data, be sure to check ob->type */
-void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_uv)
{
Main *bmain = G.main;
Object *ob1;
@@ -1521,6 +1480,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
MVert *allvert = NULL;
MEdge *alledge = NULL;
MLoop *allloop = NULL;
+ MLoopUV *alluv = NULL;
MPoly *allpoly = NULL;
int totvert, totedge, totloop, totpoly;
@@ -1529,7 +1489,8 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
if (dm == NULL) {
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
&alledge, &totedge, &allloop,
- &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+ &allpoly, (use_orco_uv)? &alluv: NULL,
+ &totloop, &totpoly) != 0)
{
/* Error initializing */
return;
@@ -1547,6 +1508,12 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
+ if (alluv) {
+ const char *uvname = "Orco";
+ me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
+ me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
+ }
+
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
BKE_mesh_calc_edges(me, TRUE);
@@ -1585,7 +1552,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
void BKE_mesh_from_nurbs(Object *ob)
{
- BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL);
+ BKE_mesh_from_nurbs_displist(ob, &ob->disp, false);
}
typedef struct EdgeLink {
@@ -2489,7 +2456,7 @@ void BKE_mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
*/
int BKE_mesh_recalc_tessellation(CustomData *fdata,
CustomData *ldata, CustomData *pdata,
- MVert *mvert, int totface, int UNUSED(totloop),
+ MVert *mvert, int totface, int totloop,
int totpoly,
/* when tessellating to recalculate normals after
* we can skip copying here */
@@ -2504,15 +2471,15 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#define TESSFACE_SCANFILL (1 << 0)
#define TESSFACE_IS_QUAD (1 << 1)
+ const int looptris_tot = poly_to_tri_count(totpoly, totloop);
+
MPoly *mp, *mpoly;
MLoop *ml, *mloop;
- MFace *mface = NULL, *mf;
- BLI_array_declare(mface);
+ MFace *mface, *mf;
ScanFillContext sf_ctx;
ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first;
ScanFillFace *sf_tri;
- int *mface_to_poly_map = NULL;
- BLI_array_declare(mface_to_poly_map);
+ int *mface_to_poly_map;
int lindex[4]; /* only ever use 3 in this case */
int poly_index, j, mface_index;
@@ -2526,8 +2493,9 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
/* allocate the length of totfaces, avoid many small reallocs,
* if all faces are tri's it will be correct, quads == 2x allocs */
- BLI_array_reserve(mface_to_poly_map, totpoly);
- BLI_array_reserve(mface, totpoly);
+ /* take care. we are _not_ calloc'ing so be sure to initialize each field */
+ mface_to_poly_map = MEM_mallocN(sizeof(*mface_to_poly_map) * looptris_tot, __func__);
+ mface = MEM_mallocN(sizeof(*mface) * looptris_tot, __func__);
mface_index = 0;
mp = mpoly;
@@ -2539,8 +2507,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#ifdef USE_TESSFACE_SPEEDUP
#define ML_TO_MF(i1, i2, i3) \
- BLI_array_grow_one(mface_to_poly_map); \
- BLI_array_grow_one(mface); \
mface_to_poly_map[mface_index] = poly_index; \
mf = &mface[mface_index]; \
/* set loop indices, transformed to vert indices later */ \
@@ -2550,12 +2516,11 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
mf->v4 = 0; \
mf->mat_nr = mp->mat_nr; \
mf->flag = mp->flag; \
+ mf->edcode = 0; \
(void)0
/* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */
#define ML_TO_MF_QUAD() \
- BLI_array_grow_one(mface_to_poly_map); \
- BLI_array_grow_one(mface); \
mface_to_poly_map[mface_index] = poly_index; \
mf = &mface[mface_index]; \
/* set loop indices, transformed to vert indices later */ \
@@ -2565,7 +2530,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
mf->v4 = mp->loopstart + 3; /* EXCEPTION */ \
mf->mat_nr = mp->mat_nr; \
mf->flag = mp->flag; \
- mf->edcode |= TESSFACE_IS_QUAD; /* EXCEPTION */ \
+ mf->edcode = TESSFACE_IS_QUAD; /* EXCEPTION */ \
(void)0
@@ -2608,29 +2573,26 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first);
totfilltri = BLI_scanfill_calc(&sf_ctx, 0);
- if (totfilltri) {
- BLI_array_grow_items(mface_to_poly_map, totfilltri);
- BLI_array_grow_items(mface, totfilltri);
+ BLI_assert(totfilltri <= mp->totloop - 2);
- for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) {
- mface_to_poly_map[mface_index] = poly_index;
- mf = &mface[mface_index];
+ for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) {
+ mface_to_poly_map[mface_index] = poly_index;
+ mf = &mface[mface_index];
- /* set loop indices, transformed to vert indices later */
- mf->v1 = sf_tri->v1->keyindex;
- mf->v2 = sf_tri->v2->keyindex;
- mf->v3 = sf_tri->v3->keyindex;
- mf->v4 = 0;
+ /* set loop indices, transformed to vert indices later */
+ mf->v1 = sf_tri->v1->keyindex;
+ mf->v2 = sf_tri->v2->keyindex;
+ mf->v3 = sf_tri->v3->keyindex;
+ mf->v4 = 0;
- mf->mat_nr = mp->mat_nr;
- mf->flag = mp->flag;
+ mf->mat_nr = mp->mat_nr;
+ mf->flag = mp->flag;
#ifdef USE_TESSFACE_SPEEDUP
- mf->edcode |= TESSFACE_SCANFILL; /* tag for sorting loop indices */
+ mf->edcode = TESSFACE_SCANFILL; /* tag for sorting loop indices */
#endif
- mface_index++;
- }
+ mface_index++;
}
BLI_scanfill_end(&sf_ctx);
@@ -2640,9 +2602,10 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
CustomData_free(fdata, totface);
totface = mface_index;
+ BLI_assert(totface <= looptris_tot);
/* not essential but without this we store over-alloc'd memory in the CustomData layers */
- if (LIKELY((MEM_allocN_len(mface) / sizeof(*mface)) != totface)) {
+ if (LIKELY(looptris_tot != totface)) {
mface = MEM_reallocN(mface, sizeof(*mface) * totface);
mface_to_poly_map = MEM_reallocN(mface_to_poly_map, sizeof(*mface_to_poly_map) * totface);
}
@@ -3009,9 +2972,9 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
else {
int i;
MLoop *l_iter = loopstart;
- float area, polynorm_local[3], (*vertexcos)[3];
+ float area, polynorm_local[3];
+ float (*vertexcos)[3] = BLI_array_alloca(vertexcos, mpoly->totloop);
const float *no = polynormal ? polynormal : polynorm_local;
- BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
@@ -3026,8 +2989,6 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
/* finally calculate the area */
area = area_poly_v3(mpoly->totloop, vertexcos, no);
- BLI_array_fixedstack_free(vertexcos);
-
return area;
}
}
@@ -3110,6 +3071,107 @@ void BKE_mesh_flush_hidden_from_verts(const MVert *mvert,
}
}
+/**
+ * simple poly -> vert/edge selection.
+ */
+void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, const int totvert,
+ MLoop *mloop,
+ MEdge *medge, const int totedge,
+ const MPoly *mpoly, const int totpoly)
+{
+ MVert *mv;
+ MEdge *med;
+ const MPoly *mp;
+ int i;
+
+ i = totvert;
+ for (mv = mvert; i--; mv++) {
+ mv->flag &= ~SELECT;
+ }
+
+ i = totedge;
+ for (med = medge; i--; med++) {
+ med->flag &= ~SELECT;
+ }
+
+ i = totpoly;
+ for (mp = mpoly; i--; mp++) {
+ /* assume if its selected its not hidden and none of its verts/edges are hidden
+ * (a common assumption)*/
+ if (mp->flag & ME_FACE_SEL) {
+ MLoop *ml;
+ int j;
+ j = mp->totloop;
+ for (ml = &mloop[mp->loopstart]; j--; ml++) {
+ mvert[ml->v].flag |= SELECT;
+ medge[ml->e].flag |= SELECT;
+ }
+ }
+ }
+}
+void BKE_mesh_flush_select_from_polys(Mesh *me)
+{
+ BKE_mesh_flush_select_from_polys_ex(me->mvert, me->totvert,
+ me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
+}
+
+void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(totvert),
+ MLoop *mloop,
+ MEdge *medge, const int totedge,
+ MPoly *mpoly, const int totpoly)
+{
+ MEdge *med;
+ MPoly *mp;
+ int i;
+
+ /* edges */
+ i = totedge;
+ for (med = medge; i--; med++) {
+ if ((med->flag & ME_HIDE) == 0) {
+ if ((mvert[med->v1].flag & SELECT) && (mvert[med->v2].flag & SELECT)) {
+ med->flag |= SELECT;
+ }
+ else {
+ med->flag &= ~SELECT;
+ }
+ }
+ }
+
+ /* polys */
+ i = totpoly;
+ for (mp = mpoly; i--; mp++) {
+ if ((mp->flag & ME_HIDE) == 0) {
+ int ok = TRUE;
+ MLoop *ml;
+ int j;
+ j = mp->totloop;
+ for (ml = &mloop[mp->loopstart]; j--; ml++) {
+ if ((mvert[ml->v].flag & SELECT) == 0) {
+ ok = FALSE;
+ break;
+ }
+ }
+
+ if (ok) {
+ mp->flag |= ME_FACE_SEL;
+ }
+ else {
+ mp->flag &= ~ME_FACE_SEL;
+ }
+ }
+ }
+}
+void BKE_mesh_flush_select_from_verts(Mesh *me)
+{
+ BKE_mesh_flush_select_from_verts_ex(me->mvert, me->totvert,
+ me->mloop,
+ me->medge, me->totedge,
+ me->mpoly, me->totpoly);
+}
+
+
/* basic vertex data functions */
int BKE_mesh_minmax(Mesh *me, float r_min[3], float r_max[3])
{
@@ -3279,3 +3341,39 @@ void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
}
}
#endif
+
+
+void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
+{
+ if (UNLIKELY(mesh->cd_flag)) {
+ return;
+ }
+ else {
+ MVert *mv;
+ MEdge *med;
+ int i;
+
+ for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
+ if (mv->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ break;
+ }
+ }
+
+ for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
+ if (med->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ break;
+ }
+ }
+ if (med->crease != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ break;
+ }
+ }
+ }
+
+ }
+}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 25b70ce..2aeda61 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -621,16 +621,6 @@ int modifiers_isPreview(Object *ob)
return FALSE;
}
-int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
-{
- int i = 0;
- ModifierData *md;
-
- for (md = ob->modifiers.first; (md && md_seek != md); md = md->next, i++) ;
- if (!md) return -1; /* modifier isn't in the object */
- return i;
-}
-
void modifier_freeTemporaryData(ModifierData *md)
{
if (md->type == eModifierType_Armature) {
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 7df7561..a6c2325 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -59,9 +59,14 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
BLI_array_declare(verts);
BLI_array_declare(edges);
int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ;
- int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
+ bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0);
+ bool is_cddm = (dm->type == DM_TYPE_CDDM); /* duplicate the arrays for non cddm */
char has_orig_hflag = 0;
+ int cd_vert_bweight_offset;
+ int cd_edge_bweight_offset;
+ int cd_edge_crease_offset;
+
if (is_init == FALSE) {
/* check if we have an origflag */
has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0;
@@ -75,43 +80,45 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP);
CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE);
+ if (is_init) {
+ BM_mesh_cd_flag_apply(bm, dm->cd_flag);
+ }
+
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
- /* add crease layer */
- BM_data_layer_add(bm, &bm->edata, CD_CREASE);
- /* add bevel weight layers */
- BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
- BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
-
vtable = MEM_callocN(sizeof(void **) * totvert, __func__);
etable = MEM_callocN(sizeof(void **) * totedge, __func__);
/*do verts*/
- mv = mvert = dm->dupVertArray(dm);
+ mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm);
for (i = 0; i < totvert; i++, mv++) {
v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD);
normal_short_to_float_v3(v->no, mv->no);
v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
BM_elem_index_set(v, i); /* set_inline */
- CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data);
+ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true);
vtable[i] = v;
/* add bevel weight */
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f);
+ if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f);
if (UNLIKELY(has_orig_hflag & BM_VERT)) {
int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX);
*orig_index = ORIGINDEX_NONE;
}
}
- MEM_freeN(mvert);
+ if (!is_cddm) MEM_freeN(mvert);
if (is_init) bm->elem_index_dirty &= ~BM_VERT;
/*do edges*/
- me = medge = dm->dupEdgeArray(dm);
+ me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm);
for (i = 0; i < totedge; i++, me++) {
//BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL);
e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD);
@@ -119,20 +126,18 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
e->head.hflag = BM_edge_flag_from_mflag(me->flag);
BM_elem_index_set(e, i); /* set_inline */
- CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
+ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true);
etable[i] = e;
- /* add crease */
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f);
- /* add bevel weight */
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f);
+ if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f);
+ if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)me->crease / 255.0f);
if (UNLIKELY(has_orig_hflag & BM_EDGE)) {
int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX);
*orig_index = ORIGINDEX_NONE;
}
}
- MEM_freeN(medge);
+ if (!is_cddm) MEM_freeN(medge);
if (is_init) bm->elem_index_dirty &= ~BM_EDGE;
/* do faces */
@@ -156,7 +161,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
edges[j] = etable[ml->e];
}
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD);
+ f = BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD);
if (UNLIKELY(f == NULL)) {
continue;
@@ -169,10 +174,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) {
- CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data);
+ CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true);
}
- CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
+ CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
if (face_normals) {
copy_v3_v3(f->no, face_normals[i]);
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4156b5b..69e368f 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1325,7 +1325,7 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index c737dcc..b12463d 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -43,9 +43,9 @@
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
@@ -379,7 +379,7 @@ void multires_force_update(Object *ob)
ob->derivedFinal = NULL;
}
if (ob->sculpt && ob->sculpt->pbvh) {
- BLI_pbvh_free(ob->sculpt->pbvh);
+ BKE_pbvh_free(ob->sculpt->pbvh);
ob->sculpt->pbvh = NULL;
}
}
@@ -1407,7 +1407,7 @@ void multires_stitch_grids(Object *ob)
int totface;
if (ccgdm->pbvh) {
- BLI_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
if (totface) {
ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 17dcf34..84e2800 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1161,11 +1161,11 @@ void ntreeSetOutput(bNodeTree *ntree)
bNodeTree *ntreeFromID(ID *id)
{
switch (GS(id->name)) {
- case ID_MA: return ((Material*)id)->nodetree;
- case ID_LA: return ((Lamp*)id)->nodetree;
- case ID_WO: return ((World*)id)->nodetree;
- case ID_TE: return ((Tex*)id)->nodetree;
- case ID_SCE: return ((Scene*)id)->nodetree;
+ case ID_MA: return ((Material *)id)->nodetree;
+ case ID_LA: return ((Lamp *)id)->nodetree;
+ case ID_WO: return ((World *)id)->nodetree;
+ case ID_TE: return ((Tex *)id)->nodetree;
+ case ID_SCE: return ((Scene *)id)->nodetree;
default: return NULL;
}
}
@@ -2162,6 +2162,24 @@ void nodeRegisterType(bNodeTreeType *ttype, bNodeType *ntype)
if (found == NULL)
BLI_addtail(typelist, ntype);
+
+ /* Associate the RNA struct type with the bNodeType.
+ * Dynamically registered nodes will create an RNA type at runtime
+ * and call RNA_struct_blender_type_set, so this only needs to be done for old RNA types
+ * created in makesrna, which can not be associated to a bNodeType immediately,
+ * since bNodeTypes are registered afterward ...
+ */
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (ID == ntype->type) { \
+ StructRNA *srna = RNA_struct_find(STRINGIFY_ARG(Category##StructName)); \
+ BLI_assert(srna != NULL); \
+ RNA_struct_blender_type_set(srna, ntype); \
+ }
+
+ /* XXX hack, this file will be moved to the nodes folder in customnodes branch,
+ * then this stupid include path is not needed any more.
+ */
+ #include "intern/rna_nodetree_types.h"
}
static void registerCompositNodes(bNodeTreeType *ttype)
@@ -2305,6 +2323,7 @@ static void registerShaderNodes(bNodeTreeType *ttype)
register_node_type_sh_layer_weight(ttype);
register_node_type_sh_tex_coord(ttype);
register_node_type_sh_particle_info(ttype);
+ register_node_type_sh_hair_info(ttype);
register_node_type_sh_bump(ttype);
register_node_type_sh_script(ttype);
register_node_type_sh_tangent(ttype);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 4905a31..b2371da 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -57,14 +57,14 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
+#include "DNA_property_types.h"
#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
#include "BLI_math.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
+#include "BKE_pbvh.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -264,14 +264,44 @@ void free_sculptsession_deformMats(SculptSession *ss)
ss->deform_imats = NULL;
}
+/* Write out the sculpt dynamic-topology BMesh to the Mesh */
+void sculptsession_bm_to_me(struct Object *ob, int reorder)
+{
+ if (ob && ob->sculpt) {
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->bm) {
+ if (ob->data) {
+ BMIter iter;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_SMOOTH,
+ ss->bm_smooth_shading);
+ }
+ if (reorder)
+ BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
+ BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
+ }
+ }
+ }
+}
+
void free_sculptsession(Object *ob)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
DerivedMesh *dm = ob->derivedFinal;
+ if (ss->bm) {
+ sculptsession_bm_to_me(ob, TRUE);
+ BM_mesh_free(ss->bm);
+ }
+
if (ss->pbvh)
- BLI_pbvh_free(ss->pbvh);
+ BKE_pbvh_free(ss->pbvh);
+ if (ss->bm_log)
+ BM_log_free(ss->bm_log);
+
if (dm && dm->getPBVH)
dm->getPBVH(NULL, dm); /* signal to clear */
@@ -349,7 +379,7 @@ void BKE_object_free(Object *ob)
free_controllers(&ob->controllers);
free_actuators(&ob->actuators);
- free_constraints(&ob->constraints);
+ BKE_free_constraints(&ob->constraints);
free_partdeflect(ob->pd);
@@ -434,7 +464,7 @@ void BKE_object_unlink(Object *ob)
bPoseChannel *pchan;
for (pchan = obt->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -465,7 +495,7 @@ void BKE_object_unlink(Object *ob)
sca_remove_ob_poin(obt, ob);
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -729,6 +759,50 @@ void BKE_object_unlink(Object *ob)
}
}
+/* actual check for internal data, not context or flags */
+int BKE_object_is_in_editmode(Object *ob)
+{
+ if (ob->data == NULL)
+ return 0;
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ if (me->edit_btmesh)
+ return 1;
+ }
+ else if (ob->type == OB_ARMATURE) {
+ bArmature *arm = ob->data;
+
+ if (arm->edbo)
+ return 1;
+ }
+ else if (ob->type == OB_FONT) {
+ Curve *cu = ob->data;
+
+ if (cu->editfont)
+ return 1;
+ }
+ else if (ob->type == OB_MBALL) {
+ MetaBall *mb = ob->data;
+
+ if (mb->editelems)
+ return 1;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
+
+ if (lt->editlatt)
+ return 1;
+ }
+ else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
+ Curve *cu = ob->data;
+
+ if (cu->editnurb)
+ return 1;
+ }
+ return 0;
+}
+
int BKE_object_exists_check(Object *obtest)
{
Object *ob;
@@ -1085,7 +1159,7 @@ static void copy_object_pose(Object *obn, Object *ob)
}
for (con = chan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1185,7 +1259,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
BKE_pose_rebuild(obn, obn->data);
}
defgroup_copy_list(&obn->defbase, &ob->defbase);
- copy_constraints(&obn->constraints, &ob->constraints, TRUE);
+ BKE_copy_constraints(&obn->constraints, &ob->constraints, TRUE);
obn->mode = 0;
obn->sculpt = NULL;
@@ -1488,7 +1562,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
/* *************** CALC ****************** */
-void BKE_object_scale_to_mat3(Object *ob, float mat[][3])
+void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
{
float vec[3];
mul_v3_v3v3(vec, ob->size, ob->dscale);
@@ -1526,13 +1600,13 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], short use_drot)
}
/* combine these rotations */
- if(use_drot)
+ if (use_drot)
mul_m3_m3m3(mat, dmat, rmat);
else
copy_m3_m3(mat, rmat);
}
-void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat)
+void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], short use_compat)
{
switch (ob->rotmode) {
case ROT_MODE_QUAT:
@@ -1635,7 +1709,7 @@ void BKE_object_tfm_protected_restore(Object *ob,
}
/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
-void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent)
+void BKE_object_apply_mat4(Object *ob, float mat[4][4], const short use_compat, const short use_parent)
{
float rot[3][3];
@@ -1664,7 +1738,7 @@ void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, c
/* BKE_object_mat3_to_rot handles delta rotations */
}
-void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */
+void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
{
float smat[3][3];
float rmat[3][3];
@@ -1678,7 +1752,7 @@ void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */
mul_m3_m3m3(mat, rmat, smat);
}
-void BKE_object_to_mat4(Object *ob, float mat[][4])
+void BKE_object_to_mat4(Object *ob, float mat[4][4])
{
float tmat[3][3];
@@ -1692,7 +1766,7 @@ void BKE_object_to_mat4(Object *ob, float mat[][4])
/* extern */
int enable_cu_speed = 1;
-static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
+static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4])
{
Curve *cu;
float vec[4], dir[3], quat[4], radius, ctime;
@@ -1776,7 +1850,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
}
}
-static void ob_parbone(Object *ob, Object *par, float mat[][4])
+static void ob_parbone(Object *ob, Object *par, float mat[4][4])
{
bPoseChannel *pchan;
float vec[3];
@@ -1795,12 +1869,19 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
}
/* get bone transform */
- copy_m4_m4(mat, pchan->pose_mat);
+ if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
+ /* the new option uses the root - expected bahaviour, but differs from old... */
+ /* XXX check on version patching? */
+ copy_m4_m4(mat, pchan->chan_mat);
+ }
+ else {
+ copy_m4_m4(mat, pchan->pose_mat);
- /* but for backwards compatibility, the child has to move to the tail */
- copy_v3_v3(vec, mat[1]);
- mul_v3_fl(vec, pchan->bone->length);
- add_v3_v3(mat[3], vec);
+ /* but for backwards compatibility, the child has to move to the tail */
+ copy_v3_v3(vec, mat[1]);
+ mul_v3_fl(vec, pchan->bone->length);
+ add_v3_v3(mat[3], vec);
+ }
}
static void give_parvert(Object *par, int nr, float vec[3])
@@ -1878,7 +1959,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
Curve *cu = par->data;
- ListBase *nurb = BKE_curve_nurbs_get(cu);;
+ ListBase *nurb = BKE_curve_nurbs_get(cu);
BKE_nurbList_index_get_co(nurb, nr, vec);
}
@@ -1906,7 +1987,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
-static void ob_parvert3(Object *ob, Object *par, float mat[][4])
+static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
{
float cmat[3][3], v1[3], v2[3], v3[3], q[4];
@@ -1934,7 +2015,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4])
}
}
-static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
+static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul)
{
float totmat[4][4];
float tmat[4][4];
@@ -2062,9 +2143,9 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- solve_constraints(&ob->constraints, cob, ctime);
- constraints_clear_evalob(cob);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_solve_constraints(&ob->constraints, cob, ctime);
+ BKE_constraints_clear_evalob(cob);
}
/* set negative scale flag in object */
@@ -2133,9 +2214,9 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
if (ob->constraints.first) {
bConstraintOb *cob;
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
- constraints_clear_evalob(cob);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
+ BKE_constraints_clear_evalob(cob);
}
}
@@ -2734,7 +2815,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
* changing PVBH node organization, we hope topology does not change in
* the meantime .. weak */
if (ss->pbvh) {
- BLI_pbvh_free(ss->pbvh);
+ BKE_pbvh_free(ss->pbvh);
ss->pbvh = NULL;
}
@@ -2744,10 +2825,10 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
PBVHNode **nodes;
int n, totnode;
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
for (n = 0; n < totnode; n++)
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
MEM_freeN(nodes);
}
@@ -2900,12 +2981,13 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
kb->data = data;
- kb->totelem = me->totvert;
+ kb->totelem = totelem;
}
return kb;
@@ -2937,11 +3019,12 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
- kb->totelem = lt->pntsu * lt->pntsv * lt->pntsw;
+ kb->totelem = totelem;
kb->data = data;
}
@@ -2976,11 +3059,12 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
- kb->totelem = BKE_nurbList_verts_count(lb);
+ kb->totelem = totelem;
kb->data = data;
}
@@ -3083,11 +3167,11 @@ void BKE_object_relink(Object *ob)
if (ob->id.lib)
return;
- relink_constraints(&ob->constraints);
+ BKE_relink_constraints(&ob->constraints);
if (ob->pose) {
bPoseChannel *chan;
for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
- relink_constraints(&chan->constraints);
+ BKE_relink_constraints(&chan->constraints);
}
}
modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index e694a7e..c4274aa 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -35,16 +35,15 @@
#include "DNA_scene_types.h"
+#include "BKE_global.h" /* XXX TESTING */
#include "BKE_image.h"
#include "BKE_ocean.h"
-#include "BKE_global.h" // XXX TESTING
-#include "BLI_math_base.h"
-#include "BLI_math_inline.h"
+#include "BLI_math.h"
+#include "BLI_path_util.h"
#include "BLI_rand.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "IMB_imbuf.h"
@@ -54,7 +53,7 @@
#ifdef WITH_OCEANSIM
-// Ocean code
+/* Ocean code */
#include "fftw3.h"
#define GRAVITY 9.81f
@@ -82,7 +81,7 @@ typedef struct Ocean {
float _Lx;
float _Lz;
- float normalize_factor; // init w
+ float normalize_factor; /* init w */
float time;
short _do_disp_y;
@@ -96,51 +95,52 @@ typedef struct Ocean {
/* ********* sim data arrays ********* */
/* two dimensional arrays of complex */
- fftw_complex *_fft_in; // init w sim w
- fftw_complex *_fft_in_x; // init w sim w
- fftw_complex *_fft_in_z; // init w sim w
- fftw_complex *_fft_in_jxx; // init w sim w
- fftw_complex *_fft_in_jzz; // init w sim w
- fftw_complex *_fft_in_jxz; // init w sim w
- fftw_complex *_fft_in_nx; // init w sim w
- fftw_complex *_fft_in_nz; // init w sim w
- fftw_complex *_htilda; // init w sim w (only once)
+ fftw_complex *_fft_in; /* init w sim w */
+ fftw_complex *_fft_in_x; /* init w sim w */
+ fftw_complex *_fft_in_z; /* init w sim w */
+ fftw_complex *_fft_in_jxx; /* init w sim w */
+ fftw_complex *_fft_in_jzz; /* init w sim w */
+ fftw_complex *_fft_in_jxz; /* init w sim w */
+ fftw_complex *_fft_in_nx; /* init w sim w */
+ fftw_complex *_fft_in_nz; /* init w sim w */
+ fftw_complex *_htilda; /* init w sim w (only once) */
/* fftw "plans" */
- fftw_plan _disp_y_plan; // init w sim r
- fftw_plan _disp_x_plan; // init w sim r
- fftw_plan _disp_z_plan; // init w sim r
- fftw_plan _N_x_plan; // init w sim r
- fftw_plan _N_z_plan; // init w sim r
- fftw_plan _Jxx_plan; // init w sim r
- fftw_plan _Jxz_plan; // init w sim r
- fftw_plan _Jzz_plan; // init w sim r
+ fftw_plan _disp_y_plan; /* init w sim r */
+ fftw_plan _disp_x_plan; /* init w sim r */
+ fftw_plan _disp_z_plan; /* init w sim r */
+ fftw_plan _N_x_plan; /* init w sim r */
+ fftw_plan _N_z_plan; /* init w sim r */
+ fftw_plan _Jxx_plan; /* init w sim r */
+ fftw_plan _Jxz_plan; /* init w sim r */
+ fftw_plan _Jzz_plan; /* init w sim r */
/* two dimensional arrays of float */
- double *_disp_y; // init w sim w via plan?
- double *_N_x; // init w sim w via plan?
- /*float * _N_y; all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
- double _N_y; // sim w ********* can be rearranged?
- double *_N_z; // init w sim w via plan?
- double *_disp_x; // init w sim w via plan?
- double *_disp_z; // init w sim w via plan?
+ double *_disp_y; /* init w sim w via plan? */
+ double *_N_x; /* init w sim w via plan? */
+ /* all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
+ /*float * _N_y; */
+ double _N_y; /* sim w ********* can be rearranged? */
+ double *_N_z; /* init w sim w via plan? */
+ double *_disp_x; /* init w sim w via plan? */
+ double *_disp_z; /* init w sim w via plan? */
/* two dimensional arrays of float */
/* Jacobian and minimum eigenvalue */
- double *_Jxx; // init w sim w
- double *_Jzz; // init w sim w
- double *_Jxz; // init w sim w
+ double *_Jxx; /* init w sim w */
+ double *_Jzz; /* init w sim w */
+ double *_Jxz; /* init w sim w */
/* one dimensional float array */
- float *_kx; // init w sim r
- float *_kz; // init w sim r
+ float *_kx; /* init w sim r */
+ float *_kz; /* init w sim r */
/* two dimensional complex array */
- fftw_complex *_h0; // init w sim r
- fftw_complex *_h0_minus; // init w sim r
+ fftw_complex *_h0; /* init w sim r */
+ fftw_complex *_h0_minus; /* init w sim r */
/* two dimensional float array */
- float *_k; // init w sim r
+ float *_k; /* init w sim r */
} Ocean;
@@ -152,10 +152,13 @@ static float nextfr(float min, float max)
static float gaussRand(void)
{
- float x; // Note: to avoid numerical problems with very small
- float y; // numbers, we make these variables singe-precision
- float length2; // floats, but later we call the double-precision log()
- // and sqrt() functions instead of logf() and sqrtf().
+ /* Note: to avoid numerical problems with very small numbers, we make these variables singe-precision floats,
+ * but later we call the double-precision log() and sqrt() functions instead of logf() and sqrtf().
+ */
+ float x;
+ float y;
+ float length2;
+
do {
x = (float) (nextfr(-1, 1));
y = (float)(nextfr(-1, 1));
@@ -167,12 +170,7 @@ static float gaussRand(void)
/**
* Some useful functions
- * */
-MINLINE float lerp(float a, float b, float f)
-{
- return a + (b - a) * f;
-}
-
+ */
MINLINE float catrom(float p0, float p1, float p2, float p3, float f)
{
return 0.5f * ((2.0f * p1) +
@@ -186,23 +184,24 @@ MINLINE float omega(float k, float depth)
return sqrtf(GRAVITY * k * tanhf(k * depth));
}
-// modified Phillips spectrum
+/* modified Phillips spectrum */
static float Ph(struct Ocean *o, float kx, float kz)
{
float tmp;
float k2 = kx * kx + kz * kz;
if (k2 == 0.0f) {
- return 0.0f; // no DC component
+ return 0.0f; /* no DC component */
}
- // damp out the waves going in the direction opposite the wind
+ /* damp out the waves going in the direction opposite the wind */
tmp = (o->_wx * kx + o->_wz * kz) / sqrtf(k2);
if (tmp < 0) {
tmp *= o->_damp_reflections;
}
- return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) * powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
+ return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) *
+ powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
}
static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, float jxz)
@@ -240,7 +239,7 @@ static void init_complex(fftw_complex cmpl, float real, float image)
cmpl[1] = image;
}
-#if 0 // unused
+#if 0 /* unused */
static void add_complex_f(fftw_complex res, fftw_complex cmpl, float f)
{
res[0] = cmpl[0] + f;
@@ -306,7 +305,7 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
float frac_x, frac_z;
float uu, vv;
- // first wrap the texture so 0 <= (u, v) < 1
+ /* first wrap the texture so 0 <= (u, v) < 1 */
u = fmodf(u, 1.0f);
v = fmodf(v, 1.0f);
@@ -334,7 +333,9 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
j1 = j1 % oc->_N;
-#define BILERP(m) (lerp(lerp(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], frac_x), lerp(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], frac_x), frac_z))
+#define BILERP(m) (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
+ interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
+ frac_z))
{
if (oc->_do_disp_y) {
ocr->disp[1] = BILERP(oc->_disp_y);
@@ -364,14 +365,14 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
BLI_rw_mutex_unlock(&oc->oceanmutex);
}
-// use catmullrom interpolation rather than linear
+/* use catmullrom interpolation rather than linear */
void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
{
int i0, i1, i2, i3, j0, j1, j2, j3;
float frac_x, frac_z;
float uu, vv;
- // first wrap the texture so 0 <= (u, v) < 1
+ /* first wrap the texture so 0 <= (u, v) < 1 */
u = fmod(u, 1.0f);
v = fmod(v, 1.0f);
@@ -408,11 +409,15 @@ void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u
j0 = j0 < 0 ? j0 + oc->_N : j0;
j3 = j3 >= oc->_N ? j3 - oc->_N : j3;
-#define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
- catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
- catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
- catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
- frac_z)
+#define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], \
+ m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
+ catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], \
+ m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
+ catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], \
+ m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
+ catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], \
+ m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
+ frac_z)
{
if (oc->_do_disp_y) {
@@ -452,9 +457,9 @@ void BKE_ocean_eval_xz_catrom(struct Ocean *oc, struct OceanResult *ocr, float x
BKE_ocean_eval_uv_catrom(oc, ocr, x / oc->_Lx, z / oc->_Lz);
}
-// note that this doesn't wrap properly for i, j < 0, but its
-// not really meant for that being just a way to get the raw data out
-// to save in some image format.
+/* note that this doesn't wrap properly for i, j < 0, but its not really meant for that being just a way to get
+ * the raw data out to save in some image format.
+ */
void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j)
{
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
@@ -496,11 +501,10 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
- // compute a new htilda
+ /* compute a new htilda */
#pragma omp parallel for private(i, j)
for (i = 0; i < o->_M; ++i) {
- // note the <= _N/2 here, see the fftw doco about
- // the mechanics of the complex->real fft storage
+ /* note the <= _N/2 here, see the fftw doco about the mechanics of the complex->real fft storage */
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex exp_param1;
fftw_complex exp_param2;
@@ -527,15 +531,15 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
#pragma omp section
{
if (o->_do_disp_y) {
- // y displacement
+ /* y displacement */
fftw_execute(o->_disp_y_plan);
}
- } // section 1
+ } /* section 1 */
#pragma omp section
{
if (o->_do_chop) {
- // x displacement
+ /* x displacement */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
@@ -546,18 +550,21 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, minus_i);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_disp_x_plan);
}
- } //section 2
+ } /* section 2 */
#pragma omp section
{
if (o->_do_chop) {
- // z displacement
+ /* z displacement */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
@@ -568,28 +575,34 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, minus_i);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_disp_z_plan);
}
- } // section 3
+ } /* section 3 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jxx
+ /* Jxx */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
@@ -601,22 +614,25 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
}
}
}
- } // section 4
+ } /* section 4 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jzz
+ /* Jzz */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
@@ -627,32 +643,35 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
}
}
}
- } // section 5
+ } /* section 5 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jxz
+ /* Jxz */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jxz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_Jxz_plan);
}
- } // section 6
+ } /* section 6 */
#pragma omp section
{
- // fft normals
+ /* fft normals */
if (o->_do_normals) {
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
@@ -667,7 +686,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
fftw_execute(o->_N_x_plan);
}
- } // section 7
+ } /* section 7 */
#pragma omp section
{
@@ -694,9 +713,9 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
#endif
o->_N_y = 1.0f / scale;
}
- } // section 8
+ } /* section 8 */
- } // omp sections
+ } /* omp sections */
BLI_rw_mutex_unlock(&o->oceanmutex);
}
@@ -726,7 +745,8 @@ static void set_height_normalize_factor(struct Ocean *oc)
BLI_rw_mutex_unlock(&oc->oceanmutex);
- if (max_h == 0.0f) max_h = 0.00001f; // just in case ...
+ if (max_h == 0.0f)
+ max_h = 0.00001f; /* just in case ... */
res = 1.0f / (max_h);
@@ -743,7 +763,8 @@ struct Ocean *BKE_add_ocean(void)
}
void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
- float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals, short do_jacobian, int seed)
+ float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
+ short do_jacobian, int seed)
{
int i, j, ii;
@@ -761,8 +782,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_Lx = Lx;
o->_Lz = Lz;
o->_wx = cos(w);
- o->_wz = -sin(w); // wave direction
- o->_L = V * V / GRAVITY; // largest wave for a given velocity V
+ o->_wz = -sin(w); /* wave direction */
+ o->_L = V * V / GRAVITY; /* largest wave for a given velocity V */
o->time = time;
o->_do_disp_y = do_height_field;
@@ -776,30 +797,30 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_kx = (float *) MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
o->_kz = (float *) MEM_mallocN(o->_N * sizeof(float), "ocean_kz");
- // make this robust in the face of erroneous usage
+ /* make this robust in the face of erroneous usage */
if (o->_Lx == 0.0f)
o->_Lx = 0.001f;
if (o->_Lz == 0.0f)
o->_Lz = 0.001f;
- // the +ve components and DC
+ /* the +ve components and DC */
for (i = 0; i <= o->_M / 2; ++i)
o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;
- // the -ve components
+ /* the -ve components */
for (i = o->_M - 1, ii = 0; i > o->_M / 2; --i, ++ii)
o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;
- // the +ve components and DC
+ /* the +ve components and DC */
for (i = 0; i <= o->_N / 2; ++i)
o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;
- // the -ve components
+ /* the -ve components */
for (i = o->_N - 1, ii = 0; i > o->_N / 2; --i, ++ii)
o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;
- // pre-calculate the k matrix
+ /* pre-calculate the k matrix */
for (i = 0; i < o->_M; ++i)
for (j = 0; j <= o->_N / 2; ++j)
o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
@@ -819,11 +840,11 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
}
}
- o->_fft_in = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
- o->_htilda = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
+ o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
+ o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
if (o->_do_disp_y) {
- o->_disp_y = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
+ o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
}
@@ -831,32 +852,35 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_fft_in_nx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nx");
o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz");
- o->_N_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
+ o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
/* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
- o->_N_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
+ o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
}
if (o->_do_chop) {
- o->_fft_in_x = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
- o->_fft_in_z = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
+ o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
+ o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
- o->_disp_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
- o->_disp_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
+ o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
+ o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
}
if (o->_do_jacobian) {
- o->_fft_in_jxx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jxx");
- o->_fft_in_jzz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jzz");
- o->_fft_in_jxz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jxz");
+ o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jxx");
+ o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jzz");
+ o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jxz");
- o->_Jxx = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
- o->_Jzz = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
- o->_Jxz = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
+ o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
+ o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
+ o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
@@ -967,7 +991,7 @@ static void cache_filename(char *string, const char *path, const char *relbase,
BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
- BKE_makepicstring(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
+ BKE_makepicstring_from_type(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
}
/* silly functions but useful to inline when the args do a lot of indirections */
@@ -1076,8 +1100,7 @@ void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, in
}
}
-struct OceanCache *BKE_init_ocean_cache(const char *bakepath, const char *relbase,
- int start, int end, float wave_scale,
+struct OceanCache *BKE_init_ocean_cache(const char *bakepath, const char *relbase, int start, int end, float wave_scale,
float chop_amount, float foam_coverage, float foam_fade, int resolution)
{
OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
@@ -1112,7 +1135,7 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
/* ibufs array is zero based, but filenames are based on frame numbers */
/* still need to clamp frame numbers to valid range of images on disk though */
CLAMP(frame, och->start, och->end);
- f = frame - och->start; // shift to 0 based
+ f = frame - och->start; /* shift to 0 based */
/* if image is already loaded in mem, return */
if (och->ibufs_disp[f] != NULL) return;
@@ -1121,22 +1144,35 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_disp[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_disp[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_foam[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_foam[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_norm[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_norm[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
}
-void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data)
+void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel),
+ void *update_cb_data)
{
/* note: some of these values remain uninitialized unless certain options
* are enabled, take care that BKE_ocean_eval_ij() initializes a member
@@ -1197,13 +1233,13 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
pr = prev_foam[res_x * y + x];
}
- /* r = BLI_frand(); */ /* UNUSED */ // randomly reduce foam
+ /* r = BLI_frand(); */ /* UNUSED */ /* randomly reduce foam */
- //pr = pr * och->foam_fade; // overall fade
+ /* pr = pr * och->foam_fade; */ /* overall fade */
- // remember ocean coord sys is Y up!
- // break up the foam where height (Y) is low (wave valley),
- // and X and Z displacement is greatest
+ /* remember ocean coord sys is Y up!
+ * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest
+ */
#if 0
vec[0] = ocr.disp[0];
@@ -1219,22 +1255,27 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;
- //if (ocr.disp[1] < 0.0 || r > och->foam_fade)
- // pr *= och->foam_fade;
+#if 0
+ if (ocr.disp[1] < 0.0 || r > och->foam_fade)
+ pr *= och->foam_fade;
- //pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
- //pr = pr * neg_disp * neg_eplus;
+ pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
+ pr = pr * neg_disp * neg_eplus;
+#endif
- if (pr < 1.0f) pr *= pr;
+ if (pr < 1.0f)
+ pr *= pr;
pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);
-
- foam_result = pr + ocr.foam;
+ /* A full clamping should not be needed! */
+ foam_result = min_ff(pr + ocr.foam, 1.0f);
prev_foam[res_x * y + x] = foam_result;
+ /*foam_result = min_ff(foam_result, 1.0f); */
+
value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
}
@@ -1279,7 +1320,7 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
och->baked = 1;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* stub */
typedef struct Ocean {
@@ -1297,8 +1338,9 @@ void BKE_ocean_eval_uv(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr)
{
}
-// use catmullrom interpolation rather than linear
-void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u), float UNUSED(v))
+/* use catmullrom interpolation rather than linear */
+void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u),
+ float UNUSED(v))
{
}
@@ -1306,7 +1348,8 @@ void BKE_ocean_eval_xz(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr)
{
}
-void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x), float UNUSED(z))
+void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x),
+ float UNUSED(z))
{
}
@@ -1325,8 +1368,10 @@ struct Ocean *BKE_add_ocean(void)
return oc;
}
-void BKE_init_ocean(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz), float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
- float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field), short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
+void BKE_init_ocean(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz),
+ float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
+ float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field),
+ short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
{
}
@@ -1351,17 +1396,19 @@ void BKE_free_ocean_cache(struct OceanCache *och)
MEM_freeN(och);
}
-void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), float UNUSED(u), float UNUSED(v))
+void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
+ float UNUSED(u), float UNUSED(v))
{
}
-void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), int UNUSED(i), int UNUSED(j))
+void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
+ int UNUSED(i), int UNUSED(j))
{
}
-OceanCache *BKE_init_ocean_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase),
- int UNUSED(start), int UNUSED(end), float UNUSED(wave_scale),
- float UNUSED(chop_amount), float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
+OceanCache *BKE_init_ocean_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase), int UNUSED(start),
+ int UNUSED(end), float UNUSED(wave_scale), float UNUSED(chop_amount),
+ float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
{
OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
@@ -1372,9 +1419,10 @@ void BKE_simulate_ocean_cache(struct OceanCache *UNUSED(och), int UNUSED(frame))
{
}
-void BKE_bake_ocean(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och), void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
+void BKE_bake_ocean(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och),
+ void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
{
/* unused */
(void)update_cb;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
\ No newline at end of file
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index dec49f4..9fab052 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_image_types.h"
+#include "DNA_ID.h"
#include "DNA_sound_types.h"
#include "DNA_vfont_types.h"
#include "DNA_packedFile_types.h"
@@ -226,6 +227,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
return (pf);
}
+/* no libraries for now */
void packAll(Main *bmain, ReportList *reports)
{
Image *ima;
@@ -538,6 +540,51 @@ int unpackImage(ReportList *reports, Image *ima, int how)
return(ret_value);
}
+int unpackLibraries(Main *bmain, ReportList *reports)
+{
+ Library *lib;
+ char *newname;
+ int ret_value = RET_ERROR;
+
+ for (lib = bmain->library.first; lib; lib = lib->id.next) {
+ if (lib->packedfile && lib->name[0]) {
+
+ newname = unpackFile(reports, lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
+ if (newname != NULL) {
+ ret_value = RET_OK;
+
+ printf("Unpacked .blend library: %s\n", newname);
+
+ freePackedFile(lib->packedfile);
+ lib->packedfile = NULL;
+
+ MEM_freeN(newname);
+ }
+ }
+ }
+
+ return(ret_value);
+}
+
+void packLibraries(Main *bmain, ReportList *reports)
+{
+ Library *lib;
+
+ /* test for relativenss */
+ for (lib = bmain->library.first; lib; lib = lib->id.next)
+ if (0 == BLI_path_is_rel(lib->name))
+ break;
+
+ if (lib) {
+ BKE_reportf(reports, RPT_ERROR, "Cannot pack absolute file: '%s'", lib->name);
+ return;
+ }
+
+ for (lib = bmain->library.first; lib; lib = lib->id.next)
+ if (lib->packedfile == NULL)
+ lib->packedfile = newPackedFile(reports, lib->name, bmain->name);
+}
+
void unpackAll(Main *bmain, ReportList *reports, int how)
{
Image *ima;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 36f9604..5847e75 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -154,7 +154,7 @@ int paint_facesel_test(Object *ob)
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
(ob->data != NULL) &&
- (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) &&
+ (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
(ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
);
}
@@ -165,7 +165,7 @@ int paint_vertsel_test(Object *ob)
return ( (ob != NULL) &&
(ob->type == OB_MESH) &&
(ob->data != NULL) &&
- (((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) &&
+ (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
(ob->mode & OB_MODE_WEIGHT_PAINT)
);
}
@@ -212,7 +212,7 @@ int paint_is_face_hidden(const MFace *f, const MVert *mvert)
}
/* returns non-zero if any of the corners of the grid
- * face whose inner corner is at (x,y) are hidden,
+ * face whose inner corner is at (x, y) are hidden,
* zero otherwise */
int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
int gridsize, int x, int y)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 5f5a713..b285196 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -55,7 +55,6 @@
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BLI_linklist.h"
-#include "BLI_bpath.h"
#include "BKE_anim.h"
#include "BKE_animsys.h"
@@ -680,7 +679,7 @@ static float psys_render_projected_area(ParticleSystem *psys, const float center
return area;
}
-void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset)
+void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset)
{
ParticleRenderData *data;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
@@ -1919,7 +1918,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
/* Path Cache */
/************************************************/
-static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[][4], int smooth_start)
+static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
{
float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
float t, dt = 1.f, result[3];
@@ -3351,7 +3350,7 @@ static void key_from_object(Object *ob, ParticleKey *key)
}
#endif
-static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4])
+static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[4][4])
{
float det, w1, w2, d1[2], d2[2];
@@ -3392,7 +3391,7 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat
cross_v3_v3v3(mat[0], mat[1], mat[2]);
}
-static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco)
+static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[4][4], int orco)
{
float v[3][3];
MFace *mface;
@@ -3425,7 +3424,7 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m
triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat);
}
-void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
{
float vec[3];
@@ -3440,7 +3439,7 @@ void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, Pa
copy_v3_v3(hairmat[3], vec);
}
-void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
{
float vec[3], orco[3];
@@ -3462,7 +3461,7 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float vec[3])
mul_mat3_m4_v3(mat, vec);
}
-void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4])
{
float facemat[4][4];
@@ -4502,7 +4501,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part,
psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco, 0);
}
-void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
+void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[4][4], float *scale)
{
Object *ob = sim->ob;
ParticleSystem *psys = sim->psys;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 90889d7..5eac86a 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -23,7 +23,8 @@
* Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn.
*
* Adaptive time step
- * Copyright 2011 AutoCRC
+ * Classical SPH
+ * Copyright 2011-2012 AutoCRC
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -521,9 +522,9 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
vec[0]/=delta[0];
vec[1]/=delta[1];
vec[2]/=delta[2];
- (pa + ((int)(vec[0] * (size[0] - 1)) * res +
- (int)(vec[1] * (size[1] - 1))) * res +
- (int)(vec[2] * (size[2] - 1)))->flag &= ~PARS_UNEXIST;
+ pa[((int)(vec[0] * (size[0] - 1)) * res +
+ (int)(vec[1] * (size[1] - 1))) * res +
+ (int)(vec[2] * (size[2] - 1))].flag &= ~PARS_UNEXIST;
}
}
else if (ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
@@ -1889,7 +1890,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
}
-
if (part->type == PART_HAIR) {
pa->lifetime = 100.0f;
}
@@ -2390,33 +2390,37 @@ typedef struct SPHRangeData {
SPHNeighbor neighbors[SPH_NEIGHBORS];
int tot_neighbors;
- float density, near_density;
- float h;
+ float* data;
ParticleSystem *npsys;
ParticleData *pa;
+ float h;
+ float mass;
float massfac;
int use_size;
} SPHRangeData;
-typedef struct SPHData {
- ParticleSystem *psys[10];
- ParticleData *pa;
- float mass;
- EdgeHash *eh;
- float *gravity;
- /* Average distance to neighbors (other particles in the support domain),
- * for calculating the Courant number (adaptive time step). */
- int pass;
- float element_size;
- float flow[3];
-
- /* Integrator callbacks. This allows different SPH implementations. */
- void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
- void (*density_cb) (void *rangedata_v, int index, float squared_dist);
-} SPHData;
+static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], SPHRangeData *pfr, float interaction_radius, BVHTree_RangeQuery callback)
+{
+ int i;
+
+ pfr->tot_neighbors = 0;
+
+ for (i=0; i < 10 && psys[i]; i++) {
+ pfr->npsys = psys[i];
+ pfr->massfac = psys[i]->part->mass / pfr->mass;
+ pfr->use_size = psys[i]->part->flag & PART_SIZEMASS;
+ if (tree) {
+ BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr);
+ break;
+ }
+ else {
+ BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr);
+ }
+ }
+}
static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
{
SPHRangeData *pfr = (SPHRangeData *)userdata;
@@ -2446,8 +2450,8 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
if (pfr->use_size)
q *= npa->size;
- pfr->density += q*q;
- pfr->near_density += q*q*q;
+ pfr->data[0] += q*q;
+ pfr->data[1] += q*q*q;
}
/*
@@ -2488,7 +2492,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
ParticleSpring *spring = NULL;
SPHRangeData pfr;
SPHNeighbor *pfn;
- float mass = sphdata->mass;
float *gravity = sphdata->gravity;
EdgeHash *springhash = sphdata->eh;
@@ -2498,10 +2501,12 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
float visc = fluid->viscosity_omega;
float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f);
- float inv_mass = 1.0f/mass;
+ float inv_mass = 1.0f / sphdata->mass;
float spring_constant = fluid->spring_k;
-
- float h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*pa->size : 1.f); /* 4.0 seems to be a pretty good value */
+
+ /* 4.0 seems to be a pretty good value */
+ float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f);
+ float h = interaction_radius * sphdata->hfac;
float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); /* 4.77 is an experimentally determined density factor */
float rest_length = fluid->rest_length * (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f);
@@ -2512,24 +2517,24 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
float vec[3];
float vel[3];
float co[3];
+ float data[2];
+ float density, near_density;
int i, spring_index, index = pa - psys[0]->particles;
- pfr.tot_neighbors = 0;
- pfr.density = pfr.near_density = 0.f;
+ data[0] = data[1] = 0;
+ pfr.data = data;
pfr.h = h;
pfr.pa = pa;
+ pfr.mass = sphdata->mass;
- for (i=0; i<10 && psys[i]; i++) {
- pfr.npsys = psys[i];
- pfr.massfac = psys[i]->part->mass*inv_mass;
- pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
+ sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb);
- BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr);
- }
+ density = data[0];
+ near_density = data[1];
- pressure = stiffness * (pfr.density - rest_density);
- near_pressure = stiffness_near_fac * pfr.near_density;
+ pressure = stiffness * (density - rest_density);
+ near_pressure = stiffness_near_fac * near_density;
pfn = pfr.neighbors;
for (i=0; i<pfr.tot_neighbors; i++, pfn++) {
@@ -2593,14 +2598,209 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
/* Artificial buoyancy force in negative gravity direction */
if (fluid->buoyancy > 0.f && gravity)
- madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
+ madd_v3_v3fl(force, gravity, fluid->buoyancy * (density-rest_density));
+
+ if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF)
+ sph_particle_courant(sphdata, &pfr);
+ sphdata->pass++;
+}
+
+/* powf is really slow for raising to integer powers. */
+MINLINE float pow2(float x)
+{
+ return x * x;
+}
+MINLINE float pow3(float x)
+{
+ return pow2(x) * x;
+}
+MINLINE float pow4(float x)
+{
+ return pow2(pow2(x));
+}
+MINLINE float pow7(float x)
+{
+ return pow2(pow3(x)) * x;
+}
+
+static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSED(squared_dist))
+{
+ SPHRangeData *pfr = (SPHRangeData *)userdata;
+ ParticleData *npa = pfr->npsys->particles + index;
+ float q;
+ float qfac = 21.0f / (256.f * (float)M_PI);
+ float rij, rij_h;
+ float vec[3];
+
+ /* Exclude particles that are more than 2h away. Can't use squared_dist here
+ * because it is not accurate enough. Use current state, i.e. the output of
+ * basic_integrate() - z0r */
+ sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co);
+ rij = len_v3(vec);
+ rij_h = rij / pfr->h;
+ if (rij_h > 2.0f)
+ return;
+
+ /* Smoothing factor. Utilise the Wendland kernel. gnuplot:
+ * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x)
+ * plot [0:2] q1(x) */
+ q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h);
+ q *= pfr->npsys->part->mass;
+
+ if (pfr->use_size)
+ q *= pfr->pa->size;
+
+ pfr->data[0] += q;
+ pfr->data[1] += q / npa->sphdensity;
+}
+
+static void sphclassical_neighbour_accum_cb(void *userdata, int index, float UNUSED(squared_dist))
+{
+ SPHRangeData *pfr = (SPHRangeData *)userdata;
+ ParticleData *npa = pfr->npsys->particles + index;
+ float rij, rij_h;
+ float vec[3];
+
+ if (pfr->tot_neighbors >= SPH_NEIGHBORS)
+ return;
+
+ /* Exclude particles that are more than 2h away. Can't use squared_dist here
+ * because it is not accurate enough. Use current state, i.e. the output of
+ * basic_integrate() - z0r */
+ sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co);
+ rij = len_v3(vec);
+ rij_h = rij / pfr->h;
+ if (rij_h > 2.0f)
+ return;
+
+ pfr->neighbors[pfr->tot_neighbors].index = index;
+ pfr->neighbors[pfr->tot_neighbors].psys = pfr->npsys;
+ pfr->tot_neighbors++;
+}
+static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse))
+{
+ SPHData *sphdata = (SPHData *)sphdata_v;
+ ParticleSystem **psys = sphdata->psys;
+ ParticleData *pa = sphdata->pa;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ SPHRangeData pfr;
+ SPHNeighbor *pfn;
+ float *gravity = sphdata->gravity;
+
+ float dq, u, rij, dv[3];
+ float pressure, npressure;
+
+ float visc = fluid->viscosity_omega;
+
+ float interaction_radius;
+ float h, hinv;
+ /* 4.77 is an experimentally determined density factor */
+ float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f);
+
+ // Use speed of sound squared
+ float stiffness = pow2(fluid->stiffness_k);
+
+ ParticleData *npa;
+ float vec[3];
+ float co[3];
+ float pressureTerm;
+
+ int i;
+
+ float qfac2 = 42.0f / (256.0f * (float)M_PI);
+ float rij_h;
+
+ /* 4.0 here is to be consistent with previous formulation/interface */
+ interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f);
+ h = interaction_radius * sphdata->hfac;
+ hinv = 1.0f / h;
+
+ pfr.h = h;
+ pfr.pa = pa;
+
+ sph_evaluate_func(NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbour_accum_cb);
+ pressure = stiffness * (pow7(pa->sphdensity / rest_density) - 1.0f);
+
+ /* multiply by mass so that we return a force, not accel */
+ qfac2 *= sphdata->mass / pow3(pfr.h);
+
+ pfn = pfr.neighbors;
+ for (i = 0; i < pfr.tot_neighbors; i++, pfn++) {
+ npa = pfn->psys->particles + pfn->index;
+ if (npa == pa) {
+ /* we do not contribute to ourselves */
+ continue;
+ }
+
+ /* Find vector to neighbour. Exclude particles that are more than 2h
+ * away. Can't use current state here because it may have changed on
+ * another thread - so do own mini integration. Unlike basic_integrate,
+ * SPH integration depends on neighbouring particles. - z0r */
+ madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time);
+ sub_v3_v3v3(vec, co, state->co);
+ rij = normalize_v3(vec);
+ rij_h = rij / pfr.h;
+ if (rij_h > 2.0f)
+ continue;
+
+ npressure = stiffness * (pow7(npa->sphdensity / rest_density) - 1.0f);
+
+ /* First derivative of smoothing factor. Utilise the Wendland kernel.
+ * gnuplot:
+ * q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x)
+ * plot [0:2] q2(x)
+ * Particles > 2h away are excluded above. */
+ dq = qfac2 * (2.0f * pow4(2.0f - rij_h) - 4.0f * pow3(2.0f - rij_h) * (1.0f + 2.0f * rij_h) );
+
+ if (pfn->psys->part->flag & PART_SIZEMASS)
+ dq *= npa->size;
+
+ pressureTerm = pressure / pow2(pa->sphdensity) + npressure / pow2(npa->sphdensity);
+
+ /* Note that 'minus' is removed, because vec = vecBA, not vecAB.
+ * This applies to the viscosity calculation below, too. */
+ madd_v3_v3fl(force, vec, pressureTerm * dq);
+
+ /* Viscosity */
+ if (visc > 0.0f) {
+ sub_v3_v3v3(dv, npa->prev_state.vel, pa->prev_state.vel);
+ u = dot_v3v3(vec, dv);
+ /* Apply parameters */
+ u *= -dq * hinv * visc / (0.5f * npa->sphdensity + 0.5f * pa->sphdensity);
+ madd_v3_v3fl(force, vec, u);
+ }
+ }
+
+ /* Artificial buoyancy force in negative gravity direction */
+ if (fluid->buoyancy > 0.f && gravity)
+ madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density));
if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF)
sph_particle_courant(sphdata, &pfr);
sphdata->pass++;
}
-static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata)
+static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata)
+{
+ ParticleSystem **psys = sphdata->psys;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ /* 4.0 seems to be a pretty good value */
+ float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f);
+ SPHRangeData pfr;
+ float data[2];
+
+ data[0] = 0;
+ data[1] = 0;
+ pfr.data = data;
+ pfr.h = interaction_radius * sphdata->hfac;
+ pfr.pa = pa;
+ pfr.mass = sphdata->mass;
+
+ sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb);
+ pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f);
+}
+
+void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata)
{
ParticleTarget *pt;
int i;
@@ -2621,17 +2821,47 @@ static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata)
sphdata->pa = NULL;
sphdata->mass = 1.0f;
- sphdata->force_cb = sph_force_cb;
- sphdata->density_cb = sph_density_accum_cb;
+ if (sim->psys->part->fluid->solver == SPH_SOLVER_DDR) {
+ sphdata->force_cb = sph_force_cb;
+ sphdata->density_cb = sph_density_accum_cb;
+ sphdata->hfac = 1.0f;
+ }
+ else {
+ /* SPH_SOLVER_CLASSICAL */
+ sphdata->force_cb = sphclassical_force_cb;
+ sphdata->density_cb = sphclassical_density_accum_cb;
+ sphdata->hfac = 0.5f;
+ }
+
}
-static void sph_solver_finalise(SPHData *sphdata)
+void psys_sph_finalise(SPHData *sphdata)
{
if (sphdata->eh) {
BLI_edgehash_free(sphdata->eh, NULL);
sphdata->eh = NULL;
}
}
+/* Sample the density field at a point in space. */
+void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2])
+{
+ ParticleSystem **psys = sphdata->psys;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ /* 4.0 seems to be a pretty good value */
+ float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f);
+ SPHRangeData pfr;
+ float density[2];
+
+ density[0] = density[1] = 0.0f;
+ pfr.data = density;
+ pfr.h = interaction_radius * sphdata->hfac;
+ pfr.mass = sphdata->mass;
+
+ sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb);
+
+ vars[0] = pfr.data[0];
+ vars[1] = pfr.data[1];
+}
static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata)
{
@@ -3781,18 +4011,19 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
/* Code for an adaptive time step based on the Courant-Friedrichs-Lewy
* condition. */
-#define MIN_TIMESTEP 1.0f / 101.0f
+static const float MIN_TIMESTEP = 1.0f / 101.0f;
/* Tolerance of 1.5 means the last subframe neither favors growing nor
* shrinking (e.g if it were 1.3, the last subframe would tend to be too
* small). */
-#define TIMESTEP_EXPANSION_TOLERANCE 1.5f
+static const float TIMESTEP_EXPANSION_FACTOR = 0.1f;
+static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f;
/* Calculate the speed of the particle relative to the local scale of the
* simulation. This should be called once per particle during a simulation
* step, after the velocity has been updated. element_size defines the scale of
* the simulation, and is typically the distance to neighboring particles. */
static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
- float dtime, SPHData *sphdata)
+ float dtime, SPHData *sphdata)
{
float relative_vel[3];
float speed;
@@ -3802,14 +4033,31 @@ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
if (sim->courant_num < speed * dtime / sphdata->element_size)
sim->courant_num = speed * dtime / sphdata->element_size;
}
+static float get_base_time_step(ParticleSettings *part)
+{
+ return 1.0f / (float) (part->subframes + 1);
+}
/* Update time step size to suit current conditions. */
static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac)
{
+ float dt_target;
if (sim->courant_num == 0.0f)
- psys->dt_frac = 1.0f;
+ dt_target = 1.0f;
+ else
+ dt_target = psys->dt_frac * (psys->part->courant_target / sim->courant_num);
+
+ /* Make sure the time step is reasonable. For some reason, the CLAMP macro
+ * doesn't work here. The time step becomes too large. - z0r */
+ if (dt_target < MIN_TIMESTEP)
+ dt_target = MIN_TIMESTEP;
+ else if (dt_target > get_base_time_step(psys->part))
+ dt_target = get_base_time_step(psys->part);
+
+ /* Decrease time step instantly, but increase slowly. */
+ if (dt_target > psys->dt_frac)
+ psys->dt_frac = interpf(dt_target, psys->dt_frac, TIMESTEP_EXPANSION_FACTOR);
else
- psys->dt_frac *= (psys->part->courant_target / sim->courant_num);
- CLAMP(psys->dt_frac, MIN_TIMESTEP, 1.0f);
+ psys->dt_frac = dt_target;
/* Sync with frame end if it's close. */
if (t_frac == 1.0f)
@@ -3973,31 +4221,72 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
case PART_PHYS_FLUID:
{
SPHData sphdata;
- sph_solver_init(sim, &sphdata);
+ ParticleSettings *part = sim->psys->part;
+ psys_sph_init(sim, &sphdata);
- #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
- LOOP_DYNAMIC_PARTICLES {
- /* do global forces & effectors */
- basic_integrate(sim, p, pa->state.time, cfra);
+ if (part->fluid->solver == SPH_SOLVER_DDR) {
+ /* Apply SPH forces using double-density relaxation algorithm
+ * (Clavat et. al.) */
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ /* do global forces & effectors */
+ basic_integrate(sim, p, pa->state.time, cfra);
- /* actual fluids calculations */
- sph_integrate(sim, pa, pa->state.time, &sphdata);
+ /* actual fluids calculations */
+ sph_integrate(sim, pa, pa->state.time, &sphdata);
- if (sim->colliders)
- collision_check(sim, p, pa->state.time, cfra);
-
- /* SPH particles are not physical particles, just interpolation
- * particles, thus rotation has not a direct sense for them */
- basic_rotate(part, pa, pa->state.time, timestep);
+ if (sim->colliders)
+ collision_check(sim, p, pa->state.time, cfra);
+
+ /* SPH particles are not physical particles, just interpolation
+ * particles, thus rotation has not a direct sense for them */
+ basic_rotate(part, pa, pa->state.time, timestep);
+
+ #pragma omp critical
+ if (part->time_flag & PART_TIME_AUTOSF)
+ update_courant_num(sim, pa, dtime, &sphdata);
+ }
+
+ sph_springs_modify(psys, timestep);
- #pragma omp critical
- if (part->time_flag & PART_TIME_AUTOSF)
- update_courant_num(sim, pa, dtime, &sphdata);
}
+ else {
+ /* SPH_SOLVER_CLASSICAL */
+ /* Apply SPH forces using classical algorithm (due to Gingold
+ * and Monaghan). Note that, unlike double-density relaxation,
+ * this algorthim is separated into distinct loops. */
+
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ basic_integrate(sim, p, pa->state.time, cfra);
+ }
+
+ /* calculate summation density */
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ sphclassical_calc_dens(pa, pa->state.time, &sphdata);
+ }
+
+ /* do global forces & effectors */
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
+ LOOP_DYNAMIC_PARTICLES {
+ /* actual fluids calculations */
+ sph_integrate(sim, pa, pa->state.time, &sphdata);
+
+ if (sim->colliders)
+ collision_check(sim, p, pa->state.time, cfra);
+
+ /* SPH particles are not physical particles, just interpolation
+ * particles, thus rotation has not a direct sense for them */
+ basic_rotate(part, pa, pa->state.time, timestep);
- sph_springs_modify(psys, timestep);
+ #pragma omp critical
+ if (part->time_flag & PART_TIME_AUTOSF)
+ update_courant_num(sim, pa, dtime, &sphdata);
+ }
+ }
- sph_solver_finalise(&sphdata);
+ psys_sph_finalise(&sphdata);
break;
}
}
@@ -4309,14 +4598,14 @@ static void system_step(ParticleSimulationData *sim, float cfra)
if (!(part->time_flag & PART_TIME_AUTOSF)) {
/* Constant time step */
- psys->dt_frac = 1.0f / (float) (part->subframes + 1);
+ psys->dt_frac = get_base_time_step(part);
}
else if ((int)cfra == startframe) {
- /* Variable time step; use a very conservative value at the start.
- * If it doesn't need to be so small, it will quickly grow. */
- psys->dt_frac = 1.0;
+ /* Variable time step; initialise to subframes */
+ psys->dt_frac = get_base_time_step(part);
}
else if (psys->dt_frac < MIN_TIMESTEP) {
+ /* Variable time step; subsequent frames */
psys->dt_frac = MIN_TIMESTEP;
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
new file mode 100644
index 0000000..2df2dd6
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -0,0 +1,1877 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/pbvh.c
+ * \ingroup bli
+ */
+
+#include "DNA_meshdata_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_bitmap.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "BKE_pbvh.h"
+#include "BKE_ccg.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
+#include "BKE_global.h" /* for BKE_mesh_calc_normals */
+#include "BKE_paint.h"
+#include "BKE_subsurf.h"
+
+#include "GPU_buffers.h"
+
+#include "pbvh_intern.h"
+
+#define LEAF_LIMIT 10000
+
+//#define PERFCNTRS
+
+#define STACK_FIXED_DEPTH 100
+
+typedef struct PBVHStack {
+ PBVHNode *node;
+ int revisiting;
+} PBVHStack;
+
+typedef struct PBVHIter {
+ PBVH *bvh;
+ BKE_pbvh_SearchCallback scb;
+ void *search_data;
+
+ PBVHStack *stack;
+ int stacksize;
+
+ PBVHStack stackfixed[STACK_FIXED_DEPTH];
+ int stackspace;
+} PBVHIter;
+
+void BB_reset(BB *bb)
+{
+ bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
+ bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
+}
+
+/* Expand the bounding box to include a new coordinate */
+void BB_expand(BB *bb, const float co[3])
+{
+ int i;
+ for (i = 0; i < 3; ++i) {
+ bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
+ bb->bmax[i] = max_ff(bb->bmax[i], co[i]);
+ }
+}
+
+/* Expand the bounding box to include another bounding box */
+void BB_expand_with_bb(BB *bb, BB *bb2)
+{
+ int i;
+ for (i = 0; i < 3; ++i) {
+ bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
+ bb->bmax[i] = max_ff(bb->bmax[i], bb2->bmax[i]);
+ }
+}
+
+/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
+int BB_widest_axis(const BB *bb)
+{
+ float dim[3];
+ int i;
+
+ for (i = 0; i < 3; ++i)
+ dim[i] = bb->bmax[i] - bb->bmin[i];
+
+ if (dim[0] > dim[1]) {
+ if (dim[0] > dim[2])
+ return 0;
+ else
+ return 2;
+ }
+ else {
+ if (dim[1] > dim[2])
+ return 1;
+ else
+ return 2;
+ }
+}
+
+void BBC_update_centroid(BBC *bbc)
+{
+ int i;
+ for (i = 0; i < 3; ++i)
+ bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
+}
+
+/* Not recursive */
+static void update_node_vb(PBVH *bvh, PBVHNode *node)
+{
+ BB vb;
+
+ BB_reset(&vb);
+
+ if (node->flag & PBVH_Leaf) {
+ PBVHVertexIter vd;
+
+ BKE_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL)
+ {
+ BB_expand(&vb, vd.co);
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+ else {
+ BB_expand_with_bb(&vb,
+ &bvh->nodes[node->children_offset].vb);
+ BB_expand_with_bb(&vb,
+ &bvh->nodes[node->children_offset + 1].vb);
+ }
+
+ node->vb = vb;
+}
+
+//void BKE_pbvh_node_BB_reset(PBVHNode *node)
+//{
+// BB_reset(&node->vb);
+//}
+//
+//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3])
+//{
+// BB_expand(&node->vb, co);
+//}
+
+static int face_materials_match(const MFace *f1, const MFace *f2)
+{
+ return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
+ (f1->mat_nr == f2->mat_nr));
+}
+
+static int grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2)
+{
+ return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
+ (f1->mat_nr == f2->mat_nr));
+}
+
+/* Adapted from BLI_kdopbvh.c */
+/* Returns the index of the first element on the right of the partition */
+static int partition_indices(int *prim_indices, int lo, int hi, int axis,
+ float mid, BBC *prim_bbc)
+{
+ int i = lo, j = hi;
+ for (;; ) {
+ for (; prim_bbc[prim_indices[i]].bcentroid[axis] < mid; i++) ;
+ for (; mid < prim_bbc[prim_indices[j]].bcentroid[axis]; j--) ;
+
+ if (!(i < j))
+ return i;
+
+ SWAP(int, prim_indices[i], prim_indices[j]);
+ i++;
+ }
+}
+
+/* Returns the index of the first element on the right of the partition */
+static int partition_indices_material(PBVH *bvh, int lo, int hi)
+{
+ const MFace *faces = bvh->faces;
+ const DMFlagMat *flagmats = bvh->grid_flag_mats;
+ const int *indices = bvh->prim_indices;
+ const void *first;
+ int i = lo, j = hi;
+
+ if (bvh->faces)
+ first = &faces[bvh->prim_indices[lo]];
+ else
+ first = &flagmats[bvh->prim_indices[lo]];
+
+ for (;; ) {
+ if (bvh->faces) {
+ for (; face_materials_match(first, &faces[indices[i]]); i++) ;
+ for (; !face_materials_match(first, &faces[indices[j]]); j--) ;
+ }
+ else {
+ for (; grid_materials_match(first, &flagmats[indices[i]]); i++) ;
+ for (; !grid_materials_match(first, &flagmats[indices[j]]); j--) ;
+ }
+
+ if (!(i < j))
+ return i;
+
+ SWAP(int, bvh->prim_indices[i], bvh->prim_indices[j]);
+ i++;
+ }
+}
+
+void pbvh_grow_nodes(PBVH *bvh, int totnode)
+{
+ if (totnode > bvh->node_mem_count) {
+ PBVHNode *prev = bvh->nodes;
+ bvh->node_mem_count *= 1.33;
+ if (bvh->node_mem_count < totnode)
+ bvh->node_mem_count = totnode;
+ bvh->nodes = MEM_callocN(sizeof(PBVHNode) * bvh->node_mem_count,
+ "bvh nodes");
+ memcpy(bvh->nodes, prev, bvh->totnode * sizeof(PBVHNode));
+ MEM_freeN(prev);
+ }
+
+ bvh->totnode = totnode;
+}
+
+/* Add a vertex to the map, with a positive value for unique vertices and
+ * a negative value for additional vertices */
+static int map_insert_vert(PBVH *bvh, GHash *map,
+ unsigned int *face_verts,
+ unsigned int *uniq_verts, int vertex)
+{
+ void *value, *key = SET_INT_IN_POINTER(vertex);
+
+ if (!BLI_ghash_haskey(map, key)) {
+ if (BLI_BITMAP_GET(bvh->vert_bitmap, vertex)) {
+ value = SET_INT_IN_POINTER(~(*face_verts));
+ ++(*face_verts);
+ }
+ else {
+ BLI_BITMAP_SET(bvh->vert_bitmap, vertex);
+ value = SET_INT_IN_POINTER(*uniq_verts);
+ ++(*uniq_verts);
+ }
+
+ BLI_ghash_insert(map, key, value);
+ return GET_INT_FROM_POINTER(value);
+ }
+ else
+ return GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
+}
+
+/* Find vertices used by the faces in this node and update the draw buffers */
+static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
+{
+ GHashIterator *iter;
+ GHash *map;
+ int i, j, totface;
+
+ map = BLI_ghash_int_new("build_mesh_leaf_node gh");
+
+ node->uniq_verts = node->face_verts = 0;
+ totface = node->totprim;
+
+ node->face_vert_indices = MEM_callocN(sizeof(int) * 4 * totface,
+ "bvh node face vert indices");
+
+ for (i = 0; i < totface; ++i) {
+ MFace *f = bvh->faces + node->prim_indices[i];
+ int sides = f->v4 ? 4 : 3;
+
+ for (j = 0; j < sides; ++j) {
+ node->face_vert_indices[i][j] =
+ map_insert_vert(bvh, map, &node->face_verts,
+ &node->uniq_verts, (&f->v1)[j]);
+ }
+ }
+
+ node->vert_indices = MEM_callocN(sizeof(int) *
+ (node->uniq_verts + node->face_verts),
+ "bvh node vert indices");
+
+ /* Build the vertex list, unique verts first */
+ for (iter = BLI_ghashIterator_new(map), i = 0;
+ BLI_ghashIterator_isDone(iter) == FALSE;
+ BLI_ghashIterator_step(iter), ++i)
+ {
+ void *value = BLI_ghashIterator_getValue(iter);
+ int ndx = GET_INT_FROM_POINTER(value);
+
+ if (ndx < 0)
+ ndx = -ndx + node->uniq_verts - 1;
+
+ node->vert_indices[ndx] =
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(iter));
+ }
+
+ BLI_ghashIterator_free(iter);
+
+ for (i = 0; i < totface; ++i) {
+ MFace *f = bvh->faces + node->prim_indices[i];
+ int sides = f->v4 ? 4 : 3;
+
+ for (j = 0; j < sides; ++j) {
+ if (node->face_vert_indices[i][j] < 0)
+ node->face_vert_indices[i][j] =
+ -node->face_vert_indices[i][j] +
+ node->uniq_verts - 1;
+ }
+ }
+
+ if (!G.background) {
+ node->draw_buffers =
+ GPU_build_mesh_buffers(node->face_vert_indices,
+ bvh->faces, bvh->verts,
+ node->prim_indices,
+ node->totprim);
+ }
+
+ node->flag |= PBVH_UpdateDrawBuffers;
+
+ BLI_ghash_free(map, NULL, NULL);
+}
+
+static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
+{
+ if (!G.background) {
+ node->draw_buffers =
+ GPU_build_grid_buffers(node->prim_indices,
+ node->totprim, bvh->grid_hidden, bvh->gridkey.grid_size);
+ }
+ node->flag |= PBVH_UpdateDrawBuffers;
+}
+
+static void update_vb(PBVH *bvh, PBVHNode *node, BBC *prim_bbc,
+ int offset, int count)
+{
+ int i;
+
+ BB_reset(&node->vb);
+ for (i = offset + count - 1; i >= offset; --i) {
+ BB_expand_with_bb(&node->vb, (BB *)(&prim_bbc[bvh->prim_indices[i]]));
+ }
+ node->orig_vb = node->vb;
+}
+
+static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
+ int offset, int count)
+{
+ bvh->nodes[node_index].flag |= PBVH_Leaf;
+
+ bvh->nodes[node_index].prim_indices = bvh->prim_indices + offset;
+ bvh->nodes[node_index].totprim = count;
+
+ /* Still need vb for searches */
+ update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
+
+ if (bvh->faces)
+ build_mesh_leaf_node(bvh, bvh->nodes + node_index);
+ else
+ build_grids_leaf_node(bvh, bvh->nodes + node_index);
+}
+
+/* Return zero if all primitives in the node can be drawn with the
+ * same material (including flat/smooth shading), non-zerootherwise */
+static int leaf_needs_material_split(PBVH *bvh, int offset, int count)
+{
+ int i, prim;
+
+ if (count <= 1)
+ return 0;
+
+ if (bvh->faces) {
+ const MFace *first = &bvh->faces[bvh->prim_indices[offset]];
+
+ for (i = offset + count - 1; i > offset; --i) {
+ prim = bvh->prim_indices[i];
+ if (!face_materials_match(first, &bvh->faces[prim]))
+ return 1;
+ }
+ }
+ else {
+ const DMFlagMat *first = &bvh->grid_flag_mats[bvh->prim_indices[offset]];
+
+ for (i = offset + count - 1; i > offset; --i) {
+ prim = bvh->prim_indices[i];
+ if (!grid_materials_match(first, &bvh->grid_flag_mats[prim]))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Recursively build a node in the tree
+ *
+ * vb is the voxel box around all of the primitives contained in
+ * this node.
+ *
+ * cb is the bounding box around all the centroids of the primitives
+ * contained in this node
+ *
+ * offset and start indicate a range in the array of primitive indices
+ */
+
+static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
+ int offset, int count)
+{
+ int i, axis, end, below_leaf_limit;
+ BB cb_backing;
+
+ /* Decide whether this is a leaf or not */
+ below_leaf_limit = count <= bvh->leaf_limit;
+ if (below_leaf_limit) {
+ if (!leaf_needs_material_split(bvh, offset, count)) {
+ build_leaf(bvh, node_index, prim_bbc, offset, count);
+ return;
+ }
+ }
+
+ /* Add two child nodes */
+ bvh->nodes[node_index].children_offset = bvh->totnode;
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
+
+ /* Update parent node bounding box */
+ update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
+
+ if (!below_leaf_limit) {
+ /* Find axis with widest range of primitive centroids */
+ if (!cb) {
+ cb = &cb_backing;
+ BB_reset(cb);
+ for (i = offset + count - 1; i >= offset; --i)
+ BB_expand(cb, prim_bbc[bvh->prim_indices[i]].bcentroid);
+ }
+ axis = BB_widest_axis(cb);
+
+ /* Partition primitives along that axis */
+ end = partition_indices(bvh->prim_indices,
+ offset, offset + count - 1,
+ axis,
+ (cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
+ prim_bbc);
+ }
+ else {
+ /* Partition primitives by material */
+ end = partition_indices_material(bvh, offset, offset + count - 1);
+ }
+
+ /* Build children */
+ build_sub(bvh, bvh->nodes[node_index].children_offset, NULL,
+ prim_bbc, offset, end - offset);
+ build_sub(bvh, bvh->nodes[node_index].children_offset + 1, NULL,
+ prim_bbc, end, offset + count - end);
+}
+
+static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
+{
+ int i;
+
+ if (totprim != bvh->totprim) {
+ bvh->totprim = totprim;
+ if (bvh->nodes) MEM_freeN(bvh->nodes);
+ if (bvh->prim_indices) MEM_freeN(bvh->prim_indices);
+ bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
+ "bvh prim indices");
+ for (i = 0; i < totprim; ++i)
+ bvh->prim_indices[i] = i;
+ bvh->totnode = 0;
+ if (bvh->node_mem_count < 100) {
+ bvh->node_mem_count = 100;
+ bvh->nodes = MEM_callocN(sizeof(PBVHNode) *
+ bvh->node_mem_count,
+ "bvh initial nodes");
+ }
+ }
+
+ bvh->totnode = 1;
+ build_sub(bvh, 0, cb, prim_bbc, 0, totprim);
+}
+
+/* Do a full rebuild with on Mesh data structure */
+void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
+{
+ BBC *prim_bbc = NULL;
+ BB cb;
+ int i, j;
+
+ bvh->type = PBVH_FACES;
+ bvh->faces = faces;
+ bvh->verts = verts;
+ bvh->vert_bitmap = BLI_BITMAP_NEW(totvert, "bvh->vert_bitmap");
+ bvh->totvert = totvert;
+ bvh->leaf_limit = LEAF_LIMIT;
+ bvh->vdata = vdata;
+
+ BB_reset(&cb);
+
+ /* For each face, store the AABB and the AABB centroid */
+ prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
+
+ for (i = 0; i < totface; ++i) {
+ MFace *f = faces + i;
+ const int sides = f->v4 ? 4 : 3;
+ BBC *bbc = prim_bbc + i;
+
+ BB_reset((BB *)bbc);
+
+ for (j = 0; j < sides; ++j)
+ BB_expand((BB *)bbc, verts[(&f->v1)[j]].co);
+
+ BBC_update_centroid(bbc);
+
+ BB_expand(&cb, bbc->bcentroid);
+ }
+
+ if (totface)
+ pbvh_build(bvh, &cb, prim_bbc, totface);
+
+ MEM_freeN(prim_bbc);
+ MEM_freeN(bvh->vert_bitmap);
+}
+
+/* Do a full rebuild with on Grids data structure */
+void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
+ int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
+{
+ BBC *prim_bbc = NULL;
+ BB cb;
+ int gridsize = key->grid_size;
+ int i, j;
+
+ bvh->type = PBVH_GRIDS;
+ bvh->grids = grids;
+ bvh->gridadj = gridadj;
+ bvh->gridfaces = gridfaces;
+ bvh->grid_flag_mats = flagmats;
+ bvh->totgrid = totgrid;
+ bvh->gridkey = *key;
+ bvh->grid_hidden = grid_hidden;
+ bvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
+
+ BB_reset(&cb);
+
+ /* For each grid, store the AABB and the AABB centroid */
+ prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
+
+ for (i = 0; i < totgrid; ++i) {
+ CCGElem *grid = grids[i];
+ BBC *bbc = prim_bbc + i;
+
+ BB_reset((BB *)bbc);
+
+ for (j = 0; j < gridsize * gridsize; ++j)
+ BB_expand((BB *)bbc, CCG_elem_offset_co(key, grid, j));
+
+ BBC_update_centroid(bbc);
+
+ BB_expand(&cb, bbc->bcentroid);
+ }
+
+ if (totgrid)
+ pbvh_build(bvh, &cb, prim_bbc, totgrid);
+
+ MEM_freeN(prim_bbc);
+}
+
+PBVH *BKE_pbvh_new(void)
+{
+ PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
+
+ return bvh;
+}
+
+void BKE_pbvh_free(PBVH *bvh)
+{
+ PBVHNode *node;
+ int i;
+
+ for (i = 0; i < bvh->totnode; ++i) {
+ node = &bvh->nodes[i];
+
+ if (node->flag & PBVH_Leaf) {
+ if (node->draw_buffers)
+ GPU_free_buffers(node->draw_buffers);
+ if (node->vert_indices)
+ MEM_freeN(node->vert_indices);
+ if (node->face_vert_indices)
+ MEM_freeN(node->face_vert_indices);
+ BKE_pbvh_node_layer_disp_free(node);
+
+ if (node->bm_faces)
+ BLI_ghash_free(node->bm_faces, NULL, NULL);
+ if (node->bm_unique_verts)
+ BLI_ghash_free(node->bm_unique_verts, NULL, NULL);
+ if (node->bm_other_verts)
+ BLI_ghash_free(node->bm_other_verts, NULL, NULL);
+ }
+ }
+
+ if (bvh->deformed) {
+ if (bvh->verts) {
+ /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
+
+ MEM_freeN(bvh->verts);
+ if (bvh->faces)
+ MEM_freeN(bvh->faces);
+ }
+ }
+
+ if (bvh->nodes)
+ MEM_freeN(bvh->nodes);
+
+ if (bvh->prim_indices)
+ MEM_freeN(bvh->prim_indices);
+
+ if (bvh->bm_vert_to_node)
+ BLI_ghash_free(bvh->bm_vert_to_node, NULL, NULL);
+ if (bvh->bm_face_to_node)
+ BLI_ghash_free(bvh->bm_face_to_node, NULL, NULL);
+
+ MEM_freeN(bvh);
+}
+
+static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BKE_pbvh_SearchCallback scb, void *search_data)
+{
+ iter->bvh = bvh;
+ iter->scb = scb;
+ iter->search_data = search_data;
+
+ iter->stack = iter->stackfixed;
+ iter->stackspace = STACK_FIXED_DEPTH;
+
+ iter->stack[0].node = bvh->nodes;
+ iter->stack[0].revisiting = 0;
+ iter->stacksize = 1;
+}
+
+static void pbvh_iter_end(PBVHIter *iter)
+{
+ if (iter->stackspace > STACK_FIXED_DEPTH)
+ MEM_freeN(iter->stack);
+}
+
+static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, int revisiting)
+{
+ if (iter->stacksize == iter->stackspace) {
+ PBVHStack *newstack;
+
+ iter->stackspace *= 2;
+ newstack = MEM_callocN(sizeof(PBVHStack) * iter->stackspace, "PBVHStack");
+ memcpy(newstack, iter->stack, sizeof(PBVHStack) * iter->stacksize);
+
+ if (iter->stackspace > STACK_FIXED_DEPTH)
+ MEM_freeN(iter->stack);
+ iter->stack = newstack;
+ }
+
+ iter->stack[iter->stacksize].node = node;
+ iter->stack[iter->stacksize].revisiting = revisiting;
+ iter->stacksize++;
+}
+
+static PBVHNode *pbvh_iter_next(PBVHIter *iter)
+{
+ PBVHNode *node;
+ int revisiting;
+
+ /* purpose here is to traverse tree, visiting child nodes before their
+ * parents, this order is necessary for e.g. computing bounding boxes */
+
+ while (iter->stacksize) {
+ /* pop node */
+ iter->stacksize--;
+ node = iter->stack[iter->stacksize].node;
+
+ /* on a mesh with no faces this can happen
+ * can remove this check if we know meshes have at least 1 face */
+ if (node == NULL)
+ return NULL;
+
+ revisiting = iter->stack[iter->stacksize].revisiting;
+
+ /* revisiting node already checked */
+ if (revisiting)
+ return node;
+
+ if (iter->scb && !iter->scb(node, iter->search_data))
+ continue; /* don't traverse, outside of search zone */
+
+ if (node->flag & PBVH_Leaf) {
+ /* immediately hit leaf node */
+ return node;
+ }
+ else {
+ /* come back later when children are done */
+ pbvh_stack_push(iter, node, 1);
+
+ /* push two child nodes on the stack */
+ pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
+ pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
+ }
+ }
+
+ return NULL;
+}
+
+static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
+{
+ PBVHNode *node;
+
+ while (iter->stacksize) {
+ /* pop node */
+ iter->stacksize--;
+ node = iter->stack[iter->stacksize].node;
+
+ /* on a mesh with no faces this can happen
+ * can remove this check if we know meshes have at least 1 face */
+ if (node == NULL) return NULL;
+
+ if (iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
+
+ if (node->flag & PBVH_Leaf) {
+ /* immediately hit leaf node */
+ return node;
+ }
+ else {
+ pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
+ pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
+ }
+ }
+
+ return NULL;
+}
+
+void BKE_pbvh_search_gather(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ PBVHNode ***r_array, int *r_tot)
+{
+ PBVHIter iter;
+ PBVHNode **array = NULL, **newarray, *node;
+ int tot = 0, space = 0;
+
+ pbvh_iter_begin(&iter, bvh, scb, search_data);
+
+ while ((node = pbvh_iter_next(&iter))) {
+ if (node->flag & PBVH_Leaf) {
+ if (tot == space) {
+ /* resize array if needed */
+ space = (tot == 0) ? 32 : space * 2;
+ newarray = MEM_callocN(sizeof(PBVHNode) * space, "PBVHNodeSearch");
+
+ if (array) {
+ memcpy(newarray, array, sizeof(PBVHNode) * tot);
+ MEM_freeN(array);
+ }
+
+ array = newarray;
+ }
+
+ array[tot] = node;
+ tot++;
+ }
+ }
+
+ pbvh_iter_end(&iter);
+
+ if (tot == 0 && array) {
+ MEM_freeN(array);
+ array = NULL;
+ }
+
+ *r_array = array;
+ *r_tot = tot;
+}
+
+void BKE_pbvh_search_callback(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitCallback hcb, void *hit_data)
+{
+ PBVHIter iter;
+ PBVHNode *node;
+
+ pbvh_iter_begin(&iter, bvh, scb, search_data);
+
+ while ((node = pbvh_iter_next(&iter)))
+ if (node->flag & PBVH_Leaf)
+ hcb(node, hit_data);
+
+ pbvh_iter_end(&iter);
+}
+
+typedef struct node_tree {
+ PBVHNode *data;
+
+ struct node_tree *left;
+ struct node_tree *right;
+} node_tree;
+
+static void node_tree_insert(node_tree *tree, node_tree *new_node)
+{
+ if (new_node->data->tmin < tree->data->tmin) {
+ if (tree->left) {
+ node_tree_insert(tree->left, new_node);
+ }
+ else {
+ tree->left = new_node;
+ }
+ }
+ else {
+ if (tree->right) {
+ node_tree_insert(tree->right, new_node);
+ }
+ else {
+ tree->right = new_node;
+ }
+ }
+}
+
+static void traverse_tree(node_tree *tree, BKE_pbvh_HitOccludedCallback hcb, void *hit_data, float *tmin)
+{
+ if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
+
+ hcb(tree->data, hit_data, tmin);
+
+ if (tree->right) traverse_tree(tree->right, hcb, hit_data, tmin);
+}
+
+static void free_tree(node_tree *tree)
+{
+ if (tree->left) {
+ free_tree(tree->left);
+ tree->left = 0;
+ }
+
+ if (tree->right) {
+ free_tree(tree->right);
+ tree->right = 0;
+ }
+
+ free(tree);
+}
+
+float BKE_pbvh_node_get_tmin(PBVHNode *node)
+{
+ return node->tmin;
+}
+
+static void BKE_pbvh_search_callback_occluded(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitOccludedCallback hcb, void *hit_data)
+{
+ PBVHIter iter;
+ PBVHNode *node;
+ node_tree *tree = 0;
+
+ pbvh_iter_begin(&iter, bvh, scb, search_data);
+
+ while ((node = pbvh_iter_next_occluded(&iter))) {
+ if (node->flag & PBVH_Leaf) {
+ node_tree *new_node = malloc(sizeof(node_tree));
+
+ new_node->data = node;
+
+ new_node->left = NULL;
+ new_node->right = NULL;
+
+ if (tree) {
+ node_tree_insert(tree, new_node);
+ }
+ else {
+ tree = new_node;
+ }
+ }
+ }
+
+ pbvh_iter_end(&iter);
+
+ if (tree) {
+ float tmin = FLT_MAX;
+ traverse_tree(tree, hcb, hit_data, &tmin);
+ free_tree(tree);
+ }
+}
+
+static int update_search_cb(PBVHNode *node, void *data_v)
+{
+ int flag = GET_INT_FROM_POINTER(data_v);
+
+ if (node->flag & PBVH_Leaf)
+ return (node->flag & flag);
+
+ return 1;
+}
+
+static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
+ int totnode, float (*face_nors)[3])
+{
+ float (*vnor)[3];
+ int n;
+
+ if (bvh->type == PBVH_BMESH) {
+ pbvh_bmesh_normals_update(nodes, totnode);
+ return;
+ }
+
+ if (bvh->type != PBVH_FACES)
+ return;
+
+ /* could be per node to save some memory, but also means
+ * we have to store for each vertex which node it is in */
+ vnor = MEM_callocN(sizeof(float) * 3 * bvh->totvert, "bvh temp vnors");
+
+ /* subtle assumptions:
+ * - We know that for all edited vertices, the nodes with faces
+ * adjacent to these vertices have been marked with PBVH_UpdateNormals.
+ * This is true because if the vertex is inside the brush radius, the
+ * bounding box of it's adjacent faces will be as well.
+ * - However this is only true for the vertices that have actually been
+ * edited, not for all vertices in the nodes marked for update, so we
+ * can only update vertices marked with ME_VERT_PBVH_UPDATE.
+ */
+
+ #pragma omp parallel for private(n) schedule(static)
+ for (n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+
+ if ((node->flag & PBVH_UpdateNormals)) {
+ int i, j, totface, *faces;
+
+ faces = node->prim_indices;
+ totface = node->totprim;
+
+ for (i = 0; i < totface; ++i) {
+ MFace *f = bvh->faces + faces[i];
+ float fn[3];
+ unsigned int *fv = &f->v1;
+ int sides = (f->v4) ? 4 : 3;
+
+ if (f->v4)
+ normal_quad_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
+ bvh->verts[f->v3].co, bvh->verts[f->v4].co);
+ else
+ normal_tri_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
+ bvh->verts[f->v3].co);
+
+ for (j = 0; j < sides; ++j) {
+ int v = fv[j];
+
+ if (bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
+ /* this seems like it could be very slow but profile
+ * does not show this, so just leave it for now? */
+ #pragma omp atomic
+ vnor[v][0] += fn[0];
+ #pragma omp atomic
+ vnor[v][1] += fn[1];
+ #pragma omp atomic
+ vnor[v][2] += fn[2];
+ }
+ }
+
+ if (face_nors)
+ copy_v3_v3(face_nors[faces[i]], fn);
+ }
+ }
+ }
+
+ #pragma omp parallel for private(n) schedule(static)
+ for (n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+
+ if (node->flag & PBVH_UpdateNormals) {
+ int i, *verts, totvert;
+
+ verts = node->vert_indices;
+ totvert = node->uniq_verts;
+
+ for (i = 0; i < totvert; ++i) {
+ const int v = verts[i];
+ MVert *mvert = &bvh->verts[v];
+
+ if (mvert->flag & ME_VERT_PBVH_UPDATE) {
+ float no[3];
+
+ copy_v3_v3(no, vnor[v]);
+ normalize_v3(no);
+ normal_float_to_short_v3(mvert->no, no);
+
+ mvert->flag &= ~ME_VERT_PBVH_UPDATE;
+ }
+ }
+
+ node->flag &= ~PBVH_UpdateNormals;
+ }
+ }
+
+ MEM_freeN(vnor);
+}
+
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
+{
+ int n;
+
+ /* update BB, redraw flag */
+ #pragma omp parallel for private(n) schedule(static)
+ for (n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+
+ if ((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB))
+ /* don't clear flag yet, leave it for flushing later */
+ update_node_vb(bvh, node);
+
+ if ((flag & PBVH_UpdateOriginalBB) && (node->flag & PBVH_UpdateOriginalBB))
+ node->orig_vb = node->vb;
+
+ if ((flag & PBVH_UpdateRedraw) && (node->flag & PBVH_UpdateRedraw))
+ node->flag &= ~PBVH_UpdateRedraw;
+ }
+}
+
+static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
+{
+ PBVHNode *node;
+ int n;
+
+ /* can't be done in parallel with OpenGL */
+ for (n = 0; n < totnode; n++) {
+ node = nodes[n];
+
+ if (node->flag & PBVH_RebuildDrawBuffers) {
+ GPU_free_buffers(node->draw_buffers);
+ switch (bvh->type) {
+ case PBVH_GRIDS:
+ node->draw_buffers =
+ GPU_build_grid_buffers(node->prim_indices,
+ node->totprim,
+ bvh->grid_hidden,
+ bvh->gridkey.grid_size);
+ break;
+ case PBVH_FACES:
+ node->draw_buffers =
+ GPU_build_mesh_buffers(node->face_vert_indices,
+ bvh->faces, bvh->verts,
+ node->prim_indices,
+ node->totprim);
+ break;
+ case PBVH_BMESH:
+ node->draw_buffers =
+ GPU_build_bmesh_buffers(bvh->flags &
+ PBVH_DYNTOPO_SMOOTH_SHADING);
+ break;
+ }
+
+ node->flag &= ~PBVH_RebuildDrawBuffers;
+ }
+
+ if (node->flag & PBVH_UpdateDrawBuffers) {
+ switch (bvh->type) {
+ case PBVH_GRIDS:
+ GPU_update_grid_buffers(node->draw_buffers,
+ bvh->grids,
+ bvh->grid_flag_mats,
+ node->prim_indices,
+ node->totprim,
+ &bvh->gridkey,
+ bvh->show_diffuse_color);
+ break;
+ case PBVH_FACES:
+ GPU_update_mesh_buffers(node->draw_buffers,
+ bvh->verts,
+ node->vert_indices,
+ node->uniq_verts +
+ node->face_verts,
+ CustomData_get_layer(bvh->vdata,
+ CD_PAINT_MASK),
+ node->face_vert_indices,
+ bvh->show_diffuse_color);
+ break;
+ case PBVH_BMESH:
+ GPU_update_bmesh_buffers(node->draw_buffers,
+ bvh->bm,
+ node->bm_faces,
+ node->bm_unique_verts,
+ node->bm_other_verts);
+ break;
+ }
+
+ node->flag &= ~PBVH_UpdateDrawBuffers;
+ }
+ }
+}
+
+static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
+{
+ int update = 0;
+
+ /* difficult to multithread well, we just do single threaded recursive */
+ if (node->flag & PBVH_Leaf) {
+ if (flag & PBVH_UpdateBB) {
+ update |= (node->flag & PBVH_UpdateBB);
+ node->flag &= ~PBVH_UpdateBB;
+ }
+
+ if (flag & PBVH_UpdateOriginalBB) {
+ update |= (node->flag & PBVH_UpdateOriginalBB);
+ node->flag &= ~PBVH_UpdateOriginalBB;
+ }
+
+ return update;
+ }
+ else {
+ update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset, flag);
+ update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset + 1, flag);
+
+ if (update & PBVH_UpdateBB)
+ update_node_vb(bvh, node);
+ if (update & PBVH_UpdateOriginalBB)
+ node->orig_vb = node->vb;
+ }
+
+ return update;
+}
+
+void BKE_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
+{
+ PBVHNode **nodes;
+ int totnode;
+
+ if (!bvh->nodes)
+ return;
+
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
+ &nodes, &totnode);
+
+ if (flag & PBVH_UpdateNormals)
+ pbvh_update_normals(bvh, nodes, totnode, face_nors);
+
+ if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw))
+ pbvh_update_BB_redraw(bvh, nodes, totnode, flag);
+
+ if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB))
+ pbvh_flush_bb(bvh, bvh->nodes, flag);
+
+ if (nodes) MEM_freeN(nodes);
+}
+
+void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
+{
+ PBVHIter iter;
+ PBVHNode *node;
+ BB bb;
+
+ BB_reset(&bb);
+
+ pbvh_iter_begin(&iter, bvh, NULL, NULL);
+
+ while ((node = pbvh_iter_next(&iter)))
+ if (node->flag & PBVH_UpdateRedraw)
+ BB_expand_with_bb(&bb, &node->vb);
+
+ pbvh_iter_end(&iter);
+
+ copy_v3_v3(bb_min, bb.bmin);
+ copy_v3_v3(bb_max, bb.bmax);
+}
+
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
+{
+ PBVHIter iter;
+ PBVHNode *node;
+ GHashIterator *hiter;
+ GHash *map;
+ void *face, **faces;
+ unsigned i;
+ int tot;
+
+ map = BLI_ghash_ptr_new("pbvh_get_grid_updates gh");
+
+ pbvh_iter_begin(&iter, bvh, NULL, NULL);
+
+ while ((node = pbvh_iter_next(&iter))) {
+ if (node->flag & PBVH_UpdateNormals) {
+ for (i = 0; i < node->totprim; ++i) {
+ face = bvh->gridfaces[node->prim_indices[i]];
+ if (!BLI_ghash_lookup(map, face))
+ BLI_ghash_insert(map, face, face);
+ }
+
+ if (clear)
+ node->flag &= ~PBVH_UpdateNormals;
+ }
+ }
+
+ pbvh_iter_end(&iter);
+
+ tot = BLI_ghash_size(map);
+ if (tot == 0) {
+ *totface = 0;
+ *gridfaces = NULL;
+ BLI_ghash_free(map, NULL, NULL);
+ return;
+ }
+
+ faces = MEM_callocN(sizeof(void *) * tot, "PBVH Grid Faces");
+
+ for (hiter = BLI_ghashIterator_new(map), i = 0;
+ !BLI_ghashIterator_isDone(hiter);
+ BLI_ghashIterator_step(hiter), ++i)
+ {
+ faces[i] = BLI_ghashIterator_getKey(hiter);
+ }
+
+ BLI_ghashIterator_free(hiter);
+
+ BLI_ghash_free(map, NULL, NULL);
+
+ *totface = tot;
+ *gridfaces = faces;
+}
+
+/***************************** PBVH Access ***********************************/
+
+PBVHType BKE_pbvh_type(const PBVH *bvh)
+{
+ return bvh->type;
+}
+
+BLI_bitmap *BKE_pbvh_grid_hidden(const PBVH *bvh)
+{
+ BLI_assert(bvh->type == PBVH_GRIDS);
+ return bvh->grid_hidden;
+}
+
+void BKE_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
+{
+ BLI_assert(bvh->type == PBVH_GRIDS);
+ *key = bvh->gridkey;
+}
+
+BMesh *BKE_pbvh_get_bmesh(PBVH *bvh)
+{
+ BLI_assert(bvh->type == PBVH_BMESH);
+ return bvh->bm;
+}
+
+/***************************** Node Access ***********************************/
+
+void BKE_pbvh_node_mark_update(PBVHNode *node)
+{
+ node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
+}
+
+void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node)
+{
+ node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
+}
+
+void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
+{
+ BLI_assert(node->flag & PBVH_Leaf);
+
+ if (fully_hidden)
+ node->flag |= PBVH_FullyHidden;
+ else
+ node->flag &= ~PBVH_FullyHidden;
+}
+
+void BKE_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
+{
+ if (vert_indices) *vert_indices = node->vert_indices;
+ if (verts) *verts = bvh->verts;
+}
+
+void BKE_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
+{
+ int tot;
+
+ switch (bvh->type) {
+ case PBVH_GRIDS:
+ tot = node->totprim * bvh->gridkey.grid_area;
+ if (totvert) *totvert = tot;
+ if (uniquevert) *uniquevert = tot;
+ break;
+ case PBVH_FACES:
+ if (totvert) *totvert = node->uniq_verts + node->face_verts;
+ if (uniquevert) *uniquevert = node->uniq_verts;
+ break;
+ case PBVH_BMESH:
+ tot = BLI_ghash_size(node->bm_unique_verts);
+ if (totvert) *totvert = tot + BLI_ghash_size(node->bm_other_verts);
+ if (uniquevert) *uniquevert = tot;
+ break;
+ }
+}
+
+void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj)
+{
+ switch (bvh->type) {
+ case PBVH_GRIDS:
+ if (grid_indices) *grid_indices = node->prim_indices;
+ if (totgrid) *totgrid = node->totprim;
+ if (maxgrid) *maxgrid = bvh->totgrid;
+ if (gridsize) *gridsize = bvh->gridkey.grid_size;
+ if (griddata) *griddata = bvh->grids;
+ if (gridadj) *gridadj = bvh->gridadj;
+ break;
+ case PBVH_FACES:
+ case PBVH_BMESH:
+ if (grid_indices) *grid_indices = NULL;
+ if (totgrid) *totgrid = 0;
+ if (maxgrid) *maxgrid = 0;
+ if (gridsize) *gridsize = 0;
+ if (griddata) *griddata = NULL;
+ if (gridadj) *gridadj = NULL;
+ break;
+ }
+}
+
+void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
+{
+ copy_v3_v3(bb_min, node->vb.bmin);
+ copy_v3_v3(bb_max, node->vb.bmax);
+}
+
+void BKE_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
+{
+ copy_v3_v3(bb_min, node->orig_vb.bmin);
+ copy_v3_v3(bb_max, node->orig_vb.bmax);
+}
+
+void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
+{
+ if (node->proxy_count > 0) {
+ if (proxies) *proxies = node->proxies;
+ if (proxy_count) *proxy_count = node->proxy_count;
+ }
+ else {
+ if (proxies) *proxies = 0;
+ if (proxy_count) *proxy_count = 0;
+ }
+}
+
+/********************************* Raycast ***********************************/
+
+typedef struct {
+ IsectRayAABBData ray;
+ int original;
+} RaycastData;
+
+static int ray_aabb_intersect(PBVHNode *node, void *data_v)
+{
+ RaycastData *rcd = data_v;
+ float bb_min[3], bb_max[3];
+
+ if (rcd->original)
+ BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
+ else
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
+
+ return isect_ray_aabb(&rcd->ray, bb_min, bb_max, &node->tmin);
+}
+
+void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
+ const float ray_start[3], const float ray_normal[3],
+ int original)
+{
+ RaycastData rcd;
+
+ isect_ray_aabb_initialize(&rcd.ray, ray_start, ray_normal);
+ rcd.original = original;
+
+ BKE_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
+}
+
+int ray_face_intersection(const float ray_start[3],
+ const float ray_normal[3],
+ const float *t0, const float *t1,
+ const float *t2, const float *t3,
+ float *fdist)
+{
+ float dist;
+
+ if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
+ (t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
+ {
+ *fdist = dist;
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
+ float (*origco)[3],
+ const float ray_start[3],
+ const float ray_normal[3], float *dist)
+{
+ const MVert *vert = bvh->verts;
+ const int *faces = node->prim_indices;
+ int i, hit = 0, totface = node->totprim;
+
+ for (i = 0; i < totface; ++i) {
+ const MFace *f = bvh->faces + faces[i];
+ const int *face_verts = node->face_vert_indices[i];
+
+ if (paint_is_face_hidden(f, vert))
+ continue;
+
+ if (origco) {
+ /* intersect with backuped original coordinates */
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ origco[face_verts[0]],
+ origco[face_verts[1]],
+ origco[face_verts[2]],
+ f->v4 ? origco[face_verts[3]] : NULL,
+ dist);
+ }
+ else {
+ /* intersect with current coordinates */
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ vert[f->v1].co,
+ vert[f->v2].co,
+ vert[f->v3].co,
+ f->v4 ? vert[f->v4].co : NULL,
+ dist);
+ }
+ }
+
+ return hit;
+}
+
+static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
+ float (*origco)[3],
+ const float ray_start[3],
+ const float ray_normal[3], float *dist)
+{
+ int totgrid = node->totprim;
+ int gridsize = bvh->gridkey.grid_size;
+ int i, x, y, hit = 0;
+
+ for (i = 0; i < totgrid; ++i) {
+ CCGElem *grid = bvh->grids[node->prim_indices[i]];
+ BLI_bitmap gh;
+
+ if (!grid)
+ continue;
+
+ gh = bvh->grid_hidden[node->prim_indices[i]];
+
+ for (y = 0; y < gridsize - 1; ++y) {
+ for (x = 0; x < gridsize - 1; ++x) {
+ /* check if grid face is hidden */
+ if (gh) {
+ if (paint_is_grid_face_hidden(gh, gridsize, x, y))
+ continue;
+ }
+
+ if (origco) {
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ origco[y * gridsize + x],
+ origco[y * gridsize + x + 1],
+ origco[(y + 1) * gridsize + x + 1],
+ origco[(y + 1) * gridsize + x],
+ dist);
+ }
+ else {
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
+ CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
+ CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
+ CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
+ dist);
+ }
+ }
+ }
+
+ if (origco)
+ origco += gridsize * gridsize;
+ }
+
+ return hit;
+}
+
+int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
+ const float ray_start[3], const float ray_normal[3],
+ float *dist)
+{
+ int hit = 0;
+
+ if (node->flag & PBVH_FullyHidden)
+ return 0;
+
+ switch (bvh->type) {
+ case PBVH_FACES:
+ hit |= pbvh_faces_node_raycast(bvh, node, origco,
+ ray_start, ray_normal, dist);
+ break;
+ case PBVH_GRIDS:
+ hit |= pbvh_grids_node_raycast(bvh, node, origco,
+ ray_start, ray_normal, dist);
+ break;
+ case PBVH_BMESH:
+ hit = pbvh_bmesh_node_raycast(node, ray_start, ray_normal, dist, use_origco);
+ break;
+ }
+
+ return hit;
+}
+
+//#include <GL/glew.h>
+
+typedef struct {
+ DMSetMaterial setMaterial;
+ int wireframe;
+} PBVHNodeDrawData;
+
+void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
+{
+ PBVHNodeDrawData *data = data_v;
+
+#if 0
+ /* XXX: Just some quick code to show leaf nodes in different colors */
+ float col[3]; int i;
+
+ if (0) { //is_partial) {
+ col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
+ }
+ else {
+ srand((long long)node);
+ for (i = 0; i < 3; ++i)
+ col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
+ }
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
+
+ glColor3f(1, 0, 0);
+#endif
+
+ if (!(node->flag & PBVH_FullyHidden))
+ GPU_draw_buffers(node->draw_buffers,
+ data->setMaterial,
+ data->wireframe);
+}
+
+typedef enum {
+ ISECT_INSIDE,
+ ISECT_OUTSIDE,
+ ISECT_INTERSECT
+} PlaneAABBIsect;
+
+/* Adapted from:
+ * http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
+ * Returns true if the AABB is at least partially within the frustum
+ * (ok, not a real frustum), false otherwise.
+ */
+static PlaneAABBIsect test_planes_aabb(const float bb_min[3],
+ const float bb_max[3],
+ const float (*planes)[4])
+{
+ float vmin[3], vmax[3];
+ PlaneAABBIsect ret = ISECT_INSIDE;
+ int i, axis;
+
+ for (i = 0; i < 4; ++i) {
+ for (axis = 0; axis < 3; ++axis) {
+ if (planes[i][axis] > 0) {
+ vmin[axis] = bb_min[axis];
+ vmax[axis] = bb_max[axis];
+ }
+ else {
+ vmin[axis] = bb_max[axis];
+ vmax[axis] = bb_min[axis];
+ }
+ }
+
+ if (dot_v3v3(planes[i], vmin) + planes[i][3] > 0)
+ return ISECT_OUTSIDE;
+ else if (dot_v3v3(planes[i], vmax) + planes[i][3] >= 0)
+ ret = ISECT_INTERSECT;
+ }
+
+ return ret;
+}
+
+int BKE_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
+{
+ float bb_min[3], bb_max[3];
+
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
+ return test_planes_aabb(bb_min, bb_max, data) != ISECT_OUTSIDE;
+}
+
+int BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
+{
+ float bb_min[3], bb_max[3];
+
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
+ return test_planes_aabb(bb_min, bb_max, data) != ISECT_INSIDE;
+}
+
+static void pbvh_node_check_diffuse_changed(PBVH *bvh, PBVHNode *node)
+{
+ if (!node->draw_buffers)
+ return;
+
+ if (GPU_buffers_diffuse_changed(node->draw_buffers, bvh->show_diffuse_color))
+ node->flag |= PBVH_UpdateDrawBuffers;
+}
+
+void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
+ DMSetMaterial setMaterial, int wireframe)
+{
+ PBVHNodeDrawData draw_data = {setMaterial, wireframe};
+ PBVHNode **nodes;
+ int a, totnode;
+
+ for (a = 0; a < bvh->totnode; a++)
+ pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
+
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
+ &nodes, &totnode);
+
+ pbvh_update_normals(bvh, nodes, totnode, face_nors);
+ pbvh_update_draw_buffers(bvh, nodes, totnode);
+
+ if (nodes) MEM_freeN(nodes);
+
+ if (planes) {
+ BKE_pbvh_search_callback(bvh, BKE_pbvh_node_planes_contain_AABB,
+ planes, BKE_pbvh_node_draw, &draw_data);
+ }
+ else {
+ BKE_pbvh_search_callback(bvh, NULL, NULL, BKE_pbvh_node_draw, &draw_data);
+ }
+}
+
+void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
+ DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
+{
+ int a;
+
+ bvh->grids = grids;
+ bvh->gridadj = gridadj;
+ bvh->gridfaces = gridfaces;
+
+ if (flagmats != bvh->grid_flag_mats || bvh->grid_hidden != grid_hidden) {
+ bvh->grid_flag_mats = flagmats;
+ bvh->grid_hidden = grid_hidden;
+
+ for (a = 0; a < bvh->totnode; ++a)
+ BKE_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
+ }
+}
+
+/* Get the node's displacement layer, creating it if necessary */
+float *BKE_pbvh_node_layer_disp_get(PBVH *bvh, PBVHNode *node)
+{
+ if (!node->layer_disp) {
+ int totvert = 0;
+ BKE_pbvh_node_num_verts(bvh, node, &totvert, NULL);
+ node->layer_disp = MEM_callocN(sizeof(float) * totvert, "layer disp");
+ }
+ return node->layer_disp;
+}
+
+/* If the node has a displacement layer, free it and set to null */
+void BKE_pbvh_node_layer_disp_free(PBVHNode *node)
+{
+ if (node->layer_disp) {
+ MEM_freeN(node->layer_disp);
+ node->layer_disp = NULL;
+ }
+}
+
+float (*BKE_pbvh_get_vertCos(PBVH * pbvh))[3]
+{
+ int a;
+ float (*vertCos)[3] = NULL;
+
+ if (pbvh->verts) {
+ float *co;
+ MVert *mvert = pbvh->verts;
+
+ vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
+ co = (float *)vertCos;
+
+ for (a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
+ copy_v3_v3(co, mvert->co);
+ }
+ }
+
+ return vertCos;
+}
+
+void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
+{
+ int a;
+
+ if (!pbvh->deformed) {
+ if (pbvh->verts) {
+ /* if pbvh is not already deformed, verts/faces points to the */
+ /* original data and applying new coords to this arrays would lead to */
+ /* unneeded deformation -- duplicate verts/faces to avoid this */
+
+ pbvh->verts = MEM_dupallocN(pbvh->verts);
+ pbvh->faces = MEM_dupallocN(pbvh->faces);
+
+ pbvh->deformed = 1;
+ }
+ }
+
+ if (pbvh->verts) {
+ MVert *mvert = pbvh->verts;
+ /* copy new verts coords */
+ for (a = 0; a < pbvh->totvert; ++a, ++mvert) {
+ copy_v3_v3(mvert->co, vertCos[a]);
+ mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+
+ /* coordinates are new -- normals should also be updated */
+ BKE_mesh_calc_normals_tessface(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
+
+ for (a = 0; a < pbvh->totnode; ++a)
+ BKE_pbvh_node_mark_update(&pbvh->nodes[a]);
+
+ BKE_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
+
+ }
+}
+
+int BKE_pbvh_isDeformed(PBVH *pbvh)
+{
+ return pbvh->deformed;
+}
+/* Proxies */
+
+PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
+{
+ int index, totverts;
+
+ #pragma omp critical
+ {
+
+ index = node->proxy_count;
+
+ node->proxy_count++;
+
+ if (node->proxies)
+ node->proxies = MEM_reallocN(node->proxies, node->proxy_count * sizeof(PBVHProxyNode));
+ else
+ node->proxies = MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
+
+ BKE_pbvh_node_num_verts(bvh, node, &totverts, NULL);
+ node->proxies[index].co = MEM_callocN(sizeof(float[3]) * totverts, "PBVHNodeProxy.co");
+ }
+
+ return node->proxies + index;
+}
+
+void BKE_pbvh_node_free_proxies(PBVHNode *node)
+{
+ #pragma omp critical
+ {
+ int p;
+
+ for (p = 0; p < node->proxy_count; p++) {
+ MEM_freeN(node->proxies[p].co);
+ node->proxies[p].co = 0;
+ }
+
+ MEM_freeN(node->proxies);
+ node->proxies = 0;
+
+ node->proxy_count = 0;
+ }
+}
+
+void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
+{
+ PBVHNode **array = NULL, **newarray, *node;
+ int tot = 0, space = 0;
+ int n;
+
+ for (n = 0; n < pbvh->totnode; n++) {
+ node = pbvh->nodes + n;
+
+ if (node->proxy_count > 0) {
+ if (tot == space) {
+ /* resize array if needed */
+ space = (tot == 0) ? 32 : space * 2;
+ newarray = MEM_callocN(sizeof(PBVHNode) * space, "BKE_pbvh_gather_proxies");
+
+ if (array) {
+ memcpy(newarray, array, sizeof(PBVHNode) * tot);
+ MEM_freeN(array);
+ }
+
+ array = newarray;
+ }
+
+ array[tot] = node;
+ tot++;
+ }
+ }
+
+ if (tot == 0 && array) {
+ MEM_freeN(array);
+ array = NULL;
+ }
+
+ *r_array = array;
+ *r_tot = tot;
+}
+
+void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
+ PBVHVertexIter *vi, int mode)
+{
+ struct CCGElem **grids;
+ struct MVert *verts;
+ int *grid_indices, *vert_indices;
+ int totgrid, gridsize, uniq_verts, totvert;
+
+ vi->grid = 0;
+ vi->no = 0;
+ vi->fno = 0;
+ vi->mvert = 0;
+
+ BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
+ BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
+ BKE_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
+ vi->key = &bvh->gridkey;
+
+ vi->grids = grids;
+ vi->grid_indices = grid_indices;
+ vi->totgrid = (grids) ? totgrid : 1;
+ vi->gridsize = gridsize;
+
+ if (mode == PBVH_ITER_ALL)
+ vi->totvert = totvert;
+ else
+ vi->totvert = uniq_verts;
+ vi->vert_indices = vert_indices;
+ vi->mverts = verts;
+
+ if (bvh->type == PBVH_BMESH) {
+ BLI_ghashIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
+ BLI_ghashIterator_init(&vi->bm_other_verts, node->bm_other_verts);
+ vi->bm_vdata = &bvh->bm->vdata;
+ }
+
+ vi->gh = NULL;
+ if (vi->grids && mode == PBVH_ITER_UNIQUE)
+ vi->grid_hidden = bvh->grid_hidden;
+
+ vi->mask = NULL;
+ if (bvh->type == PBVH_FACES)
+ vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
+}
+
+void pbvh_show_diffuse_color_set(PBVH *bvh, int show_diffuse_color)
+{
+ bvh->show_diffuse_color = show_diffuse_color;
+}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
new file mode 100644
index 0000000..791288a
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -0,0 +1,1414 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_buffer.h"
+#include "BLI_ghash.h"
+#include "BLI_heap.h"
+#include "BLI_math.h"
+
+#include "BKE_ccg.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_pbvh.h"
+
+#include "GPU_buffers.h"
+
+#include "bmesh.h"
+#include "pbvh_intern.h"
+
+#include <assert.h>
+
+/****************************** Building ******************************/
+
+/* Update node data after splitting */
+static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
+{
+ GHashIterator gh_iter;
+ PBVHNode *n = &bvh->nodes[node_index];
+
+ /* Create vert hash sets */
+ n->bm_unique_verts = BLI_ghash_ptr_new("bm_unique_verts");
+ n->bm_other_verts = BLI_ghash_ptr_new("bm_other_verts");
+
+ BB_reset(&n->vb);
+
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMIter bm_iter;
+ BMVert *v;
+ void *node_val = SET_INT_IN_POINTER(node_index);
+
+ /* Update ownership of faces */
+ BLI_ghash_insert(bvh->bm_face_to_node, f, node_val);
+
+ /* Update vertices */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ if (!BLI_ghash_haskey(n->bm_unique_verts, v)) {
+ if (BLI_ghash_haskey(bvh->bm_vert_to_node, v)) {
+ if (!BLI_ghash_haskey(n->bm_other_verts, v))
+ BLI_ghash_insert(n->bm_other_verts, v, NULL);
+ }
+ else {
+ BLI_ghash_insert(n->bm_unique_verts, v, NULL);
+ BLI_ghash_insert(bvh->bm_vert_to_node, v, node_val);
+ }
+ }
+ /* Update node bounding box */
+ BB_expand(&n->vb, v->co);
+ }
+ }
+
+ BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
+ n->vb.bmin[1] <= n->vb.bmax[1] &&
+ n->vb.bmin[2] <= n->vb.bmax[2]);
+
+ n->orig_vb = n->vb;
+
+ /* Build GPU buffers */
+ if (!G.background) {
+ int smooth = bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING;
+ n->draw_buffers = GPU_build_bmesh_buffers(smooth);
+ n->flag |= PBVH_UpdateDrawBuffers;
+ }
+}
+
+/* Recursively split the node if it exceeds the leaf_limit */
+static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
+{
+ GHash *empty, *other;
+ GHashIterator gh_iter;
+ PBVHNode *n, *c1, *c2;
+ BB cb;
+ float mid;
+ int axis, children;
+
+ n = &bvh->nodes[node_index];
+
+ if (BLI_ghash_size(n->bm_faces) <= bvh->leaf_limit) {
+ /* Node limit not exceeded */
+ pbvh_bmesh_node_finalize(bvh, node_index);
+ return;
+ }
+
+ /* Calculate bounding box around primitive centroids */
+ BB_reset(&cb);
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ const BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
+
+ BB_expand(&cb, bbc->bcentroid);
+ }
+
+ /* Find widest axis and its midpoint */
+ axis = BB_widest_axis(&cb);
+ mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
+
+ /* Add two new child nodes */
+ children = bvh->totnode;
+ n->children_offset = children;
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
+
+ /* Array reallocated, update current node pointer */
+ n = &bvh->nodes[node_index];
+
+ /* Initialize children */
+ c1 = &bvh->nodes[children];
+ c2 = &bvh->nodes[children + 1];
+ c1->flag |= PBVH_Leaf;
+ c2->flag |= PBVH_Leaf;
+ c1->bm_faces = BLI_ghash_ptr_new("bm_faces");
+ c2->bm_faces = BLI_ghash_ptr_new("bm_faces");
+
+ /* Partition the parent node's faces between the two children */
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
+
+ if (bbc->bcentroid[axis] < mid)
+ BLI_ghash_insert(c1->bm_faces, f, NULL);
+ else
+ BLI_ghash_insert(c2->bm_faces, f, NULL);
+ }
+
+ /* Enforce at least one primitive in each node */
+ empty = NULL;
+ if (BLI_ghash_size(c1->bm_faces) == 0) {
+ empty = c1->bm_faces;
+ other = c2->bm_faces;
+ }
+ else if (BLI_ghash_size(c2->bm_faces) == 0) {
+ empty = c2->bm_faces;
+ other = c1->bm_faces;
+ }
+ if (empty) {
+ GHASH_ITER (gh_iter, other) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_insert(empty, key, NULL);
+ BLI_ghash_remove(other, key, NULL, NULL);
+ break;
+ }
+ }
+
+ /* Clear this node */
+
+ /* Mark this node's unique verts as unclaimed */
+ if (n->bm_unique_verts) {
+ GHASH_ITER (gh_iter, n->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ }
+ BLI_ghash_free(n->bm_unique_verts, NULL, NULL);
+ }
+
+ /* Unclaim faces */
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+ }
+ BLI_ghash_free(n->bm_faces, NULL, NULL);
+
+ if (n->bm_other_verts)
+ BLI_ghash_free(n->bm_other_verts, NULL, NULL);
+
+ if (n->layer_disp)
+ MEM_freeN(n->layer_disp);
+
+ n->bm_faces = NULL;
+ n->bm_unique_verts = NULL;
+ n->bm_other_verts = NULL;
+ n->layer_disp = NULL;
+
+ if (n->draw_buffers) {
+ GPU_free_buffers(n->draw_buffers);
+ n->draw_buffers = NULL;
+ }
+ n->flag &= ~PBVH_Leaf;
+
+ /* Recurse */
+ c1 = c2 = NULL;
+ pbvh_bmesh_node_split(bvh, prim_bbc, children);
+ pbvh_bmesh_node_split(bvh, prim_bbc, children + 1);
+
+ /* Array maybe reallocated, update current node pointer */
+ n = &bvh->nodes[node_index];
+
+ /* Update bounding box */
+ BB_reset(&n->vb);
+ BB_expand_with_bb(&n->vb, &bvh->nodes[n->children_offset].vb);
+ BB_expand_with_bb(&n->vb, &bvh->nodes[n->children_offset + 1].vb);
+ n->orig_vb = n->vb;
+}
+
+/* Recursively split the node if it exceeds the leaf_limit */
+static int pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
+{
+ GHash *prim_bbc;
+ GHashIterator gh_iter;
+
+ if (BLI_ghash_size(bvh->nodes[node_index].bm_faces) <= bvh->leaf_limit) {
+ /* Node limit not exceeded */
+ return FALSE;
+ }
+
+ /* For each BMFace, store the AABB and AABB centroid */
+ prim_bbc = BLI_ghash_ptr_new("prim_bbc");
+
+ GHASH_ITER (gh_iter, bvh->nodes[node_index].bm_faces) {
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BBC *bbc = MEM_callocN(sizeof(BBC), "BBC");
+
+ BB_reset((BB *)bbc);
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ BB_expand((BB *)bbc, v->co);
+ }
+ BBC_update_centroid(bbc);
+
+ BLI_ghash_insert(prim_bbc, f, bbc);
+ }
+
+ pbvh_bmesh_node_split(bvh, prim_bbc, node_index);
+
+ BLI_ghash_free(prim_bbc, NULL, (void *)MEM_freeN);
+
+ return TRUE;
+}
+
+/**********************************************************************/
+
+static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
+{
+ int node_index;
+
+ BLI_assert(BLI_ghash_haskey(map, key));
+
+ node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
+ BLI_assert(node_index < bvh->totnode);
+
+ return &bvh->nodes[node_index];
+}
+
+static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
+ const float co[3],
+ const BMVert *example)
+{
+ BMVert *v = BM_vert_create(bvh->bm, co, example, 0);
+ void *val = SET_INT_IN_POINTER(node_index);
+
+ BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
+
+ BLI_ghash_insert(bvh->nodes[node_index].bm_unique_verts, v, NULL);
+ BLI_ghash_insert(bvh->bm_vert_to_node, v, val);
+
+ /* Log the new vertex */
+ BM_log_vert_added(bvh->bm, bvh->bm_log, v);
+
+ return v;
+}
+
+static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index, BMVert *v1,
+ BMVert *v2, BMVert *v3,
+ const BMFace *UNUSED(example))
+{
+ BMFace *f;
+ void *val = SET_INT_IN_POINTER(node_index);
+
+ /* Note: passing NULL for the 'example' parameter, profiling shows
+ * a small performance bump */
+ f = BM_face_create_quad_tri(bvh->bm, v1, v2, v3, NULL, NULL, TRUE);
+ if (!BLI_ghash_haskey(bvh->bm_face_to_node, f)) {
+
+ BLI_ghash_insert(bvh->nodes[node_index].bm_faces, f, NULL);
+ BLI_ghash_insert(bvh->bm_face_to_node, f, val);
+
+ /* Log the new face */
+ BM_log_face_added(bvh->bm_log, f);
+ }
+
+ return f;
+}
+
+/* Return the number of faces in 'node' that use vertex 'v' */
+static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ int count = 0;
+
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ if (f_node == node)
+ count++;
+ }
+
+ return count;
+}
+
+/* Return a node that uses vertex 'v' other than its current owner */
+static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ PBVHNode *current_node;
+
+ current_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ if (f_node != current_node)
+ return f_node;
+ }
+
+ return NULL;
+}
+
+static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
+ BMVert *v)
+{
+ PBVHNode *current_owner;
+
+ current_owner = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ BLI_assert(current_owner != new_owner);
+
+ /* Remove current ownership */
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ BLI_ghash_remove(current_owner->bm_unique_verts, v, NULL, NULL);
+
+ /* Set new ownership */
+ BLI_ghash_insert(bvh->bm_vert_to_node, v,
+ SET_INT_IN_POINTER(new_owner - bvh->nodes));
+ BLI_ghash_insert(new_owner->bm_unique_verts, v, NULL);
+ BLI_ghash_remove(new_owner->bm_other_verts, v, NULL, NULL);
+ BLI_assert(!BLI_ghash_haskey(new_owner->bm_other_verts, v));
+}
+
+static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
+{
+ PBVHNode *v_node;
+ BMIter bm_iter;
+ BMFace *f;
+
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ v_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ BLI_ghash_remove(v_node->bm_unique_verts, v, NULL, NULL);
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+
+ /* Have to check each neighboring face's node */
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ BLI_ghash_remove(f_node->bm_unique_verts, v, NULL, NULL);
+ BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL);
+
+ BLI_assert(!BLI_ghash_haskey(f_node->bm_unique_verts, v));
+ BLI_assert(!BLI_ghash_haskey(f_node->bm_other_verts, v));
+ }
+}
+
+static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
+{
+ PBVHNode *f_node;
+ BMIter bm_iter;
+ BMVert *v;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ /* Check if any of this face's vertices need to be removed
+ * from the node */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ if (pbvh_bmesh_node_vert_use_count(bvh, f_node, v) == 1) {
+ if (BLI_ghash_lookup(f_node->bm_unique_verts, v)) {
+ /* Find a different node that uses 'v' */
+ PBVHNode *new_node;
+
+ new_node = pbvh_bmesh_vert_other_node_find(bvh, v);
+ BLI_assert(new_node || BM_vert_face_count(v) == 1);
+
+ if (new_node) {
+ pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v);
+ }
+ }
+ else {
+ /* Remove from other verts */
+ BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL);
+ }
+ }
+ }
+
+ /* Remove face from node and top level */
+ BLI_ghash_remove(f_node->bm_faces, f, NULL, NULL);
+ BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+
+ /* Log removed face */
+ BM_log_face_removed(bvh->bm_log, f);
+}
+
+static BMVert *bm_triangle_other_vert_find(BMFace *triangle, const BMVert *v1,
+ const BMVert *v2)
+{
+ BLI_assert(triangle->len == 3);
+ BLI_assert(v1 != v2);
+
+ if (triangle->len == 3) {
+ BMIter iter;
+ BMVert *v, *other = NULL;
+ int found_v1 = FALSE, found_v2 = FALSE;
+
+ BM_ITER_ELEM (v, &iter, triangle, BM_VERTS_OF_FACE) {
+ if (v == v1)
+ found_v1 = TRUE;
+ else if (v == v2)
+ found_v2 = TRUE;
+ else
+ other = v;
+ }
+
+ if (found_v1 && found_v2)
+ return other;
+ }
+
+ BLI_assert(0);
+ return NULL;
+}
+
+static void pbvh_bmesh_edge_faces(BLI_Buffer *buf, BMEdge *e)
+{
+ BLI_buffer_resize(buf, BM_edge_face_count(e));
+ BM_iter_as_array(NULL, BM_FACES_OF_EDGE, e, buf->data, buf->count);
+}
+
+/* TODO: maybe a better way to do this, if not then this should go to
+ * bmesh_queries */
+static int bm_face_edge_backwards(BMFace *f, BMEdge *e)
+{
+ BMIter bm_iter;
+ BMLoop *l, *l1 = NULL, *l2 = NULL;
+
+ BM_ITER_ELEM (l, &bm_iter, f, BM_LOOPS_OF_FACE) {
+ if (l->v == e->v1)
+ l1 = l;
+ else if (l->v == e->v2)
+ l2 = l;
+ }
+
+ BLI_assert(l1 && l2);
+ BLI_assert(l1->next == l2 || l2->next == l1);
+ return l2->next == l1;
+}
+
+static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
+{
+ if (node->bm_orco)
+ MEM_freeN(node->bm_orco);
+ if (node->bm_ortri)
+ MEM_freeN(node->bm_ortri);
+ node->bm_orco = NULL;
+ node->bm_ortri = NULL;
+ node->bm_tot_ortri = 0;
+}
+
+/****************************** EdgeQueue *****************************/
+
+typedef struct {
+ Heap *heap;
+ const float *center;
+ float radius_squared;
+ float limit_len_squared;
+} EdgeQueue;
+
+static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
+{
+ BMVert *v[3];
+ float c[3];
+
+ /* Get closest point in triangle to sphere center */
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ closest_on_tri_to_point_v3(c, q->center, v[0]->co, v[1]->co, v[2]->co);
+
+ /* Check if triangle intersects the sphere */
+ return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
+}
+
+static void edge_queue_insert(EdgeQueue *q, BLI_mempool *pool, BMEdge *e,
+ float priority)
+{
+ BMVert **pair;
+
+ pair = BLI_mempool_alloc(pool);
+ pair[0] = e->v1;
+ pair[1] = e->v2;
+ BLI_heap_insert(q->heap, priority, pair);
+}
+
+static void long_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e)
+{
+ const float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq > q->limit_len_squared)
+ edge_queue_insert(q, pool, e, 1.0f / len_sq);
+}
+
+static void short_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e)
+{
+ const float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq < q->limit_len_squared)
+ edge_queue_insert(q, pool, e, len_sq);
+}
+
+static int long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
+ BMFace *f)
+{
+ BMIter bm_iter;
+ BMEdge *e;
+
+ if (edge_queue_tri_in_sphere(q, f)) {
+ /* Check each edge of the face */
+ BM_ITER_ELEM (e, &bm_iter, f, BM_EDGES_OF_FACE) {
+ long_edge_queue_edge_add(q, pool, e);
+ }
+ }
+
+ return TRUE;
+}
+
+static int short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
+ BMFace *f)
+{
+ BMIter bm_iter;
+ BMEdge *e;
+
+ if (edge_queue_tri_in_sphere(q, f)) {
+ /* Check each edge of the face */
+ BM_ITER_ELEM (e, &bm_iter, f, BM_EDGES_OF_FACE) {
+ short_edge_queue_edge_add(q, pool, e);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Create a priority queue containing vertex pairs connected by a long
+ * edge as defined by PBVH.bm_max_edge_len.
+ *
+ * Only nodes marked for topology update are checked, and in those
+ * nodes only edges used by a face intersecting the (center, radius)
+ * sphere are checked.
+ *
+ * The highest priority (lowest number) is given to the longest edge.
+ */
+static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
+ PBVH *bvh, const float center[3],
+ float radius)
+{
+ int n;
+
+ q->heap = BLI_heap_new();
+ q->center = center;
+ q->radius_squared = radius * radius;
+ q->limit_len_squared = bvh->bm_max_edge_len * bvh->bm_max_edge_len;
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ /* Check leaf nodes marked for topology update */
+ if ((node->flag & PBVH_Leaf) &&
+ (node->flag & PBVH_UpdateTopology))
+ {
+ GHashIterator gh_iter;
+
+ /* Check each face */
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ long_edge_queue_face_add(q, pool, f);
+ }
+ }
+ }
+}
+
+/* Create a priority queue containing vertex pairs connected by a
+ * short edge as defined by PBVH.bm_min_edge_len.
+ *
+ * Only nodes marked for topology update are checked, and in those
+ * nodes only edges used by a face intersecting the (center, radius)
+ * sphere are checked.
+ *
+ * The highest priority (lowest number) is given to the shortest edge.
+ */
+static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
+ PBVH *bvh, const float center[3],
+ float radius)
+{
+ int n;
+
+ q->heap = BLI_heap_new();
+ q->center = center;
+ q->radius_squared = radius * radius;
+ q->limit_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ /* Check leaf nodes marked for topology update */
+ if ((node->flag & PBVH_Leaf) &&
+ (node->flag & PBVH_UpdateTopology))
+ {
+ GHashIterator gh_iter;
+
+ /* Check each face */
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ short_edge_queue_face_add(q, pool, f);
+ }
+ }
+ }
+}
+
+/*************************** Topology update **************************/
+
+static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e, BLI_Buffer *edge_faces)
+{
+ BMVert *v_new;
+ float mid[3];
+ int i, node_index;
+
+ /* Get all faces adjacent to the edge */
+ pbvh_bmesh_edge_faces(edge_faces, e);
+
+ /* Create a new vertex in current node at the edge's midpoint */
+ mid_v3_v3v3(mid, e->v1->co, e->v2->co);
+
+ node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(bvh->bm_vert_to_node,
+ e->v1));
+ v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1);
+
+ /* For each face, add two new triangles and delete the original */
+ for (i = 0; i < edge_faces->count; i++) {
+ BMFace *f_adj = BLI_buffer_at(edge_faces, BMFace *, i);
+ BMFace *f_new;
+ BMVert *opp, *v1, *v2;
+ void *nip;
+ int ni;
+
+ BLI_assert(f_adj->len == 3);
+ nip = BLI_ghash_lookup(bvh->bm_face_to_node, f_adj);
+ ni = GET_INT_FROM_POINTER(nip);
+
+ /* Ensure node gets redrawn */
+ bvh->nodes[ni].flag |= PBVH_UpdateDrawBuffers;
+
+ /* Find the vertex not in the edge */
+ opp = bm_triangle_other_vert_find(f_adj, e->v1, e->v2);
+
+ /* Get e->v1 and e->v2 in the order they appear in the
+ * existing face so that the new faces' winding orders
+ * match */
+ v1 = e->v1;
+ v2 = e->v2;
+ if (bm_face_edge_backwards(f_adj, e))
+ SWAP(BMVert *, v1, v2);
+
+ if (ni != node_index && i == 0)
+ pbvh_bmesh_vert_ownership_transfer(bvh, &bvh->nodes[ni], v_new);
+
+ /* Create two new faces */
+ f_new = pbvh_bmesh_face_create(bvh, ni, v1, v_new, opp, f_adj);
+ long_edge_queue_face_add(q, pool, f_new);
+ f_new = pbvh_bmesh_face_create(bvh, ni, v_new, v2, opp, f_adj);
+ long_edge_queue_face_add(q, pool, f_new);
+
+ /* Delete original */
+ pbvh_bmesh_face_remove(bvh, f_adj);
+ BM_face_kill(bvh->bm, f_adj);
+
+ /* Ensure new vertex is in the node */
+ if (!BLI_ghash_haskey(bvh->nodes[ni].bm_unique_verts, v_new) &&
+ !BLI_ghash_haskey(bvh->nodes[ni].bm_other_verts, v_new))
+ {
+ BLI_ghash_insert(bvh->nodes[ni].bm_other_verts, v_new, NULL);
+ }
+
+ if (BM_vert_edge_count(opp) >= 9) {
+ BMIter bm_iter;
+ BMEdge *e2;
+
+ BM_ITER_ELEM (e2, &bm_iter, opp, BM_EDGES_OF_VERT) {
+ long_edge_queue_edge_add(q, pool, e2);
+ }
+ }
+ }
+
+ BM_edge_kill(bvh->bm, e);
+}
+
+static int pbvh_bmesh_subdivide_long_edges(PBVH *bvh, EdgeQueue *q,
+ BLI_mempool *pool,
+ BLI_Buffer *edge_faces)
+{
+ int any_subdivided = FALSE;
+
+ while (!BLI_heap_is_empty(q->heap)) {
+ BMVert **pair = BLI_heap_popmin(q->heap);
+ BMEdge *e;
+
+ /* Check that the edge still exists */
+ if (!(e = BM_edge_exists(pair[0], pair[1]))) {
+ BLI_mempool_free(pool, pair);
+ continue;
+ }
+
+ BLI_mempool_free(pool, pair);
+ pair = NULL;
+
+ /* Check that the edge's vertices are still in the PBVH. It's
+ * possible that an edge collapse has deleted adjacent faces
+ * and the node has been split, thus leaving wire edges and
+ * associated vertices. */
+ if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
+ !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ {
+ continue;
+ }
+
+ if (BM_edge_calc_length_squared(e) <= q->limit_len_squared)
+ continue;
+
+ any_subdivided = TRUE;
+
+ pbvh_bmesh_split_edge(bvh, q, pool, e, edge_faces);
+ }
+
+ return any_subdivided;
+}
+
+static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
+ BMVert *v2, GHash *deleted_verts,
+ BLI_Buffer *edge_faces,
+ BLI_Buffer *deleted_faces)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ int i;
+
+ /* Get all faces adjacent to the edge */
+ pbvh_bmesh_edge_faces(edge_faces, e);
+
+ /* Remove the merge vertex from the PBVH */
+ pbvh_bmesh_vert_remove(bvh, v2);
+
+ /* Remove all faces adjacent to the edge */
+ for (i = 0; i < edge_faces->count; i++) {
+ BMFace *f_adj = BLI_buffer_at(edge_faces, BMFace *, i);
+
+ pbvh_bmesh_face_remove(bvh, f_adj);
+ BM_face_kill(bvh->bm, f_adj);
+ }
+
+ /* Kill the edge */
+ BLI_assert(BM_edge_face_count(e) == 0);
+ BM_edge_kill(bvh->bm, e);
+
+ /* For all remaining faces of v2, create a new face that is the
+ same except it uses v1 instead of v2 */
+ /* Note: this could be done with BM_vert_splice(), but that
+ * requires handling other issues like duplicate edges, so doesn't
+ * really buy anything. */
+ deleted_faces->count = 0;
+ BM_ITER_ELEM (f, &bm_iter, v2, BM_FACES_OF_VERT) {
+ BMVert *v[3];
+ BMFace *existing_face;
+ PBVHNode *n;
+ int ni;
+
+ /* Get vertices, replace use of v2 with v1 */
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ for (i = 0; i < 3; i++) {
+ if (v[i] == v2)
+ v[i] = v1;
+ }
+
+ /* Check if a face using these vertices already exists. If so,
+ * skip adding this face and mark the existing one for
+ * deletion as well. Prevents extraneous "flaps" from being
+ * created. */
+ if (BM_face_exists(v, 3, &existing_face)) {
+ BLI_assert(existing_face);
+ BLI_buffer_append(deleted_faces, BMFace *, existing_face);
+ }
+ else {
+ n = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ ni = n - bvh->nodes;
+ pbvh_bmesh_face_create(bvh, ni, v[0], v[1], v[2], f);
+
+ /* Ensure that v1 is in the new face's node */
+ if (!BLI_ghash_haskey(n->bm_unique_verts, v1) &&
+ !BLI_ghash_haskey(n->bm_other_verts, v1)) {
+ BLI_ghash_insert(n->bm_other_verts, v1, NULL);
+ }
+ }
+
+ BLI_buffer_append(deleted_faces, BMFace *, f);
+ }
+
+ /* Delete the tagged faces */
+ for (i = 0; i < deleted_faces->count; i++) {
+ BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
+ BMVert *v[3];
+ int j;
+
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f_del, (void **)v, 3);
+
+ /* Check if any of the face's vertices are now unused, if so
+ remove them from the PBVH */
+ for (j = 0; j < 3; j++) {
+ if (v[j] != v2 && BM_vert_face_count(v[j]) == 0) {
+ BLI_ghash_insert(deleted_verts, v[j], NULL);
+ pbvh_bmesh_vert_remove(bvh, v[j]);
+ }
+ else {
+ v[j] = NULL;
+ }
+ }
+
+ /* Remove the face */
+ pbvh_bmesh_face_remove(bvh, f_del);
+ BM_face_kill(bvh->bm, f_del);
+
+ /* Delete unused vertices */
+ for (j = 0; j < 3; j++) {
+ if (v[j]) {
+ BM_log_vert_removed(bvh->bm, bvh->bm_log, v[j]);
+ BM_vert_kill(bvh->bm, v[j]);
+ }
+ }
+ }
+
+ /* Move v1 to the midpoint of v1 and v2 */
+ BM_log_vert_before_modified(bvh->bm, bvh->bm_log, v1);
+ mid_v3_v3v3(v1->co, v1->co, v2->co);
+
+ /* Delete v2 */
+ BLI_assert(BM_vert_face_count(v2) == 0);
+ BLI_ghash_insert(deleted_verts, v2, NULL);
+ BM_log_vert_removed(bvh->bm, bvh->bm_log, v2);
+ BM_vert_kill(bvh->bm, v2);
+}
+
+static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
+ BLI_mempool *pool,
+ BLI_Buffer *edge_faces,
+ BLI_Buffer *deleted_faces)
+{
+ float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
+ GHash *deleted_verts;
+ int any_collapsed = FALSE;
+
+ deleted_verts = BLI_ghash_ptr_new("deleted_verts");
+
+ while (!BLI_heap_is_empty(q->heap)) {
+ BMVert **pair = BLI_heap_popmin(q->heap);
+ BMEdge *e;
+ BMVert *v1, *v2;
+
+ v1 = pair[0];
+ v2 = pair[1];
+ BLI_mempool_free(pool, pair);
+ pair = NULL;
+
+ /* Check that the vertices/edge still exist */
+ if (BLI_ghash_haskey(deleted_verts, v1) ||
+ BLI_ghash_haskey(deleted_verts, v2) ||
+ !(e = BM_edge_exists(v1, v2)))
+ {
+ continue;
+ }
+
+ /* Check that the edge's vertices are still in the PBVH. It's
+ * possible that an edge collapse has deleted adjacent faces
+ * and the node has been split, thus leaving wire edges and
+ * associated vertices. */
+ if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
+ !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ {
+ continue;
+ }
+
+ if (BM_edge_calc_length_squared(e) >= min_len_squared)
+ continue;
+
+ any_collapsed = TRUE;
+
+ pbvh_bmesh_collapse_edge(bvh, e, v1, v2,
+ deleted_verts, edge_faces,
+ deleted_faces);
+ }
+
+ BLI_ghash_free(deleted_verts, NULL, NULL);
+
+ return any_collapsed;
+}
+
+/************************* Called from pbvh.c *************************/
+
+int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ int use_original)
+{
+ GHashIterator gh_iter;
+ int hit = 0;
+
+ if (use_original && node->bm_tot_ortri) {
+ int i;
+ for (i = 0; i < node->bm_tot_ortri; i++) {
+ const int *t = node->bm_ortri[i];
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ node->bm_orco[t[0]],
+ node->bm_orco[t[1]],
+ node->bm_orco[t[2]],
+ NULL, dist);
+ }
+ }
+ else {
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ BLI_assert(f->len == 3);
+ if (f->len == 3) {
+ BMVert *v[3];
+
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ v[0]->co,
+ v[1]->co,
+ v[2]->co,
+ NULL, dist);
+ }
+ }
+ }
+
+ return hit;
+}
+
+void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
+{
+ int n;
+
+ for (n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BM_face_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ }
+ GHASH_ITER (gh_iter, node->bm_unique_verts) {
+ BM_vert_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ }
+ }
+}
+
+/***************************** Public API *****************************/
+
+/* Build a PBVH from a BMesh */
+void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
+ BMLog *log)
+{
+ BMIter iter;
+ BMFace *f;
+ PBVHNode *n;
+ int node_index = 0;
+
+ bvh->bm = bm;
+
+ BKE_pbvh_bmesh_detail_size_set(bvh, 0.75);
+
+ bvh->type = PBVH_BMESH;
+ bvh->bm_face_to_node = BLI_ghash_ptr_new("bm_face_to_node");
+ bvh->bm_vert_to_node = BLI_ghash_ptr_new("bm_vert_to_node");
+ bvh->bm_log = log;
+
+ /* TODO: choose leaf limit better */
+ bvh->leaf_limit = 100;
+
+ if (smooth_shading)
+ bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
+
+ /* Start with all faces in the root node */
+ n = bvh->nodes = MEM_callocN(sizeof(PBVHNode), "PBVHNode");
+ bvh->totnode = 1;
+ n->flag = PBVH_Leaf;
+ n->bm_faces = BLI_ghash_ptr_new("bm_faces");
+ BM_ITER_MESH (f, &iter, bvh->bm, BM_FACES_OF_MESH) {
+ BLI_ghash_insert(n->bm_faces, f, NULL);
+ }
+
+ /* Recursively split the node until it is under the limit; if no
+ * splitting occurs then finalize the existing leaf node */
+ if (!pbvh_bmesh_node_limit_ensure(bvh, node_index))
+ pbvh_bmesh_node_finalize(bvh, 0);
+}
+
+/* Collapse short edges, subdivide long edges */
+int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius)
+{
+ BLI_buffer_declare_static(BMFace *, edge_faces, BLI_BUFFER_NOP, 8);
+ BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
+
+ int modified = FALSE;
+ int n;
+
+ if (mode & PBVH_Collapse) {
+ EdgeQueue q;
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
+ 128, 128, 0);
+ short_edge_queue_create(&q, queue_pool, bvh, center, radius);
+ pbvh_bmesh_collapse_short_edges(bvh, &q, queue_pool, &edge_faces,
+ &deleted_faces);
+ BLI_heap_free(q.heap, NULL);
+ BLI_mempool_destroy(queue_pool);
+ }
+
+ if (mode & PBVH_Subdivide) {
+ EdgeQueue q;
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
+ 128, 128, 0);
+ long_edge_queue_create(&q, queue_pool, bvh, center, radius);
+ pbvh_bmesh_subdivide_long_edges(bvh, &q, queue_pool, &edge_faces);
+ BLI_heap_free(q.heap, NULL);
+ BLI_mempool_destroy(queue_pool);
+ }
+
+ /* Unmark nodes */
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ if (node->flag & PBVH_Leaf &&
+ node->flag & PBVH_UpdateTopology)
+ {
+ node->flag &= ~PBVH_UpdateTopology;
+ }
+ }
+ BLI_buffer_free(&edge_faces);
+ BLI_buffer_free(&deleted_faces);
+
+ return modified;
+}
+
+/* In order to perform operations on the original node coordinates
+ * (such as raycast), store the node's triangles and vertices.*/
+void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
+{
+ GHashIterator gh_iter;
+ int i, totvert, tottri;
+
+ /* Skip if original coords/triangles are already saved */
+ if (node->bm_orco)
+ return;
+
+ totvert = (BLI_ghash_size(node->bm_unique_verts) +
+ BLI_ghash_size(node->bm_other_verts));
+
+ tottri = BLI_ghash_size(node->bm_faces);
+
+ node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, AT);
+ node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, AT);
+
+ /* Copy out the vertices and assign a temporary index */
+ i = 0;
+ GHASH_ITER (gh_iter, node->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ copy_v3_v3(node->bm_orco[i], v->co);
+ BM_elem_index_set(v, i); /* set_dirty! */
+ i++;
+ }
+ GHASH_ITER (gh_iter, node->bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ copy_v3_v3(node->bm_orco[i], v->co);
+ BM_elem_index_set(v, i); /* set_dirty! */
+ i++;
+ }
+
+ /* Copy the triangles */
+ i = 0;
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMIter bm_iter;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMVert *v;
+ int j = 0;
+
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ node->bm_ortri[i][j] = BM_elem_index_get(v);
+ j++;
+ }
+ i++;
+ }
+ node->bm_tot_ortri = i;
+}
+
+void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
+{
+ int i;
+ for (i = 0; i < bvh->totnode; i++) {
+ PBVHNode *n = &bvh->nodes[i];
+ if (n->flag & PBVH_Leaf) {
+ /* Free orco/ortri data */
+ pbvh_bmesh_node_drop_orig(n);
+
+ /* Recursively split nodes that have gotten too many
+ * elements */
+ pbvh_bmesh_node_limit_ensure(bvh, i);
+ }
+ }
+}
+
+void BKE_pbvh_bmesh_detail_size_set(PBVH *bvh, float detail_size)
+{
+ bvh->bm_max_edge_len = detail_size;
+ bvh->bm_min_edge_len = bvh->bm_max_edge_len * 0.4f;
+}
+
+void BKE_pbvh_node_mark_topology_update(PBVHNode *node)
+{
+ node->flag |= PBVH_UpdateTopology;
+}
+
+GHash *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node)
+{
+ return node->bm_unique_verts;
+}
+
+GHash *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node)
+{
+ return node->bm_other_verts;
+}
+
+/****************************** Debugging *****************************/
+
+#if 0
+void bli_ghash_duplicate_key_check(GHash *gh)
+{
+ GHashIterator gh_iter1, gh_iter2;
+
+ GHASH_ITER (gh_iter1, gh) {
+ void *key1 = BLI_ghashIterator_getKey(&gh_iter1);
+ int dup = -1;
+
+ GHASH_ITER (gh_iter2, gh) {
+ void *key2 = BLI_ghashIterator_getKey(&gh_iter2);
+
+ if (key1 == key2) {
+ dup++;
+ if (dup > 0) {
+ BLI_assert(!"duplicate in hash");
+ }
+ }
+ }
+ }
+}
+
+void bmesh_print(BMesh *bm)
+{
+ BMIter iter, siter;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+ BMLoop *l;
+
+ fprintf(stderr, "\nbm=%p, totvert=%d, totedge=%d, "
+ "totloop=%d, totface=%d\n",
+ bm, bm->totvert, bm->totedge,
+ bm->totloop, bm->totface);
+
+ fprintf(stderr, "vertices:\n");
+ BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+ fprintf(stderr, " %d co=(%.3f %.3f %.3f) oflag=%x\n",
+ BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
+ v->oflags[bm->stackdepth - 1].f);
+ }
+
+ fprintf(stderr, "edges:\n");
+ BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+ fprintf(stderr, " %d v1=%d, v2=%d, oflag=%x\n",
+ BM_elem_index_get(e),
+ BM_elem_index_get(e->v1),
+ BM_elem_index_get(e->v2),
+ e->oflags[bm->stackdepth - 1].f);
+ }
+
+ fprintf(stderr, "faces:\n");
+ BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
+ fprintf(stderr, " %d len=%d, oflag=%x\n",
+ BM_elem_index_get(f), f->len,
+ f->oflags[bm->stackdepth - 1].f);
+
+ fprintf(stderr, " v: ");
+ BM_ITER_ELEM(v, &siter, f, BM_VERTS_OF_FACE) {
+ fprintf(stderr, "%d ", BM_elem_index_get(v));
+ }
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " e: ");
+ BM_ITER_ELEM(e, &siter, f, BM_EDGES_OF_FACE) {
+ fprintf(stderr, "%d ", BM_elem_index_get(e));
+ }
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " l: ");
+ BM_ITER_ELEM(l, &siter, f, BM_LOOPS_OF_FACE) {
+ fprintf(stderr, "%d(v=%d, e=%d) ",
+ BM_elem_index_get(l),
+ BM_elem_index_get(l->v),
+ BM_elem_index_get(l->e));
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+void pbvh_bmesh_print(PBVH *bvh)
+{
+ GHashIterator gh_iter;
+ int n;
+
+ fprintf(stderr, "\npbvh=%p\n", bvh);
+ fprintf(stderr, "bm_face_to_node:\n");
+ GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
+ fprintf(stderr, " %d -> %d\n",
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ }
+
+ fprintf(stderr, "bm_vert_to_node:\n");
+ GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
+ fprintf(stderr, " %d -> %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ }
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+ if (!(node->flag & PBVH_Leaf))
+ continue;
+
+ fprintf(stderr, "node %d\n faces:\n", n);
+ GHASH_ITER (gh_iter, node->bm_faces)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
+ fprintf(stderr, " unique verts:\n");
+ GHASH_ITER (gh_iter, node->bm_unique_verts)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ fprintf(stderr, " other verts:\n");
+ GHASH_ITER (gh_iter, node->bm_other_verts)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ }
+}
+
+void print_flag_factors(int flag)
+{
+ int i;
+ printf("flag=0x%x:\n", flag);
+ for (i = 0; i < 32; i++) {
+ if (flag & (1 << i)) {
+ printf(" %d (1 << %d)\n", 1 << i, i);
+ }
+ }
+}
+
+void pbvh_bmesh_verify(PBVH *bvh)
+{
+ GHashIterator gh_iter;
+ int i;
+
+ /* Check faces */
+ BLI_assert(bvh->bm->totface == BLI_ghash_size(bvh->bm_face_to_node));
+ GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghashIterator_getValue(&gh_iter);
+ int ni = GET_INT_FROM_POINTER(nip);
+ PBVHNode *n = &bvh->nodes[ni];
+
+ /* Check that the face's node is a leaf */
+ BLI_assert(n->flag & PBVH_Leaf);
+
+ /* Check that the face's node knows it owns the face */
+ BLI_assert(BLI_ghash_haskey(n->bm_faces, f));
+
+ /* Check the face's vertices... */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ PBVHNode *nv;
+
+ /* Check that the vertex is in the node */
+ BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v) ^
+ BLI_ghash_haskey(n->bm_other_verts, v));
+
+ /* Check that the vertex has a node owner */
+ nv = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+
+ /* Check that the vertex's node knows it owns the vert */
+ BLI_assert(BLI_ghash_haskey(nv->bm_unique_verts, v));
+
+ /* Check that the vertex isn't duplicated as an 'other' vert */
+ BLI_assert(!BLI_ghash_haskey(nv->bm_other_verts, v));
+ }
+ }
+
+ /* Check verts */
+ BLI_assert(bvh->bm->totvert == BLI_ghash_size(bvh->bm_vert_to_node));
+ GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
+ BMIter bm_iter;
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BMFace *f;
+ void *nip = BLI_ghashIterator_getValue(&gh_iter);
+ int ni = GET_INT_FROM_POINTER(nip);
+ PBVHNode *n = &bvh->nodes[ni];
+ int found;
+
+ /* Check that the vert's node is a leaf */
+ BLI_assert(n->flag & PBVH_Leaf);
+
+ /* Check that the vert's node knows it owns the vert */
+ BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v));
+
+ /* Check that the vertex isn't duplicated as an 'other' vert */
+ BLI_assert(!BLI_ghash_haskey(n->bm_other_verts, v));
+
+ /* Check that the vert's node also contains one of the vert's
+ * adjacent faces */
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ if (BLI_ghash_lookup(bvh->bm_face_to_node, f) == nip) {
+ found = TRUE;
+ break;
+ }
+ }
+ BLI_assert(found);
+ }
+
+ /* Check that node elements are recorded in the top level */
+ for (i = 0; i < bvh->totnode; i++) {
+ PBVHNode *n = &bvh->nodes[i];
+ if (n->flag & PBVH_Leaf) {
+ /* Check for duplicate entries */
+ /* Slow */
+ #if 0
+ bli_ghash_duplicate_key_check(n->bm_faces);
+ bli_ghash_duplicate_key_check(n->bm_unique_verts);
+ bli_ghash_duplicate_key_check(n->bm_other_verts);
+ #endif
+
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghash_lookup(bvh->bm_face_to_node, f);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_face_to_node, f));
+ BLI_assert(GET_INT_FROM_POINTER(nip) == (n - bvh->nodes));
+ }
+
+ GHASH_ITER (gh_iter, n->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghash_lookup(bvh->bm_vert_to_node, v);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ BLI_assert(!BLI_ghash_haskey(n->bm_other_verts, v));
+ BLI_assert(GET_INT_FROM_POINTER(nip) == (n - bvh->nodes));
+ }
+
+ GHASH_ITER (gh_iter, n->bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ BLI_assert(BM_vert_face_count(v) > 0);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
new file mode 100644
index 0000000..b3f7bf6
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -0,0 +1,186 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#ifndef __PBVH_INTERN_H__
+#define __PBVH_INTERN_H__
+
+/* Axis-aligned bounding box */
+typedef struct {
+ float bmin[3], bmax[3];
+} BB;
+
+/* Axis-aligned bounding box with centroid */
+typedef struct {
+ float bmin[3], bmax[3], bcentroid[3];
+} BBC;
+
+/* Note: this structure is getting large, might want to split it into
+ * union'd structs */
+struct PBVHNode {
+ /* Opaque handle for drawing code */
+ struct GPU_Buffers *draw_buffers;
+
+ /* Voxel bounds */
+ BB vb;
+ BB orig_vb;
+
+ /* For internal nodes, the offset of the children in the PBVH
+ * 'nodes' array. */
+ int children_offset;
+
+ /* Pointer into the PBVH prim_indices array and the number of
+ * primitives used by this leaf node.
+ *
+ * Used for leaf nodes in both mesh- and multires-based PBVHs.
+ */
+ int *prim_indices;
+ unsigned int totprim;
+
+ /* Array of indices into the mesh's MVert array. Contains the
+ * indices of all vertices used by faces that are within this
+ * node's bounding box.
+ *
+ * Note that a vertex might be used by a multiple faces, and
+ * these faces might be in different leaf nodes. Such a vertex
+ * will appear in the vert_indices array of each of those leaf
+ * nodes.
+ *
+ * In order to support cases where you want access to multiple
+ * nodes' vertices without duplication, the vert_indices array
+ * is ordered such that the first part of the array, up to
+ * index 'uniq_verts', contains "unique" vertex indices. These
+ * vertices might not be truly unique to this node, but if
+ * they appear in another node's vert_indices array, they will
+ * be above that node's 'uniq_verts' value.
+ *
+ * Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int *vert_indices;
+ unsigned int uniq_verts, face_verts;
+
+ /* An array mapping face corners into the vert_indices
+ * array. The array is sized to match 'totprim', and each of
+ * the face's corners gets an index into the vert_indices
+ * array, in the same order as the corners in the original
+ * MFace. The fourth value should not be used if the original
+ * face is a triangle.
+ *
+ * Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int (*face_vert_indices)[4];
+
+ /* Indicates whether this node is a leaf or not; also used for
+ * marking various updates that need to be applied. */
+ PBVHNodeFlags flag : 16;
+
+ /* Used for raycasting: how close bb is to the ray point. */
+ float tmin;
+
+ /* Scalar displacements for sculpt mode's layer brush. */
+ float *layer_disp;
+
+ int proxy_count;
+ PBVHProxyNode *proxies;
+
+ /* Dyntopo */
+ GHash *bm_faces;
+ GHash *bm_unique_verts;
+ GHash *bm_other_verts;
+ float (*bm_orco)[3];
+ int (*bm_ortri)[3];
+ int bm_tot_ortri;
+};
+
+typedef enum {
+ PBVH_DYNTOPO_SMOOTH_SHADING = 1
+} PBVHFlags;
+
+typedef struct PBVHBMeshLog PBVHBMeshLog;
+
+struct PBVH {
+ PBVHType type;
+ PBVHFlags flags;
+
+ PBVHNode *nodes;
+ int node_mem_count, totnode;
+
+ int *prim_indices;
+ int totprim;
+ int totvert;
+
+ int leaf_limit;
+
+ /* Mesh data */
+ MVert *verts;
+ MFace *faces;
+ CustomData *vdata;
+
+ /* Grid Data */
+ CCGKey gridkey;
+ CCGElem **grids;
+ DMGridAdjacency *gridadj;
+ void **gridfaces;
+ const DMFlagMat *grid_flag_mats;
+ int totgrid;
+ BLI_bitmap *grid_hidden;
+
+ /* Only used during BVH build and update,
+ * don't need to remain valid after */
+ BLI_bitmap vert_bitmap;
+
+#ifdef PERFCNTRS
+ int perf_modified;
+#endif
+
+ /* flag are verts/faces deformed */
+ int deformed;
+
+ int show_diffuse_color;
+
+ /* Dynamic topology */
+ BMesh *bm;
+ GHash *bm_face_to_node;
+ GHash *bm_vert_to_node;
+ float bm_max_edge_len;
+ float bm_min_edge_len;
+
+ struct BMLog *bm_log;
+};
+
+/* pbvh.c */
+void BB_reset(BB *bb);
+void BB_expand(BB *bb, const float co[3]);
+void BB_expand_with_bb(BB *bb, BB *bb2);
+void BBC_update_centroid(BBC *bbc);
+int BB_widest_axis(const BB *bb);
+void pbvh_grow_nodes(PBVH *bvh, int totnode);
+int ray_face_intersection(const float ray_start[3], const float ray_normal[3],
+ const float *t0, const float *t1, const float *t2,
+ const float *t3, float *fdist);
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
+
+/* pbvh_bmesh.c */
+int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ int use_original);
+
+void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
+
+#endif
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 965a1e2..9794868 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -272,7 +272,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
ParticleSystem *psys= psys_v;
ParticleData *pa;
BoidParticle *boid;
- float timestep = 0.04f*psys->part->timetweak;
+ float timestep = 0.04f * psys->part->timetweak;
if (index >= psys->totpart)
return;
@@ -333,7 +333,7 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f
ParticleSystem *psys= psys_v;
ParticleData *pa;
ParticleKey keys[4];
- float dfra, timestep = 0.04f*psys->part->timetweak;
+ float dfra, timestep = 0.04f * psys->part->timetweak;
if (index >= psys->totpart)
return;
@@ -559,7 +559,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v)
float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b;
unsigned char *obstacles;
unsigned int in_len = sizeof(float)*(unsigned int)res;
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
//int mode = res >= 1000000 ? 2 : 1;
int mode=1; // light
if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy
@@ -792,7 +792,7 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v)
int cache_compress = 1;
/* version header */
- ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char)*4);
+ ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char) * 4);
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
int total_points=surface->data->total_points;
@@ -831,7 +831,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
char version[4];
/* version header */
- ptcache_file_read(pf, version, 1, sizeof(char)*4);
+ ptcache_file_read(pf, version, 1, sizeof(char) * 4);
if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;}
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
@@ -1163,7 +1163,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
*/
#define MAX_PTCACHE_PATH FILE_MAX
-#define MAX_PTCACHE_FILE ((FILE_MAX)*2)
+#define MAX_PTCACHE_FILE (FILE_MAX * 2)
static int ptcache_path(PTCacheID *pid, char *filename)
{
@@ -1258,7 +1258,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
{
PTCacheFile *pf;
FILE *fp = NULL;
- char filename[(FILE_MAX)*2];
+ char filename[FILE_MAX * 2];
#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow writing for linked objects */
@@ -1311,7 +1311,7 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result,
size_t out_len = len;
#endif
unsigned char *in;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp");
ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
if (compressed) {
@@ -1354,7 +1354,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns
int r = 0;
unsigned char compressed = 0;
size_t out_len= 0;
- unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp");
size_t sizeOfIt = 5;
(void)mode; /* unused when building w/o compression */
@@ -1540,7 +1540,7 @@ void BKE_ptcache_mem_pointers_incr(PTCacheMem *pm)
for (i=0; i<BPHYS_TOT_DATA; i++) {
if (pm->cur[i])
- pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
+ pm->cur[i] = (char *)pm->cur[i] + ptcache_data_size[i];
}
}
int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
@@ -1558,7 +1558,7 @@ int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
}
for (i=0; i<BPHYS_TOT_DATA; i++)
- pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+ pm->cur[i] = data_types & (1<<i) ? (char *)pm->data[i] + index * ptcache_data_size[i] : NULL;
return 1;
}
@@ -1787,7 +1787,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
for (i=0; i<BPHYS_TOT_DATA; i++) {
if (pm->data[i]) {
unsigned int in_len = pm->totpoint*ptcache_data_size[i];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
@@ -1820,7 +1820,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
if (pid->cache->compression) {
unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type];
- unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer");
ptcache_file_compressed_write(pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression);
MEM_freeN(out);
}
@@ -2782,7 +2782,8 @@ static PointCache *ptcache_copy(PointCache *cache, int copy_data)
ncache->mem_cache.last = NULL;
ncache->cached_frames = NULL;
- ncache->flag= 0;
+ /* flag is a mix of user settings and simulator/baking state */
+ ncache->flag= ncache->flag & (PTCACHE_DISK_CACHE|PTCACHE_EXTERNAL|PTCACHE_IGNORE_LIBPATH);
ncache->simframe= 0;
}
else {
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index 8da4f11..c465871 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -287,7 +287,7 @@ void BKE_bproperty_add(bProperty *prop, const char *str)
}
/* reads value of property, sets it in chars in str */
-void BKE_bproperty_set_valstr(bProperty *prop, char *str)
+void BKE_bproperty_set_valstr(bProperty *prop, char str[MAX_PROPSTRING])
{
// extern int Gdfra; /* sector.c */
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index d925d73..1fd7dc1 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -27,6 +27,10 @@
* \ingroup bke
*/
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
#include "MEM_guardedalloc.h"
@@ -39,10 +43,6 @@
#include "BKE_report.h"
#include "BKE_global.h" /* G.background only */
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
static const char *report_type_str(int type)
{
switch (type) {
@@ -52,6 +52,8 @@ static const char *report_type_str(int type)
return TIP_("Info");
case RPT_OPERATOR:
return TIP_("Operator");
+ case RPT_PROPERTY:
+ return TIP_("Property");
case RPT_WARNING:
return TIP_("Warning");
case RPT_ERROR:
@@ -300,3 +302,36 @@ int BKE_reports_contain(ReportList *reports, ReportType level)
return FALSE;
}
+bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
+{
+ Report *report;
+
+ if (header) {
+ fputs(header, fp);
+ }
+
+ for (report = reports->list.first; report; report = report->next) {
+ fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
+ }
+
+ return true;
+}
+
+bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
+{
+ FILE *fp;
+
+ errno = 0;
+ fp = BLI_fopen(filepath, "wb");
+ if (fp == NULL) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ filepath, errno ? strerror(errno) : "Unknown error opening file");
+ return false;
+ }
+
+ BKE_report_write_file_fp(fp, reports, header);
+
+ fclose(fp);
+
+ return true;
+}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 9bb2fb2..9cf0724 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -143,7 +143,8 @@ Scene *BKE_scene_copy(Scene *sce, int type)
if (type == SCE_COPY_EMPTY) {
ListBase lb;
- scen = BKE_scene_add(sce->id.name + 2);
+ /* XXX. main should become an arg */
+ scen = BKE_scene_add(G.main, sce->id.name + 2);
lb = scen->r.layers;
scen->r = sce->r;
@@ -372,9 +373,8 @@ void BKE_scene_free(Scene *sce)
BKE_color_managed_view_settings_free(&sce->view_settings);
}
-Scene *BKE_scene_add(const char *name)
+static Scene *scene_add(Main *bmain, const char *name)
{
- Main *bmain = G.main;
Scene *sce;
ParticleEditSettings *pset;
int a;
@@ -400,6 +400,7 @@ Scene *BKE_scene_add(const char *name)
sce->r.im_format.planes = R_IMF_PLANES_RGB;
sce->r.im_format.imtype = R_IMF_IMTYPE_PNG;
+ sce->r.im_format.depth = R_IMF_CHAN_DEPTH_8;
sce->r.im_format.quality = 90;
sce->r.im_format.compress = 90;
@@ -432,6 +433,8 @@ Scene *BKE_scene_add(const char *name)
sce->r.bake_osa = 5;
sce->r.bake_flag = R_BAKE_CLEAR;
sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
+ sce->r.bake_samples = 256;
+ sce->r.bake_biasdist = 0.001;
sce->r.scemode = R_DOCOMP | R_DOSEQ | R_EXTENSION;
sce->r.stamp = R_STAMP_TIME | R_STAMP_FRAME | R_STAMP_DATE | R_STAMP_CAMERA | R_STAMP_SCENE | R_STAMP_FILENAME | R_STAMP_RENDERTIME;
sce->r.stamp_font_id = 12;
@@ -605,6 +608,11 @@ Scene *BKE_scene_add(const char *name)
return sce;
}
+Scene *BKE_scene_add(Main *bmain, const char *name)
+{
+ return scene_add(bmain, name);
+}
+
Base *BKE_scene_base_find(Scene *scene, Object *ob)
{
return BLI_findptr(&scene->base, ob, offsetof(Base, object));
@@ -1023,6 +1031,47 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
}
}
+/* deps hack - do extra recalcs at end */
+static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
+{
+ Base *base;
+
+ scene->customdata_mask = scene_parent->customdata_mask;
+
+ /* sets first, we allow per definition current scene to have
+ * dependencies on sets, but not the other way around. */
+ if (scene->set)
+ scene_depsgraph_hack(scene->set, scene_parent);
+
+ for (base = scene->base.first; base; base = base->next) {
+ Object *ob = base->object;
+
+ if (ob->depsflag) {
+ int recalc = 0;
+ // printf("depshack %s\n", ob->id.name+2);
+
+ if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC)
+ recalc |= OB_RECALC_OB;
+ if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC)
+ recalc |= OB_RECALC_DATA;
+
+ ob->recalc |= recalc;
+ BKE_object_handle_update(scene_parent, ob);
+
+ if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) {
+ GroupObject *go;
+
+ for (go = ob->dup_group->gobject.first; go; go = go->next) {
+ if (go->ob)
+ go->ob->recalc |= recalc;
+ }
+ group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
+ }
+ }
+ }
+
+}
+
static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
{
Base *base;
@@ -1058,6 +1107,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* update masking curves */
BKE_mask_update_scene(bmain, scene, FALSE);
+
}
/* this is called in main loop, doing tagged updates before redraw */
@@ -1150,6 +1200,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
/* BKE_object_handle_update() on all objects, groups and sets */
scene_update_tagged_recursive(bmain, sce, sce);
+ scene_depsgraph_hack(sce, sce);
+
/* notify editors and python about recalc */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 56fddfd..95b72d0 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -167,6 +167,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
newar->prev = newar->next = NULL;
newar->handlers.first = newar->handlers.last = NULL;
newar->uiblocks.first = newar->uiblocks.last = NULL;
+ newar->ui_lists.first = newar->ui_lists.last = NULL;
newar->swinid = 0;
/* use optional regiondata callback */
@@ -279,6 +280,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
}
BLI_freelistN(&ar->panels);
+ BLI_freelistN(&ar->ui_lists);
}
/* not area itself */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 0b7fdaa..c64609c 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -156,42 +156,43 @@ static void init_alpha_over_or_under(Sequence *seq)
seq->seq1 = seq2;
}
-static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
- int fac2, mfac, fac, fac4;
- int xo, tempc;
- char *rt1, *rt2, *rt;
+ float fac2, mfac, fac, fac4;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *) rect1;
- rt2 = (char *) rect2;
- rt = (char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac2 = (int) (256.0f * facf0);
- fac4 = (int) (256.0f * facf1);
+ fac2 = facf0;
+ fac4 = facf1;
while (y--) {
x = xo;
while (x--) {
-
/* rt = rt1 over rt2 (alpha from rt1) */
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
fac = fac2;
- mfac = 256 - ( (fac2 * rt1[3]) >> 8);
+ mfac = 1.0f - fac2 * rt1[3];
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
- else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+ if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+ else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
else {
- tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
- if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
- tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
- if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
- tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
- if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
- tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
- if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+ tempc[0] = fac * rt1[0] + mfac * rt2[0];
+ tempc[1] = fac * rt1[1] + mfac * rt2[1];
+ tempc[2] = fac * rt1[2] + mfac * rt2[2];
+ tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
}
- rt1 += 4; rt2 += 4; rt += 4;
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0) break;
@@ -199,22 +200,23 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, ch
x = xo;
while (x--) {
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
fac = fac4;
- mfac = 256 - ( (fac4 * rt1[3]) >> 8);
+ mfac = 1.0f - (fac4 * rt1[3]);
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
- else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+ if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+ else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
else {
- tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
- if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
- tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
- if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
- tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
- if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
- tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
- if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+ tempc[0] = fac * rt1[0] + mfac * rt2[0];
+ tempc[1] = fac * rt1[1] + mfac * rt2[1];
+ tempc[2] = fac * rt1[2] + mfac * rt2[2];
+ tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
}
- rt1 += 4; rt2 += 4; rt += 4;
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -298,17 +300,17 @@ static void do_alphaover_effect(SeqRenderData context, Sequence *UNUSED(seq), fl
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
/*********************** Alpha Under *************************/
-static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
int fac2, mfac, fac, fac4;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
rt1 = rect1;
@@ -460,17 +462,17 @@ static void do_alphaunder_effect(SeqRenderData context, Sequence *UNUSED(seq), f
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
/*********************** Cross *************************/
-static void do_cross_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_cross_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
int fac1, fac2, fac3, fac4;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
rt1 = rect1;
@@ -570,7 +572,7 @@ static void do_cross_effect(SeqRenderData context, Sequence *UNUSED(seq), float
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
@@ -713,31 +715,32 @@ static void free_gammacross(Sequence *UNUSED(seq))
static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1,
unsigned char *rect2, unsigned char *out)
{
- int fac1, fac2, col;
+ float fac1, fac2;
int xo;
- unsigned char *rt1, *rt2, *rt;
-
+ unsigned char *cp1, *cp2, *rt;
+ float rt1[4], rt2[4], tempc[4];
+
xo = x;
- rt1 = (unsigned char *) rect1;
- rt2 = (unsigned char *) rect2;
- rt = (unsigned char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac2 = (int)(256.0f * facf0);
- fac1 = 256 - fac2;
+ fac2 = facf0;
+ fac1 = 1.0f - fac2;
while (y--) {
x = xo;
while (x--) {
- col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
- if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
- if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
- if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
- if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
+ tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
+ tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
+ tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
+
+ premul_float_to_straight_uchar(rt, tempc);
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -746,16 +749,16 @@ static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x,
x = xo;
while (x--) {
- col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
- if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
- if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
- if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
- if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
+ tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
+ tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
+ tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
+
+ premul_float_to_straight_uchar(rt, tempc);
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -828,31 +831,34 @@ static void do_gammacross_effect(SeqRenderData context, Sequence *UNUSED(seq), f
static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2,
unsigned char *out)
{
- int col, xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float fac1, fac3;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac1 = (int)(256.0f * facf0);
- fac3 = (int)(256.0f * facf1);
+ fac1 = facf0;
+ fac3 = facf1;
while (y--) {
x = xo;
while (x--) {
- col = rt1[0] + ((fac1 * rt2[0]) >> 8);
- if (col > 255) rt[0] = 255; else rt[0] = col;
- col = rt1[1] + ((fac1 * rt2[1]) >> 8);
- if (col > 255) rt[1] = 255; else rt[1] = col;
- col = rt1[2] + ((fac1 * rt2[2]) >> 8);
- if (col > 255) rt[2] = 255; else rt[2] = col;
- col = rt1[3] + ((fac1 * rt2[3]) >> 8);
- if (col > 255) rt[3] = 255; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] + fac1 * rt2[0];
+ tempc[1] = rt1[1] + fac1 * rt2[1];
+ tempc[2] = rt1[2] + fac1 * rt2[2];
+ tempc[3] = min_ff(1.0f, rt1[3] + fac1 * rt2[3]);
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -861,16 +867,17 @@ static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned
x = xo;
while (x--) {
- col = rt1[0] + ((fac3 * rt2[0]) >> 8);
- if (col > 255) rt[0] = 255; else rt[0] = col;
- col = rt1[1] + ((fac3 * rt2[1]) >> 8);
- if (col > 255) rt[1] = 255; else rt[1] = col;
- col = rt1[2] + ((fac3 * rt2[2]) >> 8);
- if (col > 255) rt[2] = 255; else rt[2] = col;
- col = rt1[3] + ((fac3 * rt2[3]) >> 8);
- if (col > 255) rt[3] = 255; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] + fac3 * rt2[0];
+ tempc[1] = rt1[1] + fac3 * rt2[1];
+ tempc[2] = rt1[2] + fac3 * rt2[2];
+ tempc[3] = min_ff(1.0f, rt1[3] + fac3 * rt2[3]);
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -890,22 +897,28 @@ static void do_add_effect_float(float facf0, float facf1, int x, int y, float *r
fac3 = facf1;
while (y--) {
- x = xo * 4;
+ x = xo;
while (x--) {
- *rt = *rt1 + fac1 * (*rt2);
+ rt[0] = rt1[0] + fac1 * rt2[0];
+ rt[1] = rt1[1] + fac1 * rt2[1];
+ rt[2] = rt1[2] + fac1 * rt2[2];
+ rt[3] = min_ff(1.0f, rt1[3] + fac1 * rt2[3]);
- rt1++; rt2++; rt++;
+ rt1 += 4; rt2 += 4; rt += 4;
}
if (y == 0)
break;
y--;
- x = xo * 4;
+ x = xo;
while (x--) {
- *rt = *rt1 + fac3 * (*rt2);
+ rt[0] = rt1[0] + fac1 * rt2[0];
+ rt[1] = rt1[1] + fac1 * rt2[1];
+ rt[2] = rt1[2] + fac1 * rt2[2];
+ rt[3] = min_ff(1.0f, rt1[3] + fac3 * rt2[3]);
- rt1++; rt2++; rt++;
+ rt1 += 4; rt2 += 4; rt += 4;
}
}
}
@@ -931,32 +944,35 @@ static void do_add_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
/*********************** Sub *************************/
-static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
- int col, xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float fac1, fac3;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *) rect1;
- rt2 = (char *) rect2;
- rt = (char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac1 = (int) (256.0f * facf0);
- fac3 = (int) (256.0f * facf1);
+ fac1 = facf0;
+ fac3 = facf1;
while (y--) {
x = xo;
while (x--) {
- col = rt1[0] - ((fac1 * rt2[0]) >> 8);
- if (col < 0) rt[0] = 0; else rt[0] = col;
- col = rt1[1] - ((fac1 * rt2[1]) >> 8);
- if (col < 0) rt[1] = 0; else rt[1] = col;
- col = rt1[2] - ((fac1 * rt2[2]) >> 8);
- if (col < 0) rt[2] = 0; else rt[2] = col;
- col = rt1[3] - ((fac1 * rt2[3]) >> 8);
- if (col < 0) rt[3] = 0; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] - fac1 * rt2[0];
+ tempc[1] = rt1[1] - fac1 * rt2[1];
+ tempc[2] = rt1[2] - fac1 * rt2[2];
+ tempc[3] = rt1[3] - fac1 * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -965,16 +981,17 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rec
x = xo;
while (x--) {
- col = rt1[0] - ((fac3 * rt2[0]) >> 8);
- if (col < 0) rt[0] = 0; else rt[0] = col;
- col = rt1[1] - ((fac3 * rt2[1]) >> 8);
- if (col < 0) rt[1] = 0; else rt[1] = col;
- col = rt1[2] - ((fac3 * rt2[2]) >> 8);
- if (col < 0) rt[2] = 0; else rt[2] = col;
- col = rt1[3] - ((fac3 * rt2[3]) >> 8);
- if (col < 0) rt[3] = 0; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] - fac3 * rt2[0];
+ tempc[1] = rt1[1] - fac3 * rt2[1];
+ tempc[2] = rt1[2] - fac3 * rt2[2];
+ tempc[3] = rt1[3] - fac3 * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -1029,7 +1046,7 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
@@ -1039,10 +1056,10 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
#define XOFF 8
#define YOFF 8
-static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *rect2i, char *rect1i, char *outi)
+static void do_drop_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
{
int height, width, temp, fac, fac1, fac2;
- char *rt1, *rt2, *out;
+ unsigned char *rt1, *rt2, *out;
int field = 1;
width = x;
@@ -1051,9 +1068,9 @@ static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *re
fac1 = (int) (70.0f * facf0);
fac2 = (int) (70.0f * facf1);
- rt2 = (char *) (rect2i + YOFF * width);
- rt1 = (char *) rect1i;
- out = (char *) outi;
+ rt2 = (unsigned char *) (rect2i + YOFF * width);
+ rt1 = (unsigned char *) rect1i;
+ out = (unsigned char *) outi;
for (y = 0; y < height - YOFF; y++) {
if (field) fac = fac1;
else fac = fac2;
@@ -1122,18 +1139,18 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned
unsigned char *out)
{
int xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ rt1 = rect1;
+ rt2 = rect2;
+ rt = out;
fac1 = (int)(256.0f * facf0);
fac3 = (int)(256.0f * facf1);
/* formula:
- * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
+ * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx
* yaux = -s * px + c * py; //+centy
*/
@@ -1539,13 +1556,13 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
WipeZone wipezone;
WipeVars *wipe = (WipeVars *)seq->effectdata;
int xo, yo;
- char *rt1, *rt2, *rt;
+ unsigned char *cp1, *cp2, *rt;
precalc_wipe_zone(&wipezone, wipe, x, y);
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
xo = x;
yo = y;
@@ -1553,11 +1570,18 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
for (x = 0; x < xo; x++) {
float check = check_zone(&wipezone, x, y, seq, facf0);
if (check) {
- if (rt1) {
- rt[0] = (int)(rt1[0] * check) + (int)(rt2[0] * (1 - check));
- rt[1] = (int)(rt1[1] * check) + (int)(rt2[1] * (1 - check));
- rt[2] = (int)(rt1[2] * check) + (int)(rt2[2] * (1 - check));
- rt[3] = (int)(rt1[3] * check) + (int)(rt2[3] * (1 - check));
+ if (cp1) {
+ float rt1[4], rt2[4], tempc[4];
+
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
+ tempc[0] = rt1[0] * check + rt2[0] * (1 - check);
+ tempc[1] = rt1[1] * check + rt2[1] * (1 - check);
+ tempc[2] = rt1[2] * check + rt2[2] * (1 - check);
+ tempc[3] = rt1[3] * check + rt2[3] * (1 - check);
+
+ premul_float_to_straight_uchar(rt, tempc);
}
else {
rt[0] = 0;
@@ -1567,11 +1591,11 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
}
}
else {
- if (rt2) {
- rt[0] = rt2[0];
- rt[1] = rt2[1];
- rt[2] = rt2[2];
- rt[3] = rt2[3];
+ if (cp2) {
+ rt[0] = cp2[0];
+ rt[1] = cp2[1];
+ rt[2] = cp2[2];
+ rt[3] = cp2[3];
}
else {
rt[0] = 0;
@@ -1582,11 +1606,11 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
}
rt += 4;
- if (rt1 != NULL) {
- rt1 += 4;
+ if (cp1 != NULL) {
+ cp1 += 4;
}
- if (rt2 != NULL) {
- rt2 += 4;
+ if (cp2 != NULL) {
+ cp2 += 4;
}
}
}
@@ -1745,7 +1769,7 @@ static void transform_image(int x, int y, ImBuf *ibuf1, ImBuf *out, float scale
/* interpolate */
switch (interpolation) {
case 0:
- neareast_interpolation(ibuf1, out, xt, yt, xi, yi);
+ nearest_interpolation(ibuf1, out, xt, yt, xi, yi);
break;
case 1:
bilinear_interpolation(ibuf1, out, xt, yt, xi, yi);
@@ -1803,166 +1827,6 @@ static ImBuf *do_transform_effect(SeqRenderData context, Sequence *seq, float UN
/*********************** Glow *************************/
-static void RVBlurBitmap2_byte(unsigned char *map, int width, int height, float blur, int quality)
-/* MUUUCCH better than the previous blur. */
-/* We do the blurring in two passes which is a whole lot faster. */
-/* I changed the math arount to implement an actual Gaussian */
-/* distribution. */
-/* */
-/* Watch out though, it tends to misbehaven with large blur values on */
-/* a small bitmap. Avoid avoid avoid. */
-/*=============================== */
-{
- unsigned char *temp = NULL, *swap;
- float *filter = NULL;
- int x, y, i, fx, fy;
- int index, ix, halfWidth;
- float fval, k, curColor[3], curColor2[3], weight = 0;
-
- /* If we're not really blurring, bail out */
- if (blur <= 0)
- return;
-
- /*Allocate memory for the tempmap and the blur filter matrix */
- temp = MEM_mallocN((width * height * 4), "blurbitmaptemp");
- if (!temp)
- return;
-
- /*Allocate memory for the filter elements */
- halfWidth = ((quality + 1) * blur);
- filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
- if (!filter) {
- MEM_freeN(temp);
- return;
- }
-
- /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
- * This code is based on an example posted to comp.graphics.algorithms by
- * Blancmange (bmange at airdmhor.gen.nz)
- */
-
- k = -1.0f / (2.0f * (float)M_PI * blur * blur);
- for (ix = 0; ix < halfWidth; ix++) {
- weight = (float)exp(k * (ix * ix));
- filter[halfWidth - ix] = weight;
- filter[halfWidth + ix] = weight;
- }
- filter[0] = weight;
-
- /* Normalize the array */
- fval = 0;
- for (ix = 0; ix < halfWidth * 2; ix++)
- fval += filter[ix];
-
- for (ix = 0; ix < halfWidth * 2; ix++)
- filter[ix] /= fval;
-
- /* Blur the rows */
- for (y = 0; y < height; y++) {
- /* Do the left & right strips */
- for (x = 0; x < halfWidth; x++) {
- index = (x + y * width) * 4;
- fx = 0;
- zero_v3(curColor);
- zero_v3(curColor2);
-
- for (i = x - halfWidth; i < x + halfWidth; i++) {
- if ((i >= 0) && (i < width)) {
- curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
- curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
- curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
-
- curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] * filter[fx];
- curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] * filter[fx];
- curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] * filter[fx];
- }
- fx++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
-
- temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
- temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
- temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
-
- }
-
- /* Do the main body */
- for (x = halfWidth; x < width - halfWidth; x++) {
- index = (x + y * width) * 4;
- fx = 0;
- zero_v3(curColor);
- for (i = x - halfWidth; i < x + halfWidth; i++) {
- curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
- curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
- curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
- fx++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- }
- }
-
- /* Swap buffers */
- swap = temp; temp = map; map = swap;
-
- /* Blur the columns */
- for (x = 0; x < width; x++) {
- /* Do the top & bottom strips */
- for (y = 0; y < halfWidth; y++) {
- index = (x + y * width) * 4;
- fy = 0;
- zero_v3(curColor);
- zero_v3(curColor2);
- for (i = y - halfWidth; i < y + halfWidth; i++) {
- if ((i >= 0) && (i < height)) {
- /* Bottom */
- curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
- curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
- curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
-
- /* Top */
- curColor2[0] += map[(x + (height - 1 - i) * width) * 4 + GlowR] * filter[fy];
- curColor2[1] += map[(x + (height - 1 - i) * width) * 4 + GlowG] * filter[fy];
- curColor2[2] += map[(x + (height - 1 - i) * width) * 4 + GlowB] * filter[fy];
- }
- fy++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
- temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
- temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
- }
-
- /* Do the main body */
- for (y = halfWidth; y < height - halfWidth; y++) {
- index = (x + y * width) * 4;
- fy = 0;
- zero_v3(curColor);
- for (i = y - halfWidth; i < y + halfWidth; i++) {
- curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
- curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
- curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
- fy++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- }
- }
-
- /* Swap buffers */
- swap = temp; temp = map; /* map = swap; */ /* UNUSED */
-
- /* Tidy up */
- MEM_freeN(filter);
- MEM_freeN(temp);
-}
-
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
/* MUUUCCH better than the previous blur. */
/* We do the blurring in two passes which is a whole lot faster. */
@@ -2124,26 +1988,6 @@ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, i
MEM_freeN(temp);
}
-
-/* Adds two bitmaps and puts the results into a third map. */
-/* C must have been previously allocated but it may be A or B. */
-/* We clamp values to 255 to prevent weirdness */
-/*=============================== */
-static void RVAddBitmaps_byte(unsigned char *a, unsigned char *b, unsigned char *c, int width, int height)
-{
- int x, y, index;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- index = (x + y * width) * 4;
- c[index + GlowR] = MIN2(255, a[index + GlowR] + b[index + GlowR]);
- c[index + GlowG] = MIN2(255, a[index + GlowG] + b[index + GlowG]);
- c[index + GlowB] = MIN2(255, a[index + GlowB] + b[index + GlowB]);
- c[index + GlowA] = MIN2(255, a[index + GlowA] + b[index + GlowA]);
- }
- }
-}
-
static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
{
int x, y, index;
@@ -2159,37 +2003,6 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig
}
}
-/* For each pixel whose total luminance exceeds the threshold,
- * Multiply it's value by BOOST and add it to the output map
- */
-static void RVIsolateHighlights_byte(unsigned char *in, unsigned char *out, int width, int height, int threshold,
- float boost, float clamp)
-{
- int x, y, index;
- int intensity;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- index = (x + y * width) * 4;
-
- /* Isolate the intensity */
- intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
- if (intensity > 0) {
- out[index + GlowR] = MIN2(255 * clamp, (in[index + GlowR] * boost * intensity) / 255);
- out[index + GlowG] = MIN2(255 * clamp, (in[index + GlowG] * boost * intensity) / 255);
- out[index + GlowB] = MIN2(255 * clamp, (in[index + GlowB] * boost * intensity) / 255);
- out[index + GlowA] = MIN2(255 * clamp, (in[index + GlowA] * boost * intensity) / 255);
- }
- else {
- out[index + GlowR] = 0;
- out[index + GlowG] = 0;
- out[index + GlowB] = 0;
- out[index + GlowA] = 0;
- }
- }
- }
-}
-
static void RVIsolateHighlights_float(float *in, float *out, int width, int height, float threshold, float boost, float clamp)
{
int x, y, index;
@@ -2254,16 +2067,27 @@ static void copy_glow_effect(Sequence *dst, Sequence *src)
}
static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
- char *rect1, char *UNUSED(rect2), char *out)
+ unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out)
{
- unsigned char *outbuf = (unsigned char *)out;
- unsigned char *inbuf = (unsigned char *)rect1;
+ float *outbuf, *inbuf;
GlowVars *glow = (GlowVars *)seq->effectdata;
-
- RVIsolateHighlights_byte(inbuf, outbuf, x, y, glow->fMini * 765, glow->fBoost * facf0, glow->fClamp);
- RVBlurBitmap2_byte(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
+
+ inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input");
+ outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output");
+
+ IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+ IMB_buffer_float_premultiply(inbuf, x, y);
+
+ RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
+ RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
if (!glow->bNoComp)
- RVAddBitmaps_byte(inbuf, outbuf, outbuf, x, y);
+ RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
+
+ IMB_buffer_float_unpremultiply(outbuf, x, y);
+ IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+
+ MEM_freeN(inbuf);
+ MEM_freeN(outbuf);
}
static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
@@ -2292,7 +2116,7 @@ static ImBuf *do_glow_effect(SeqRenderData context, Sequence *seq, float UNUSED(
}
else {
do_glow_effect_byte(seq, render_size, facf0, facf1, context.rectx, context.recty,
- (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
+ (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
}
return out;
@@ -2735,7 +2559,7 @@ static ImBuf *do_speed_effect(SeqRenderData context, Sequence *UNUSED(seq), floa
}
else {
do_cross_effect_byte(facf0, facf1, context.rectx, context.recty,
- (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
+ (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
}
return out;
}
@@ -2761,8 +2585,8 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_drop_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
- do_alphaover_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
+ do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
}
}
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 5b2e9f2..3d8a2f7 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -226,24 +226,28 @@ static void curves_apply_threaded(int width, int height, unsigned char *rect, fl
}
if (rect) {
unsigned char *pixel = rect + pixel_index;
- unsigned char result[3];
+ float result[3], tempc[4];
- curvemapping_evaluate_premulRGB(curve_mapping, result, pixel);
+ straight_uchar_to_premul_float(tempc, pixel);
+
+ curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
if (mask_rect) {
float t[3];
rgb_uchar_to_float(t, mask_rect + pixel_index);
- pixel[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
- pixel[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
- pixel[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
+ tempc[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
+ tempc[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
+ tempc[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
}
else {
- pixel[0] = result[0];
- pixel[1] = result[1];
- pixel[2] = result[2];
+ tempc[0] = result[0];
+ tempc[1] = result[1];
+ tempc[2] = result[2];
}
+
+ premul_float_to_straight_uchar(pixel, tempc);
}
}
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 71d22ef..2c1fd09 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -324,7 +324,6 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_
{
const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
const char *to_colorspace = scene->sequencer_colorspace_settings.name;
- int predivide = ibuf->flags & IB_cm_predivide;
if (!ibuf->rect_float) {
if (make_float && ibuf->rect) {
@@ -354,7 +353,7 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_
imb_freerectImBuf(ibuf);
IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -367,10 +366,8 @@ void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
return;
if (to_colorspace && to_colorspace[0] != '\0') {
- int predivide = ibuf->flags & IB_cm_predivide;
-
IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -593,8 +590,8 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
/* XXX These resets should not be necessary, but users used to be able to
* edit effect's length, leading to strange results. See [#29190] */
seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
- seq->start = seq->startdisp = MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
- seq->enddisp = MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
+ seq->start = seq->startdisp = max_iii(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
+ seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
/* we cant help if strips don't overlap, it wont give useful results.
* but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
if (seq->enddisp < seq->startdisp) {
@@ -636,7 +633,7 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
}
}
-/* note: caller should run calc_sequence(scene, seq) after */
+/* note: caller should run BKE_sequence_calc(scene, seq) after */
void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range)
{
char str[FILE_MAX];
@@ -1517,18 +1514,6 @@ MINLINE float color_balance_fl(float in, const float lift, const float gain, con
return powf(x, gamma) * mul;
}
-static void make_cb_table_byte(float lift, float gain, float gamma,
- unsigned char *table, float mul)
-{
- int y;
-
- for (y = 0; y < 256; y++) {
- float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
-
- table[y] = FTOCHAR(v);
- }
-}
-
static void make_cb_table_float(float lift, float gain, float gamma,
float *table, float mul)
{
@@ -1543,35 +1528,33 @@ static void make_cb_table_float(float lift, float gain, float gamma,
static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
{
- unsigned char cb_tab[3][256];
- int c;
- unsigned char *p = rect;
- unsigned char *e = p + width * 4 * height;
+ //unsigned char cb_tab[3][256];
+ unsigned char *cp = rect;
+ unsigned char *e = cp + width * 4 * height;
unsigned char *m = mask_rect;
StripColorBalance cb = calc_cb(cb_);
- for (c = 0; c < 3; c++) {
- make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
- }
+ while (cp < e) {
+ float p[4];
+ int c;
- while (p < e) {
- if (m) {
- float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+ straight_uchar_to_premul_float(p, cp);
- p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
- p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
- p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+ for (c = 0; c < 3; c++) {
+ float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
- m += 4;
- }
- else {
- p[0] = cb_tab[0][p[0]];
- p[1] = cb_tab[1][p[1]];
- p[2] = cb_tab[2][p[2]];
+ if (m)
+ p[c] = p[c] * (1.0f - (float)m[c] / 255.0f) + t * m[c];
+ else
+ p[c] = t;
}
- p += 4;
+ premul_float_to_straight_uchar(cp, p);
+
+ cp += 4;
+ if (m)
+ m += 4;
}
}
@@ -1795,7 +1778,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
{
float mul;
- if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) {
+ if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
return TRUE;
}
@@ -1892,7 +1875,8 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
-
+ sequencer_imbuf_assign_spaces(context.scene, i);
+
IMB_freeImBuf(ibuf);
ibuf = i;
@@ -1931,12 +1915,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
multibuf(ibuf, mul);
}
- if (seq->flag & SEQ_MAKE_PREMUL) {
- if (ibuf->planes == 32 && ibuf->zbuf == NULL) {
- IMB_premultiply_alpha(ibuf);
- }
- }
-
if (ibuf->x != context.rectx || ibuf->y != context.recty) {
if (context.scene->r.mode & R_OSA) {
IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
@@ -2411,8 +2389,9 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
/* opengl offscreen render */
BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
- ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty,
- IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out);
+ ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect,
+ context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX,
+ TRUE, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
@@ -2545,13 +2524,18 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
case SEQ_TYPE_IMAGE:
{
StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
+ int flag;
if (s_elem) {
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
BLI_path_abs(name, G.main->name);
}
- if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name))) {
+ flag = IB_rect;
+ if (seq->alpha_mode == SEQ_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ if (s_elem && (ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name))) {
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
@@ -2640,7 +2624,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
{
ImBuf *ibuf = NULL;
- int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ int use_preprocess = FALSE;
int is_proxy_image = FALSE;
float nr = give_stripelem_index(seq, cfra);
/* all effects are handled similarly with the exception of speed effect */
@@ -2649,30 +2633,36 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
- /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
- * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
- if (ibuf)
- use_preprocess = FALSE;
-
- if (ibuf == NULL)
- ibuf = copy_from_ibuf_still(context, seq, nr);
-
if (ibuf == NULL) {
- ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+ if (ibuf == NULL)
+ ibuf = copy_from_ibuf_still(context, seq, nr);
if (ibuf == NULL) {
- /* MOVIECLIPs have their own proxy management */
- if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
- ibuf = seq_proxy_fetch(context, seq, cfra);
- is_proxy_image = (ibuf != NULL);
- }
+ ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+
+ if (ibuf == NULL) {
+ /* MOVIECLIPs have their own proxy management */
+ if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
+ ibuf = seq_proxy_fetch(context, seq, cfra);
+ is_proxy_image = (ibuf != NULL);
+ }
- if (ibuf == NULL)
- ibuf = do_render_strip_uncached(context, seq, cfra);
+ if (ibuf == NULL)
+ ibuf = do_render_strip_uncached(context, seq, cfra);
- if (ibuf)
- BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ if (ibuf)
+ BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ }
}
+
+ if (ibuf)
+ use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ }
+ else {
+ /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
+ * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL
+ * so, no need in check for preprocess here
+ */
}
if (ibuf == NULL) {
@@ -3972,10 +3962,18 @@ void BKE_sequence_init_colorspace(Sequence *seq)
/* initialize input color space */
if (seq->type == SEQ_TYPE_IMAGE) {
- ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name);
+ ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, seq->strip->colorspace_settings.name);
+
+ /* byte images are default to straight alpha, however sequencer
+ * works in premul space, so mark strip to be premultiplied first
+ */
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
+ if (ibuf) {
+ if (ibuf->flags & IB_alphamode_premul)
+ seq->alpha_mode = IMA_ALPHA_PREMUL;
- if (ibuf)
IMB_freeImBuf(ibuf);
+ }
}
}
}
@@ -4175,7 +4173,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->seqbase.first = seqn->seqbase.last = NULL;
/* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
- /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/
+ /* - seq_dupli_recursive(&seq->seqbase, &seqn->seqbase);*/
}
else if (seq->type == SEQ_TYPE_SCENE) {
seqn->strip->stripdata = NULL;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 53dfbdc..2563fc2 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -170,7 +170,7 @@ void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int
if (free_old && sds->fluid)
smoke_free(sds->fluid);
- if (!MIN3(res[0], res[1], res[2])) {
+ if (!min_iii(res[0], res[1], res[2])) {
sds->fluid = NULL;
return;
}
@@ -191,7 +191,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
if (free_old && sds->wt)
smoke_turbulence_free(sds->wt);
- if (!MIN3(res[0], res[1], res[2])) {
+ if (!min_iii(res[0], res[1], res[2])) {
sds->wt = NULL;
return;
}
@@ -924,7 +924,8 @@ static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3]
}
}
-static void em_allocateData(EmissionMap *em, int use_velocity) {
+static void em_allocateData(EmissionMap *em, int use_velocity)
+{
int i, res[3];
for (i = 0; i < 3; i++) {
@@ -941,7 +942,8 @@ static void em_allocateData(EmissionMap *em, int use_velocity) {
em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity");
}
-static void em_freeData(EmissionMap *em) {
+static void em_freeData(EmissionMap *em)
+{
if (em->influence)
MEM_freeN(em->influence);
if (em->velocity)
@@ -2405,7 +2407,7 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene)
bv[3] = (float)sds->res[1]; // y
bv[5] = (float)sds->res[2]; // z
-// #pragma omp parallel for schedule(static,1)
+// #pragma omp parallel for schedule(static, 1)
for (z = 0; z < sds->res[2]; z++)
{
size_t index = z * slabsize;
@@ -2509,7 +2511,8 @@ float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity
return -1.0f;
}
-int smoke_get_data_flags(SmokeDomainSettings *sds) {
+int smoke_get_data_flags(SmokeDomainSettings *sds)
+{
int flags = 0;
if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT;
if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE;
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index bb0cfe1..79356d3 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1097,12 +1097,12 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
float facedist, outerfacethickness, tune = 10.f;
int a, deflected=0;
- aabbmin[0] = MIN3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmin[1] = MIN3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmin[2] = MIN3(face_v1[2], face_v2[2], face_v3[2]);
- aabbmax[0] = MAX3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmax[1] = MAX3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmax[2] = MAX3(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
/* calculate face normal once again SIGH */
sub_v3_v3v3(edge1, face_v1, face_v2);
@@ -1196,12 +1196,12 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
float t, tune = 10.0f;
int a, deflected=0;
- aabbmin[0] = MIN3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmin[1] = MIN3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmin[2] = MIN3(face_v1[2], face_v2[2], face_v3[2]);
- aabbmax[0] = MAX3(face_v1[0], face_v2[0], face_v3[0]);
- aabbmax[1] = MAX3(face_v1[1], face_v2[1], face_v3[1]);
- aabbmax[2] = MAX3(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
+ aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
+ aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
+ aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
@@ -1957,7 +1957,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv2, nv3);
- sub_v3_v3v3(ve, opco, ve);
+ sub_v3_v3v3(ve, opco, ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )) {
copy_v3_v3(coledge, ve);
@@ -1966,7 +1966,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv3, nv1);
- sub_v3_v3v3(ve, opco, ve);
+ sub_v3_v3v3(ve, opco, ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )) {
copy_v3_v3(coledge, ve);
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index 0944059..f6599cc 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -35,7 +35,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index be8b572..6d4313d 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -50,8 +50,8 @@
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
@@ -1314,8 +1314,8 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
for (index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
- /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
- /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
+ /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */
+ /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */
for (S = 0; S < numVerts; S++) {
for (y = 0; y < gridSize - 1; y++) {
@@ -1569,7 +1569,7 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
CCGFace **faces;
int totface;
- BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
if (totface) {
ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
@@ -1707,7 +1707,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
if (dm->numTessFaceData) {
- BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, setMaterial);
+ BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
+ setMaterial, FALSE);
glShadeModel(GL_FLAT);
}
@@ -3025,7 +3026,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
* when the ccgdm gets remade, the assumption is that the topology
* does not change. */
ccgdm_create_grids(dm);
- BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
+ BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
ccgdm->gridFlagMats, ccgdm->gridHidden);
}
@@ -3043,15 +3044,15 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
numGrids = ccgDM_getNumGrids(dm);
- ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
- BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
+ BKE_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
}
else if (ob->type == OB_MESH) {
Mesh *me = ob->data;
- ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
- BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
+ BKE_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
}
@@ -3319,7 +3320,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
/*I think this is for interpolating the center vert?*/
- w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
+ w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
numVerts, vertNum);
if (vertOrigIndex) {
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index ff9774f..6f9736d 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -163,13 +163,13 @@ void texttool_suggest_add(const char *name, char type)
suggestions.top = 0;
}
-void texttool_suggest_prefix(const char *prefix)
+void texttool_suggest_prefix(const char *prefix, const int prefix_len)
{
SuggItem *match, *first, *last;
- int cmp, len = strlen(prefix), top = 0;
+ int cmp, top = 0;
if (!suggestions.first) return;
- if (len == 0) {
+ if (prefix_len == 0) {
suggestions.selected = suggestions.firstmatch = suggestions.first;
suggestions.lastmatch = suggestions.last;
return;
@@ -177,7 +177,7 @@ void texttool_suggest_prefix(const char *prefix)
first = last = NULL;
for (match = suggestions.first; match; match = match->next) {
- cmp = txttl_cmp(prefix, match->name, len);
+ cmp = txttl_cmp(prefix, match->name, prefix_len);
if (cmp == 0) {
if (!first) {
first = match;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 322b77e..c337e33 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -2936,3 +2936,18 @@ int text_check_whitespace(const char ch)
return 1;
return 0;
}
+
+int text_find_identifier_start(const char *str, int i)
+{
+ if (UNLIKELY(i <= 0)) {
+ return 0;
+ }
+
+ while (i--) {
+ if (!text_check_identifier(str[i])) {
+ break;
+ }
+ }
+ i++;
+ return i;
+}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 6d0313f..fbaf6f7 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -42,7 +42,6 @@
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
@@ -441,7 +440,7 @@ void default_tex(Tex *tex)
tex->type = TEX_CLOUDS;
tex->stype = 0;
tex->flag = TEX_CHECKER_ODD;
- tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA;
+ tex->imaflag = TEX_INTERPOL | TEX_MIPMAP;
tex->extend = TEX_REPEAT;
tex->cropxmin = tex->cropymin = 0.0;
tex->cropxmax = tex->cropymax = 1.0;
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 30b4840..3c5d94a 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1660,7 +1660,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
/* real sampling requires libmv, but areas are supposing pattern would be
* sampled if search area does exists, so we'll need to create empty
* pattern area here to prevent adding NULL-checks all over just to deal
- * with situation when lubmv is disabled
+ * with situation when libmv is disabled
*/
(void) frame_width;
@@ -3462,15 +3462,15 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf
BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
invert_m4(mat);
- if (filter == TRACKING_FILTER_NEAREAST)
- interpolation = neareast_interpolation;
+ if (filter == TRACKING_FILTER_NEAREST)
+ interpolation = nearest_interpolation;
else if (filter == TRACKING_FILTER_BILINEAR)
interpolation = bilinear_interpolation;
else if (filter == TRACKING_FILTER_BICUBIC)
interpolation = bicubic_interpolation;
else
/* fallback to default interpolation method */
- interpolation = neareast_interpolation;
+ interpolation = nearest_interpolation;
for (j = 0; j < tmpibuf->y; j++) {
for (i = 0; i < tmpibuf->x; i++) {
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 4bde895..ad101c4 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -40,7 +40,6 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
-#include "BLI_bpath.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 0f861a7..7e51025 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -373,7 +373,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
{
char name[128];
char *param;
- const AVOption *rv = NULL;
+ int fail = TRUE;
PRINT("FFMPEG expert option: %s: ", prop->name);
@@ -388,30 +388,30 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
switch (prop->type) {
case IDP_STRING:
PRINT("%s.\n", IDP_String(prop));
- av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
+ fail = av_opt_set(c, prop->name, IDP_String(prop), 0);
break;
case IDP_FLOAT:
PRINT("%g.\n", IDP_Float(prop));
- rv = av_set_double(c, prop->name, IDP_Float(prop));
+ fail = av_opt_set_double(c, prop->name, IDP_Float(prop), 0);
break;
case IDP_INT:
PRINT("%d.\n", IDP_Int(prop));
if (param) {
if (IDP_Int(prop)) {
- av_set_string3(c, name, param, 1, &rv);
+ fail = av_opt_set(c, name, param, 0);
}
else {
return;
}
}
else {
- rv = av_set_int(c, prop->name, IDP_Int(prop));
+ fail = av_opt_set_int(c, prop->name, IDP_Int(prop), 0);
}
break;
}
- if (!rv) {
+ if (fail) {
PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
}
}
@@ -464,8 +464,9 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
error[0] = '\0';
- st = av_new_stream(of, 0);
+ st = avformat_new_stream(of, NULL);
if (!st) return NULL;
+ st->id = 0;
/* Set up the codec context */
@@ -497,8 +498,15 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->rc_max_rate = rd->ffcodecdata.rc_max_rate * 1000;
c->rc_min_rate = rd->ffcodecdata.rc_min_rate * 1000;
c->rc_buffer_size = rd->ffcodecdata.rc_buffer_size * 1024;
+
+#if 0
+ /* this options are not set in ffmpeg.c and leads to artifacts with MPEG-4
+ * see #33586: Encoding to mpeg4 makes first frame(s) blocky
+ */
c->rc_initial_buffer_occupancy = rd->ffcodecdata.rc_buffer_size * 3 / 4;
c->rc_buffer_aggressivity = 1.0;
+#endif
+
c->me_method = ME_EPZS;
codec = avcodec_find_encoder(c->codec_id);
@@ -534,16 +542,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
}
if (codec_id == CODEC_ID_FFV1) {
-#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
- if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
- c->pix_fmt = PIX_FMT_RGB32;
- }
- else {
- c->pix_fmt = PIX_FMT_BGR0;
- }
-#else
c->pix_fmt = PIX_FMT_RGB32;
-#endif
}
if (codec_id == CODEC_ID_QTRLE) {
@@ -575,7 +574,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
set_ffmpeg_properties(rd, c, "video");
- if (avcodec_open(c, codec) < 0) {
+ if (avcodec_open2(c, codec, NULL) < 0) {
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
}
@@ -612,8 +611,9 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
error[0] = '\0';
- st = av_new_stream(of, 1);
+ st = avformat_new_stream(of, NULL);
if (!st) return NULL;
+ st->id = 1;
c = st->codec;
c->codec_id = codec_id;
@@ -635,7 +635,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
set_ffmpeg_properties(rd, c, "audio");
- if (avcodec_open(c, codec) < 0) {
+ if (avcodec_open2(c, codec, NULL) < 0) {
//XXX error("Couldn't initialize audio codec");
BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
@@ -1144,7 +1144,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
val.i = 0;
- avcodec_get_context_defaults(&c);
+ avcodec_get_context_defaults3(&c, NULL);
o = c.av_class->option + opt_index;
parent = c.av_class->option + parent_index;
@@ -1175,23 +1175,23 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
}
switch (o->type) {
- case FF_OPT_TYPE_INT:
- case FF_OPT_TYPE_INT64:
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_INT64:
val.i = FFMPEG_DEF_OPT_VAL_INT(o);
idp_type = IDP_INT;
break;
- case FF_OPT_TYPE_DOUBLE:
- case FF_OPT_TYPE_FLOAT:
+ case AV_OPT_TYPE_DOUBLE:
+ case AV_OPT_TYPE_FLOAT:
val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
idp_type = IDP_FLOAT;
break;
- case FF_OPT_TYPE_STRING:
+ case AV_OPT_TYPE_STRING:
val.string.str = (char *)" ";
val.string.len = 80;
/* val.str = (char *)" ";*/
idp_type = IDP_STRING;
break;
- case FF_OPT_TYPE_CONST:
+ case AV_OPT_TYPE_CONST:
val.i = 1;
idp_type = IDP_INT;
break;
@@ -1231,7 +1231,7 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
char *param;
IDProperty *prop = NULL;
- avcodec_get_context_defaults(&c);
+ avcodec_get_context_defaults3(&c, NULL);
strncpy(name_, str, sizeof(name_));
@@ -1252,10 +1252,10 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
if (!o) {
return 0;
}
- if (param && o->type == FF_OPT_TYPE_CONST) {
+ if (param && o->type == AV_OPT_TYPE_CONST) {
return 0;
}
- if (param && o->type != FF_OPT_TYPE_CONST && o->unit) {
+ if (param && o->type != AV_OPT_TYPE_CONST && o->unit) {
p = my_av_find_opt(&c, param, o->unit, 0, 0);
if (p) {
prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option);
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index a217783..7c8816c 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -106,8 +106,8 @@
((arr = (void *)_##arr##_static), (_##arr##_count += (num))) \
: \
/* use existing static array or allocate */ \
- ((BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
- (_##arr##_count += num) : \
+ (LIKELY(BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
+ (_##arr##_count += num) : /* UNLIKELY --> realloc */ \
( \
(void) (_##arr##_tmp = MEM_callocN( \
sizeof(*arr) * (num < _##arr##_count ? \
@@ -196,3 +196,31 @@
if (_##arr##_is_static) { \
MEM_freeN(arr); \
} (void)0
+
+
+/* alloca */
+#ifdef _MSC_VER
+# define alloca _alloca
+#endif
+
+#if defined(__MINGW32__)
+# include <malloc.h> /* mingw needs for alloca() */
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BLI_array_alloca(arr, realsize) \
+ (typeof(arr))alloca(sizeof(*arr) * (realsize))
+
+#define BLI_array_alloca_and_count(arr, realsize) \
+ (typeof(arr))alloca(sizeof(*arr) * (realsize)); \
+ const int _##arr##_count = (realsize)
+
+#else
+#define BLI_array_alloca(arr, realsize) \
+ alloca(sizeof(*arr) * (realsize))
+
+#define BLI_array_alloca_and_count(arr, realsize) \
+ alloca(sizeof(*arr) * (realsize)); \
+ const int _##arr##_count = (realsize)
+#endif
+
diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h
deleted file mode 100644
index 438bffb..0000000
--- a/source/blender/blenlib/BLI_bpath.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Campbell Barton
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file BLI_bpath.h
- * \ingroup bli
- * \attention Based on ghash, difference is ghash is not a fixed size,
- * so for BPath we don't need to malloc
- */
-
-#ifndef __BLI_BPATH_H__
-#define __BLI_BPATH_H__
-
-struct ID;
-struct ListBase;
-struct Main;
-struct ReportList;
-
-/* Function that does something with an ID's file path. Should return 1 if the
- * path has changed, and in that case, should write the result to pathOut. */
-typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src);
-/* Executes 'visit' for each path associated with 'id'. */
-void BLI_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata);
-void BLI_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata);
-void BLI_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata);
-int BLI_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src);
-
-/* Functions for temp backup/restore of paths, path count must NOT change */
-void *BLI_bpath_list_backup(struct Main *bmain, const int flag);
-void BLI_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle);
-void BLI_bpath_list_free(void *ls_handle);
-
-#define BLI_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */
-#define BLI_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */
-#define BLI_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */
-#define BLI_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg.
- * sequence strip images and pointcache. in this case only use the first
- * file, this is needed for directory manipulation functions which might
- * otherwise modify the same directory multiple times */
-
-/* high level funcs */
-
-/* creates a text file with missing files if there are any */
-void BLI_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports);
-void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports);
-void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
-void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports);
-
-#endif /* __BLI_BPATH_H__ */
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
new file mode 100644
index 0000000..880a97a
--- /dev/null
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -0,0 +1,90 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_BUFFER_H__
+#define __BLI_BUFFER_H__
+
+/* Note: this more or less fills same purpose as BLI_array, but makes
+ * it much easier to resize the array outside of the function it was
+ * declared in since */
+
+/* Usage examples:
+ *
+ * {
+ * BLI_buffer_declare_static(int, my_int_array, BLI_BUFFER_NOP, 32);
+ *
+ * BLI_buffer_append(my_int_array, int, 42);
+ * assert(my_int_array.count == 1);
+ * assert(BLI_buffer_at(my_int_array, int, 0) == 42);
+ *
+ * BLI_buffer_free(&my_int_array);
+ * }
+ */
+
+typedef struct {
+ void *data;
+ const int elem_size;
+ int count, alloc_count;
+ int flag;
+} BLI_Buffer;
+
+enum {
+ BLI_BUFFER_NOP = 0,
+ BLI_BUFFER_USE_STATIC = (1 << 0),
+ BLI_BUFFER_USE_CALLOC = (1 << 1), /* ensure the array is always calloc'd */
+};
+
+#define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \
+ type_ *name_ ## _static_[static_count_]; \
+ BLI_Buffer name_ = { \
+ /* clear the static memory if this is a calloc'd array */ \
+ ((void)((flag_ & BLI_BUFFER_USE_CALLOC) ? \
+ memset(name_ ## _static_, 0, sizeof(name_ ## _static_)) : 0\
+ ), /* memset-end */ \
+ name_ ## _static_), \
+ sizeof(type_), \
+ 0, \
+ static_count_, \
+ BLI_BUFFER_USE_STATIC | flag_}
+
+/* never use static*/
+#define BLI_buffer_declare(type_, name_, flag_) \
+ BLI_Buffer name_ = {NULL, \
+ sizeof(type_), \
+ 0, \
+ 0, \
+ flag_}
+
+
+#define BLI_buffer_at(buffer_, type_, index_) ( \
+ (((type_ *)(buffer_)->data)[(BLI_assert(sizeof(type_) == (buffer_)->elem_size)), index_]))
+
+#define BLI_buffer_append(buffer_, type_, val_) ( \
+ BLI_buffer_resize(buffer_, (buffer_)->count + 1), \
+ (BLI_buffer_at(buffer_, type_, (buffer_)->count - 1) = val_) \
+)
+
+/* Never decreases the amount of memory allocated */
+void BLI_buffer_resize(BLI_Buffer *buffer, int new_count);
+
+/* Does not free the buffer structure itself */
+void BLI_buffer_free(BLI_Buffer *buffer);
+
+#endif /* __BLI_BUFFER_H__ */
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 1330a74..d06956e 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -41,7 +41,7 @@ extern "C" {
#endif
void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
-int BLI_findindex(const struct ListBase *listbase, void *vlink);
+int BLI_findindex(const struct ListBase *listbase, const void *vlink);
int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset);
/* find forwards */
@@ -79,4 +79,4 @@ struct LinkData *BLI_genericNodeN(void *data);
}
#endif
-#endif
+#endif /* __BLI_LISTBASE_H__ */
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index c71463d..3831ec3 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -100,6 +100,13 @@ MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[
void BLI_init_srgb_conversion(void);
+/**************** Alpha Transformations *****************/
+
+MINLINE void premul_to_straight_v4(float straight[4], const float premul[4]);
+MINLINE void straight_to_premul_v4(float straight[4], const float premul[4]);
+MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4]);
+MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4]);
+
/************************** Other *************************/
int constrain_rgb(float *r, float *g, float *b);
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index cfd163d..4483968 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -53,6 +53,7 @@ float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]
float area_tri_v3(const float a[3], const float b[3], const float c[3]);
float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
float area_poly_v3(int nr, float verts[][3], const float normal[3]);
+float area_poly_v2(int nr, float verts[][2]);
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
@@ -72,6 +73,9 @@ float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const
void closest_to_line_segment_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
void closest_to_plane_v3(float r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3]);
+/* Set 'r' to the point in triangle (t1, t2, t3) closest to point 'p' */
+void closest_on_tri_to_point_v3(float r[3], const float p[3], const float t1[3], const float t2[3], const float t3[3]);
+
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]);
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]);
@@ -202,7 +206,7 @@ void perspective_m4(float mat[4][4], const float left, const float right,
const float bottom, const float top, const float nearClip, const float farClip);
void orthographic_m4(float mat[4][4], const float left, const float right,
const float bottom, const float top, const float nearClip, const float farClip);
-void window_translate_m4(float winmat[][4], float perspmat[][4],
+void window_translate_m4(float winmat[4][4], float perspmat[4][4],
const float x, const float y);
int box_clip_bounds_m4(float boundbox[2][3],
@@ -257,11 +261,18 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
float form_factor_hemi_poly(float p[3], float n[3],
float v1[3], float v2[3], float v3[3], float v4[3]);
-void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]);
+void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
+float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+#endif
+;
MINLINE int max_axis_v3(const float vec[3]);
MINLINE int min_axis_v3(const float vec[3]);
+MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index f51bd1c..c12ec62 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -144,10 +144,14 @@ float determinant_m2(float a, float b,
float determinant_m3(float a, float b, float c,
float d, float e, float f,
float g, float h, float i);
+float determinant_m3_array(float m[3][3]);
float determinant_m4(float A[4][4]);
+#define PSEUDOINVERSE_EPSILON 1e-8f
+
void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon);
+void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
/****************************** Transformations ******************************/
@@ -167,8 +171,8 @@ void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle);
-void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[][3]);
-void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]);
+void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
void loc_eul_size_to_mat4(float R[4][4],
const float loc[3], const float eul[3], const float size[3]);
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 5e47adf..8c51c92 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -67,6 +67,8 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check);
#define BLENDER_RESOURCE_PATH_SYSTEM 2
#define BLENDER_STARTUP_FILE "startup.blend"
+#define BLENDER_USERPREF_FILE "userpref.blend"
+#define BLENDER_QUIT_FILE "quit.blend"
#define BLENDER_BOOKMARK_FILE "bookmarks.txt"
#define BLENDER_HISTORY_FILE "recent-files.txt"
@@ -118,7 +120,11 @@ int BLI_split_name_num(char *left, int *nr, const char *name, const char delim);
void BLI_splitdirstring(char *di, char *fi);
/* make sure path separators conform to system one */
-void BLI_clean(char *path);
+void BLI_clean(char *path)
+#ifdef __GNUC__
+__attribute__((nonnull(1)))
+#endif
+;
/**
* dir can be any input, like from buttons, and this function
@@ -171,7 +177,11 @@ int BLI_path_is_rel(const char *path);
* \a from The character to replace
* \a to The character to replace with
*/
-void BLI_char_switch(char *string, char from, char to);
+void BLI_char_switch(char *string, char from, char to)
+#ifdef __GNUC__
+__attribute__((nonnull(1)))
+#endif
+;
/* Initialize path to program executable */
void BLI_init_program_path(const char *argv0);
diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h
deleted file mode 100644
index 59ecdb3..0000000
--- a/source/blender/blenlib/BLI_pbvh.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * ***** 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 LICENSE BLOCK *****
- */
-
-#ifndef __BLI_PBVH_H__
-#define __BLI_PBVH_H__
-
-/** \file BLI_pbvh.h
- * \ingroup bli
- * \brief A BVH for high poly meshes.
- */
-
-#include "BLI_bitmap.h"
-
-struct CCGElem;
-struct CCGKey;
-struct CustomData;
-struct DMFlagMat;
-struct DMGridAdjacency;
-struct ListBase;
-struct MFace;
-struct MVert;
-struct PBVH;
-struct PBVHNode;
-
-typedef struct PBVH PBVH;
-typedef struct PBVHNode PBVHNode;
-
-typedef struct {
- float (*co)[3];
-} PBVHProxyNode;
-
-/* Callbacks */
-
-/* returns 1 if the search should continue from this node, 0 otherwise */
-typedef int (*BLI_pbvh_SearchCallback)(PBVHNode *node, void *data);
-
-typedef void (*BLI_pbvh_HitCallback)(PBVHNode *node, void *data);
-typedef void (*BLI_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin);
-
-/* Building */
-
-PBVH *BLI_pbvh_new(void);
-void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
- int totface, int totvert, struct CustomData *vdata);
-void BLI_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
- struct DMGridAdjacency *gridadj, int totgrid,
- struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
- unsigned int **grid_hidden);
-void BLI_pbvh_free(PBVH *bvh);
-
-/* Hierarchical Search in the BVH, two methods:
- * - for each hit calling a callback
- * - gather nodes in an array (easy to multithread) */
-
-void BLI_pbvh_search_callback(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitCallback hcb, void *hit_data);
-
-void BLI_pbvh_search_gather(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- PBVHNode ***array, int *tot);
-
-/* Raycast
- * the hit callback is called for all leaf nodes intersecting the ray;
- * it's up to the callback to find the primitive within the leaves that is
- * hit first */
-
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
- const float ray_start[3], const float ray_normal[3],
- int original);
-
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
- const float ray_start[3], const float ray_normal[3],
- float *dist);
-
-/* Drawing */
-
-void BLI_pbvh_node_draw(PBVHNode *node, void *data);
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- int (*setMaterial)(int, void *attribs));
-
-/* PBVH Access */
-typedef enum {
- PBVH_FACES,
- PBVH_GRIDS,
-} PBVHType;
-
-PBVHType BLI_pbvh_type(const PBVH *bvh);
-
-/* multires hidden data, only valid for type == PBVH_GRIDS */
-unsigned int **BLI_pbvh_grid_hidden(const PBVH *bvh);
-
-/* multires level, only valid for type == PBVH_GRIDS */
-void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
-
-/* Node Access */
-
-typedef enum {
- PBVH_Leaf = 1,
-
- PBVH_UpdateNormals = 2,
- PBVH_UpdateBB = 4,
- PBVH_UpdateOriginalBB = 8,
- PBVH_UpdateDrawBuffers = 16,
- PBVH_UpdateRedraw = 32,
-
- PBVH_RebuildDrawBuffers = 64,
- PBVH_FullyHidden = 128
-} PBVHNodeFlags;
-
-void BLI_pbvh_node_mark_update(PBVHNode *node);
-void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node);
-void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
-
-void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
- int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
- struct CCGElem ***grid_elems, struct DMGridAdjacency **gridadj);
-void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node,
- int *uniquevert, int *totvert);
-void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
- int **vert_indices, struct MVert **verts);
-
-void BLI_pbvh_node_get_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
-void BLI_pbvh_node_get_original_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
-
-float BLI_pbvh_node_get_tmin(PBVHNode *node);
-
-/* test if AABB is at least partially inside the planes' volume */
-int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
-/* test if AABB is at least partially outside the planes' volume */
-int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
-
-/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
-
-void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
-void BLI_pbvh_redraw_BB(PBVH * bvh, float bb_min[3], float bb_max[3]);
-void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
-void BLI_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
- struct DMGridAdjacency *gridadj, void **gridfaces,
- struct DMFlagMat *flagmats, unsigned int **grid_hidden);
-
-/* vertex deformer */
-float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
-void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
-int BLI_pbvh_isDeformed(struct PBVH *pbvh);
-
-
-/* Vertex Iterator */
-
-/* this iterator has quite a lot of code, but it's designed to:
- * - allow the compiler to eliminate dead code and variables
- * - spend most of the time in the relatively simple inner loop */
-
-/* note: PBVH_ITER_ALL does not skip hidden vertices,
- * PBVH_ITER_UNIQUE does */
-#define PBVH_ITER_ALL 0
-#define PBVH_ITER_UNIQUE 1
-
-typedef struct PBVHVertexIter {
- /* iteration */
- int g;
- int width;
- int height;
- int gx;
- int gy;
- int i;
-
- /* grid */
- struct CCGElem **grids;
- struct CCGElem *grid;
- struct CCGKey *key;
- BLI_bitmap *grid_hidden, gh;
- int *grid_indices;
- int totgrid;
- int gridsize;
-
- /* mesh */
- struct MVert *mverts;
- int totvert;
- int *vert_indices;
- float *vmask;
-
- /* result: these are all computed in the macro, but we assume
- * that compiler optimization's will skip the ones we don't use */
- struct MVert *mvert;
- float *co;
- short *no;
- float *fno;
- float *mask;
-} PBVHVertexIter;
-
-#ifdef _MSC_VER
-#pragma warning (disable:4127) // conditional expression is constant
-#endif
-
-void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
- PBVHVertexIter *vi, int mode);
-
-#define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
- pbvh_vertex_iter_init(bvh, node, &vi, mode); \
- \
- for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \
- if (vi.grids) { \
- vi.width = vi.gridsize; \
- vi.height = vi.gridsize; \
- vi.grid = vi.grids[vi.grid_indices[vi.g]]; \
- if (mode == PBVH_ITER_UNIQUE) \
- vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \
- } \
- else { \
- vi.width = vi.totvert; \
- vi.height = 1; \
- } \
- \
- for (vi.gy = 0; vi.gy < vi.height; vi.gy++) { \
- for (vi.gx = 0; vi.gx < vi.width; vi.gx++, vi.i++) { \
- if (vi.grid) { \
- vi.co = CCG_elem_co(vi.key, vi.grid); \
- vi.fno = CCG_elem_no(vi.key, vi.grid); \
- vi.mask = vi.key->has_mask ? CCG_elem_mask(vi.key, vi.grid) : NULL; \
- vi.grid = CCG_elem_next(vi.key, vi.grid); \
- if (vi.gh) { \
- if (BLI_BITMAP_GET(vi.gh, vi.gy * vi.gridsize + vi.gx)) \
- continue; \
- } \
- } \
- else { \
- vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
- if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
- continue; \
- vi.co = vi.mvert->co; \
- vi.no = vi.mvert->no; \
- if (vi.vmask) \
- vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
- } \
-
-#define BLI_pbvh_vertex_iter_end \
- } \
- } \
- }
-
-void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
-void BLI_pbvh_node_free_proxies(PBVHNode *node);
-PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node);
-void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***nodes, int *totnode);
-
-//void BLI_pbvh_node_BB_reset(PBVHNode *node);
-//void BLI_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
-
-void pbvh_show_diffuse_color_set(PBVH *bvh, int show_diffuse_color);
-
-#endif /* __BLI_PBVH_H__ */
-
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index f2e2609..3c93630 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -56,6 +56,8 @@ void BLI_rctf_translate(struct rctf *rect, float x, float y);
void BLI_rcti_translate(struct rcti *rect, int x, int y);
void BLI_rcti_resize(struct rcti *rect, int x, int y);
void BLI_rctf_resize(struct rctf *rect, float x, float y);
+void BLI_rcti_scale(rcti *rect, const float scale);
+void BLI_rctf_scale(rctf *rect, const float scale);
void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac);
//void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac);
int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index c8fd72b..7830c06 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -101,6 +101,10 @@ enum {
* Assumes ordered edges, otherwise we risk an eternal loop
* removing double verts. - campbell */
BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1),
+
+ /* note: This flag removes checks for overlapping polygons.
+ * when this flag is set, we'll never get back more faces then (totvert - 2) */
+ BLI_SCANFILL_CALC_HOLES = (1 << 2)
};
int BLI_scanfill_begin(ScanFillContext *sf_ctx);
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 7c3b705..43b1e78 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -32,12 +32,41 @@
* \ingroup bli
*/
-#ifndef FALSE
-# define FALSE 0
+#ifndef NDEBUG /* for BLI_assert */
+#include <stdio.h>
#endif
-#ifndef TRUE
-# define TRUE 1
+/* note: use of (int, TRUE / FALSE) is deprecated,
+ * use (bool, true / false) instead */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# ifndef HAVE__BOOL
+# ifdef __cplusplus
+typedef bool _BLI_Bool;
+# else
+# define _BLI_Bool signed char
+# endif
+# else
+# define _BLI_Bool _Bool
+# endif
+# define bool _BLI_Bool
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif
+
+/* remove this when we're ready to remove TRUE/FALSE completely */
+#ifdef WITH_BOOL_COMPAT
+/* interim until all occurrences of these can be updated to stdbool */
+/* XXX Why not use the true/false velues here? */
+# ifndef FALSE
+# define FALSE 0
+# endif
+
+# ifndef TRUE
+# define TRUE 1
+# endif
#endif
/* useful for finding bad use of min/max */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 8a3b1c9..49e3db0 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -25,9 +25,7 @@
set(INC
.
- ../blenkernel
- ../blenloader
- ../gpu
+ # ../blenkernel # dont add this back!
../makesdna
../../../intern/ghost
../../../intern/guardedalloc
@@ -50,7 +48,7 @@ set(SRC
intern/BLI_mempool.c
intern/DLRB_tree.c
intern/boxpack2d.c
- intern/bpath.c
+ intern/buffer.c
intern/callbacks.c
intern/cpu.c
intern/dynlib.c
@@ -78,7 +76,6 @@ set(SRC
intern/md5.c
intern/noise.c
intern/path_util.c
- intern/pbvh.c
intern/quadric.c
intern/rand.c
intern/rct.c
@@ -100,8 +97,8 @@ set(SRC
BLI_array.h
BLI_bitmap.h
BLI_blenlib.h
+ BLI_buffer.h
BLI_boxpack2d.h
- BLI_bpath.h
BLI_callbacks.h
BLI_cpu.h
BLI_dlrbTree.h
@@ -137,7 +134,6 @@ set(SRC
BLI_mempool.h
BLI_noise.h
BLI_path_util.h
- BLI_pbvh.h
BLI_quadric.h
BLI_rand.h
BLI_rect.h
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index e53f622..2be06f7 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -1,11 +1,37 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
cflags=''
-incs = '. ../makesdna ../blenkernel #/intern/guardedalloc #/intern/ghost ../editors/include ../gpu ../blenloader'
-incs += ' ../windowmanager ../bmesh #/extern/glew/include'
+# don't add ../blenkernel back!
+incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost'
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index c409492..7d2fc38 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -39,7 +39,7 @@
#include "BLI_mempool.h"
#include "BLI_ghash.h"
-#include "BLO_sys_types.h" // for intptr_t support
+#include "MEM_sys_types.h" /* for intptr_t support */
/***/
unsigned int hashsizes[] = {
@@ -312,17 +312,25 @@ int BLI_ghashutil_intcmp(const void *a, const void *b)
return (a < b) ? -1 : 1;
}
+/**
+ * This function implements the widely used "djb" hash apparently posted
+ * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
+ * unsigned hash value starts at 5381 and for each byte 'c' in the
+ * string, is updated: <literal>hash = hash * 33 + c</literal>. This
+ * function uses the signed value of each byte.
+ *
+ * note: this is the same hash method that glib 2.34.0 uses.
+ */
unsigned int BLI_ghashutil_strhash(const void *ptr)
{
- const char *s = ptr;
- unsigned int i = 0;
- unsigned char c;
+ const signed char *p;
+ unsigned int h = 5381;
- while ((c = *s++)) {
- i = i * 37 + c;
+ for (p = ptr; *p != '\0'; p++) {
+ h = (h << 5) + h + *p;
}
- return i;
+ return h;
}
int BLI_ghashutil_strcmp(const void *a, const void *b)
{
@@ -376,4 +384,3 @@ void BLI_ghashutil_pairfree(void *ptr)
{
MEM_freeN((void *)ptr);
}
-
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 6cf167b..b2d07b9 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -1237,7 +1237,7 @@ static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node)
#define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024
-#define NodeDistance_priority(a, b) ( (a).dist < (b).dist)
+#define NodeDistance_priority(a, b) ((a).dist < (b).dist)
static void NodeDistance_push_heap(NodeDistance *heap, int heap_size)
PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size)
@@ -1554,7 +1554,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f
float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3])
{
BVHRayCastData data;
- float dist = 0.0;
+ float dist;
data.hit.dist = FLT_MAX;
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
deleted file mode 100644
index c650438..0000000
--- a/source/blender/blenlib/intern/bpath.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Campbell barton, Alex Fraser
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/blenlib/intern/bpath.c
- * \ingroup bli
- */
-
-/* TODO,
- * currently there are some cases we don't support.
- * - passing output paths to the visitor?, like render out.
- * - passing sequence strips with many images.
- * - passing directory paths - visitors don't know which path is a dir or a file.
- * */
-
-#include <sys/stat.h>
-
-#include <string.h>
-#include <assert.h>
-
-/* path/file handling stuff */
-#ifndef WIN32
-# include <dirent.h>
-# include <unistd.h>
-#else
-# include <io.h>
-# include "BLI_winstuff.h"
-#endif
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_brush_types.h"
-#include "DNA_image_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_object_force.h"
-#include "DNA_object_types.h"
-#include "DNA_particle_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_sound_types.h"
-#include "DNA_text_types.h"
-#include "DNA_material_types.h"
-#include "DNA_node_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_vfont_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_smoke_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
-#include "BLI_utildefines.h"
-
-#include "BKE_font.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_node.h"
-#include "BKE_report.h"
-#include "BKE_sequencer.h"
-#include "BKE_image.h" /* so we can check the image's type */
-
-static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
-{
- ReportList *reports = (ReportList *)userdata;
-
- if (!BLI_exists(path_src)) {
- BKE_reportf(reports, RPT_WARNING, "Path '%s' not found", path_src);
- }
-
- return FALSE;
-}
-
-/* high level function */
-void BLI_bpath_missing_files_check(Main *bmain, ReportList *reports)
-{
- BLI_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BLI_BPATH_TRAVERSE_ABS, reports);
-}
-
-typedef struct BPathRemap_Data {
- const char *basedir;
- ReportList *reports;
-
- int count_tot;
- int count_changed;
- int count_failed;
-} BPathRemap_Data;
-
-static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char *path_src)
-{
- BPathRemap_Data *data = (BPathRemap_Data *)userdata;
-
- data->count_tot++;
-
- if (BLI_path_is_rel(path_src)) {
- return FALSE; /* already relative */
- }
- else {
- strcpy(path_dst, path_src);
- BLI_path_rel(path_dst, data->basedir);
- if (BLI_path_is_rel(path_dst)) {
- data->count_changed++;
- }
- else {
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
- data->count_failed++;
- }
- return TRUE;
- }
-}
-
-void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports)
-{
- BPathRemap_Data data = {NULL};
-
- if (basedir[0] == '\0') {
- printf("%s: basedir='', this is a bug\n", __func__);
- return;
- }
-
- data.basedir = basedir;
- data.reports = reports;
-
- BLI_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data);
-
- BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
- "Total files %d | Changed %d | Failed %d",
- data.count_tot, data.count_changed, data.count_failed);
-}
-
-static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char *path_src)
-{
- BPathRemap_Data *data = (BPathRemap_Data *)userdata;
-
- data->count_tot++;
-
- if (BLI_path_is_rel(path_src) == FALSE) {
- return FALSE; /* already absolute */
- }
- else {
- strcpy(path_dst, path_src);
- BLI_path_abs(path_dst, data->basedir);
- if (BLI_path_is_rel(path_dst) == FALSE) {
- data->count_changed++;
- }
- else {
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
- data->count_failed++;
- }
- return TRUE;
- }
-}
-
-/* similar to BLI_bpath_relative_convert - keep in sync! */
-void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports)
-{
- BPathRemap_Data data = {NULL};
-
- if (basedir[0] == '\0') {
- printf("%s: basedir='', this is a bug\n", __func__);
- return;
- }
-
- data.basedir = basedir;
- data.reports = reports;
-
- BLI_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data);
-
- BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO,
- "Total files %d | Changed %d | Failed %d",
- data.count_tot, data.count_changed, data.count_failed);
-}
-
-/**
- * find this file recursively, use the biggest file so thumbnails don't get used by mistake
- * \param filename_new: the path will be copied here, caller must initialize as empty string.
- * \param dirname: subdir to search
- * \param filename: set this filename
- * \param filesize: filesize for the file
- *
- * \returns found: 1/0.
- */
-#define MAX_RECUR 16
-static int findFileRecursive(char *filename_new,
- const char *dirname,
- const char *filename,
- int *filesize,
- int *recur_depth)
-{
- /* file searching stuff */
- DIR *dir;
- struct dirent *de;
- struct stat status;
- char path[FILE_MAX];
- int size;
- int found = FALSE;
-
- dir = opendir(dirname);
-
- if (dir == NULL)
- return found;
-
- if (*filesize == -1)
- *filesize = 0; /* dir opened fine */
-
- while ((de = readdir(dir)) != NULL) {
-
- if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0)
- continue;
-
- BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);
-
- if (stat(path, &status) != 0)
- continue; /* cant stat, don't bother with this file, could print debug info here */
-
- if (S_ISREG(status.st_mode)) { /* is file */
- if (strncmp(filename, de->d_name, FILE_MAX) == 0) { /* name matches */
- /* open the file to read its size */
- size = status.st_size;
- if ((size > 0) && (size > *filesize)) { /* find the biggest file */
- *filesize = size;
- BLI_strncpy(filename_new, path, FILE_MAX);
- found = TRUE;
- }
- }
- }
- else if (S_ISDIR(status.st_mode)) { /* is subdir */
- if (*recur_depth <= MAX_RECUR) {
- (*recur_depth)++;
- found |= findFileRecursive(filename_new, path, filename, filesize, recur_depth);
- (*recur_depth)--;
- }
- }
- }
- closedir(dir);
- return found;
-}
-
-typedef struct BPathFind_Data {
- const char *basedir;
- char searchdir[FILE_MAX];
- ReportList *reports;
-} BPathFind_Data;
-
-static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char *path_src)
-{
- BPathFind_Data *data = (BPathFind_Data *)userdata;
- char filename_new[FILE_MAX];
-
- int filesize = -1;
- int recur_depth = 0;
- int found;
-
- filename_new[0] = '\0';
-
- found = findFileRecursive(filename_new,
- data->searchdir, BLI_path_basename((char *)path_src),
- &filesize, &recur_depth);
-
- if (filesize == -1) { /* could not open dir */
- BKE_reportf(data->reports, RPT_WARNING,
- "Could not open directory '%s'",
- BLI_path_basename(data->searchdir));
- return FALSE;
- }
- else if (found == FALSE) {
- BKE_reportf(data->reports, RPT_WARNING,
- "Could not find '%s' in '%s'",
- BLI_path_basename((char *)path_src), data->searchdir);
- return FALSE;
- }
- else {
- BLI_strncpy(path_dst, filename_new, FILE_MAX);
- return TRUE;
- }
-}
-
-void BLI_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports)
-{
- struct BPathFind_Data data = {NULL};
-
- data.reports = reports;
- BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir));
-
- BLI_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data);
-}
-
-/* Run a visitor on a string, replacing the contents of the string as needed. */
-static int rewrite_path_fixed(char *path, BPathVisitor visit_cb, const char *absbase, void *userdata)
-{
- char path_src_buf[FILE_MAX];
- const char *path_src;
- char path_dst[FILE_MAX];
-
- if (absbase) {
- BLI_strncpy(path_src_buf, path, sizeof(path_src_buf));
- BLI_path_abs(path_src_buf, absbase);
- path_src = path_src_buf;
- }
- else {
- path_src = path;
- }
-
- if (visit_cb(userdata, path_dst, path_src)) {
- BLI_strncpy(path, path_dst, FILE_MAX);
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
-static int rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
- char path_file[FILE_MAXFILE],
- BPathVisitor visit_cb,
- const char *absbase,
- void *userdata)
-{
- char path_src[FILE_MAX];
- char path_dst[FILE_MAX];
-
- BLI_join_dirfile(path_src, sizeof(path_src), path_dir, path_file);
-
- if (absbase) {
- BLI_path_abs(path_src, absbase);
- }
-
- if (visit_cb(userdata, path_dst, (const char *)path_src)) {
- BLI_split_dirfile(path_dst, path_dir, path_file, FILE_MAXDIR, FILE_MAXFILE);
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
-static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *absbase, void *userdata)
-{
- char path_src_buf[FILE_MAX];
- const char *path_src;
- char path_dst[FILE_MAX];
-
- if (absbase) {
- BLI_strncpy(path_src_buf, *path, sizeof(path_src_buf));
- BLI_path_abs(path_src_buf, absbase);
- path_src = path_src_buf;
- }
- else {
- path_src = *path;
- }
-
- if (visit_cb(userdata, path_dst, path_src)) {
- MEM_freeN((*path));
- (*path) = BLI_strdup(path_dst);
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
-/* Run visitor function 'visit' on all paths contained in 'id'. */
-void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
-{
- const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
-
- if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) {
- return;
- }
-
- switch (GS(id->name)) {
- case ID_IM:
- {
- Image *ima;
- ima = (Image *)id;
- if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
- if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
- rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data);
- }
- }
- break;
- }
- case ID_BR:
- {
- Brush *brush = (Brush *)id;
- if (brush->icon_filepath[0]) {
- rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data);
- }
- break;
- }
- case ID_OB:
- {
- Object *ob = (Object *)id;
- ModifierData *md;
- ParticleSystem *psys;
-
-#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \
- { \
- PointCache *cache; \
- for (cache = (ptcaches).first; cache; cache = cache->next) { \
- if (cache->flag & PTCACHE_DISK_CACHE) { \
- rewrite_path_fixed(cache->path, \
- visit_cb, \
- absbase, \
- bpath_user_data); \
- } \
- } \
- } (void)0
-
- /* do via modifiers instead */
-#if 0
- if (ob->fluidsimSettings) {
- rewrite_path_fixed(ob->fluidsimSettings->surfdataPath, visit_cb, absbase, bpath_user_data);
- }
-#endif
-
- for (md = ob->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Fluidsim) {
- FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
- if (fluidmd->fss) {
- rewrite_path_fixed(fluidmd->fss->surfdataPath, visit_cb, absbase, bpath_user_data);
- }
- }
- else if (md->type == eModifierType_Smoke) {
- SmokeModifierData *smd = (SmokeModifierData *)md;
- if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
- BPATH_TRAVERSE_POINTCACHE(smd->domain->ptcaches[0]);
- }
- }
- else if (md->type == eModifierType_Cloth) {
- ClothModifierData *clmd = (ClothModifierData *) md;
- BPATH_TRAVERSE_POINTCACHE(clmd->ptcaches);
- }
- else if (md->type == eModifierType_Ocean) {
- OceanModifierData *omd = (OceanModifierData *) md;
- rewrite_path_fixed(omd->cachepath, visit_cb, absbase, bpath_user_data);
- }
- }
-
- if (ob->soft) {
- BPATH_TRAVERSE_POINTCACHE(ob->soft->ptcaches);
- }
-
- for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- BPATH_TRAVERSE_POINTCACHE(psys->ptcaches);
- }
-
-#undef BPATH_TRAVERSE_POINTCACHE
-
- break;
- }
- case ID_SO:
- {
- bSound *sound = (bSound *)id;
- if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
- rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data);
- }
- break;
- }
- case ID_TXT:
- if (((Text *)id)->name) {
- rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data);
- }
- break;
- case ID_VF:
- {
- VFont *vfont = (VFont *)id;
- if (vfont->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
- if (BKE_vfont_is_builtin(vfont) == FALSE) {
- rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data);
- }
- }
- break;
- }
- case ID_MA:
- {
- Material *ma = (Material *)id;
- bNodeTree *ntree = ma->nodetree;
-
- if (ntree) {
- bNode *node;
-
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->type == SH_NODE_SCRIPT) {
- NodeShaderScript *nss = (NodeShaderScript *)node->storage;
- rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
- }
- }
- }
- break;
- }
- case ID_NT:
- {
- bNodeTree *ntree = (bNodeTree *)id;
- bNode *node;
-
- if (ntree->type == NTREE_SHADER) {
- /* same as lines above */
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->type == SH_NODE_SCRIPT) {
- NodeShaderScript *nss = (NodeShaderScript *)node->storage;
- rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
- }
- }
- }
- break;
- }
- case ID_TE:
- {
- Tex *tex = (Tex *)id;
- if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) {
- rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data);
- }
- break;
- }
- case ID_SCE:
- {
- Scene *scene = (Scene *)id;
- if (scene->ed) {
- Sequence *seq;
-
- SEQ_BEGIN(scene->ed, seq)
- {
- if (SEQ_HAS_PATH(seq)) {
- if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM)) {
- rewrite_path_fixed_dirfile(seq->strip->dir, seq->strip->stripdata->name,
- visit_cb, absbase, bpath_user_data);
- }
- else if (seq->type == SEQ_TYPE_IMAGE) {
- /* might want an option not to loop over all strips */
- StripElem *se = seq->strip->stripdata;
- int len = MEM_allocN_len(se) / sizeof(*se);
- int i;
-
- if (flag & BLI_BPATH_TRAVERSE_SKIP_MULTIFILE) {
- /* only operate on one path */
- len = MIN2(1, len);
- }
-
- for (i = 0; i < len; i++, se++) {
- rewrite_path_fixed_dirfile(seq->strip->dir, se->name,
- visit_cb, absbase, bpath_user_data);
- }
- }
- else {
- /* simple case */
- rewrite_path_fixed(seq->strip->dir, visit_cb, absbase, bpath_user_data);
- }
- }
-
- }
- SEQ_END
- }
- break;
- }
- case ID_ME:
- {
- Mesh *me = (Mesh *)id;
- if (me->ldata.external) {
- rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data);
- }
- break;
- }
- case ID_LI:
- {
- Library *lib = (Library *)id;
- if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
- BKE_library_filepath_set(lib, lib->name);
- }
- break;
- }
- case ID_MC:
- {
- MovieClip *clip = (MovieClip *)id;
- rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data);
- break;
- }
- default:
- /* Nothing to do for other IDs that don't contain file paths. */
- break;
- }
-}
-
-void BLI_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
-{
- ID *id;
- for (id = lb->first; id; id = id->next) {
- BLI_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data);
- }
-}
-
-void BLI_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
-{
- ListBase *lbarray[MAX_LIBARRAY];
- int a = set_listbasepointers(bmain, lbarray);
- while (a--) {
- BLI_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data);
- }
-}
-
-/* Rewrites a relative path to be relative to the main file - unless the path is
- * absolute, in which case it is not altered. */
-int BLI_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src)
-{
- /* be sure there is low chance of the path being too short */
- char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
- const char *base_new = ((char **)pathbase_v)[0];
- const char *base_old = ((char **)pathbase_v)[1];
-
- if (BLI_path_is_rel(base_old)) {
- printf("%s: error, old base path '%s' is not absolute.\n",
- __func__, base_old);
- return FALSE;
- }
-
- /* Make referenced file absolute. This would be a side-effect of
- * BLI_cleanup_file, but we do it explicitly so we know if it changed. */
- BLI_strncpy(filepath, path_src, FILE_MAX);
- if (BLI_path_abs(filepath, base_old)) {
- /* Path was relative and is now absolute. Remap.
- * Important BLI_cleanup_dir runs before the path is made relative
- * because it wont work for paths that start with "//../" */
- BLI_cleanup_file(base_new, filepath);
- BLI_path_rel(filepath, base_new);
- BLI_strncpy(path_dst, filepath, FILE_MAX);
- return TRUE;
- }
- else {
- /* Path was not relative to begin with. */
- return FALSE;
- }
-}
-
-
-/* -------------------------------------------------------------------- */
-/**
- * Backup/Restore/Free functions,
- * \note These functions assume the data won't chane order.
- */
-
-struct PathStore {
- struct PathStore *next, *prev;
-} PathStore;
-
-static int bpath_list_append(void *userdata, char *UNUSED(path_dst), const char *path_src)
-{
- /* store the path and string in a single alloc */
- ListBase *ls = userdata;
- size_t path_size = strlen(path_src) + 1;
- struct PathStore *path_store = MEM_mallocN(sizeof(PathStore) + path_size, __func__);
- char *filepath = (char *)(path_store + 1);
-
- memcpy(filepath, path_src, path_size);
- BLI_addtail(ls, path_store);
- return FALSE;
-}
-
-static int bpath_list_restore(void *userdata, char *path_dst, const char *path_src)
-{
- /* assume ls->first wont be NULL because the number of paths can't change!
- * (if they do caller is wrong) */
- ListBase *ls = userdata;
- struct PathStore *path_store = ls->first;
- const char *filepath = (char *)(path_store + 1);
- int ret;
-
- if (strcmp(path_src, filepath) == 0) {
- ret = FALSE;
- }
- else {
- BLI_strncpy(path_dst, filepath, FILE_MAX);
- ret = TRUE;
- }
-
- BLI_freelinkN(ls, path_store);
- return ret;
-}
-
-/* return ls_handle */
-void *BLI_bpath_list_backup(Main *bmain, const int flag)
-{
- ListBase *ls = MEM_callocN(sizeof(ListBase), __func__);
-
- BLI_bpath_traverse_main(bmain, bpath_list_append, flag, ls);
-
- return ls;
-}
-
-void BLI_bpath_list_restore(Main *bmain, const int flag, void *ls_handle)
-{
- ListBase *ls = ls_handle;
-
- BLI_bpath_traverse_main(bmain, bpath_list_restore, flag, ls);
-}
-
-void BLI_bpath_list_free(void *ls_handle)
-{
- ListBase *ls = ls_handle;
- BLI_assert(ls->first == NULL); /* assumes we were used */
- BLI_freelistN(ls);
- MEM_freeN(ls);
-}
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
new file mode 100644
index 0000000..b2280b9
--- /dev/null
+++ b/source/blender/blenlib/intern/buffer.c
@@ -0,0 +1,81 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_buffer.h"
+#include "BLI_utildefines.h"
+
+#include <string.h>
+
+static void *buffer_alloc(BLI_Buffer *buffer, int len)
+{
+ return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ?
+ MEM_callocN : MEM_mallocN)
+ (buffer->elem_size * len, "BLI_Buffer.data");
+}
+
+static void *buffer_realloc(BLI_Buffer *buffer, int len)
+{
+ return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ?
+ MEM_recallocN : MEM_reallocN)
+ (buffer->data, (buffer->elem_size * len));
+}
+
+void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
+{
+ if (new_count > buffer->alloc_count) {
+ if (buffer->flag & BLI_BUFFER_USE_STATIC) {
+ void *orig = buffer->data;
+
+ buffer->data = buffer_alloc(buffer, new_count);
+ memcpy(buffer->data, orig, buffer->elem_size * buffer->count);
+ buffer->alloc_count = new_count;
+ buffer->flag &= ~BLI_BUFFER_USE_STATIC;
+ }
+ else {
+ if (buffer->alloc_count && (new_count < buffer->alloc_count * 2)) {
+ buffer->alloc_count *= 2;
+ }
+ else {
+ buffer->alloc_count = new_count;
+ }
+
+ if (buffer->data) {
+ buffer->data = buffer_realloc(buffer, buffer->alloc_count);
+ }
+ else {
+ buffer->data = buffer_alloc(buffer, buffer->alloc_count);
+ }
+ }
+ }
+
+ buffer->count = new_count;
+}
+
+void BLI_buffer_free(BLI_Buffer *buffer)
+{
+ if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
+ if (buffer->data) {
+ MEM_freeN(buffer->data);
+ }
+ }
+ memset(buffer, 0, sizeof(*buffer));
+}
diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c
index b9b1813..e3ed88b 100644
--- a/source/blender/blenlib/intern/endian_switch.c
+++ b/source/blender/blenlib/intern/endian_switch.c
@@ -24,7 +24,7 @@
* \ingroup bli
*/
-#include "BLO_sys_types.h"
+#include "MEM_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 883cdfd..0f42fca 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -63,7 +63,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLO_sys_types.h" // for intptr_t support
+#include "MEM_sys_types.h" // for intptr_t support
/* gzip the file in from and write it to "to".
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 0a87316..353b73a 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -52,8 +52,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BKE_font.h"
-
#include "DNA_vfont_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_curve_types.h"
diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter.c
index 6203a98..3fe0ef1 100644
--- a/source/blender/blenlib/intern/jitter.c
+++ b/source/blender/blenlib/intern/jitter.c
@@ -165,7 +165,7 @@ void BLI_jitter_init(float *jitarr, int num)
MEM_freeN(jit2);
- /* finally, move jittertab to be centered around (0,0) */
+ /* finally, move jittertab to be centered around (0, 0) */
for (i = 0; i < 2 * num; i += 2) {
jitarr[i] -= 0.5f;
jitarr[i + 1] -= 0.5f;
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 9f6f409..c60a9ae 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -345,7 +345,7 @@ void *BLI_rfindlink(const ListBase *listbase, int number)
return link;
}
-int BLI_findindex(const ListBase *listbase, void *vlink)
+int BLI_findindex(const ListBase *listbase, const void *vlink)
{
Link *link = NULL;
int number = 0;
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index b9866f9..8eb6561 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -175,6 +175,42 @@ MINLINE int max_ii(int a, int b)
return (b < a) ? a : b;
}
+MINLINE float min_fff(float a, float b, float c)
+{
+ return min_ff(min_ff(a, b), c);
+}
+MINLINE float max_fff(float a, float b, float c)
+{
+ return max_ff(max_ff(a, b), c);
+}
+
+MINLINE int min_iii(int a, int b, int c)
+{
+ return min_ii(min_ii(a, b), c);
+}
+MINLINE int max_iii(int a, int b, int c)
+{
+ return max_ii(max_ii(a, b), c);
+}
+
+MINLINE float min_ffff(float a, float b, float c, float d)
+{
+ return min_ff(min_fff(a, b, c), d);
+}
+MINLINE float max_ffff(float a, float b, float c, float d)
+{
+ return max_ff(max_fff(a, b, c), d);
+}
+
+MINLINE int min_iiii(int a, int b, int c, int d)
+{
+ return min_ii(min_iii(a, b, c), d);
+}
+MINLINE int max_iiii(int a, int b, int c, int d)
+{
+ return max_ii(max_iii(a, b, c), d);
+}
+
MINLINE float signf(float f)
{
return (f < 0.f) ? -1.f : 1.f;
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 64851db..07cd85c 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -266,8 +266,8 @@ void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
{
- float cmax = MAX3(r, g, b);
- float cmin = MIN3(r, g, b);
+ const float cmax = max_fff(r, g, b);
+ const float cmin = min_fff(r, g, b);
float h, s, l = (cmax + cmin) / 2.0f;
if (cmax == cmin) {
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 4c8bd43..b8eeca5 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -149,31 +149,6 @@ MINLINE void linearrgb_to_srgb_ushort4(unsigned short srgb[4], const float linea
srgb[3] = FTOUSHORT(linear[3]);
}
-MINLINE void linearrgb_to_srgb_ushort4_predivide(unsigned short srgb[4], const float linear[4])
-{
- float alpha, inv_alpha, t;
- int i;
-
- if (linear[3] == 1.0f || linear[3] == 0.0f) {
- linearrgb_to_srgb_ushort4(srgb, linear);
- return;
- }
-
- alpha = linear[3];
- inv_alpha = 1.0f / alpha;
-
- for (i = 0; i < 3; ++i) {
- t = linear[i] * inv_alpha;
- srgb[i] = (t <= 1.0f) ?
- /* warning - converts: float -> short -> float -> short */
- (unsigned short) (to_srgb_table_lookup(t) * alpha) :
- /* if FTOUSHORT was an inline function this could be done less confusingly */
- ((t = linearrgb_to_srgb(t) * alpha), FTOUSHORT(t));
- }
-
- srgb[3] = FTOUSHORT(linear[3]);
-}
-
MINLINE void srgb_to_linearrgb_uchar4(float linear[4], const unsigned char srgb[4])
{
linear[0] = BLI_color_from_srgb_table[srgb[0]];
@@ -293,4 +268,62 @@ MINLINE int compare_rgb_uchar(const unsigned char col_a[3], const unsigned char
return 0;
}
+/**************** Alpha Transformations *****************/
+
+MINLINE void premul_to_straight_v4(float straight[4], const float premul[4])
+{
+ if (premul[3] == 0.0f || premul[3] == 1.0f) {
+ straight[0] = premul[0];
+ straight[1] = premul[1];
+ straight[2] = premul[2];
+ straight[3] = premul[3];
+ }
+ else {
+ float alpha_inv = 1.0f / premul[3];
+ straight[0] = premul[0] * alpha_inv;
+ straight[1] = premul[1] * alpha_inv;
+ straight[2] = premul[2] * alpha_inv;
+ straight[3] = premul[3];
+ }
+}
+
+MINLINE void straight_to_premul_v4(float premul[4], const float straight[4])
+{
+ float alpha = straight[3];
+ premul[0] = straight[0] * alpha;
+ premul[1] = straight[1] * alpha;
+ premul[2] = straight[2] * alpha;
+ premul[3] = straight[3];
+}
+
+MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
+{
+ float alpha = color[3] / 255.0f;
+ float fac = alpha / 255.0f;
+
+ result[0] = color[0] * fac;
+ result[1] = color[1] * fac;
+ result[2] = color[2] * fac;
+ result[3] = alpha;
+}
+
+MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4])
+{
+ if (color[3] == 0.0f || color[3] == 1.0f) {
+ result[0] = FTOCHAR(color[0]);
+ result[1] = FTOCHAR(color[1]);
+ result[2] = FTOCHAR(color[2]);
+ result[3] = FTOCHAR(color[3]);
+ }
+ else {
+ float alpha_inv = 1.0f / color[3];
+
+ /* hopefully this would be optimized */
+ result[0] = FTOCHAR(color[0] * alpha_inv);
+ result[1] = FTOCHAR(color[1] * alpha_inv);
+ result[2] = FTOCHAR(color[2] * alpha_inv);
+ result[3] = FTOCHAR(color[3]);
+ }
+}
+
#endif /* __MATH_COLOR_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 74abd7e..fc1d0e9 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -131,35 +131,43 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
float area_poly_v3(int nr, float verts[][3], const float normal[3])
{
- float x, y, z, area, max;
- float *cur, *prev;
- int a, px = 0, py = 1;
-
- /* first: find dominant axis: 0==X, 1==Y, 2==Z
- * don't use 'axis_dominant_v3()' because we need max axis too */
- x = fabsf(normal[0]);
- y = fabsf(normal[1]);
- z = fabsf(normal[2]);
- max = MAX3(x, y, z);
- if (max == y) py = 2;
- else if (max == x) {
- px = 1;
- py = 2;
- }
+ int a, px, py;
+ const float max = axis_dominant_v3_max(&px, &py, normal);
+ float area;
+ float *co_curr, *co_prev;
/* The Trapezium Area Rule */
- prev = verts[nr - 1];
- cur = verts[0];
- area = 0;
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ area = 0.0f;
for (a = 0; a < nr; a++) {
- area += (cur[px] - prev[px]) * (cur[py] + prev[py]);
- prev = verts[a];
- cur = verts[a + 1];
+ area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]);
+ co_prev = verts[a];
+ co_curr = verts[a + 1];
}
return fabsf(0.5f * area / max);
}
+float area_poly_v2(int nr, float verts[][2])
+{
+ int a;
+ float area;
+ float *co_curr, *co_prev;
+
+ /* The Trapezium Area Rule */
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ area = 0.0f;
+ for (a = 0; a < nr; a++) {
+ area += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
+ co_prev = verts[a];
+ co_curr = verts[a + 1];
+ }
+
+ return fabsf(0.5f * area);
+}
+
/********************************* Distance **********************************/
/* distance p to line v1-v2
@@ -180,7 +188,7 @@ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2])
/* distance p to line-piece v1-v2 */
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
{
- float labda, rc[2], pt[2], len;
+ float lambda, rc[2], pt[2], len;
rc[0] = l2[0] - l1[0];
rc[1] = l2[1] - l1[1];
@@ -191,18 +199,18 @@ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const
return (rc[0] * rc[0] + rc[1] * rc[1]);
}
- labda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len;
- if (labda <= 0.0f) {
+ lambda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len;
+ if (lambda <= 0.0f) {
pt[0] = l1[0];
pt[1] = l1[1];
}
- else if (labda >= 1.0f) {
+ else if (lambda >= 1.0f) {
pt[0] = l2[0];
pt[1] = l2[1];
}
else {
- pt[0] = labda * rc[0] + l1[0];
- pt[1] = labda * rc[1] + l1[1];
+ pt[0] = lambda * rc[0] + l1[0];
+ pt[1] = lambda * rc[1] + l1[1];
}
rc[0] = pt[0] - p[0];
@@ -296,22 +304,104 @@ float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float
return len_v3v3(closest, v1);
}
+/* Adapted from "Real-Time Collision Detection" by Christer Ericson,
+ * published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc.
+ *
+ * Set 'r' to the point in triangle (a, b, c) closest to point 'p' */
+void closest_on_tri_to_point_v3(float r[3], const float p[3],
+ const float a[3], const float b[3], const float c[3])
+{
+ float ab[3], ac[3], ap[3], d1, d2;
+ float bp[3], d3, d4, vc, cp[3], d5, d6, vb, va;
+ float denom, v, w;
+
+ /* Check if P in vertex region outside A */
+ sub_v3_v3v3(ab, b, a);
+ sub_v3_v3v3(ac, c, a);
+ sub_v3_v3v3(ap, p, a);
+ d1 = dot_v3v3(ab, ap);
+ d2 = dot_v3v3(ac, ap);
+ if (d1 <= 0.0f && d2 <= 0.0f) {
+ /* barycentric coordinates (1,0,0) */
+ copy_v3_v3(r, a);
+ return;
+ }
+
+ /* Check if P in vertex region outside B */
+ sub_v3_v3v3(bp, p, b);
+ d3 = dot_v3v3(ab, bp);
+ d4 = dot_v3v3(ac, bp);
+ if (d3 >= 0.0f && d4 <= d3) {
+ /* barycentric coordinates (0,1,0) */
+ copy_v3_v3(r, b);
+ return;
+ }
+ /* Check if P in edge region of AB, if so return projection of P onto AB */
+ vc = d1 * d4 - d3 * d2;
+ if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
+ float v = d1 / (d1 - d3);
+ /* barycentric coordinates (1-v,v,0) */
+ madd_v3_v3v3fl(r, a, ab, v);
+ return;
+ }
+ /* Check if P in vertex region outside C */
+ sub_v3_v3v3(cp, p, c);
+ d5 = dot_v3v3(ab, cp);
+ d6 = dot_v3v3(ac, cp);
+ if (d6 >= 0.0f && d5 <= d6) {
+ /* barycentric coordinates (0,0,1) */
+ copy_v3_v3(r, c);
+ return;
+ }
+ /* Check if P in edge region of AC, if so return projection of P onto AC */
+ vb = d5 * d2 - d1 * d6;
+ if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
+ float w = d2 / (d2 - d6);
+ /* barycentric coordinates (1-w,0,w) */
+ madd_v3_v3v3fl(r, a, ac, w);
+ return;
+ }
+ /* Check if P in edge region of BC, if so return projection of P onto BC */
+ va = d3 * d6 - d5 * d4;
+ if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
+ float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
+ /* barycentric coordinates (0,1-w,w) */
+ sub_v3_v3v3(r, c, b);
+ mul_v3_fl(r, w);
+ add_v3_v3(r, b);
+ return;
+ }
+
+ /* P inside face region. Compute Q through its barycentric coordinates (u,v,w) */
+ denom = 1.0f / (va + vb + vc);
+ v = vb * denom;
+ w = vc * denom;
+
+ /* = u*a + v*b + w*c, u = va * denom = 1.0f - v - w */
+ /* ac * w */
+ mul_v3_fl(ac, w);
+ /* a + ab * v */
+ madd_v3_v3v3fl(r, a, ab, v);
+ /* a + ab * v + ac * w */
+ add_v3_v3(r, ac);
+}
+
/******************************* Intersection ********************************/
/* intersect Line-Line, shorts */
int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
{
- float div, labda, mu;
+ float div, lambda, mu;
div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
- labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
- if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
+ if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
+ if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
return ISECT_LINE_LINE_CROSS;
}
return ISECT_LINE_LINE_NONE;
@@ -335,17 +425,17 @@ int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v
/* intersect Line-Line, floats */
int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
- float div, labda, mu;
+ float div, lambda, mu;
div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
- labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
- if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
+ if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
+ if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
return ISECT_LINE_LINE_CROSS;
}
return ISECT_LINE_LINE_NONE;
@@ -1037,7 +1127,7 @@ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const flo
if (t0 > 1.0f || t1 < 0.0f) return 0;
- /* clamp to [0,1] */
+ /* clamp to [0, 1] */
CLAMP(t0, 0.0f, 1.0f);
CLAMP(t1, 0.0f, 1.0f);
@@ -1157,10 +1247,10 @@ int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const flo
}
/*e3*/
- /* sub_v3_v3v3(bv,v0,p1); */ /* UNUSED */
- /* elen2 = dot_v3v3(e1,e1); */ /* UNUSED */
- /* edotv = dot_v3v3(e1,vel); */ /* UNUSED */
- /* edotbv = dot_v3v3(e1,bv); */ /* UNUSED */
+ /* sub_v3_v3v3(bv, v0, p1); */ /* UNUSED */
+ /* elen2 = dot_v3v3(e1, e1); */ /* UNUSED */
+ /* edotv = dot_v3v3(e1, vel); */ /* UNUSED */
+ /* edotbv = dot_v3v3(e1, bv); */ /* UNUSED */
sub_v3_v3v3(bv, v1, p1);
elen2 = dot_v3v3(e3, e3);
@@ -1195,13 +1285,13 @@ int isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3]
int a0 = axis, a1 = (axis + 1) % 3, a2 = (axis + 2) % 3;
#if 0
- return isect_line_tri_v3(p1,p2,v0,v1,v2,lambda);
+ return isect_line_tri_v3(p1, p2, v0, v1, v2, lambda);
/* first a simple bounding box test */
- if (MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
- if (MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
- if (MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
- if (MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
+ if (min_fff(v0[a1], v1[a1], v2[a1]) > p1[a1]) return 0;
+ if (min_fff(v0[a2], v1[a2], v2[a2]) > p1[a2]) return 0;
+ if (max_fff(v0[a1], v1[a1], v2[a1]) < p1[a1]) return 0;
+ if (max_fff(v0[a2], v1[a2], v2[a2]) < p1[a2]) return 0;
/* then a full intersection test */
#endif
@@ -1415,8 +1505,8 @@ int isect_ray_aabb(const IsectRayAABBData *data, const float bb_min[3],
return TRUE;
}
-/* find closest point to p on line through l1,l2 and return lambda,
- * where (0 <= lambda <= 1) when cp is in the line segment l1,l2
+/* find closest point to p on line through (l1, l2) and return lambda,
+ * where (0 <= lambda <= 1) when cp is in the line segment (l1, l2)
*/
float closest_to_line_v3(float cp[3], const float p[3], const float l1[3], const float l2[3])
{
@@ -1702,9 +1792,9 @@ static int point_in_slice(const float p[3], const float v1[3], const float l1[3]
/*
* what is a slice ?
* some maths:
- * a line including l1,l2 and a point not on the line
+ * a line including (l1, l2) and a point not on the line
* define a subset of R3 delimited by planes parallel to the line and orthogonal
- * to the (point --> line) distance vector,one plane on the line one on the point,
+ * to the (point --> line) distance vector, one plane on the line one on the point,
* the room inside usually is rather small compared to R3 though still infinite
* useful for restricting (speeding up) searches
* e.g. all points of triangular prism are within the intersection of 3 'slices'
@@ -1735,7 +1825,7 @@ static int point_in_slice_as(float p[3], float origin[3], float normal[3])
return 1;
}
-/*mama (knowing the squared length of the normal)*/
+/*mama (knowing the squared length of the normal) */
static int point_in_slice_m(float p[3], float origin[3], float normal[3], float lns)
{
float h, rp[3];
@@ -1870,15 +1960,27 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int,
/****************************** Interpolation ********************************/
/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
-void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3])
+void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
{
const float xn = fabsf(axis[0]);
const float yn = fabsf(axis[1]);
const float zn = fabsf(axis[2]);
- if (zn >= xn && zn >= yn) { *axis_a = 0; *axis_b = 1; }
- else if (yn >= xn && yn >= zn) { *axis_a = 0; *axis_b = 2; }
- else { *axis_a = 1; *axis_b = 2; }
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; }
+ else { *r_axis_a = 1; *r_axis_b = 2; }
+}
+
+/* same as axis_dominant_v3 but return the max value */
+float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
+{
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; }
+ else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; }
+ else { *r_axis_a = 1; *r_axis_b = 2; return xn; }
}
static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
@@ -2252,14 +2354,25 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i;
+ int i, i_next, i_curr;
+ bool edge_interp = false;
totweight = 0.0f;
for (i = 0; i < n; i++) {
+ i_curr = i;
+ i_next = (i == n - 1) ? 0 : i + 1;
+
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = (i == n - 1) ? v[0] : v[i + 1];
+ vnext = v[i_next];
+
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
+ if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ edge_interp = true;
+ break;
+ }
t1 = mean_value_half_tan_v3(co, vprev, vmid);
t2 = mean_value_half_tan_v3(co, vmid, vnext);
@@ -2269,25 +2382,49 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
totweight += w[i];
}
- if (totweight != 0.0f) {
- for (i = 0; i < n; i++) {
- w[i] /= totweight;
+ if (edge_interp) {
+ float len_curr = len_v3v3(co, vmid);
+ float len_next = len_v3v3(co, vnext);
+ float edge_len = len_curr + len_next;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+
+ w[i_curr] = len_next / edge_len;
+ w[i_next] = len_curr / edge_len;
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i = 0; i < n; i++) {
+ w[i] /= totweight;
+ }
}
}
}
+
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
{
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i;
+ int i, i_next, i_curr;
+ bool edge_interp = false;
totweight = 0.0f;
for (i = 0; i < n; i++) {
+ i_curr = i;
+ i_next = (i == n - 1) ? 0 : i + 1;
+
vmid = v[i];
vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = (i == n - 1) ? v[0] : v[i + 1];
+ vnext = v[i_next];
+
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
+ if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ edge_interp = true;
+ break;
+ }
t1 = mean_value_half_tan_v2(co, vprev, vmid);
t2 = mean_value_half_tan_v2(co, vmid, vnext);
@@ -2297,14 +2434,26 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
totweight += w[i];
}
- if (totweight != 0.0f) {
- for (i = 0; i < n; i++) {
- w[i] /= totweight;
+ if (edge_interp) {
+ float len_curr = len_v2v2(co, vmid);
+ float len_next = len_v2v2(co, vnext);
+ float edge_len = len_curr + len_next;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+
+ w[i_curr] = len_next / edge_len;
+ w[i_next] = len_curr / edge_len;
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i = 0; i < n; i++) {
+ w[i] /= totweight;
+ }
}
}
}
-/* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
+/* (x1, v1)(t1=0)------(x2, v2)(t2=1), 0<t<1 --> (x, v)(t) */
void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t)
{
float a[3], b[3];
@@ -2435,7 +2584,7 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
/***************************** View & Projection *****************************/
-void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top,
+void orthographic_m4(float matrix[4][4], const float left, const float right, const float bottom, const float top,
const float nearClip, const float farClip)
{
float Xdelta, Ydelta, Zdelta;
@@ -2481,7 +2630,7 @@ void perspective_m4(float mat[4][4], const float left, const float right, const
}
/* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords (used to jitter the view) */
-void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, const float y)
+void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y)
{
if (winmat[2][3] == -1.0f) {
/* in the case of a win-matrix, this means perspective always */
@@ -2509,7 +2658,7 @@ void window_translate_m4(float winmat[][4], float perspmat[][4], const float x,
}
}
-static void i_multmatrix(float icand[][4], float Vm[][4])
+static void i_multmatrix(float icand[4][4], float Vm[4][4])
{
int row, col;
float temp[4][4];
@@ -2523,7 +2672,7 @@ static void i_multmatrix(float icand[][4], float Vm[][4])
copy_m4_m4(Vm, temp);
}
-void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, float twist)
+void polarview_m4(float Vm[4][4], float dist, float azimuth, float incidence, float twist)
{
unit_m4(Vm);
@@ -2534,7 +2683,7 @@ void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, flo
rotate_m4(Vm, 'Z', -azimuth);
}
-void lookat_m4(float mat[][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
+void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
{
float sine, cosine, hyp, hyp1, dx, dy, dz;
float mat1[4][4] = MAT4_UNITY;
@@ -2791,8 +2940,8 @@ void tangent_from_uv(float uv1[2], float uv2[2], float uv3[3], float co1[3], flo
/****************************** Vector Clouds ********************************/
/* vector clouds */
-/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight,
- * float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
+/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, float (*rpos)[3], float *rweight,
+ * float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3])
*
* input
* (
@@ -2881,9 +3030,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
/* build 'projection' matrix */
for (a = 0; a < list_size; a++) {
sub_v3_v3v3(va, rpos[a], accu_rcom);
- /* mul_v3_fl(va,bp->mass); mass needs renormalzation here ?? */
+ /* mul_v3_fl(va, bp->mass); mass needs renormalzation here ?? */
sub_v3_v3v3(vb, pos[a], accu_com);
- /* mul_v3_fl(va,rp->mass); */
+ /* mul_v3_fl(va, rp->mass); */
m[0][0] += va[0] * vb[0];
m[0][1] += va[0] * vb[1];
m[0][2] += va[0] * vb[2];
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index ba9770e..f32b477 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -158,4 +158,31 @@ MINLINE int min_axis_v3(const float vec[3])
((y < z) ? 1 : 2));
}
+/**
+ * Simple method to find how many tri's we need when we already know the corner+poly count.
+ *
+ * Formula is:
+ *
+ * tri = ((corner_count / poly_count) - 2) * poly_count;
+ *
+ * Use doubles since this is used for allocating and we
+ * don't want float precision to give incorrect results.
+ *
+ * \param poly_count The number of ngon's/tris (1-2 sided faces will give incorrect results)
+ * \param corner_count - also known as loops in BMesh/DNA
+ */
+MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
+{
+ if (poly_count != 0) {
+ const double poly_count_d = (double)poly_count;
+ const double corner_count_d = (double)corner_count;
+ BLI_assert(poly_count > 0);
+ BLI_assert(corner_count > 0);
+ return (int)((((corner_count_d / poly_count_d) - 2.0) * poly_count_d) + 0.5);
+ }
+ else {
+ return 0;
+ }
+}
+
#endif /* __MATH_GEOM_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 38214f9..6784c41 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -43,7 +43,7 @@ void zero_m4(float m[4][4])
memset(m, 0, 4 * 4 * sizeof(float));
}
-void unit_m3(float m[][3])
+void unit_m3(float m[3][3])
{
m[0][0] = m[1][1] = m[2][2] = 1.0;
m[0][1] = m[0][2] = 0.0;
@@ -51,7 +51,7 @@ void unit_m3(float m[][3])
m[2][0] = m[2][1] = 0.0;
}
-void unit_m4(float m[][4])
+void unit_m4(float m[4][4])
{
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0;
m[0][1] = m[0][2] = m[0][3] = 0.0;
@@ -60,18 +60,18 @@ void unit_m4(float m[][4])
m[3][0] = m[3][1] = m[3][2] = 0.0;
}
-void copy_m3_m3(float m1[][3], float m2[][3])
+void copy_m3_m3(float m1[3][3], float m2[3][3])
{
/* destination comes first: */
memcpy(&m1[0], &m2[0], 9 * sizeof(float));
}
-void copy_m4_m4(float m1[][4], float m2[][4])
+void copy_m4_m4(float m1[4][4], float m2[4][4])
{
memcpy(m1, m2, 4 * 4 * sizeof(float));
}
-void copy_m3_m4(float m1[][3], float m2[][4])
+void copy_m3_m4(float m1[3][3], float m2[4][4])
{
m1[0][0] = m2[0][0];
m1[0][1] = m2[0][1];
@@ -86,7 +86,7 @@ void copy_m3_m4(float m1[][3], float m2[][4])
m1[2][2] = m2[2][2];
}
-void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */
+void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */
{
m1[0][0] = m2[0][0];
m1[0][1] = m2[0][1];
@@ -112,7 +112,7 @@ void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */
}
-void swap_m3m3(float m1[][3], float m2[][3])
+void swap_m3m3(float m1[3][3], float m2[3][3])
{
float t;
int i, j;
@@ -126,7 +126,7 @@ void swap_m3m3(float m1[][3], float m2[][3])
}
}
-void swap_m4m4(float m1[][4], float m2[][4])
+void swap_m4m4(float m1[4][4], float m2[4][4])
{
float t;
int i, j;
@@ -142,7 +142,7 @@ void swap_m4m4(float m1[][4], float m2[][4])
/******************************** Arithmetic *********************************/
-void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4])
+void mult_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4])
{
float m2[4][4], m3[4][4];
@@ -173,7 +173,7 @@ void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4])
}
-void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
+void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3])
{
float m2[3][3], m3[3][3];
@@ -195,7 +195,7 @@ void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3])
+void mul_m4_m4m3(float m1[4][4], float m3_[4][4], float m2_[3][3])
{
float m2[3][3], m3[4][4];
@@ -215,7 +215,7 @@ void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3])
}
/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */
-void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3])
+void mult_m3_m3m4(float m1[3][3], float m3_[4][4], float m2_[3][3])
{
float m2[3][3], m3[4][4];
@@ -237,7 +237,7 @@ void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4])
+void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4])
{
float m2[4][4], m3[3][3];
@@ -256,10 +256,10 @@ void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
-void mul_serie_m3(float answ[][3],
- float m1[][3], float m2[][3], float m3[][3],
- float m4[][3], float m5[][3], float m6[][3],
- float m7[][3], float m8[][3])
+void mul_serie_m3(float answ[3][3],
+ float m1[3][3], float m2[3][3], float m3[3][3],
+ float m4[3][3], float m5[3][3], float m6[3][3],
+ float m7[3][3], float m8[3][3])
{
float temp[3][3];
@@ -289,10 +289,10 @@ void mul_serie_m3(float answ[][3],
}
}
-void mul_serie_m4(float answ[][4], float m1[][4],
- float m2[][4], float m3[][4], float m4[][4],
- float m5[][4], float m6[][4], float m7[][4],
- float m8[][4])
+void mul_serie_m4(float answ[4][4], float m1[4][4],
+ float m2[4][4], float m3[4][4], float m4[4][4],
+ float m5[4][4], float m6[4][4], float m7[4][4],
+ float m8[4][4])
{
float temp[4][4];
@@ -322,7 +322,7 @@ void mul_serie_m4(float answ[][4], float m1[][4],
}
}
-void mul_m4_v3(float mat[][4], float vec[3])
+void mul_m4_v3(float mat[4][4], float vec[3])
{
float x, y;
@@ -333,7 +333,7 @@ void mul_m4_v3(float mat[][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
-void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3])
+void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3])
{
float x, y;
@@ -345,7 +345,7 @@ void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3])
}
/* same as mul_m4_v3() but doesnt apply translation component */
-void mul_mat3_m4_v3(float mat[][4], float vec[3])
+void mul_mat3_m4_v3(float mat[4][4], float vec[3])
{
float x, y;
@@ -356,7 +356,7 @@ void mul_mat3_m4_v3(float mat[][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
}
-void mul_project_m4_v3(float mat[][4], float vec[3])
+void mul_project_m4_v3(float mat[4][4], float vec[3])
{
const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
mul_m4_v3(mat, vec);
@@ -419,7 +419,7 @@ void mul_m3_v3(float M[3][3], float r[3])
copy_v3_v3(r, tmp);
}
-void mul_transposed_m3_v3(float mat[][3], float vec[3])
+void mul_transposed_m3_v3(float mat[3][3], float vec[3])
{
float x, y;
@@ -457,7 +457,7 @@ void mul_mat3_m4_fl(float m[4][4], float f)
m[i][j] *= f;
}
-void mul_m3_v3_double(float mat[][3], double vec[3])
+void mul_m3_v3_double(float mat[3][3], double vec[3])
{
double x, y;
@@ -468,7 +468,7 @@ void mul_m3_v3_double(float mat[][3], double vec[3])
vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2];
}
-void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
+void add_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
{
int i, j;
@@ -477,7 +477,7 @@ void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
m1[i][j] = m2[i][j] + m3[i][j];
}
-void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
+void add_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
{
int i, j;
@@ -486,7 +486,7 @@ void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
m1[i][j] = m2[i][j] + m3[i][j];
}
-void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
+void sub_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3])
{
int i, j;
@@ -495,7 +495,7 @@ void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
m1[i][j] = m2[i][j] - m3[i][j];
}
-void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
+void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4])
{
int i, j;
@@ -504,8 +504,7 @@ void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
m1[i][j] = m2[i][j] - m3[i][j];
}
-/* why not make this a standard part of the API? */
-static float determinant_m3_local(float m[3][3])
+float determinant_m3_array(float m[3][3])
{
return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
@@ -534,7 +533,7 @@ int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon)
adjoint_m3_m3(m1, m2);
/* then determinant old matrix! */
- det = determinant_m3_local(m2);
+ det = determinant_m3_array(m2);
success = (fabsf(det) > epsilon);
@@ -569,7 +568,7 @@ int invert_m3_m3(float m1[3][3], float m2[3][3])
adjoint_m3_m3(m1, m2);
/* then determinant old matrix! */
- det = determinant_m3_local(m2);
+ det = determinant_m3_array(m2);
success = (det != 0.0f);
@@ -613,6 +612,8 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4])
float max;
int maxj;
+ BLI_assert(inverse != mat);
+
/* Set inverse to identity */
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
@@ -665,7 +666,7 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4])
/****************************** Linear Algebra *******************************/
-void transpose_m3(float mat[][3])
+void transpose_m3(float mat[3][3])
{
float t;
@@ -680,7 +681,7 @@ void transpose_m3(float mat[][3])
mat[2][1] = t;
}
-void transpose_m4(float mat[][4])
+void transpose_m4(float mat[4][4])
{
float t;
@@ -706,7 +707,7 @@ void transpose_m4(float mat[][4])
mat[3][2] = t;
}
-void orthogonalize_m3(float mat[][3], int axis)
+void orthogonalize_m3(float mat[3][3], int axis)
{
float size[3];
mat3_to_size(size, mat);
@@ -784,7 +785,7 @@ void orthogonalize_m3(float mat[][3], int axis)
mul_v3_fl(mat[2], size[2]);
}
-void orthogonalize_m4(float mat[][4], int axis)
+void orthogonalize_m4(float mat[4][4], int axis)
{
float size[3];
mat4_to_size(size, mat);
@@ -863,7 +864,7 @@ void orthogonalize_m4(float mat[][4], int axis)
mul_v3_fl(mat[2], size[2]);
}
-int is_orthogonal_m3(float m[][3])
+int is_orthogonal_m3(float m[3][3])
{
int i, j;
@@ -877,7 +878,7 @@ int is_orthogonal_m3(float m[][3])
return 1;
}
-int is_orthogonal_m4(float m[][4])
+int is_orthogonal_m4(float m[4][4])
{
int i, j;
@@ -892,7 +893,7 @@ int is_orthogonal_m4(float m[][4])
return 1;
}
-int is_orthonormal_m3(float m[][3])
+int is_orthonormal_m3(float m[3][3])
{
if (is_orthogonal_m3(m)) {
int i;
@@ -907,7 +908,7 @@ int is_orthonormal_m3(float m[][3])
return 0;
}
-int is_orthonormal_m4(float m[][4])
+int is_orthonormal_m4(float m[4][4])
{
if (is_orthogonal_m4(m)) {
int i;
@@ -922,7 +923,7 @@ int is_orthonormal_m4(float m[][4])
return 0;
}
-int is_uniform_scaled_m3(float m[][3])
+int is_uniform_scaled_m3(float m[3][3])
{
const float eps = 1e-7;
float t[3][3];
@@ -951,21 +952,21 @@ int is_uniform_scaled_m3(float m[][3])
return 0;
}
-void normalize_m3(float mat[][3])
+void normalize_m3(float mat[3][3])
{
normalize_v3(mat[0]);
normalize_v3(mat[1]);
normalize_v3(mat[2]);
}
-void normalize_m3_m3(float rmat[][3], float mat[][3])
+void normalize_m3_m3(float rmat[3][3], float mat[3][3])
{
normalize_v3_v3(rmat[0], mat[0]);
normalize_v3_v3(rmat[1], mat[1]);
normalize_v3_v3(rmat[2], mat[2]);
}
-void normalize_m4(float mat[][4])
+void normalize_m4(float mat[4][4])
{
float len;
@@ -977,7 +978,7 @@ void normalize_m4(float mat[][4])
if (len != 0.0f) mat[2][3] /= len;
}
-void normalize_m4_m4(float rmat[][4], float mat[][4])
+void normalize_m4_m4(float rmat[4][4], float mat[4][4])
{
float len;
@@ -989,7 +990,7 @@ void normalize_m4_m4(float rmat[][4], float mat[][4])
if (len != 0.0f) rmat[2][3] = mat[2][3] / len;
}
-void adjoint_m2_m2(float m1[][2], float m[][2])
+void adjoint_m2_m2(float m1[2][2], float m[2][2])
{
BLI_assert(m1 != m);
m1[0][0] = m[1][1];
@@ -998,7 +999,7 @@ void adjoint_m2_m2(float m1[][2], float m[][2])
m1[1][1] = m[0][0];
}
-void adjoint_m3_m3(float m1[][3], float m[][3])
+void adjoint_m3_m3(float m1[3][3], float m[3][3])
{
BLI_assert(m1 != m);
m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1];
@@ -1014,7 +1015,7 @@ void adjoint_m3_m3(float m1[][3], float m[][3])
m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
-void adjoint_m4_m4(float out[][4], float in[][4]) /* out = ADJ(in) */
+void adjoint_m4_m4(float out[4][4], float in[4][4]) /* out = ADJ(in) */
{
float a1, a2, a3, a4, b1, b2, b3, b4;
float c1, c2, c3, c4, d1, d2, d3, d4;
@@ -1080,7 +1081,7 @@ float determinant_m3(float a1, float a2, float a3,
return ans;
}
-float determinant_m4(float m[][4])
+float determinant_m4(float m[4][4])
{
float ans;
float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
@@ -1115,7 +1116,7 @@ float determinant_m4(float m[][4])
/****************************** Transformations ******************************/
-void size_to_mat3(float mat[][3], const float size[3])
+void size_to_mat3(float mat[3][3], const float size[3])
{
mat[0][0] = size[0];
mat[0][1] = 0.0f;
@@ -1128,7 +1129,7 @@ void size_to_mat3(float mat[][3], const float size[3])
mat[2][0] = 0.0f;
}
-void size_to_mat4(float mat[][4], const float size[3])
+void size_to_mat4(float mat[4][4], const float size[3])
{
float tmat[3][3];
@@ -1137,14 +1138,14 @@ void size_to_mat4(float mat[][4], const float size[3])
copy_m4_m3(mat, tmat);
}
-void mat3_to_size(float size[3], float mat[][3])
+void mat3_to_size(float size[3], float mat[3][3])
{
size[0] = len_v3(mat[0]);
size[1] = len_v3(mat[1]);
size[2] = len_v3(mat[2]);
}
-void mat4_to_size(float size[3], float mat[][4])
+void mat4_to_size(float size[3], float mat[4][4])
{
size[0] = len_v3(mat[0]);
size[1] = len_v3(mat[1]);
@@ -1154,7 +1155,7 @@ void mat4_to_size(float size[3], float mat[][4])
/* this gets the average scale of a matrix, only use when your scaling
* data that has no idea of scale axis, examples are bone-envelope-radius
* and curve radius */
-float mat3_to_scale(float mat[][3])
+float mat3_to_scale(float mat[3][3])
{
/* unit length vector */
float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
@@ -1162,7 +1163,7 @@ float mat3_to_scale(float mat[][3])
return len_v3(unit_vec);
}
-float mat4_to_scale(float mat[][4])
+float mat4_to_scale(float mat[4][4])
{
float tmat[3][3];
copy_m3_m4(tmat, mat);
@@ -1200,7 +1201,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
size[2] = mat3[2][2];
}
-void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4])
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4])
{
float mat3[3][3]; /* wmat -> 3x3 */
@@ -1211,7 +1212,7 @@ void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wm
copy_v3_v3(loc, wmat[3]);
}
-void scale_m3_fl(float m[][3], float scale)
+void scale_m3_fl(float m[3][3], float scale)
{
m[0][0] = m[1][1] = m[2][2] = scale;
m[0][1] = m[0][2] = 0.0;
@@ -1219,7 +1220,7 @@ void scale_m3_fl(float m[][3], float scale)
m[2][0] = m[2][1] = 0.0;
}
-void scale_m4_fl(float m[][4], float scale)
+void scale_m4_fl(float m[4][4], float scale)
{
m[0][0] = m[1][1] = m[2][2] = scale;
m[3][3] = 1.0;
@@ -1229,14 +1230,14 @@ void scale_m4_fl(float m[][4], float scale)
m[3][0] = m[3][1] = m[3][2] = 0.0;
}
-void translate_m4(float mat[][4], float Tx, float Ty, float Tz)
+void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
{
mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
}
-void rotate_m4(float mat[][4], const char axis, const float angle)
+void rotate_m4(float mat[4][4], const char axis, const float angle)
{
int col;
float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -1244,8 +1245,8 @@ void rotate_m4(float mat[][4], const char axis, const float angle)
assert(axis >= 'X' && axis <= 'Z');
- cosine = (float)cos(angle);
- sine = (float)sin(angle);
+ cosine = cosf(angle);
+ sine = sinf(angle);
switch (axis) {
case 'X':
for (col = 0; col < 4; col++)
@@ -1276,7 +1277,7 @@ void rotate_m4(float mat[][4], const char axis, const float angle)
}
}
-void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight)
+void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
float squat[4], dquat[4], fquat[4];
@@ -1299,7 +1300,7 @@ void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float s
mul_m3_m3m3(out, rmat, smat);
}
-void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight)
+void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const float srcweight)
{
float sloc[3], dloc[3], floc[3];
float srot[3][3], drot[3][3];
@@ -1321,14 +1322,14 @@ void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float s
loc_quat_size_to_mat4(out, floc, fquat, fsize);
}
-int is_negative_m3(float mat[][3])
+int is_negative_m3(float mat[3][3])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
-int is_negative_m4(float mat[][4])
+int is_negative_m4(float mat[4][4])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
@@ -1418,7 +1419,7 @@ void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float
/*********************************** Other ***********************************/
-void print_m3(const char *str, float m[][3])
+void print_m3(const char *str, float m[3][3])
{
printf("%s\n", str);
printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
@@ -1427,7 +1428,7 @@ void print_m3(const char *str, float m[][3])
printf("\n");
}
-void print_m4(const char *str, float m[][4])
+void print_m4(const char *str, float m[4][4])
{
printf("%s\n", str);
printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
@@ -1901,3 +1902,16 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon)
mul_serie_m4(Ainv, U, Wm, V, NULL, NULL, NULL, NULL, NULL);
}
+
+void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon)
+{
+ /* try regular inverse when possible, otherwise fall back to slow svd */
+ if (!invert_m3_m3(Ainv, A)) {
+ float tmp[4][4], tmpinv[4][4];
+
+ copy_m4_m3(tmp, A);
+ pseudoinverse_m4_m4(tmpinv, tmp, epsilon);
+ copy_m3_m4(Ainv, tmpinv);
+ }
+}
+
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 3069542..dc54bf9 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -185,7 +185,7 @@ void mul_fac_qt_fl(float q[4], const float fac)
}
/* skip error check, currently only needed by mat3_to_quat_is_ok */
-static void quat_to_mat3_no_error(float m[][3], const float q[4])
+static void quat_to_mat3_no_error(float m[3][3], const float q[4])
{
double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
@@ -217,7 +217,7 @@ static void quat_to_mat3_no_error(float m[][3], const float q[4])
m[2][2] = (float)(1.0 - qaa - qbb);
}
-void quat_to_mat3(float m[][3], const float q[4])
+void quat_to_mat3(float m[3][3], const float q[4])
{
#ifdef DEBUG
float f;
@@ -229,7 +229,7 @@ void quat_to_mat3(float m[][3], const float q[4])
quat_to_mat3_no_error(m, q);
}
-void quat_to_mat4(float m[][4], const float q[4])
+void quat_to_mat4(float m[4][4], const float q[4])
{
double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
@@ -273,7 +273,7 @@ void quat_to_mat4(float m[][4], const float q[4])
m[3][3] = 1.0f;
}
-void mat3_to_quat(float q[4], float wmat[][3])
+void mat3_to_quat(float q[4], float wmat[3][3])
{
double tr, s;
float mat[3][3];
@@ -325,7 +325,7 @@ void mat3_to_quat(float q[4], float wmat[][3])
normalize_qt(q);
}
-void mat4_to_quat(float q[4], float m[][4])
+void mat4_to_quat(float q[4], float m[4][4])
{
float mat[3][3];
@@ -589,10 +589,10 @@ void interp_qt_qtqt(float result[4], const float quat1[4], const float quat2[4],
}
if ((1.0f - cosom) > 0.0001f) {
- omega = (float)acos(cosom);
- sinom = (float)sin(omega);
- sc1 = (float)sin((1 - t) * omega) / sinom;
- sc2 = (float)sin(t * omega) / sinom;
+ omega = acosf(cosom);
+ sinom = sinf(omega);
+ sc1 = sinf((1.0f - t) * omega) / sinom;
+ sc2 = sinf(t * omega) / sinom;
}
else {
sc1 = 1.0f - t;
@@ -861,7 +861,7 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang
/* TODO: the following calls should probably be deprecated sometime */
/* TODO, replace use of this function with axis_angle_to_mat3() */
-void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi)
+void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi)
{
/* rotation of phi radials around vec */
float vx, vx2, vy, vy2, vz, vz2, co, si;
@@ -889,7 +889,7 @@ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi)
/******************************** XYZ Eulers *********************************/
/* XYZ order */
-void eul_to_mat3(float mat[][3], const float eul[3])
+void eul_to_mat3(float mat[3][3], const float eul[3])
{
double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
@@ -917,7 +917,7 @@ void eul_to_mat3(float mat[][3], const float eul[3])
}
/* XYZ order */
-void eul_to_mat4(float mat[][4], const float eul[3])
+void eul_to_mat4(float mat[4][4], const float eul[3])
{
double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
@@ -950,7 +950,7 @@ void eul_to_mat4(float mat[][4], const float eul[3])
/* returns two euler calculation methods, so we can pick the best */
/* XYZ order */
-static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3])
+static void mat3_to_eul2(float tmat[3][3], float eul1[3], float eul2[3])
{
float cy, quat[4], mat[3][3];
@@ -982,7 +982,7 @@ static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3])
}
/* XYZ order */
-void mat3_to_eul(float *eul, float tmat[][3])
+void mat3_to_eul(float *eul, float tmat[3][3])
{
float eul1[3], eul2[3];
@@ -998,7 +998,7 @@ void mat3_to_eul(float *eul, float tmat[][3])
}
/* XYZ order */
-void mat4_to_eul(float *eul, float tmat[][4])
+void mat4_to_eul(float *eul, float tmat[4][4])
{
float tempMat[3][3];
@@ -1107,7 +1107,7 @@ void compatible_eul(float eul[3], const float oldrot[3])
/* uses 2 methods to retrieve eulers, and picks the closest */
/* XYZ order */
-void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[][3])
+void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3])
{
float eul1[3], eul2[3];
float d1, d2;
@@ -1388,7 +1388,7 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang)
}
/* the matrix is written to as 3 axis vectors */
-void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order)
+void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order)
{
const RotOrderInfo *R = GET_ROTATIONORDER_INFO(order);
@@ -1447,7 +1447,7 @@ void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order)
* - added support for scaling
*/
-void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4])
+void mat4_to_dquat(DualQuat *dq, float basemat[4][4], float mat[4][4])
{
float *t, *q, dscale[3], scale[3], basequat[4];
float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4];
@@ -1502,7 +1502,7 @@ void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4])
dq->trans[3] = 0.5f * ( t[0] * q[2] - t[1] * q[1] + t[2] * q[0]);
}
-void dquat_to_mat4(float mat[][4], DualQuat *dq)
+void dquat_to_mat4(float mat[4][4], DualQuat *dq)
{
float len, *t, q0[4];
@@ -1583,7 +1583,7 @@ void normalize_dq(DualQuat *dq, float totweight)
}
}
-void mul_v3m3_dq(float co[3], float mat[][3], DualQuat *dq)
+void mul_v3m3_dq(float co[3], float mat[3][3], DualQuat *dq)
{
float M[3][3], t[3], scalemat[3][3], len2;
float w = dq->quat[0], x = dq->quat[1], y = dq->quat[2], z = dq->quat[3];
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 3ede863..8c62fdf 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -461,7 +461,7 @@ MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
r[2] = v1[2] * v2[2];
}
-MINLINE void negate_v2(float r[3])
+MINLINE void negate_v2(float r[2])
{
r[0] = -r[0];
r[1] = -r[1];
@@ -544,7 +544,7 @@ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const f
n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
}
-MINLINE void star_m3_v3(float rmat[][3], float a[3])
+MINLINE void star_m3_v3(float rmat[3][3], float a[3])
{
rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
rmat[0][1] = -a[2];
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 444daf8..06b1f1f 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -47,7 +47,7 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
-#include "BKE_blender.h" /* BLENDER_VERSION */
+#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
#include "GHOST_Path-api.h"
@@ -1212,8 +1212,6 @@ void BLI_setenv_if_new(const char *env, const char *val)
void BLI_clean(char *path)
{
- if (path == NULL) return;
-
#ifdef WIN32
if (path && BLI_strnlen(path, 3) > 2) {
BLI_char_switch(path + 2, '/', '\\');
@@ -1225,7 +1223,6 @@ void BLI_clean(char *path)
void BLI_char_switch(char *string, char from, char to)
{
- if (string == NULL) return;
while (*string != 0) {
if (*string == from) *string = to;
string++;
@@ -1622,7 +1619,7 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
rel_dir[0] = 0;
/* if image is "below" current .blend file directory */
- if (!strncmp(path, blend_dir, len)) {
+ if (!BLI_path_ncmp(path, blend_dir, len)) {
/* if image is _in_ current .blend file directory */
if (BLI_path_cmp(dir, blend_dir) == 0) {
diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c
deleted file mode 100644
index 6fa6d86..0000000
--- a/source/blender/blenlib/intern/pbvh.c
+++ /dev/null
@@ -1,1911 +0,0 @@
-/*
- * ***** 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 LICENSE BLOCK *****
- */
-
-/** \file blender/blenlib/intern/pbvh.c
- * \ingroup bli
- */
-
-
-
-#include "DNA_meshdata_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_bitmap.h"
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_pbvh.h"
-
-#include "BKE_ccg.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_mesh.h" /* for BKE_mesh_calc_normals */
-#include "BKE_global.h" /* for BKE_mesh_calc_normals */
-#include "BKE_paint.h"
-#include "BKE_subsurf.h"
-
-#include "GPU_buffers.h"
-
-#define LEAF_LIMIT 10000
-
-//#define PERFCNTRS
-
-/* Axis-aligned bounding box */
-typedef struct {
- float bmin[3], bmax[3];
-} BB;
-
-/* Axis-aligned bounding box with centroid */
-typedef struct {
- float bmin[3], bmax[3], bcentroid[3];
-} BBC;
-
-struct PBVHNode {
- /* Opaque handle for drawing code */
- GPU_Buffers *draw_buffers;
-
- /* Voxel bounds */
- BB vb;
- BB orig_vb;
-
- /* For internal nodes, the offset of the children in the PBVH
- * 'nodes' array. */
- int children_offset;
-
- /* Pointer into the PBVH prim_indices array and the number of
- * primitives used by this leaf node.
- *
- * Used for leaf nodes in both mesh- and multires-based PBVHs.
- */
- int *prim_indices;
- unsigned int totprim;
-
- /* Array of indices into the mesh's MVert array. Contains the
- * indices of all vertices used by faces that are within this
- * node's bounding box.
- *
- * Note that a vertex might be used by a multiple faces, and
- * these faces might be in different leaf nodes. Such a vertex
- * will appear in the vert_indices array of each of those leaf
- * nodes.
- *
- * In order to support cases where you want access to multiple
- * nodes' vertices without duplication, the vert_indices array
- * is ordered such that the first part of the array, up to
- * index 'uniq_verts', contains "unique" vertex indices. These
- * vertices might not be truly unique to this node, but if
- * they appear in another node's vert_indices array, they will
- * be above that node's 'uniq_verts' value.
- *
- * Used for leaf nodes in a mesh-based PBVH (not multires.)
- */
- int *vert_indices;
- unsigned int uniq_verts, face_verts;
-
- /* An array mapping face corners into the vert_indices
- * array. The array is sized to match 'totprim', and each of
- * the face's corners gets an index into the vert_indices
- * array, in the same order as the corners in the original
- * MFace. The fourth value should not be used if the original
- * face is a triangle.
- *
- * Used for leaf nodes in a mesh-based PBVH (not multires.)
- */
- int (*face_vert_indices)[4];
-
- /* Indicates whether this node is a leaf or not; also used for
- * marking various updates that need to be applied. */
- PBVHNodeFlags flag : 8;
-
- /* Used for raycasting: how close bb is to the ray point. */
- float tmin;
-
- int proxy_count;
- PBVHProxyNode *proxies;
-};
-
-struct PBVH {
- PBVHType type;
-
- PBVHNode *nodes;
- int node_mem_count, totnode;
-
- int *prim_indices;
- int totprim;
- int totvert;
-
- int leaf_limit;
-
- /* Mesh data */
- MVert *verts;
- MFace *faces;
- CustomData *vdata;
-
- /* Grid Data */
- CCGKey gridkey;
- CCGElem **grids;
- DMGridAdjacency *gridadj;
- void **gridfaces;
- const DMFlagMat *grid_flag_mats;
- int totgrid;
- BLI_bitmap *grid_hidden;
-
- /* Only used during BVH build and update,
- * don't need to remain valid after */
- BLI_bitmap vert_bitmap;
-
-#ifdef PERFCNTRS
- int perf_modified;
-#endif
-
- /* flag are verts/faces deformed */
- int deformed;
-
- int show_diffuse_color;
-};
-
-#define STACK_FIXED_DEPTH 100
-
-typedef struct PBVHStack {
- PBVHNode *node;
- int revisiting;
-} PBVHStack;
-
-typedef struct PBVHIter {
- PBVH *bvh;
- BLI_pbvh_SearchCallback scb;
- void *search_data;
-
- PBVHStack *stack;
- int stacksize;
-
- PBVHStack stackfixed[STACK_FIXED_DEPTH];
- int stackspace;
-} PBVHIter;
-
-static void BB_reset(BB *bb)
-{
- bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
- bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
-}
-
-/* Expand the bounding box to include a new coordinate */
-static void BB_expand(BB *bb, float co[3])
-{
- int i;
- for (i = 0; i < 3; ++i) {
- bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
- bb->bmax[i] = max_ff(bb->bmax[i], co[i]);
- }
-}
-
-/* Expand the bounding box to include another bounding box */
-static void BB_expand_with_bb(BB *bb, BB *bb2)
-{
- int i;
- for (i = 0; i < 3; ++i) {
- bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
- bb->bmax[i] = max_ff(bb->bmax[i], bb2->bmax[i]);
- }
-}
-
-/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
-static int BB_widest_axis(BB *bb)
-{
- float dim[3];
- int i;
-
- for (i = 0; i < 3; ++i)
- dim[i] = bb->bmax[i] - bb->bmin[i];
-
- if (dim[0] > dim[1]) {
- if (dim[0] > dim[2])
- return 0;
- else
- return 2;
- }
- else {
- if (dim[1] > dim[2])
- return 1;
- else
- return 2;
- }
-}
-
-static void BBC_update_centroid(BBC *bbc)
-{
- int i;
- for (i = 0; i < 3; ++i)
- bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
-}
-
-/* Not recursive */
-static void update_node_vb(PBVH *bvh, PBVHNode *node)
-{
- BB vb;
-
- BB_reset(&vb);
-
- if (node->flag & PBVH_Leaf) {
- PBVHVertexIter vd;
-
- BLI_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL)
- {
- BB_expand(&vb, vd.co);
- }
- BLI_pbvh_vertex_iter_end;
- }
- else {
- BB_expand_with_bb(&vb,
- &bvh->nodes[node->children_offset].vb);
- BB_expand_with_bb(&vb,
- &bvh->nodes[node->children_offset + 1].vb);
- }
-
- node->vb = vb;
-}
-
-//void BLI_pbvh_node_BB_reset(PBVHNode *node)
-//{
-// BB_reset(&node->vb);
-//}
-//
-//void BLI_pbvh_node_BB_expand(PBVHNode *node, float co[3])
-//{
-// BB_expand(&node->vb, co);
-//}
-
-static int face_materials_match(const MFace *f1, const MFace *f2)
-{
- return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
- (f1->mat_nr == f2->mat_nr));
-}
-
-static int grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2)
-{
- return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
- (f1->mat_nr == f2->mat_nr));
-}
-
-/* Adapted from BLI_kdopbvh.c */
-/* Returns the index of the first element on the right of the partition */
-static int partition_indices(int *prim_indices, int lo, int hi, int axis,
- float mid, BBC *prim_bbc)
-{
- int i = lo, j = hi;
- for (;; ) {
- for (; prim_bbc[prim_indices[i]].bcentroid[axis] < mid; i++) ;
- for (; mid < prim_bbc[prim_indices[j]].bcentroid[axis]; j--) ;
-
- if (!(i < j))
- return i;
-
- SWAP(int, prim_indices[i], prim_indices[j]);
- i++;
- }
-}
-
-/* Returns the index of the first element on the right of the partition */
-static int partition_indices_material(PBVH *bvh, int lo, int hi)
-{
- const MFace *faces = bvh->faces;
- const DMFlagMat *flagmats = bvh->grid_flag_mats;
- const int *indices = bvh->prim_indices;
- const void *first;
- int i = lo, j = hi;
-
- if (bvh->faces)
- first = &faces[bvh->prim_indices[lo]];
- else
- first = &flagmats[bvh->prim_indices[lo]];
-
- for (;; ) {
- if (bvh->faces) {
- for (; face_materials_match(first, &faces[indices[i]]); i++) ;
- for (; !face_materials_match(first, &faces[indices[j]]); j--) ;
- }
- else {
- for (; grid_materials_match(first, &flagmats[indices[i]]); i++) ;
- for (; !grid_materials_match(first, &flagmats[indices[j]]); j--) ;
- }
-
- if (!(i < j))
- return i;
-
- SWAP(int, bvh->prim_indices[i], bvh->prim_indices[j]);
- i++;
- }
-}
-
-static void grow_nodes(PBVH *bvh, int totnode)
-{
- if (totnode > bvh->node_mem_count) {
- PBVHNode *prev = bvh->nodes;
- bvh->node_mem_count *= 1.33;
- if (bvh->node_mem_count < totnode)
- bvh->node_mem_count = totnode;
- bvh->nodes = MEM_callocN(sizeof(PBVHNode) * bvh->node_mem_count,
- "bvh nodes");
- memcpy(bvh->nodes, prev, bvh->totnode * sizeof(PBVHNode));
- MEM_freeN(prev);
- }
-
- bvh->totnode = totnode;
-}
-
-/* Add a vertex to the map, with a positive value for unique vertices and
- * a negative value for additional vertices */
-static int map_insert_vert(PBVH *bvh, GHash *map,
- unsigned int *face_verts,
- unsigned int *uniq_verts, int vertex)
-{
- void *value, *key = SET_INT_IN_POINTER(vertex);
-
- if (!BLI_ghash_haskey(map, key)) {
- if (BLI_BITMAP_GET(bvh->vert_bitmap, vertex)) {
- value = SET_INT_IN_POINTER(~(*face_verts));
- ++(*face_verts);
- }
- else {
- BLI_BITMAP_SET(bvh->vert_bitmap, vertex);
- value = SET_INT_IN_POINTER(*uniq_verts);
- ++(*uniq_verts);
- }
-
- BLI_ghash_insert(map, key, value);
- return GET_INT_FROM_POINTER(value);
- }
- else
- return GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
-}
-
-/* Find vertices used by the faces in this node and update the draw buffers */
-static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
-{
- GHashIterator *iter;
- GHash *map;
- int i, j, totface;
-
- map = BLI_ghash_int_new("build_mesh_leaf_node gh");
-
- node->uniq_verts = node->face_verts = 0;
- totface = node->totprim;
-
- node->face_vert_indices = MEM_callocN(sizeof(int) * 4 * totface,
- "bvh node face vert indices");
-
- for (i = 0; i < totface; ++i) {
- MFace *f = bvh->faces + node->prim_indices[i];
- int sides = f->v4 ? 4 : 3;
-
- for (j = 0; j < sides; ++j) {
- node->face_vert_indices[i][j] =
- map_insert_vert(bvh, map, &node->face_verts,
- &node->uniq_verts, (&f->v1)[j]);
- }
- }
-
- node->vert_indices = MEM_callocN(sizeof(int) *
- (node->uniq_verts + node->face_verts),
- "bvh node vert indices");
-
- /* Build the vertex list, unique verts first */
- for (iter = BLI_ghashIterator_new(map), i = 0;
- BLI_ghashIterator_isDone(iter) == FALSE;
- BLI_ghashIterator_step(iter), ++i)
- {
- void *value = BLI_ghashIterator_getValue(iter);
- int ndx = GET_INT_FROM_POINTER(value);
-
- if (ndx < 0)
- ndx = -ndx + node->uniq_verts - 1;
-
- node->vert_indices[ndx] =
- GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(iter));
- }
-
- BLI_ghashIterator_free(iter);
-
- for (i = 0; i < totface; ++i) {
- MFace *f = bvh->faces + node->prim_indices[i];
- int sides = f->v4 ? 4 : 3;
-
- for (j = 0; j < sides; ++j) {
- if (node->face_vert_indices[i][j] < 0)
- node->face_vert_indices[i][j] =
- -node->face_vert_indices[i][j] +
- node->uniq_verts - 1;
- }
- }
-
- if (!G.background) {
- node->draw_buffers =
- GPU_build_mesh_buffers(node->face_vert_indices,
- bvh->faces, bvh->verts,
- node->prim_indices,
- node->totprim);
- }
-
- node->flag |= PBVH_UpdateDrawBuffers;
-
- BLI_ghash_free(map, NULL, NULL);
-}
-
-static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
-{
- if (!G.background) {
- node->draw_buffers =
- GPU_build_grid_buffers(node->prim_indices,
- node->totprim, bvh->grid_hidden, bvh->gridkey.grid_size);
- }
- node->flag |= PBVH_UpdateDrawBuffers;
-}
-
-static void update_vb(PBVH *bvh, PBVHNode *node, BBC *prim_bbc,
- int offset, int count)
-{
- int i;
-
- BB_reset(&node->vb);
- for (i = offset + count - 1; i >= offset; --i) {
- BB_expand_with_bb(&node->vb, (BB *)(&prim_bbc[bvh->prim_indices[i]]));
- }
- node->orig_vb = node->vb;
-}
-
-static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
- int offset, int count)
-{
- bvh->nodes[node_index].flag |= PBVH_Leaf;
-
- bvh->nodes[node_index].prim_indices = bvh->prim_indices + offset;
- bvh->nodes[node_index].totprim = count;
-
- /* Still need vb for searches */
- update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
-
- if (bvh->faces)
- build_mesh_leaf_node(bvh, bvh->nodes + node_index);
- else
- build_grids_leaf_node(bvh, bvh->nodes + node_index);
-}
-
-/* Return zero if all primitives in the node can be drawn with the
- * same material (including flat/smooth shading), non-zerootherwise */
-static int leaf_needs_material_split(PBVH *bvh, int offset, int count)
-{
- int i, prim;
-
- if (count <= 1)
- return 0;
-
- if (bvh->faces) {
- const MFace *first = &bvh->faces[bvh->prim_indices[offset]];
-
- for (i = offset + count - 1; i > offset; --i) {
- prim = bvh->prim_indices[i];
- if (!face_materials_match(first, &bvh->faces[prim]))
- return 1;
- }
- }
- else {
- const DMFlagMat *first = &bvh->grid_flag_mats[bvh->prim_indices[offset]];
-
- for (i = offset + count - 1; i > offset; --i) {
- prim = bvh->prim_indices[i];
- if (!grid_materials_match(first, &bvh->grid_flag_mats[prim]))
- return 1;
- }
- }
-
- return 0;
-}
-
-
-/* Recursively build a node in the tree
- *
- * vb is the voxel box around all of the primitives contained in
- * this node.
- *
- * cb is the bounding box around all the centroids of the primitives
- * contained in this node
- *
- * offset and start indicate a range in the array of primitive indices
- */
-
-static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
- int offset, int count)
-{
- int i, axis, end, below_leaf_limit;
- BB cb_backing;
-
- /* Decide whether this is a leaf or not */
- below_leaf_limit = count <= bvh->leaf_limit;
- if (below_leaf_limit) {
- if (!leaf_needs_material_split(bvh, offset, count)) {
- build_leaf(bvh, node_index, prim_bbc, offset, count);
- return;
- }
- }
-
- /* Add two child nodes */
- bvh->nodes[node_index].children_offset = bvh->totnode;
- grow_nodes(bvh, bvh->totnode + 2);
-
- /* Update parent node bounding box */
- update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
-
- if (!below_leaf_limit) {
- /* Find axis with widest range of primitive centroids */
- if (!cb) {
- cb = &cb_backing;
- BB_reset(cb);
- for (i = offset + count - 1; i >= offset; --i)
- BB_expand(cb, prim_bbc[bvh->prim_indices[i]].bcentroid);
- }
- axis = BB_widest_axis(cb);
-
- /* Partition primitives along that axis */
- end = partition_indices(bvh->prim_indices,
- offset, offset + count - 1,
- axis,
- (cb->bmax[axis] + cb->bmin[axis]) * 0.5f,
- prim_bbc);
- }
- else {
- /* Partition primitives by material */
- end = partition_indices_material(bvh, offset, offset + count - 1);
- }
-
- /* Build children */
- build_sub(bvh, bvh->nodes[node_index].children_offset, NULL,
- prim_bbc, offset, end - offset);
- build_sub(bvh, bvh->nodes[node_index].children_offset + 1, NULL,
- prim_bbc, end, offset + count - end);
-}
-
-static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
-{
- int i;
-
- if (totprim != bvh->totprim) {
- bvh->totprim = totprim;
- if (bvh->nodes) MEM_freeN(bvh->nodes);
- if (bvh->prim_indices) MEM_freeN(bvh->prim_indices);
- bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
- "bvh prim indices");
- for (i = 0; i < totprim; ++i)
- bvh->prim_indices[i] = i;
- bvh->totnode = 0;
- if (bvh->node_mem_count < 100) {
- bvh->node_mem_count = 100;
- bvh->nodes = MEM_callocN(sizeof(PBVHNode) *
- bvh->node_mem_count,
- "bvh initial nodes");
- }
- }
-
- bvh->totnode = 1;
- build_sub(bvh, 0, cb, prim_bbc, 0, totprim);
-}
-
-/* Do a full rebuild with on Mesh data structure */
-void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
-{
- BBC *prim_bbc = NULL;
- BB cb;
- int i, j;
-
- bvh->type = PBVH_FACES;
- bvh->faces = faces;
- bvh->verts = verts;
- bvh->vert_bitmap = BLI_BITMAP_NEW(totvert, "bvh->vert_bitmap");
- bvh->totvert = totvert;
- bvh->leaf_limit = LEAF_LIMIT;
- bvh->vdata = vdata;
-
- BB_reset(&cb);
-
- /* For each face, store the AABB and the AABB centroid */
- prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
-
- for (i = 0; i < totface; ++i) {
- MFace *f = faces + i;
- const int sides = f->v4 ? 4 : 3;
- BBC *bbc = prim_bbc + i;
-
- BB_reset((BB *)bbc);
-
- for (j = 0; j < sides; ++j)
- BB_expand((BB *)bbc, verts[(&f->v1)[j]].co);
-
- BBC_update_centroid(bbc);
-
- BB_expand(&cb, bbc->bcentroid);
- }
-
- if (totface)
- pbvh_build(bvh, &cb, prim_bbc, totface);
-
- MEM_freeN(prim_bbc);
- MEM_freeN(bvh->vert_bitmap);
-}
-
-/* Do a full rebuild with on Grids data structure */
-void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
- int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
-{
- BBC *prim_bbc = NULL;
- BB cb;
- int gridsize = key->grid_size;
- int i, j;
-
- bvh->type = PBVH_GRIDS;
- bvh->grids = grids;
- bvh->gridadj = gridadj;
- bvh->gridfaces = gridfaces;
- bvh->grid_flag_mats = flagmats;
- bvh->totgrid = totgrid;
- bvh->gridkey = *key;
- bvh->grid_hidden = grid_hidden;
- bvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
-
- BB_reset(&cb);
-
- /* For each grid, store the AABB and the AABB centroid */
- prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
-
- for (i = 0; i < totgrid; ++i) {
- CCGElem *grid = grids[i];
- BBC *bbc = prim_bbc + i;
-
- BB_reset((BB *)bbc);
-
- for (j = 0; j < gridsize * gridsize; ++j)
- BB_expand((BB *)bbc, CCG_elem_offset_co(key, grid, j));
-
- BBC_update_centroid(bbc);
-
- BB_expand(&cb, bbc->bcentroid);
- }
-
- if (totgrid)
- pbvh_build(bvh, &cb, prim_bbc, totgrid);
-
- MEM_freeN(prim_bbc);
-}
-
-PBVH *BLI_pbvh_new(void)
-{
- PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
-
- return bvh;
-}
-
-void BLI_pbvh_free(PBVH *bvh)
-{
- PBVHNode *node;
- int i;
-
- for (i = 0; i < bvh->totnode; ++i) {
- node = &bvh->nodes[i];
-
- if (node->flag & PBVH_Leaf) {
- if (node->draw_buffers)
- GPU_free_buffers(node->draw_buffers);
- if (node->vert_indices)
- MEM_freeN(node->vert_indices);
- if (node->face_vert_indices)
- MEM_freeN(node->face_vert_indices);
- }
- }
-
- if (bvh->deformed) {
- if (bvh->verts) {
- /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
-
- MEM_freeN(bvh->verts);
- if (bvh->faces)
- MEM_freeN(bvh->faces);
- }
- }
-
- if (bvh->nodes)
- MEM_freeN(bvh->nodes);
-
- if (bvh->prim_indices)
- MEM_freeN(bvh->prim_indices);
-
- MEM_freeN(bvh);
-}
-
-static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BLI_pbvh_SearchCallback scb, void *search_data)
-{
- iter->bvh = bvh;
- iter->scb = scb;
- iter->search_data = search_data;
-
- iter->stack = iter->stackfixed;
- iter->stackspace = STACK_FIXED_DEPTH;
-
- iter->stack[0].node = bvh->nodes;
- iter->stack[0].revisiting = 0;
- iter->stacksize = 1;
-}
-
-static void pbvh_iter_end(PBVHIter *iter)
-{
- if (iter->stackspace > STACK_FIXED_DEPTH)
- MEM_freeN(iter->stack);
-}
-
-static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, int revisiting)
-{
- if (iter->stacksize == iter->stackspace) {
- PBVHStack *newstack;
-
- iter->stackspace *= 2;
- newstack = MEM_callocN(sizeof(PBVHStack) * iter->stackspace, "PBVHStack");
- memcpy(newstack, iter->stack, sizeof(PBVHStack) * iter->stacksize);
-
- if (iter->stackspace > STACK_FIXED_DEPTH)
- MEM_freeN(iter->stack);
- iter->stack = newstack;
- }
-
- iter->stack[iter->stacksize].node = node;
- iter->stack[iter->stacksize].revisiting = revisiting;
- iter->stacksize++;
-}
-
-static PBVHNode *pbvh_iter_next(PBVHIter *iter)
-{
- PBVHNode *node;
- int revisiting;
-
- /* purpose here is to traverse tree, visiting child nodes before their
- * parents, this order is necessary for e.g. computing bounding boxes */
-
- while (iter->stacksize) {
- /* pop node */
- iter->stacksize--;
- node = iter->stack[iter->stacksize].node;
-
- /* on a mesh with no faces this can happen
- * can remove this check if we know meshes have at least 1 face */
- if (node == NULL)
- return NULL;
-
- revisiting = iter->stack[iter->stacksize].revisiting;
-
- /* revisiting node already checked */
- if (revisiting)
- return node;
-
- if (iter->scb && !iter->scb(node, iter->search_data))
- continue; /* don't traverse, outside of search zone */
-
- if (node->flag & PBVH_Leaf) {
- /* immediately hit leaf node */
- return node;
- }
- else {
- /* come back later when children are done */
- pbvh_stack_push(iter, node, 1);
-
- /* push two child nodes on the stack */
- pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
- pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
- }
- }
-
- return NULL;
-}
-
-static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
-{
- PBVHNode *node;
-
- while (iter->stacksize) {
- /* pop node */
- iter->stacksize--;
- node = iter->stack[iter->stacksize].node;
-
- /* on a mesh with no faces this can happen
- * can remove this check if we know meshes have at least 1 face */
- if (node == NULL) return NULL;
-
- if (iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
-
- if (node->flag & PBVH_Leaf) {
- /* immediately hit leaf node */
- return node;
- }
- else {
- pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
- pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
- }
- }
-
- return NULL;
-}
-
-void BLI_pbvh_search_gather(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- PBVHNode ***r_array, int *r_tot)
-{
- PBVHIter iter;
- PBVHNode **array = NULL, **newarray, *node;
- int tot = 0, space = 0;
-
- pbvh_iter_begin(&iter, bvh, scb, search_data);
-
- while ((node = pbvh_iter_next(&iter))) {
- if (node->flag & PBVH_Leaf) {
- if (tot == space) {
- /* resize array if needed */
- space = (tot == 0) ? 32 : space * 2;
- newarray = MEM_callocN(sizeof(PBVHNode) * space, "PBVHNodeSearch");
-
- if (array) {
- memcpy(newarray, array, sizeof(PBVHNode) * tot);
- MEM_freeN(array);
- }
-
- array = newarray;
- }
-
- array[tot] = node;
- tot++;
- }
- }
-
- pbvh_iter_end(&iter);
-
- if (tot == 0 && array) {
- MEM_freeN(array);
- array = NULL;
- }
-
- *r_array = array;
- *r_tot = tot;
-}
-
-void BLI_pbvh_search_callback(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitCallback hcb, void *hit_data)
-{
- PBVHIter iter;
- PBVHNode *node;
-
- pbvh_iter_begin(&iter, bvh, scb, search_data);
-
- while ((node = pbvh_iter_next(&iter)))
- if (node->flag & PBVH_Leaf)
- hcb(node, hit_data);
-
- pbvh_iter_end(&iter);
-}
-
-typedef struct node_tree {
- PBVHNode *data;
-
- struct node_tree *left;
- struct node_tree *right;
-} node_tree;
-
-static void node_tree_insert(node_tree *tree, node_tree *new_node)
-{
- if (new_node->data->tmin < tree->data->tmin) {
- if (tree->left) {
- node_tree_insert(tree->left, new_node);
- }
- else {
- tree->left = new_node;
- }
- }
- else {
- if (tree->right) {
- node_tree_insert(tree->right, new_node);
- }
- else {
- tree->right = new_node;
- }
- }
-}
-
-static void traverse_tree(node_tree *tree, BLI_pbvh_HitOccludedCallback hcb, void *hit_data, float *tmin)
-{
- if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
-
- hcb(tree->data, hit_data, tmin);
-
- if (tree->right) traverse_tree(tree->right, hcb, hit_data, tmin);
-}
-
-static void free_tree(node_tree *tree)
-{
- if (tree->left) {
- free_tree(tree->left);
- tree->left = 0;
- }
-
- if (tree->right) {
- free_tree(tree->right);
- tree->right = 0;
- }
-
- free(tree);
-}
-
-float BLI_pbvh_node_get_tmin(PBVHNode *node)
-{
- return node->tmin;
-}
-
-static void BLI_pbvh_search_callback_occluded(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
-{
- PBVHIter iter;
- PBVHNode *node;
- node_tree *tree = 0;
-
- pbvh_iter_begin(&iter, bvh, scb, search_data);
-
- while ((node = pbvh_iter_next_occluded(&iter))) {
- if (node->flag & PBVH_Leaf) {
- node_tree *new_node = malloc(sizeof(node_tree));
-
- new_node->data = node;
-
- new_node->left = NULL;
- new_node->right = NULL;
-
- if (tree) {
- node_tree_insert(tree, new_node);
- }
- else {
- tree = new_node;
- }
- }
- }
-
- pbvh_iter_end(&iter);
-
- if (tree) {
- float tmin = FLT_MAX;
- traverse_tree(tree, hcb, hit_data, &tmin);
- free_tree(tree);
- }
-}
-
-static int update_search_cb(PBVHNode *node, void *data_v)
-{
- int flag = GET_INT_FROM_POINTER(data_v);
-
- if (node->flag & PBVH_Leaf)
- return (node->flag & flag);
-
- return 1;
-}
-
-static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
- int totnode, float (*face_nors)[3])
-{
- float (*vnor)[3];
- int n;
-
- if (bvh->type != PBVH_FACES)
- return;
-
- /* could be per node to save some memory, but also means
- * we have to store for each vertex which node it is in */
- vnor = MEM_callocN(sizeof(float) * 3 * bvh->totvert, "bvh temp vnors");
-
- /* subtle assumptions:
- * - We know that for all edited vertices, the nodes with faces
- * adjacent to these vertices have been marked with PBVH_UpdateNormals.
- * This is true because if the vertex is inside the brush radius, the
- * bounding box of it's adjacent faces will be as well.
- * - However this is only true for the vertices that have actually been
- * edited, not for all vertices in the nodes marked for update, so we
- * can only update vertices marked with ME_VERT_PBVH_UPDATE.
- */
-
- #pragma omp parallel for private(n) schedule(static)
- for (n = 0; n < totnode; n++) {
- PBVHNode *node = nodes[n];
-
- if ((node->flag & PBVH_UpdateNormals)) {
- int i, j, totface, *faces;
-
- faces = node->prim_indices;
- totface = node->totprim;
-
- for (i = 0; i < totface; ++i) {
- MFace *f = bvh->faces + faces[i];
- float fn[3];
- unsigned int *fv = &f->v1;
- int sides = (f->v4) ? 4 : 3;
-
- if (f->v4)
- normal_quad_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
- bvh->verts[f->v3].co, bvh->verts[f->v4].co);
- else
- normal_tri_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co,
- bvh->verts[f->v3].co);
-
- for (j = 0; j < sides; ++j) {
- int v = fv[j];
-
- if (bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
- /* this seems like it could be very slow but profile
- * does not show this, so just leave it for now? */
- #pragma omp atomic
- vnor[v][0] += fn[0];
- #pragma omp atomic
- vnor[v][1] += fn[1];
- #pragma omp atomic
- vnor[v][2] += fn[2];
- }
- }
-
- if (face_nors)
- copy_v3_v3(face_nors[faces[i]], fn);
- }
- }
- }
-
- #pragma omp parallel for private(n) schedule(static)
- for (n = 0; n < totnode; n++) {
- PBVHNode *node = nodes[n];
-
- if (node->flag & PBVH_UpdateNormals) {
- int i, *verts, totvert;
-
- verts = node->vert_indices;
- totvert = node->uniq_verts;
-
- for (i = 0; i < totvert; ++i) {
- const int v = verts[i];
- MVert *mvert = &bvh->verts[v];
-
- if (mvert->flag & ME_VERT_PBVH_UPDATE) {
- float no[3];
-
- copy_v3_v3(no, vnor[v]);
- normalize_v3(no);
- normal_float_to_short_v3(mvert->no, no);
-
- mvert->flag &= ~ME_VERT_PBVH_UPDATE;
- }
- }
-
- node->flag &= ~PBVH_UpdateNormals;
- }
- }
-
- MEM_freeN(vnor);
-}
-
-static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
- int totnode, int flag)
-{
- int n;
-
- /* update BB, redraw flag */
- #pragma omp parallel for private(n) schedule(static)
- for (n = 0; n < totnode; n++) {
- PBVHNode *node = nodes[n];
-
- if ((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB))
- /* don't clear flag yet, leave it for flushing later */
- update_node_vb(bvh, node);
-
- if ((flag & PBVH_UpdateOriginalBB) && (node->flag & PBVH_UpdateOriginalBB))
- node->orig_vb = node->vb;
-
- if ((flag & PBVH_UpdateRedraw) && (node->flag & PBVH_UpdateRedraw))
- node->flag &= ~PBVH_UpdateRedraw;
- }
-}
-
-static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
-{
- PBVHNode *node;
- int n;
-
- /* can't be done in parallel with OpenGL */
- for (n = 0; n < totnode; n++) {
- node = nodes[n];
-
- if (node->flag & PBVH_RebuildDrawBuffers) {
- GPU_free_buffers(node->draw_buffers);
- switch (bvh->type) {
- case PBVH_GRIDS:
- node->draw_buffers =
- GPU_build_grid_buffers(node->prim_indices,
- node->totprim,
- bvh->grid_hidden,
- bvh->gridkey.grid_size);
- break;
- case PBVH_FACES:
- node->draw_buffers =
- GPU_build_mesh_buffers(node->face_vert_indices,
- bvh->faces, bvh->verts,
- node->prim_indices,
- node->totprim);
- break;
- }
-
- node->flag &= ~PBVH_RebuildDrawBuffers;
- }
-
- if (node->flag & PBVH_UpdateDrawBuffers) {
- switch (bvh->type) {
- case PBVH_GRIDS:
- GPU_update_grid_buffers(node->draw_buffers,
- bvh->grids,
- bvh->grid_flag_mats,
- node->prim_indices,
- node->totprim,
- &bvh->gridkey,
- bvh->show_diffuse_color);
- break;
- case PBVH_FACES:
- GPU_update_mesh_buffers(node->draw_buffers,
- bvh->verts,
- node->vert_indices,
- node->uniq_verts +
- node->face_verts,
- CustomData_get_layer(bvh->vdata,
- CD_PAINT_MASK),
- node->face_vert_indices,
- bvh->show_diffuse_color);
- break;
- }
-
- node->flag &= ~PBVH_UpdateDrawBuffers;
- }
- }
-}
-
-static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
-{
- int update = 0;
-
- /* difficult to multithread well, we just do single threaded recursive */
- if (node->flag & PBVH_Leaf) {
- if (flag & PBVH_UpdateBB) {
- update |= (node->flag & PBVH_UpdateBB);
- node->flag &= ~PBVH_UpdateBB;
- }
-
- if (flag & PBVH_UpdateOriginalBB) {
- update |= (node->flag & PBVH_UpdateOriginalBB);
- node->flag &= ~PBVH_UpdateOriginalBB;
- }
-
- return update;
- }
- else {
- update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset, flag);
- update |= pbvh_flush_bb(bvh, bvh->nodes + node->children_offset + 1, flag);
-
- if (update & PBVH_UpdateBB)
- update_node_vb(bvh, node);
- if (update & PBVH_UpdateOriginalBB)
- node->orig_vb = node->vb;
- }
-
- return update;
-}
-
-void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
-{
- PBVHNode **nodes;
- int totnode;
-
- if (!bvh->nodes)
- return;
-
- BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
- &nodes, &totnode);
-
- if (flag & PBVH_UpdateNormals)
- pbvh_update_normals(bvh, nodes, totnode, face_nors);
-
- if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw))
- pbvh_update_BB_redraw(bvh, nodes, totnode, flag);
-
- if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB))
- pbvh_flush_bb(bvh, bvh->nodes, flag);
-
- if (nodes) MEM_freeN(nodes);
-}
-
-void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
-{
- PBVHIter iter;
- PBVHNode *node;
- BB bb;
-
- BB_reset(&bb);
-
- pbvh_iter_begin(&iter, bvh, NULL, NULL);
-
- while ((node = pbvh_iter_next(&iter)))
- if (node->flag & PBVH_UpdateRedraw)
- BB_expand_with_bb(&bb, &node->vb);
-
- pbvh_iter_end(&iter);
-
- copy_v3_v3(bb_min, bb.bmin);
- copy_v3_v3(bb_max, bb.bmax);
-}
-
-void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
-{
- PBVHIter iter;
- PBVHNode *node;
- GHashIterator *hiter;
- GHash *map;
- void *face, **faces;
- unsigned i;
- int tot;
-
- map = BLI_ghash_ptr_new("pbvh_get_grid_updates gh");
-
- pbvh_iter_begin(&iter, bvh, NULL, NULL);
-
- while ((node = pbvh_iter_next(&iter))) {
- if (node->flag & PBVH_UpdateNormals) {
- for (i = 0; i < node->totprim; ++i) {
- face = bvh->gridfaces[node->prim_indices[i]];
- if (!BLI_ghash_lookup(map, face))
- BLI_ghash_insert(map, face, face);
- }
-
- if (clear)
- node->flag &= ~PBVH_UpdateNormals;
- }
- }
-
- pbvh_iter_end(&iter);
-
- tot = BLI_ghash_size(map);
- if (tot == 0) {
- *totface = 0;
- *gridfaces = NULL;
- BLI_ghash_free(map, NULL, NULL);
- return;
- }
-
- faces = MEM_callocN(sizeof(void *) * tot, "PBVH Grid Faces");
-
- for (hiter = BLI_ghashIterator_new(map), i = 0;
- !BLI_ghashIterator_isDone(hiter);
- BLI_ghashIterator_step(hiter), ++i)
- {
- faces[i] = BLI_ghashIterator_getKey(hiter);
- }
-
- BLI_ghashIterator_free(hiter);
-
- BLI_ghash_free(map, NULL, NULL);
-
- *totface = tot;
- *gridfaces = faces;
-}
-
-/***************************** PBVH Access ***********************************/
-
-PBVHType BLI_pbvh_type(const PBVH *bvh)
-{
- return bvh->type;
-}
-
-BLI_bitmap *BLI_pbvh_grid_hidden(const PBVH *bvh)
-{
- BLI_assert(bvh->type == PBVH_GRIDS);
- return bvh->grid_hidden;
-}
-
-void BLI_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
-{
- BLI_assert(bvh->type == PBVH_GRIDS);
- *key = bvh->gridkey;
-}
-
-/***************************** Node Access ***********************************/
-
-void BLI_pbvh_node_mark_update(PBVHNode *node)
-{
- node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
-}
-
-void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node)
-{
- node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
-}
-
-void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
-{
- BLI_assert(node->flag & PBVH_Leaf);
-
- if (fully_hidden)
- node->flag |= PBVH_FullyHidden;
- else
- node->flag &= ~PBVH_FullyHidden;
-}
-
-void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
-{
- if (vert_indices) *vert_indices = node->vert_indices;
- if (verts) *verts = bvh->verts;
-}
-
-void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
-{
- int tot;
-
- switch (bvh->type) {
- case PBVH_GRIDS:
- tot = node->totprim * bvh->gridkey.grid_area;
- if (totvert) *totvert = tot;
- if (uniquevert) *uniquevert = tot;
- break;
- case PBVH_FACES:
- if (totvert) *totvert = node->uniq_verts + node->face_verts;
- if (uniquevert) *uniquevert = node->uniq_verts;
- break;
- }
-}
-
-void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj)
-{
- switch (bvh->type) {
- case PBVH_GRIDS:
- if (grid_indices) *grid_indices = node->prim_indices;
- if (totgrid) *totgrid = node->totprim;
- if (maxgrid) *maxgrid = bvh->totgrid;
- if (gridsize) *gridsize = bvh->gridkey.grid_size;
- if (griddata) *griddata = bvh->grids;
- if (gridadj) *gridadj = bvh->gridadj;
- break;
- case PBVH_FACES:
- if (grid_indices) *grid_indices = NULL;
- if (totgrid) *totgrid = 0;
- if (maxgrid) *maxgrid = 0;
- if (gridsize) *gridsize = 0;
- if (griddata) *griddata = NULL;
- if (gridadj) *gridadj = NULL;
- break;
- }
-}
-
-void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
-{
- copy_v3_v3(bb_min, node->vb.bmin);
- copy_v3_v3(bb_max, node->vb.bmax);
-}
-
-void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
-{
- copy_v3_v3(bb_min, node->orig_vb.bmin);
- copy_v3_v3(bb_max, node->orig_vb.bmax);
-}
-
-void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
-{
- if (node->proxy_count > 0) {
- if (proxies) *proxies = node->proxies;
- if (proxy_count) *proxy_count = node->proxy_count;
- }
- else {
- if (proxies) *proxies = 0;
- if (proxy_count) *proxy_count = 0;
- }
-}
-
-/********************************* Raycast ***********************************/
-
-typedef struct {
- IsectRayAABBData ray;
- int original;
-} RaycastData;
-
-static int ray_aabb_intersect(PBVHNode *node, void *data_v)
-{
- RaycastData *rcd = data_v;
- float bb_min[3], bb_max[3];
-
- if (rcd->original)
- BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
- else
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
-
- return isect_ray_aabb(&rcd->ray, bb_min, bb_max, &node->tmin);
-}
-
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
- const float ray_start[3], const float ray_normal[3],
- int original)
-{
- RaycastData rcd;
-
- isect_ray_aabb_initialize(&rcd.ray, ray_start, ray_normal);
- rcd.original = original;
-
- BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
-}
-
-static int ray_face_intersection(const float ray_start[3],
- const float ray_normal[3],
- const float *t0, const float *t1,
- const float *t2, const float *t3,
- float *fdist)
-{
- float dist;
-
- if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
- (t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
- {
- *fdist = dist;
- return 1;
- }
- else {
- return 0;
- }
-}
-
-static int pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
- float (*origco)[3],
- const float ray_start[3],
- const float ray_normal[3], float *dist)
-{
- const MVert *vert = bvh->verts;
- const int *faces = node->prim_indices;
- int i, hit = 0, totface = node->totprim;
-
- for (i = 0; i < totface; ++i) {
- const MFace *f = bvh->faces + faces[i];
- const int *face_verts = node->face_vert_indices[i];
-
- if (paint_is_face_hidden(f, vert))
- continue;
-
- if (origco) {
- /* intersect with backuped original coordinates */
- hit |= ray_face_intersection(ray_start, ray_normal,
- origco[face_verts[0]],
- origco[face_verts[1]],
- origco[face_verts[2]],
- f->v4 ? origco[face_verts[3]] : NULL,
- dist);
- }
- else {
- /* intersect with current coordinates */
- hit |= ray_face_intersection(ray_start, ray_normal,
- vert[f->v1].co,
- vert[f->v2].co,
- vert[f->v3].co,
- f->v4 ? vert[f->v4].co : NULL,
- dist);
- }
- }
-
- return hit;
-}
-
-static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
- float (*origco)[3],
- const float ray_start[3],
- const float ray_normal[3], float *dist)
-{
- int totgrid = node->totprim;
- int gridsize = bvh->gridkey.grid_size;
- int i, x, y, hit = 0;
-
- for (i = 0; i < totgrid; ++i) {
- CCGElem *grid = bvh->grids[node->prim_indices[i]];
- BLI_bitmap gh;
-
- if (!grid)
- continue;
-
- gh = bvh->grid_hidden[node->prim_indices[i]];
-
- for (y = 0; y < gridsize - 1; ++y) {
- for (x = 0; x < gridsize - 1; ++x) {
- /* check if grid face is hidden */
- if (gh) {
- if (paint_is_grid_face_hidden(gh, gridsize, x, y))
- continue;
- }
-
- if (origco) {
- hit |= ray_face_intersection(ray_start, ray_normal,
- origco[y * gridsize + x],
- origco[y * gridsize + x + 1],
- origco[(y + 1) * gridsize + x + 1],
- origco[(y + 1) * gridsize + x],
- dist);
- }
- else {
- hit |= ray_face_intersection(ray_start, ray_normal,
- CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
- CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
- CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
- CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
- dist);
- }
- }
- }
-
- if (origco)
- origco += gridsize * gridsize;
- }
-
- return hit;
-}
-
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
- const float ray_start[3], const float ray_normal[3],
- float *dist)
-{
- int hit = 0;
-
- if (node->flag & PBVH_FullyHidden)
- return 0;
-
- switch (bvh->type) {
- case PBVH_FACES:
- hit |= pbvh_faces_node_raycast(bvh, node, origco,
- ray_start, ray_normal, dist);
- break;
- case PBVH_GRIDS:
- hit |= pbvh_grids_node_raycast(bvh, node, origco,
- ray_start, ray_normal, dist);
- break;
- }
-
- return hit;
-}
-
-//#include <GL/glew.h>
-
-void BLI_pbvh_node_draw(PBVHNode *node, void *setMaterial)
-{
-#if 0
- /* XXX: Just some quick code to show leaf nodes in different colors */
- float col[3]; int i;
-
- if (0) { //is_partial) {
- col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
- }
- else {
- srand((long long)node);
- for (i = 0; i < 3; ++i)
- col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
- }
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
-
- glColor3f(1, 0, 0);
-#endif
-
- if (!(node->flag & PBVH_FullyHidden))
- GPU_draw_buffers(node->draw_buffers, setMaterial);
-}
-
-typedef enum {
- ISECT_INSIDE,
- ISECT_OUTSIDE,
- ISECT_INTERSECT
-} PlaneAABBIsect;
-
-/* Adapted from:
- * http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
- * Returns true if the AABB is at least partially within the frustum
- * (ok, not a real frustum), false otherwise.
- */
-static PlaneAABBIsect test_planes_aabb(const float bb_min[3],
- const float bb_max[3],
- const float (*planes)[4])
-{
- float vmin[3], vmax[3];
- PlaneAABBIsect ret = ISECT_INSIDE;
- int i, axis;
-
- for (i = 0; i < 4; ++i) {
- for (axis = 0; axis < 3; ++axis) {
- if (planes[i][axis] > 0) {
- vmin[axis] = bb_min[axis];
- vmax[axis] = bb_max[axis];
- }
- else {
- vmin[axis] = bb_max[axis];
- vmax[axis] = bb_min[axis];
- }
- }
-
- if (dot_v3v3(planes[i], vmin) + planes[i][3] > 0)
- return ISECT_OUTSIDE;
- else if (dot_v3v3(planes[i], vmax) + planes[i][3] >= 0)
- ret = ISECT_INTERSECT;
- }
-
- return ret;
-}
-
-int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
-{
- float bb_min[3], bb_max[3];
-
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
- return test_planes_aabb(bb_min, bb_max, data) != ISECT_OUTSIDE;
-}
-
-int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
-{
- float bb_min[3], bb_max[3];
-
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
- return test_planes_aabb(bb_min, bb_max, data) != ISECT_INSIDE;
-}
-
-static void pbvh_node_check_diffuse_changed(PBVH *bvh, PBVHNode *node)
-{
- if (!node->draw_buffers)
- return;
-
- if (GPU_buffers_diffuse_changed(node->draw_buffers, bvh->show_diffuse_color))
- node->flag |= PBVH_UpdateDrawBuffers;
-}
-
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- DMSetMaterial setMaterial)
-{
- PBVHNode **nodes;
- int a, totnode;
-
- for (a = 0; a < bvh->totnode; a++)
- pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
-
- BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
- &nodes, &totnode);
-
- pbvh_update_normals(bvh, nodes, totnode, face_nors);
- pbvh_update_draw_buffers(bvh, nodes, totnode);
-
- if (nodes) MEM_freeN(nodes);
-
- if (planes) {
- BLI_pbvh_search_callback(bvh, BLI_pbvh_node_planes_contain_AABB,
- planes, BLI_pbvh_node_draw, setMaterial);
- }
- else {
- BLI_pbvh_search_callback(bvh, NULL, NULL, BLI_pbvh_node_draw, setMaterial);
- }
-}
-
-void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
- DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
-{
- int a;
-
- bvh->grids = grids;
- bvh->gridadj = gridadj;
- bvh->gridfaces = gridfaces;
-
- if (flagmats != bvh->grid_flag_mats || bvh->grid_hidden != grid_hidden) {
- bvh->grid_flag_mats = flagmats;
- bvh->grid_hidden = grid_hidden;
-
- for (a = 0; a < bvh->totnode; ++a)
- BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
- }
-}
-
-float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
-{
- int a;
- float (*vertCos)[3] = NULL;
-
- if (pbvh->verts) {
- float *co;
- MVert *mvert = pbvh->verts;
-
- vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BLI_pbvh_get_vertCoords");
- co = (float *)vertCos;
-
- for (a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
- copy_v3_v3(co, mvert->co);
- }
- }
-
- return vertCos;
-}
-
-void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
-{
- int a;
-
- if (!pbvh->deformed) {
- if (pbvh->verts) {
- /* if pbvh is not already deformed, verts/faces points to the */
- /* original data and applying new coords to this arrays would lead to */
- /* unneeded deformation -- duplicate verts/faces to avoid this */
-
- pbvh->verts = MEM_dupallocN(pbvh->verts);
- pbvh->faces = MEM_dupallocN(pbvh->faces);
-
- pbvh->deformed = 1;
- }
- }
-
- if (pbvh->verts) {
- MVert *mvert = pbvh->verts;
- /* copy new verts coords */
- for (a = 0; a < pbvh->totvert; ++a, ++mvert) {
- copy_v3_v3(mvert->co, vertCos[a]);
- mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
-
- /* coordinates are new -- normals should also be updated */
- BKE_mesh_calc_normals_tessface(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
-
- for (a = 0; a < pbvh->totnode; ++a)
- BLI_pbvh_node_mark_update(&pbvh->nodes[a]);
-
- BLI_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
- BLI_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
-
- }
-}
-
-int BLI_pbvh_isDeformed(PBVH *pbvh)
-{
- return pbvh->deformed;
-}
-/* Proxies */
-
-PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
-{
- int index, totverts;
-
- #pragma omp critical
- {
-
- index = node->proxy_count;
-
- node->proxy_count++;
-
- if (node->proxies)
- node->proxies = MEM_reallocN(node->proxies, node->proxy_count * sizeof(PBVHProxyNode));
- else
- node->proxies = MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
-
- BLI_pbvh_node_num_verts(bvh, node, &totverts, NULL);
- node->proxies[index].co = MEM_callocN(sizeof(float[3]) * totverts, "PBVHNodeProxy.co");
- }
-
- return node->proxies + index;
-}
-
-void BLI_pbvh_node_free_proxies(PBVHNode *node)
-{
- #pragma omp critical
- {
- int p;
-
- for (p = 0; p < node->proxy_count; p++) {
- MEM_freeN(node->proxies[p].co);
- node->proxies[p].co = 0;
- }
-
- MEM_freeN(node->proxies);
- node->proxies = 0;
-
- node->proxy_count = 0;
- }
-}
-
-void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
-{
- PBVHNode **array = NULL, **newarray, *node;
- int tot = 0, space = 0;
- int n;
-
- for (n = 0; n < pbvh->totnode; n++) {
- node = pbvh->nodes + n;
-
- if (node->proxy_count > 0) {
- if (tot == space) {
- /* resize array if needed */
- space = (tot == 0) ? 32 : space * 2;
- newarray = MEM_callocN(sizeof(PBVHNode) * space, "BLI_pbvh_gather_proxies");
-
- if (array) {
- memcpy(newarray, array, sizeof(PBVHNode) * tot);
- MEM_freeN(array);
- }
-
- array = newarray;
- }
-
- array[tot] = node;
- tot++;
- }
- }
-
- if (tot == 0 && array) {
- MEM_freeN(array);
- array = NULL;
- }
-
- *r_array = array;
- *r_tot = tot;
-}
-
-void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
- PBVHVertexIter *vi, int mode)
-{
- struct CCGElem **grids;
- struct MVert *verts;
- int *grid_indices, *vert_indices;
- int totgrid, gridsize, uniq_verts, totvert;
-
- vi->grid = 0;
- vi->no = 0;
- vi->fno = 0;
- vi->mvert = 0;
-
- BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
- BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
- BLI_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
- vi->key = &bvh->gridkey;
-
- vi->grids = grids;
- vi->grid_indices = grid_indices;
- vi->totgrid = (grids) ? totgrid : 1;
- vi->gridsize = gridsize;
-
- if (mode == PBVH_ITER_ALL)
- vi->totvert = totvert;
- else
- vi->totvert = uniq_verts;
- vi->vert_indices = vert_indices;
- vi->mverts = verts;
-
- vi->gh = NULL;
- if (vi->grids && mode == PBVH_ITER_UNIQUE)
- vi->grid_hidden = bvh->grid_hidden;
-
- vi->mask = NULL;
- if (!vi->grids)
- vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
-}
-
-void pbvh_show_diffuse_color_set(PBVH *bvh, int show_diffuse_color)
-{
- bvh->show_diffuse_color = show_diffuse_color;
-}
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index ee073d5..4bd7715 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -109,9 +109,9 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c
return 1; /* co-linear */
}
else {
- const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0);
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
}
static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
@@ -121,9 +121,9 @@ static int isect_segments_fl(const float v1[2], const float v2[2], const float v
return 1; /* co-linear */
}
else {
- const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0);
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
}
@@ -317,6 +317,30 @@ void BLI_rctf_resize(rctf *rect, float x, float y)
rect->ymax = rect->ymin + y;
}
+void BLI_rcti_scale(rcti *rect, const float scale)
+{
+ const int cent_x = BLI_rcti_cent_x(rect);
+ const int cent_y = BLI_rcti_cent_y(rect);
+ const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
+ const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
+}
+
+void BLI_rctf_scale(rctf *rect, const float scale)
+{
+ const float cent_x = BLI_rctf_cent_x(rect);
+ const float cent_y = BLI_rctf_cent_y(rect);
+ const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
+ const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
+}
+
void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
{
const float ifac = 1.0f - fac;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index defe500..771295b 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -459,7 +459,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
/* new edge */
ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
- /* printf("fill: vertex near edge %x\n",eve); */
+ /* printf("fill: vertex near edge %x\n", eve); */
ed1->f = 0;
ed1->poly_nr = eed->poly_nr;
eed->v1 = eve;
@@ -630,11 +630,16 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
/* (temporal) security: never much more faces than vertices */
totface = 0;
- maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
+ if (flag & BLI_SCANFILL_CALC_HOLES) {
+ maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
+ }
+ else {
+ maxface = verts - 2; /* when we don't calc any holes, we assume face is a non overlapping loop */
+ }
sc = sf_ctx->_scdata;
for (a = 0; a < verts; a++) {
- /* printf("VERTEX %d %x\n",a,sc->v1); */
+ /* printf("VERTEX %d %x\n", a, sc->v1); */
ed1 = sc->edge_first;
while (ed1) { /* set connectflags */
nexted = ed1->next;
@@ -654,7 +659,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
/* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */
/* if (callLocalInterruptCallBack()) break; */
- if (totface > maxface) {
+ if (totface >= maxface) {
/* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */
a = verts;
break;
@@ -675,30 +680,31 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
v3 = ed2->v2;
/* this happens with a serial of overlapping edges */
if (v1 == v2 || v2 == v3) break;
- /* printf("test verts %x %x %x\n",v1,v2,v3); */
+ /* printf("test verts %x %x %x\n", v1, v2, v3); */
miny = min_ff(v1->xy[1], v3->xy[1]);
- /* miny = min_ff(v1->xy[1],v3->xy[1]); */
+ /* miny = min_ff(v1->xy[1], v3->xy[1]); */
sc1 = sc + 1;
test = 0;
for (b = a + 1; b < verts; b++) {
if (sc1->vert->f == 0) {
if (sc1->vert->xy[1] <= miny) break;
-
- if (testedgeside(v1->xy, v2->xy, sc1->vert->xy))
- if (testedgeside(v2->xy, v3->xy, sc1->vert->xy))
+ if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) {
+ if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) {
if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) {
/* point in triangle */
-
+
test = 1;
break;
}
+ }
+ }
}
sc1++;
}
if (test) {
/* make new edge, and start over */
- /* printf("add new edge %x %x and start again\n",v2,sc1->vert); */
+ /* printf("add new edge %x %x and start again\n", v2, sc1->vert); */
ed3 = BLI_scanfill_edge_add(sf_ctx, v2, sc1->vert);
BLI_remlink(&sf_ctx->filledgebase, ed3);
@@ -710,7 +716,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
}
else {
/* new triangle */
- /* printf("add face %x %x %x\n",v1,v2,v3); */
+ /* printf("add face %x %x %x\n", v1, v2, v3); */
addfillface(sf_ctx, v1, v2, v3);
totface++;
BLI_remlink((ListBase *)&(sc->edge_first), ed1);
@@ -734,7 +740,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
ed3->v1->h++;
ed3->v2->h++;
- /* printf("add new edge %x %x\n",v1,v3); */
+ /* printf("add new edge %x %x\n", v1, v3); */
sc1 = addedgetoscanlist(sf_ctx, ed3, verts);
if (sc1) { /* ed3 already exists: remove if a boundary */
@@ -773,12 +779,15 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
ed1 = nexted;
}
}
+
sc++;
}
MEM_freeN(sf_ctx->_scdata);
sf_ctx->_scdata = NULL;
+ BLI_assert(totface <= maxface);
+
return totface;
}
@@ -910,50 +919,68 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
/* STEP 1: COUNT POLYS */
- eve = sf_ctx->fillvertbase.first;
- while (eve) {
- eve->xy[0] = eve->co[co_x];
- eve->xy[1] = eve->co[co_y];
+ if (flag & BLI_SCANFILL_CALC_HOLES) {
+ eve = sf_ctx->fillvertbase.first;
+ while (eve) {
+ eve->xy[0] = eve->co[co_x];
+ eve->xy[1] = eve->co[co_y];
+
+ /* get first vertex with no poly number */
+ if (eve->poly_nr == 0) {
+ poly++;
+ /* now a sort of select connected */
+ ok = 1;
+ eve->poly_nr = poly;
- /* get first vertex with no poly number */
- if (eve->poly_nr == 0) {
- poly++;
- /* now a sort of select connected */
- ok = 1;
- eve->poly_nr = poly;
-
- while (ok) {
-
- ok = 0;
- toggle++;
- if (toggle & 1) eed = sf_ctx->filledgebase.first;
- else eed = sf_ctx->filledgebase.last;
-
- while (eed) {
- if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) {
- eed->v1->poly_nr = poly;
- eed->poly_nr = poly;
- ok = 1;
- }
- else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) {
- eed->v2->poly_nr = poly;
- eed->poly_nr = poly;
- ok = 1;
- }
- else if (eed->poly_nr == 0) {
- if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
+ while (ok) {
+
+ ok = 0;
+ toggle++;
+ if (toggle & 1) eed = sf_ctx->filledgebase.first;
+ else eed = sf_ctx->filledgebase.last;
+
+ while (eed) {
+ if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) {
+ eed->v1->poly_nr = poly;
eed->poly_nr = poly;
ok = 1;
}
+ else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) {
+ eed->v2->poly_nr = poly;
+ eed->poly_nr = poly;
+ ok = 1;
+ }
+ else if (eed->poly_nr == 0) {
+ if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
+ eed->poly_nr = poly;
+ ok = 1;
+ }
+ }
+ if (toggle & 1) eed = eed->next;
+ else eed = eed->prev;
}
- if (toggle & 1) eed = eed->next;
- else eed = eed->prev;
}
}
+ eve = eve->next;
+ }
+ /* printf("amount of poly's: %d\n", poly); */
+ }
+ else {
+ poly = 1;
+
+ eve = sf_ctx->fillvertbase.first;
+ while (eve) {
+ eve->xy[0] = eve->co[co_x];
+ eve->xy[1] = eve->co[co_y];
+ eve->poly_nr = poly;
+ eve = eve->next;
+ }
+ eed = sf_ctx->filledgebase.first;
+ while (eed) {
+ eed->poly_nr = poly;
+ eed = eed->next;
}
- eve = eve->next;
}
- /* printf("amount of poly's: %d\n",poly); */
/* STEP 2: remove loose edges and strings of edges */
eed = sf_ctx->filledgebase.first;
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index f23f75f..28fdf7b 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -412,7 +412,7 @@ int BLI_natstrcmp(const char *s1, const char *s2)
void BLI_timestr(double _time, char *str)
{
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
- int hr = ( (int) _time) / (60*60);
+ int hr = ( (int) _time) / (60 * 60);
int min = (((int) _time) / 60 ) % 60;
int sec = ( (int) (_time)) % 60;
int hun = ( (int) (_time * 100.0)) % 100;
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 68d9d74..65fb490 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -41,7 +41,7 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BKE_global.h"
+#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */
#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
#include "BLI_winstuff.h"
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 16a4d8d..2ee5dec 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -240,13 +240,32 @@ struct ID *BLO_library_append_named_part_ex(const struct bContext *C, struct Mai
void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag);
+void BLO_library_append_all(struct Main *mainl, BlendHandle *bh);
+
void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, struct ReportList *reports);
-
+
/* internal function but we need to expose it */
void blo_lib_link_screen_restore(struct Main *newmain, struct bScreen *curscreen, struct Scene *curscene);
+/**
+ * BLO_expand_main() loops over all ID data in Main to mark relations.
+ * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding.
+ *
+ * \param expand_doit_func() gets called for each ID block it finds
+ */
+void BLO_main_expander(void (*expand_doit_func)(void *, struct Main *, void *));
+
+/**
+ * BLO_expand_main() loops over all ID data in Main to mark relations.
+ * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding.
+ *
+ * \param fdhandle usually filedata, or own handle
+ * \param mainvar the Main database to expand
+ */
+void BLO_expand_main(void *fdhandle, struct Main *mainvar);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenloader/BLO_soundfile.h b/source/blender/blenloader/BLO_soundfile.h
deleted file mode 100644
index d2f8713..0000000
--- a/source/blender/blenloader/BLO_soundfile.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef __BLO_SOUNDFILE_H__
-#define __BLO_SOUNDFILE_H__
-
-/** \file BLO_soundfile.h
- * \ingroup blenloader
- */
-
-#include "DNA_sound_types.h"
-#include "DNA_packedFile_types.h"
-
-struct bSound;
-struct PackedFile;
-
-#endif
-
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index 3c5812f..5b92919 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -52,7 +52,6 @@ set(SRC
BLO_blend_defs.h
BLO_readfile.h
BLO_runtime.h
- BLO_soundfile.h
BLO_sys_types.h
BLO_undofile.h
BLO_writefile.h
diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript
index 49e8869..8950c4f 100644
--- a/source/blender/blenloader/SConscript
+++ b/source/blender/blenloader/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index e9caa33..b2d37e3 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -311,6 +311,9 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
/* makes lookup of existing video clips in old main */
blo_make_movieclip_pointer_map(fd, oldmain);
+ /* makes lookup of existing video clips in old main */
+ blo_make_packed_pointer_map(fd, oldmain);
+
bfd = blo_read_file_internal(fd, filename);
/* ensures relinked images are not freed */
@@ -319,6 +322,9 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
/* ensures relinked movie clips are not freed */
blo_end_movieclip_pointer_map(fd, oldmain);
+ /* ensures relinked packed data is not freed */
+ blo_end_packed_pointer_map(fd, oldmain);
+
/* move libraries from old main to new main */
if (bfd && mainlist.first != mainlist.last) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ddb42e1..44499f1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -543,7 +543,9 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
BLI_strncpy(name1, filepath, sizeof(name1));
cleanup_path(relabase, name1);
-// printf("blo_find_main: original in %s\n", name);
+
+// printf("blo_find_main: relabase %s\n", relabase);
+// printf("blo_find_main: original in %s\n", filepath);
// printf("blo_find_main: converted to %s\n", name1);
for (m = mainlist->first; m; m = m->next) {
@@ -1020,6 +1022,46 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports)
}
}
+static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, unsigned int size)
+{
+ int err;
+
+ filedata->strm.next_out = (Bytef *) buffer;
+ filedata->strm.avail_out = size;
+
+ // Inflate another chunk.
+ err = inflate (&filedata->strm, Z_SYNC_FLUSH);
+
+ if (err == Z_STREAM_END) {
+ return 0;
+ }
+ else if (err != Z_OK) {
+ printf("fd_read_gzip_from_memory: zlib error\n");
+ return 0;
+ }
+
+ filedata->seek += size;
+
+ return (size);
+}
+
+static int fd_read_gzip_from_memory_init(FileData *fd)
+{
+
+ fd->strm.next_in = (Bytef *) fd->buffer;
+ fd->strm.avail_in = fd->buffersize;
+ fd->strm.total_out = 0;
+ fd->strm.zalloc = Z_NULL;
+ fd->strm.zfree = Z_NULL;
+
+ if (inflateInit2(&fd->strm, (16+MAX_WBITS)) != Z_OK)
+ return 0;
+
+ fd->read = fd_read_gzip_from_memory;
+
+ return 1;
+}
+
FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
{
if (!mem || memsize<SIZEOFBLENDERHEADER) {
@@ -1028,11 +1070,23 @@ FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
}
else {
FileData *fd = filedata_new();
+ char *cp = mem;
+
fd->buffer = mem;
fd->buffersize = memsize;
- fd->read = fd_read_from_memory;
- fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+ /* test if gzip */
+ if (cp[0] == 0x1f && cp[1] == 0x8b) {
+ if (0 == fd_read_gzip_from_memory_init(fd)) {
+ blo_freefiledata(fd);
+ return NULL;
+ }
+ }
+ else
+ fd->read = fd_read_from_memory;
+
+ fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+
return blo_decode_and_check(fd, reports);
}
}
@@ -1066,6 +1120,12 @@ void blo_freefiledata(FileData *fd)
gzclose(fd->gzfiledes);
}
+ if (fd->strm.next_in) {
+ if (inflateEnd (&fd->strm) != Z_OK) {
+ printf("close gzip stream error\n");
+ }
+ }
+
if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
MEM_freeN(fd->buffer);
fd->buffer = NULL;
@@ -1089,6 +1149,8 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->imamap);
if (fd->movieclipmap)
oldnewmap_free(fd->movieclipmap);
+ if (fd->packedmap)
+ oldnewmap_free(fd->packedmap);
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
oldnewmap_free(fd->libmap);
if (fd->bheadmap)
@@ -1154,25 +1216,33 @@ static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
return oldnewmap_lookup_and_inc(fd->datamap, adr);
}
-static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
+static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
{
return oldnewmap_lookup_and_inc(fd->globmap, adr);
}
-static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
+static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
{
if (fd->imamap && adr)
return oldnewmap_lookup_and_inc(fd->imamap, adr);
return NULL;
}
-static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
+static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
{
if (fd->movieclipmap && adr)
return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
return NULL;
}
+static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
+{
+ if (fd->packedmap && adr)
+ return oldnewmap_lookup_and_inc(fd->packedmap, adr);
+
+ return oldnewmap_lookup_and_inc(fd->datamap, adr);
+}
+
static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
{
@@ -1369,6 +1439,69 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
}
}
+static void insert_packedmap(FileData *fd, PackedFile *pf)
+{
+ oldnewmap_insert(fd->packedmap, pf, pf, 0);
+ oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0);
+}
+
+void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
+{
+ Image *ima;
+ VFont *vfont;
+ bSound *sound;
+ Library *lib;
+
+ fd->packedmap = oldnewmap_new();
+
+ for (ima = oldmain->image.first; ima; ima = ima->id.next)
+ if (ima->packedfile)
+ insert_packedmap(fd, ima->packedfile);
+
+ for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
+ if (vfont->packedfile)
+ insert_packedmap(fd, vfont->packedfile);
+
+ for (sound = oldmain->sound.first; sound; sound = sound->id.next)
+ if (sound->packedfile)
+ insert_packedmap(fd, sound->packedfile);
+
+ for (lib = oldmain->library.first; lib; lib = lib->id.next)
+ if (lib->packedfile)
+ insert_packedmap(fd, lib->packedfile);
+
+}
+
+/* set old main packed data to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
+{
+ Image *ima;
+ VFont *vfont;
+ bSound *sound;
+ Library *lib;
+ OldNew *entry = fd->packedmap->entries;
+ int i;
+
+ /* used entries were restored, so we put them to zero */
+ for (i=0; i < fd->packedmap->nentries; i++, entry++) {
+ if (entry->nr > 0)
+ entry->newp = NULL;
+ }
+
+ for (ima = oldmain->image.first; ima; ima = ima->id.next)
+ ima->packedfile = newpackedadr(fd, ima->packedfile);
+
+ for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
+ vfont->packedfile = newpackedadr(fd, vfont->packedfile);
+
+ for (sound = oldmain->sound.first; sound; sound = sound->id.next)
+ sound->packedfile = newpackedadr(fd, sound->packedfile);
+
+ for (lib = oldmain->library.first; lib; lib = lib->id.next)
+ lib->packedfile = newpackedadr(fd, lib->packedfile);
+}
+
/* undo file support: add all library pointers in lookup */
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
@@ -1708,10 +1841,10 @@ static void direct_link_script(FileData *UNUSED(fd), Script *script)
static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
{
- PackedFile *pf = newdataadr(fd, oldpf);
+ PackedFile *pf = newpackedadr(fd, oldpf);
if (pf) {
- pf->data = newdataadr(fd, pf->data);
+ pf->data = newpackedadr(fd, pf->data);
}
return pf;
@@ -2535,7 +2668,7 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
cld.fd = fd;
cld.id = id;
- id_loop_constraints(conlist, lib_link_constraint_cb, &cld);
+ BKE_id_loop_constraints(conlist, lib_link_constraint_cb, &cld);
}
static void direct_link_constraints(FileData *fd, ListBase *lb)
@@ -2981,7 +3114,7 @@ static void direct_link_text(FileData *fd, Text *text)
if (text->flags & TXT_ISEXT) {
BKE_text_reload(text);
}
- else {
+ /* else { */
#endif
link_list(fd, &text->lines);
@@ -3207,7 +3340,7 @@ static void direct_link_texture(FileData *fd, Tex *tex)
tex->env = newdataadr(fd, tex->env);
if (tex->env) {
tex->env->ima = NULL;
- memset(tex->env->cube, 0, 6*sizeof(void *));
+ memset(tex->env->cube, 0, 6 * sizeof(void *));
tex->env->ok= 0;
}
tex->pd = newdataadr(fd, tex->pd);
@@ -4991,6 +5124,16 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->toolsettings->imapaint.paintcursor = NULL;
sce->toolsettings->particle.paintcursor = NULL;
+
+ /* in rare cases this is needed, see [#33806] */
+ if (sce->toolsettings->vpaint) {
+ sce->toolsettings->vpaint->vpaint_prev = NULL;
+ sce->toolsettings->vpaint->tot = 0;
+ }
+ if (sce->toolsettings->wpaint) {
+ sce->toolsettings->wpaint->wpaint_prev = NULL;
+ sce->toolsettings->wpaint->tot = 0;
+ }
}
if (sce->ed) {
@@ -5160,6 +5303,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->drawdata = NULL;
win->drawmethod = -1;
win->drawfail = 0;
+ win->active = 0;
}
wm->timers.first = wm->timers.last = NULL;
@@ -5231,27 +5375,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
/* ****************** READ SCREEN ***************** */
-static void butspace_version_132(SpaceButs *buts)
-{
- buts->v2d.tot.xmin = 0.0f;
- buts->v2d.tot.ymin = 0.0f;
- buts->v2d.tot.xmax = 1279.0f;
- buts->v2d.tot.ymax = 228.0f;
-
- buts->v2d.min[0] = 256.0f;
- buts->v2d.min[1] = 42.0f;
-
- buts->v2d.max[0] = 2048.0f;
- buts->v2d.max[1] = 450.0f;
-
- buts->v2d.minzoom = 0.5f;
- buts->v2d.maxzoom = 1.21f;
-
- buts->v2d.scroll = 0;
- buts->v2d.keepzoom = 1;
- buts->v2d.keeptot = 1;
-}
-
/* note: file read without screens option G_FILE_NO_UI;
* check lib pointers in call below */
static void lib_link_screen(FileData *fd, Main *main)
@@ -5305,18 +5428,9 @@ static void lib_link_screen(FileData *fd, Main *main)
else if (sl->spacetype == SPACE_BUTS) {
SpaceButs *sbuts = (SpaceButs *)sl;
sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid);
- sbuts->mainbo = sbuts->mainb;
- sbuts->mainbuser = sbuts->mainb;
- if (main->versionfile < 132)
- butspace_version_132(sbuts);
}
else if (sl->spacetype == SPACE_FILE) {
- SpaceFile *sfile = (SpaceFile *)sl;
- sfile->files = NULL;
- sfile->op = NULL;
- sfile->layout = NULL;
- sfile->folders_prev = NULL;
- sfile->folders_next = NULL;
+ ;
}
else if (sl->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sl;
@@ -5348,12 +5462,6 @@ static void lib_link_screen(FileData *fd, Main *main)
*/
sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd);
- sseq->scopes.reference_ibuf = NULL;
- sseq->scopes.zebra_ibuf = NULL;
- sseq->scopes.waveform_ibuf = NULL;
- sseq->scopes.sep_waveform_ibuf = NULL;
- sseq->scopes.vector_ibuf = NULL;
- sseq->scopes.histogram_ibuf = NULL;
}
else if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla= (SpaceNla *)sl;
@@ -5368,7 +5476,6 @@ static void lib_link_screen(FileData *fd, Main *main)
SpaceText *st= (SpaceText *)sl;
st->text= newlibadr(fd, sc->id.lib, st->text);
- st->drawcache= NULL;
}
else if (sl->spacetype == SPACE_SCRIPT) {
SpaceScript *scpt = (SpaceScript *)sl;
@@ -5385,7 +5492,6 @@ static void lib_link_screen(FileData *fd, Main *main)
TreeStoreElem *tselem;
int a;
- so->tree.first = so->tree.last= NULL;
so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id);
if (so->treestore) {
@@ -5399,7 +5505,6 @@ static void lib_link_screen(FileData *fd, Main *main)
SpaceNode *snode = (SpaceNode *)sl;
snode->id = newlibadr(fd, sc->id.lib, snode->id);
- snode->edittree = NULL;
if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) {
/* internal data, a bit patchy */
@@ -5420,19 +5525,12 @@ static void lib_link_screen(FileData *fd, Main *main)
else {
snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree);
}
-
- snode->linkdrag.first = snode->linkdrag.last = NULL;
}
else if (sl->spacetype == SPACE_CLIP) {
SpaceClip *sclip = (SpaceClip *)sl;
sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip);
sclip->mask_info.mask = newlibadr_us(fd, sc->id.lib, sclip->mask_info.mask);
-
- sclip->scopes.track_search = NULL;
- sclip->scopes.track_preview = NULL;
- sclip->draw_context = NULL;
- sclip->scopes.ok = 0;
}
else if (sl->spacetype == SPACE_LOGIC) {
SpaceLogic *slogic = (SpaceLogic *)sl;
@@ -5744,6 +5842,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
{
Panel *pa;
+ uiList *ui_list;
link_list(fd, &ar->panels);
@@ -5753,7 +5852,13 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
pa->activedata = NULL;
pa->type = NULL;
}
-
+
+ link_list(fd, &ar->ui_lists);
+
+ for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) {
+ ui_list->type = NULL;
+ }
+
ar->regiondata = newdataadr(fd, ar->regiondata);
if (ar->regiondata) {
if (spacetype == SPACE_VIEW3D) {
@@ -5781,6 +5886,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ar->type = NULL;
ar->swap = 0;
ar->do_draw = FALSE;
+ ar->regiontimer = NULL;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
@@ -5925,6 +6031,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
soops->treestore->totelem = soops->treestore->usedelem;
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
}
+ soops->tree.first = soops->tree.last= NULL;
}
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
@@ -5957,6 +6064,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
snode->gpd = newdataadr(fd, snode->gpd);
direct_link_gpencil(fd, snode->gpd);
}
+ snode->edittree = NULL;
+ snode->linkdrag.first = snode->linkdrag.last = NULL;
+ }
+ else if (sl->spacetype == SPACE_TEXT) {
+ SpaceText *st= (SpaceText *)sl;
+
+ st->drawcache= NULL;
}
else if (sl->spacetype == SPACE_TIME) {
SpaceTime *stime = (SpaceTime *)sl;
@@ -5972,6 +6086,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
}
}
else if (sl->spacetype == SPACE_SEQ) {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
/* grease pencil data is not a direct data and can't be linked from direct_link*
* functions, it should be linked from lib_link* functions instead
*
@@ -5980,17 +6096,26 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
* simple return NULL here (sergey)
*/
#if 0
- SpaceSeq *sseq = (SpaceSeq *)sl;
if (sseq->gpd) {
sseq->gpd = newdataadr(fd, sseq->gpd);
direct_link_gpencil(fd, sseq->gpd);
}
#endif
+ sseq->scopes.reference_ibuf = NULL;
+ sseq->scopes.zebra_ibuf = NULL;
+ sseq->scopes.waveform_ibuf = NULL;
+ sseq->scopes.sep_waveform_ibuf = NULL;
+ sseq->scopes.vector_ibuf = NULL;
+ sseq->scopes.histogram_ibuf = NULL;
+
}
else if (sl->spacetype == SPACE_BUTS) {
SpaceButs *sbuts = (SpaceButs *)sl;
+
sbuts->path= NULL;
sbuts->texuser= NULL;
+ sbuts->mainbo = sbuts->mainb;
+ sbuts->mainbuser = sbuts->mainb;
}
else if (sl->spacetype == SPACE_CONSOLE) {
SpaceConsole *sconsole = (SpaceConsole *)sl;
@@ -6030,6 +6155,14 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sfile->op = NULL;
sfile->params = newdataadr(fd, sfile->params);
}
+ else if (sl->spacetype == SPACE_CLIP) {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ sclip->scopes.track_search = NULL;
+ sclip->scopes.track_preview = NULL;
+ sclip->draw_context = NULL;
+ sclip->scopes.ok = 0;
+ }
}
sa->actionzones.first = sa->actionzones.last = NULL;
@@ -6048,6 +6181,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
{
Main *newmain;
+ /* check if the library was already read */
for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) {
if (newmain->curlib) {
if (BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) {
@@ -6066,14 +6200,14 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
}
}
}
- /* make sure we have full path in lib->filename */
+ /* make sure we have full path in lib->filepath */
BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name));
cleanup_path(fd->relabase, lib->filepath);
-#if 0
- printf("direct_link_library: name %s\n", lib->name);
- printf("direct_link_library: filename %s\n", lib->filename);
-#endif
+// printf("direct_link_library: name %s\n", lib->name);
+// printf("direct_link_library: filepath %s\n", lib->filepath);
+
+ lib->packedfile = direct_link_packedfile(fd, lib->packedfile);
/* new main */
newmain= MEM_callocN(sizeof(Main), "directlink");
@@ -6632,6 +6766,17 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->globalf = fg->globalf;
BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
+ /* error in 2.65 and older: main->name was not set if you save from startup (not after loading file) */
+ if (bfd->filename[0] == 0) {
+ if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1))
+ if ((G.fileflags & G_FILE_RECOVER)==0)
+ BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename));
+
+ /* early 2.50 version patch - filename not in FileGlobal struct at all */
+ if (fd->fileversion <= 250)
+ BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename));
+ }
+
if (G.fileflags & G_FILE_RECOVER)
BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase));
@@ -6727,7 +6872,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
/* Convert degrees to radians. */
NodeDefocus *nqd = node->storage;
/* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */
- nqd->rotation = DEG2RADF(nqd->rotation*255.0f);
+ nqd->rotation = DEG2RADF(nqd->rotation * 255.0f);
}
else if (node->type == CMP_NODE_CHROMA_MATTE) {
/* Convert degrees to radians. */
@@ -6739,7 +6884,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
/* Convert degrees to radians. */
NodeGlare *ndg = node->storage;
/* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */
- ndg->angle_ofs = DEG2RADF(ndg->angle_ofs*255.0f);
+ ndg->angle_ofs = DEG2RADF(ndg->angle_ofs * 255.0f);
}
/* XXX TexMapping struct is used by other nodes too (at least node_composite_mapValue),
* but not the rot part...
@@ -7510,7 +7655,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ob = main->object.first; ob; ob = ob->id.next) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (!cti)
continue;
@@ -7891,7 +8036,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
- int maxres = MAX3(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
+ int maxres = max_iii(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
smd->domain->scale = smd->domain->dx * maxres;
smd->domain->dx = 1.0f / smd->domain->scale;
}
@@ -8389,6 +8534,128 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 3)) {
+ bScreen *sc;
+ for (sc = main->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D:
+ {
+ View3D *v3d = (View3D *)sl;
+ v3d->flag2 |= V3D_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_SEQ:
+ {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+ sseq->flag |= SEQ_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_IMAGE:
+ {
+ SpaceImage *sima = (SpaceImage *)sl;
+ sima->flag |= SI_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_NODE:
+ {
+ SpaceNode *snode = (SpaceNode *)sl;
+ snode->flag |= SNODE_SHOW_GPENCIL;
+ break;
+ }
+ case SPACE_CLIP:
+ {
+ SpaceClip *sclip = (SpaceClip *)sl;
+ sclip->flag |= SC_SHOW_GPENCIL;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
+ Scene *scene;
+ Image *image;
+ Tex *tex;
+
+ for (scene = main->scene.first; scene; scene = scene->id.next) {
+ Sequence *seq;
+
+ SEQ_BEGIN (scene->ed, seq)
+ {
+ if (seq->flag & SEQ_MAKE_PREMUL)
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
+ }
+ SEQ_END
+
+ if (scene->r.bake_samples == 0)
+ scene->r.bake_samples = 256;
+ }
+
+ for (image = main->image.first; image; image = image->id.next) {
+ if (image->flag & IMA_DO_PREMUL)
+ image->alpha_mode = IMA_ALPHA_STRAIGHT;
+ }
+
+ for (tex = main->tex.first; tex; tex = tex->id.next) {
+ if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
+ image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
+
+ if (image)
+ image->flag |= IMA_IGNORE_ALPHA;
+ }
+ }
+ }
+
+ if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+ Curve *cu;
+
+ for (cu = main->curve.first; cu; cu = cu->id.next) {
+ if (cu->flag & (CU_FRONT | CU_BACK)) {
+ if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) {
+ Nurb *nu;
+
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
+ int a;
+
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ a = nu->pntsu;
+
+ while (a--) {
+ bezt->radius = 1.0f;
+ bezt++;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+
+ while (a--) {
+ bp->radius = 1.0f;
+ bp++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 265, 8)) {
+ Mesh *me;
+ for (me = main->mesh.first; me; me = me->id.next) {
+ BKE_mesh_do_versions_cd_flag_init(me);
+ }
+ }
+
+ // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
@@ -8408,8 +8675,11 @@ static void lib_link_all(FileData *fd, Main *main)
{
oldnewmap_sort(fd);
- lib_link_windowmanager(fd, main);
- lib_link_screen(fd, main);
+ /* No load UI for undo memfiles */
+ if (fd->memfile == NULL) {
+ lib_link_windowmanager(fd, main);
+ lib_link_screen(fd, main);
+ }
lib_link_scene(fd, main);
lib_link_object(fd, main);
lib_link_curve(fd, main);
@@ -8456,6 +8726,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
wmKeyMap *keymap;
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
+ bAddon *addon;
bfd->user = user= read_struct(fd, bhead, "user def");
@@ -8493,7 +8764,14 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
for (kmi=keymap->items.first; kmi; kmi=kmi->next)
direct_link_keymapitem(fd, kmi);
}
-
+
+ for (addon = user->addons.first; addon; addon = addon->next) {
+ addon->prop = newdataadr(fd, addon->prop);
+ if (addon->prop) {
+ IDP_DirectLinkProperty(addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
+ }
+
// XXX
user->uifonts.first = user->uifonts.last= NULL;
@@ -8682,9 +8960,10 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
}
-static void expand_doit(FileData *fd, Main *mainvar, void *old)
+static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
{
BHead *bhead;
+ FileData *fd = fdhandle;
ID *id;
bhead = find_bhead(fd, old);
@@ -8697,7 +8976,15 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
Library *lib = read_struct(fd, bheadlib, "Library");
Main *ptr = blo_find_main(fd, lib->name, fd->relabase);
- id = is_yet_read(fd, ptr, bhead);
+ if (ptr->curlib == NULL) {
+ const char *idname= bhead_id_name(fd, bhead);
+
+ BKE_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB ERROR: Data refers to main .blend file: '%s' from %s"),
+ idname, mainvar->curlib->filepath);
+ return;
+ }
+ else
+ id = is_yet_read(fd, ptr, bhead);
if (id == NULL) {
read_libblock(fd, ptr, bhead, LIB_READ+LIB_INDIRECT, NULL);
@@ -8751,7 +9038,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
}
}
-
+static void (*expand_doit)(void *, Main *, void *);
// XXX deprecated - old animation system
static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
@@ -9136,7 +9423,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
ced.fd = fd;
ced.mainvar = mainvar;
- id_loop_constraints(lb, expand_constraint_cb, &ced);
+ BKE_id_loop_constraints(lb, expand_constraint_cb, &ced);
/* deprecated manual expansion stuff */
for (curcon = lb->first; curcon; curcon = curcon->next) {
@@ -9462,14 +9749,18 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask)
}
}
-static void expand_main(FileData *fd, Main *mainvar)
+void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *))
+{
+ expand_doit = expand_doit_func;
+}
+
+void BLO_expand_main(void *fdhandle, Main *mainvar)
{
ListBase *lbarray[MAX_LIBARRAY];
+ FileData *fd = fdhandle;
ID *id;
int a, do_it = TRUE;
- if (fd == NULL) return;
-
while (do_it) {
do_it = FALSE;
@@ -9560,6 +9851,9 @@ static void expand_main(FileData *fd, Main *mainvar)
}
}
+
+/* ***************************** */
+
static int object_in_any_scene(Main *mainvar, Object *ob)
{
Scene *sce;
@@ -9708,6 +10002,28 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons
return (found) ? id : NULL;
}
+/* simple reader for copy/paste buffers */
+void BLO_library_append_all(Main *mainl, BlendHandle *bh)
+{
+ FileData *fd = (FileData *)(bh);
+ BHead *bhead;
+ ID *id = NULL;
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (bhead->code == ENDB)
+ break;
+ if (bhead->code == ID_OB)
+ read_libblock(fd, mainl, bhead, LIB_TESTIND, &id);
+
+ if (id) {
+ /* sort by name in list */
+ ListBase *lb = which_libbase(mainl, GS(id->name));
+ id_sort_by_name(lb, id);
+ }
+ }
+}
+
+
static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag)
{
ID *id= append_named_part(mainl, fd, idname, idcode);
@@ -9812,8 +10128,11 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
Main *mainvar;
Library *curlib;
+ /* expander now is callback function */
+ BLO_main_expander(expand_doit_library);
+
/* make main consistent */
- expand_main(*fd, mainl);
+ BLO_expand_main(*fd, mainl);
/* do this when expand found other libs */
read_libraries(*fd, (*fd)->mainlist);
@@ -9908,6 +10227,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
ListBase *lbarray[MAX_LIBARRAY];
int a, do_it = TRUE;
+ /* expander now is callback function */
+ BLO_main_expander(expand_doit_library);
+
while (do_it) {
do_it = FALSE;
@@ -9921,12 +10243,26 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
FileData *fd = mainptr->curlib->filedata;
if (fd == NULL) {
+
/* printf and reports for now... its important users know this */
- BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
- mainptr->curlib->filepath, mainptr->curlib->name);
- fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
-
+ /* if packed file... */
+ if (mainptr->curlib->packedfile) {
+ PackedFile *pf = mainptr->curlib->packedfile;
+
+ BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read packed library: '%s'"),
+ mainptr->curlib->name);
+ fd = blo_openblendermemory(pf->data, pf->size, basefd->reports);
+
+
+ /* needed for library_append and read_libraries */
+ BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase));
+ }
+ else {
+ BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
+ mainptr->curlib->filepath, mainptr->curlib->name);
+ fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
+ }
/* allow typing in a new lib path */
if (G.debug_value == -666) {
while (fd == NULL) {
@@ -10007,7 +10343,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
}
}
- expand_main(fd, mainptr);
+ BLO_expand_main(fd, mainptr);
}
}
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index a979a16..a0895c9 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -69,6 +69,9 @@ typedef struct FileData {
char headerdone;
int inbuffer;
+ // gzip stream for memory decompression
+ z_stream strm;
+
// general reading variables
struct SDNA *filesdna;
struct SDNA *memsdna;
@@ -83,6 +86,7 @@ typedef struct FileData {
struct OldNewMap *libmap;
struct OldNewMap *imamap;
struct OldNewMap *movieclipmap;
+ struct OldNewMap *packedmap;
struct BHeadSort *bheadmap;
int tot_bheadmap;
@@ -127,6 +131,8 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
+void blo_make_packed_pointer_map(FileData *fd, Main *oldmain);
+void blo_end_packed_pointer_map(FileData *fd, Main *oldmain);
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd);
void blo_freefiledata(FileData *fd);
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
index 5d8a865..cbbaf71 100644
--- a/source/blender/blenloader/intern/runtime.c
+++ b/source/blender/blenloader/intern/runtime.c
@@ -48,11 +48,12 @@
#include "BLO_readfile.h"
#include "BLO_runtime.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
#include "BKE_blender.h"
#include "BKE_report.h"
-#include "BLI_blenlib.h"
-
/* Runtime reading */
static int handle_read_msb_int(int handle)
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 1521739..f4d841f 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -292,7 +292,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
memcpy(&ar->v2d, &soops->v2d, sizeof(View2D));
ar->v2d.scroll &= ~V2D_SCROLL_LEFT;
- ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
ar->v2d.keepzoom |= (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPASPECT);
ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
@@ -415,7 +415,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.tot.ymax = ar->winy;
ar->v2d.cur = ar->v2d.tot;
ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
+ ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
break;
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 8a56e3c..65a60e1 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -289,11 +289,10 @@ static void ntree_version_245(FileData *fd, Library *lib, bNodeTree *ntree)
iuser = node->storage;
if (iuser->flag & IMA_OLD_PREMUL) {
iuser->flag &= ~IMA_OLD_PREMUL;
- iuser->flag |= IMA_DO_PREMUL;
}
if (iuser->flag & IMA_DO_PREMUL) {
image->flag &= ~IMA_OLD_PREMUL;
- image->flag |= IMA_DO_PREMUL;
+ image->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
}
@@ -545,7 +544,7 @@ void blo_do_version_old_trackto_to_constraints(Object *ob)
{
/* create new trackto constraint from the relationship */
if (ob->track) {
- bConstraint *con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+ bConstraint *con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
bTrackToConstraint *data = con->data;
/* copy tracking settings from the object */
@@ -1840,7 +1839,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
SEQ_BEGIN (sce->ed, seq)
{
if (seq->type == SEQ_TYPE_IMAGE || seq->type == SEQ_TYPE_MOVIE)
- seq->flag |= SEQ_MAKE_PREMUL;
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
}
SEQ_END
}
@@ -2901,20 +2900,19 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
for (ima = main->image.first; ima; ima = ima->id.next) {
if (ima->flag & IMA_OLD_PREMUL) {
ima->flag &= ~IMA_OLD_PREMUL;
- ima->flag |= IMA_DO_PREMUL;
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
for (tex = main->tex.first; tex; tex = tex->id.next) {
if (tex->iuser.flag & IMA_OLD_PREMUL) {
tex->iuser.flag &= ~IMA_OLD_PREMUL;
- tex->iuser.flag |= IMA_DO_PREMUL;
}
ima = blo_do_versions_newlibadr(fd, lib, tex->ima);
if (ima && (tex->iuser.flag & IMA_DO_PREMUL)) {
ima->flag &= ~IMA_OLD_PREMUL;
- ima->flag |= IMA_DO_PREMUL;
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index b010cae..6f5b0e9 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -139,7 +139,7 @@
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
-#include "BLI_bpath.h"
+#include "BKE_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -850,8 +850,12 @@ static void write_userdef(WriteData *wd)
write_keymapitem(wd, kmi);
}
- for (bext= U.addons.first; bext; bext=bext->next)
+ for (bext= U.addons.first; bext; bext=bext->next) {
writestruct(wd, DATA, "bAddon", 1, bext);
+ if (bext->prop) {
+ IDP_WriteProperty(bext->prop, wd);
+ }
+ }
for (style= U.uistyles.first; style; style= style->next) {
writestruct(wd, DATA, "uiStyle", 1, style);
@@ -1228,7 +1232,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
bConstraint *con;
for (con=conlist->first; con; con=con->next) {
- bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti= BKE_constraint_get_typeinfo(con);
/* Write the specific data */
if (cti && con->data) {
@@ -1416,8 +1420,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
int size = mmd->dyngridsize;
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences);
- writedata(wd, DATA, sizeof(int)*(mmd->totvert+1), mmd->bindoffsets);
- writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert,
+ writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets);
+ writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert,
mmd->bindcagecos);
writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid);
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
@@ -1508,7 +1512,7 @@ static void write_vfonts(WriteData *wd, ListBase *idbase)
/* direct data */
- if (vf->packedfile) {
+ if (vf->packedfile && !wd->current) {
pf = vf->packedfile;
writestruct(wd, DATA, "PackedFile", 1, pf);
writedata(wd, DATA, pf->size, pf->data);
@@ -1674,7 +1678,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external)
MDisps *md = &mdlist[i];
if (md->disps) {
if (!external)
- writedata(wd, DATA, sizeof(float)*3*md->totdisp, md->disps);
+ writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps);
}
if (md->hidden)
@@ -1958,7 +1962,7 @@ static void write_images(WriteData *wd, ListBase *idbase)
writestruct(wd, ID_IM, "Image", 1, ima);
if (ima->id.properties) IDP_WriteProperty(ima->id.properties, wd);
- if (ima->packedfile) {
+ if (ima->packedfile && !wd->current) {
pf = ima->packedfile;
writestruct(wd, DATA, "PackedFile", 1, pf);
writedata(wd, DATA, pf->size, pf->data);
@@ -2395,6 +2399,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
for (sa= sc->areabase.first; sa; sa= sa->next) {
SpaceLink *sl;
Panel *pa;
+ uiList *ui_list;
ARegion *ar;
writestruct(wd, DATA, "ScrArea", 1, sa);
@@ -2404,6 +2409,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
for (pa= ar->panels.first; pa; pa= pa->next)
writestruct(wd, DATA, "Panel", 1, pa);
+
+ for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next)
+ writestruct(wd, DATA, "uiList", 1, ui_list);
}
sl= sa->spacedata.first;
@@ -2515,6 +2523,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
sc= sc->id.next;
}
+
+ /* flush helps the compression for undo-save */
+ mywrite(wd, MYWRITE_FLUSH, 0);
}
static void write_libraries(WriteData *wd, Main *main)
@@ -2528,20 +2539,31 @@ static void write_libraries(WriteData *wd, Main *main)
a=tot= set_listbasepointers(main, lbarray);
/* test: is lib being used */
- foundone = FALSE;
- while (tot--) {
- for (id= lbarray[tot]->first; id; id= id->next) {
- if (id->us>0 && (id->flag & LIB_EXTERN)) {
- foundone = TRUE;
- break;
+ if (main->curlib && main->curlib->packedfile)
+ foundone = TRUE;
+ else {
+ foundone = FALSE;
+ while (tot--) {
+ for (id= lbarray[tot]->first; id; id= id->next) {
+ if (id->us>0 && (id->flag & LIB_EXTERN)) {
+ foundone = TRUE;
+ break;
+ }
}
+ if (foundone) break;
}
- if (foundone) break;
}
-
+
if (foundone) {
writestruct(wd, ID_LI, "Library", 1, main->curlib);
+ if (main->curlib->packedfile && !wd->current) {
+ PackedFile *pf = main->curlib->packedfile;
+ writestruct(wd, DATA, "PackedFile", 1, pf);
+ writedata(wd, DATA, pf->size, pf->data);
+ printf("write packed .blend: %s\n", main->curlib->name);
+ }
+
while (a--) {
for (id= lbarray[a]->first; id; id= id->next) {
if (id->us>0 && (id->flag & LIB_EXTERN)) {
@@ -2670,7 +2692,7 @@ static void write_sounds(WriteData *wd, ListBase *idbase)
writestruct(wd, ID_SO, "bSound", 1, sound);
if (sound->id.properties) IDP_WriteProperty(sound->id.properties, wd);
- if (sound->packedfile) {
+ if (sound->packedfile && !wd->current) {
pf = sound->packedfile;
writestruct(wd, DATA, "PackedFile", 1, pf);
writedata(wd, DATA, pf->size, pf->data);
@@ -2877,7 +2899,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
/* XXX still remap G */
fg.curscreen= screen;
- fg.curscene= screen->scene;
+ fg.curscene= screen? screen->scene : NULL;
fg.displaymode= G.displaymode;
fg.winpos= G.winpos;
@@ -2886,7 +2908,6 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
fg.globalf= G.f;
BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
-
sprintf(subvstr, "%4d", BLENDER_SUBVERSION);
memcpy(fg.subvstr, subvstr, 4);
@@ -2938,11 +2959,8 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
write_thumb(wd, thumb);
write_global(wd, write_flags, mainvar);
- /* no UI save in undo */
- if (current==NULL) {
- write_windowmanagers(wd, &mainvar->wm);
- write_screens (wd, &mainvar->screen);
- }
+ write_windowmanagers(wd, &mainvar->wm);
+ write_screens (wd, &mainvar->screen);
write_movieclips (wd, &mainvar->movieclip);
write_masks (wd, &mainvar->mask);
write_scenes (wd, &mainvar->scene);
@@ -3027,13 +3045,12 @@ static int do_history(const char *name, ReportList *reports)
/* return: success (1) */
int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb)
{
- char userfilename[FILE_MAX];
char tempname[FILE_MAX+1];
int file, err, write_user_block;
/* path backup/restore */
void *path_list_backup = NULL;
- const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE);
+ const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE);
/* open temporary file, so we preserve the original in case we crash */
BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
@@ -3046,7 +3063,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
/* check if we need to backup and restore paths */
if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) {
- path_list_backup = BLI_bpath_list_backup(mainvar, path_list_flag);
+ path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag);
}
/* remapping of relative paths to new file location */
@@ -3069,24 +3086,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
* we should not have any relative paths, but if there
* is somehow, an invalid or empty G.main->name it will
* print an error, don't try make the absolute in this case. */
- BLI_bpath_absolute_convert(mainvar, G.main->name, NULL);
+ BKE_bpath_absolute_convert(mainvar, G.main->name, NULL);
}
}
}
- BLI_make_file_string(G.main->name, userfilename, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
- write_user_block= (BLI_path_cmp(filepath, userfilename) == 0);
+ write_user_block= write_flags & G_FILE_USERPREFS;
if (write_flags & G_FILE_RELATIVE_REMAP)
- BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
+ BKE_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
/* actual file writing */
err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb);
close(file);
if (UNLIKELY(path_list_backup)) {
- BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
- BLI_bpath_list_free(path_list_backup);
+ BKE_bpath_list_restore(mainvar, path_list_flag, path_list_backup);
+ BKE_bpath_list_free(path_list_backup);
}
if (err) {
@@ -3151,3 +3167,4 @@ int BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int wr
if (err==0) return 1;
return 0;
}
+
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 2a23658..d11d748 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -30,7 +30,7 @@ set(INC
../blenlib
../makesdna
../../../intern/guardedalloc
- ../../../extern/bullet2/src
+ ../../../extern/rangetree
../../../intern/opennl/extern
)
@@ -74,6 +74,8 @@ set(SRC
intern/bmesh_iterators.c
intern/bmesh_iterators.h
intern/bmesh_iterators_inline.h
+ intern/bmesh_log.c
+ intern/bmesh_log.h
intern/bmesh_marking.c
intern/bmesh_marking.h
intern/bmesh_mesh.c
@@ -111,6 +113,8 @@ set(SRC
tools/bmesh_decimate_dissolve.c
tools/bmesh_decimate_unsubdivide.c
tools/bmesh_decimate.h
+ tools/bmesh_edgesplit.c
+ tools/bmesh_edgesplit.h
bmesh.h
bmesh_class.h
@@ -122,6 +126,9 @@ endif()
if(WITH_BULLET)
add_definitions(-DWITH_BULLET)
+ list(APPEND INC_SYS
+ ${BULLET_INCLUDE_DIRS}
+ )
endif()
if(WITH_INTERNATIONAL)
diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript
index 6765d57..a8ca514 100644
--- a/source/blender/bmesh/SConscript
+++ b/source/blender/bmesh/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
cflags=''
@@ -15,7 +41,9 @@ incs = [
'../blenkernel',
'#/intern/guardedalloc',
'#/extern/bullet2/src',
- '#/intern/opennl/extern', ]
+ '#/extern/rangetree',
+ '#/intern/opennl/extern'
+ ]
defs = []
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 6257aa4..60d3871 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -254,6 +254,7 @@ extern "C" {
#include "intern/bmesh_core.h"
#include "intern/bmesh_interp.h"
#include "intern/bmesh_iterators.h"
+#include "intern/bmesh_log.h"
#include "intern/bmesh_marking.h"
#include "intern/bmesh_mesh.h"
#include "intern/bmesh_mesh_conv.h"
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 9d797c1..824884f 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -184,11 +184,12 @@ typedef struct BMesh {
* BM_LOOP isn't handled so far. */
char elem_index_dirty;
- /*element pools*/
+ /* element pools */
struct BLI_mempool *vpool, *epool, *lpool, *fpool;
- /*operator api stuff*/
- struct BLI_mempool *toolflagpool;
+ /* operator api stuff (must be all NULL or all alloc'd) */
+ struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
+
int stackdepth;
struct BMOperator *currentop;
@@ -204,7 +205,7 @@ typedef struct BMesh {
* Only use when the edit mesh cant be accessed - campbell */
short selectmode;
- /*ID of the shape key this bmesh came from*/
+ /* ID of the shape key this bmesh came from */
int shapenr;
int walkers, totflags;
@@ -253,6 +254,18 @@ enum {
/* defines */
+#define BM_ELEM_CD_GET_VOID_P(ele, offset) \
+ ((void)0, (void *)((char *)(ele)->head.data + (offset)))
+
+#define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \
+ { *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0
+
+#define BM_ELEM_CD_GET_FLOAT(ele, offset) \
+ ((void)0, *((float *)((char *)(ele)->head.data + (offset))))
+
+#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
+ (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f)
+
/*forward declarations*/
#ifdef USE_BMESH_HOLES
@@ -276,5 +289,6 @@ enum {
* but should not error on valid cases */
#define BM_LOOP_RADIAL_MAX 10000
#define BM_NGON_MAX 100000
+#define BM_OMP_LIMIT 0 /* setting zero so we can catch bugs in OpenMP/BMesh */
#endif /* __BMESH_CLASS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 8b7fac1..31f7958 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -173,24 +173,24 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
*/
BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag)
{
- BMEdge **edges2 = NULL;
- BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
- BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
+ BMEdge **edges_sort = BLI_array_alloca(edges_sort, len);
+ BMVert **verts_sort = BLI_array_alloca(verts_sort, len + 1);
+ int esort_index = 0;
+ int vsort_index = 0;
+
BMFace *f = NULL;
BMEdge *e;
BMVert *v, *ev1, *ev2;
- int i, /* j, */ v1found, reverse;
+ int i;
+ bool is_v1_found, is_reverse;
+
/* this code is hideous, yeek. I'll have to think about ways of
* cleaning it up. basically, it now combines the old BM_face_create_ngon
* _and_ the old bmesh_mf functions, so its kindof smashed together
* - joeedh */
- if (!len || !v1 || !v2 || !edges || !bm) {
- BLI_assert(0);
- return NULL;
- }
+ BLI_assert(len && v1 && v2 && edges && bm);
/* put edges in correct order */
for (i = 0; i < len; i++) {
@@ -207,14 +207,19 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
SWAP(BMVert *, ev1, ev2);
}
- BLI_array_append(verts, ev1);
+ verts_sort[vsort_index++] = ev1;
v = ev2;
e = edges[0];
do {
BMEdge *e2 = e;
- BLI_array_append(verts, v);
- BLI_array_append(edges2, e);
+ /* vertex array is (len + 1) */
+ if (UNLIKELY(vsort_index > len)) {
+ goto err; /* vertex in loop twice */
+ }
+
+ verts_sort[vsort_index++] = v;
+ edges_sort[esort_index++] = e;
/* we only flag the verts to check if they are in the face more then once */
BM_ELEM_API_FLAG_ENABLE(v, _FLAG_MV);
@@ -227,84 +232,78 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
}
} while (e2 != e);
- if (e2 == e)
+ if (UNLIKELY(e2 == e)) {
goto err; /* the edges do not form a closed loop */
+ }
e = e2;
} while (e != edges[0]);
- if (BLI_array_count(edges2) != len) {
+ if (UNLIKELY(esort_index != len)) {
goto err; /* we didn't use all edges in forming the boundary loop */
}
/* ok, edges are in correct order, now ensure they are going
* in the correct direction */
- v1found = reverse = FALSE;
+ is_v1_found = is_reverse = false;
for (i = 0; i < len; i++) {
- if (BM_vert_in_edge(edges2[i], v1)) {
+ if (BM_vert_in_edge(edges_sort[i], v1)) {
/* see if v1 and v2 are in the same edge */
- if (BM_vert_in_edge(edges2[i], v2)) {
+ if (BM_vert_in_edge(edges_sort[i], v2)) {
/* if v1 is shared by the *next* edge, then the winding
* is incorrect */
- if (BM_vert_in_edge(edges2[(i + 1) % len], v1)) {
- reverse = TRUE;
+ if (BM_vert_in_edge(edges_sort[(i + 1) % len], v1)) {
+ is_reverse = true;
break;
}
}
- v1found = TRUE;
+ is_v1_found = true;
}
- if ((v1found == FALSE) && BM_vert_in_edge(edges2[i], v2)) {
- reverse = TRUE;
+ if ((is_v1_found == false) && BM_vert_in_edge(edges_sort[i], v2)) {
+ is_reverse = true;
break;
}
}
- if (reverse) {
+ if (is_reverse) {
for (i = 0; i < len / 2; i++) {
- v = verts[i];
- verts[i] = verts[len - i - 1];
- verts[len - i - 1] = v;
+ v = verts_sort[i];
+ verts_sort[i] = verts_sort[len - i - 1];
+ verts_sort[len - i - 1] = v;
}
}
for (i = 0; i < len; i++) {
- edges2[i] = BM_edge_exists(verts[i], verts[(i + 1) % len]);
- if (!edges2[i]) {
+ edges_sort[i] = BM_edge_exists(verts_sort[i], verts_sort[(i + 1) % len]);
+ if (UNLIKELY(edges_sort[i] == NULL)) {
goto err;
}
/* check if vert is in face more then once. if the flag is disabled. we've already visited */
- if (!BM_ELEM_API_FLAG_TEST(verts[i], _FLAG_MV)) {
+ if (UNLIKELY(!BM_ELEM_API_FLAG_TEST(verts_sort[i], _FLAG_MV))) {
goto err;
}
- BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
+ BM_ELEM_API_FLAG_DISABLE(verts_sort[i], _FLAG_MV);
}
- f = BM_face_create(bm, verts, edges2, len, create_flag);
+ f = BM_face_create(bm, verts_sort, edges_sort, len, create_flag);
/* clean up flags */
for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_DISABLE(edges2[i], _FLAG_MF);
+ BM_ELEM_API_FLAG_DISABLE(edges_sort[i], _FLAG_MF);
}
- BLI_array_free(verts);
- BLI_array_free(edges2);
-
return f;
err:
for (i = 0; i < len; i++) {
BM_ELEM_API_FLAG_DISABLE(edges[i], _FLAG_MF);
- /* vert count may != len */
- if (i < BLI_array_count(verts)) {
- BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
- }
}
-
- BLI_array_free(verts);
- BLI_array_free(edges2);
+ for (i = 0; i < vsort_index; i++) {
+ BM_ELEM_API_FLAG_DISABLE(verts_sort[i], _FLAG_MV);
+ }
return NULL;
}
@@ -821,6 +820,8 @@ void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *sour
BMesh *BM_mesh_copy(BMesh *bm_old)
{
+#define USE_FAST_FACE_COPY
+
BMesh *bm_new;
BMVert *v, *v2, **vtable = NULL;
BMEdge *e, *e2, **edges = NULL, **etable = NULL;
@@ -828,6 +829,10 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
BLI_array_declare(edges);
BMLoop *l, /* *l2, */ **loops = NULL;
BLI_array_declare(loops);
+#ifdef USE_FAST_FACE_COPY
+ BMVert **verts = NULL;
+ BLI_array_declare(verts);
+#endif
BMFace *f, *f2, **ftable = NULL;
BMEditSelection *ese;
BMIter iter, liter;
@@ -895,12 +900,24 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
BLI_array_grow_items(loops, f->len);
BLI_array_grow_items(edges, f->len);
+#ifdef USE_FAST_FACE_COPY
+ BLI_array_empty(verts);
+ BLI_array_grow_items(verts, f->len);
+#endif
+
l = BM_iter_new(&liter, bm_old, BM_LOOPS_OF_FACE, f);
for (j = 0; j < f->len; j++, l = BM_iter_step(&liter)) {
loops[j] = l;
edges[j] = etable[BM_elem_index_get(l->e)];
+
+#ifdef USE_FAST_FACE_COPY
+ verts[j] = vtable[BM_elem_index_get(l->v)];
+#endif
}
+#ifdef USE_FAST_FACE_COPY
+ f2 = BM_face_create(bm_new, verts, edges, f->len, BM_CREATE_SKIP_CD);
+#else
v = vtable[BM_elem_index_get(loops[0]->v)];
v2 = vtable[BM_elem_index_get(loops[1]->v)];
@@ -910,6 +927,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
}
f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD);
+#endif
+
if (UNLIKELY(f2 == NULL)) {
continue;
}
@@ -965,9 +984,12 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
MEM_freeN(vtable);
MEM_freeN(ftable);
+#ifdef USE_FAST_FACE_COPY
+ BLI_array_free(verts);
+#endif
+
BLI_array_free(loops);
BLI_array_free(edges);
-
return bm_new;
}
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 14fab7a..ea9ab36 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -78,9 +78,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, cons
copy_v3_v3(v->co, co);
}
- /* allocate flag */
- if (bm->toolflagpool) {
- v->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ /* allocate flags */
+ if (bm->vtoolflagpool) {
+ v->oflags = BLI_mempool_calloc(bm->vtoolflagpool);
}
if (!(create_flag & BM_CREATE_SKIP_CD)) {
@@ -132,9 +132,9 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example,
e->head.htype = BM_EDGE;
- /* allocate flag */
- if (bm->toolflagpool) {
- e->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ /* allocate flags */
+ if (bm->etoolflagpool) {
+ e->oflags = BLI_mempool_calloc(bm->etoolflagpool);
}
e->v1 = v1;
@@ -211,10 +211,8 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge
BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges)
{
- BMVert **verts = NULL;
- BMEdge **edges = NULL;
- BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
- BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
+ BMVert **verts = BLI_array_alloca(verts, f->len);
+ BMEdge **edges = BLI_array_alloca(edges, f->len);
BMLoop *l_iter;
BMLoop *l_first;
BMLoop *l_copy;
@@ -267,9 +265,6 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
l_copy = l_copy->next;
} while ((l_iter = l_iter->next) != l_first);
- BLI_array_fixedstack_free(verts);
- BLI_array_fixedstack_free(edges);
-
return f_copy;
}
@@ -295,9 +290,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag creat
f->head.htype = BM_FACE;
- /* allocate flag */
- if (bm->toolflagpool) {
- f->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ /* allocate flags */
+ if (bm->ftoolflagpool) {
+ f->oflags = BLI_mempool_calloc(bm->ftoolflagpool);
}
if (!(create_flag & BM_CREATE_SKIP_CD)) {
@@ -321,7 +316,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
int i, overlap;
if (len == 0) {
- /* just return NULL for no */
+ /* just return NULL for now */
return NULL;
}
@@ -517,8 +512,8 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
if (v->head.data)
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, v->oflags);
+ if (bm->vtoolflagpool) {
+ BLI_mempool_free(bm->vtoolflagpool, v->oflags);
}
BLI_mempool_free(bm->vpool, v);
}
@@ -537,8 +532,8 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
if (e->head.data)
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, e->oflags);
+ if (bm->etoolflagpool) {
+ BLI_mempool_free(bm->etoolflagpool, e->oflags);
}
BLI_mempool_free(bm->epool, e);
}
@@ -560,8 +555,8 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
if (f->head.data)
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, f->oflags);
+ if (bm->ftoolflagpool) {
+ BLI_mempool_free(bm->ftoolflagpool, f->oflags);
}
BLI_mempool_free(bm->fpool, f);
}
@@ -585,22 +580,19 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
*/
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
- BMEdge **edges = NULL;
- BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
+ BMEdge **edges = BLI_array_alloca_and_count(edges, f->len);
BMLoop *l_iter;
BMLoop *l_first;
- int i;
+ int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BLI_array_append(edges, l_iter->e);
+ edges[i++] = l_iter->e;
} while ((l_iter = l_iter->next) != l_first);
for (i = 0; i < BLI_array_count(edges); i++) {
BM_edge_kill(bm, edges[i]);
}
-
- BLI_array_free(edges);
}
/**
@@ -609,22 +601,19 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
*/
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
- BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
+ BMVert **verts = BLI_array_alloca_and_count(verts, f->len);
BMLoop *l_iter;
BMLoop *l_first;
- int i;
+ int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BLI_array_append(verts, l_iter->v);
+ verts[i++] = l_iter->v;
} while ((l_iter = l_iter->next) != l_first);
for (i = 0; i < BLI_array_count(verts); i++) {
BM_vert_kill(bm, verts[i]);
}
-
- BLI_array_free(verts);
}
/**
@@ -761,8 +750,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
const int len = f->len;
const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMLoop *l_iter, *oldprev, *oldnext;
- BMEdge **edar = NULL;
- BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
+ BMEdge **edar = BLI_array_alloca(edar, len);
int i, j, edok;
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
@@ -814,11 +802,11 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
}
}
}
- /* rebuild radia */
+ /* rebuild radial */
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next)
bmesh_radial_append(l_iter->e, l_iter);
- /* validate radia */
+ /* validate radial */
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
BM_CHECK_ELEMENT(l_iter);
BM_CHECK_ELEMENT(l_iter->e);
@@ -826,8 +814,6 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
BM_CHECK_ELEMENT(l_iter->f);
}
- BLI_array_fixedstack_free(edar);
-
BM_CHECK_ELEMENT(f);
return 1;
@@ -1068,7 +1054,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
} while (l2 != l_iter);
if (l2 != l_iter) {
- /* I think this is correct */
+ /* I think this is correct? */
if (l2->v != l_iter->v) {
l2 = l2->next;
}
@@ -1080,7 +1066,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
BM_elem_attrs_copy(bm, bm, faces[0], newf);
#ifdef USE_BMESH_HOLES
- /* add hole */
+ /* add holes */
BLI_movelisttolist(&newf->loops, &holes);
#endif
@@ -1396,7 +1382,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
/* add ne to tv's disk cycle */
bmesh_disk_edge_append(ne, tv);
- /* verify disk cycle */
+ /* verify disk cycles */
edok = bmesh_disk_validate(valence1, ov->e, ov);
BMESH_ASSERT(edok != FALSE);
edok = bmesh_disk_validate(valence2, tv->e, tv);
@@ -1483,7 +1469,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BMESH_ASSERT(l->v != l->next->v);
BMESH_ASSERT(l->e != l->next->e);
- /* verify loop cycle for kloop-> */
+ /* verify loop cycle for kloop->f */
BM_CHECK_ELEMENT(l);
BM_CHECK_ELEMENT(l->v);
BM_CHECK_ELEMENT(l->e);
@@ -1564,7 +1550,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
oe = bmesh_disk_edge_next(ke, kv);
tv = bmesh_edge_other_vert_get(ke, kv);
ov = bmesh_edge_other_vert_get(oe, kv);
- halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edge */
+ halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */
if (halt) {
return NULL;
@@ -1572,7 +1558,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
else {
BMEdge *e_splice;
- /* For verification later, count valence of ov and t */
+ /* For verification later, count valence of ov and tv */
valence1 = bmesh_disk_count(ov);
valence2 = bmesh_disk_count(tv);
@@ -1614,8 +1600,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
radlen = bmesh_radial_length(ke->l);
if (LIKELY(radlen)) {
- BMLoop **loops = NULL;
- BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__);
+ BMLoop **loops = BLI_array_alloca(loops, radlen);
killoop = ke->l;
@@ -1628,7 +1613,6 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
bm->totloop--;
BLI_mempool_free(bm->lpool, loops[i]);
}
- BLI_array_fixedstack_free(loops);
}
/* Validate radial cycle of oe */
@@ -1801,8 +1785,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
/* deallocate edge and its two loops as well as f2 */
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
+ if (bm->etoolflagpool) {
+ BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags);
}
BLI_mempool_free(bm->epool, f1loop->e);
bm->totedge--;
@@ -1810,8 +1794,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
bm->totloop--;
BLI_mempool_free(bm->lpool, f2loop);
bm->totloop--;
- if (bm->toolflagpool) {
- BLI_mempool_free(bm->toolflagpool, f2->oflags);
+ if (bm->ftoolflagpool) {
+ BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
}
BLI_mempool_free(bm->fpool, f2);
bm->totface--;
@@ -1895,7 +1879,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
{
BMEdge **stack = NULL;
- BLI_array_declare(stack);
+ BLI_array_staticdeclare(stack, BM_DEFAULT_ITER_STACK_SIZE);
BMVert **verts = NULL;
GHash *visithash;
BMIter eiter, liter;
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index caf9f3c..1afaf85 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -172,11 +172,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = NULL;
- float (*cos)[3] = NULL, *w = NULL;
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ void **blocks = BLI_array_alloca(blocks, source->len);
+ float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float *w = BLI_array_alloca(w, source->len);
int i;
BM_elem_attrs_copy(bm, bm, source, target);
@@ -196,10 +194,6 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data);
i++;
} while ((l_iter = l_iter->next) != l_first);
-
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(w);
- BLI_array_fixedstack_free(blocks);
}
/**
@@ -609,14 +603,12 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
{
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = NULL;
- void **vblocks = NULL;
- float (*cos)[3] = NULL, co[3], *w = NULL;
- float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
+ void **vblocks = do_vertex ? BLI_array_alloca(vblocks, source->len) : NULL;
+ void **blocks = BLI_array_alloca(blocks, source->len);
+ float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
+ float *w = BLI_array_alloca(w, source->len);
+ float co[2];
int i, ax, ay;
BM_elem_attrs_copy(bm, bm, source, target->f);
@@ -625,7 +617,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
copy_v3_v3(cos[i], l_iter->v->co);
- add_v3_v3(cent, cos[i]);
w[i] = 0.0f;
blocks[i] = l_iter->head.data;
@@ -642,38 +633,22 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
axis_dominant_v3(&ax, &ay, source->no);
- /* scale source face coordinates a bit, so points sitting directly on an
- * edge will work. */
- mul_v3_fl(cent, 1.0f / (float)source->len);
for (i = 0; i < source->len; i++) {
- float vec[3], tmp[3];
- sub_v3_v3v3(vec, cent, cos[i]);
- mul_v3_fl(vec, 0.001f);
- add_v3_v3(cos[i], vec);
-
- copy_v3_v3(tmp, cos[i]);
- cos[i][0] = tmp[ax];
- cos[i][1] = tmp[ay];
- cos[i][2] = 0.0f;
+ cos_2d[i][0] = cos[i][ax];
+ cos_2d[i][1] = cos[i][ay];
}
/* interpolate */
co[0] = target->v->co[ax];
co[1] = target->v->co[ay];
- co[2] = 0.0f;
- interp_weights_poly_v3(w, cos, source->len, co);
+ interp_weights_poly_v2(w, cos_2d, source->len, co);
CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data);
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data);
- BLI_array_fixedstack_free(vblocks);
}
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(w);
- BLI_array_fixedstack_free(blocks);
-
if (do_multires) {
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
bm_loop_interp_mdisps(bm, target, source);
@@ -686,42 +661,24 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
{
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = NULL;
- float (*cos)[3] = NULL, *w = NULL;
- float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ void **blocks = BLI_array_alloca(blocks, source->len);
+ float (*cos)[3] = BLI_array_alloca(cos, source->len);
+ float *w = BLI_array_alloca(w, source->len);
int i;
i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(source);
do {
copy_v3_v3(cos[i], l_iter->v->co);
- add_v3_v3(cent, cos[i]);
w[i] = 0.0f;
blocks[i] = l_iter->v->head.data;
i++;
} while ((l_iter = l_iter->next) != l_first);
- /* scale source face coordinates a bit, so points sitting directly on an
- * edge will work. */
- mul_v3_fl(cent, 1.0f / (float)source->len);
- for (i = 0; i < source->len; i++) {
- float vec[3];
- sub_v3_v3v3(vec, cent, cos[i]);
- mul_v3_fl(vec, 0.01f);
- add_v3_v3(cos[i], vec);
- }
-
/* interpolate */
interp_weights_poly_v3(w, cos, source->len, v->co);
CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data);
-
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(w);
- BLI_array_fixedstack_free(blocks);
}
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
new file mode 100644
index 0000000..a251012
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -0,0 +1,962 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_ghash.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_mempool.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_customdata.h"
+
+#include "bmesh.h"
+#include "bmesh_log.h"
+#include "range_tree_c_api.h"
+
+struct BMLogEntry {
+ struct BMLogEntry *next, *prev;
+
+ /* The following GHashes map from an element ID to one of the log
+ * types above */
+
+ /* Elements that were in the previous entry, but have been
+ * deleted */
+ GHash *deleted_verts;
+ GHash *deleted_faces;
+ /* Elements that were not in the previous entry, but are in the
+ * result of this entry */
+ GHash *added_verts;
+ GHash *added_faces;
+
+ /* Vertices whose coordinates, mask value, or hflag have changed */
+ GHash *modified_verts;
+
+ BLI_mempool *pool_verts;
+ BLI_mempool *pool_faces;
+
+ /* This is only needed for dropping BMLogEntries while still in
+ * dynamic-topology mode, as that should release vert/face IDs
+ * back to the BMLog but no BMLog pointer is available at that
+ * time.
+ *
+ * This field is not guaranteed to be valid, any use of it should
+ * check for NULL. */
+ BMLog *log;
+};
+
+struct BMLog {
+ /* Tree of free IDs */
+ struct RangeTreeUInt *unused_ids;
+
+ /* Mapping from unique IDs to vertices and faces
+ *
+ * Each vertex and face in the log gets a unique unsigned integer
+ * assigned. That ID is taken from the set managed by the
+ * unused_ids range tree.
+ *
+ * The ID is needed because element pointers will change as they
+ * are created and deleted.
+ */
+ GHash *id_to_elem;
+ GHash *elem_to_id;
+
+ /* All BMLogEntrys, ordered from earliest to most recent */
+ ListBase entries;
+
+ /* The current log entry from entries list
+ *
+ * If null, then the original mesh from before any of the log
+ * entries is current (i.e. there is nothing left to undo.)
+ *
+ * If equal to the last entry in the entries list, then all log
+ * entries have been applied (i.e. there is nothing left to redo.)
+ */
+ BMLogEntry *current_entry;
+};
+
+typedef struct {
+ float co[3];
+ float mask;
+ char hflag;
+} BMLogVert;
+
+typedef struct {
+ unsigned int v_ids[3];
+} BMLogFace;
+
+/************************* Get/set element IDs ************************/
+
+/* Get the vertex's unique ID from the log */
+static unsigned int bm_log_vert_id_get(BMLog *log, BMVert *v)
+{
+ BLI_assert(BLI_ghash_haskey(log->elem_to_id, v));
+ return GET_INT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, v));
+}
+
+/* Set the vertex's unique ID in the log */
+static void bm_log_vert_id_set(BMLog *log, BMVert *v, unsigned int id)
+{
+ void *vid = SET_INT_IN_POINTER(id);
+
+ BLI_ghash_remove(log->id_to_elem, vid, NULL, NULL);
+ BLI_ghash_insert(log->id_to_elem, vid, v);
+ BLI_ghash_remove(log->elem_to_id, v, NULL, NULL);
+ BLI_ghash_insert(log->elem_to_id, v, vid);
+}
+
+/* Get a vertex from its unique ID */
+static BMVert *bm_log_vert_from_id(BMLog *log, unsigned int id)
+{
+ void *key = SET_INT_IN_POINTER(id);
+ BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
+ return BLI_ghash_lookup(log->id_to_elem, key);
+}
+
+/* Get the face's unique ID from the log */
+static unsigned int bm_log_face_id_get(BMLog *log, BMFace *f)
+{
+ BLI_assert(BLI_ghash_haskey(log->elem_to_id, f));
+ return GET_INT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, f));
+}
+
+/* Set the face's unique ID in the log */
+static void bm_log_face_id_set(BMLog *log, BMFace *f, unsigned int id)
+{
+ void *fid = SET_INT_IN_POINTER(id);
+
+ BLI_ghash_remove(log->id_to_elem, fid, NULL, NULL);
+ BLI_ghash_insert(log->id_to_elem, fid, f);
+ BLI_ghash_remove(log->elem_to_id, f, NULL, NULL);
+ BLI_ghash_insert(log->elem_to_id, f, fid);
+}
+
+/* Get a face from its unique ID */
+static BMFace *bm_log_face_from_id(BMLog *log, unsigned int id)
+{
+ void *key = SET_INT_IN_POINTER(id);
+ BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
+ return BLI_ghash_lookup(log->id_to_elem, key);
+}
+
+
+/************************ BMLogVert / BMLogFace ***********************/
+
+/* Get a vertex's paint-mask value
+ *
+ * Returns zero if no paint-mask layer is present */
+static float vert_mask_get(BMesh *bm, BMVert *v)
+{
+ CustomData *cd = &bm->vdata;
+ if (CustomData_has_layer(&bm->vdata, CD_PAINT_MASK)) {
+ float *mask = CustomData_bmesh_get(cd, v->head.data, CD_PAINT_MASK);
+ return *mask;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* Set a vertex's paint-mask value
+ *
+ * Has no effect is no paint-mask layer is present */
+static void vert_mask_set(BMesh *bm, BMVert *v, float new_mask)
+{
+ CustomData *cd = &bm->vdata;
+ if (CustomData_has_layer(cd, CD_PAINT_MASK)) {
+ float *mask = CustomData_bmesh_get(cd, v->head.data, CD_PAINT_MASK);
+ (*mask) = new_mask;
+ }
+}
+
+/* Update a BMLogVert with data from a BMVert */
+static void bm_log_vert_bmvert_copy(BMesh *bm, BMLogVert *lv, BMVert *v)
+{
+ copy_v3_v3(lv->co, v->co);
+ lv->mask = vert_mask_get(bm, v);
+ lv->hflag = v->head.hflag;
+}
+
+/* Allocate and initialize a BMLogVert */
+static BMLogVert *bm_log_vert_alloc(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
+
+ bm_log_vert_bmvert_copy(bm, lv, v);
+
+ return lv;
+}
+
+/* Allocate and initialize a BMLogFace */
+static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
+{
+ BMLogEntry *entry = log->current_entry;
+ BMLogFace *lf = BLI_mempool_alloc(entry->pool_faces);
+ BMVert *v[3];
+
+ BLI_assert(f->len == 3);
+
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+
+ lf->v_ids[0] = bm_log_vert_id_get(log, v[0]);
+ lf->v_ids[1] = bm_log_vert_id_get(log, v[1]);
+ lf->v_ids[2] = bm_log_vert_id_get(log, v[2]);
+
+ return lf;
+}
+
+
+/************************ Helpers for undo/redo ***********************/
+
+static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ BMVert *v = bm_log_vert_from_id(log, id);
+
+ /* Ensure the log has the final values of the vertex before
+ * deleting it */
+ bm_log_vert_bmvert_copy(bm, lv, v);
+
+ BM_vert_kill(bm, v);
+ }
+}
+
+static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ BMFace *f = bm_log_face_from_id(log, id);
+
+ BM_face_kill(bm, f);
+ }
+}
+
+static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ BMVert *v = BM_vert_create(bm, lv->co, NULL, 0);
+ v->head.hflag = lv->hflag;
+ vert_mask_set(bm, v, lv->mask);
+ bm_log_vert_id_set(log, v, GET_INT_FROM_POINTER(key));
+ }
+}
+
+static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
+ BMVert *v[3] = {bm_log_vert_from_id(log, lf->v_ids[0]),
+ bm_log_vert_from_id(log, lf->v_ids[1]),
+ bm_log_vert_from_id(log, lf->v_ids[2])};
+ BMFace *f;
+
+ f = BM_face_create_quad_tri_v(bm, v, 3, NULL, FALSE);
+ bm_log_face_id_set(log, f, GET_INT_FROM_POINTER(key));
+ }
+}
+
+static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
+{
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ BMVert *v = bm_log_vert_from_id(log, id);
+ float mask;
+
+ swap_v3_v3(v->co, lv->co);
+ SWAP(char, v->head.hflag, lv->hflag);
+ mask = lv->mask;
+ lv->mask = vert_mask_get(bm, v);
+ vert_mask_set(bm, v, mask);
+ }
+}
+
+
+/**********************************************************************/
+
+/* Assign unique IDs to all vertices and faces already in the BMesh */
+static void bm_log_assign_ids(BMesh *bm, BMLog *log)
+{
+ BMIter iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Generate vertex IDs */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ unsigned int id = range_tree_uint_take_any(log->unused_ids);
+ bm_log_vert_id_set(log, v, id);
+ }
+
+ /* Generate face IDs */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ unsigned int id = range_tree_uint_take_any(log->unused_ids);
+ bm_log_face_id_set(log, f, id);
+ }
+}
+
+/* Allocate an empty log entry */
+static BMLogEntry *bm_log_entry_create(void)
+{
+ BMLogEntry *entry = MEM_callocN(sizeof(BMLogEntry), AT);
+
+ entry->deleted_verts = BLI_ghash_ptr_new(AT);
+ entry->deleted_faces = BLI_ghash_ptr_new(AT);
+ entry->added_verts = BLI_ghash_ptr_new(AT);
+ entry->added_faces = BLI_ghash_ptr_new(AT);
+ entry->modified_verts = BLI_ghash_ptr_new(AT);
+
+ entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 1, 64, 0);
+ entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 1, 64, 0);
+
+ return entry;
+}
+
+/* Free the data in a log entry
+ *
+ * Note: does not free the log entry itself */
+static void bm_log_entry_free(BMLogEntry *entry)
+{
+ BLI_ghash_free(entry->deleted_verts, NULL, NULL);
+ BLI_ghash_free(entry->deleted_faces, NULL, NULL);
+ BLI_ghash_free(entry->added_verts, NULL, NULL);
+ BLI_ghash_free(entry->added_faces, NULL, NULL);
+ BLI_ghash_free(entry->modified_verts, NULL, NULL);
+
+ BLI_mempool_destroy(entry->pool_verts);
+ BLI_mempool_destroy(entry->pool_faces);
+}
+
+static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, id_ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+
+ if (range_tree_uint_has(unused_ids, id)) {
+ range_tree_uint_take(unused_ids, id);
+ }
+ }
+}
+
+static int uint_compare(const void *a_v, const void *b_v)
+{
+ const unsigned int *a = a_v;
+ const unsigned int *b = b_v;
+ return (*a) < (*b);
+}
+
+/* Remap IDs to contiguous indices
+ *
+ * E.g. if the vertex IDs are (4, 1, 10, 3), the mapping will be:
+ * 4 -> 2
+ * 1 -> 0
+ * 10 -> 3
+ * 3 -> 1
+ */
+static GHash *bm_log_compress_ids_to_indices(unsigned int *ids, int totid)
+{
+ GHash *map = BLI_ghash_int_new(AT);
+ int i;
+
+ qsort(ids, totid, sizeof(*ids), uint_compare);
+
+ for (i = 0; i < totid; i++) {
+ void *key = SET_INT_IN_POINTER(ids[i]);
+ void *val = SET_INT_IN_POINTER(i);
+ BLI_ghash_insert(map, key, val);
+ }
+
+ return map;
+}
+
+/* Release all ID keys in id_ghash */
+static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, id_ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ unsigned int id = GET_INT_FROM_POINTER(key);
+ range_tree_uint_release(log->unused_ids, id);
+ }
+}
+
+/***************************** Public API *****************************/
+
+/* Allocate, initialize, and assign a new BMLog */
+BMLog *BM_log_create(BMesh *bm)
+{
+ BMLog *log = MEM_callocN(sizeof(*log), AT);
+
+ log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1);
+ log->id_to_elem = BLI_ghash_ptr_new(AT);
+ log->elem_to_id = BLI_ghash_ptr_new(AT);
+
+ /* Assign IDs to all existing vertices and faces */
+ bm_log_assign_ids(bm, log);
+
+ return log;
+}
+
+/* Allocate and initialize a new BMLog using existing BMLogEntries
+ *
+ * The 'entry' should be the last entry in the BMLog. Its prev pointer
+ * will be followed back to find the first entry.
+ *
+ * The unused IDs field of the log will be initialized by taking all
+ * keys from all GHashes in the log entry.
+ */
+BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
+{
+ BMLog *log = BM_log_create(bm);
+
+ if (entry->prev)
+ log->current_entry = entry;
+ else
+ log->current_entry = NULL;
+
+ /* Let BMLog manage the entry list again */
+ log->entries.first = log->entries.last = entry;
+ if (entry) {
+ while (entry->prev) {
+ entry = entry->prev;
+ log->entries.first = entry;
+ }
+ entry = log->entries.last;
+ while (entry->next) {
+ entry = entry->next;
+ log->entries.last = entry;
+ }
+ }
+
+ for (entry = log->entries.first; entry; entry = entry->next) {
+ entry->log = log;
+
+ /* Take all used IDs */
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
+ }
+
+ return log;
+}
+
+/* Free all the data in a BMLog including the log itself */
+void BM_log_free(BMLog *log)
+{
+ BMLogEntry *entry;
+
+ if (log->unused_ids)
+ range_tree_uint_free(log->unused_ids);
+
+ if (log->id_to_elem)
+ BLI_ghash_free(log->id_to_elem, NULL, NULL);
+
+ if (log->elem_to_id)
+ BLI_ghash_free(log->elem_to_id, NULL, NULL);
+
+ /* Clear the BMLog references within each entry, but do not free
+ * the entries themselves */
+ for (entry = log->entries.first; entry; entry = entry->next)
+ entry->log = NULL;
+
+ MEM_freeN(log);
+}
+
+/* Get the number of log entries */
+int BM_log_length(const BMLog *log)
+{
+ return BLI_countlist(&log->entries);
+}
+
+/* Apply a consistent ordering to BMesh vertices */
+void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
+{
+ void *varr;
+ void *farr;
+
+ GHash *id_to_idx;
+
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ int i;
+
+ /* Put all vertex IDs into an array */
+ i = 0;
+ varr = MEM_mallocN(sizeof(int) * bm->totvert, AT);
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ ((unsigned int *)varr)[i++] = bm_log_vert_id_get(log, v);
+ }
+
+ /* Put all face IDs into an array */
+ i = 0;
+ farr = MEM_mallocN(sizeof(int) * bm->totface, AT);
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ ((unsigned int *)farr)[i++] = bm_log_face_id_get(log, f);
+ }
+
+ /* Create BMVert index remap array */
+ id_to_idx = bm_log_compress_ids_to_indices(varr, bm->totvert);
+ i = 0;
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ const unsigned id = bm_log_vert_id_get(log, v);
+ const void *key = SET_INT_IN_POINTER(id);
+ const void *val = BLI_ghash_lookup(id_to_idx, key);
+ ((int *)varr)[i++] = GET_INT_FROM_POINTER(val);
+ }
+ BLI_ghash_free(id_to_idx, NULL, NULL);
+
+ /* Create BMFace index remap array */
+ id_to_idx = bm_log_compress_ids_to_indices(farr, bm->totface);
+ i = 0;
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ const unsigned id = bm_log_face_id_get(log, f);
+ const void *key = SET_INT_IN_POINTER(id);
+ const void *val = BLI_ghash_lookup(id_to_idx, key);
+ ((int *)farr)[i++] = GET_INT_FROM_POINTER(val);
+ }
+ BLI_ghash_free(id_to_idx, NULL, NULL);
+
+ BM_mesh_remap(bm, varr, NULL, farr);
+
+ MEM_freeN(varr);
+ MEM_freeN(farr);
+}
+
+/* Start a new log entry and update the log entry list
+ *
+ * If the log entry list is empty, or if the current log entry is the
+ * last entry, the new entry is simply appended to the end.
+ *
+ * Otherwise, the new entry is added after the current entry and all
+ * following entries are deleted.
+ *
+ * In either case, the new entry is set as the current log entry.
+ */
+BMLogEntry *BM_log_entry_add(BMLog *log)
+{
+ BMLogEntry *entry, *next;
+
+ /* Delete any entries after the current one */
+ entry = log->current_entry;
+ if (entry) {
+ for (entry = entry->next; entry; entry = next) {
+ next = entry->next;
+ bm_log_entry_free(entry);
+ BLI_freelinkN(&log->entries, entry);
+ }
+ }
+
+ /* Create and append the new entry */
+ entry = bm_log_entry_create();
+ BLI_addtail(&log->entries, entry);
+ entry->log = log;
+ log->current_entry = entry;
+
+ return entry;
+}
+
+/* Remove an entry from the log
+ *
+ * Uses entry->log as the log. If the log is NULL, the entry will be
+ * free'd but not removed from any list, nor shall its IDs be
+ * released.
+ *
+ * This operation is only valid on the first and last entries in the
+ * log. Deleting from the middle will assert.
+ */
+void BM_log_entry_drop(BMLogEntry *entry)
+{
+ BMLog *log = entry->log;
+
+ if (!log) {
+ /* Unlink */
+ BLI_assert(!(entry->prev && entry->next));
+ if (entry->prev)
+ entry->prev->next = NULL;
+ else if (entry->next)
+ entry->next->prev = NULL;
+
+ bm_log_entry_free(entry);
+ MEM_freeN(entry);
+ return;
+ }
+
+ if (!entry->prev) {
+ /* Release IDs of elements that are deleted by this
+ * entry. Since the entry is at the beginning of the undo
+ * stack, and it's being deleted, those elements can never be
+ * restored. Their IDs can go back into the pool. */
+ bm_log_id_ghash_release(log, entry->deleted_faces);
+ bm_log_id_ghash_release(log, entry->deleted_verts);
+ }
+ else if (!entry->next) {
+ /* Release IDs of elements that are added by this entry. Since
+ * the entry is at the end of the undo stack, and it's being
+ * deleted, those elements can never be restored. Their IDs
+ * can go back into the pool. */
+ bm_log_id_ghash_release(log, entry->added_faces);
+ bm_log_id_ghash_release(log, entry->added_verts);
+ }
+ else {
+ BLI_assert(!"Cannot drop BMLogEntry from middle");
+ }
+
+ if (log->current_entry == entry)
+ log->current_entry = entry->prev;
+
+ bm_log_entry_free(entry);
+ BLI_freelinkN(&log->entries, entry);
+}
+
+/* Undo one BMLogEntry
+ *
+ * Has no effect if there's nothing left to undo */
+void BM_log_undo(BMesh *bm, BMLog *log)
+{
+ BMLogEntry *entry = log->current_entry;
+
+ if (entry) {
+ log->current_entry = entry->prev;
+
+ /* Delete added faces and verts */
+ bm_log_faces_unmake(bm, log, entry->added_faces);
+ bm_log_verts_unmake(bm, log, entry->added_verts);
+
+ /* Restore deleted verts and faces */
+ bm_log_verts_restore(bm, log, entry->deleted_verts);
+ bm_log_faces_restore(bm, log, entry->deleted_faces);
+
+ /* Restore vertex coordinates, mask, and hflag */
+ bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ }
+}
+
+/* Redo one BMLogEntry
+ *
+ * Has no effect if there's nothing left to redo */
+void BM_log_redo(BMesh *bm, BMLog *log)
+{
+ BMLogEntry *entry = log->current_entry;
+
+ if (!entry) {
+ /* Currently at the beginning of the undo stack, move to first entry */
+ entry = log->entries.first;
+ }
+ else if (entry && entry->next) {
+ /* Move to next undo entry */
+ entry = entry->next;
+ }
+ else {
+ /* Currently at the end of the undo stack, nothing left to redo */
+ return;
+ }
+
+ log->current_entry = entry;
+
+ if (entry) {
+ /* Re-delete previously deleted faces and verts */
+ bm_log_faces_unmake(bm, log, entry->deleted_faces);
+ bm_log_verts_unmake(bm, log, entry->deleted_verts);
+
+ /* Restore previously added verts and faces */
+ bm_log_verts_restore(bm, log, entry->added_verts);
+ bm_log_faces_restore(bm, log, entry->added_faces);
+
+ /* Restore vertex coordinates, mask, and hflag */
+ bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ }
+}
+
+/* Log a vertex before it is modified
+ *
+ * Before modifying vertex coordinates, masks, or hflags, call this
+ * function to log it's current values. This is better than logging
+ * after the coordinates have been modified, because only those
+ * vertices that are modified need to have their original values
+ * stored.
+ *
+ * Handles two separate cases:
+ *
+ * If the vertex was added in the current log entry, update the
+ * vertex in the map of added vertices.
+ *
+ * If the vertex already existed prior to the current log entry, a
+ * seperate key/value map of modified vertices is used (using the
+ * vertex's ID as the key). The values stored in that case are
+ * the vertex's original state so that an undo can restore the
+ * previous state.
+ *
+ * On undo, the current vertex state will be swapped with the stored
+ * state so that a subsequent redo operation will restore the newer
+ * vertex state.
+ */
+void BM_log_vert_before_modified(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ BMLogVert *lv;
+ unsigned int v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ /* Find or create the BMLogVert entry */
+ if ((lv = BLI_ghash_lookup(entry->added_verts, key))) {
+ bm_log_vert_bmvert_copy(bm, lv, v);
+ }
+ else if (!BLI_ghash_haskey(entry->modified_verts, key)) {
+ lv = bm_log_vert_alloc(bm, log, v);
+ BLI_ghash_insert(entry->modified_verts, key, lv);
+ }
+}
+
+/* Log a new vertex as added to the BMesh
+ *
+ * The new vertex gets a unique ID assigned. It is then added to a map
+ * of added vertices, with the key being its ID and the value
+ * containing everything needed to reconstruct that vertex.
+ */
+void BM_log_vert_added(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogVert *lv;
+ unsigned int v_id = range_tree_uint_take_any(log->unused_ids);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ bm_log_vert_id_set(log, v, v_id);
+ lv = bm_log_vert_alloc(bm, log, v);
+ BLI_ghash_insert(log->current_entry->added_verts, key, lv);
+}
+
+/* Log a new face as added to the BMesh
+ *
+ * The new face gets a unique ID assigned. It is then added to a map
+ * of added faces, with the key being its ID and the value containing
+ * everything needed to reconstruct that face.
+ */
+void BM_log_face_added(BMLog *log, BMFace *f)
+{
+ BMLogFace *lf;
+ unsigned int f_id = range_tree_uint_take_any(log->unused_ids);
+ void *key = SET_INT_IN_POINTER(f_id);
+
+ /* Only triangles are supported for now */
+ BLI_assert(f->len == 3);
+
+ bm_log_face_id_set(log, f, f_id);
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(log->current_entry->added_faces, key, lf);
+}
+
+/* Log a vertex as removed from the BMesh
+ *
+ * A couple things can happen here:
+ *
+ * If the vertex was added as part of the current log entry, then it's
+ * deleted and forgotten about entirely. Its unique ID is returned to
+ * the unused pool.
+ *
+ * If the vertex was already part of the BMesh before the current log
+ * entry, it is added to a map of deleted vertices, with the key being
+ * its ID and the value containing everything needed to reconstruct
+ * that vertex.
+ *
+ * If there's a move record for the vertex, that's used as the
+ * vertices original location, then the move record is deleted.
+ */
+void BM_log_vert_removed(BMesh *bm, BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ unsigned int v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ if (BLI_ghash_lookup(entry->added_verts, key)) {
+ BLI_ghash_remove(entry->added_verts, key, NULL, NULL);
+ range_tree_uint_release(log->unused_ids, v_id);
+ }
+ else {
+ BMLogVert *lv, *lv_mod;
+
+ lv = bm_log_vert_alloc(bm, log, v);
+ BLI_ghash_insert(entry->deleted_verts, key, lv);
+
+ /* If the vertex was modified before deletion, ensure that the
+ * original vertex values are stored */
+ if ((lv_mod = BLI_ghash_lookup(entry->modified_verts, key))) {
+ (*lv) = (*lv_mod);
+ BLI_ghash_remove(entry->modified_verts, key, NULL, NULL);
+ }
+ }
+}
+
+/* Log a face as removed from the BMesh
+ *
+ * A couple things can happen here:
+ *
+ * If the face was added as part of the current log entry, then it's
+ * deleted and forgotten about entirely. Its unique ID is returned to
+ * the unused pool.
+ *
+ * If the face was already part of the BMesh before the current log
+ * entry, it is added to a map of deleted faces, with the key being
+ * its ID and the value containing everything needed to reconstruct
+ * that face.
+ */
+void BM_log_face_removed(BMLog *log, BMFace *f)
+{
+ BMLogEntry *entry = log->current_entry;
+ unsigned int f_id = bm_log_face_id_get(log, f);
+ void *key = SET_INT_IN_POINTER(f_id);
+
+ if (BLI_ghash_lookup(entry->added_faces, key)) {
+ BLI_ghash_remove(entry->added_faces, key, NULL, NULL);
+ range_tree_uint_release(log->unused_ids, f_id);
+ }
+ else {
+ BMLogFace *lf;
+
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(entry->deleted_faces, key, lf);
+ }
+}
+
+/* Log all vertices/faces in the BMesh as added */
+void BM_log_all_added(BMesh *bm, BMLog *log)
+{
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Log all vertices as newly created */
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_added(bm, log, v);
+ }
+
+ /* Log all faces as newly created */
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ BM_log_face_added(log, f);
+ }
+}
+
+/* Log all vertices/faces in the BMesh as removed */
+void BM_log_before_all_removed(BMesh *bm, BMLog *log)
+{
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Log deletion of all faces */
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ BM_log_face_removed(log, f);
+ }
+
+ /* Log deletion of all vertices */
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_removed(bm, log, v);
+ }
+}
+
+/* Get the logged coordinates of a vertex
+ *
+ * Does not modify the log or the vertex */
+const float *BM_log_original_vert_co(BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ BLI_assert(entry);
+
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->co;
+}
+
+/* Get the logged mask of a vertex
+ *
+ * Does not modify the log or the vertex */
+float BM_log_original_mask(BMLog *log, BMVert *v)
+{
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = SET_INT_IN_POINTER(v_id);
+
+ BLI_assert(entry);
+
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->mask;
+}
+
+/************************ Debugging and Testing ***********************/
+
+/* For internal use only (unit testing) */
+BMLogEntry *BM_log_current_entry(BMLog *log)
+{
+ return log->current_entry;
+}
+
+/* For internal use only (unit testing) */
+RangeTreeUInt *BM_log_unused_ids(BMLog *log)
+{
+ return log->unused_ids;
+}
+
+#if 0
+/* Print the list of entries, marking the current one
+ *
+ * Keep around for debugging */
+void bm_log_print(const BMLog *log, const char *description)
+{
+ const BMLogEntry *entry;
+ const char *current = " <-- current";
+ int i;
+
+ printf("%s:\n", description);
+ printf(" % 2d: [ initial ]%s\n", 0,
+ (!log->current_entry) ? current : "");
+ for (entry = log->entries.first, i = 1; entry; entry = entry->next, i++) {
+ printf(" % 2d: [%p]%s\n", i, entry,
+ (entry == log->current_entry) ? current : "");
+ }
+}
+#endif
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
new file mode 100644
index 0000000..958ff34
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -0,0 +1,102 @@
+/*
+ * ***** 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 LICENSE BLOCK *****
+ */
+
+#ifndef __BMESH_LOG_H__
+#define __BMESH_LOG_H__
+
+/* The BMLog is an interface for storing undo/redo steps as a BMesh is
+ * modified. It only stores changes to the BMesh, not full copies.
+ *
+ * Currently it supports the following types of changes:
+ *
+ * - Adding and removing vertices
+ * - Adding and removing faces
+ * - Moving vertices
+ * - Setting vertex paint-mask values
+ * - Setting vertex hflags
+ */
+
+struct BMFace;
+struct BMVert;
+struct BMesh;
+struct RangeTreeUInt;
+
+typedef struct BMLog BMLog;
+typedef struct BMLogEntry BMLogEntry;
+
+/* Allocate and initialize a new BMLog */
+BMLog *BM_log_create(BMesh *bm);
+
+/* Allocate and initialize a new BMLog using existing BMLogEntries */
+BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry);
+
+/* Free all the data in a BMLog including the log itself */
+void BM_log_free(BMLog *log);
+
+/* Get the number of log entries */
+int BM_log_length(const BMLog *log);
+
+/* Apply a consistent ordering to BMesh vertices and faces */
+void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log);
+
+/* Start a new log entry and update the log entry list */
+BMLogEntry *BM_log_entry_add(BMLog *log);
+
+/* Remove an entry from the log */
+void BM_log_entry_drop(BMLogEntry *entry);
+
+/* Undo one BMLogEntry */
+void BM_log_undo(BMesh *bm, BMLog *log);
+
+/* Redo one BMLogEntry */
+void BM_log_redo(BMesh *bm, BMLog *log);
+
+/* Log a vertex before it is modified */
+void BM_log_vert_before_modified(BMesh *bm, BMLog *log, struct BMVert *v);
+
+/* Log a new vertex as added to the BMesh */
+void BM_log_vert_added(BMesh *bm, BMLog *log, struct BMVert *v);
+
+/* Log a new face as added to the BMesh */
+void BM_log_face_added(BMLog *log, struct BMFace *f);
+
+/* Log a vertex as removed from the BMesh */
+void BM_log_vert_removed(BMesh *bm, BMLog *log, struct BMVert *v);
+
+/* Log a face as removed from the BMesh */
+void BM_log_face_removed(BMLog *log, struct BMFace *f);
+
+/* Log all vertices/faces in the BMesh as added */
+void BM_log_all_added(BMesh *bm, BMLog *log);
+
+/* Log all vertices/faces in the BMesh as removed */
+void BM_log_before_all_removed(BMesh *bm, BMLog *log);
+
+/* Get the logged coordinates of a vertex */
+const float *BM_log_original_vert_co(BMLog *log, BMVert *v);
+
+/* Get the logged mask of a vertex */
+float BM_log_original_mask(BMLog *log, BMVert *v);
+
+/* For internal use only (unit testing) */
+BMLogEntry *BM_log_current_entry(BMLog *log);
+struct RangeTreeUInt *BM_log_unused_ids(BMLog *log);
+
+#endif
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 9af65d7..669be31 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -44,8 +44,6 @@
static void recount_totsels(BMesh *bm)
{
- BMIter iter;
- BMElem *ele;
const char iter_types[3] = {BM_VERTS_OF_MESH,
BM_EDGES_OF_MESH,
BM_FACES_OF_MESH};
@@ -58,11 +56,16 @@ static void recount_totsels(BMesh *bm)
tots[1] = &bm->totedgesel;
tots[2] = &bm->totfacesel;
+#pragma omp parallel for schedule(dynamic)
for (i = 0; i < 3; i++) {
- ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) *tots[i] += 1;
+ BMIter iter;
+ BMElem *ele;
+ int count = 0;
+
+ BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) count += 1;
}
+ *tots[i] = count;
}
}
@@ -83,41 +86,50 @@ void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode)
BMIter eiter;
BMIter fiter;
- int ok;
-
if (selectmode & SCE_SELECT_VERTEX) {
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ /* both loops only set edge/face flags and read off verts */
+#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
{
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
- }
- else {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ }
+ else {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ }
}
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+#pragma omp section
+ {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ int ok = TRUE;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = FALSE;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
ok = FALSE;
- break;
}
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = FALSE;
- }
- BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
+ BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
+ }
+ }
}
+ /* end sections */
}
else if (selectmode & SCE_SELECT_EDGE) {
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
+ int ok = TRUE;
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
@@ -161,34 +173,45 @@ void BM_mesh_deselect_flush(BMesh *bm)
int ok;
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+ /* we can use 2 sections here because the second loop isnt checking edge selection */
+#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
{
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+ {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ }
}
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+#pragma omp section
+ {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ ok = TRUE;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = FALSE;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
ok = FALSE;
- break;
}
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = FALSE;
- }
- if (ok == FALSE) {
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ if (ok == FALSE) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ }
+ }
}
}
+ /* end sections */
/* Remove any deselected elements from the BMEditSelection */
BM_select_history_validate(bm);
@@ -212,32 +235,42 @@ void BM_mesh_select_flush(BMesh *bm)
int ok;
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ /* we can use 2 sections here because the second loop isnt checking edge selection */
+#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
{
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ }
+ }
}
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = TRUE;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+#pragma omp section
+ {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ ok = TRUE;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = FALSE;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
ok = FALSE;
- break;
}
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = FALSE;
- }
- if (ok) {
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ if (ok) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ }
+ }
}
}
@@ -810,8 +843,6 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
- BMIter iter;
- BMElem *ele;
int i;
if (hflag & BM_ELEM_SELECT) {
@@ -825,16 +856,25 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
{
/* fast path for deselect all, avoid topology loops
* since we know all will be de-selected anyway. */
+
+#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
for ( ; ele; ele = BM_iter_step(&iter)) {
BM_elem_flag_disable(ele, BM_ELEM_SELECT);
}
}
+
bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
}
else {
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
if (htype & flag_types[i]) {
ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
for ( ; ele; ele = BM_iter_step(&iter)) {
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 590edc4..769ede0 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -63,40 +63,62 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize)
void BM_mesh_elem_toolflags_ensure(BMesh *bm)
{
- if (bm->toolflagpool == NULL) {
- const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface);
- BLI_mempool *toolflagpool;
-
- BMIter iter;
- BMElemF *ele;
- const char iter_types[3] = {BM_VERTS_OF_MESH,
- BM_EDGES_OF_MESH,
- BM_FACES_OF_MESH};
-
- int i;
-
- BLI_assert(bm->totflags == 0);
-
- /* allocate one flag pool that we don't get rid of. */
- toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0);
-
+ if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) {
+ return;
+ }
- for (i = 0; i < 3; i++) {
- BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totvert), 512, 0);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0);
+
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ BLI_mempool *toolflagpool = bm->vtoolflagpool;
+ BMIter iter;
+ BMElemF *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ ele->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+ }
+#pragma omp section
+ {
+ BLI_mempool *toolflagpool = bm->etoolflagpool;
+ BMIter iter;
+ BMElemF *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ ele->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+ }
+#pragma omp section
+ {
+ BLI_mempool *toolflagpool = bm->ftoolflagpool;
+ BMIter iter;
+ BMElemF *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
ele->oflags = BLI_mempool_calloc(toolflagpool);
}
}
-
- bm->toolflagpool = toolflagpool;
- bm->totflags = 1;
}
+
+
+ bm->totflags = 1;
}
void BM_mesh_elem_toolflags_clear(BMesh *bm)
{
- if (bm->toolflagpool) {
- BLI_mempool_destroy(bm->toolflagpool);
- bm->toolflagpool = NULL;
+ if (bm->vtoolflagpool) {
+ BLI_mempool_destroy(bm->vtoolflagpool);
+ bm->vtoolflagpool = NULL;
+ }
+ if (bm->etoolflagpool) {
+ BLI_mempool_destroy(bm->etoolflagpool);
+ bm->etoolflagpool = NULL;
+ }
+ if (bm->ftoolflagpool) {
+ BLI_mempool_destroy(bm->ftoolflagpool);
+ bm->ftoolflagpool = NULL;
}
}
@@ -439,57 +461,71 @@ void bmesh_edit_end(BMesh *bm, int UNUSED(flag))
void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag)
{
- BMIter iter;
- BMElem *ele;
-
#ifdef DEBUG
BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__);
#endif
- if (hflag & BM_VERT) {
- if (bm->elem_index_dirty & BM_VERT) {
- int index = 0;
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ if (hflag & BM_VERT) {
+ if (bm->elem_index_dirty & BM_VERT) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, index) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+ BLI_assert(index == bm->totvert);
+ }
+ else {
+ // printf("%s: skipping vert index calc!\n", __func__);
+ }
}
- bm->elem_index_dirty &= ~BM_VERT;
- BLI_assert(index == bm->totvert);
- }
- else {
- // printf("%s: skipping vert index calc!\n", __func__);
}
- }
- if (hflag & BM_EDGE) {
- if (bm->elem_index_dirty & BM_EDGE) {
- int index = 0;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
+#pragma omp section
+ {
+ if (hflag & BM_EDGE) {
+ if (bm->elem_index_dirty & BM_EDGE) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, index) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+ BLI_assert(index == bm->totedge);
+ }
+ else {
+ // printf("%s: skipping edge index calc!\n", __func__);
+ }
}
- bm->elem_index_dirty &= ~BM_EDGE;
- BLI_assert(index == bm->totedge);
- }
- else {
- // printf("%s: skipping edge index calc!\n", __func__);
}
- }
- if (hflag & BM_FACE) {
- if (bm->elem_index_dirty & BM_FACE) {
- int index = 0;
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
+#pragma omp section
+ {
+ if (hflag & BM_FACE) {
+ if (bm->elem_index_dirty & BM_FACE) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, index) {
+ BM_elem_index_set(ele, index); /* set_ok */
+ }
+ BLI_assert(index == bm->totface);
+ }
+ else {
+ // printf("%s: skipping face index calc!\n", __func__);
+ }
}
- bm->elem_index_dirty &= ~BM_FACE;
- BLI_assert(index == bm->totface);
- }
- else {
- // printf("%s: skipping face index calc!\n", __func__);
}
}
+
+ bm->elem_index_dirty &= ~hflag;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 388d148..8198e30 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -98,6 +98,70 @@
#include "bmesh.h"
#include "intern/bmesh_private.h" /* for element checking */
+void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
+{
+ const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
+ BM_mesh_cd_flag_apply(bm, cd_flag_all);
+ if (mesh) {
+ mesh->cd_flag = cd_flag_all;
+ }
+}
+
+void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
+{
+ /* CustomData_bmesh_init_pool() must run first */
+ BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
+ BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
+
+ if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_CREASE);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_free(bm, &bm->edata, CD_CREASE);
+ }
+ }
+}
+
+char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
+{
+ char cd_flag = 0;
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+ return cd_flag;
+}
+
/* Mesh -> BMesh */
void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
{
@@ -116,6 +180,10 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
int *keyi;
int totuv, i, j;
+ int cd_vert_bweight_offset;
+ int cd_edge_bweight_offset;
+ int cd_edge_crease_offset;
+
/* free custom data */
/* this isnt needed in most cases but do just incase */
CustomData_free(&bm->vdata, bm->totvert);
@@ -152,15 +220,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
}
- if (!CustomData_has_layer(&bm->edata, CD_CREASE))
- CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0);
-
- if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT))
- CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
-
- if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT))
- CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
-
if ((act_key_nr != 0) && (me->key != NULL)) {
actkey = BLI_findlink(&me->key->block, act_key_nr - 1);
}
@@ -205,6 +264,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
+ BM_mesh_cd_flag_apply(bm, me->cd_flag);
+
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
@@ -221,9 +286,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
normal_short_to_float_v3(v->no, mvert->no);
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
+ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
+ if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
/* set shapekey data */
if (me->key) {
@@ -267,10 +332,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data);
+ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
+
+ if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
+ if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f);
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f);
}
bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
@@ -338,11 +404,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
j = 0;
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) {
/* Save index of correspsonding MLoop */
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data);
+ CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data, true);
}
/* Copy Custom Data */
- CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data);
+ CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
}
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
@@ -496,6 +562,10 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
BMIter iter, liter;
int i, j, ototvert;
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
ototvert = me->totvert;
/* new vertex block */
@@ -555,10 +625,6 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT);
-
- mvert->bweight = bweight ? (char)((*bweight) * 255) : 0;
-
copy_v3_v3(mvert->co, v->co);
normal_float_to_short_v3(mvert->no, v->no);
@@ -569,6 +635,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
/* copy over customdat */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
+ if (cd_vert_bweight_offset != -1) mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
+
i++;
mvert++;
@@ -579,13 +647,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
med = medge;
i = 0;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
- float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
-
med->v1 = BM_elem_index_get(e->v1);
med->v2 = BM_elem_index_get(e->v2);
- med->crease = crease ? (char)((*crease) * 255) : 0;
- med->bweight = bweight ? (char)((*bweight) * 255) : 0;
med->flag = BM_edge_flag_to_mflag(e);
@@ -596,6 +659,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
bmesh_quick_edgedraw_flag(med, e);
+ if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
+ if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
+
i++;
med++;
BM_CHECK_ELEMENT(e);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index f9c5158..55ac39c 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -34,6 +34,10 @@
struct Mesh;
+void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag);
+void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag);
+char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
+
void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, int set_key, int act_key_nr);
void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, int dotess);
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 8951606..9a99d5b 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -152,14 +152,14 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
return TRUE;
}
else if (keepedge == NULL && len == 2) {
- /* collapse the verte */
+ /* collapse the vertex */
e = BM_vert_collapse_faces(bm, v->e, v, 1.0, TRUE, TRUE);
if (!e) {
return FALSE;
}
- /* handle two-valenc */
+ /* handle two-valence */
f = e->l->f;
f2 = e->l->radial_next->f;
@@ -205,12 +205,12 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
return FALSE;
}
- /* get remaining two face */
+ /* get remaining two faces */
f = e->l->f;
f2 = e->l->radial_next->f;
if (f != f2) {
- /* join two remaining face */
+ /* join two remaining faces */
if (!BM_faces_join_pair(bm, f, f2, e, TRUE)) {
return FALSE;
}
@@ -343,7 +343,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
BLI_assert(v1 != v2);
- /* do we have a multires layer */
+ /* do we have a multires layer? */
if (has_mdisp) {
of = BM_face_copy(bm, f, FALSE, FALSE);
}
@@ -641,7 +641,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
BMFace **oldfaces = NULL;
BMEdge *e_dummy;
BLI_array_staticdeclare(oldfaces, 32);
- SmallHash hash;
const int do_mdisp = (e->l && CustomData_has_layer(&bm->ldata, CD_MDISPS));
/* we need this for handling multi-res */
@@ -649,7 +648,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
r_e = &e_dummy;
}
- /* do we have a multi-res layer */
+ /* do we have a multi-res layer? */
if (do_mdisp) {
BMLoop *l;
int i;
@@ -660,12 +659,11 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
l = l->radial_next;
} while (l != e->l);
- /* create a hash so we can differentiate oldfaces from new face */
- BLI_smallhash_init(&hash);
-
+ /* flag existing faces so we can differentiate oldfaces from new faces */
for (i = 0; i < BLI_array_count(oldfaces); i++) {
+ BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
oldfaces[i] = BM_face_copy(bm, oldfaces[i], TRUE, TRUE);
- BLI_smallhash_insert(&hash, (intptr_t)oldfaces[i], NULL);
+ BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP);
}
}
@@ -689,7 +687,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
if (do_mdisp) {
int i, j;
- /* interpolate new/changed loop data from copied old face */
+ /* interpolate new/changed loop data from copied old faces */
for (j = 0; j < 2; j++) {
for (i = 0; i < BLI_array_count(oldfaces); i++) {
BMEdge *e1 = j ? *r_e : e;
@@ -703,7 +701,8 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
}
do {
- if (!BLI_smallhash_haskey(&hash, (intptr_t)l->f)) {
+ /* check this is an old face */
+ if (BM_ELEM_API_FLAG_TEST(l->f, _FLAG_OVERLAP)) {
BMLoop *l2_first;
l2 = l2_first = BM_FACE_FIRST_LOOP(l->f);
@@ -716,7 +715,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
}
}
- /* destroy the old face */
+ /* destroy the old faces */
for (i = 0; i < BLI_array_count(oldfaces); i++) {
BM_face_verts_kill(bm, oldfaces[i]);
}
@@ -741,7 +740,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
#endif
BLI_array_free(oldfaces);
- BLI_smallhash_release(&hash);
}
return nv;
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 58c6e05..8461ec6 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -128,7 +128,7 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = {
"smooth_laplacian_vert",
/* slots_in */
{{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"lambda", BMO_OP_SLOT_FLT}, /* lambda param */
+ {"lambda_factor", BMO_OP_SLOT_FLT}, /* lambda param */
{"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */
{"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */
{"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */
@@ -339,7 +339,7 @@ static BMOpDefine bmo_automerge_def = {
static BMOpDefine bmo_collapse_def = {
"collapse",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -374,7 +374,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = {
static BMOpDefine bmo_average_vert_facedata_def = {
"average_vert_facedata",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -390,7 +390,7 @@ static BMOpDefine bmo_average_vert_facedata_def = {
static BMOpDefine bmo_pointmerge_def = {
"pointmerge",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{"merge_co", BMO_OP_SLOT_VEC},
{{'\0'}},
},
@@ -407,7 +407,7 @@ static BMOpDefine bmo_pointmerge_def = {
static BMOpDefine bmo_collapse_uvs_def = {
"collapse_uvs",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -513,7 +513,7 @@ static BMOpDefine bmo_contextual_create_def = {
static BMOpDefine bmo_bridge_loops_def = {
"bridge_loops",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{"use_merge", BMO_OP_SLOT_BOOL},
{"merge_factor", BMO_OP_SLOT_FLT},
{{'\0'}},
@@ -534,7 +534,7 @@ static BMOpDefine bmo_bridge_loops_def = {
static BMOpDefine bmo_edgenet_fill_def = {
"edgenet_fill",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
/* restricts edges to groups. maps edges to integer */
{"restrict", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}},
{"use_restrict", BMO_OP_SLOT_BOOL},
@@ -547,7 +547,7 @@ static BMOpDefine bmo_edgenet_fill_def = {
/* slots_out */
/* maps new faces to the group numbers they came from */
{{"face_groupmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new face */
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
{{'\0'}},
},
bmo_edgenet_fill_exec,
@@ -962,7 +962,7 @@ static BMOpDefine bmo_subdivide_edges_def = {
{/* these next three can have multiple types of elements in them */
{"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
{{'\0'}},
},
bmo_subdivide_edges_exec,
@@ -1403,6 +1403,7 @@ static BMOpDefine bmo_bevel_def = {
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
{"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
{"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */
+ {"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */
{{'\0'}},
},
/* slots_out */
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 7df9c94..b8fbfbe 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -435,7 +435,7 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_
* //whether it's a float, pointer, whatever.
* //
* // so to get a pointer, for example, use:
- * // *((void**)BMO_iter_map_value(&oiter));
+ * // *((void **)BMO_iter_map_value(&oiter));
* //or something like that.
* }
* \endcode
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 5e51f5a..fbf51b7 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -599,6 +599,7 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty
BMElemF *ele;
int i;
+#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
for (i = 0; i < 3; i++) {
if (htype & flag_types[i]) {
BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
@@ -1159,100 +1160,161 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
*/
static void bmo_flag_layer_alloc(BMesh *bm)
{
- BMElemF *ele;
/* set the index values since we are looping over all data anyway,
* may save time later on */
- int i;
- BMIter iter;
- BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */
- BLI_mempool *newpool;
- void *oldflags;
+ BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */
+ BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */
+ BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */
/* store memcpy size for reuse */
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
- BLI_assert(oldpool != NULL);
-
bm->totflags++;
- /* allocate new flag poo */
- bm->toolflagpool = newpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, 512, 512, 0);
-
- /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totvert), 512, 0);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totedge), 512, 0);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totface), 512, 0);
+
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->vtoolflagpool;
+
+ /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->etoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->ftoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
}
+ BLI_mempool_destroy(voldpool);
+ BLI_mempool_destroy(eoldpool);
+ BLI_mempool_destroy(foldpool);
+
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
- BLI_mempool_destroy(oldpool);
+
}
static void bmo_flag_layer_free(BMesh *bm)
{
- BMElemF *ele;
/* set the index values since we are looping over all data anyway,
* may save time later on */
- int i;
- BMIter iter;
- BLI_mempool *oldpool = bm->toolflagpool;
- BLI_mempool *newpool;
- void *oldflags;
-
+ BLI_mempool *voldpool = bm->vtoolflagpool;
+ BLI_mempool *eoldpool = bm->etoolflagpool;
+ BLI_mempool *foldpool = bm->ftoolflagpool;
+
/* store memcpy size for reuse */
const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer));
/* de-increment the totflags first.. */
bm->totflags--;
- /* allocate new flag poo */
- bm->toolflagpool = newpool = BLI_mempool_create(new_totflags_size, 512, 512, 0);
-
- /* now go through and memcpy all the flag */
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- oldflags = ele->oflags;
- ele->oflags = BLI_mempool_calloc(newpool);
- memcpy(ele->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(ele, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+
+ bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, 0);
+ bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, 0);
+ bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, 0);
+
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->vtoolflagpool;
+
+ /* now go through and memcpy all the flag */
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->etoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
+#pragma omp section
+ {
+ BMIter iter;
+ BMElemF *ele;
+ int i;
+
+ BLI_mempool *newpool = bm->ftoolflagpool;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ void *oldflags = ele->oflags;
+ ele->oflags = BLI_mempool_calloc(newpool);
+ memcpy(ele->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
+ }
+ }
}
- bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
+ BLI_mempool_destroy(voldpool);
+ BLI_mempool_destroy(eoldpool);
+ BLI_mempool_destroy(foldpool);
- BLI_mempool_destroy(oldpool);
+ bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
static void bmo_flag_layer_clear(BMesh *bm)
@@ -1261,22 +1323,35 @@ static void bmo_flag_layer_clear(BMesh *bm)
/* set the index values since we are looping over all data anyway,
* may save time later on */
int i;
+ const BMFlagLayer zero_flag = {0};
BMIter iter;
const int totflags_offset = bm->totflags - 1;
- /* now go through and memcpy all the flag */
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
- BM_elem_index_set(ele, i); /* set_inline */
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
- BM_elem_index_set(ele, i); /* set_inline */
- }
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
- BM_elem_index_set(ele, i); /* set_inline */
+#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT)
+ {
+ /* now go through and memcpy all the flag */
+#pragma omp section
+ {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(ele, i); /* set_inline */
+ }
+ }
+#pragma omp section
+ {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(ele, i); /* set_inline */
+ }
+ }
+#pragma omp section
+ {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(ele, i); /* set_inline */
+ }
+ }
}
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
@@ -1364,7 +1439,7 @@ void *BMO_iter_step(BMOIter *iter)
return NULL;
}
-/* used for iterating over mapping */
+/* used for iterating over mappings */
void *BMO_iter_map_value(BMOIter *iter)
{
return iter->val;
@@ -1380,7 +1455,7 @@ float BMO_iter_map_value_f(BMOIter *iter)
return *((float *)iter->val);
}
-/* error syste */
+/* error system */
typedef struct BMOpError {
struct BMOpError *next, *prev;
int errorcode;
@@ -1562,7 +1637,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
goto error; \
} (void)0
- /* we muck around in here, so dup i */
+ /* we muck around in here, so dup it */
fmt = ofmt = BLI_strdup(_fmt);
/* find operator name */
@@ -1589,11 +1664,11 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
while (*fmt) {
if (state) {
- /* jump past leading whitespac */
+ /* jump past leading whitespace */
i = strspn(fmt, " ");
fmt += i;
- /* ignore trailing whitespac */
+ /* ignore trailing whitespace */
if (!fmt[i])
break;
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 2e04718..4545c9b 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -157,13 +157,10 @@ float BM_face_calc_area(BMFace *f)
{
BMLoop *l;
BMIter iter;
- float (*verts)[3];
- float normal[3];
+ float (*verts)[3] = BLI_array_alloca(verts, f->len);
float area;
int i;
- BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
-
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
copy_v3_v3(verts[i], l->v->co);
}
@@ -175,12 +172,11 @@ float BM_face_calc_area(BMFace *f)
area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]);
}
else {
+ float normal[3];
calc_poly_normal(normal, verts, f->len);
area = area_poly_v3(f->len, verts, normal);
}
- BLI_array_fixedstack_free(verts);
-
return area;
}
@@ -855,8 +851,8 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const s
BMLoop *newl;
BMLoop *l_iter;
BMLoop *l_first;
- float *abscoss = NULL;
- BLI_array_fixedstack_declare(abscoss, 16, f->len, "BM_face_triangulate: temp absolute cosines of face corners");
+ /* BM_face_triangulate: temp absolute cosines of face corners */
+ float *abscoss = BLI_array_alloca(abscoss, f->len);
/* copy vertex coordinates to vertspace area */
i = 0;
@@ -940,11 +936,10 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const s
}
#endif
- BLI_array_fixedstack_free(abscoss);
-
/* NULL-terminate */
- if (newfaces)
+ if (newfaces) {
newfaces[nf_i] = NULL;
+ }
}
/**
@@ -961,13 +956,10 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
BMLoop *l;
float v1[3], v2[3], v3[3] /*, v4[3 */, no[3], mid[3], *p1, *p2, *p3, *p4;
float out[3] = {-FLT_MAX, -FLT_MAX, 0.0f};
- float (*projverts)[3];
- float (*edgeverts)[3];
+ float (*projverts)[3] = BLI_array_alloca(projverts, f->len);
+ float (*edgeverts)[3] = BLI_array_alloca(edgeverts, len * 2);
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
int i, j, a = 0, clen;
-
- BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb");
- BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
i = 0;
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
@@ -1042,7 +1034,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
}
}
- /* do line crossing test */
+ /* do line crossing tests */
for (i = 0; i < f->len; i++) {
p1 = projverts[i];
p2 = projverts[(i + 1) % f->len];
@@ -1085,7 +1077,4 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
}
}
}
-
- BLI_array_fixedstack_free(projverts);
- BLI_array_fixedstack_free(edgeverts);
}
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 195c60c..b5b6c69 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -468,7 +468,7 @@ BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
}
/**
- * Returms edge length
+ * Returns edge length
*/
float BM_edge_calc_length(BMEdge *e)
{
@@ -476,6 +476,14 @@ float BM_edge_calc_length(BMEdge *e)
}
/**
+ * Returns edge length squared (for comparisons)
+ */
+float BM_edge_calc_length_squared(BMEdge *e)
+{
+ return len_squared_v3v3(e->v1->co, e->v2->co);
+}
+
+/**
* Utility function, since enough times we have an edge
* and want to access 2 connected faces.
*
@@ -1113,6 +1121,40 @@ float BM_vert_calc_shell_factor(BMVert *v)
return 1.0f;
}
}
+/* alternate version of #BM_vert_calc_shell_factor which only
+ * uses 'hflag' faces, but falls back to all if none found. */
+float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag)
+{
+ BMIter iter;
+ BMLoop *l;
+ float accum_shell = 0.0f;
+ float accum_angle = 0.0f;
+ int tot_sel = 0, tot = 0;
+
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */
+ const float face_angle = BM_loop_calc_face_angle(l);
+ accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
+ accum_angle += face_angle;
+ tot_sel++;
+ }
+ tot++;
+ }
+
+ if (accum_angle != 0.0f) {
+ return accum_shell / accum_angle;
+ }
+ else {
+ /* other main difference from BM_vert_calc_shell_factor! */
+ if (tot != 0 && tot_sel == 0) {
+ /* none selected, so use all */
+ return BM_vert_calc_shell_factor(v);
+ }
+ else {
+ return 1.0f;
+ }
+ }
+}
/**
* \note quite an obscure function.
@@ -1415,8 +1457,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
/* same as 'BM_face_exists_multi' but built vert array from edges */
int BM_face_exists_multi_edge(BMEdge **earr, int len)
{
- BMVert **varr;
- BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
+ BMVert **varr = BLI_array_alloca(varr, len);
int ok;
int i, i_next;
@@ -1432,14 +1473,11 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len)
if (ok == FALSE) {
BMESH_ASSERT(0);
- BLI_array_fixedstack_free(varr);
return FALSE;
}
ok = BM_face_exists_multi(varr, earr, len);
- BLI_array_fixedstack_free(varr);
-
return ok;
}
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 7a18f69..a9d6719 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -37,6 +37,7 @@ int BM_vert_in_edge(BMEdge *e, BMVert *v);
int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
float BM_edge_calc_length(BMEdge *e);
+float BM_edge_calc_length_squared(BMEdge *e);
int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb);
int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb);
BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v);
@@ -69,6 +70,7 @@ void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3])
float BM_vert_calc_edge_angle(BMVert *v);
float BM_vert_calc_shell_factor(BMVert *v);
+float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag);
float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
BMLoop *BM_face_find_shortest_loop(BMFace *f);
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index bb013e6..538a905 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -403,6 +403,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
continue;
}
+ /* saves checking BLI_ghash_haskey below (manifold edges theres a 50% chance) */
+ if (f == iwalk->cur) {
+ continue;
+ }
+
if (BLI_ghash_haskey(walker->visithash, f)) {
continue;
}
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 126d0f4..eb8e84d 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -34,6 +34,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
{
const float offset = BMO_slot_float_get(op->slots_in, "offset");
const int seg = BMO_slot_int_get(op->slots_in, "segments");
+ const int vonly = BMO_slot_bool_get(op->slots_in, "vertex_only");
if (offset > 0) {
BMOIter siter;
@@ -54,7 +55,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
}
}
- BM_mesh_bevel(bm, offset, seg);
+ BM_mesh_bevel(bm, offset, seg, vonly);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index aa69806..2ea5914 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -578,7 +578,7 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
//rotsys_fill_faces(bm, edata, vdata);
#if 0
- /* create visualizing geometr */
+ /* create visualizing geometry */
BMVert *lastv;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BMVert *v2;
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 9a58d7a..f288901 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -483,7 +483,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
{
BMOperator dupop, extop;
float cent[3], dvec[3];
- float axis[3] = {0.0f, 0.0f, 1.0f};
+ float axis[3];
float rmat[3][3];
float phi;
int steps, do_dupli, a, usedvec;
diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c
index 9e9e4b8..b4b50a6 100644
--- a/source/blender/bmesh/operators/bmo_edgesplit.c
+++ b/source/blender/bmesh/operators/bmo_edgesplit.c
@@ -22,152 +22,32 @@
/** \file blender/bmesh/operators/bmo_edgesplit.c
* \ingroup bmesh
+ *
+ * Just a wrapper around #BM_mesh_edgesplit
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "bmesh.h"
+#include "tools/bmesh_edgesplit.h"
#include "intern/bmesh_operators_private.h" /* own include */
-enum {
- EDGE_SEAM = 1
-};
-
-enum {
- VERT_SEAM = 2
-};
-
-/**
- * Remove the EDGE_SEAM flag for edges we cant split
- *
- * un-tag edges not connected to other tagged edges,
- * unless they are on a boundary
- */
-static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op)
-{
- BMOIter siter;
- BMIter iter;
- BMEdge *e;
-
- unsigned char *vtouch;
- unsigned char *vt;
-
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
- vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
-
- /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-
- /* unrelated to flag assignment in this function - since this is the
- * only place we loop over all edges, disable tag */
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
-
- if (e->l == NULL) {
- BMO_elem_flag_disable(bm, e, EDGE_SEAM);
- }
- else if (BM_edge_is_boundary(e)) {
- vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
- vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
-
- /* while the boundary verts need to be tagged,
- * the edge its self can't be split */
- BMO_elem_flag_disable(bm, e, EDGE_SEAM);
- }
- }
-
- /* single marked edges unconnected to any other marked edges
- * are illegal, go through and unmark them */
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- /* lame, but we don't want the count to exceed 255,
- * so just count to 2, its all we need */
- unsigned char *vt;
- vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
- vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
- }
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
- vtouch[BM_elem_index_get(e->v2)] == 1)
- {
- BMO_elem_flag_disable(bm, e, EDGE_SEAM);
- }
- }
-
- MEM_freeN(vtouch);
-}
/* keep this operator fast, its used in a modifier */
void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
{
- BMOIter siter;
- BMEdge *e;
const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_SEAM);
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "edges", BM_EDGE, BM_ELEM_TAG, FALSE);
if (use_verts) {
/* this slows down the operation but its ok because the modifier doesn't use */
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_SEAM);
-
- /* prevent one edge having both verts unflagged
- * we could alternately disable these edges, either way its a corner case.
- *
- * This is needed so we don't split off the edge but then none of its verts which
- * would leave a duplicate edge.
- */
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (UNLIKELY((BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE &&
- (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE))))
- {
- BMO_elem_flag_enable(bm, e->v1, VERT_SEAM);
- BMO_elem_flag_enable(bm, e->v2, VERT_SEAM);
- }
- }
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "verts", BM_VERT, BM_ELEM_TAG, FALSE);
}
- bm_edgesplit_validate_seams(bm, op);
-
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
- /* this flag gets copied so we can be sure duplicate edges get it too (important) */
- BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
-
- /* keep splitting until each loop has its own edge */
- do {
- bmesh_edge_separate(bm, e, e->l);
- } while (!BM_edge_is_boundary(e));
-
- BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
- }
- }
-
- if (use_verts) {
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE) {
- BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
- }
- if (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE) {
- BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
- }
- }
- }
-
- BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
- if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
- BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
- bmesh_vert_separate(bm, e->v1, NULL, NULL);
- }
- if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
- BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
- bmesh_vert_separate(bm, e->v2, NULL, NULL);
- }
- }
- }
+ /* this is where everything happens */
+ BM_mesh_edgesplit(bm, use_verts, TRUE);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 065a1b5..2cca3fc 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -51,28 +51,35 @@ enum {
void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
{
+ BMVert **verts = NULL;
+ BLI_array_declare(verts);
+ BMEdge **edges = NULL;
+ BLI_array_declare(edges);
+
BMOIter siter;
BMIter liter, liter2;
BMFace *f, *f2, *f3;
BMLoop *l, *l2, *l3, *l4, *l_tmp;
- BMEdge **edges = NULL, *e, *laste;
+ BMEdge *e, *laste;
BMVert *v, *lastv, *firstv;
- BLI_array_declare(edges);
int i;
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
+ BLI_array_empty(verts);
BLI_array_empty(edges);
+ BLI_array_grow_items(verts, f->len);
BLI_array_grow_items(edges, f->len);
i = 0;
firstv = lastv = NULL;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
v = BM_vert_create(bm, l->v->co, l->v, 0);
-
/* skip on the first iteration */
if (lastv) {
e = BM_edge_create(bm, lastv, v, l->e, 0);
- edges[i++] = e;
+ edges[i] = e;
+ verts[i] = lastv;
+ i++;
}
lastv = v;
@@ -82,11 +89,13 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
/* this fits in the array because we skip one in the loop above */
e = BM_edge_create(bm, v, firstv, laste, 0);
- edges[i++] = e;
+ edges[i] = e;
+ verts[i] = lastv;
+ i++;
BMO_elem_flag_enable(bm, f, EXT_DEL);
- f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, 0);
+ f2 = BM_face_create(bm, verts, edges, f->len, 0);
if (UNLIKELY(f2 == NULL)) {
BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed: could not create face");
BLI_array_free(edges);
@@ -117,6 +126,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
}
}
+ BLI_array_free(verts);
BLI_array_free(edges);
BMO_op_callf(bm, op->flag,
@@ -305,27 +315,29 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
/* calculate verts to delete */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- found = FALSE;
+ if (v->e) { /* only deal with verts attached to geometry [#33651] */
+ found = FALSE;
- BM_ITER_ELEM (e, &viter, v, BM_EDGES_OF_VERT) {
- if (!BMO_elem_flag_test(bm, e, EXT_INPUT) || !BMO_elem_flag_test(bm, e, EXT_DEL)) {
- found = TRUE;
- break;
- }
- }
-
- /* avoid an extra loop */
- if (found == TRUE) {
- BM_ITER_ELEM (f, &viter, v, BM_FACES_OF_VERT) {
- if (!BMO_elem_flag_test(bm, f, EXT_INPUT)) {
+ BM_ITER_ELEM (e, &viter, v, BM_EDGES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, e, EXT_INPUT) || !BMO_elem_flag_test(bm, e, EXT_DEL)) {
found = TRUE;
break;
}
}
- }
- if (found == FALSE) {
- BMO_elem_flag_enable(bm, v, EXT_DEL);
+ /* avoid an extra loop */
+ if (found == TRUE) {
+ BM_ITER_ELEM (f, &viter, v, BM_FACES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, f, EXT_INPUT)) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (found == FALSE) {
+ BMO_elem_flag_enable(bm, v, EXT_DEL);
+ }
}
}
@@ -600,39 +612,31 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
float *vert_accum = vert_angles + bm->totvert;
int i, index;
- /* array for passing verts to angle_poly_v3 */
- float **verts = NULL;
- BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
- /* array for receiving angles from angle_poly_v3 */
- float *face_angles = NULL;
- BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE);
-
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (!BMO_elem_flag_test(bm, f, FACE_MARK)) {
- continue;
- }
+ if (BMO_elem_flag_test(bm, f, FACE_MARK)) {
- BLI_array_grow_items(verts, f->len);
- BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
- verts[i] = l->v->co;
- }
+ /* array for passing verts to angle_poly_v3 */
+ float *face_angles = BLI_array_alloca(face_angles, f->len);
+ /* array for receiving angles from angle_poly_v3 */
+ float **verts = BLI_array_alloca(verts, f->len);
- BLI_array_grow_items(face_angles, f->len);
- angle_poly_v3(face_angles, (const float **)verts, f->len);
+ BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
+ verts[i] = l->v->co;
+ }
- i = 0;
- BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) {
- v = l->v;
- index = BM_elem_index_get(v);
- vert_accum[index] += face_angles[i];
- vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i];
- i++;
- }
+ angle_poly_v3(face_angles, (const float **)verts, f->len);
- BLI_array_empty(verts);
- BLI_array_empty(face_angles);
+ i = 0;
+ BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) {
+ v = l->v;
+ index = BM_elem_index_get(v);
+ vert_accum[index] += face_angles[i];
+ vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i];
+ i++;
+ }
+ }
}
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -643,9 +647,6 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
}
MEM_freeN(vert_angles);
-
- BLI_array_free(verts);
- BLI_array_free(face_angles);
}
void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op)
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 1e18a83..45ecdee 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -331,13 +331,13 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
}
}
- /* if l isn't NULL, we broke out of the loo */
+ /* if l isn't NULL, we broke out of the loop */
if (l) {
break;
}
}
- /* if i isn't 2, we broke out of that loo */
+ /* if i isn't 2, we broke out of that loop */
if (i != 2) {
continue;
}
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 4a367a8..ce58468 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -538,7 +538,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
int i;
int m_vertex_id;
int usex, usey, usez, preserve_volume;
- float lambda, lambda_border;
+ float lambda_factor, lambda_border;
float w;
BMOIter siter;
BMVert *v;
@@ -553,7 +553,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
memset_laplacian_system(sys, 0);
BM_mesh_elem_index_ensure(bm, BM_VERT);
- lambda = BMO_slot_float_get(op->slots_in, "lambda");
+ lambda_factor = BMO_slot_float_get(op->slots_in, "lambda_factor");
lambda_border = BMO_slot_float_get(op->slots_in, "lambda_border");
sys->min_area = 0.00001f;
usex = BMO_slot_bool_get(op->slots_in, "use_x");
@@ -592,12 +592,12 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
i = m_vertex_id;
if (sys->zerola[i] == 0) {
w = sys->vweights[i] * sys->ring_areas[i];
- sys->vweights[i] = (w == 0.0f) ? 0.0f : -lambda / (4.0f * w);
+ sys->vweights[i] = (w == 0.0f) ? 0.0f : -lambda_factor / (4.0f * w);
w = sys->vlengths[i];
sys->vlengths[i] = (w == 0.0f) ? 0.0f : -lambda_border * 2.0f / w;
if (!vert_is_boundary(v)) {
- nlMatrixAdd(i, i, 1.0f + lambda / (4.0f * sys->ring_areas[i]));
+ nlMatrixAdd(i, i, 1.0f + lambda_factor / (4.0f * sys->ring_areas[i]));
}
else {
nlMatrixAdd(i, i, 1.0f + lambda_border * 2.0f);
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index 248c726..172f0d4 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -361,6 +361,12 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
BMFace *f_new;
int i;
+ /* TODO: calling symmetrize in dynamic-topology sculpt mode
+ * frequently tries to create faces of length less than two,
+ * should investigate further */
+ if (len < 3)
+ return NULL;
+
for (i = 0; i < len; i++) {
int j = (i + 1) % len;
fe[i] = BM_edge_exists(fv[i], fv[j]);
@@ -374,6 +380,7 @@ static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
BM_elem_attrs_copy(bm, bm, example, f_new);
BM_face_select_set(bm, f_new, TRUE);
BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM);
+
return f_new;
}
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index d20d01a..663ee46 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
- BLI_scanfill_calc(&sf_ctx, 0);
+ BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_HOLES);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMFace *f = BM_face_create_quad_tri(bm,
diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c
index 3f2ca21..5e1d581 100644
--- a/source/blender/bmesh/tools/BME_bevel.c
+++ b/source/blender/bmesh/tools/BME_bevel.c
@@ -965,7 +965,7 @@ static BMesh *BME_bevel_initialize(BMesh *bm, int options,
BMIter iter;
int /* wire, */ len;
- /* tag non-manifold geometr */
+ /* tag non-manifold geometry */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG);
if (v->e) {
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 8f2de4d..a593e40 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -119,6 +119,7 @@ typedef struct BevelParams {
float offset; /* blender units to offset each side of a beveled edge */
int seg; /* number of segments in beveled edge profile */
+ int vertex_only; /* bevel vertices only */
} BevelParams;
// #pragma GCC diagnostic ignored "-Wpadded"
@@ -166,6 +167,7 @@ static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert
{
NewVert *nv = mesh_vert(vm, i, j, k);
nv->v = BM_vert_create(bm, nv->co, eg, 0);
+ BM_elem_flag_disable(nv->v, BM_ELEM_TAG);
}
static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto,
@@ -264,14 +266,16 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF
}
else {
int i;
- BMEdge **ee = NULL;
- BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__);
+ BMEdge **ee = BLI_array_alloca(ee, totv);
for (i = 0; i < totv; i++) {
ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE);
}
+#if 0
f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0);
- BLI_array_fixedstack_free(ee);
+#else
+ f = BM_face_create(bm, vert_arr, ee, totv, 0);
+#endif
}
if (facerep && f) {
int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
@@ -696,8 +700,9 @@ static void snap_to_edge_profile(EdgeHalf *e, const float va[3], const float vb[
* of a vertex on the the boundary of the beveled vertex bv->v.
* Also decide on the mesh pattern that will be used inside the boundary.
* Doesn't make the actual BMVerts */
-static void build_boundary(MemArena *mem_arena, BevVert *bv)
+static void build_boundary(BevelParams *bp, BevVert *bv)
{
+ MemArena *mem_arena = bp->mem_arena;
EdgeHalf *efirst, *e;
BoundVert *v;
VMesh *vm;
@@ -705,9 +710,13 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
const float *no;
float lastd;
- e = efirst = next_bev(bv, NULL);
vm = bv->vmesh;
+ if (bp->vertex_only)
+ e = efirst = &bv->edges[0];
+ else
+ e = efirst = next_bev(bv, NULL);
+
BLI_assert(bv->edgecount >= 2); /* since bevel edges incident to 2 faces */
if (bv->edgecount == 2 && bv->selcount == 1) {
@@ -732,7 +741,7 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
return;
}
- lastd = e->offset;
+ lastd = bp->vertex_only ? bp->offset : e->offset;
vm->boundstart = NULL;
do {
if (e->is_bev) {
@@ -1138,7 +1147,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
/* Make center ngon if odd number of segments and fully beveled */
if (ns % 2 == 1 && vm->count == bv->selcount) {
BMVert **vv = NULL;
- BLI_array_declare(vv);
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
v = vm->boundstart;
do {
@@ -1156,7 +1165,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
if (vm->count > bv->selcount) {
int j;
BMVert **vv = NULL;
- BLI_array_declare(vv);
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
v = vm->boundstart;
f = boundvert_rep_face(v);
@@ -1218,7 +1227,7 @@ static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
VMesh *vm = bv->vmesh;
BoundVert *v;
BMVert **vv = NULL;
- BLI_array_declare(vv);
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
v = vm->boundstart;
n = 0;
@@ -1274,7 +1283,7 @@ static void bevel_build_trifan(BMesh *bm, BevVert *bv)
else { BLI_assert(0); }
}
else {
- if (l_fan->v == v_fan) { l_fan = l_fan; }
+ if (l_fan->v == v_fan) { /* l_fan = l_fan; */ }
else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; }
else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; }
else { BLI_assert(0); }
@@ -1323,8 +1332,9 @@ static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
/* Given that the boundary is built, now make the actual BMVerts
* for the boundary and the interior of the vertex mesh. */
-static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
+static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
{
+ MemArena *mem_arena = bp->mem_arena;
VMesh *vm = bv->vmesh;
BoundVert *v, *weld1, *weld2;
int n, ns, ns2, i, k, weld;
@@ -1489,7 +1499,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
{
BMEdge *bme;
BevVert *bv;
- BMEdge *bme2, *unflagged_bme;
+ BMEdge *bme2, *unflagged_bme, *first_bme;
BMFace *f;
BMIter iter, iter2;
EdgeHalf *e;
@@ -1501,17 +1511,23 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
* Only bevel selected edges that have exactly two incident faces.
*/
+ if (bp->vertex_only)
+ first_bme = v->e;
+ else
+ first_bme = NULL;
BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(bme, BM_ELEM_TAG)) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
BLI_assert(BM_edge_is_manifold(bme));
nsel++;
+ if (!first_bme)
+ first_bme = bme;
}
ntot++;
BM_BEVEL_EDGE_TAG_DISABLE(bme);
}
- if (nsel == 0) {
+ if ((nsel == 0 && !bp->vertex_only) || (ntot < 3 && bp->vertex_only)) {
/* signal this vert isn't being beveled */
BM_elem_flag_disable(v, BM_ELEM_TAG);
return;
@@ -1533,7 +1549,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
/* add edges to bv->edges in order that keeps adjacent edges sharing
* a face, if possible */
i = 0;
- bme = v->e;
+
+ bme = first_bme;
BM_BEVEL_EDGE_TAG_ENABLE(bme);
e = &bv->edges[0];
e->e = bme;
@@ -1547,6 +1564,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
continue;
if (!unflagged_bme)
unflagged_bme = bme2;
+ if (!bme->l)
+ continue;
BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) {
if (BM_face_edge_share_loop(f, bme)) {
found_shared_face = 1;
@@ -1568,7 +1587,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
}
bme = e->e;
BM_BEVEL_EDGE_TAG_ENABLE(bme);
- if (BM_elem_flag_test(bme, BM_ELEM_TAG)) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
e->is_bev = TRUE;
e->seg = bp->seg;
}
@@ -1581,7 +1600,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
}
/* find wrap-around shared face */
BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
- if (BM_face_edge_share_loop(f, bv->edges[0].e)) {
+ if (bv->edges[0].e->l && BM_face_edge_share_loop(f, bv->edges[0].e)) {
if (bv->edges[0].fnext == f)
continue; /* if two shared faces, want the other one now */
bv->edges[ntot - 1].fnext = f;
@@ -1624,8 +1643,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
BM_BEVEL_EDGE_TAG_DISABLE(e->e);
}
- build_boundary(bp->mem_arena, bv);
- build_vmesh(bp->mem_arena, bm, bv);
+ build_boundary(bp, bv);
+ build_vmesh(bp, bm, bv);
}
/* Face f has at least one beveled vertex. Rebuild f */
@@ -1788,7 +1807,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
*
* \warning all tagged edges _must_ be manifold.
*/
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, const int vertex_only)
{
BMIter iter;
BMVert *v;
@@ -1797,6 +1816,7 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
bp.offset = offset;
bp.seg = segments;
+ bp.vertex_only = vertex_only;
if (bp.offset > 0) {
/* primary alloc */
@@ -1812,9 +1832,11 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
}
/* Build polygons for edges */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
- bevel_build_edge_polygons(bm, &bp, e);
+ if (!bp.vertex_only) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ bevel_build_edge_polygons(bm, &bp, e);
+ }
}
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index a80e4f3..d56aa13 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -27,6 +27,6 @@
* \ingroup bmesh
*/
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments);
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, const int vertex_only);
#endif /* __BMESH_BEVEL_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 7c054d8..794afb3 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -172,7 +172,7 @@ static int bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_c
#endif
/* use a small value rather then zero so we don't flip a face in multiple steps
- * (first making it zero area, then flipping again)*/
+ * (first making it zero area, then flipping again) */
if (dot_v3v3(cross_exist, cross_optim) <= FLT_EPSILON) {
//printf("no flip\n");
return TRUE;
@@ -441,6 +441,8 @@ static void bm_decim_triangulate_end(BMesh *bm)
static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_clear, BMVert *v_other,
const float customdata_fac)
{
+ /* disable seam check - the seam check would have to be done per layer, its not really that important */
+//#define USE_SEAM
/* these don't need to be updated, since they will get removed when the edge collapses */
BMLoop *l_clear, *l_other;
const int is_manifold = BM_edge_is_manifold(l->e);
@@ -464,7 +466,9 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
/* now we have both corners of the face 'l->f' */
for (side = 0; side < 2; side++) {
+#ifdef USE_SEAM
int is_seam = FALSE;
+#endif
void *src[2];
BMFace *f_exit = is_manifold ? l->radial_next->f : NULL;
BMEdge *e_prev = l->e;
@@ -501,34 +505,40 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
break;
}
+#ifdef USE_SEAM
/* break out unless we find a match */
is_seam = TRUE;
+#endif
/* ok. we have a loop. now be smart with it! */
for (i = 0; i < bm->ldata.totlayer; i++) {
if (CustomData_layer_has_math(&bm->ldata, i)) {
const int offset = bm->ldata.layers[i].offset;
const int type = bm->ldata.layers[i].type;
- void *cd_src, *cd_iter;
-
- /* todo, make nicer macros for this */
- cd_src = (char *)src[0] + offset;
- // cd_dst = (char *)src[1] + offset; // UNUSED
- cd_iter = (char *)l_iter->head.data + offset;
+ void *cd_src[2] = {(char *)src[0] + offset,
+ (char *)src[1] + offset};
+ void *cd_iter = (char *)l_iter->head.data + offset;;
/* detect seams */
- if (CustomData_data_equals(type, cd_src, cd_iter)) {
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_iter->head.data);
+ if (CustomData_data_equals(type, cd_src[0], cd_iter)) {
+ CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i);
+#ifdef USE_SEAM
is_seam = FALSE;
+#endif
}
}
}
+#ifdef USE_SEAM
if (is_seam) {
break;
}
+#endif
}
}
+
+//#undef USE_SEAM
+
}
#endif /* USE_CUSTOMDATA */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index acdab25..71c1ced 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -268,7 +268,7 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int
BMW_end(&walker);
#else
- BM_elem_index_set(v_first, (offset + depth) % nth ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */
+ BM_elem_index_set(v_first, ((offset + depth) % nth) ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */
vert_seek_b_tot = 0;
vert_seek_b[vert_seek_b_tot++] = v_first;
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
new file mode 100644
index 0000000..b6a8c79
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -0,0 +1,170 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_edgesplit.c
+ * \ingroup bmesh
+ *
+ * Edge-Split.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "bmesh.h"
+
+#include "bmesh_edgesplit.h" /* own include */
+
+
+/**
+ * Remove the BM_ELEM_TAG flag for edges we cant split
+ *
+ * un-tag edges not connected to other tagged edges,
+ * unless they are on a boundary
+ */
+static void bm_edgesplit_validate_seams(BMesh *bm)
+{
+ BMIter iter;
+ BMEdge *e;
+
+ unsigned char *vtouch;
+ unsigned char *vt;
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
+
+ /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+
+ /* unrelated to flag assignment in this function - since this is the
+ * only place we loop over all edges, disable tag */
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+
+ if (e->l == NULL) {
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ else if (BM_edge_is_boundary(e)) {
+ vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+ vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
+
+ /* while the boundary verts need to be tagged,
+ * the edge its self can't be split */
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
+
+ /* single marked edges unconnected to any other marked edges
+ * are illegal, go through and unmark them */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ /* lame, but we don't want the count to exceed 255,
+ * so just count to 2, its all we need */
+ unsigned char *vt;
+ vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+ vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
+ }
+ }
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
+ vtouch[BM_elem_index_get(e->v2)] == 1)
+ {
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+
+ MEM_freeN(vtouch);
+}
+
+void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only)
+{
+ BMIter iter;
+ BMEdge *e;
+
+
+ if (tag_only == FALSE) {
+ BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, FALSE);
+ }
+
+ if (use_verts) {
+ /* prevent one edge having both verts unflagged
+ * we could alternately disable these edges, either way its a corner case.
+ *
+ * This is needed so we don't split off the edge but then none of its verts which
+ * would leave a duplicate edge.
+ */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) &&
+ (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE))))
+ {
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ bm_edgesplit_validate_seams(bm);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ /* this flag gets copied so we can be sure duplicate edges get it too (important) */
+ BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
+
+ /* keep splitting until each loop has its own edge */
+ do {
+ bmesh_edge_separate(bm, e, e->l);
+ } while (!BM_edge_is_boundary(e));
+
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+
+ if (use_verts) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) {
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ }
+ if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) {
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ bmesh_vert_separate(bm, e->v1, NULL, NULL);
+ }
+ if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+ bmesh_vert_separate(bm, e->v2, NULL, NULL);
+ }
+ }
+ }
+}
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h
new file mode 100644
index 0000000..687fdac
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.h
@@ -0,0 +1,32 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BMESH_EDGESPLIT_H__
+#define __BMESH_EDGESPLIT_H__
+
+/** \file blender/bmesh/tools/bmesh_edgesplit.h
+ * \ingroup bmesh
+ */
+
+void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only);
+
+#endif /* __BMESH_EDGESPLIT_H__ */
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 44e74e3..3d0ceb5 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -1194,7 +1194,7 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv
calc_joint_parent_mat_rest(par, NULL, root, node);
mult_m4_m4m4(temp, par, matfra);
- // evaluate_joint_world_transform_at_frame(temp, NULL,, node, fra);
+ // evaluate_joint_world_transform_at_frame(temp, NULL, node, fra);
// calc special matrix
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
@@ -1529,7 +1529,7 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
calc_joint_parent_mat_rest(par, NULL, root, node);
mult_m4_m4m4(temp, par, matfra);
- // evaluate_joint_world_transform_at_frame(temp, NULL,, node, fra);
+ // evaluate_joint_world_transform_at_frame(temp, NULL, node, fra);
// calc special matrix
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index cd2574d..f1cf732 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -79,7 +79,7 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
}
#endif
void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], Object *ob_arm)
+ float parent_mat[4][4], Object *ob_arm)
{
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
@@ -156,7 +156,7 @@ void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *pa
}
void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], bArmature *arm)
+ float parent_mat[4][4], bArmature *arm)
{
//Checking if bone is already made.
std::vector<COLLADAFW::Node *>::iterator it;
@@ -268,7 +268,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo
finished_joints.push_back(node);
}
-void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node *node)
+void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node)
{
LeafBone leaf;
@@ -572,7 +572,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// is a child of a node (not joint), root should be true since
// this is where we build armature bones from
-void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[][4])
+void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4])
{
char *bone_name = (char *) bc_get_joint_name(root_node);
float mat[4][4];
@@ -792,7 +792,7 @@ void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint
}
// gives a world-space mat
-bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
+bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
{
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
bool found = false;
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index a6b3728..bb710f0 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -104,16 +104,16 @@ private:
#endif
void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], bArmature *arm);
+ float parent_mat[4][4], bArmature *arm);
void create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild,
- float parent_mat[][4], Object * ob_arm);
+ float parent_mat[4][4], Object * ob_arm);
- void add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node);
+ void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node);
void fix_leaf_bones();
- void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[][4]);
+ void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[4][4]);
#if 0
@@ -168,7 +168,7 @@ public:
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count);
// gives a world-space mat
- bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint);
+ bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint);
void set_tags_map( TagsMap& tags_map);
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 084f71e..b7797b5 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -614,7 +614,6 @@ MTex *DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::T
ma->mtex[i]->texco = TEXCO_UV;
ma->mtex[i]->tex = add_texture("Texture");
ma->mtex[i]->tex->type = TEX_IMAGE;
- ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
@@ -745,7 +744,6 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
if (mtex != NULL) {
mtex->mapto = MAP_ALPHA;
- mtex->tex->imaflag |= TEX_USEALPHA;
i++;
ma->spectra = ma->alpha = 0;
ma->mode |= MA_ZTRANSP | MA_TRANSP;
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index aba290f..55fe203 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -89,7 +89,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
// make absolute destination path
BLI_strncpy(export_file, name.c_str(), sizeof(export_file));
- BKE_add_image_extension(export_file, imageFormat.imtype);
+ BKE_add_image_extension(export_file, &imageFormat);
BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file);
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index de8d1e8..8256618 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -1083,8 +1083,8 @@ void MeshImporter::optimize_material_assignments()
Object *ob = (*it);
Mesh *me = (Mesh *) ob->data;
if (me->id.us==1) {
- bc_copy_materials_to_data(ob,me);
- bc_remove_materials_from_object(ob,me);
+ bc_copy_materials_to_data(ob, me);
+ bc_remove_materials_from_object(ob, me);
bc_remove_mark(ob);
}
else if (me->id.us > 1)
@@ -1101,10 +1101,10 @@ void MeshImporter::optimize_material_assignments()
}
}
if (can_move) {
- bc_copy_materials_to_data(ref_ob,me);
+ bc_copy_materials_to_data(ref_ob, me);
for (int index = 0; index < mesh_users.size(); index++) {
Object *object = mesh_users[index];
- bc_remove_materials_from_object(object,me);
+ bc_remove_materials_from_object(object, me);
bc_remove_mark(object);
}
}
diff --git a/source/blender/collada/SConscript b/source/blender/collada/SConscript
index 5d92168..1351441 100644
--- a/source/blender/collada/SConscript
+++ b/source/blender/collada/SConscript
@@ -1,4 +1,5 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index 9b0d59d..470f663 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -168,7 +168,7 @@ Object *SkinInfo::set_armature(Object *ob_arm)
return ob_arm;
}
-bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node)
+bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node)
{
const COLLADAFW::UniqueId& uid = node->getUniqueId();
std::vector<JointData>::iterator it;
diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h
index 894f53f..e074f59 100644
--- a/source/blender/collada/SkinInfo.h
+++ b/source/blender/collada/SkinInfo.h
@@ -103,7 +103,7 @@ public:
Object* set_armature(Object *ob_arm);
- bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node);
+ bool get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node);
Object *BKE_armature_from_object();
diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp
index 6179358..5bc135e 100644
--- a/source/blender/collada/TransformReader.cpp
+++ b/source/blender/collada/TransformReader.cpp
@@ -34,7 +34,7 @@ TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv)
/* pass */
}
-void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob)
+void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob)
{
float cur[4][4];
float copy[4][4];
@@ -79,7 +79,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m
}
}
-void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm;
COLLADABU::Math::Vector3& axis = ro->getRotationAxis();
@@ -91,7 +91,7 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[
axis_angle_to_mat4(m, ax, angle);
}
-void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADAFW::Translate *tra = (COLLADAFW::Translate *)tm;
COLLADABU::Math::Vector3& t = tra->getTranslation();
@@ -103,14 +103,14 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float
m[3][2] = (float)t[2];
}
-void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale *)tm)->getScale();
float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
size_to_mat4(m, size);
}
-void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
+void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
{
unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix *)tm)->getMatrix());
}
diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h
index 47e59a1..ab974b9 100644
--- a/source/blender/collada/TransformReader.h
+++ b/source/blender/collada/TransformReader.h
@@ -58,12 +58,12 @@ public:
TransformReader(UnitConverter *conv);
- void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob);
+ void get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob);
- void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
- void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
- void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
- void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]);
+ void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
+ void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
+ void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
+ void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]);
void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]);
void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]);
void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]);
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index 0d6e383..3fe3f62 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -32,7 +32,7 @@
#include "BLI_math.h"
-void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4])
+void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4])
{
float loc[3], rot[3], scale[3];
float local[4][4];
diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h
index 917e26d..d2a4b54 100644
--- a/source/blender/collada/TransformWriter.h
+++ b/source/blender/collada/TransformWriter.h
@@ -37,7 +37,7 @@
class TransformWriter : protected TransformBase
{
protected:
- void add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]);
+ void add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]);
void add_node_transform_ob(COLLADASW::Node& node, Object *ob);
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index a496973..51d81dc 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -74,7 +74,7 @@ void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
// TODO need also for angle conversion, time conversion...
-void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in)
+void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in)
{
// in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
// so here, to make a blender matrix, we swap columns and rows
@@ -85,13 +85,13 @@ void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::M
}
}
-void UnitConverter::mat4_to_dae(float out[][4], float in[][4])
+void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
{
copy_m4_m4(out, in);
transpose_m4(out);
}
-void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4])
+void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
{
float mat[4][4];
@@ -102,7 +102,7 @@ void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4])
out[i][j] = mat[i][j];
}
-void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size)
+void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
{
mat4_to_size(size, mat);
if (eul) {
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 6eec6a1..d92f53f 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -69,17 +69,17 @@ public:
// TODO need also for angle conversion, time conversion...
- void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in);
+ void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in);
- void mat4_to_dae(float out[][4], float in[][4]);
+ void mat4_to_dae(float out[4][4], float in[4][4]);
- void mat4_to_dae_double(double out[][4], float in[][4]);
+ void mat4_to_dae_double(double out[4][4], float in[4][4]);
};
class TransformBase
{
public:
- void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size);
+ void decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size);
};
extern void clear_global_id_map();
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 8259cb6..0e8ddf4 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -491,10 +491,10 @@ set(SRC
operations/COM_ColorMatteOperation.h
operations/COM_ChannelMatteOperation.cpp
operations/COM_ChannelMatteOperation.h
- operations/COM_ConvertPremulToKeyOperation.cpp
- operations/COM_ConvertPremulToKeyOperation.h
- operations/COM_ConvertKeyToPremulOperation.cpp
- operations/COM_ConvertKeyToPremulOperation.h
+ operations/COM_ConvertPremulToStraightOperation.cpp
+ operations/COM_ConvertPremulToStraightOperation.h
+ operations/COM_ConvertStraightToPremulOperation.cpp
+ operations/COM_ConvertStraightToPremulOperation.h
operations/COM_ReadBufferOperation.cpp
operations/COM_ReadBufferOperation.h
diff --git a/source/blender/compositor/SConscript b/source/blender/compositor/SConscript
index 9f947ca..1872bf2 100644
--- a/source/blender/compositor/SConscript
+++ b/source/blender/compositor/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jeroen Bakker, Monique Dewanchand, Blender Developers Fund.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
defs = ['GLEW_STATIC']
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h
index 25f0610..9beccba 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.h
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.h
@@ -41,7 +41,8 @@ using namespace std;
* In order to get to an efficient model for execution, several steps are being done. these steps are explained below.
*
* @section EM_Step1 Step 1: translating blender node system to the new compsitor system
- * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture. We want to use classes in order to simplify the system.
+ * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture.
+ * We want to use classes in order to simplify the system.
* during this step the blender node_tree is evaluated and converted to a CPP node system.
*
* @see ExecutionSystem
@@ -49,13 +50,17 @@ using namespace std;
* @see Node
*
* @section EM_Step2 Step2: translating nodes to operations
- * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's. The new system only supports a single level of node_tree. We will 'flatten' the system in a single level.
+ * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's.
+ * The new system only supports a single level of node_tree. We will 'flatten' the system in a single level.
* @see GroupNode
* @see ExecutionSystemHelper.ungroup
*
- * Every node has the ability to convert itself to operations. The node itself is responsible to create a correct NodeOperation setup based on its internal settings.
- * Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything, but replaces itself with a ConvertColorToBWOperation.
- * More complex nodes can use different NodeOperation based on settings; like MixNode. based on the selected Mixtype a different operation will be used.
+ * Every node has the ability to convert itself to operations. The node itself is responsible to create a correct
+ * NodeOperation setup based on its internal settings.
+ * Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything,
+ * but replaces itself with a ConvertColorToBWOperation.
+ * More complex nodes can use different NodeOperation based on settings; like MixNode.
+ * based on the selected Mixtype a different operation will be used.
* for more information see the page about creating new Nodes. [@subpage newnode]
*
* @see ExecutionSystem.convertToOperations
@@ -63,9 +68,12 @@ using namespace std;
* @see NodeOperation base class for all operations in the system
*
* @section EM_Step3 Step3: add additional conversions to the operation system
- * - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR. The user can connect a Value socket to a color socket. As values are ordered differently than colors a conversion happens.
+ * - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR.
+ * The user can connect a Value socket to a color socket.
+ * As values are ordered differently than colors a conversion happens.
*
- * - Image size conversions: the system can automatically convert when resolutions do not match. An InputSocket has a resize mode. This can be any of the following settings.
+ * - Image size conversions: the system can automatically convert when resolutions do not match.
+ * An InputSocket has a resize mode. This can be any of the following settings.
* - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned
@@ -77,8 +85,10 @@ using namespace std;
* @see Converter.convertResolution Image size conversions
*
* @section EM_Step4 Step4: group operations in executions groups
- * ExecutionGroup are groups of operations that are calculated as being one bigger operation. All operations will be part of an ExecutionGroup.
- * Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers. ReadBufferOperations and WriteBufferOperations are added where needed.
+ * ExecutionGroup are groups of operations that are calculated as being one bigger operation.
+ * All operations will be part of an ExecutionGroup.
+ * Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers.
+ * ReadBufferOperations and WriteBufferOperations are added where needed.
*
* <pre>
*
diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h
index c098d6d..5b0381f 100644
--- a/source/blender/compositor/intern/COM_Node.h
+++ b/source/blender/compositor/intern/COM_Node.h
@@ -58,7 +58,7 @@ private:
* @brief The group node this node belongs to.
* @note: used to find the links in the current subtree for muting nodes
*/
- bNode* m_bNodeGroup;
+ bNode *m_bNodeGroup;
public:
Node(bNode *editorNode, bool create_sockets = true);
@@ -145,8 +145,8 @@ public:
*/
OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket);
- inline void setbNodeGroup(bNode* group) {this->m_bNodeGroup = group;}
- inline bNode* getbNodeGroup() {return this->m_bNodeGroup;}
+ inline void setbNodeGroup(bNode *group) {this->m_bNodeGroup = group;}
+ inline bNode *getbNodeGroup() {return this->m_bNodeGroup;}
protected:
void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket);
void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket);
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp
index a05c37e..d33b808 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperation.cpp
@@ -34,6 +34,7 @@ NodeOperation::NodeOperation() : NodeBase()
this->m_complex = false;
this->m_width = 0;
this->m_height = 0;
+ this->m_isResolutionSet = false;
this->m_openCL = false;
this->m_btree = NULL;
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index f856d8e..60ffadf 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -81,6 +81,7 @@ private:
*/
const bNodeTree *m_btree;
+ bool m_isResolutionSet;
public:
/**
* @brief is this node an operation?
@@ -170,7 +171,7 @@ public:
virtual void deinitExecution();
bool isResolutionSet() {
- return this->m_width != 0 && this->m_height != 0;
+ return this->m_isResolutionSet;
}
/**
@@ -181,6 +182,7 @@ public:
if (!isResolutionSet()) {
this->m_width = resolution[0];
this->m_height = resolution[1];
+ this->m_isResolutionSet = true;
}
}
@@ -254,8 +256,8 @@ public:
protected:
NodeOperation();
- void setWidth(unsigned int width) { this->m_width = width; }
- void setHeight(unsigned int height) { this->m_height = height; }
+ void setWidth(unsigned int width) { this->m_width = width; this->m_isResolutionSet = true; }
+ void setHeight(unsigned int height) { this->m_height = height; this->m_isResolutionSet = true; }
SocketReader *getInputSocketReader(unsigned int inputSocketindex);
NodeOperation *getInputOperation(unsigned int inputSocketindex);
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
index d5da079..bb60a62 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
@@ -65,12 +65,16 @@ void OpenCLDevice::execute(WorkPackage *work)
executionGroup->finalizeChunkExecution(chunkNumber, inputBuffers);
}
-cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader *reader)
+cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
+ list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
+ SocketReader *reader)
{
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
}
-cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, ReadBufferOperation *reader)
+cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
+ list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
+ ReadBufferOperation *reader)
{
cl_int error;
diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
index 254dfb7..a7149cc 100644
--- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
+++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cpp
@@ -20,8 +20,8 @@
*/
#include "COM_ConvertAlphaNode.h"
-#include "COM_ConvertPremulToKeyOperation.h"
-#include "COM_ConvertKeyToPremulOperation.h"
+#include "COM_ConvertPremulToStraightOperation.h"
+#include "COM_ConvertStraightToPremulOperation.h"
#include "COM_ExecutionSystem.h"
void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
@@ -31,10 +31,10 @@ void ConvertAlphaNode::convertToOperations(ExecutionSystem *graph, CompositorCon
/* value hardcoded in rna_nodetree.c */
if (node->custom1 == 1) {
- operation = new ConvertPremulToKeyOperation();
+ operation = new ConvertPremulToStraightOperation();
}
else {
- operation = new ConvertKeyToPremulOperation();
+ operation = new ConvertStraightToPremulOperation();
}
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 4293e34..864d6f0 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -28,6 +28,10 @@
#include "BKE_node.h"
#include "BLI_utildefines.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+#include "COM_SetColorOperation.h"
+
ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
@@ -165,6 +169,46 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
graph->addOperation(depthOperation);
}
}
+ if (numberOfOutputs > 3) {
+ /* happens when unlinking image datablock from multilayer node */
+ for (int i = 3; i < numberOfOutputs; i++) {
+ OutputSocket *output = this->getOutputSocket(i);
+ NodeOperation *operation = NULL;
+ switch (output->getDataType()) {
+ case COM_DT_VALUE:
+ {
+ SetValueOperation *valueoperation = new SetValueOperation();
+ valueoperation->setValue(0.0f);
+ operation = valueoperation;
+ break;
+ }
+ case COM_DT_VECTOR:
+ {
+ SetVectorOperation *vectoroperation = new SetVectorOperation();
+ vectoroperation->setX(0.0f);
+ vectoroperation->setY(0.0f);
+ vectoroperation->setW(0.0f);
+ operation = vectoroperation;
+ break;
+ }
+ case COM_DT_COLOR:
+ {
+ SetColorOperation *coloroperation = new SetColorOperation();
+ coloroperation->setChannel1(0.0f);
+ coloroperation->setChannel2(0.0f);
+ coloroperation->setChannel3(0.0f);
+ coloroperation->setChannel4(0.0f);
+ operation = coloroperation;
+ break;
+ }
+ }
+
+ if (operation) {
+ output->relinkConnections(operation->getOutputSocket());
+ graph->addOperation(operation);
+ }
+ }
+ }
}
}
diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp
index f1c7c61..b751c9a 100644
--- a/source/blender/compositor/nodes/COM_PixelateNode.cpp
+++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp
@@ -36,8 +36,8 @@ void PixelateNode::convertToOperations(ExecutionSystem *graph, CompositorContext
OutputSocket *outputSocket = this->getOutputSocket(0);
DataType datatype = inputSocket->getDataType();
if (inputSocket->isConnected()) {
- SocketConnection * connection = inputSocket->getConnection();
- OutputSocket* otherOutputSocket = connection->getFromSocket();
+ SocketConnection *connection = inputSocket->getConnection();
+ OutputSocket *otherOutputSocket = connection->getFromSocket();
datatype = otherOutputSocket->getDataType();
}
diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp
deleted file mode 100644
index 4497db5..0000000
--- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Dalai Felinto
- */
-
-#include "COM_ConvertKeyToPremulOperation.h"
-#include "BLI_math.h"
-
-ConvertKeyToPremulOperation::ConvertKeyToPremulOperation() : NodeOperation()
-{
- this->addInputSocket(COM_DT_COLOR);
- this->addOutputSocket(COM_DT_COLOR);
-
- this->m_inputColor = NULL;
-}
-
-void ConvertKeyToPremulOperation::initExecution()
-{
- this->m_inputColor = getInputSocketReader(0);
-}
-
-void ConvertKeyToPremulOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
-{
- float inputValue[4];
- float alpha;
-
- this->m_inputColor->read(inputValue, x, y, sampler);
- alpha = inputValue[3];
-
- mul_v3_v3fl(output, inputValue, alpha);
-
- /* never touches the alpha */
- output[3] = alpha;
-}
-
-void ConvertKeyToPremulOperation::deinitExecution()
-{
- this->m_inputColor = NULL;
-}
diff --git a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h b/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h
deleted file mode 100644
index 502674e..0000000
--- a/source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Dalai Felinto
- */
-
-#ifndef _COM_ConvertKeyToPremulOperation_h
-#define _COM_ConvertKeyToPremulOperation_h
-#include "COM_NodeOperation.h"
-
-
-/**
- * this program converts an input color to an output value.
- * it assumes we are in sRGB color space.
- */
-class ConvertKeyToPremulOperation : public NodeOperation {
-private:
- SocketReader *m_inputColor;
-public:
- /**
- * Default constructor
- */
- ConvertKeyToPremulOperation();
-
- /**
- * the inner loop of this program
- */
- void executePixel(float output[4], float x, float y, PixelSampler sampler);
-
- void initExecution();
- void deinitExecution();
-
-};
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp
deleted file mode 100644
index b92da4c..0000000
--- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Dalai Felinto
- */
-
-#include "COM_ConvertPremulToKeyOperation.h"
-#include "BLI_math.h"
-
-ConvertPremulToKeyOperation::ConvertPremulToKeyOperation() : NodeOperation()
-{
- this->addInputSocket(COM_DT_COLOR);
- this->addOutputSocket(COM_DT_COLOR);
-
- this->m_inputColor = NULL;
-}
-
-void ConvertPremulToKeyOperation::initExecution()
-{
- this->m_inputColor = getInputSocketReader(0);
-}
-
-void ConvertPremulToKeyOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
-{
- float inputValue[4];
- float alpha;
-
- this->m_inputColor->read(inputValue, x, y, sampler);
- alpha = inputValue[3];
-
- if (fabsf(alpha) < 1e-5f) {
- zero_v3(output);
- }
- else {
- mul_v3_v3fl(output, inputValue, 1.0f / alpha);
- }
-
- /* never touches the alpha */
- output[3] = alpha;
-}
-
-void ConvertPremulToKeyOperation::deinitExecution()
-{
- this->m_inputColor = NULL;
-}
diff --git a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h b/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h
deleted file mode 100644
index 04a9965..0000000
--- a/source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2012, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Dalai Felinto
- */
-
-#ifndef _COM_ConvertPremulToKeyOperation_h
-#define _COM_ConvertPremulToKeyOperation_h
-#include "COM_NodeOperation.h"
-
-
-/**
- * this program converts an input color to an output value.
- * it assumes we are in sRGB color space.
- */
-class ConvertPremulToKeyOperation : public NodeOperation {
-private:
- SocketReader *m_inputColor;
-public:
- /**
- * Default constructor
- */
- ConvertPremulToKeyOperation();
-
- /**
- * the inner loop of this program
- */
- void executePixel(float output[4], float x, float y, PixelSampler sampler);
-
- void initExecution();
- void deinitExecution();
-};
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.cpp b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.cpp
new file mode 100644
index 0000000..2af4b55
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Dalai Felinto
+ */
+
+#include "COM_ConvertPremulToStraightOperation.h"
+#include "BLI_math.h"
+
+ConvertPremulToStraightOperation::ConvertPremulToStraightOperation() : NodeOperation()
+{
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
+
+ this->m_inputColor = NULL;
+}
+
+void ConvertPremulToStraightOperation::initExecution()
+{
+ this->m_inputColor = getInputSocketReader(0);
+}
+
+void ConvertPremulToStraightOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
+{
+ float inputValue[4];
+ float alpha;
+
+ this->m_inputColor->read(inputValue, x, y, sampler);
+ alpha = inputValue[3];
+
+ if (fabsf(alpha) < 1e-5f) {
+ zero_v3(output);
+ }
+ else {
+ mul_v3_v3fl(output, inputValue, 1.0f / alpha);
+ }
+
+ /* never touches the alpha */
+ output[3] = alpha;
+}
+
+void ConvertPremulToStraightOperation::deinitExecution()
+{
+ this->m_inputColor = NULL;
+}
diff --git a/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.h b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.h
new file mode 100644
index 0000000..9d3ab15
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConvertPremulToStraightOperation.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Dalai Felinto
+ */
+
+#ifndef _COM_ConvertPremulToStraightOperation_h
+#define _COM_ConvertPremulToStraightOperation_h
+#include "COM_NodeOperation.h"
+
+
+/**
+ * this program converts an input color to an output value.
+ * it assumes we are in sRGB color space.
+ */
+class ConvertPremulToStraightOperation : public NodeOperation {
+private:
+ SocketReader *m_inputColor;
+public:
+ /**
+ * Default constructor
+ */
+ ConvertPremulToStraightOperation();
+
+ /**
+ * the inner loop of this program
+ */
+ void executePixel(float output[4], float x, float y, PixelSampler sampler);
+
+ void initExecution();
+ void deinitExecution();
+};
+#endif
diff --git a/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.cpp b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.cpp
new file mode 100644
index 0000000..ae55d94
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Dalai Felinto
+ */
+
+#include "COM_ConvertStraightToPremulOperation.h"
+#include "BLI_math.h"
+
+ConvertStraightToPremulOperation::ConvertStraightToPremulOperation() : NodeOperation()
+{
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
+
+ this->m_inputColor = NULL;
+}
+
+void ConvertStraightToPremulOperation::initExecution()
+{
+ this->m_inputColor = getInputSocketReader(0);
+}
+
+void ConvertStraightToPremulOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
+{
+ float inputValue[4];
+ float alpha;
+
+ this->m_inputColor->read(inputValue, x, y, sampler);
+ alpha = inputValue[3];
+
+ mul_v3_v3fl(output, inputValue, alpha);
+
+ /* never touches the alpha */
+ output[3] = alpha;
+}
+
+void ConvertStraightToPremulOperation::deinitExecution()
+{
+ this->m_inputColor = NULL;
+}
diff --git a/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.h b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.h
new file mode 100644
index 0000000..d0191f2
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConvertStraightToPremulOperation.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Dalai Felinto
+ */
+
+#ifndef _COM_ConvertStraightToPremulOperation_h
+#define _COM_ConvertStraightToPremulOperation_h
+#include "COM_NodeOperation.h"
+
+
+/**
+ * this program converts an input color to an output value.
+ * it assumes we are in sRGB color space.
+ */
+class ConvertStraightToPremulOperation : public NodeOperation {
+private:
+ SocketReader *m_inputColor;
+public:
+ /**
+ * Default constructor
+ */
+ ConvertStraightToPremulOperation();
+
+ /**
+ * the inner loop of this program
+ */
+ void executePixel(float output[4], float x, float y, PixelSampler sampler);
+
+ void initExecution();
+ void deinitExecution();
+
+};
+#endif
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp
index 8455711..c8e3dbf 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_ImageOperation.cpp
@@ -120,7 +120,7 @@ void ImageOperation::executePixel(float output[4], float x, float y, PixelSample
else {
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_buffer, NULL, output, x, y);
+ nearest_interpolation_color(this->m_buffer, NULL, output, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_buffer, NULL, output, x, y);
@@ -143,7 +143,7 @@ void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelS
tempcolor[3] = 1.0f;
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
+ nearest_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_buffer, NULL, tempcolor, x, y);
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
index 709e4b7..74761f0 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
@@ -95,7 +95,7 @@ void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSa
else {
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y);
+ nearest_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y);
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
index af0d516..1c9dd0f 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
@@ -54,7 +54,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P
if (this->m_numberOfChannels == 4) {
switch (sampler) {
case COM_PS_NEAREST:
- neareast_interpolation_color(this->m_buffer, NULL, output, x, y);
+ nearest_interpolation_color(this->m_buffer, NULL, output, x, y);
break;
case COM_PS_BILINEAR:
bilinear_interpolation_color(this->m_buffer, NULL, output, x, y);
diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl
index 36205bb..8cc25fc 100644
--- a/source/blender/compositor/operations/COM_OpenCLKernels.cl
+++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl
@@ -66,7 +66,8 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
}
color /= multiplyer;
- } else {
+ }
+ else {
int2 imageCoordinates = realCoordinate - offsetInput;
color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates);
}
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 7d05202..47b69ec 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -141,7 +141,7 @@ void OutputSingleLayerOperation::deinitExecution()
IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, m_viewSettings, m_displaySettings,
this->m_format);
- BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format->imtype,
+ BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
(this->m_rd->scemode & R_EXTENSION), true);
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
@@ -205,7 +205,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
char filename[FILE_MAX];
void *exrhandle = IMB_exr_get_handle();
- BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
+ BKE_makepicstring_from_type(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
(this->m_rd->scemode & R_EXTENSION), true);
BLI_make_existing_file(filename);
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
index d2c6c83..fb996f2 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
@@ -204,10 +204,10 @@ bool ScreenLensDistortionOperation::determineDependingAreaOfInterest(rcti *input
}
#define UPDATE_INPUT { \
- newInput.xmin = MIN4(newInput.xmin, coords[0], coords[2], coords[4]); \
- newInput.ymin = MIN4(newInput.ymin, coords[1], coords[3], coords[5]); \
- newInput.xmax = MAX4(newInput.xmax, coords[0], coords[2], coords[4]); \
- newInput.ymax = MAX4(newInput.ymax, coords[1], coords[3], coords[5]); \
+ newInput.xmin = min_ffff(newInput.xmin, coords[0], coords[2], coords[4]); \
+ newInput.ymin = min_ffff(newInput.ymin, coords[1], coords[3], coords[5]); \
+ newInput.xmax = max_ffff(newInput.xmax, coords[0], coords[2], coords[4]); \
+ newInput.ymax = max_ffff(newInput.ymax, coords[1], coords[3], coords[5]); \
} (void)0
rcti newInput;
@@ -273,7 +273,7 @@ void ScreenLensDistortionOperation::updateVariables(float distortion, float disp
const float d = 0.25f * max_ff(min_ff(dispersion, 1.0f), 0.0f);
this->m_kr = max_ff(min_ff((this->m_kg + d), 1.0f), -0.999f);
this->m_kb = max_ff(min_ff((this->m_kg - d), 1.0f), -0.999f);
- this->m_maxk = MAX3(this->m_kr, this->m_kg, this->m_kb);
+ this->m_maxk = max_fff(this->m_kr, this->m_kg, this->m_kb);
this->m_sc = (this->m_data->fit && (this->m_maxk > 0.0f)) ? (1.0f / (1.0f + 2.0f * this->m_maxk)) :
(1.0f / (1.0f + this->m_maxk));
this->m_drg = 4.0f * (this->m_kg - this->m_kr);
diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp
index 8b52883..e647ae9 100644
--- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp
+++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp
@@ -42,7 +42,7 @@ TrackPositionOperation::TrackPositionOperation() : NodeOperation()
this->m_trackingObjectName[0] = 0;
this->m_trackName[0] = 0;
this->m_axis = 0;
- this->m_position = POSITION_ABSOLUTE;;
+ this->m_position = POSITION_ABSOLUTE;
this->m_relativeFrame = 0;
}
diff --git a/source/blender/datatoc/datatoc.c b/source/blender/datatoc/datatoc.c
index 379658b..236d9af 100644
--- a/source/blender/datatoc/datatoc.c
+++ b/source/blender/datatoc/datatoc.c
@@ -51,6 +51,7 @@ int main(int argc, char **argv)
FILE *fpin, *fpout;
long size;
int i;
+ int argv_len;
if (argc < 2) {
printf("Usage: datatoc <data_file_from> <data_file_to>\n");
@@ -75,7 +76,8 @@ int main(int argc, char **argv)
printf("Making C file <%s>\n", argv[2]);
#endif
- for (i = 0; i < (int)strlen(argv[1]); i++)
+ argv_len = (int)strlen(argv[1]);
+ for (i = 0; i < argv_len; i++)
if (argv[1][i] == '.') argv[1][i] = '_';
fpout = fopen(argv[2], "w");
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index 6233ea0..1ea2bc0 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
diff --git a/source/blender/editors/animation/SConscript b/source/blender/editors/animation/SConscript
index 658ad27..2a6b381 100644
--- a/source/blender/editors/animation/SConscript
+++ b/source/blender/editors/animation/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 9ceecd6..f5c9bfb 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -82,7 +82,7 @@
#define EXTRA_SCROLL_PAD 100.0f
/* size of indent steps */
-#define INDENT_STEP_SIZE 7
+#define INDENT_STEP_SIZE (0.35f * U.widget_unit)
/* size of string buffers used for animation channel displayed names */
#define ANIM_CHAN_NAME_SIZE 256
@@ -305,15 +305,15 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
if (ale->id) {
/* texture animdata */
if (GS(ale->id->name) == ID_TE) {
- offset += 21;
+ offset += U.widget_unit;
}
/* materials and particles animdata */
else if (ELEM(GS(ale->id->name), ID_MA, ID_PA))
- offset += 14;
+ offset += (short)(0.7f * U.widget_unit);
/* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
else if (ac->datatype != ANIMCONT_ACTION)
- offset += 14;
+ offset += (short)(0.7f * U.widget_unit);
/* nodetree animdata */
if (GS(ale->id->name) == ID_NT) {
@@ -2911,12 +2911,12 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting,
/* --------------------------- */
-// XXX hardcoded size of icons
-#define ICON_WIDTH 17
-// XXX hardcoded width of sliders
-#define SLIDER_WIDTH 80
-// XXX hardcoded width of rename textboxes
-#define RENAME_TEXT_WIDTH 100
+// size of icons
+#define ICON_WIDTH (0.85f * U.widget_unit)
+// width of sliders
+#define SLIDER_WIDTH (4 * U.widget_unit)
+// width of rename textboxes
+#define RENAME_TEXT_WIDTH (5 * U.widget_unit)
/* Draw the given channel */
void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
@@ -2937,12 +2937,11 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
offset = 0;
/* calculate appropriate y-coordinates for icon buttons
- * 7 is hardcoded factor for half-height of icons
*/
y = (ymaxc - yminc) / 2 + yminc;
- ymid = y - 7;
+ ymid = y - 0.5f * ICON_WIDTH;
/* y-coordinates for text is only 4 down from middle */
- ytext = y - 4;
+ ytext = y - 0.2f * U.widget_unit;
/* check if channel is selected */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
@@ -2989,10 +2988,8 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
glColor3fv(fcu->color);
/* just a solid color rect
- * hardcoded 17 pixels width is slightly wider than icon width, so that
- * there's a slight border around it
*/
- glRectf(offset, yminc, offset + 17, ymaxc);
+ glRectf(offset, yminc, offset + ICON_WIDTH, ymaxc);
}
/* icon is drawn as widget now... */
@@ -3086,7 +3083,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
}
- /* finally draw a backdrop rect behind these
+ /* finally draw a backdrop rect behind these
* - starts from the point where the first toggle/slider starts,
* - ends past the space that might be reserved for a scroller
*/
@@ -3365,12 +3362,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
offset = 0;
/* calculate appropriate y-coordinates for icon buttons
- * 7 is hardcoded factor for half-height of icons
*/
y = (ymaxc - yminc) / 2 + yminc;
- ymid = y - 7;
- /* y-coordinates for text is only 4 down from middle */
- /* ytext = y - 4; */
+ ymid = y - 0.5f * ICON_WIDTH;
/* no button backdrop behind icons */
uiBlockSetEmboss(block, UI_EMBOSSN);
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 92e1ff1..458054c 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -538,12 +538,26 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
BLI_remlink(&adt->drivers, fcu);
}
else if (adt->action) {
+ bAction *act = adt->action;
+
/* remove from group or action, whichever one "owns" the F-Curve */
- if (fcu->grp)
- action_groups_remove_channel(adt->action, fcu);
- else
- BLI_remlink(&adt->action->curves, fcu);
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
+
+ /* remove F-Curve from group+action */
+ action_groups_remove_channel(act, fcu);
+ /* if group has no more channels, remove it too,
+ * otherwise can have many dangling groups [#33541]
+ */
+ if (agrp->channels.first == NULL) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ else {
+ BLI_remlink(&act->curves, fcu);
+ }
+
/* if action has no more F-Curves as a result of this, unlink it from
* AnimData if it did not come from a NLA Strip being tweaked.
*
@@ -551,12 +565,8 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
* channel list that are empty, and linger around long after the data they
* are for has disappeared (and probably won't come back).
*/
- // XXX: does everybody always want this?
- /* XXX: there's a problem where many actions could build up in the file if multiple
- * full add/delete cycles are performed on the same objects, but assume that this is rare
- */
- if ((adt->action->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
- id_us_min(&adt->action->id);
+ if ((act->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
+ id_us_min(&act->id);
adt->action = NULL;
}
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 0f0584a..d83d180 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -33,9 +33,12 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
#include "BLI_math.h"
#include "BKE_context.h"
+#include "BKE_blender.h"
#include "BKE_global.h"
#include "BKE_nla.h"
#include "BKE_object.h"
@@ -197,15 +200,15 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, float cfra, short time)
/* get starting coordinates for drawing */
x = cfra * xscale;
- y = 18;
+ y = 0.9f * U.widget_unit;
/* draw green box around/behind text */
UI_ThemeColorShade(TH_CFRAME, 0);
- glRectf(x, y, x + slen, y + 15);
+ glRectf(x, y, x + slen, y + 0.75f * U.widget_unit);
/* draw current frame number - black text */
UI_ThemeColor(TH_TEXT);
- UI_DrawString(x - 5, y + 3, numstr);
+ UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr);
/* restore view transform */
glScalef(xscale, 1.0, 1.0);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 5e215fb..655ab2b 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -290,7 +290,7 @@ static short nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
short ANIM_animdata_context_getdata(bAnimContext *ac)
{
SpaceLink *sl = ac->sl;
- short ok = 0;
+ short ok = FALSE;
/* context depends on editor we are currently in */
if (sl) {
@@ -319,10 +319,7 @@ short ANIM_animdata_context_getdata(bAnimContext *ac)
}
/* check if there's any valid data */
- if (ok && ac->data)
- return 1;
- else
- return 0;
+ return (ok && ac->data);
}
/* Obtain current anim-data context from Blender Context info
@@ -354,6 +351,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->regiontype = (ar) ? ar->regiontype : 0;
/* get data context info */
+ // XXX: if the below fails, try to grab this info from context instead... (to allow for scripting)
return ANIM_animdata_context_getdata(ac);
}
@@ -913,14 +911,14 @@ static short skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_i
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = NULL;
char *seq_name;
-
+
if (ed) {
/* get strip name, and check if this strip is selected */
seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, FALSE);
if (seq_name) MEM_freeN(seq_name);
}
-
+
/* can only add this F-Curve if it is selected */
if (ads->filterflag & ADS_FILTER_ONLYSEL) {
if ((seq == NULL) || (seq->flag & SELECT) == 0)
@@ -2146,7 +2144,7 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
}
-
+
/* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
}
END_ANIMFILTER_SUBCHANNELS;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 1b98079..f684e57 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -395,7 +395,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
ICON_MARKER;
}
- UI_icon_draw(xpos * xscale - 5.0f, 16.0f, icon_id);
+ UI_icon_draw(xpos * xscale - 0.3f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id);
glDisable(GL_BLEND);
@@ -405,18 +405,18 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
if (marker->flag & SELECT) {
UI_ThemeColor(TH_TEXT_HI);
- x = xpos * xscale + 4.0f;
- y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f;
+ x = xpos * xscale + 4.0f * UI_DPI_FAC;
+ y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
}
else {
UI_ThemeColor(TH_TEXT);
if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) {
- x = xpos * xscale + 4.0f;
- y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f;
+ x = xpos * xscale + 8.0f * UI_DPI_FAC;
+ y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
}
else {
- x = xpos * xscale + 4.0f;
- y = 17.0f;
+ x = xpos * xscale + 8.0f * UI_DPI_FAC;
+ y = 17.0f * UI_DPI_FAC;
}
}
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index ca036a8..6687cce 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -62,16 +62,28 @@
/* Check if the operator can be run from the current context */
static int change_frame_poll(bContext *C)
{
- ScrArea *curarea = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
/* XXX temp? prevent changes during render */
- if (G.is_rendering) return 0;
+ if (G.is_rendering) return FALSE;
- /* as long as there is an active area, and it isn't a Graph Editor
- * (since the Graph Editor has its own version which does extra stuff),
- * we're fine
+ /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
+ * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
*/
- return ((curarea) && (curarea->spacetype != SPACE_IPO));
+ if (sa) {
+ if (ELEM5(sa->spacetype, SPACE_TIME, SPACE_ACTION, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
+ return TRUE;
+ }
+ else if (sa->spacetype == SPACE_IPO) {
+ /* NOTE: Graph Editor has special version which does some extra stuff.
+ * No need to show the generic error message for that case though!
+ */
+ return FALSE;
+ }
+ }
+
+ CTX_wm_operator_poll_msg_set(C, "Expected an timeline/animation area to be active");
+ return FALSE;
}
/* Set the new frame number */
@@ -83,7 +95,7 @@ static void change_frame_apply(bContext *C, wmOperator *op)
/* set the new frame number */
CFRA = RNA_int_get(op->ptr, "frame");
FRAMENUMBER_MIN_CLAMP(CFRA);
- SUBFRA = 0.f;
+ SUBFRA = 0.0f;
/* do updates */
sound_seek_scene(bmain, scene);
@@ -161,7 +173,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
static void ANIM_OT_change_frame(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Change frame";
+ ot->name = "Change Frame";
ot->idname = "ANIM_OT_change_frame";
ot->description = "Interactively change the current frame number";
@@ -175,7 +187,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_POINTER;
/* rna */
- RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
+ ot->prop = RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
}
/* ****************** set preview range operator ****************************/
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 79a4c9a..6bd774e 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -151,7 +151,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
}
else {
/* basic size (just "x") */
- maxXWidth = 15;
+ maxXWidth = UI_GetStringWidth("x") + 10;
}
/* draw controls for each coefficient and a + sign at end of row */
@@ -231,16 +231,16 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 100, 20, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Second coefficient"));
- /* closing bracket and '+' sign */
+ /* closing bracket and multiplication sign */
if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
- uiDefBut(block, LABEL, 1, ") +", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, ") ×", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
/* set up new row for the next pair of coefficients */
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
}
else
- uiDefBut(block, LABEL, 1, ")", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, ") ", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
}
}
break;
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index e520a95..d9d2180 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -649,7 +649,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
ActKeyColumn *ak;
ActKeyBlock *ab;
float xscale;
-
+ float iconsize = U.widget_unit / 4.0f;
glEnable(GL_BLEND);
/* get View2D scaling factor */
@@ -665,7 +665,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
else
UI_ThemeColor4(TH_STRIP);
- glRectf(ab->start, ypos - 5, ab->end, ypos + 5);
+ glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize);
}
}
}
@@ -686,7 +686,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
/* draw using OpenGL - uglier but faster */
/* NOTE1: a previous version of this didn't work nice for some intel cards
* NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */
- draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha);
+ draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha);
}
}
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 8ba330e..9add193 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -540,8 +540,8 @@ static float setting_get_rna_value(PointerRNA *ptr, PropertyRNA *prop, int index
enum {
VISUALKEY_NONE = 0,
VISUALKEY_LOC,
- VISUALKEY_ROT
- /* VISUALKEY_SCA */ /* TODO - looks like support can be added now */
+ VISUALKEY_ROT,
+ VISUALKEY_SCA,
};
/* This helper function determines if visual-keyframing should be used when
@@ -560,7 +560,7 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
/* validate data */
if (ELEM3(NULL, ptr, ptr->data, prop))
return 0;
-
+
/* get first constraint and determine type of keyframe constraints to check for
* - constraints can be on either Objects or PoseChannels, so we only check if the
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
@@ -586,7 +586,7 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
/* check if any data to search using */
if (ELEM(NULL, con, identifier) && (has_parent == FALSE))
return 0;
-
+
/* location or rotation identifiers only... */
if (identifier == NULL) {
printf("%s failed: NULL identifier\n", __func__);
@@ -598,6 +598,9 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
else if (strstr(identifier, "rotation")) {
searchtype = VISUALKEY_ROT;
}
+ else if (strstr(identifier, "scale")) {
+ searchtype = VISUALKEY_SCA;
+ }
else {
printf("%s failed: identifier - '%s'\n", __func__, identifier);
return 0;
@@ -628,7 +631,7 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
return 1;
case CONSTRAINT_TYPE_KINEMATIC:
return 1;
-
+
/* single-transform constraits */
case CONSTRAINT_TYPE_TRACKTO:
if (searchtype == VISUALKEY_ROT) return 1;
@@ -642,15 +645,21 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
case CONSTRAINT_TYPE_LOCLIMIT:
if (searchtype == VISUALKEY_LOC) return 1;
break;
- case CONSTRAINT_TYPE_ROTLIKE:
- if (searchtype == VISUALKEY_ROT) return 1;
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ if (searchtype == VISUALKEY_SCA) return 1;
break;
case CONSTRAINT_TYPE_DISTLIMIT:
if (searchtype == VISUALKEY_LOC) return 1;
break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ if (searchtype == VISUALKEY_ROT) return 1;
+ break;
case CONSTRAINT_TYPE_LOCLIKE:
if (searchtype == VISUALKEY_LOC) return 1;
break;
+ case CONSTRAINT_TYPE_SIZELIKE:
+ if (searchtype == VISUALKEY_SCA) return 1;
+ break;
case CONSTRAINT_TYPE_LOCKTRACK:
if (searchtype == VISUALKEY_ROT) return 1;
break;
@@ -675,45 +684,26 @@ static short visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_index)
{
const char *identifier = RNA_property_identifier(prop);
+ float tmat[4][4];
+ int rotmode;
/* handle for Objects or PoseChannels only
+ * - only Location, Rotation or Scale keyframes are supported curently
* - constraints can be on either Objects or PoseChannels, so we only check if the
- * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
+ * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
* those structs, allowing us to identify the owner of the data
- * - assume that array_index will be sane
+ * - assume that array_index will be sane
*/
if (ptr->type == &RNA_Object) {
Object *ob = (Object *)ptr->data;
-
- /* only Location or Rotation keyframes are supported now */
+
+ /* Loc code is specific... */
if (strstr(identifier, "location")) {
return ob->obmat[3][array_index];
}
- else if (strstr(identifier, "rotation_euler")) {
- float eul[3];
-
- mat4_to_eulO(eul, ob->rotmode, ob->obmat);
- return eul[array_index];
- }
- else if (strstr(identifier, "rotation_quaternion")) {
- float trimat[3][3], quat[4];
-
- copy_m3_m4(trimat, ob->obmat);
- mat3_to_quat_is_ok(quat, trimat);
-
- return quat[array_index];
- }
- else if (strstr(identifier, "rotation_axis_angle")) {
- float axis[3], angle;
-
- mat4_to_axis_angle(axis, &angle, ob->obmat);
-
- /* w = 0, x,y,z = 1,2,3 */
- if (array_index == 0)
- return angle;
- else
- return axis[array_index - 1];
- }
+
+ copy_m4_m4(tmat, ob->obmat);
+ rotmode = ob->rotmode;
}
else if (ptr->type == &RNA_PoseBone) {
Object *ob = (Object *)ptr->id.data; /* we assume that this is always set, and is an object */
@@ -726,42 +716,53 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i
* will be what owns the pose-channel that is getting this anyway.
*/
copy_m4_m4(tmat, pchan->pose_mat);
- constraint_mat_convertspace(ob, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ rotmode = pchan->rotmode;
- /* Loc, Rot/Quat keyframes are supported... */
+ /* Loc code is specific... */
if (strstr(identifier, "location")) {
/* only use for non-connected bones */
- if ((pchan->bone->parent) && !(pchan->bone->flag & BONE_CONNECTED))
+ if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED))
return tmat[3][array_index];
- else if (pchan->bone->parent == NULL)
- return tmat[3][array_index];
- }
- else if (strstr(identifier, "rotation_euler")) {
- float eul[3];
-
- mat4_to_eulO(eul, pchan->rotmode, tmat);
- return eul[array_index];
- }
- else if (strstr(identifier, "rotation_quaternion")) {
- float trimat[3][3], quat[4];
-
- copy_m3_m4(trimat, tmat);
- mat3_to_quat_is_ok(quat, trimat);
-
- return quat[array_index];
- }
- else if (strstr(identifier, "rotation_axis_angle")) {
- float axis[3], angle;
-
- mat4_to_axis_angle(axis, &angle, tmat);
-
- /* w = 0, x,y,z = 1,2,3 */
- if (array_index == 0)
- return angle;
- else
- return axis[array_index - 1];
}
}
+ else {
+ return setting_get_rna_value(ptr, prop, array_index);
+ }
+
+ /* Rot/Scale code are common! */
+ if (strstr(identifier, "rotation_euler")) {
+ float eul[3];
+
+ mat4_to_eulO(eul, rotmode, tmat);
+ return eul[array_index];
+ }
+ else if (strstr(identifier, "rotation_quaternion")) {
+ float mat3[3][3], quat[4];
+
+ copy_m3_m4(mat3, tmat);
+ mat3_to_quat_is_ok(quat, mat3);
+
+ return quat[array_index];
+ }
+ else if (strstr(identifier, "rotation_axis_angle")) {
+ float axis[3], angle;
+
+ mat4_to_axis_angle(axis, &angle, tmat);
+
+ /* w = 0, x,y,z = 1,2,3 */
+ if (array_index == 0)
+ return angle;
+ else
+ return axis[array_index - 1];
+ }
+ else if (strstr(identifier, "scale")) {
+ float scale[3];
+
+ mat4_to_size(scale, tmat);
+
+ return scale[array_index];
+ }
/* as the function hasn't returned yet, read value from system in the default way */
return setting_get_rna_value(ptr, prop, array_index);
diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h
index 06ee3fb..7110957 100644
--- a/source/blender/editors/armature/BIF_generate.h
+++ b/source/blender/editors/armature/BIF_generate.h
@@ -40,9 +40,10 @@ int nextFixedSubdivision(struct ToolSettings *toolsettings, struct BArcIterator
int nextLengthSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
int nextAdaptativeSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
-struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion);
+struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter,
+ float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion);
-void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[][4], float tmat[][3]);
+void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[4][4], float tmat[3][3]);
#endif /* __BIF_GENERATE_H__ */
diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript
index ba375f3..1911d76 100644
--- a/source/blender/editors/armature/SConscript
+++ b/source/blender/editors/armature/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index e801d36..4a987d1 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -812,7 +812,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
pose = ob->pose;
for (pchant = pose->chanbase.first; pchant; pchant = pchant->next) {
for (con = pchant->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -859,7 +859,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
/* fix object-level constraints */
if (ob != srcArm) {
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1032,7 +1032,7 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
if (ob->type == OB_ARMATURE) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1070,7 +1070,7 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
/* fix object-level constraints */
if (ob != origArm) {
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1712,7 +1712,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2062,7 +2062,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
float cursor_local[3];
- float *cursor = give_cursor(scene, v3d);
+ const float *cursor = give_cursor(scene, v3d);
copy_v3_v3(cursor_local, cursor);
@@ -2256,6 +2256,7 @@ void undo_push_armature(bContext *C, const char *name)
/* *************** Adding stuff in editmode *************** */
/* default bone add, returns it selected, but without tail set */
+/* XXX should be used everywhere, now it mallocs bones still locally in functions */
EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
{
EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
@@ -2265,7 +2266,7 @@ EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
BLI_addtail(arm->edbo, bone);
- bone->flag |= BONE_TIPSEL;
+ bone->flag |= BONE_TIPSEL | BONE_RELATIVE_PARENTING;
bone->weight = 1.0f;
bone->dist = 0.25f;
bone->xwidth = 0.1f;
@@ -2323,7 +2324,8 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
View3D *v3d;
bArmature *arm;
EditBone *ebone, *newbone, *flipbone;
- float *curs, mat[3][3], imat[3][3];
+ float mat[3][3], imat[3][3];
+ const float *curs;
int a, to_root = 0;
Object *obedit;
Scene *scene;
@@ -2418,7 +2420,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *e
Scene *scene;
ARegion *ar;
View3D *v3d;
- float *fp = NULL, tvec[3], oldcurs[3], mval_f[2];
+ float *fp, tvec[3], oldcurs[3], mval_f[2];
int retv;
scene = CTX_data_scene(C);
@@ -2521,7 +2523,7 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
/* does this constraint have a subtarget in
* this armature?
*/
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -3409,7 +3411,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
copy_v3_v3(newbone->tail, newbone->head);
newbone->parent = ebone;
- newbone->flag = ebone->flag & BONE_TIPSEL; // copies it, in case mirrored bone
+ newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING); // copies it, in case mirrored bone
if (newbone->parent) newbone->flag |= BONE_CONNECTED;
}
@@ -3418,7 +3420,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
copy_v3_v3(newbone->tail, ebone->head);
newbone->parent = ebone->parent;
- newbone->flag = BONE_TIPSEL;
+ newbone->flag = BONE_TIPSEL | BONE_RELATIVE_PARENTING;
if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
newbone->flag |= BONE_CONNECTED;
@@ -4347,7 +4349,7 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "direction", direction_items,
BONE_SELECT_PARENT, "Direction", "");
- RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/* ***************** EditBone Alignment ********************* */
@@ -5531,7 +5533,7 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldnam
bConstraintTarget *ct;
for (curcon = conlist->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index d9c7e78..979c352 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -50,7 +50,7 @@
#include "armature_intern.h"
#include "BIF_generate.h"
-void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[][4]), float tmat[][3])
+void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[4][4]), float tmat[3][3])
{
if (no != NULL && !is_zero_v3(no)) {
float normal[3];
@@ -257,7 +257,8 @@ int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int st
return -1;
}
-EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
+EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter,
+ float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion)
{
EditBone *lastBone = NULL;
EditBone *child = NULL;
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 68cfc7f..3e34a4c 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -725,7 +725,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* DO SOME MAGIC HERE */
for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -850,7 +850,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* DO SOME MAGIC HERE */
for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1830,7 +1830,9 @@ static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEd
}
#endif
-static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2, float angle_weight, float length_weight, float distance_weight)
+static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge,
+ float *vec0, float *vec1, float *vec2, int i1, int i2,
+ float angle_weight, float length_weight, float distance_weight)
{
float vec_second[3], vec_first[3];
float length2;
@@ -1878,7 +1880,9 @@ static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions,
}
}
-static MemoNode *solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left, float angle_weight, float length_weight, float distance_weight)
+static MemoNode *solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache,
+ int nb_joints, int nb_positions, int previous, int current, RigEdge *edge,
+ int joints_left, float angle_weight, float length_weight, float distance_weight)
{
MemoNode *node;
int index = indexMemoNode(nb_positions, previous, current, joints_left);
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index f9cf4a2..b61aa86 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -361,7 +361,7 @@ static void sk_autoname(bContext *C, ReebArc *arc)
}
}
-static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
+static ReebNode *sk_pointToNode(SK_Point *pt, float imat[4][4], float tmat[3][3])
{
ReebNode *node;
@@ -375,7 +375,7 @@ static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
return node;
}
-static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
+static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[4][4], float tmat[3][3])
{
ReebArc *arc;
int i;
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 9152ea8..a7e84d5 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -649,7 +649,9 @@ static float heat_limit_weight(float weight)
return weight;
}
-void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
+void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
+ bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
+ float (*root)[3], float (*tip)[3], int *selected, const char **err_str)
{
LaplacianSystem *sys;
MPoly *mp;
@@ -666,8 +668,8 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource,
*err_str = NULL;
/* count triangles and create mask */
- if ((use_face_sel = ((me->editflag & ME_EDIT_PAINT_MASK) != 0)) ||
- (use_vert_sel = ((me->editflag & ME_EDIT_VERT_SEL) != 0)))
+ if ((use_face_sel = ((me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0)) ||
+ (use_vert_sel = ((me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0)))
{
mask = MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask");
@@ -862,7 +864,7 @@ static void rigid_add_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2
rigid_add_half_edge_to_R(sys, v2, v1, w);
}
-static void rigid_orthogonalize_R(float R[][3])
+static void rigid_orthogonalize_R(float R[3][3])
{
HMatrix M, Q, S;
@@ -1120,7 +1122,7 @@ typedef struct MeshDeformBind {
typedef struct MeshDeformIsect {
float start[3];
float vec[3];
- float labda;
+ float lambda;
void *face;
int isect;
@@ -1227,7 +1229,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
copy_v3_v3(hit->co, co);
isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f);
- isec->labda = dist;
+ isec->lambda = dist;
isec->face = mf;
}
}
@@ -1245,7 +1247,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
/* setup isec */
memset(&isect_mdef, 0, sizeof(isect_mdef));
- isect_mdef.labda = 1e10f;
+ isect_mdef.lambda = 1e10f;
add_v3_v3v3(isect_mdef.start, co1, epsilon);
add_v3_v3v3(end, co2, epsilon);
@@ -1256,7 +1258,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec,
0.0, &hit, harmonic_ray_callback, data) != -1)
{
- len = isect_mdef.labda;
+ len = isect_mdef.lambda;
isect_mdef.face = mface = mface1 + hit.index;
/* create MDefBoundIsect */
@@ -1767,7 +1769,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi");
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
- mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6);
+ mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6);
mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
@@ -1956,7 +1958,7 @@ static void heat_weighting_bind(Scene *scene, DerivedMesh *dm, MeshDeformModifie
}
#endif
-void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4])
+void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4])
{
MeshDeformBind mdb;
MVert *mvert;
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index ae3d496..04815b9 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -687,9 +687,6 @@ static int poselib_rename_exec(bContext *C, wmOperator *op)
void POSELIB_OT_pose_rename(wmOperatorType *ot)
{
PropertyRNA *prop;
- static EnumPropertyItem prop_poses_dummy_types[] = {
- {0, NULL, 0, NULL, NULL}
- };
/* identifiers */
ot->name = "PoseLib Rename Pose";
@@ -707,7 +704,7 @@ void POSELIB_OT_pose_rename(wmOperatorType *ot)
/* properties */
/* NOTE: name not pose is the operator's "main" property, so that it will get activated in the popup for easy renaming */
ot->prop = RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
- prop = RNA_def_enum(ot->srna, "pose", prop_poses_dummy_types, 0, "Pose", "The pose to rename");
+ prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to rename");
RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 576e598..3892410 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -417,7 +417,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op
{
if (pchan->bone->flag & BONE_SELECTED) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -576,7 +576,7 @@ void POSE_OT_select_hierarchy(wmOperatorType *ot)
/* props */
ot->prop = RNA_def_enum(ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
- RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/* ******************* select grouped operator ************* */
@@ -925,7 +925,7 @@ static void pose_copy_menu(Scene *scene)
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
- copy_constraints(&tmp_constraints, &pchanact->constraints, TRUE);
+ BKE_copy_constraints(&tmp_constraints, &pchanact->constraints, TRUE);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
bConstraint *con;
@@ -1034,7 +1034,7 @@ static void pose_copy_menu(Scene *scene)
/* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
- copy_constraints(&tmp_constraints, &const_copy, TRUE);
+ BKE_copy_constraints(&tmp_constraints, &const_copy, TRUE);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
/* add proxy-local tags */
for (con = tmp_constraints.first; con; con = con->next)
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index b1bf13d..1b5c550 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -634,7 +634,7 @@ static void mergeArcBuckets(ReebArc *aDst, ReebArc *aSrc, float start, float end
if (aDst->bcount > 0 && aSrc->bcount > 0) {
int indexDst = 0, indexSrc = 0;
- start = MAX3(start, aDst->buckets[0].val, aSrc->buckets[0].val);
+ start = max_fff(start, aDst->buckets[0].val, aSrc->buckets[0].val);
while (indexDst < aDst->bcount && aDst->buckets[indexDst].val < start) {
indexDst++;
diff --git a/source/blender/editors/curve/SConscript b/source/blender/editors/curve/SConscript
index 95dd7fc..abefd3c 100644
--- a/source/blender/editors/curve/SConscript
+++ b/source/blender/editors/curve/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 23fed4c..69c4b38 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1022,13 +1022,12 @@ static int curve_is_animated(Curve *cu)
return ad && (ad->action || ad->drivers.first);
}
-static void fcurve_path_rename(AnimData *ad, char *orig_rna_path, char *rna_path, ListBase *orig_curves, ListBase *curves)
+static void fcurve_path_rename(AnimData *adt, char *orig_rna_path, char *rna_path, ListBase *orig_curves, ListBase *curves)
{
FCurve *fcu, *nfcu, *nextfcu;
int len = strlen(orig_rna_path);
- fcu = orig_curves->first;
- while (fcu) {
+ for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
nextfcu = fcu->next;
if (!strncmp(fcu->rna_path, orig_rna_path, len)) {
char *spath, *suffix = fcu->rna_path + len;
@@ -1038,26 +1037,25 @@ static void fcurve_path_rename(AnimData *ad, char *orig_rna_path, char *rna_path
BLI_addtail(curves, nfcu);
if (fcu->grp) {
- action_groups_remove_channel(ad->action, fcu);
- action_groups_add_channel(ad->action, fcu->grp, nfcu);
+ action_groups_remove_channel(adt->action, fcu);
+ action_groups_add_channel(adt->action, fcu->grp, nfcu);
}
- else if (ad->action && &ad->action->curves == orig_curves)
- BLI_remlink(&ad->action->curves, fcu);
+ else if ((adt->action) && (&adt->action->curves == orig_curves))
+ BLI_remlink(&adt->action->curves, fcu);
else
- BLI_remlink(&ad->drivers, fcu);
+ BLI_remlink(&adt->drivers, fcu);
free_fcurve(fcu);
MEM_freeN(spath);
}
- fcu = nextfcu;
}
}
-static void fcurve_remove(AnimData *ad, ListBase *orig_curves, FCurve *fcu)
+static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu)
{
- if (orig_curves == &ad->drivers) BLI_remlink(&ad->drivers, fcu);
- else action_groups_remove_channel(ad->action, fcu);
+ if (orig_curves == &adt->drivers) BLI_remlink(&adt->drivers, fcu);
+ else action_groups_remove_channel(adt->action, fcu);
free_fcurve(fcu);
}
@@ -1073,7 +1071,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
ListBase curves = {NULL, NULL};
FCurve *fcu, *next;
- while (nu) {
+ for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
a = nu->pntsu;
@@ -1126,8 +1124,6 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
pt_index++;
}
}
- nu = nu->next;
- nu_index++;
}
/* remove paths for removed control points
@@ -1144,9 +1140,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
}
}
- nu_index = 0;
- nu = editnurb->nurbs.first;
- while (nu) {
+ for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
keyIndex = NULL;
if (nu->pntsu) {
if (nu->bezt) keyIndex = getCVKeyIndex(editnurb, &nu->bezt[0]);
@@ -1158,9 +1152,6 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index);
fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
}
-
- nu_index++;
- nu = nu->next;
}
/* the remainders in orig_curves can be copied back (like follow path) */
@@ -1493,7 +1484,7 @@ static void setflagsNurb(ListBase *editnurb, short flag)
}
}
-static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3])
+static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[3][3])
{
/* all verts with (flag & 'flag') rotate */
Nurb *nu;
@@ -4278,7 +4269,7 @@ int mouse_nurb(bContext *C, const int mval[2], int extend, int deselect, int tog
/* 'cent' is in object space and 'dvec' in worldspace.
*/
-static int spin_nurb(float viewmat[][4], Object *obedit, float *axis, float *cent)
+static int spin_nurb(float viewmat[4][4], Object *obedit, float *axis, float *cent)
{
Curve *cu = (Curve *)obedit->data;
ListBase *editnurb = object_editcurve_get(obedit);
@@ -5519,7 +5510,7 @@ void CURVE_OT_select_random(wmOperatorType *ot)
/* properties */
RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, "Percent", "Percentage of elements to select randomly", 0.f, 100.0f);
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend Selection", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/********************* every nth number of point *******************/
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index ec20e2d..6d6b7ec 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -46,7 +46,8 @@ if(WITH_BLENDER)
# images
data_to_c_simple(../../../../release/datafiles/splash.png SRC)
- data_to_c_simple(../../../../release/datafiles/blender_icons.png SRC)
+ data_to_c_simple(../../../../release/datafiles/blender_icons16.png SRC)
+ data_to_c_simple(../../../../release/datafiles/blender_icons32.png SRC)
data_to_c_simple(../../../../release/datafiles/prvicons.png SRC)
# brushes
diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript
index e0816f7..cb6fe11 100644
--- a/source/blender/editors/datafiles/SConscript
+++ b/source/blender/editors/datafiles/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
# all source generated now
@@ -14,7 +40,8 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
os.path.join(env['DATA_SOURCES'], "splash.png.c"),
- os.path.join(env['DATA_SOURCES'], "blender_icons.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
os.path.join(env['DATA_SOURCES'], "startup.blend.c"),
diff --git a/source/blender/editors/gpencil/SConscript b/source/blender/editors/gpencil/SConscript
index 9d92a23..f72e124 100644
--- a/source/blender/editors/gpencil/SConscript
+++ b/source/blender/editors/gpencil/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 11e0758..3e092ed 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -45,8 +45,10 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
+#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 8a3c996..0aa109a 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -312,6 +312,13 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin
}
}
+void gpencil_panel_standard_header(const bContext *C, Panel *pa)
+{
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, CTX_wm_space_data(C), &ptr);
+
+ uiItemR(pa->layout, &ptr, "show_grease_pencil", 0, "", ICON_NONE);
+}
/* Standard panel to be included wherever Grease Pencil is used... */
void gpencil_panel_standard(const bContext *C, Panel *pa)
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index e9ca739..e4e640e 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -451,7 +451,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
copy_v3_v3(p3d, &pt->x);
}
else {
- float *fp = give_cursor(scene, v3d);
+ const float *fp = give_cursor(scene, v3d);
float mvalf[2];
/* get screen coordinate */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 8fdca73..c403127 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -208,7 +208,7 @@ static int gpencil_project_check(tGPsdata *p)
static void gp_get_3d_reference(tGPsdata *p, float vec[3])
{
View3D *v3d = p->sa->spacedata.first;
- float *fp = give_cursor(p->scene, v3d);
+ const float *fp = give_cursor(p->scene, v3d);
/* the reference point used depends on the owner... */
#if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index 479e0b6..cdf9b71 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -35,6 +35,14 @@
#include "GL/glew.h"
+#ifdef __APPLE__
+
+/* hacking pointsize and linewidth */
+#define glPointSize(f) glPointSize(U.pixelsize*(f))
+#define glLineWidth(f) glLineWidth(U.pixelsize*(f))
+
+#endif
+
/*
* these should be phased out. cpack should be replaced in
* code with calls to glColor3ub. - zr
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 5771139..31f8906 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -51,10 +51,10 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2);
/* OpenGL stipple defines */
/* OpenGL stipple defines */
-extern unsigned char stipple_halftone[128];
-extern unsigned char stipple_quarttone[128];
-extern unsigned char stipple_diag_stripes_pos[128];
-extern unsigned char stipple_diag_stripes_neg[128];
+extern const unsigned char stipple_halftone[128];
+extern const unsigned char stipple_quarttone[128];
+extern const unsigned char stipple_diag_stripes_pos[128];
+extern const unsigned char stipple_diag_stripes_neg[128];
/**
* Draw a lined (non-looping) arc with the given
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 8d7ae3a..551d304 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -300,34 +300,34 @@ typedef enum eAnimFilter_Flags {
/* -------------- Channel Defines -------------- */
/* channel heights */
-#define ACHANNEL_FIRST -16
-#define ACHANNEL_HEIGHT 16
-#define ACHANNEL_HEIGHT_HALF 8
-#define ACHANNEL_SKIP 2
+#define ACHANNEL_FIRST (-0.8f * U.widget_unit)
+#define ACHANNEL_HEIGHT (0.8f * U.widget_unit)
+#define ACHANNEL_HEIGHT_HALF (0.4f * U.widget_unit)
+#define ACHANNEL_SKIP (0.1f * U.widget_unit)
#define ACHANNEL_STEP (ACHANNEL_HEIGHT + ACHANNEL_SKIP)
/* channel widths */
-#define ACHANNEL_NAMEWIDTH 200
+#define ACHANNEL_NAMEWIDTH (10 * U.widget_unit)
/* channel toggle-buttons */
-#define ACHANNEL_BUTTON_WIDTH 16
+#define ACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit)
/* -------------- NLA Channel Defines -------------- */
/* NLA channel heights */
// XXX: NLACHANNEL_FIRST isn't used?
-#define NLACHANNEL_FIRST -16
-#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 16 : 24)
-#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 8 : 12)
-#define NLACHANNEL_SKIP 2
+#define NLACHANNEL_FIRST (-0.8f * U.widget_unit)
+#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit))
+#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.4f * U.widget_unit) : (0.6f * U.widget_unit))
+#define NLACHANNEL_SKIP (0.1f * U.widget_unit)
#define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP)
/* channel widths */
-#define NLACHANNEL_NAMEWIDTH 200
+#define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit)
/* channel toggle-buttons */
-#define NLACHANNEL_BUTTON_WIDTH 16
+#define NLACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit)
/* ---------------- API -------------------- */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index efd10f3..4db79df 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -184,7 +184,7 @@ int BDR_drawSketchNames(struct ViewContext *vc);
/* meshlaplacian.c */
void mesh_deform_bind(struct Scene *scene,
struct MeshDeformModifierData *mmd,
- float *vertexcos, int totvert, float cagemat[][4]);
+ float *vertexcos, int totvert, float cagemat[4][4]);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index 8ad3639..6d7bcec 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -36,8 +36,11 @@
extern int datatoc_startup_blend_size;
extern char datatoc_startup_blend[];
-extern int datatoc_blender_icons_png_size;
-extern char datatoc_blender_icons_png[];
+extern int datatoc_blender_icons16_png_size;
+extern char datatoc_blender_icons16_png[];
+
+extern int datatoc_blender_icons32_png_size;
+extern char datatoc_blender_icons32_png[];
extern int datatoc_prvicons_png_size;
extern char datatoc_prvicons_png[];
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 5cc1eca..29d4097 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -81,6 +81,7 @@ void draw_gpencil_2dimage(const struct bContext *C);
void draw_gpencil_view2d(const struct bContext *C, short onlyv2d);
void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d);
+void gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa);
void gpencil_panel_standard(const struct bContext *C, struct Panel *pa);
/* ----------- Grease-Pencil AnimEdit API ------------------ */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 865da8f..f5ab002 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -86,11 +86,15 @@ void EDBM_mesh_clear(struct BMEditMesh *em);
void EDBM_selectmode_to_scene(struct bContext *C);
void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob);
-void EDBM_mesh_free(struct BMEditMesh *tm);
+void EDBM_mesh_free(struct BMEditMesh *em);
void EDBM_mesh_load(struct Object *ob);
-void EDBM_index_arrays_init(struct BMEditMesh *em, int forvert, int foredge, int forface);
+void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype);
+void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype);
void EDBM_index_arrays_free(struct BMEditMesh *em);
+#ifndef NDEBUG
+int EDBM_index_arrays_check(struct BMEditMesh *em);
+#endif
struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index);
struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index);
struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index);
@@ -115,7 +119,7 @@ int EDBM_vert_color_check(struct BMEditMesh *em);
void EDBM_mesh_hide(struct BMEditMesh *em, int swap);
void EDBM_mesh_reveal(struct BMEditMesh *em);
-void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short do_tessface);
+void EDBM_update_generic(struct BMEditMesh *em, const short do_tessface, const short is_destructive);
struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands);
void EDBM_uv_element_map_free(struct UvElementMap *vmap);
@@ -126,7 +130,7 @@ struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace *
void EDBM_uv_vert_map_free(struct UvVertMap *vmap);
struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v);
-struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]);
+struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, const float limit[2]);
void EDBM_flag_enable_all(struct BMEditMesh *em, const char hflag);
void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag);
@@ -287,9 +291,9 @@ int mesh_get_x_mirror_vert(struct Object *ob, int index);
struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em, struct BMVert *eve, const float co[3], int index);
int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em);
-int ED_mesh_pick_vert(struct bContext *C, struct Mesh *me, const int mval[2], unsigned int *index, int size);
-int ED_mesh_pick_face(struct bContext *C, struct Mesh *me, const int mval[2], unsigned int *index, int size);
-int ED_mesh_pick_face_vert(struct bContext *C, struct Mesh *me, struct Object *ob, const int mval[2], unsigned int *index, int size);
+int ED_mesh_pick_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf);
+int ED_mesh_pick_face(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size);
+int ED_mesh_pick_face_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size);
#define ED_MESH_PICK_DEFAULT_VERT_SIZE 50
#define ED_MESH_PICK_DEFAULT_FACE_SIZE 3
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 0d0b8d8..533bfe2 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -134,7 +134,7 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]);
void ED_object_rotation_from_view(struct bContext *C, float rot[3]);
void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob,
- const float loc[3], const float rot[3], float primmat[][4],
+ const float loc[3], const float rot[3], float primmat[4][4],
int apply_diameter);
void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 860d176..72208a8 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -64,9 +64,11 @@ void ED_region_panels(const struct bContext *C, struct ARegion *ar, int verti
void ED_region_header_init(struct ARegion *ar);
void ED_region_header(const struct bContext *C, struct ARegion *ar);
void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar);
-void region_scissor_winrct(struct ARegion *ar, struct rcti *winrct);
void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float alpha);
void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
+float ED_region_blend_factor(struct ARegion *ar);
+void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
+
/* spaces */
void ED_spacetypes_init(void);
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index 84fd533..23d173a 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -38,6 +38,8 @@ int ED_space_sequencer_maskedit_mask_poll(struct bContext *C);
int ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene);
int ED_space_sequencer_maskedit_poll(struct bContext *C);
+int ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq);
+
void ED_operatormacros_sequencer(void);
#endif /* __ED_SEQUENCER_H__ */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index d7e9fc3..03c1dd5 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -124,7 +124,7 @@ void BIF_createTransformOrientation(struct bContext *C, struct ReportList *repor
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
-void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[][3], int activeOnly);
+void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], int activeOnly);
struct EnumPropertyItem *BIF_enumTransformOrientation(struct bContext *C);
const char *BIF_menustringTransformOrientation(const struct bContext *C, const char *title); /* the returned value was allocated and needs to be freed after use */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index f15f241..ac2c472 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -85,9 +85,10 @@ typedef struct ViewDepths {
} ViewDepths;
float *give_cursor(struct Scene *scene, struct View3D *v3d);
+void ED_view3d_cursor3d_position(struct bContext *C, float *fp, int mx, int my);
-void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist);
-void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist);
+void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist);
+void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist);
void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
@@ -114,15 +115,20 @@ typedef enum {
V3D_PROJ_TEST_NOP = 0,
V3D_PROJ_TEST_CLIP_BB = (1 << 0),
V3D_PROJ_TEST_CLIP_WIN = (1 << 1),
+ V3D_PROJ_TEST_CLIP_NEAR = (1 << 2),
} eV3DProjTest;
-#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN)
-#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN)
+#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
+#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR)
/* view3d_iterators.c */
/* foreach iterators */
+void meshobject_foreachScreenVert(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct MVert *eve, const float screen_co[2], int index),
+ void *userData, const eV3DProjTest clip_flag);
void mesh_foreachScreenVert(
struct ViewContext *vc,
void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index),
@@ -208,7 +214,7 @@ void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struc
void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]);
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
-void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]);
+void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local);
void ED_view3d_clipping_set(struct RegionView3D *rv3d);
void ED_view3d_clipping_enable(void);
@@ -219,7 +225,7 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]);
float ED_view3d_radius_to_persp_dist(const float angle, const float radius);
float ED_view3d_radius_to_ortho_dist(const float lens, const float radius);
-void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]);
+void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]);
/* backbuffer select and draw support */
void view3d_validate_backbuf(struct ViewContext *vc);
@@ -264,17 +270,17 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
int ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
- int winx, int winy, float viewmat[][4], float winmat[][4], int do_bgpic, int colormanage_background);
+ int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
- int draw_background, int colormanage_background, char err_out[256]);
+ int draw_background, int alpha_mode, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype,
- int draw_background, int colormanage_background, char err_out[256]);
-
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]);
+void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip);
-void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]);
+void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
int ED_view3d_lock(struct RegionView3D *rv3d);
uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
@@ -295,7 +301,8 @@ void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic);
void ED_view3D_background_image_clear(struct View3D *v3d);
#define VIEW3D_MARGIN 1.4f
-float ED_view3d_offset_distance(float mat[4][4], float ofs[3]);
+#define VIEW3D_DIST_FALLBACK 1.0f
+float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback);
float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit);
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 99f7f08..0a79404 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -699,9 +699,7 @@ DEF_ICON(RNDCURVE)
DEF_ICON(PROP_OFF)
DEF_ICON(PROP_ON)
DEF_ICON(PROP_CON)
-#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK212)
-#endif
+DEF_ICON(SCULPT_DYNTOPO)
DEF_ICON(PARTICLE_POINT)
DEF_ICON(PARTICLE_TIP)
DEF_ICON(PARTICLE_PATH)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 2dc552d..292cc4c 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -42,6 +42,7 @@ struct ID;
struct Main;
struct ListBase;
struct ARegion;
+struct ARegionType;
struct ScrArea;
struct wmWindow;
struct wmWindowManager;
@@ -56,6 +57,7 @@ struct PropertyRNA;
struct ReportList;
struct rcti;
struct rctf;
+struct uiList;
struct uiStyle;
struct uiFontStyle;
struct uiWidgetColors;
@@ -175,12 +177,11 @@ typedef struct uiLayout uiLayout;
/* uiBut->drawflag */
#define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */
-/* scale fixed button widths by this to account for DPI
- * 8.4852 == sqrtf(72.0f)) */
-#define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f)
-#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f)
+/* scale fixed button widths by this to account for DPI */
+
+#define UI_DPI_FAC ((U.pixelsize * (float)U.dpi) / 72.0f)
/* 16 to copy ICON_DEFAULT_HEIGHT */
-#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC)
+#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_FAC)
/* Button types, bits stored in 1 value... and a short even!
* - bits 0-4: bitnr (0-31)
@@ -253,7 +254,8 @@ typedef enum {
HISTOGRAM = (48 << 9),
WAVEFORM = (49 << 9),
VECTORSCOPE = (50 << 9),
- PROGRESSBAR = (51 << 9)
+ PROGRESSBAR = (51 << 9),
+ SEARCH_MENU_UNLINK = (52 << 9)
} eButType;
#define BUTTYPE (63 << 9)
@@ -287,7 +289,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float
#define UI_SCROLL_PRESSED 1
#define UI_SCROLL_ARROWS 2
#define UI_SCROLL_NO_OUTLINE 4
-void uiWidgetScrollDraw(struct uiWidgetColors *wcol, struct rcti *rect, struct rcti *slider, int state);
+void uiWidgetScrollDraw(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state);
/* Callbacks
*
@@ -659,6 +661,7 @@ void uiDrawPanels(const struct bContext *C, struct ARegion *ar);
struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open);
void uiEndPanel(uiBlock *block, int width, int height);
+void uiScalePanels(struct ARegion *ar, float new_width);
/* Handlers
*
@@ -779,7 +782,7 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align);
uiLayout *uiLayoutColumn(uiLayout *layout, int align);
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align);
uiLayout *uiLayoutBox(uiLayout *layout);
-uiLayout *uiLayoutListBox(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop,
+uiLayout *uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct PointerRNA *ptr, struct PropertyRNA *prop,
struct PointerRNA *actptr, struct PropertyRNA *actprop);
uiLayout *uiLayoutAbsolute(uiLayout *layout, int align);
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align);
@@ -825,7 +828,9 @@ void uiTemplateTextureImage(uiLayout *layout, struct bContext *C, struct Tex *te
void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
-void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type);
+void uiTemplateList(uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id,
+ struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr,
+ const char *active_propname, int rows, int maxrows, int layout_type);
void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
void uiTemplateTextureUser(uiLayout *layout, struct bContext *C);
@@ -885,7 +890,7 @@ void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct Prop
/* Styled text draw */
void uiStyleFontSet(struct uiFontStyle *fs);
-void uiStyleFontDrawExt(struct uiFontStyle *fs, struct rcti *rect, const char *str,
+void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str,
float *r_xofs, float *r_yofs);
void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, const char *str);
void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const char *str);
@@ -893,7 +898,10 @@ void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const cha
int UI_GetStringWidth(const char *str); // XXX temp
void UI_DrawString(float x, float y, const char *str); // XXX temp
void UI_DrawTriIcon(float x, float y, char dir);
-uiStyle *UI_GetStyle(void);
+
+uiStyle *UI_GetStyle(void); /* use for fonts etc */
+uiStyle *UI_GetStyleDraw(void); /* DPI scaled settings for drawing */
+
/* linker workaround ack! */
void UI_template_fix_linking(void);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index aa94bde..f578d68 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -32,12 +32,14 @@
#ifndef __UI_INTERFACE_ICONS_H__
#define __UI_INTERFACE_ICONS_H__
+struct bContext;
struct Image;
struct ImBuf;
struct World;
struct Tex;
struct Lamp;
struct Material;
+struct PointerRNA;
typedef struct IconFile {
struct IconFile *next, *prev;
@@ -74,5 +76,6 @@ void UI_icons_free_drawinfo(void *drawinfo);
struct ListBase *UI_iconfile_list(void);
int UI_iconfile_get_index(const char *filename);
+int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big);
#endif /* __UI_INTERFACE_ICONS_H__ */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index f4e921e..7e7be17 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -64,10 +64,11 @@ enum {
TH_HEADER_TEXT,
TH_HEADER_TEXT_HI,
- /* float panels */
- TH_PANEL,
- TH_PANEL_TEXT,
- TH_PANEL_TEXT_HI,
+ /* panels */
+ TH_PANEL_HEADER,
+ TH_PANEL_BACK,
+ TH_PANEL_SHOW_HEADER,
+ TH_PANEL_SHOW_BACK,
TH_BUTBACK,
TH_BUTBACK_TEXT,
@@ -121,9 +122,12 @@ enum {
TH_SYNTAX_B,
TH_SYNTAX_V,
+ TH_SYNTAX_R,
TH_SYNTAX_C,
TH_SYNTAX_L,
+ TH_SYNTAX_D,
TH_SYNTAX_N,
+ TH_SYNTAX_S,
TH_BONE_SOLID,
TH_BONE_POSE,
@@ -219,7 +223,11 @@ enum {
TH_AXIS_X, /* X/Y/Z Axis */
TH_AXIS_Y,
- TH_AXIS_Z
+ TH_AXIS_Z,
+
+ TH_LOW_GRAD,
+ TH_HIGH_GRAD,
+ TH_SHOW_BACK_GRAD
};
/* XXX WARNING: previous is saved in file, so do not change order! */
@@ -286,6 +294,9 @@ void UI_SetTheme(int spacetype, int regionid);
// get current theme
struct bTheme *UI_GetTheme(void);
+// return shadow width outside menus and popups */
+int UI_ThemeMenuShadowWidth(void);
+
/* only for buttons in theme editor! */
const unsigned char *UI_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 24759fa..81a0f52 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -102,11 +102,11 @@ enum {
/* ------ Defines for Scrollers ----- */
/* scroller area */
-#define V2D_SCROLL_HEIGHT 17
-#define V2D_SCROLL_WIDTH 17
+#define V2D_SCROLL_HEIGHT (0.85f * U.widget_unit)
+#define V2D_SCROLL_WIDTH (0.85f * U.widget_unit)
/* scroller 'handles' hotspot radius for mouse */
-#define V2D_SCROLLER_HANDLE_SIZE 12
+#define V2D_SCROLLER_HANDLE_SIZE (0.6f * U.widget_unit)
/* ------ Define for UI_view2d_sync ----- */
@@ -132,6 +132,7 @@ struct View2DScrollers;
struct wmKeyConfig;
struct bScreen;
+struct Scene;
struct ScrArea;
struct ARegion;
struct bContext;
@@ -147,7 +148,6 @@ typedef struct View2DScrollers View2DScrollers;
void UI_view2d_region_reinit(struct View2D *v2d, short type, int winx, int winy);
void UI_view2d_curRect_validate(struct View2D *v2d);
-void UI_view2d_curRect_validate_resize(struct View2D *v2d, int resize);
void UI_view2d_curRect_reset(struct View2D *v2d);
void UI_view2d_sync(struct bScreen *screen, struct ScrArea *sa, struct View2D *v2dcur, int flag);
@@ -198,6 +198,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C);
struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C);
void UI_view2d_getscale(struct View2D *v2d, float *x, float *y);
+void UI_view2d_getscale_inverse(struct View2D *v2d, float *x, float *y);
short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, int x, int y);
diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript
index 2d6d5cd..8d277d6 100644
--- a/source/blender/editors/interface/SConscript
+++ b/source/blender/editors/interface/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index ce82e06..1dee497 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -69,7 +69,6 @@
#include "WM_api.h"
#include "WM_types.h"
#include "wm_subwindow.h"
-#include "wm_window.h"
#include "RNA_access.h"
@@ -298,9 +297,9 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
/* note: this is used for the splash where window bounds event has not been
* updated by ghost, get the window bounds from ghost directly */
- // wm_window_get_size(window, &xmax, &ymax);
- wm_window_get_size_ghost(window, &xmax, &ymax);
-
+ xmax = WM_window_pixels_x(window);
+ ymax = WM_window_pixels_y(window);
+
ui_bounds_block(block);
width = BLI_rctf_size_x(&block->rect);
@@ -326,7 +325,8 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
/* compute mouse position with user defined offset */
ui_bounds_block(block);
- wm_window_get_size(window, &xmax, &ymax);
+ xmax = WM_window_pixels_x(window);
+ ymax = WM_window_pixels_y(window);
oldwidth = BLI_rctf_size_x(&block->rect);
oldheight = BLI_rctf_size_y(&block->rect);
@@ -334,7 +334,7 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound
/* first we ensure wide enough text bounds */
if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) {
if (block->flag & UI_BLOCK_LOOP) {
- block->bounds = 50;
+ block->bounds = 2.5f * UI_UNIT_X;
ui_text_bounds_block(block, block->rect.xmin);
}
}
@@ -983,7 +983,8 @@ void ui_fontscale(short *points, float aspect)
float pointsf = *points;
/* for some reason scaling fonts goes too fast compared to widget size */
- aspect = sqrt(aspect);
+ /* XXX not true anymore? (ton) */
+ //aspect = sqrt(aspect);
pointsf /= aspect;
if (aspect > 1.0f)
@@ -1000,7 +1001,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin);
ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax);
-
+
rectf.xmin -= ar->winrct.xmin;
rectf.ymin -= ar->winrct.ymin;
rectf.xmax -= ar->winrct.xmin;
@@ -1015,7 +1016,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
/* uses local copy of style, to scale things down, and allow widgets to change stuff */
void uiDrawBlock(const bContext *C, uiBlock *block)
{
- uiStyle style = *UI_GetStyle(); /* XXX pass on as arg */
+ uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */
ARegion *ar;
uiBut *but;
rcti rect;
@@ -1290,7 +1291,7 @@ void ui_delete_linkline(uiLinkLine *line, uiBut *but)
void ui_get_but_vectorf(uiBut *but, float vec[3])
{
PropertyRNA *prop;
- int a, tot;
+ int a;
if (but->editvec) {
copy_v3_v3(vec, but->editvec);
@@ -1299,18 +1300,25 @@ void ui_get_but_vectorf(uiBut *but, float vec[3])
if (but->rnaprop) {
prop = but->rnaprop;
- vec[0] = vec[1] = vec[2] = 0.0f;
+ zero_v3(vec);
if (RNA_property_type(prop) == PROP_FLOAT) {
- tot = RNA_property_array_length(&but->rnapoin, prop);
- tot = min_ii(tot, 3);
-
- for (a = 0; a < tot; a++)
- vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
+ int tot = RNA_property_array_length(&but->rnapoin, prop);
+ BLI_assert(tot > 0);
+ if (tot == 3) {
+ RNA_property_float_get_array(&but->rnapoin, prop, vec);
+ }
+ else {
+ tot = min_ii(tot, 3);
+ for (a = 0; a < tot; a++) {
+ vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
+ }
+ }
}
}
else if (but->pointype == UI_BUT_POIN_CHAR) {
char *cp = (char *)but->poin;
+
vec[0] = ((float)cp[0]) / 255.0f;
vec[1] = ((float)cp[1]) / 255.0f;
vec[2] = ((float)cp[2]) / 255.0f;
@@ -1321,8 +1329,8 @@ void ui_get_but_vectorf(uiBut *but, float vec[3])
}
else {
if (but->editvec == NULL) {
- fprintf(stderr, "ui_get_but_vectorf: can't get color, should never happen\n");
- vec[0] = vec[1] = vec[2] = 0.0f;
+ fprintf(stderr, "%s: can't get color, should never happen\n", __func__);
+ zero_v3(vec);
}
}
@@ -1348,10 +1356,15 @@ void ui_set_but_vectorf(uiBut *but, const float vec[3])
int a;
tot = RNA_property_array_length(&but->rnapoin, prop);
- tot = min_ii(tot, 3);
-
- for (a = 0; a < tot; a++) {
- RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
+ BLI_assert(tot > 0);
+ if (tot == 3) {
+ RNA_property_float_set_array(&but->rnapoin, prop, vec);
+ }
+ else {
+ tot = min_ii(tot, 3);
+ for (a = 0; a < tot; a++) {
+ RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
+ }
}
}
}
@@ -1592,7 +1605,7 @@ void ui_set_but_val(uiBut *but, double value)
int ui_get_but_string_max_length(uiBut *but)
{
- if (ELEM(but->type, TEX, SEARCH_MENU))
+ if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK))
return but->hardmax;
else if (but->type == IDPOIN)
return MAX_ID_NAME - 2;
@@ -1675,7 +1688,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
{
- if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
PropertyType type;
const char *buf = NULL;
int buf_len;
@@ -1729,7 +1742,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
BLI_strncpy(str, but->poin, maxlen);
return;
}
- else if (but->type == SEARCH_MENU) {
+ else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(str, but->poin, maxlen);
return;
@@ -1820,7 +1833,7 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double
int ui_set_but_string(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
PropertyType type;
@@ -1877,7 +1890,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
return 1;
}
- else if (but->type == SEARCH_MENU) {
+ else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(but->poin, str, but->hardmax);
return 1;
@@ -2347,6 +2360,7 @@ void ui_check_but(uiBut *but)
case IDPOIN:
case TEX:
case SEARCH_MENU:
+ case SEARCH_MENU_UNLINK:
if (!but->editstr) {
char str[UI_MAX_DRAW_STR];
@@ -2650,9 +2664,11 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
BLI_assert(width >= 0);
BLI_assert(height >= 0);
-
+
/* we could do some more error checks here */
if ((type & BUTTYPE) == LABEL) {
+ if ((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)))
+ printf("blah\n");
BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE);
}
@@ -2726,7 +2742,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
if ((block->flag & UI_BLOCK_LOOP) ||
- ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR))
+ ELEM9(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK))
{
but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT);
}
@@ -2786,6 +2802,10 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
uiBut *but;
int freestr = 0, icon = 0;
+ if (ELEM3(type, COLOR, HSVCIRCLE, HSVCUBE)) {
+ BLI_assert(index == -1);
+ }
+
/* use rna values if parameters are not specified */
if (!str) {
if (type == MENU && proptype == PROP_ENUM) {
@@ -2826,12 +2846,13 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
EnumPropertyItem *item;
int i, totitem, free;
- /* TODO, translate after getting the item, saves many lookups */
- RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
+ /* get untranslated, then translate the single string we need */
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
for (i = 0; i < totitem; i++) {
if (item[i].identifier[0] && item[i].value == (int)max) {
- str = item[i].name;
+ str = CTX_IFACE_(RNA_property_translation_context(prop), item[i].name);
icon = item[i].icon;
+ break;
}
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 4d96ad8..792553f 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -429,17 +429,18 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
#else
ImBuf *ibuf = (ImBuf *)but->poin;
//GLint scissor[4];
- //int w, h;
+ int w, h;
if (!ibuf) return;
+ w = BLI_rcti_size_x(rect);
+ h = BLI_rcti_size_y(rect);
+
/* scissor doesn't seem to be doing the right thing...? */
#if 0
//glColor4f(1.0, 0.f, 0.f, 1.f);
//fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax)
- w = BLI_rcti_size_x(rect);
- h = BLI_rcti_size_y(rect);
/* prevent drawing outside widget area */
glGetIntegerv(GL_SCISSOR_BOX, scissor);
glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h);
@@ -448,9 +449,16 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
glEnable(GL_BLEND);
glColor4f(0.0, 0.0, 0.0, 0.0);
+ if (w != ibuf->x || h != ibuf->y) {
+ float facx = (float)w / (float)ibuf->x;
+ float facy = (float)h / (float)ibuf->y;
+ glPixelZoom(facx, facy);
+ }
glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
//glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glPixelZoom(1.0f, 1.0f);
+
glDisable(GL_BLEND);
#if 0
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 319116b..c87bb2a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -44,6 +44,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -219,6 +220,30 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but);
/* ******************** menu navigation helpers ************** */
+/* assumes event type is MOUSEPAN */
+void ui_pan_to_scroll(wmEvent *event, int *type, int *val)
+{
+ static int lastdy = 0;
+ int dy = event->prevy - event->y;
+
+ /* sign differs, reset */
+ if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0))
+ lastdy = dy;
+ else {
+ lastdy += dy;
+
+ if (ABS(lastdy) > (int)UI_UNIT_Y) {
+ *val = KM_PRESS;
+ if (event->prevy - event->y > 0)
+ *type = WHEELUPMOUSE;
+ else
+ *type = WHEELDOWNMOUSE;
+
+ lastdy = 0;
+ }
+ }
+}
+
static int ui_but_editable(uiBut *but)
{
return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
@@ -397,6 +422,17 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but)
/* try autokey */
ui_but_anim_autokey(C, but, scene, scene->r.cfra);
+
+ /* make a little report about what we've done! */
+ if (but->rnaprop) {
+ char *buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
+ if (buf) {
+ BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf);
+ MEM_freeN(buf);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
+ }
+ }
}
static void ui_apply_but_funcs_after(bContext *C)
@@ -1026,6 +1062,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
ui_apply_but_BUT(C, but, data);
break;
case TEX:
+ case SEARCH_MENU_UNLINK:
case SEARCH_MENU:
ui_apply_but_TEX(C, but, data);
break;
@@ -1133,7 +1170,7 @@ static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonD
for (wmd = drags->first; wmd; wmd = wmd->next) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ID *id = (ID *)wmd->poin;
if (but->poin == NULL && but->rnapoin.data == NULL) {}
@@ -1197,37 +1234,44 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* RGB triple */
else if (but->type == COLOR) {
- float rgb[3];
+ float rgba[4];
if (but->poin == NULL && but->rnapoin.data == NULL) {
/* pass */
}
else if (mode == 'c') {
-
- ui_get_but_vectorf(but, rgb);
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ rgba[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
+ else
+ rgba[3] = 1.0f;
+
+ ui_get_but_vectorf(but, rgba);
/* convert to linear color to do compatible copy between gamma and non-gamma */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
- srgb_to_linearrgb_v3_v3(rgb, rgb);
+ srgb_to_linearrgb_v3_v3(rgba, rgba);
- BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f]", rgb[0], rgb[1], rgb[2]);
+ BLI_snprintf(buf, sizeof(buf), "[%f, %f, %f, %f]", rgba[0], rgba[1], rgba[2], rgba[3]);
WM_clipboard_text_set(buf, 0);
}
else {
- if (sscanf(buf, "[%f, %f, %f]", &rgb[0], &rgb[1], &rgb[2]) == 3) {
+ if (sscanf(buf, "[%f, %f, %f, %f]", &rgba[0], &rgba[1], &rgba[2], &rgba[3]) == 4) {
/* assume linear colors in buffer */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
- linearrgb_to_srgb_v3_v3(rgb, rgb);
+ linearrgb_to_srgb_v3_v3(rgba, rgba);
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- ui_set_but_vectorf(but, rgb);
+ ui_set_but_vectorf(but, rgba);
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
+ RNA_property_float_set_index(&but->rnapoin, but->rnaprop, 3, rgba[3]);
+
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
}
/* text/string and ID data */
- else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ else if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
uiHandleButtonData *active_data = but->active;
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1246,7 +1290,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen);
else BLI_strncpy(active_data->str, buf, active_data->maxlen);
- if (but->type == SEARCH_MENU) {
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* else uiSearchboxData.active member is not updated [#26856] */
ui_searchbox_update(C, data->searchbox, but, 1);
}
@@ -1393,7 +1437,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
/* XXX solve generic */
if (but->type == NUM || but->type == NUMSLI)
startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect)));
- else if (ELEM(but->type, TEX, SEARCH_MENU)) {
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
startx += 5;
if (but->flag & UI_HAS_ICON)
startx += UI_DPI_ICON_SIZE;
@@ -1674,10 +1718,11 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
{
char buf[UI_MAX_DRAW_STR] = {0};
char *str, *p, *pbuf;
- int len, x, i, changed = 0;
+ int x, changed = 0;
+ int str_len, buf_len;
str = data->str;
- len = strlen(str);
+ str_len = strlen(str);
/* paste */
if (paste) {
@@ -1687,28 +1732,28 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste
if (p && p[0]) {
unsigned int y;
- i = 0;
- while (*p && *p != '\r' && *p != '\n' && i < UI_MAX_DRAW_STR - 1) {
- buf[i++] = *p;
+ buf_len = 0;
+ while (*p && *p != '\r' && *p != '\n' && buf_len < UI_MAX_DRAW_STR - 1) {
+ buf[buf_len++] = *p;
p++;
}
- buf[i] = 0;
+ buf[buf_len] = 0;
/* paste over the current selection */
if ((but->selend - but->selsta) > 0) {
ui_textedit_delete_selection(but, data);
- len = strlen(str);
+ str_len = strlen(str);
}
- for (y = 0; y < strlen(buf); y++) {
+ for (y = 0; y < buf_len; y++) {
/* add contents of buffer */
- if (len + 1 < data->maxlen) {
+ if (str_len + 1 < data->maxlen) {
for (x = data->maxlen; x > but->pos; x--)
str[x] = str[x - 1];
str[but->pos] = buf[y];
but->pos++;
- len++;
- str[len] = '\0';
+ str_len++;
+ str[str_len] = '\0';
}
}
@@ -1772,7 +1817,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
but->selend = len;
/* optional searchbox */
- if (but->type == SEARCH_MENU) {
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
data->searchbox = ui_searchbox_create(C, data->region, but);
ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */
}
@@ -1818,7 +1863,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
return;
for (but = actbut->next; but; but = but->next) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1827,7 +1872,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.first; but != actbut; but = but->next) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1846,7 +1891,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
return;
for (but = actbut->prev; but; but = but->prev) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1855,7 +1900,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.last; but != actbut; but = but->prev) {
- if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
+ if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -1874,6 +1919,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
case MOUSEMOVE:
+ case MOUSEPAN:
if (data->searchbox)
ui_searchbox_event(C, data->searchbox, but, event);
@@ -2385,6 +2431,34 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return WM_UI_HANDLER_CONTINUE;
}
+static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+ /* unlink icon is on right */
+ if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
+ ARegion *ar = CTX_wm_region(C);
+ rcti rect;
+ int x = event->x, y = event->y;
+
+ ui_window_to_block(ar, but->block, &x, &y);
+
+ BLI_rcti_rctf_copy(&rect, &but->rect);
+
+ rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
+ if ( BLI_rcti_isect_pt(&rect, x, y) ) {
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (data->str == NULL)
+ data->str = MEM_callocN(16, "temp str");
+ data->str[0] = 0;
+
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ return ui_do_but_TEX(C, block, but, data, event);
+}
+
static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -2668,12 +2742,18 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ ui_pan_to_scroll(event, &type, &val);
+
/* XXX hardcoded keymap check.... */
- if (event->type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 1;
}
- else if (event->type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->alt) {
mx = but->rect.xmax;
click = 1;
}
@@ -2892,12 +2972,18 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ ui_pan_to_scroll(event, &type, &val);
+
/* XXX hardcoded keymap check.... */
- if (event->type == WHEELDOWNMOUSE && event->alt) {
+ if (type == MOUSEPAN && event->alt)
+ retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
+ else if (type == WHEELDOWNMOUSE && event->alt) {
mx = but->rect.xmin;
click = 2;
}
- else if (event->type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->alt) {
mx = but->rect.xmax;
click = 2;
}
@@ -3123,7 +3209,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
}
}
else if (but->type == COLOR) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
float *hsv = ui_block_hsv_get(but->block);
float col[3];
@@ -3132,8 +3218,12 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
if (event->type == WHEELDOWNMOUSE)
hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f);
- else
+ else if (event->type == WHEELUPMOUSE)
hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f);
+ else {
+ float fac = 0.005 * (event->y - event->prevy);
+ hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f);
+ }
hsv_to_rgb_v(hsv, data->vec);
ui_set_but_vectorf(but, data->vec);
@@ -4530,7 +4620,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
@@ -4562,7 +4652,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id;
@@ -5077,6 +5167,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case SEARCH_MENU:
retval = ui_do_but_TEX(C, block, but, data, event);
break;
+ case SEARCH_MENU_UNLINK:
+ retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
+ break;
case MENU:
case ICONROW:
case ICONTEXTROW:
@@ -5190,7 +5283,7 @@ int UI_but_active_drop_name(bContext *C)
uiBut *but = ui_but_find_activated(ar);
if (but) {
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU))
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK))
return 1;
}
@@ -5229,32 +5322,15 @@ static int ui_mouse_inside_region(ARegion *ar, int x, int y)
*/
if (ar->v2d.mask.xmin != ar->v2d.mask.xmax) {
View2D *v2d = &ar->v2d;
- rcti mask_rct;
int mx, my;
/* convert window coordinates to region coordinates */
mx = x;
my = y;
ui_window_to_region(ar, &mx, &my);
-
- /* make a copy of the mask rect, and tweak accordingly for hidden scrollbars */
- mask_rct = v2d->mask;
-
- if (v2d->scroll & (V2D_SCROLL_VERTICAL_HIDE | V2D_SCROLL_VERTICAL_FULLR)) {
- if (v2d->scroll & V2D_SCROLL_LEFT)
- mask_rct.xmin = v2d->vert.xmin;
- else if (v2d->scroll & V2D_SCROLL_RIGHT)
- mask_rct.xmax = v2d->vert.xmax;
- }
- if (v2d->scroll & (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_HORIZONTAL_FULLR)) {
- if (v2d->scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O))
- mask_rct.ymin = v2d->hor.ymin;
- else if (v2d->scroll & V2D_SCROLL_TOP)
- mask_rct.ymax = v2d->hor.ymax;
- }
-
+
/* check if in the rect */
- if (!BLI_rcti_isect_pt(&mask_rct, mx, my))
+ if (!BLI_rcti_isect_pt(&v2d->mask, mx, my))
return 0;
}
@@ -5533,7 +5609,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) {
+ if (ELEM3(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* XXX curve is temp */
}
else {
@@ -5971,19 +6047,18 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
retval = WM_UI_HANDLER_CONTINUE;
break;
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- case MIDDLEMOUSE:
- /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
- if (data->tooltiptimer) {
- WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
- data->tooltiptimer = NULL;
- }
- /* pass on purposedly */
- default:
- /* handle button type specific events */
- retval = ui_do_button(C, block, but, event);
}
+ /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ case MIDDLEMOUSE:
+ case MOUSEPAN:
+ button_timers_tooltip_remove(C, but);
+
+ /* pass on purposedly */
+ default:
+ /* handle button type specific events */
+ retval = ui_do_button(C, block, but, event);
}
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
@@ -6090,64 +6165,81 @@ static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
uiBut *but = ui_list_find_mouse_over(ar, event->x, event->y);
int retval = WM_UI_HANDLER_CONTINUE;
int value, min, max;
+ int type = event->type, val = event->val;
- if (but && (event->val == KM_PRESS)) {
- Panel *pa = but->block->panel;
+ if (but) {
+ uiList *ui_list = but->custom_data;
- if (ELEM(event->type, UPARROWKEY, DOWNARROWKEY) ||
- ((ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
- {
- /* activate up/down the list */
- value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ if (ui_list) {
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+
+ /* if type still is mousepan, we call it handled, since delta-y accumulate */
+ /* also see wm_event_system.c do_wheel_ui hack */
+ if (type == MOUSEPAN)
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ if (val == KM_PRESS) {
+
+ if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
+ {
+ /* activate up/down the list */
+ value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
- if (ELEM(event->type, UPARROWKEY, WHEELUPMOUSE))
- value--;
- else
- value++;
+ if (ELEM(type, UPARROWKEY, WHEELUPMOUSE))
+ value--;
+ else
+ value++;
- CLAMP(value, 0, pa->list_last_len - 1);
+ CLAMP(value, 0, ui_list->list_last_len - 1);
- if (value < pa->list_scroll)
- pa->list_scroll = value;
- else if (value >= pa->list_scroll + pa->list_size)
- pa->list_scroll = value - pa->list_size + 1;
+ if (value < ui_list->list_scroll)
+ ui_list->list_scroll = value;
+ else if (value >= ui_list->list_scroll + ui_list->list_size)
+ ui_list->list_scroll = value - ui_list->list_size + 1;
- RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
- value = CLAMPIS(value, min, max);
+ RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
+ value = CLAMPIS(value, min, max);
- RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- ED_region_tag_redraw(ar);
+ RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
- /* silly replacement for proper grip */
- if (pa->list_grip_size == 0)
- pa->list_grip_size = pa->list_size;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
+ /* silly replacement for proper grip */
+ if (ui_list->list_grip_size == 0)
+ ui_list->list_grip_size = ui_list->list_size;
- if (event->type == WHEELUPMOUSE)
- pa->list_grip_size--;
- else
- pa->list_grip_size++;
+ if (type == WHEELUPMOUSE)
+ ui_list->list_grip_size--;
+ else
+ ui_list->list_grip_size++;
- pa->list_grip_size = MAX2(pa->list_grip_size, 1);
+ ui_list->list_grip_size = MAX2(ui_list->list_grip_size, 1);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- if (pa->list_last_len > pa->list_size) {
- /* list template will clamp */
- if (event->type == WHEELUPMOUSE)
- pa->list_scroll--;
- else
- pa->list_scroll++;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ if (ui_list->list_last_len > ui_list->list_size) {
+ /* list template will clamp */
+ if (type == WHEELUPMOUSE)
+ ui_list->list_scroll--;
+ else
+ ui_list->list_scroll++;
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
}
}
}
@@ -6327,7 +6419,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymax = max_ff(ymax, bt->rect.ymax);
- if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
+ if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD)
dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD;
}
else {
@@ -6337,7 +6429,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
for (bt = block->buttons.first; bt; bt = bt->next)
ymin = min_ff(ymin, bt->rect.ymin);
- if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
+ if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD)
dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
}
@@ -6380,7 +6472,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
/* if there's an active modal button, don't check events or outside, except for search menu */
but = ui_but_find_activated(ar);
- if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU) {
+ if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK) {
/* if a button is activated modal, always reset the start mouse
* position of the towards mechanism to avoid loosing focus,
* and don't handle events */
@@ -6406,7 +6498,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
if (block->block_event_func && block->block_event_func(C, block, event)) {
/* pass */
} /* events not for active search menu button */
- else if (but == NULL || but->type != SEARCH_MENU) {
+ else if (but == NULL || (but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK)) {
switch (event->type) {
@@ -6453,21 +6545,29 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
case DOWNARROWKEY:
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
+ case MOUSEPAN:
/* arrowkeys: only handle for block_loop blocks */
if (event->alt || event->shift || event->ctrl || event->oskey) {
/* pass */
}
else if (inside || (block->flag & UI_BLOCK_LOOP)) {
- if (event->val == KM_PRESS) {
+ int type = event->type;
+ int val = event->val;
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN)
+ ui_pan_to_scroll(event, &type, &val);
+
+ if (val == KM_PRESS) {
PASS_EVENT_TO_PARENT_IF_NONACTIVE;
but = ui_but_find_activated(ar);
if (but) {
/* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */
- if (((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP)))
+ if (((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) ||
+ ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) ||
+ ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP)))
{
/* the following is just a hack - uiBut->type set to BUT and BUTM have there menus built
* opposite ways - this should be changed so that all popup-menus use the same uiBlock->direction */
@@ -6490,9 +6590,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
}
if (!but) {
- if (((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(event->type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(event->type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP)))
+ if (((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) ||
+ ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) ||
+ ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP)))
{
if ((bt = ui_but_first(block)) && (bt->type & BUT)) {
bt = ui_but_last(block);
@@ -6909,8 +7009,6 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
{
ARegion *ar;
uiBut *but;
- uiHandleButtonData *data;
- int retval;
/* here we handle buttons at the window level, modal, for example
* while number sliding, text editing, or when a menu block is open */
@@ -6921,17 +7019,23 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user
but = ui_but_find_activated(ar);
if (but) {
+ uiHandleButtonData *data;
+
/* handle activated button events */
data = but->active;
if (data->state == BUTTON_STATE_MENU_OPEN) {
+ int retval;
+
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
if (data->menu)
retval = ui_handle_menus_recursive(C, event, data->menu, 0);
/* handle events for the activated button */
- if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
+ if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
+ (event->type == TIMER))
+ {
if (data->menu && data->menu->menuretval)
ui_handle_button_return_submenu(C, event, but);
else
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index bb0cc11..6878008 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -49,6 +49,7 @@
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
+#include "DNA_dynamicpaint_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -75,15 +76,15 @@
#include "interface_intern.h"
-#define ICON_IMAGE_W 600
-#define ICON_IMAGE_H 640
+// #define ICON_IMAGE_W 600
+// #define ICON_IMAGE_H 640
#define ICON_GRID_COLS 26
#define ICON_GRID_ROWS 30
-#define ICON_GRID_MARGIN 5
-#define ICON_GRID_W 16
-#define ICON_GRID_H 16
+#define ICON_GRID_MARGIN 10
+#define ICON_GRID_W 32
+#define ICON_GRID_H 32
typedef struct IconImage {
int w;
@@ -467,7 +468,10 @@ static void init_brush_icons(void)
bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_ ##name## _png, \
datatoc_ ##name## _png_size, \
IB_rect, NULL, "<brush icon>"); \
- def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
+ if (bbuf) { \
+ IMB_premultiply_alpha(bbuf); \
+ def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
+ } \
IMB_freeImBuf(bbuf); \
} (void)0
/* end INIT_BRUSH_ICON */
@@ -511,13 +515,15 @@ static void init_brush_icons(void)
static void init_internal_icons(void)
{
- bTheme *btheme = UI_GetTheme();
- ImBuf *bbuf = NULL;
+// bTheme *btheme = UI_GetTheme();
+ ImBuf *b16buf = NULL, *b32buf = NULL;
int x, y, icontype;
- char iconfilestr[FILE_MAX];
-
+
+#if 0 // temp disabled
if ((btheme != NULL) && btheme->tui.iconfile[0]) {
char *icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
+ char iconfilestr[FILE_MAX];
+
if (icondir) {
BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); /* if the image is missing bbuf will just be NULL */
@@ -531,11 +537,20 @@ static void init_internal_icons(void)
printf("%s: 'icons' data path not found, continuing\n", __func__);
}
}
- if (bbuf == NULL)
- bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png,
- datatoc_blender_icons_png_size, IB_rect, NULL, "<blender icons>");
-
- if (bbuf) {
+#endif
+ if (b16buf == NULL)
+ b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png,
+ datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
+ if (b16buf)
+ IMB_premultiply_alpha(b16buf);
+
+ if (b32buf == NULL)
+ b32buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons32_png,
+ datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>");
+ if (b32buf)
+ IMB_premultiply_alpha(b32buf);
+
+ if (b16buf && b32buf) {
/* free existing texture if any */
if (icongltex.id) {
glDeleteTextures(1, &icongltex.id);
@@ -547,17 +562,31 @@ static void init_internal_icons(void)
glGenTextures(1, &icongltex.id);
if (icongltex.id) {
- icongltex.w = bbuf->x;
- icongltex.h = bbuf->y;
- icongltex.invw = 1.0f / bbuf->x;
- icongltex.invh = 1.0f / bbuf->y;
+ int level = 2;
+
+ icongltex.w = b32buf->x;
+ icongltex.h = b32buf->y;
+ icongltex.invw = 1.0f / b32buf->x;
+ icongltex.invh = 1.0f / b32buf->y;
glBindTexture(GL_TEXTURE_2D, icongltex.id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bbuf->x, bbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect);
+ glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect);
+
+ while (b16buf->x > 1) {
+ ImBuf *nbuf = IMB_onehalf(b16buf);
+ glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect);
+ level++;
+ IMB_freeImBuf(b16buf);
+ b16buf = nbuf;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
glBindTexture(GL_TEXTURE_2D, 0);
-
+
if (glGetError() == GL_OUT_OF_MEMORY) {
glDeleteTextures(1, &icongltex.id);
icongltex.id = 0;
@@ -571,10 +600,10 @@ static void init_internal_icons(void)
else
icontype = ICON_TYPE_BUFFER;
- if (bbuf) {
+ if (b32buf) {
for (y = 0; y < ICON_GRID_ROWS; y++) {
for (x = 0; x < ICON_GRID_COLS; x++) {
- def_internal_icon(bbuf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
+ def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W,
icontype);
@@ -593,7 +622,9 @@ static void init_internal_icons(void)
def_internal_vicon(VICO_X_VEC, vicon_x_draw);
def_internal_vicon(VICO_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);
- IMB_freeImBuf(bbuf);
+ IMB_freeImBuf(b16buf);
+ IMB_freeImBuf(b32buf);
+
}
#endif /* WITH_HEADLESS */
@@ -750,7 +781,7 @@ static DrawInfo *icon_create_drawinfo(void)
return di;
}
-/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */
+/* note!, returns unscaled by DPI */
int UI_icon_get_width(int icon_id)
{
Icon *icon = NULL;
@@ -920,7 +951,7 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
float x1, x2, y1, y2;
if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha);
- else glColor4f(1.0f, 1.0f, 1.0f, alpha);
+ else glColor4f(alpha, alpha, alpha, alpha);
x1 = ix * icongltex.invw;
x2 = (ix + ih) * icongltex.invw;
@@ -930,6 +961,9 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ /* sharper downscaling, has no effect when scale matches with a mip level */
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -0.5f);
+
glBegin(GL_QUADS);
glTexCoord2f(x1, y1);
glVertex2f(x, y);
@@ -944,6 +978,8 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
glVertex2f(x, y + h);
glEnd();
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0f);
+
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
@@ -965,7 +1001,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
Icon *icon = NULL;
DrawInfo *di = NULL;
IconImage *iimg;
- float fdraw_size = is_preview ? draw_size : (draw_size * UI_DPI_ICON_FAC);
+ const float fdraw_size = (float)draw_size;
int w, h;
icon = BKE_icon_get(icon_id);
@@ -996,8 +1032,11 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
di->data.vector.func((int)x, (int)y, ICON_DEFAULT_HEIGHT, ICON_DEFAULT_HEIGHT, 1.0f);
}
else if (di->type == ICON_TYPE_TEXTURE) {
+ /* texture image use premul alpha for correct scaling */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y,
di->data.texture.w, di->data.texture.h, alpha, rgb);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_BUFFER) {
/* it is a builtin icon */
@@ -1005,7 +1044,9 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
if (!iimg->rect) return; /* something has gone wrong! */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_PREVIEW) {
PreviewImage *pi = BKE_previewimg_get((ID *)icon->obj);
@@ -1141,6 +1182,44 @@ int ui_id_icon_get(bContext *C, ID *id, int big)
return iconid;
}
+int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, int big)
+{
+ ID *id = NULL;
+
+ if (!ptr->data)
+ return rnaicon;
+
+ /* try ID, material, texture or dynapaint slot */
+ if (RNA_struct_is_ID(ptr->type)) {
+ id = ptr->id.data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_MaterialSlot)) {
+ id = RNA_pointer_get(ptr, "material").data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_TextureSlot)) {
+ id = RNA_pointer_get(ptr, "texture").data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_DynamicPaintSurface)) {
+ DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data;
+
+ if (surface->format == MOD_DPAINT_SURFACE_F_PTEX)
+ return ICON_TEXTURE_SHADED;
+ else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX)
+ return ICON_OUTLINER_DATA_MESH;
+ else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
+ return ICON_FILE_IMAGE;
+ }
+
+ /* get icon from ID */
+ if (id) {
+ int icon = ui_id_icon_get(C, id, big);
+
+ return icon ? icon : rnaicon;
+ }
+
+ return rnaicon;
+}
+
static void icon_draw_at_size(float x, float y, int icon_id, float aspect, float alpha, enum eIconSizes size, int nocreate)
{
int draw_size = get_draw_size(size);
@@ -1158,9 +1237,10 @@ void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, cons
icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, FALSE, FALSE);
}
+/* draws icon with dpi scale factor */
void UI_icon_draw(float x, float y, int icon_id)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f, 1.0f);
+ UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f);
}
void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 23d3810..706301d 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -267,10 +267,13 @@ struct uiBut {
void *dragpoin;
struct ImBuf *imb;
float imb_scale;
-
+
/* active button data */
struct uiHandleButtonData *active;
+ /* Custom button data. */
+ void *custom_data;
+
char *editstr;
double *editval;
float *editvec;
@@ -358,7 +361,7 @@ struct uiBlock {
char color_profile; /* color profile for correcting linear colors for display */
- char *display_device; /* display device name used to display this block,
+ const char *display_device; /* display device name used to display this block,
* used by color widgets to transform colors from/to scene linear
*/
};
@@ -492,7 +495,7 @@ extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *r
/* interface_draw.c */
extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
-void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha);
+void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha);
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
@@ -504,6 +507,7 @@ void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rct
void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
/* interface_handlers.c */
+extern void ui_pan_to_scroll(struct wmEvent *event, int *type, int *val);
extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
extern void ui_button_active_free(const struct bContext *C, uiBut *but);
extern int ui_button_is_active(struct ARegion *ar);
@@ -517,8 +521,8 @@ void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
uiWidgetColors *ui_tooltip_get_theme(void);
void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock * block, rcti * rect);
void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect);
-int ui_link_bezier_points(rcti * rect, float coord_array[][2], int resol);
-void ui_draw_link_bezier(rcti *rect);
+int ui_link_bezier_points(const rcti * rect, float coord_array[][2], int resol);
+void ui_draw_link_bezier(const rcti *rect);
extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
/* theme color init */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 9759c22..3b0a1cd 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -65,8 +65,6 @@
#define RNA_NO_INDEX -1
#define RNA_ENUM_VALUE -2
-#define EM_SEPR_X 6
-#define EM_SEPR_Y 6
// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
@@ -188,13 +186,13 @@ static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_
static int ui_item_fit(int item, int pos, int all, int available, int last, int alignment, int *offset)
{
+ if (offset)
+ *offset = 0;
+
/* available == 0 is unlimited */
if (available == 0)
return item;
-
- if (offset)
- *offset = 0;
-
+
if (all > available) {
/* contents is bigger than available space */
if (last)
@@ -227,14 +225,16 @@ static int ui_layout_vary_direction(uiLayout *layout)
/* estimated size of text + icon */
static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, int compact)
{
+ float f5 = 0.25f * UI_UNIT_X;
+ float f10 = 0.5f * UI_UNIT_X;
int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X;
if (icon && !name[0])
return UI_UNIT_X; /* icon only */
else if (icon)
- return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */
+ return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */
else
- return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */
+ return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */
}
static void ui_item_size(uiItem *item, int *r_w, int *r_h)
@@ -346,7 +346,9 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
}
/* create buttons for an item with an RNA array */
-static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h), int expand, int slider, int toggle, int icon_only)
+static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, int icon,
+ PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h),
+ int expand, int slider, int toggle, int icon_only)
{
uiStyle *style = layout->root->style;
uiBut *but;
@@ -718,8 +720,11 @@ static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, Prope
int totitem, free;
const char *name;
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free);
- if (RNA_enum_name(item, retval, &name) == 0) {
+ RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free);
+ if (RNA_enum_name(item, retval, &name)) {
+ name = CTX_IFACE_(RNA_property_translation_context(prop), name);
+ }
+ else {
name = "";
}
@@ -904,10 +909,11 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char
UI_OPERATOR_ERROR_RET(ot, opname, return );
WM_operator_properties_create_ptr(&ptr, ot);
-
+
/* enum lookup */
if ((prop = RNA_struct_find_property(&ptr, propname))) {
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
+ /* no need for translations here */
+ RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
if (item == NULL || RNA_enum_value_from_id(item, value_str, &value) == 0) {
if (free) {
MEM_freeN(item);
@@ -924,9 +930,9 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char
RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
return;
}
-
+
RNA_property_enum_set(&ptr, prop, value);
-
+
/* same as uiItemEnumO */
if (!name)
name = ui_menu_enumpropname(layout, &ptr, prop, value);
@@ -1172,7 +1178,7 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
return;
}
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
+ RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
if (!RNA_enum_value_from_id(item, value, &ivalue)) {
if (free) {
@@ -1185,7 +1191,9 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
for (a = 0; item[a].identifier; a++) {
if (item[a].value == ivalue) {
- uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, name ? name : item[a].name, icon ? icon : item[a].icon);
+ const char *item_name = CTX_IFACE_(RNA_property_translation_context(prop), item[a].name);
+
+ uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, item_name ? item_name : name, icon ? icon : item[a].icon);
break;
}
}
@@ -1378,7 +1386,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
/* turn button into search button */
if (searchprop) {
- but->type = SEARCH_MENU;
+ but->type = SEARCH_MENU_UNLINK;
but->hardmax = MAX2(but->hardmax, 256.0f);
but->rnasearchpoin = *searchptr;
but->rnasearchprop = searchprop;
@@ -1466,7 +1474,13 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
printf("%s: opening menu \"%s\"\n", __func__, mt->idname);
}
+ if (layout->context)
+ CTX_store_set(C, layout->context);
+
mt->draw(C, &menu);
+
+ if (layout->context)
+ CTX_store_set(C, NULL);
}
static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN, const char *tip)
@@ -1489,7 +1503,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre
h = UI_UNIT_Y;
if (layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */
- w -= 10;
+ w -= UI_UNIT_Y / 2;
if (name[0] && icon)
but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip);
@@ -1604,7 +1618,7 @@ void uiItemS(uiLayout *layout)
uiBlock *block = layout->root->block;
uiBlockSetCurLayout(block, layout);
- uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, SEPR, 0, "", 0, 0, 0.3f * UI_UNIT_X, 0.3f * UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
/* level items */
@@ -2294,11 +2308,14 @@ uiLayout *uiLayoutBox(uiLayout *layout)
return (uiLayout *)ui_layout_box(layout, ROUNDBOX);
}
-uiLayout *uiLayoutListBox(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr, PropertyRNA *actprop)
+uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
+ PropertyRNA *actprop)
{
uiLayoutItemBx *box = ui_layout_box(layout, LISTBOX);
uiBut *but = box->roundbox;
+ but->custom_data = ui_list;
+
but->rnasearchpoin = *ptr;
but->rnasearchprop = prop;
but->rnapoin = *actptr;
@@ -2935,7 +2952,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
col = uiLayoutColumn(layout, FALSE);
block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, 18, 20,
+ but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 10ba10d..1df10f9 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -112,7 +112,7 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
return BUT_VERTICAL;
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
- return BUT_VERTICAL;
+ return BUT_VERTICAL;
else if (ELEM3(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS))
return BUT_VERTICAL;
@@ -133,8 +133,6 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
if (sbuts->re_align || sbuts->mainbo != sbuts->mainb)
return 1;
}
- else if (ar->regiontype == RGN_TYPE_UI)
- return 1;
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
return 1;
else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
@@ -310,7 +308,7 @@ void uiEndPanel(uiBlock *block, int width, int height)
static void ui_offset_panel_block(uiBlock *block)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiBut *but;
int ofsy;
@@ -350,14 +348,18 @@ static void uiPanelPop(uiBlock *UNUSED(block))
/* triangle 'icon' for panel header */
void UI_DrawTriIcon(float x, float y, char dir)
{
+ float f3 = 0.15 * U.widget_unit;
+ float f5 = 0.25 * U.widget_unit;
+ float f7 = 0.35 * U.widget_unit;
+
if (dir == 'h') {
- ui_draw_anti_tria(x - 3, y - 5, x - 3, y + 5, x + 7, y);
+ ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y);
}
else if (dir == 't') {
- ui_draw_anti_tria(x - 5, y - 7, x + 5, y - 7, x, y + 3);
+ ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3);
}
else { /* 'v' = vertical, down */
- ui_draw_anti_tria(x - 5, y + 3, x + 5, y + 3, x, y - 7);
+ ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7);
}
}
@@ -500,7 +502,6 @@ static void rectf_scale(rctf *rect, const float scale)
/* panel integrated in buttonswindow, tool/property lists etc */
void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
{
- bTheme *btheme = UI_GetTheme();
Panel *panel = block->panel;
rcti headrect;
rctf itemrect;
@@ -522,10 +523,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
glEnable(GL_BLEND);
- if (btheme->tui.panel.show_header) {
+
+ if (UI_GetThemeValue(TH_PANEL_SHOW_HEADER)) {
/* draw with background color */
glEnable(GL_BLEND);
- glColor4ubv((unsigned char *)btheme->tui.panel.header);
+ UI_ThemeColor4(TH_PANEL_HEADER);
glRectf(minx, headrect.ymin + 1, maxx, y);
fdrawline(minx, y, maxx, y);
@@ -582,6 +584,14 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8);
}
+ /* panel backdrop */
+ if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
+ /* draw with background color */
+ glEnable(GL_BLEND);
+ UI_ThemeColor4(TH_PANEL_BACK);
+ glRecti(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ }
+
if (panel->control & UI_PNL_SCALE)
ui_draw_panel_scalewidget(rect);
}
@@ -802,8 +812,8 @@ static void ui_panels_size(ScrArea *sa, ARegion *ar, int *x, int *y)
{
Panel *pa;
int align = panel_aligned(sa, ar);
- int sizex = UI_PANEL_WIDTH;
- int sizey = UI_PANEL_WIDTH;
+ int sizex = 0;
+ int sizey = 0;
/* compute size taken up by panels, for setting in view2d */
for (pa = ar->panels.first; pa; pa = pa->next) {
@@ -824,6 +834,11 @@ static void ui_panels_size(ScrArea *sa, ARegion *ar, int *x, int *y)
}
}
+ if (sizex == 0)
+ sizex = UI_PANEL_WIDTH;
+ if (sizey == 0)
+ sizey = -UI_PANEL_WIDTH;
+
*x = sizex;
*y = sizey;
}
@@ -905,6 +920,7 @@ void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y)
/* re-align, possibly with animation */
if (panels_re_align(sa, ar, &pa)) {
+ /* XXX code never gets here... PNL_ANIM_ALIGN flag is never set */
if (pa)
panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
else
@@ -945,6 +961,25 @@ void uiDrawPanels(const bContext *C, ARegion *ar)
}
}
+void uiScalePanels(ARegion *ar, float new_width)
+{
+ uiBlock *block;
+ uiBut *but;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (block->panel) {
+ float fac = new_width / (float)block->panel->sizex;
+ printf("scaled %f\n", fac);
+ block->panel->sizex = new_width;
+
+ for (but = block->buttons.first; but; but = but->next) {
+ but->rect.xmin *= fac;
+ but->rect.xmax *= fac;
+ }
+ }
+ }
+}
+
/* ------------ panel merging ---------------- */
static void check_panel_overlap(ARegion *ar, Panel *panel)
@@ -1054,7 +1089,7 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
ED_region_tag_redraw(ar);
}
else { /* collapse */
- if(ctrl)
+ if (ctrl)
panels_collapse_all(sa, ar, block->panel);
if (block->panel->flag & PNL_CLOSED) {
@@ -1099,28 +1134,48 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
ARegion *ar = CTX_wm_region(C);
uiBlock *block;
Panel *pa;
- int retval, mx, my, inside_header = 0, inside_scale = 0, inside;
+ int retval, mx, my;
retval = WM_UI_HANDLER_CONTINUE;
for (block = ar->uiblocks.last; block; block = block->prev) {
+ int inside = 0, inside_header = 0, inside_scale = 0;
+
mx = event->x;
my = event->y;
ui_window_to_block(ar, block, &mx, &my);
- /* check if inside boundbox */
- inside = 0;
+ /* checks for mouse position inside */
pa = block->panel;
if (!pa || pa->paneltab != NULL)
continue;
if (pa->type && pa->type->flag & PNL_NO_HEADER) /* XXX - accessed freed panels when scripts reload, need to fix. */
continue;
-
- if (block->rect.xmin <= mx && block->rect.xmax >= mx)
- if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my)
- inside = 1;
- if (inside && event->val == KM_PRESS) {
+ /* clicked at panel header? */
+ if (pa->flag & PNL_CLOSEDX) {
+ if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx)
+ inside_header = 1;
+ }
+ else if (block->rect.xmin > mx || block->rect.xmax < mx);
+ /* outside left/right side */
+ else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ inside_header = 1;
+ }
+ else if (!(pa->flag & PNL_CLOSEDY)) {
+ /* open panel */
+ if (pa->control & UI_PNL_SCALE) {
+ if (block->rect.xmax - PNL_HEADER <= mx)
+ if (block->rect.ymin + PNL_HEADER >= my)
+ inside_scale = 1;
+ }
+ if (block->rect.xmin <= mx && block->rect.xmax >= mx)
+ if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my)
+ inside = 1;
+ }
+
+ /* XXX hardcoded key warning */
+ if ((inside || inside_header) && event->val == KM_PRESS) {
if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) {
if (pa->flag & PNL_CLOSEDY) {
@@ -1130,6 +1185,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
else
ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
+ retval = WM_UI_HANDLER_BREAK;
continue;
}
}
@@ -1138,38 +1194,33 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
if (ui_button_is_active(ar))
continue;
- if (inside) {
- /* clicked at panel header? */
- if (pa->flag & PNL_CLOSEDX) {
- if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx)
- inside_header = 1;
- }
- else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
- inside_header = 1;
- }
- else if (pa->control & UI_PNL_SCALE) {
- if (block->rect.xmax - PNL_HEADER <= mx)
- if (block->rect.ymin + PNL_HEADER >= my)
- inside_scale = 1;
- }
+ if (inside || inside_header) {
if (event->val == KM_PRESS) {
+
/* open close on header */
if (ELEM(event->type, RETKEY, PADENTER)) {
if (inside_header) {
ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl);
+ retval = WM_UI_HANDLER_BREAK;
break;
}
}
else if (event->type == LEFTMOUSE) {
+ /* all inside clicks should return in break - overlapping/float panels */
+ retval = WM_UI_HANDLER_BREAK;
+
if (inside_header) {
ui_handle_panel_header(C, block, mx, my, 0, event->ctrl);
+ retval = WM_UI_HANDLER_BREAK;
break;
}
else if (inside_scale && !(pa->flag & PNL_CLOSED)) {
panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE);
+ retval = WM_UI_HANDLER_BREAK;
break;
}
+
}
else if (event->type == ESCKEY) {
/*XXX 2.50*/
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index c13aade..ca5e2a1 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -73,8 +73,6 @@
#include "interface_intern.h"
#define B_NOP -1
-#define MENU_SHADOW_SIDE 8
-#define MENU_SHADOW_BOTTOM 10
#define MENU_TOP 8
/*********************** Menu Data Parsing ********************* */
@@ -306,8 +304,9 @@ static ARegion *ui_add_temporary_region(bScreen *sc)
static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar)
{
- if (CTX_wm_window(C))
- wm_draw_region_clear(CTX_wm_window(C), ar);
+ wmWindow *win = CTX_wm_window(C);
+ if (win)
+ wm_draw_region_clear(win, ar);
ED_region_exit(C, ar);
BKE_area_region_free(NULL, ar); /* NULL: no spacetype */
@@ -416,6 +415,7 @@ static void ui_tooltip_region_free_cb(ARegion *ar)
ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
{
+ wmWindow *win = CTX_wm_window(C);
uiStyle *style = UI_GetStyle();
static ARegionType type;
ARegion *ar;
@@ -423,7 +423,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* IDProperty *prop;*/
char buf[512];
float fonth, fontw, aspect = but->block->aspect;
- int winx, winy, ofsx, ofsy, w, h, a;
+ int winx /*, winy */, ofsx, ofsy, w, h, a;
rctf rect_fl;
rcti rect_i;
@@ -466,7 +466,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->totline++;
}
- if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
+ if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
/* full string */
ui_get_but_string(but, buf, sizeof(buf));
if (buf[0]) {
@@ -565,7 +565,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
char *data_path = NULL;
/* never fails */
- id_path = RNA_path_from_ID_python(id);
+ id_path = RNA_path_full_ID_py(id);
if (ptr->id.data && ptr->data && prop) {
data_path = RNA_path_from_ID_to_property(ptr, prop);
@@ -622,12 +622,14 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* set font, get bb */
data->fstyle = style->widget; /* copy struct */
data->fstyle.align = UI_STYLE_TEXT_CENTER;
+ ui_fontscale(&data->fstyle.points, aspect);
+
uiStyleFontSet(&data->fstyle);
- /* these defines may need to be tweaked depending on font */
-#define TIP_MARGIN_Y 2
-#define TIP_BORDER_X 16.0f
-#define TIP_BORDER_Y 6.0f
+ /* these defines tweaked depending on font */
+#define TIP_MARGIN_Y (2.0f / aspect)
+#define TIP_BORDER_X (16.0f / aspect)
+#define TIP_BORDER_Y (6.0f / aspect)
h = BLF_height_max(data->fstyle.uifont_id);
@@ -637,7 +639,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
fonth += (a == 0) ? h : h + TIP_MARGIN_Y;
}
- fontw *= aspect;
+ //fontw *= aspect;
ar->regiondata = data;
@@ -645,34 +647,30 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->lineh = h;
data->spaceh = TIP_MARGIN_Y;
-
/* compute position */
- ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
- ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
+ ofsx = 0; //(but->block->panel) ? but->block->panel->ofsx : 0;
+ ofsy = 0; //(but->block->panel) ? but->block->panel->ofsy : 0;
+
+ rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - TIP_BORDER_X;
+ rect_fl.xmax = rect_fl.xmin + fontw + TIP_BORDER_X;
+ rect_fl.ymax = but->rect.ymin + ofsy - TIP_BORDER_Y;
+ rect_fl.ymin = rect_fl.ymax - fonth - TIP_BORDER_Y;
- rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - (TIP_BORDER_X * aspect);
- rect_fl.xmax = rect_fl.xmin + fontw + (TIP_BORDER_X * aspect);
- rect_fl.ymax = but->rect.ymin + ofsy - (TIP_BORDER_Y * aspect);
- rect_fl.ymin = rect_fl.ymax - fonth * aspect - (TIP_BORDER_Y * aspect);
-
#undef TIP_MARGIN_Y
#undef TIP_BORDER_X
#undef TIP_BORDER_Y
-
- /* copy to int, gets projected if possible too */
- BLI_rcti_rctf_copy(&rect_i, &rect_fl);
+ /* since the text has beens caled already, the size of tooltips is defined now */
+ /* here we try to figure out the right location */
if (butregion) {
- /* XXX temp, region v2ds can be empty still */
- if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmin, rect_fl.ymin, &rect_i.xmin, &rect_i.ymin);
- UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmax, rect_fl.ymax, &rect_i.xmax, &rect_i.ymax);
- }
-
- BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
+ float ofsx = rect_fl.xmin, ofsy = rect_fl.ymax;
+ ui_block_to_window_fl(butregion, but->block, &ofsx, &ofsy);
+ BLI_rctf_translate(&rect_fl, ofsx - rect_fl.xmin, ofsy - rect_fl.ymax);
}
+ BLI_rcti_rctf_copy(&rect_i, &rect_fl);
- wm_window_get_size(CTX_wm_window(C), &winx, &winy);
+ /* clip with window boundaries */
+ winx = WM_window_pixels_x(win);
if (rect_i.xmax > winx) {
/* super size */
@@ -693,16 +691,20 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
}
/* widget rect, in region coords */
- data->bbox.xmin = MENU_SHADOW_SIDE;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + MENU_SHADOW_SIDE;
- data->bbox.ymin = MENU_SHADOW_BOTTOM;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + MENU_SHADOW_BOTTOM;
-
- /* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - MENU_SHADOW_SIDE;
- ar->winrct.xmax = rect_i.xmax + MENU_SHADOW_SIDE;
- ar->winrct.ymin = rect_i.ymin - MENU_SHADOW_BOTTOM;
- ar->winrct.ymax = rect_i.ymax + MENU_TOP;
+ {
+ int width = UI_ThemeMenuShadowWidth();
+
+ data->bbox.xmin = width;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) + width;
+ data->bbox.ymin = width;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i) + width;
+
+ /* region bigger for shadow */
+ ar->winrct.xmin = rect_i.xmin - width;
+ ar->winrct.xmax = rect_i.xmax + width;
+ ar->winrct.ymin = rect_i.ymin - width;
+ ar->winrct.ymax = rect_i.ymax + MENU_TOP;
+ }
/* adds subwindow */
ED_region_init(C, ar);
@@ -894,8 +896,12 @@ void ui_searchbox_apply(uiBut *but, ARegion *ar)
void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, wmEvent *event)
{
uiSearchboxData *data = ar->regiondata;
+ int type = event->type, val = event->val;
- switch (event->type) {
+ if (type == MOUSEPAN)
+ ui_pan_to_scroll(event, &type, &val);
+
+ switch (type) {
case WHEELUPMOUSE:
case UPARROWKEY:
ui_searchbox_select(C, ar, but, -1);
@@ -1097,6 +1103,7 @@ static void ui_searchbox_region_free_cb(ARegion *ar)
ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
{
+ wmWindow *win = CTX_wm_window(C);
uiStyle *style = UI_GetStyle();
static ARegionType type;
ARegion *ar;
@@ -1104,7 +1111,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
float aspect = but->block->aspect;
rctf rect_fl;
rcti rect_i;
- int winx, winy, ofsx, ofsy;
+ int winx /*, winy */, ofsx, ofsy;
int i;
/* create area region */
@@ -1139,16 +1146,17 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
+ int width = UI_ThemeMenuShadowWidth();
/* this case is search menu inside other menu */
/* we copy region size */
ar->winrct = butregion->winrct;
/* widget rect, in region coords */
- data->bbox.xmin = MENU_SHADOW_SIDE;
- data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - MENU_SHADOW_SIDE;
- data->bbox.ymin = MENU_SHADOW_BOTTOM;
- data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - MENU_SHADOW_BOTTOM;
+ data->bbox.xmin = width;
+ data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - width;
+ data->bbox.ymin = width;
+ data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - width;
/* check if button is lower half */
if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
@@ -1160,6 +1168,8 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
else {
const int searchbox_width = uiSearchBoxWidth();
+ const int shadow_width = UI_ThemeMenuShadowWidth();
+
rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
rect_fl.ymax = but->rect.ymin;
@@ -1185,7 +1195,9 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
- wm_window_get_size(CTX_wm_window(C), &winx, &winy);
+ winx = WM_window_pixels_x(win);
+ // winy = WM_window_pixels_y(win); /* UNUSED */
+ //wm_window_get_size(win, &winx, &winy);
if (rect_i.xmax > winx) {
/* super size */
@@ -1209,15 +1221,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
/* widget rect, in region coords */
- data->bbox.xmin = MENU_SHADOW_SIDE;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + MENU_SHADOW_SIDE;
- data->bbox.ymin = MENU_SHADOW_BOTTOM;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + MENU_SHADOW_BOTTOM;
+ data->bbox.xmin = shadow_width;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) + shadow_width;
+ data->bbox.ymin = shadow_width;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i) + shadow_width;
/* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - MENU_SHADOW_SIDE;
- ar->winrct.xmax = rect_i.xmax + MENU_SHADOW_SIDE;
- ar->winrct.ymin = rect_i.ymin - MENU_SHADOW_BOTTOM;
+ ar->winrct.xmin = rect_i.xmin - shadow_width;
+ ar->winrct.xmax = rect_i.xmax + shadow_width;
+ ar->winrct.ymin = rect_i.ymin - shadow_width;
ar->winrct.ymax = rect_i.ymax;
}
@@ -1314,11 +1326,11 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/* widget_roundbox_set has this correction too, keep in sync */
if (but->type != PULLDOWN) {
if (but->flag & UI_BUT_ALIGN_TOP)
- butrct.ymax += 1.0f;
+ butrct.ymax += U.pixelsize;
if (but->flag & UI_BUT_ALIGN_LEFT)
- butrct.xmin -= 1.0f;
+ butrct.xmin -= U.pixelsize;
}
-
+
/* calc block rect */
if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
if (block->buttons.first) {
@@ -1334,7 +1346,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
block->rect.xmax = block->rect.ymax = 20;
}
}
-
+
/* aspect = (float)(BLI_rcti_size_x(&block->rect) + 4);*/ /*UNUSED*/
ui_block_to_window_fl(butregion, but->block, &block->rect.xmin, &block->rect.ymin);
ui_block_to_window_fl(butregion, but->block, &block->rect.xmax, &block->rect.ymax);
@@ -1342,8 +1354,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
//block->rect.xmin -= 2.0; block->rect.ymin -= 2.0;
//block->rect.xmax += 2.0; block->rect.ymax += 2.0;
- xsize = BLI_rctf_size_x(&block->rect) + 4; /* 4 for shadow */
- ysize = BLI_rctf_size_y(&block->rect) + 4;
+ xsize = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */
+ ysize = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y;
/* aspect /= (float)xsize;*/ /*UNUSED*/
{
@@ -1351,7 +1363,9 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
int winx, winy;
// int offscreen;
- wm_window_get_size(window, &winx, &winy);
+ winx = WM_window_pixels_x(window);
+ winy = WM_window_pixels_y(window);
+ // wm_window_get_size(window, &winx, &winy);
if (block->direction & UI_CENTER) center = ysize / 2;
else center = 0;
@@ -1517,23 +1531,35 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
{
+ uiBut *bt;
+ int width = UI_ThemeMenuShadowWidth();
int winx, winy;
if (block->flag & UI_BLOCK_NO_WIN_CLIP) {
return;
}
- wm_window_get_size(window, &winx, &winy);
+ winx = WM_window_pixels_x(window);
+ winy = WM_window_pixels_y(window);
- if (block->rect.xmin < MENU_SHADOW_SIDE)
- block->rect.xmin = MENU_SHADOW_SIDE;
- if (block->rect.xmax > winx - MENU_SHADOW_SIDE)
- block->rect.xmax = winx - MENU_SHADOW_SIDE;
+ if (block->rect.xmin < width)
+ block->rect.xmin = width;
+ if (block->rect.xmax > winx - width)
+ block->rect.xmax = winx - width;
- if (block->rect.ymin < MENU_SHADOW_BOTTOM)
- block->rect.ymin = MENU_SHADOW_BOTTOM;
+ if (block->rect.ymin < width)
+ block->rect.ymin = width;
if (block->rect.ymax > winy - MENU_TOP)
block->rect.ymax = winy - MENU_TOP;
+
+ /* ensure menu items draw inside left/right boundary */
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (bt->rect.xmin < block->rect.xmin)
+ bt->rect.xmin = block->rect.xmin;
+ if (bt->rect.xmax > block->rect.xmax)
+ bt->rect.xmax = block->rect.xmax;
+ }
+
}
void ui_popup_block_scrolltest(uiBlock *block)
@@ -1583,6 +1609,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
uiBlock *block;
uiPopupBlockHandle *handle;
uiSafetyRct *saferct;
+ int width = UI_ThemeMenuShadowWidth();
/* create handle */
handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
@@ -1635,7 +1662,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
/* if this is being created from a button */
if (but) {
block->aspect = but->block->aspect;
-
ui_block_position(window, butregion, but, block);
handle->direction = block->direction;
}
@@ -1652,9 +1678,9 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
/* the block and buttons were positioned in window space as in 2.4x, now
* these menu blocks are regions so we bring it back to region space.
* additionally we add some padding for the menu shadow or rounded menus */
- ar->winrct.xmin = block->rect.xmin - MENU_SHADOW_SIDE;
- ar->winrct.xmax = block->rect.xmax + MENU_SHADOW_SIDE;
- ar->winrct.ymin = block->rect.ymin - MENU_SHADOW_BOTTOM;
+ ar->winrct.xmin = block->rect.xmin - width;
+ ar->winrct.xmax = block->rect.xmax + width;
+ ar->winrct.ymin = block->rect.ymin - width;
ar->winrct.ymax = block->rect.ymax + MENU_TOP;
ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
@@ -2019,10 +2045,10 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a
picker_new_hide_reveal(bt->block, colormode);
}
-#define PICKER_H 150
-#define PICKER_W 150
-#define PICKER_SPACE 6
-#define PICKER_BAR 14
+#define PICKER_H (7.5f * U.widget_unit)
+#define PICKER_W (7.5f * U.widget_unit)
+#define PICKER_SPACE (0.3f * U.widget_unit)
+#define PICKER_BAR (0.7f * U.widget_unit)
#define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR)
@@ -2031,11 +2057,11 @@ static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
uiBut *bt;
/* HS circle */
- bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color");
+ bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0, 0, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
@@ -2046,11 +2072,11 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, in
int bartype = type + 3;
/* HS square */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color");
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value");
+ bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
@@ -2066,11 +2092,12 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
float rgb_gamma[3];
float min, max, step, precision;
float *hsv = ui_block_hsv_get(block);
+ int yco;
ui_block_hsv_get(block);
width = PICKER_TOTAL_W;
- butwidth = width - UI_UNIT_X - 10;
+ butwidth = width - 1.5f * UI_UNIT_X;
/* existence of profile means storage is in linear color space, with display correction */
/* XXX That tip message is not use anywhere! */
@@ -2108,44 +2135,47 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
}
/* mode */
+ yco = -1.5f * UI_UNIT_Y;
uiBlockBeginAlign(block);
- bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
+ bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
- bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
+ bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
- bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
+ bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
uiBlockEndAlign(block);
+ yco = -3.0f * UI_UNIT_Y;
if (show_picker) {
- bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, -60, UI_UNIT_X, UI_UNIT_Y, NULL);
+ bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
uiButSetFunc(bt, close_popup_cb, bt, NULL);
}
/* RGB values */
uiBlockBeginAlign(block);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
+ bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
+ bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
+ bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE);
* but need to use uiButSetFunc for updating other fake buttons */
/* HSV values */
+ yco = -3.0f * UI_UNIT_Y;
uiBlockBeginAlign(block);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
+ bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, -80, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
+ bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, -100, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
+ bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
uiBlockEndAlign(block);
if (rgba[3] != FLT_MAX) {
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha"));
+ bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha"));
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
else {
@@ -2154,9 +2184,10 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
- bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
+ yco = -3.0f * UI_UNIT_Y;
+ bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol);
- uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, -80, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
rgb_to_hsv_v(rgba, hsv);
@@ -2228,7 +2259,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker);
block->flag = UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT;
- uiBoundsBlock(block, 10);
+ uiBoundsBlock(block, 0.5 * UI_UNIT_X);
block->block_event_func = ui_picker_small_wheel_cb;
@@ -2240,7 +2271,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
/************************ Popup Menu Memory ****************************/
-static int ui_popup_string_hash(char *str)
+static int ui_popup_string_hash(const char *str)
{
/* sometimes button contains hotkey, sometimes not, strip for proper compare */
int hash;
@@ -2386,7 +2417,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
}
block->minbounds = minwidth;
- uiTextBoundsBlock(block, 50);
+ uiTextBoundsBlock(block, 2.5 * UI_UNIT_X);
}
/* if menu slides out of other menu, override direction */
@@ -2402,7 +2433,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
uiMenuCreateFunc menu_func, void *arg, char *str)
{
wmWindow *window = CTX_wm_window(C);
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiPopupBlockHandle *handle;
uiPopupMenu *pup;
pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
@@ -2466,7 +2497,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
/* only return handler, and set optional title */
uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
uiBut *but;
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 7e7db6a..ef24ea9 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -143,7 +143,7 @@ static uiFont *uifont_to_blfont(int id)
/* *************** draw ************************ */
-void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str,
+void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str,
float *r_xofs, float *r_yofs)
{
float height;
@@ -166,7 +166,7 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str,
}
/* clip is very strict, so we give it some space */
- BLF_clipping(fs->uifont_id, rect->xmin - 1, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4);
+ BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4);
BLF_enable(fs->uifont_id, BLF_CLIPPING);
BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f);
@@ -261,6 +261,32 @@ uiStyle *UI_GetStyle(void)
return (style != NULL) ? style : U.uistyles.first;
}
+/* for drawing, scaled with DPI setting */
+uiStyle *UI_GetStyleDraw(void)
+{
+ uiStyle *style = UI_GetStyle();
+ static uiStyle _style;
+
+ _style = *style;
+
+ _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx);
+ _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady);
+ _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx);
+ _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady);
+ _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx);
+ _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady);
+
+ _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace);
+ _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace);
+ _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace);
+ _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex);
+ _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey);
+ _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace);
+ _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter);
+
+ return &_style;
+}
+
/* temporarily, does widget font */
int UI_GetStringWidth(const char *str)
{
@@ -364,9 +390,9 @@ void uiStyleInit(void)
* Yes, this build the glyph cache and create
* the texture.
*/
- BLF_size(font->blf_id, 11, U.dpi);
- BLF_size(font->blf_id, 12, U.dpi);
- BLF_size(font->blf_id, 14, U.dpi);
+ BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi);
}
}
@@ -378,19 +404,19 @@ void uiStyleInit(void)
if (blf_mono_font == -1)
blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
- BLF_size(blf_mono_font, 12, 72);
+ BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
/* second for rendering else we get threading problems */
if (blf_mono_font_render == -1)
blf_mono_font_render = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
- BLF_size(blf_mono_font_render, 12, 72);
+ BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 );
}
void uiStyleFontSet(uiFontStyle *fs)
{
uiFont *font = uifont_to_blfont(fs->uifont_id);
- BLF_size(font->blf_id, fs->points, U.dpi);
+ BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi);
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index f7a53c6..a190f3d 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -31,18 +31,16 @@
#include "MEM_guardedalloc.h"
-#include "DNA_anim_types.h"
#include "DNA_dynamicpaint_types.h"
-#include "DNA_key_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_userdef_types.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
#include "BLI_rect.h"
+#include "BLF_api.h"
#include "BLF_translation.h"
#include "BKE_animsys.h"
@@ -59,6 +57,7 @@
#include "BKE_displist.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "ED_screen.h"
#include "ED_object.h"
@@ -71,11 +70,9 @@
#include "WM_types.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "interface_intern.h"
-#include "BLF_api.h"
-#include "BLF_translation.h"
-
void UI_template_fix_linking(void)
{
}
@@ -179,13 +176,13 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
/* preview thumbnails */
if (template.prv_rows > 0 && template.prv_cols > 0) {
- int w = 96 * template.prv_cols;
- int h = 96 * template.prv_rows + 20;
+ int w = 4 * U.widget_unit * template.prv_cols;
+ int h = 4 * U.widget_unit * template.prv_rows + U.widget_unit;
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19,
+ but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
template.prv_rows, template.prv_cols, "");
uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
}
@@ -193,15 +190,15 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
else {
const int searchbox_width = uiSearchBoxWidth();
const int searchbox_height = uiSearchBoxHeight();
+
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL);
-
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
}
- uiBoundsBlock(block, 6);
+ uiBoundsBlock(block, 0.3f * U.widget_unit);
uiBlockSetDirection(block, UI_DOWN);
uiEndBlock(C, block);
@@ -347,6 +344,7 @@ static const char *template_id_browse_tip(StructRNA *type)
/* Return a type-based i18n context, needed e.g. by "New" button.
* In most languages, this adjective takes different form based on gender of type name...
*/
+#ifdef WITH_INTERNATIONAL
static const char *template_id_context(StructRNA *type)
{
if (type) {
@@ -377,6 +375,7 @@ static const char *template_id_context(StructRNA *type)
}
return BLF_I18NCONTEXT_DEFAULT;
}
+#endif
static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
const char *newop, const char *openop, const char *unlinkop)
@@ -387,7 +386,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
// ListBase *lb; // UNUSED
ID *id, *idfrom;
int editable = RNA_property_editable(&template->ptr, template->prop);
- const char *i18n_ctxt = template_id_context(type);
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
id = idptr.data;
@@ -518,11 +516,11 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
if (newop) {
but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
- (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"), 0, 0, w, UI_UNIT_Y, NULL);
+ (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"),
+ but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
@@ -1079,7 +1077,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
// int rb_col; // UNUSED
/* get constraint typeinfo */
- cti = constraint_get_typeinfo(con);
+ cti = BKE_constraint_get_typeinfo(con);
if (cti == NULL) {
/* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
BLI_strncpy(typestr, (con->type == CONSTRAINT_TYPE_NULL) ? "Null" : "Unknown", sizeof(typestr));
@@ -1088,7 +1086,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
BLI_strncpy(typestr, cti->name, sizeof(typestr));
/* determine whether constraint is proxy protected or not */
- if (proxylocked_constraints_owner(ob, pchan))
+ if (BKE_proxylocked_constraints_owner(ob, pchan))
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
else
proxy_protected = 0;
@@ -1150,7 +1148,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
*
* Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
*/
- if (proxylocked_constraints_owner(ob, pchan)) {
+ if (BKE_proxylocked_constraints_owner(ob, pchan)) {
if (con->prev) {
prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
}
@@ -1437,7 +1435,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
const int line2_y = yoffs + 65;
if (coba == NULL) return;
-
+
bt = uiDefBut(block, BUT, 0, IFACE_("Add"), 0 + xoffs, line1_y, 40, UI_UNIT_Y, NULL, 0, 0, 0, 0,
TIP_("Add a new color stop to the colorband"));
uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
@@ -1547,8 +1545,8 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 19.5f * UI_UNIT_X;
block = uiLayoutAbsoluteBlock(layout);
colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
@@ -1579,8 +1577,8 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
//colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
@@ -1589,8 +1587,9 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height;
- bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), hist->height, hist,
- 0, 0, 0, 0, "");
+ bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * hist->height,
+ hist, 0, 0, 0, 0, "");
+
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
@@ -1620,15 +1619,15 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height;
- bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->wavefrm_height, scopes,
- 0, 0, 0, 0, "");
+ bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * scopes->wavefrm_height,
+ scopes, 0, 0, 0, 0, "");
(void)bt; /* UNUSED */
MEM_freeN(cb);
@@ -1658,15 +1657,15 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna
cb->ptr = *ptr;
cb->prop = prop;
- rect.xmin = 0; rect.xmax = 200;
- rect.ymin = 0; rect.ymax = 190;
+ rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y;
block = uiLayoutAbsoluteBlock(layout);
scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->vecscope_height;
bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect),
- scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
+ UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
@@ -2010,7 +2009,7 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
/* curve itself */
size = uiLayoutGetWidth(layout);
row = uiLayoutRow(layout, FALSE);
- uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 200), cumap, 0.0f, 1.0f, bg, 0, "");
+ uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 10.0f * UI_UNIT_X), cumap, 0.0f, 1.0f, bg, 0, "");
/* sliders for selected point */
for (i = 0; i < cm->totpoint; i++) {
@@ -2081,7 +2080,7 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn
/********************* ColorPicker Template ************************/
-#define WHEEL_SIZE 100
+#define WHEEL_SIZE (5 * U.widget_unit)
/* This template now follows User Preference for type - name is not correct anymore... */
void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider,
@@ -2329,254 +2328,28 @@ void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propnam
/************************* List Template **************************/
-
-static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon, int big)
+static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout,
+ struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, int icon,
+ struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname),
+ int UNUSED(index))
{
- ID *id = NULL;
- int icon;
-
- if (!itemptr->data)
- return rnaicon;
-
- /* try ID, material or texture slot */
- if (RNA_struct_is_ID(itemptr->type)) {
- id = itemptr->id.data;
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) {
- id = RNA_pointer_get(itemptr, "material").data;
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_TextureSlot)) {
- id = RNA_pointer_get(itemptr, "texture").data;
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_DynamicPaintSurface)) {
- DynamicPaintSurface *surface = (DynamicPaintSurface *)itemptr->data;
-
- if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) return ICON_TEXTURE_SHADED;
- else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) return ICON_OUTLINER_DATA_MESH;
- else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return ICON_FILE_IMAGE;
- }
-
- /* get icon from ID */
- if (id) {
- icon = ui_id_icon_get(C, id, big);
-
- if (icon)
- return icon;
- }
-
- return rnaicon;
-}
-
-static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i,
- int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop, const char *prop_list_id)
-{
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but;
- uiLayout *split, *overlap, *sub, *row;
char *namebuf;
const char *name;
- int icon;
-
- overlap = uiLayoutOverlap(layout);
-
- /* list item behind label & other buttons */
- sub = uiLayoutRow(overlap, FALSE);
-
- but = uiDefButR_prop(block, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr, activeprop,
- 0, 0, i, 0, 0, "");
- uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
-
- sub = uiLayoutRow(overlap, FALSE);
-
- /* retrieve icon and name */
- icon = list_item_icon_get(C, itemptr, rnaicon, 0);
- if (icon == ICON_NONE || icon == ICON_DOT)
- icon = 0;
namebuf = RNA_struct_name_get_alloc(itemptr, NULL, 0, NULL);
name = (namebuf) ? namebuf : "";
- /* hardcoded types */
- if (itemptr->type == &RNA_MeshTexturePolyLayer || itemptr->type == &RNA_MeshLoopColorLayer) {
- uiItemL(sub, name, icon);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render",
- 0, 0, 0, 0, 0, NULL);
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialTextureSlot)) {
- uiItemL(sub, name, icon);
- uiBlockSetEmboss(block, UI_EMBOSS);
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) {
- uiItemL(sub, name, icon);
- uiBlockSetEmboss(block, UI_EMBOSS);
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "use", 0, 0, 0, 0, 0, NULL);
- }
- else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) {
- /* provision to draw active node name */
- Material *ma, *manode;
- Scene *scene = CTX_data_scene(C);
- Object *ob = (Object *)ptr->id.data;
- int index = (Material **)itemptr->data - ob->mat;
-
- /* default item with material base name */
- uiItemL(sub, name, icon);
-
- ma = give_current_material(ob, index + 1);
- if (ma && !BKE_scene_use_new_shading_nodes(scene)) {
- manode = give_node_material(ma);
- if (manode) {
- char str[MAX_ID_NAME + 12];
- BLI_snprintf(str, sizeof(str), IFACE_("Node %s"), manode->id.name + 2);
- uiItemL(sub, str, ui_id_icon_get(C, &manode->id, 1));
- }
- else if (ma->use_nodes) {
- uiItemL(sub, IFACE_("Node <none>"), ICON_NONE);
- }
- }
- }
- else if (itemptr->type == &RNA_ShapeKey) {
- Object *ob = (Object *)activeptr->data;
- Key *key = (Key *)itemptr->id.data;
- KeyBlock *kb = (KeyBlock *)itemptr->data;
-
- split = uiLayoutSplit(sub, 0.66f, FALSE);
-
- uiItemL(split, name, icon);
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- row = uiLayoutRow(split, TRUE);
- if (i == 0 || (key->type != KEY_RELATIVE)) uiItemL(row, "", ICON_NONE);
- else uiItemR(row, itemptr, "value", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "mute", 0, "", ICON_NONE);
-
- if ((kb->flag & KEYBLOCK_MUTE) ||
- (ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH)))
- {
- uiLayoutSetActive(row, FALSE);
- }
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else if (itemptr->type == &RNA_VertexGroup) {
- bDeformGroup *dg = (bDeformGroup *)itemptr->data;
- uiItemL(sub, name, icon);
- /* RNA does not allow nice lock icons, use lower level buttons */
-#if 0
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "lock_weight", 0, 0, 0, 0, 0, NULL);
-#else
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButBitC(block, TOG, DG_LOCK_WEIGHT, 0, (dg->flag & DG_LOCK_WEIGHT) ? ICON_LOCKED : ICON_UNLOCKED,
- 0, 0, UI_UNIT_X, UI_UNIT_Y, &dg->flag, 0, 0, 0, 0,
- TIP_("Maintain relative weights while painting"));
- uiBlockSetEmboss(block, UI_EMBOSS);
-#endif
+ /* Simplest one! */
+ switch (ui_list->layout_type) {
+ case UILST_LAYOUT_GRID:
+ uiItemL(layout, "", icon);
+ break;
+ case UILST_LAYOUT_DEFAULT:
+ case UILST_LAYOUT_COMPACT:
+ default:
+ uiItemL(layout, name, icon);
+ break;
}
- else if (itemptr->type == &RNA_KeyingSetPath) {
- KS_Path *ksp = (KS_Path *)itemptr->data;
-
- /* icon needs to be the type of ID which is currently active */
- RNA_enum_icon_from_value(id_type_items, ksp->idtype, &icon);
-
- /* nothing else special to do... */
- uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */
- }
- else if (itemptr->type == &RNA_DynamicPaintSurface) {
- char name_final[96];
- const char *enum_name;
- PropertyRNA *prop = RNA_struct_find_property(itemptr, "surface_type");
- DynamicPaintSurface *surface = (DynamicPaintSurface *)itemptr->data;
-
- RNA_property_enum_name(C, itemptr, prop, RNA_property_enum_get(itemptr, prop), &enum_name);
-
- BLI_snprintf(name_final, sizeof(name_final), "%s (%s)", name, enum_name);
- uiItemL(sub, name_final, icon);
- if (dynamicPaint_surfaceHasColorPreview(surface)) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR(block, OPTION, 0,
- (surface->flags & MOD_DPAINT_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON,
- 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "show_preview", 0, 0, 0, 0, 0, NULL);
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "is_active", i, 0, 0, 0, 0, NULL);
- }
- else if (itemptr->type == &RNA_MovieTrackingObject) {
- MovieTrackingObject *tracking_object = (MovieTrackingObject *)itemptr->data;
-
- split = uiLayoutSplit(sub, 0.75f, FALSE);
- if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
- uiItemL(split, name, ICON_CAMERA_DATA);
- }
- else {
- uiItemL(split, name, ICON_OBJECT_DATA);
- }
- }
- else if (itemptr->type == &RNA_MaskLayer) {
- split = uiLayoutRow(sub, FALSE);
-
- uiItemL(split, name, icon);
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- row = uiLayoutRow(split, TRUE);
- uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "hide", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "hide_select", 0, "", ICON_NONE);
- uiItemR(row, itemptr, "hide_render", 0, "", ICON_NONE);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
-
- /* There is a last chance to display custom controls (in addition to the name/label):
- * If the given item property group features a string property named as prop_list,
- * this tries to add controls for all properties of the item listed in that string property.
- * (colon-separated names).
- *
- * This is especially useful for python. E.g., if you list a collection of this property
- * group:
- *
- * class TestPropertyGroup(bpy.types.PropertyGroup):
- * bool = BoolProperty(default=False)
- * integer = IntProperty()
- * string = StringProperty()
- *
- * # A string of all identifiers (colon-separated) which property's controls should be
- * # displayed in a template_list.
- * template_list_controls = StringProperty(default="integer:bool:string", options={"HIDDEN"})
- *
- * ... you'll get a numfield for the integer prop, a check box for the bool prop, and a textfield
- * for the string prop, after the name of each item of the collection.
- */
- else if (prop_list_id) {
- row = uiLayoutRow(sub, TRUE);
- uiItemL(row, name, icon);
-
- /* XXX: Check, as sometimes we get an itemptr looking like
- * {id = {data = 0x0}, type = 0x0, data = 0x0}
- * which would obviously produce a sigsev... */
- if (itemptr->type) {
- /* If the special property is set for the item, and it is a collection... */
- PropertyRNA *prop_list = RNA_struct_find_property(itemptr, prop_list_id);
-
- if (prop_list && RNA_property_type(prop_list) == PROP_STRING) {
- int prop_names_len;
- char *prop_names = RNA_property_string_get_alloc(itemptr, prop_list, NULL, 0, &prop_names_len);
- char *prop_names_end = prop_names + prop_names_len;
- char *id = prop_names;
- char *id_next;
- while (id < prop_names_end) {
- if ((id_next = strchr(id, ':'))) *id_next++ = '\0';
- else id_next = prop_names_end;
- uiItemR(row, itemptr, id, 0, NULL, ICON_NONE);
- id = id_next;
- }
- MEM_freeN(prop_names);
- }
- }
- }
-
- else
- uiItemL(sub, name, icon); /* fails, backdrop LISTROW... */
/* free name */
if (namebuf) {
@@ -2584,177 +2357,166 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
}
}
-void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr,
- const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype)
+void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
+ PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr,
+ const char *active_propname, int rows, int maxrows, int layout_type)
{
+ uiListType *ui_list_type;
+ uiList *ui_list = NULL;
+ ARegion *ar;
+ uiListDrawItemFunc draw_item;
+
PropertyRNA *prop = NULL, *activeprop;
PropertyType type, activetype;
StructRNA *ptype;
- uiLayout *box, *row, *col;
- uiBlock *block;
+ uiLayout *box, *row, *col, *sub, *overlap;
+ uiBlock *block, *subblock;
uiBut *but;
- Panel *pa;
- const char *name;
+
+ char ui_list_id[UI_MAX_NAME_STR];
char numstr[32];
- int rnaicon = 0, icon = 0, i = 0, activei = 0, len = 0, items, found, min, max;
+ int rnaicon = ICON_NONE, icon = ICON_NONE;
+ int i = 0, activei = 0;
+ int len = 0;
+ int items;
+ int found;
+ int min, max;
/* validate arguments */
block = uiLayoutGetBlock(layout);
- pa = block->panel;
- if (!pa) {
- RNA_warning("Only works inside a panel");
+ if (!active_dataptr->data) {
+ RNA_warning("No active data");
return;
}
- if (!activeptr->data)
- return;
-
- if (ptr->data) {
- prop = RNA_struct_find_property(ptr, propname);
+ if (dataptr->data) {
+ prop = RNA_struct_find_property(dataptr, propname);
if (!prop) {
- RNA_warning("Property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
return;
}
}
- activeprop = RNA_struct_find_property(activeptr, activepropname);
+ activeprop = RNA_struct_find_property(active_dataptr, active_propname);
if (!activeprop) {
- RNA_warning("Property not found: %s.%s", RNA_struct_identifier(ptr->type), activepropname);
+ RNA_warning("Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
return;
}
if (prop) {
type = RNA_property_type(prop);
if (type != PROP_COLLECTION) {
- RNA_warning("uiExpected collection property");
+ RNA_warning("Expected a collection data property");
return;
}
}
activetype = RNA_property_type(activeprop);
if (activetype != PROP_INT) {
- RNA_warning("Expected integer property");
+ RNA_warning("Expected an integer active data property");
return;
}
/* get icon */
- if (ptr->data && prop) {
- ptype = RNA_property_pointer_type(ptr, prop);
+ if (dataptr->data && prop) {
+ ptype = RNA_property_pointer_type(dataptr, prop);
rnaicon = RNA_struct_ui_icon(ptype);
}
/* get active data */
- activei = RNA_property_int_get(activeptr, activeprop);
-
- if (listtype == 'i') {
- box = uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
- col = uiLayoutColumn(box, TRUE);
- row = uiLayoutRow(col, FALSE);
-
- if (ptr->data && prop) {
- /* create list items */
- RNA_PROP_BEGIN (ptr, itemptr, prop)
- {
- /* create button */
- if (!(i % 9))
- row = uiLayoutRow(col, FALSE);
+ activei = RNA_property_int_get(active_dataptr, activeprop);
- icon = list_item_icon_get(C, &itemptr, rnaicon, 1);
- but = uiDefIconButR_prop(block, LISTROW, 0, icon, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr,
- activeprop, 0, 0, i, 0, 0, "");
- uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
-
+ /* Find the uiList type. */
+ ui_list_type = WM_uilisttype_find(listtype_name, FALSE);
- i++;
- }
- RNA_PROP_END;
- }
+ if (ui_list_type == NULL) {
+ RNA_warning("List type %s not found", listtype_name);
+ return;
}
- else if (listtype == 'c') {
- /* compact layout */
- row = uiLayoutRow(layout, TRUE);
+ draw_item = ui_list_type->draw_item ? ui_list_type->draw_item : uilist_draw_item_default;
- if (ptr->data && prop) {
- /* create list items */
- RNA_PROP_BEGIN (ptr, itemptr, prop)
- {
- found = (activei == i);
+ /* Find or add the uiList to the current Region. */
+ /* We tag the list id with the list type... */
+ BLI_snprintf(ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : "");
- if (found) {
- /* create button */
- name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
- icon = list_item_icon_get(C, &itemptr, rnaicon, 0);
- uiItemL(row, (name) ? name : "", icon);
+ ar = CTX_wm_region(C);
+ ui_list = BLI_findstring(&ar->ui_lists, ui_list_id, offsetof(uiList, list_id));
- if (name) {
- MEM_freeN((void *)name);
- }
- }
+ if (!ui_list) {
+ ui_list = MEM_callocN(sizeof(uiList), __func__);
+ BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id));
+ BLI_addtail(&ar->ui_lists, ui_list);
+ }
- i++;
- }
- RNA_PROP_END;
- }
+ /* Because we can't actually pass type across save&load... */
+ ui_list->type = ui_list_type;
+ ui_list->layout_type = layout_type;
- /* if not found, add in dummy button */
- if (i == 0)
- uiItemL(row, "", ICON_NONE);
-
- /* next/prev button */
- BLI_snprintf(numstr, sizeof(numstr), "%d :", i);
- but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, activeptr,
- activeprop, 0, 0, 0, 0, 0, "");
- if (i == 0)
- uiButSetFlag(but, UI_BUT_DISABLED);
- }
- else {
+ switch (layout_type) {
+ case UILST_LAYOUT_DEFAULT:
/* default rows */
if (rows == 0)
rows = 5;
if (maxrows == 0)
maxrows = 5;
- if (pa->list_grip_size != 0)
- rows = pa->list_grip_size;
+ if (ui_list->list_grip_size != 0)
+ rows = ui_list->list_grip_size;
/* layout */
- box = uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
+ box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
row = uiLayoutRow(box, FALSE);
col = uiLayoutColumn(row, TRUE);
/* init numbers */
- RNA_property_int_range(activeptr, activeprop, &min, &max);
+ RNA_property_int_range(active_dataptr, activeprop, &min, &max);
if (prop)
- len = RNA_property_collection_length(ptr, prop);
+ len = RNA_property_collection_length(dataptr, prop);
items = CLAMPIS(len, rows, MAX2(rows, maxrows));
/* if list length changes and active is out of view, scroll to it */
- if (pa->list_last_len != len)
- if ((activei < pa->list_scroll || activei >= pa->list_scroll + items))
- pa->list_scroll = activei;
+ if ((ui_list->list_last_len != len) &&
+ (activei < ui_list->list_scroll || activei >= ui_list->list_scroll + items)) {
+ ui_list->list_scroll = activei;
+ }
- pa->list_scroll = MIN2(pa->list_scroll, len - items);
- pa->list_scroll = MAX2(pa->list_scroll, 0);
- pa->list_size = items;
- pa->list_last_len = len;
+ ui_list->list_scroll = min_ii(ui_list->list_scroll, len - items);
+ ui_list->list_scroll = max_ii(ui_list->list_scroll, 0);
+ ui_list->list_size = items;
+ ui_list->list_last_len = len;
- if (ptr->data && prop) {
+ if (dataptr->data && prop) {
/* create list items */
- RNA_PROP_BEGIN (ptr, itemptr, prop)
+ RNA_PROP_BEGIN (dataptr, itemptr, prop)
{
- if (i >= pa->list_scroll && i < pa->list_scroll + items)
- list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activeprop, prop_list);
+ if (i >= ui_list->list_scroll && i < ui_list->list_scroll + items) {
+ subblock = uiLayoutGetBlock(col);
+ overlap = uiLayoutOverlap(col);
+
+ /* list item behind label & other buttons */
+ sub = uiLayoutRow(overlap, FALSE);
+ but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ active_dataptr, activeprop, 0, 0, i, 0, 0, "");
+ uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
+
+ sub = uiLayoutRow(overlap, FALSE);
+
+ icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, FALSE);
+ if (icon == ICON_DOT)
+ icon = ICON_NONE;
+ draw_item(ui_list, C, sub, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+ }
i++;
}
RNA_PROP_END;
}
/* add dummy buttons to fill space */
- while (i < pa->list_scroll + items) {
- if (i >= pa->list_scroll)
+ while (i < ui_list->list_scroll + items) {
+ if (i >= ui_list->list_scroll)
uiItemL(col, "", ICON_NONE);
i++;
}
@@ -2762,9 +2524,75 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* add scrollbar */
if (len > items) {
col = uiLayoutColumn(row, FALSE);
- uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * items, &pa->list_scroll,
+ uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * items, &ui_list->list_scroll,
0, len - items, items, 0, "");
}
+ break;
+ case UILST_LAYOUT_COMPACT:
+ row = uiLayoutRow(layout, TRUE);
+
+ if (dataptr->data && prop) {
+ /* create list items */
+ RNA_PROP_BEGIN (dataptr, itemptr, prop)
+ {
+ found = (activei == i);
+
+ if (found) {
+ icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, FALSE);
+ if (icon == ICON_DOT)
+ icon = ICON_NONE;
+ draw_item(ui_list, C, row, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+ }
+
+ i++;
+ }
+ RNA_PROP_END;
+ }
+
+ /* if list is empty, add in dummy button */
+ if (i == 0)
+ uiItemL(row, "", ICON_NONE);
+
+ /* next/prev button */
+ BLI_snprintf(numstr, sizeof(numstr), "%d :", i);
+ but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y,
+ active_dataptr, activeprop, 0, 0, 0, 0, 0, "");
+ if (i == 0)
+ uiButSetFlag(but, UI_BUT_DISABLED);
+ break;
+ case UILST_LAYOUT_GRID:
+ box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ col = uiLayoutColumn(box, TRUE);
+ row = uiLayoutRow(col, FALSE);
+
+ if (dataptr->data && prop) {
+ /* create list items */
+ RNA_PROP_BEGIN (dataptr, itemptr, prop)
+ {
+ /* create button */
+ if (!(i % 9))
+ row = uiLayoutRow(col, FALSE);
+
+ subblock = uiLayoutGetBlock(row);
+ overlap = uiLayoutOverlap(row);
+
+ /* list item behind label & other buttons */
+ sub = uiLayoutRow(overlap, FALSE);
+
+ but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ active_dataptr, activeprop, 0, 0, i, 0, 0, "");
+ uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
+
+ sub = uiLayoutRow(overlap, FALSE);
+
+ icon = UI_rnaptr_icon_get(C, &itemptr, rnaicon, FALSE);
+ draw_item(ui_list, C, sub, dataptr, &itemptr, icon, active_dataptr, active_propname, i);
+
+ i++;
+ }
+ RNA_PROP_END;
+ }
+ break;
}
}
@@ -3078,7 +2906,7 @@ void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char
colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
- uiItemL(layout, "Color Space:", ICON_NONE);
+ uiItemL(layout, "Input Color Space:", ICON_NONE);
uiItemR(layout, &colorspace_settings_ptr, "name", 0, "", ICON_NONE);
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index d363609..7c84784 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -78,7 +78,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
if (arraylen && index == -1) {
if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA))
- but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, 0, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
}
else if (RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR)
but = uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 0643199..6b44a82 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -119,7 +119,7 @@ typedef struct uiWidgetType {
void (*state)(struct uiWidgetType *, int state);
void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign);
void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign);
- void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *);
+ void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *);
} uiWidgetType;
@@ -251,7 +251,7 @@ static void widget_init(uiWidgetBase *wtb)
/* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
/* return tot */
-static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step)
+static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step)
{
float vec[WIDGET_CURVE_RESOLU][2];
float minx, miny, maxx, maxy;
@@ -261,7 +261,7 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
if (2.0f * rad > BLI_rcti_size_y(rect))
rad = 0.5f * BLI_rcti_size_y(rect);
-
+
minx = rect->xmin - step;
miny = rect->ymin - step;
maxx = rect->xmax + step;
@@ -329,14 +329,14 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
}
/* this call has 1 extra arg to allow mask outline */
-static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi)
+static void round_box__edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi)
{
float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax;
- float minxi = minx + 1.0f; /* boundbox inner */
- float maxxi = maxx - 1.0f;
- float minyi = miny + 1.0f;
- float maxyi = maxy - 1.0f;
+ float minxi = minx + U.pixelsize; /* boundbox inner */
+ float maxxi = maxx - U.pixelsize;
+ float minyi = miny + U.pixelsize;
+ float maxyi = maxy - U.pixelsize;
float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; /* for uv, can divide by zero */
float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f;
int a, tot = 0, minsize;
@@ -352,7 +352,7 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
rad = 0.5f * minsize;
if (2.0f * (radi + 1.0f) > minsize)
- radi = 0.5f * minsize - 1.0f;
+ radi = 0.5f * minsize - U.pixelsize;
/* mult */
for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
@@ -479,14 +479,14 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
wt->totvert = tot;
}
-static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad)
+static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad)
{
- round_box__edges(wt, roundboxalign, rect, rad, rad - 1.0f);
+ round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize);
}
/* based on button rect, return scaled array of triangles */
-static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+static void widget_num_tria(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
{
float centx, centy, sizex, sizey, minsize;
int a, i1 = 0, i2 = 1;
@@ -521,7 +521,7 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha
tria->index = num_tria_face;
}
-static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
{
float centx, centy, sizex, sizey, minsize;
int a, i1 = 0, i2 = 1;
@@ -564,21 +564,16 @@ static void widget_trias_draw(uiWidgetTrias *tria)
glDisableClientState(GL_VERTEX_ARRAY);
}
-static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
+static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
{
- float centx, centy, size, asp;
+ float centx, centy, size;
int a;
/* center position and size */
- centx = rect->xmax - 0.5f * BLI_rcti_size_y(rect);
- centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
+ centx = rect->xmax - 0.32f * BLI_rcti_size_y(rect);
+ centy = rect->ymin + 0.50f * BLI_rcti_size_y(rect);
size = 0.4f * (float)BLI_rcti_size_y(rect);
- /* XXX exception */
- asp = ((float)BLI_rcti_size_x(rect)) / ((float)BLI_rcti_size_y(rect));
- if (asp > 1.2f && asp < 2.6f)
- centx = rect->xmax - 0.4f * (float)BLI_rcti_size_y(rect);
-
for (a = 0; a < 6; a++) {
tria->vec[a][0] = size * menu_tria_vert[a][0] + centx;
tria->vec[a][1] = size * menu_tria_vert[a][1] + centy;
@@ -588,7 +583,7 @@ static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
tria->index = menu_tria_face;
}
-static void widget_check_trias(uiWidgetTrias *tria, rcti *rect)
+static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect)
{
float centx, centy, size;
int a;
@@ -833,7 +828,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
#define PREVIEW_PAD 4
-static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect)
+static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti *rect)
{
int w, h, size;
@@ -861,9 +856,9 @@ static int ui_but_draw_menu_icon(uiBut *but)
/* icons have been standardized... and this call draws in untransformed coordinates */
-static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect)
+static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti *rect)
{
- int xs = 0, ys = 0;
+ float xs = 0.0f, ys = 0.0f;
float aspect, height;
if (but->flag & UI_ICON_PREVIEW) {
@@ -874,21 +869,9 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
/* this icon doesn't need draw... */
if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return;
- /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */
- aspect = but->block->aspect;
- if (aspect != but->aspect) {
- /* prevent scaling up icon in pupmenu */
- if (aspect < 1.0f) {
- height = UI_DPI_ICON_SIZE;
- aspect = 1.0f;
-
- }
- else
- height = UI_DPI_ICON_SIZE / aspect;
- }
- else
- height = UI_DPI_ICON_SIZE;
-
+ aspect = but->block->aspect / UI_DPI_FAC;
+ height = ICON_DEFAULT_HEIGHT / aspect;
+
/* calculate blend color */
if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) {
if (but->flag & UI_SELECT) {}
@@ -902,32 +885,40 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
glEnable(GL_BLEND);
if (icon && icon != ICON_BLANK1) {
+ float ofs = 1.0f / aspect;
+
if (but->flag & UI_ICON_LEFT) {
if (but->type == BUT_TOGDUAL) {
if (but->drawstr[0]) {
- xs = rect->xmin - 1;
+ xs = rect->xmin - ofs;
}
else {
- xs = (rect->xmin + rect->xmax - height) / 2;
+ xs = (rect->xmin + rect->xmax - height) / 2.0f;
}
}
else if (but->block->flag & UI_BLOCK_LOOP) {
- if (but->type == SEARCH_MENU)
- xs = rect->xmin + 4;
+ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK))
+ xs = rect->xmin + 4.0f * ofs;
else
- xs = rect->xmin + 1;
+ xs = rect->xmin + ofs;
}
else if ((but->type == ICONROW) || (but->type == ICONTEXTROW)) {
- xs = rect->xmin + 3;
+ xs = rect->xmin + 3.0f * ofs;
}
else {
- xs = rect->xmin + 4;
+ xs = rect->xmin + 4.0f * ofs;
}
- ys = (rect->ymin + rect->ymax - height) / 2;
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
}
else {
- xs = (rect->xmin + rect->xmax - height) / 2;
- ys = (rect->ymin + rect->ymax - height) / 2;
+ xs = (rect->xmin + rect->xmax - height) / 2.0f;
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
+ }
+
+ /* force positions to integers, for zoom levels near 1. draws icons crisp. */
+ if (aspect > 0.95f && aspect < 1.05f) {
+ xs = (int)(xs + 0.1f);
+ ys = (int)(ys + 0.1f);
}
/* to indicate draggable */
@@ -940,8 +931,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
}
if (ui_but_draw_menu_icon(but)) {
- xs = rect->xmax - UI_DPI_ICON_SIZE - 1;
- ys = (rect->ymin + rect->ymax - height) / 2;
+ xs = rect->xmax - UI_DPI_ICON_SIZE - aspect;
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha);
}
@@ -971,7 +962,7 @@ static void ui_text_clip_give_next_off(uiBut *but)
* \note Sets but->ofs to make sure text is correctly visible.
* \note Clips right in some cases, this function could be cleaned up.
*/
-static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1000,7 +991,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect)
/**
* Cut off the text, taking into account the cursor location (text display while editing).
*/
-static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1064,7 +1055,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
*
* \note deals with ': ' especially for number buttons
*/
-static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1292,7 +1283,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) {
ui_text_clip_right_label(fstyle, but, rect);
}
- else if (ELEM(but->type, TEX, SEARCH_MENU)) {
+ else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
ui_text_clip_left(fstyle, but, rect);
}
else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
@@ -1329,14 +1320,25 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
if (but->flag & UI_HAS_ICON) {
widget_draw_icon(but, but->icon + but->iconadd, 1.0f, rect);
+
+ /* icons default draw 0.8f x height */
+ rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect));
- rect->xmin += (int)((float)UI_icon_get_width(but->icon + but->iconadd) * UI_DPI_ICON_FAC);
-
- if (but->editstr || (but->flag & UI_TEXT_LEFT))
- rect->xmin += 5;
+ if (but->editstr || (but->flag & UI_TEXT_LEFT)) {
+ rect->xmin += (0.4f * U.widget_unit) / but->block->aspect;
+ }
+ }
+ else if ((but->flag & UI_TEXT_LEFT)) {
+ rect->xmin += (0.4f * U.widget_unit) / but->block->aspect;
+ }
+
+ /* unlink icon for this button type */
+ if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) {
+ rcti temp = *rect;
+
+ temp.xmin = temp.xmax - BLI_rcti_size_y(rect);
+ widget_draw_icon(but, ICON_X, 1.0f, &temp);
}
- else if ((but->flag & UI_TEXT_LEFT))
- rect->xmin += 5;
/* always draw text for textbutton cursor */
widget_draw_text(fstyle, wcol, but, rect);
@@ -1807,38 +1809,45 @@ static void widget_state_menu_item(uiWidgetType *wt, int state)
/* ************ menu backdrop ************************* */
/* outside of rect, rad to left/bottom/right */
-static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float radout)
+static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin)
{
+ bTheme *btheme = UI_GetTheme();
uiWidgetBase wtb;
rcti rect1 = *rect;
- float alpha, alphastep;
+ float alphastep;
int step, totvert;
- float quad_strip[WIDGET_SIZE_MAX * 2][2];
+ float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2];
+ const float radout = UI_ThemeMenuShadowWidth();
+
+ /* disabled shadow */
+ if (radout == 0.0f)
+ return;
/* prevent tooltips to not show round shadow */
- if (2.0f * radout > 0.2f * BLI_rcti_size_y(&rect1))
+ if (radout > 0.2f * BLI_rcti_size_y(&rect1))
rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1);
else
- rect1.ymax -= 2.0f * radout;
+ rect1.ymax -= radout;
/* inner part */
totvert = round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f);
- /* inverse linear shadow alpha */
- alpha = 0.15;
- alphastep = 0.67;
+ /* we draw a number of increasing size alpha quad strips */
+ alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
glEnableClientState(GL_VERTEX_ARRAY);
- for (step = 1; step <= radout; step++, alpha *= alphastep) {
+ for (step = 1; step <= (int)radout; step++) {
+ float expfac = sqrt(step / radout);
+
round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
- glColor4f(0.0f, 0.0f, 0.0f, alpha);
+ glColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
- widget_verts_to_quad_strip_open(&wtb, totvert, quad_strip);
+ widget_verts_to_quad_strip(&wtb, totvert, quad_strip);
glVertexPointer(2, GL_FLOAT, 0, quad_strip);
- glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2);
+ glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2 + 2);
}
glDisableClientState(GL_VERTEX_ARRAY);
@@ -1858,17 +1867,17 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
}
else if (direction == UI_DOWN) {
roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
- rect->ymin -= 4.0;
+ rect->ymin -= 0.1f * U.widget_unit;
}
else if (direction == UI_TOP) {
roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
- rect->ymax += 4.0;
+ rect->ymax += 0.1f * U.widget_unit;
}
glEnable(GL_BLEND);
- widget_softshadow(rect, roundboxalign, 5.0f, 8.0f);
+ widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit);
- round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+ round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit);
wtb.emboss = 0;
widgetbase_draw(&wtb, wcol);
@@ -2000,7 +2009,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
/* ************ custom buttons, old stuff ************** */
/* draws in resolution of 20x4 colors */
-void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha)
+void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha)
{
const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f;
int a;
@@ -2139,7 +2148,7 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa
-static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
+static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
{
float rgb[3];
float x = 0.0f, y = 0.0f;
@@ -2190,10 +2199,10 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
}
/* vertical 'value' slider, using new widget code */
-static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
+static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
{
uiWidgetBase wtb;
- float rad = 0.5f * BLI_rcti_size_x(rect);
+ const float rad = 0.5f * BLI_rcti_size_x(rect);
float x, y;
float rgb[3], hsv[3], v, range;
int color_profile = but->block->color_profile;
@@ -2238,7 +2247,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
/* ************ separator, for menus etc ***************** */
-static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol)
+static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
{
int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1;
unsigned char col[4];
@@ -2259,7 +2268,7 @@ static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol)
static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb;
- float rad = 0.5f * BLI_rcti_size_y(rect);
+ const float rad = 0.5f * BLI_rcti_size_y(rect);
float textofs = rad * 0.75f;
if (state & UI_SELECT)
@@ -2283,7 +2292,7 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
rect->xmax -= textofs;
}
-int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol)
+int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
{
float dist, vec[4][2];
@@ -2307,7 +2316,7 @@ int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol)
}
#define LINK_RESOL 24
-void ui_draw_link_bezier(rcti *rect)
+void ui_draw_link_bezier(const rcti *rect)
{
float coord_array[LINK_RESOL + 1][2];
@@ -2320,7 +2329,7 @@ void ui_draw_link_bezier(rcti *rect)
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, coord_array);
- glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL);
+ glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL + 1);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
@@ -2330,18 +2339,18 @@ void ui_draw_link_bezier(rcti *rect)
}
/* function in use for buttons and for view2d sliders */
-void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state)
+void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
{
uiWidgetBase wtb;
- float rad;
int horizontal;
+ float rad;
short outline = 0;
widget_init(&wtb);
/* determine horizontal/vertical */
horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
-
+
if (horizontal)
rad = 0.5f * BLI_rcti_size_y(rect);
else
@@ -2548,14 +2557,15 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin);
/* left part of slider, always rounded */
- rect1.xmax = rect1.xmin + ceil(offs + 1.0f);
+ rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize);
round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs);
wtb1.outline = 0;
widgetbase_draw(&wtb1, wcol);
/* right part of slider, interpolate roundness */
rect1.xmax = rect1.xmin + fac + offs;
- rect1.xmin += floor(offs - 1.0f);
+ rect1.xmin += floor(offs - U.pixelsize);
+
if (rect1.xmax + offs > rect->xmax)
offs *= (rect1.xmax + offs - rect->xmax) / offs;
else
@@ -2585,12 +2595,14 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb;
- float col[4];
+ float rad, col[4];
int color_profile = but->block->color_profile;
col[3] = 1.0f;
if (but->rnaprop) {
+ BLI_assert(but->rnaindex == -1);
+
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
color_profile = FALSE;
@@ -2602,7 +2614,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+ rad = 0.25f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
ui_get_but_vectorf(but, col);
@@ -2616,7 +2629,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
rect->ymin += SWATCH_KEYED_BORDER;
rect->ymax -= SWATCH_KEYED_BORDER;
- round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+ round_box_edges(&wtb, roundboxalign, rect, rad);
}
if (color_profile)
@@ -2640,12 +2653,14 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
{
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
uiWidgetBase wtb;
-
+ float rad;
+
widget_init(&wtb);
wtb.outline = 0;
/* rounded */
- round_box_edges(&wtb, UI_CNR_ALL, rect, 10.0f);
+ rad = 0.5f * BLI_rcti_size_y(rect);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
}
@@ -2654,6 +2669,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
if (state & UI_SELECT)
SWAP(short, wcol->shadetop, wcol->shadedown);
@@ -2661,7 +2677,8 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -2671,11 +2688,13 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
widget_menu_trias(&wtb.tria1, rect);
@@ -2689,11 +2708,13 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
widgetbase_draw(&wtb, wcol);
@@ -2704,11 +2725,13 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat
/* silly node link button hacks */
uiWidgetBase wtb;
uiWidgetColors wcol_backup = *wcol;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
wcol->inner[0] += 15;
wcol->inner[1] += 15;
@@ -2726,7 +2749,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int
{
if (state & UI_ACTIVE) {
uiWidgetBase wtb;
- float rad = 0.25f * BLI_rcti_size_y(rect); /* 4.0f */
+ const float rad = 0.2f * U.widget_unit;
widget_init(&wtb);
@@ -2753,12 +2776,14 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* rounded, but no outline */
wtb.outline = 0;
- round_box_edges(&wtb, UI_CNR_ALL, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
@@ -2767,6 +2792,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
{
uiWidgetBase wtb;
rcti recttemp = *rect;
+ float rad;
int delta;
widget_init(&wtb);
@@ -2782,7 +2808,8 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
recttemp.ymax -= delta;
/* half rounded */
- round_box_edges(&wtb, UI_CNR_ALL, &recttemp, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
/* decoration */
if (state & UI_SELECT) {
@@ -2799,11 +2826,13 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -2812,6 +2841,7 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
char old_col[3];
widget_init(&wtb);
@@ -2826,7 +2856,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
}
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
@@ -2841,12 +2872,14 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
+ float rad;
widget_init(&wtb);
/* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, 4.0f);
-
+ rad = 0.2f * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+
widgetbase_draw(&wtb, wcol);
}
@@ -2854,7 +2887,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int
static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
- float rad = 5.0f; /* 0.5f * BLI_rcti_size_y(rect); */
+ const float rad = 0.25f * U.widget_unit;
widget_init(&wtb);
@@ -2867,6 +2900,7 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect)
{
uiWidgetBase wtb;
+ const float rad = 0.25f * U.widget_unit;
unsigned char col[4];
/* state copy! */
@@ -2882,12 +2916,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
UI_GetThemeColor3ubv(TH_BACK, col);
glColor3ubv(col);
- round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, 4.0);
+ round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
widgetbase_outline(&wtb);
}
/* outline */
- round_box_edges(&wtb, UI_CNR_ALL, rect, 5.0f);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
wtb.outline = 1;
wtb.inner = 0;
widgetbase_draw(&wtb, &wt->wcol);
@@ -2895,7 +2929,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
}
-static void widget_disabled(rcti *rect)
+static void widget_disabled(const rcti *rect)
{
float col[4];
@@ -3076,9 +3110,9 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
/* ui_block_position has this correction too, keep in sync */
if (but->flag & UI_BUT_ALIGN_TOP)
- rect->ymax += 1;
+ rect->ymax += U.pixelsize;
if (but->flag & UI_BUT_ALIGN_LEFT)
- rect->xmin -= 1;
+ rect->xmin -= U.pixelsize;
switch (but->flag & UI_BUT_ALIGN) {
case UI_BUT_ALIGN_TOP:
@@ -3189,7 +3223,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case TEX:
wt = widget_type(UI_WTYPE_NAME);
break;
-
+
+ case SEARCH_MENU_UNLINK:
case SEARCH_MENU:
wt = widget_type(UI_WTYPE_NAME);
if (but->block->flag & UI_BLOCK_LOOP)
@@ -3389,7 +3424,7 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
uiWidgetType *wt = widget_type(UI_WTYPE_BOX);
glEnable(GL_BLEND);
- widget_softshadow(rect, UI_CNR_ALL, 5.0f, 8.0f);
+ widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit);
glDisable(GL_BLEND);
wt->state(wt, 0);
@@ -3416,7 +3451,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
fstyle->align = UI_STYLE_TEXT_LEFT;
/* text location offset */
- rect->xmin += 5;
+ rect->xmin += 0.25f * UI_UNIT_X;
if (iconid) rect->xmin += UI_DPI_ICON_SIZE;
/* cut string in 2 parts? */
@@ -3441,10 +3476,16 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
*rect = _rect;
if (iconid) {
- int xs = rect->xmin + 4;
- int ys = 1 + (rect->ymin + rect->ymax - UI_DPI_ICON_SIZE) / 2;
+ float height, aspect;
+ int xs = rect->xmin + 0.2f * UI_UNIT_X;
+ int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect);
+
+ /* icons are 80% of height of button (16 pixels inside 20 height) */
+ height = 0.8f * BLI_rcti_size_y(rect);
+ aspect = ICON_DEFAULT_HEIGHT / height;
+
glEnable(GL_BLEND);
- UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */
+ UI_icon_draw_aspect(xs, ys, iconid, aspect, 1.0f); /* XXX scale weak get from fstyle? */
glDisable(GL_BLEND);
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index fa5d580..ac7d423 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -86,7 +86,7 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
static char error[4] = {240, 0, 240, 255};
static char alert[4] = {240, 60, 60, 255};
static char headerdesel[4] = {0, 0, 0, 255};
-
+ static char setting = 0;
const char *cp = error;
if (btheme) {
@@ -170,6 +170,16 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
else
cp = ts->button;
break;
+ case TH_LOW_GRAD:
+ cp = ts->gradients.gradient;
+ break;
+ case TH_HIGH_GRAD:
+ cp = ts->gradients.high_gradient;
+ break;
+ case TH_SHOW_BACK_GRAD:
+ cp = &setting;
+ setting = ts->gradients.show_grad;
+ break;
case TH_TEXT:
if (theme_regionid == RGN_TYPE_WINDOW)
cp = ts->text;
@@ -216,13 +226,19 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_HEADER_TEXT_HI:
cp = ts->header_text_hi; break;
- case TH_PANEL:
- cp = ts->panel; break;
- case TH_PANEL_TEXT:
- cp = ts->panel_text; break;
- case TH_PANEL_TEXT_HI:
- cp = ts->panel_text_hi; break;
-
+ case TH_PANEL_HEADER:
+ cp = ts->panelcolors.header; break;
+ case TH_PANEL_BACK:
+ cp = ts->panelcolors.back; break;
+ case TH_PANEL_SHOW_HEADER:
+ cp = &setting;
+ setting = ts->panelcolors.show_header;
+ break;
+ case TH_PANEL_SHOW_BACK:
+ cp = &setting;
+ setting = ts->panelcolors.show_back;
+ break;
+
case TH_BUTBACK:
cp = ts->button; break;
case TH_BUTBACK_TEXT:
@@ -352,8 +368,14 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->syntaxc; break;
case TH_SYNTAX_L:
cp = ts->syntaxl; break;
+ case TH_SYNTAX_D:
+ cp = ts->syntaxd; break;
+ case TH_SYNTAX_R:
+ cp = ts->syntaxr; break;
case TH_SYNTAX_N:
cp = ts->syntaxn; break;
+ case TH_SYNTAX_S:
+ cp = ts->syntaxs; break;
case TH_NODE:
cp = ts->syntaxl; break;
@@ -603,9 +625,9 @@ static void ui_theme_init_new_do(ThemeSpace *ts)
rgba_char_args_test_set(ts->header_title, 0, 0, 0, 255);
rgba_char_args_test_set(ts->header_text_hi, 255, 255, 255, 255);
- rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255);
- rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255);
- rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255);
+// rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255);
+// rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255);
+// rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255);
rgba_char_args_test_set(ts->button, 145, 145, 145, 245);
rgba_char_args_test_set(ts->button_title, 0, 0, 0, 255);
@@ -671,6 +693,9 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
+ btheme->tui.menu_shadow_fac = 0.5f;
+ btheme->tui.menu_shadow_width = 12;
+
/* Bone Color Sets */
ui_theme_init_boneColorSets(btheme);
@@ -683,8 +708,8 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.text_hi, 255, 255, 255, 255);
rgba_char_args_set_fl(btheme->tv3d.header, 0.45, 0.45, 0.45, 1.0);
- rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 1.0);
- rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127);
+ rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 0.5);
+// rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127);
rgba_char_args_set(btheme->tv3d.shade1, 160, 160, 160, 100);
rgba_char_args_set(btheme->tv3d.shade2, 0x7f, 0x70, 0x70, 100);
@@ -757,20 +782,23 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255);
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
-
+ rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0);
+ rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 58, 58, 58, 255);
+ btheme->tv3d.gradients.show_grad = FALSE;
+
/* space buttons */
/* to have something initialized */
btheme->tbuts = btheme->tv3d;
rgba_char_args_set_fl(btheme->tbuts.back, 0.45, 0.45, 0.45, 1.0);
- rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255);
+// rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255);
/* graph editor */
btheme->tipo = btheme->tv3d;
rgba_char_args_set_fl(btheme->tipo.back, 0.42, 0.42, 0.42, 1.0);
rgba_char_args_set_fl(btheme->tipo.list, 0.4, 0.4, 0.4, 1.0);
rgba_char_args_set(btheme->tipo.grid, 94, 94, 94, 255);
- rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150);
+// rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150);
rgba_char_args_set(btheme->tipo.shade1, 150, 150, 150, 100); /* scrollbars */
rgba_char_args_set(btheme->tipo.shade2, 0x70, 0x70, 0x70, 100);
rgba_char_args_set(btheme->tipo.vertex, 0, 0, 0, 255);
@@ -816,11 +844,11 @@ void ui_theme_init_default(void)
/* to have something initialized */
btheme->tfile = btheme->tv3d;
rgba_char_args_set_fl(btheme->tfile.back, 0.3, 0.3, 0.3, 1);
- rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1);
+// rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1);
rgba_char_args_set_fl(btheme->tfile.list, 0.4, 0.4, 0.4, 1);
rgba_char_args_set(btheme->tfile.text, 250, 250, 250, 255);
rgba_char_args_set(btheme->tfile.text_hi, 15, 15, 15, 255);
- rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */
+// rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */
rgba_char_args_set(btheme->tfile.active, 130, 130, 130, 255); /* selected files */
rgba_char_args_set(btheme->tfile.hilite, 255, 140, 25, 255); /* selected files */
@@ -860,6 +888,7 @@ void ui_theme_init_default(void)
rgba_char_args_set_fl(btheme->tima.preview_stitch_vert, 0.0, 0.0, 1.0, 0.2);
rgba_char_args_set_fl(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0);
rgba_char_args_set_fl(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0);
+ rgba_char_args_set_fl(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140);
/* space text */
btheme->text = btheme->tv3d;
@@ -870,10 +899,13 @@ void ui_theme_init_default(void)
/* syntax highlighting */
rgba_char_args_set(btheme->text.syntaxn, 0, 0, 200, 255); /* Numbers Blue*/
- rgba_char_args_set(btheme->text.syntaxl, 100, 0, 0, 255); /* Strings red */
- rgba_char_args_set(btheme->text.syntaxc, 0, 100, 50, 255); /* Comments greenish */
- rgba_char_args_set(btheme->text.syntaxv, 95, 95, 0, 255); /* Special */
- rgba_char_args_set(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin, red-purple */
+ rgba_char_args_set(btheme->text.syntaxl, 100, 0, 0, 255); /* Strings Red */
+ rgba_char_args_set(btheme->text.syntaxc, 0, 100, 50, 255); /* Comments Greenish */
+ rgba_char_args_set(btheme->text.syntaxv, 95, 95, 0, 255); /* Special Yellow*/
+ rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
+ rgba_char_args_set(btheme->text.syntaxr, 140, 60, 0, 255); /* Reserved Orange*/
+ rgba_char_args_set(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin Red-purple */
+ rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
/* space oops */
btheme->toops = btheme->tv3d;
@@ -1252,6 +1284,12 @@ void UI_ThemeClearColor(int colorid)
glClearColor(col[0], col[1], col[2], 0.0);
}
+int UI_ThemeMenuShadowWidth(void)
+{
+ bTheme *btheme = UI_GetTheme();
+ return (int)(btheme->tui.menu_shadow_width * UI_DPI_FAC);
+}
+
void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3], const char axis)
{
unsigned char col[3];
@@ -1990,7 +2028,7 @@ void init_userdef_do_versions(void)
if (U.dragthreshold == 0)
U.dragthreshold = 5;
if (U.widget_unit == 0)
- U.widget_unit = (U.dpi * 20 + 36) / 72;
+ U.widget_unit = 20;
if (U.anisotropic_filter <= 0)
U.anisotropic_filter = 1;
@@ -2009,6 +2047,82 @@ void init_userdef_do_versions(void)
if (U.tweak_threshold == 0)
U.tweak_threshold = 10;
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 1)) {
+ bTheme *btheme;
+
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ /* note: the toggle operator for transparent backdrops limits to these spacetypes */
+ if (btheme->tnode.button[3] == 255) {
+ btheme->tv3d.button[3] = 128;
+ btheme->tnode.button[3] = 128;
+ btheme->tima.button[3] = 128;
+ btheme->tseq.button[3] = 128;
+ btheme->tclip.button[3] = 128;
+ }
+ }
+ }
+
+ /* panel header/backdrop supported locally per editor now */
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 2)) {
+ bTheme *btheme;
+
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+
+ /* new color, panel backdrop. Not used anywhere yet, until you enable it */
+ copy_v3_v3_char(btheme->tui.panel.back, btheme->tbuts.button);
+ btheme->tui.panel.back[3] = 128;
+
+ btheme->tbuts.panelcolors = btheme->tui.panel;
+ btheme->tv3d.panelcolors = btheme->tui.panel;
+ btheme->tfile.panelcolors = btheme->tui.panel;
+ btheme->tipo.panelcolors = btheme->tui.panel;
+ btheme->tinfo.panelcolors = btheme->tui.panel;
+ btheme->tact.panelcolors = btheme->tui.panel;
+ btheme->tnla.panelcolors = btheme->tui.panel;
+ btheme->tseq.panelcolors = btheme->tui.panel;
+ btheme->tima.panelcolors = btheme->tui.panel;
+ btheme->text.panelcolors = btheme->tui.panel;
+ btheme->toops.panelcolors = btheme->tui.panel;
+ btheme->ttime.panelcolors = btheme->tui.panel;
+ btheme->tnode.panelcolors = btheme->tui.panel;
+ btheme->tlogic.panelcolors = btheme->tui.panel;
+ btheme->tuserpref.panelcolors = btheme->tui.panel;
+ btheme->tconsole.panelcolors = btheme->tui.panel;
+ btheme->tclip.panelcolors = btheme->tui.panel;
+ }
+ }
+
+ if (bmain->versionfile < 266) {
+ bTheme *btheme;
+
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ /* rna definition limits fac to 0.01 */
+ if (btheme->tui.menu_shadow_fac == 0.0f) {
+ btheme->tui.menu_shadow_fac = 0.5f;
+ btheme->tui.menu_shadow_width = 12;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 265, 4)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
+ rgba_char_args_set(btheme->text.syntaxr, 140, 60, 0, 255); /* Reserved Orange */
+ rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 265, 6)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ copy_v4_v4_char(btheme->tv3d.gradients.high_gradient, btheme->tv3d.back);
+ }
+ }
+
+ if (U.pixelsize == 0.0f)
+ U.pixelsize = 1.0f;
+
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
/* this timer uses U */
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f1a3f59..41bbed8 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -60,6 +60,8 @@
#include "interface_intern.h"
+static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_scrollers);
+
/* *********************************************************************** */
/* XXX still unresolved: scrolls hide/unhide vs region mask handling */
@@ -73,15 +75,15 @@
*/
static int view2d_scroll_mapped(int scroll)
{
- if (scroll & V2D_SCROLL_HORIZONTAL_HIDE)
+ if (scroll & V2D_SCROLL_HORIZONTAL_FULLR)
scroll &= ~(V2D_SCROLL_HORIZONTAL);
- if (scroll & V2D_SCROLL_VERTICAL_HIDE)
+ if (scroll & V2D_SCROLL_VERTICAL_FULLR)
scroll &= ~(V2D_SCROLL_VERTICAL);
return scroll;
}
/* called each time cur changes, to dynamically update masks */
-static void view2d_masks(View2D *v2d)
+static void view2d_masks(View2D *v2d, int check_scrollers)
{
int scroll;
@@ -90,19 +92,26 @@ static void view2d_masks(View2D *v2d)
v2d->mask.xmax = v2d->winx - 1; /* -1 yes! masks are pixels */
v2d->mask.ymax = v2d->winy - 1;
-#if 0
- /* XXX see above */
- v2d->scroll &= ~(V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_VERTICAL_HIDE);
- /* check size if: */
- if (v2d->scroll & V2D_SCROLL_HORIZONTAL)
- if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL))
- if (BLI_rctf_size_x(&v2d->tot) <= BLI_rcti_size_x(&v2d->cur))
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- if (v2d->scroll & V2D_SCROLL_VERTICAL)
- if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL))
- if (BLI_rctf_size_y(&v2d->tot) <= BLI_rctf_size_y(&v2d->cur))
- v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
-#endif
+ if (check_scrollers) {
+ /* check size if hiding flag is set: */
+ if (v2d->scroll & V2D_SCROLL_HORIZONTAL_HIDE) {
+ if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL)) {
+ if (BLI_rctf_size_x(&v2d->tot) > BLI_rctf_size_x(&v2d->cur))
+ v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
+ else
+ v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR;
+ }
+ }
+ if (v2d->scroll & V2D_SCROLL_VERTICAL_HIDE) {
+ if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL)) {
+ if (BLI_rctf_size_y(&v2d->tot) + 0.01f > BLI_rctf_size_y(&v2d->cur))
+ v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
+ else
+ v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR;
+ }
+ }
+ }
+
scroll = view2d_scroll_mapped(v2d->scroll);
/* scrollers shrink mask area, but should be based off regionsize
@@ -126,8 +135,8 @@ static void view2d_masks(View2D *v2d)
}
/* horizontal scroller */
- if (scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O)) {
- /* on bottom edge of region (V2D_SCROLL_BOTTOM_O is outliner, the other is for standard) */
+ if (scroll & (V2D_SCROLL_BOTTOM)) {
+ /* on bottom edge of region */
v2d->hor = v2d->mask;
v2d->hor.ymax = V2D_SCROLL_HEIGHT;
v2d->mask.ymin = v2d->hor.ymax + 1;
@@ -142,8 +151,8 @@ static void view2d_masks(View2D *v2d)
/* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
if (scroll & V2D_SCROLL_VERTICAL) {
/* just set y min/max for vertical scroller to y min/max of mask as appropriate */
- if (scroll & (V2D_SCROLL_BOTTOM | V2D_SCROLL_BOTTOM_O)) {
- /* on bottom edge of region (V2D_SCROLL_BOTTOM_O is outliner, the other is for standard) */
+ if (scroll & (V2D_SCROLL_BOTTOM)) {
+ /* on bottom edge of region */
v2d->vert.ymin = v2d->mask.ymin;
}
else if (scroll & V2D_SCROLL_TOP) {
@@ -152,7 +161,6 @@ static void view2d_masks(View2D *v2d)
}
}
}
-
}
/* Refresh and Validation */
@@ -165,163 +173,173 @@ static void view2d_masks(View2D *v2d)
*/
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
{
- short tot_changed = 0, init = 0;
+ short tot_changed = 0, do_init;
uiStyle *style = UI_GetStyle();
- /* initialize data if there is a need for such */
- if ((v2d->flag & V2D_IS_INITIALISED) == 0) {
- /* set initialized flag so that View2D doesn't get reinitialised next time again */
- v2d->flag |= V2D_IS_INITIALISED;
-
- init = 1;
+ do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
- /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
- switch (type) {
- /* 'standard view' - optimum setup for 'standard' view behavior,
- * that should be used new views as basis for their
- * own unique View2D settings, which should be used instead of this in most cases...
+ /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
+ switch (type) {
+ /* 'standard view' - optimum setup for 'standard' view behavior,
+ * that should be used new views as basis for their
+ * own unique View2D settings, which should be used instead of this in most cases...
+ */
+ case V2D_COMMONVIEW_STANDARD:
+ {
+ /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
+ v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM);
+ v2d->minzoom = 0.01f;
+ v2d->maxzoom = 1000.0f;
+
+ /* tot rect and cur should be same size, and aligned using 'standard' OpenGL coordinates for now
+ * - region can resize 'tot' later to fit other data
+ * - keeptot is only within bounds, as strict locking is not that critical
+ * - view is aligned for (0,0) -> (winx-1, winy-1) setup
*/
- case V2D_COMMONVIEW_STANDARD:
- {
- /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
- v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM);
- v2d->minzoom = 0.01f;
- v2d->maxzoom = 1000.0f;
-
- /* tot rect and cur should be same size, and aligned using 'standard' OpenGL coordinates for now
- * - region can resize 'tot' later to fit other data
- * - keeptot is only within bounds, as strict locking is not that critical
- * - view is aligned for (0,0) -> (winx-1, winy-1) setup
- */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_BOUNDS;
-
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_BOUNDS;
+
+ if (do_init) {
v2d->tot.xmin = v2d->tot.ymin = 0.0f;
v2d->tot.xmax = (float)(winx - 1);
v2d->tot.ymax = (float)(winy - 1);
v2d->cur = v2d->tot;
-
- /* scrollers - should we have these by default? */
- /* XXX for now, we don't override this, or set it either! */
}
- break;
+ /* scrollers - should we have these by default? */
+ /* XXX for now, we don't override this, or set it either! */
+ }
+ break;
+
+ /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */
+ case V2D_COMMONVIEW_LIST:
+ {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
- /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */
- case V2D_COMMONVIEW_LIST:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = 1;
-
- /* scroller settings are currently not set here... that is left for regions... */
- }
- break;
-
- /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead.
- * zoom, aspect ratio, and alignment restrictions are set here */
- case V2D_COMMONVIEW_STACK:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = 1;
-
- /* scroller settings are currently not set here... that is left for regions... */
- }
- break;
+ /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* scroller settings are currently not set here... that is left for regions... */
+ }
+ break;
+
+ /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead.
+ * zoom, aspect ratio, and alignment restrictions are set here */
+ case V2D_COMMONVIEW_STACK:
+ {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* scroller settings are currently not set here... that is left for regions... */
+ }
+ break;
+
+ /* 'header' regions - zoom, aspect ratio, alignment, and panning restrictions are set here */
+ case V2D_COMMONVIEW_HEADER:
+ {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ if (do_init) {
+ v2d->tot.xmin = 0.0f;
+ v2d->tot.xmax = winx;
+ v2d->tot.ymin = 0.0f;
+ v2d->tot.ymax = winy;
+ v2d->cur = v2d->tot;
- /* 'header' regions - zoom, aspect ratio, alignment, and panning restrictions are set here */
- case V2D_COMMONVIEW_HEADER:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
v2d->min[0] = v2d->max[0] = (float)(winx - 1);
v2d->min[1] = v2d->max[1] = (float)(winy - 1);
-
- /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = 1;
-
- /* panning in y-axis is prohibited */
- v2d->keepofs = V2D_LOCKOFS_Y;
-
- /* absolutely no scrollers allowed */
- v2d->scroll = 0;
-
}
- break;
+ /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* panning in y-axis is prohibited */
+ v2d->keepofs = V2D_LOCKOFS_Y;
+
+ /* absolutely no scrollers allowed */
+ v2d->scroll = 0;
+
+ }
+ break;
+
+ /* panels view, with horizontal/vertical align */
+ case V2D_COMMONVIEW_PANELS_UI:
+ {
- /* panels view, with horizontal/vertical align */
- case V2D_COMMONVIEW_PANELS_UI:
- {
+ /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
+ v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM | V2D_KEEPZOOM);
+ v2d->minzoom = 0.5f;
+ v2d->maxzoom = 2.0f;
+
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot = V2D_KEEPTOT_BOUNDS;
+
+ /* note, scroll is being flipped in ED_region_panels() drawing */
+ v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ if (do_init) {
float panelzoom = (style) ? style->panelzoom : 1.0f;
+ float scrolw = v2d->scroll & V2D_SCROLL_RIGHT ? V2D_SCROLL_WIDTH : 0.0f;
- /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
- v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM | V2D_KEEPZOOM);
- v2d->minzoom = 0.5f;
- v2d->maxzoom = 2.0f;
- //tot_changed = 1;
-
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- v2d->keeptot = V2D_KEEPTOT_BOUNDS;
-
- v2d->scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
-
v2d->tot.xmin = 0.0f;
- v2d->tot.xmax = winx;
+ v2d->tot.xmax = winx - scrolw;
v2d->tot.ymax = 0.0f;
v2d->tot.ymin = -winy;
v2d->cur.xmin = 0.0f;
- /* bad workaround for keeping zoom level with scrollers */
- v2d->cur.xmax = (winx - V2D_SCROLL_WIDTH) * panelzoom;
+ v2d->cur.xmax = (winx) * panelzoom - scrolw;
v2d->cur.ymax = 0.0f;
v2d->cur.ymin = (-winy) * panelzoom;
}
- break;
-
- /* other view types are completely defined using their own settings already */
- default:
- /* we don't do anything here, as settings should be fine, but just make sure that rect */
- break;
}
+ break;
+
+ /* other view types are completely defined using their own settings already */
+ default:
+ /* we don't do anything here, as settings should be fine, but just make sure that rect */
+ break;
}
+ /* set initialized flag so that View2D doesn't get reinitialised next time again */
+ v2d->flag |= V2D_IS_INITIALISED;
+
/* store view size */
v2d->winx = winx;
v2d->winy = winy;
- /* set masks */
- view2d_masks(v2d);
+ /* set masks (always do), but leave scroller scheck to totrect_set */
+ view2d_masks(v2d, 0);
/* set 'tot' rect before setting cur? */
- if (tot_changed)
- UI_view2d_totRect_set_resize(v2d, winx, winy, !init);
+ /* XXX confusing stuff here still - I made this function not check scroller hide - that happens in totrect_set */
+ if (tot_changed)
+ UI_view2d_totRect_set_resize(v2d, winx, winy, !do_init);
else
- UI_view2d_curRect_validate_resize(v2d, !init);
+ ui_view2d_curRect_validate_resize(v2d, !do_init, 0);
+
}
/* Ensure View2D rects remain in a viable configuration
* - cur is not allowed to be: larger than max, smaller than min, or outside of tot
*/
// XXX pre2.5 -> this used to be called test_view2d()
-void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
+static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_scrollers)
{
float totwidth, totheight, curwidth, curheight, width, height;
float winx, winy;
@@ -715,12 +733,12 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
}
/* set masks */
- view2d_masks(v2d);
+ view2d_masks(v2d, mask_scrollers);
}
void UI_view2d_curRect_validate(View2D *v2d)
{
- UI_view2d_curRect_validate_resize(v2d, 0);
+ ui_view2d_curRect_validate_resize(v2d, 0, 1);
}
/* ------------------ */
@@ -844,7 +862,7 @@ void UI_view2d_curRect_reset(View2D *v2d)
/* Change the size of the maximum viewable area (i.e. 'tot' rect) */
void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize)
{
- int scroll = view2d_scroll_mapped(v2d->scroll);
+// int scroll = view2d_scroll_mapped(v2d->scroll);
/* don't do anything if either value is 0 */
width = abs(width);
@@ -852,10 +870,11 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize
/* hrumf! */
/* XXX: there are work arounds for this in the panel and file browse code. */
- if (scroll & V2D_SCROLL_HORIZONTAL)
- width -= V2D_SCROLL_WIDTH;
- if (scroll & V2D_SCROLL_VERTICAL)
- height -= V2D_SCROLL_HEIGHT;
+ /* round to int, because this is called with width + V2D_SCROLL_WIDTH */
+// if (scroll & V2D_SCROLL_HORIZONTAL)
+// width -= (int)V2D_SCROLL_WIDTH;
+// if (scroll & V2D_SCROLL_VERTICAL)
+// height -= (int)V2D_SCROLL_HEIGHT;
if (ELEM(0, width, height)) {
if (G.debug & G_DEBUG)
@@ -902,12 +921,21 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize
}
/* make sure that 'cur' rect is in a valid state as a result of these changes */
- UI_view2d_curRect_validate_resize(v2d, resize);
+ ui_view2d_curRect_validate_resize(v2d, resize, 1);
+
}
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
{
+ int scroll = view2d_scroll_mapped(v2d->scroll);
+
UI_view2d_totRect_set_resize(v2d, width, height, 0);
+
+ /* solve bad recursion... if scroller state changed, mask is different, so you get different rects */
+ if (scroll != view2d_scroll_mapped(v2d->scroll)) {
+ UI_view2d_totRect_set_resize(v2d, width, height, 0);
+ }
+
}
int UI_view2d_tab_set(View2D *v2d, int tab)
@@ -1150,7 +1178,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d,
pixels = (float)BLI_rcti_size_x(&v2d->mask);
if (pixels != 0.0f) {
- grid->dx = (U.v2d_min_gridsize * space) / (seconddiv * pixels);
+ grid->dx = (U.v2d_min_gridsize * UI_DPI_FAC * space) / (seconddiv * pixels);
step_to_grid(&grid->dx, &grid->powerx, xunits);
grid->dx *= seconddiv;
}
@@ -1167,7 +1195,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d,
space = BLI_rctf_size_y(&v2d->cur);
pixels = (float)winy;
- grid->dy = U.v2d_min_gridsize * space / pixels;
+ grid->dy = U.v2d_min_gridsize * UI_DPI_FAC * space / pixels;
step_to_grid(&grid->dy, &grid->powery, yunits);
if (yclamp == V2D_GRID_CLAMP) {
@@ -1212,7 +1240,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec2[1] = v2d->cur.ymax;
/* minor gridlines */
- step = (BLI_rcti_size_x(&v2d->mask) + 1) / U.v2d_min_gridsize;
+ step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
UI_ThemeColor(TH_GRID);
for (a = 0; a < step; a++) {
@@ -1246,7 +1274,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
vec1[0] = grid->startx;
vec2[0] = v2d->cur.xmax;
- step = (BLI_rcti_size_y(&v2d->mask) + 1) / U.v2d_min_gridsize;
+ step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
UI_ThemeColor(TH_GRID);
for (a = 0; a <= step; a++) {
@@ -1427,6 +1455,7 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
rcti vert, hor;
float fac1, fac2, totsize, scrollsize;
int scroll = view2d_scroll_mapped(v2d->scroll);
+ int smaller;
/* scrollers is allocated here... */
scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
@@ -1435,19 +1464,20 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
hor = v2d->hor;
/* slider rects need to be smaller than region */
- hor.xmin += 4;
- hor.xmax -= 4;
+ smaller = (int)(0.2f * U.widget_unit);
+ hor.xmin += smaller;
+ hor.xmax -= smaller;
if (scroll & V2D_SCROLL_BOTTOM)
- hor.ymin += 4;
+ hor.ymin += smaller;
else
- hor.ymax -= 4;
+ hor.ymax -= smaller;
if (scroll & V2D_SCROLL_LEFT)
- vert.xmin += 4;
+ vert.xmin += smaller;
else
- vert.xmax -= 4;
- vert.ymin += 4;
- vert.ymax -= 4;
+ vert.xmax -= smaller;
+ vert.ymin += smaller;
+ vert.ymax -= smaller;
CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
@@ -1491,15 +1521,6 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
CLAMP(scrollers->hor_min, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
}
- /* check whether sliders can disappear due to the full-range being used */
- if (v2d->keeptot) {
- if ((fac1 <= 0.0f) && (fac2 >= 1.0f)) {
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR;
- scrollers->horfull = 1;
- }
- else
- v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
- }
}
/* vertical scrollers */
@@ -1533,15 +1554,6 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
CLAMP(scrollers->vert_min, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
}
- /* check whether sliders can disappear due to the full-range being used */
- if (v2d->keeptot) {
- if ((fac1 <= 0.0f) && (fac2 >= 1.0f)) {
- v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR;
- scrollers->vertfull = 1;
- }
- else
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
- }
}
/* grid markings on scrollbars */
@@ -1615,40 +1627,42 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* horizontal scrollbar */
if (scroll & V2D_SCROLL_HORIZONTAL) {
- /* only draw scrollbar when it doesn't fill the entire space */
- if (vs->horfull == 0) {
- bTheme *btheme = UI_GetTheme();
- uiWidgetColors wcol = btheme->tui.wcol_scroll;
- rcti slider;
- int state;
-
- slider.xmin = vs->hor_min;
- slider.xmax = vs->hor_max;
- slider.ymin = hor.ymin;
- slider.ymax = hor.ymax;
-
- state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-
- /* show zoom handles if:
- * - zooming on x-axis is allowed (no scroll otherwise)
- * - slider bubble is large enough (no overdraw confusion)
- * - scale is shown on the scroller
- * (workaround to make sure that button windows don't show these,
- * and only the time-grids with their zoomability can do so)
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 &&
- (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
- (BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE))
- {
- state |= UI_SCROLL_ARROWS;
- }
-
- UI_ThemeColor(TH_BACK);
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetColors wcol = btheme->tui.wcol_scroll;
+ rcti slider;
+ int state;
+ unsigned char col[4];
+
+ slider.xmin = vs->hor_min;
+ slider.xmax = vs->hor_max;
+ slider.ymin = hor.ymin;
+ slider.ymax = hor.ymax;
+
+ state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
+
+ /* show zoom handles if:
+ * - zooming on x-axis is allowed (no scroll otherwise)
+ * - slider bubble is large enough (no overdraw confusion)
+ * - scale is shown on the scroller
+ * (workaround to make sure that button windows don't show these,
+ * and only the time-grids with their zoomability can do so)
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 &&
+ (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
+ (BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE))
+ {
+ state |= UI_SCROLL_ARROWS;
+ }
+
+ /* clean rect behind slider, but not with transparent background */
+ UI_GetThemeColor4ubv(TH_BACK, col);
+ if (col[3] == 255) {
+ glColor3ub(col[0], col[1], col[2]);
glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax);
-
- uiWidgetScrollDraw(&wcol, &hor, &slider, state);
}
+ uiWidgetScrollDraw(&wcol, &hor, &slider, state);
+
/* scale indicators */
if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) {
View2DGrid *grid = vs->grid;
@@ -1680,12 +1694,12 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
- float h = 2.0f + (float)(hor.ymin);
+ float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin);
- for (; fac < hor.xmax - 10; fac += dfac, val += grid->dx) {
+ for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) {
/* make prints look nicer for scrollers */
- if (fac < hor.xmin + 10)
+ if (fac < hor.xmin + 0.5f * U.widget_unit)
continue;
switch (vs->xunits) {
@@ -1726,40 +1740,42 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* vertical scrollbar */
if (scroll & V2D_SCROLL_VERTICAL) {
- /* only draw scrollbar when it doesn't fill the entire space */
- if (vs->vertfull == 0) {
- bTheme *btheme = UI_GetTheme();
- uiWidgetColors wcol = btheme->tui.wcol_scroll;
- rcti slider;
- int state;
-
- slider.xmin = vert.xmin;
- slider.xmax = vert.xmax;
- slider.ymin = vs->vert_min;
- slider.ymax = vs->vert_max;
-
- state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-
- /* show zoom handles if:
- * - zooming on y-axis is allowed (no scroll otherwise)
- * - slider bubble is large enough (no overdraw confusion)
- * - scale is shown on the scroller
- * (workaround to make sure that button windows don't show these,
- * and only the time-grids with their zoomability can do so)
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
- (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
- (BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE))
- {
- state |= UI_SCROLL_ARROWS;
- }
-
- UI_ThemeColor(TH_BACK);
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetColors wcol = btheme->tui.wcol_scroll;
+ rcti slider;
+ int state;
+ unsigned char col[4];
+
+ slider.xmin = vert.xmin;
+ slider.xmax = vert.xmax;
+ slider.ymin = vs->vert_min;
+ slider.ymax = vs->vert_max;
+
+ state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
+
+ /* show zoom handles if:
+ * - zooming on y-axis is allowed (no scroll otherwise)
+ * - slider bubble is large enough (no overdraw confusion)
+ * - scale is shown on the scroller
+ * (workaround to make sure that button windows don't show these,
+ * and only the time-grids with their zoomability can do so)
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
+ (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
+ (BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE))
+ {
+ state |= UI_SCROLL_ARROWS;
+ }
+
+ /* clean rect behind slider, but not with transparent background */
+ UI_GetThemeColor4ubv(TH_BACK, col);
+ if (col[3] == 255) {
+ glColor3ub(col[0], col[1], col[2]);
glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax);
-
- uiWidgetScrollDraw(&wcol, &vert, &slider, state);
}
+ uiWidgetScrollDraw(&wcol, &vert, &slider, state);
+
/* scale indiators */
if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) {
@@ -2047,6 +2063,12 @@ void UI_view2d_getscale(View2D *v2d, float *x, float *y)
if (x) *x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur);
if (y) *y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur);
}
+/* Same as UI_view2d_getscale() - 1.0f / x, y */
+void UI_view2d_getscale_inverse(View2D *v2d, float *x, float *y)
+{
+ if (x) *x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
+ if (y) *y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
+}
/* Check if mouse is within scrollers
* - Returns appropriate code for match
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 48a1f8b..fbbcb65 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -937,7 +937,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
vzd = op->customdata;
v2d = vzd->v2d;
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float dx, dy, fac;
vzd->lastx = event->prevx;
@@ -946,10 +946,19 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* As we have only 1D information (magnify value), feed both axes
* with magnify information that is stored in x axis
*/
- fac = 0.01f * (event->x - event->prevx);
+ fac = 0.01f * (event->prevx - event->x);
dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
+ if (event->type == MOUSEPAN)
+ fac = 0.01f * (event->prevy - event->y);
dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
+ /* support trackpad zoom to always zoom entirely - the v2d code uses portrait or landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(dx) > fabsf(dy))
+ dy = dx;
+ else
+ dx = dy;
+ }
RNA_float_set(op->ptr, "deltax", dx);
RNA_float_set(op->ptr, "deltay", dy);
@@ -1015,12 +1024,12 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
/* x-axis transform */
dist = BLI_rcti_size_x(&v2d->mask) / 2.0f;
- dx = 1.0f - (fabsf(vzd->lastx - dist) + 2.0f) / (fabsf(event->x - dist) + 2.0f);
+ dx = 1.0f - (fabsf(vzd->lastx - vzd->ar->winrct.xmin - dist) + 2.0f) / (fabsf(event->mval[0] - dist) + 2.0f);
dx *= 0.5f * BLI_rctf_size_x(&v2d->cur);
/* y-axis transform */
dist = BLI_rcti_size_y(&v2d->mask) / 2.0f;
- dy = 1.0f - (fabsf(vzd->lasty - dist) + 2.0f) / (fabsf(event->y - dist) + 2.0f);
+ dy = 1.0f - (fabsf(vzd->lasty - vzd->ar->winrct.ymin - dist) + 2.0f) / (fabsf(event->mval[1] - dist) + 2.0f);
dy *= 0.5f * BLI_rctf_size_y(&v2d->cur);
}
else {
@@ -1034,18 +1043,15 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
/* y-axis transform */
fac = 0.01f * (event->y - vzd->lasty);
dy = fac * BLI_rctf_size_y(&v2d->cur);
-#if 0
- /* continuous zoom shouldn't move that fast... */
- if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
- double time = PIL_check_seconds_timer();
- float time_step = (float)(time - vzd->timer_lastdraw);
-
- dx /= (0.1f / time_step);
- dy /= (0.1f / time_step);
-
- vzd->timer_lastdraw = time;
- }
-#endif
+
+ }
+
+ /* support zoom to always zoom entirely - the v2d code uses portrait or landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(dx) > fabsf(dy))
+ dy = dx;
+ else
+ dx = dy;
}
/* set transform amount, and add current deltas to stored total delta (for redo) */
@@ -1755,8 +1761,8 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* zone is also inappropriate if scroller is not visible... */
- if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_HORIZONTAL_FULLR))) ||
- ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_HIDE | V2D_SCROLL_VERTICAL_FULLR))) )
+ if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_FULLR))) ||
+ ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_FULLR))) )
{
/* free customdata initialized */
scroller_activate_exit(C, op);
@@ -1914,6 +1920,7 @@ void UI_view2d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW2D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
@@ -1962,6 +1969,7 @@ void UI_view2d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/io/SConscript b/source/blender/editors/io/SConscript
index d012576..cef73f3 100644
--- a/source/blender/editors/io/SConscript
+++ b/source/blender/editors/io/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import ('env')
diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript
index 4af000d..3200362 100644
--- a/source/blender/editors/mask/SConscript
+++ b/source/blender/editors/mask/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index 18384ad..cd2995b 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -324,15 +324,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
case SPACE_CLIP:
{
SpaceClip *sc = sa->spacedata.first;
- int width, height;
- float zoomx, zoomy, aspx, aspy;
+ float aspx, aspy;
- ED_space_clip_get_size(sc, &width, &height);
- ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
+ UI_view2d_getscale(&ar->v2d, scalex, scaley);
ED_space_clip_get_aspect(sc, &aspx, &aspy);
- *scalex = ((float)width * aspx) * zoomx;
- *scaley = ((float)height * aspy) * zoomy;
+ *scalex *= aspx;
+ *scaley *= aspy;
break;
}
case SPACE_SEQ:
@@ -343,15 +341,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s
case SPACE_IMAGE:
{
SpaceImage *sima = sa->spacedata.first;
- int width, height;
- float zoomx, zoomy, aspx, aspy;
+ float aspx, aspy;
- ED_space_image_get_size(sima, &width, &height);
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ UI_view2d_getscale(&ar->v2d, scalex, scaley);
ED_space_image_get_aspect(sima, &aspx, &aspy);
- *scalex = ((float)width * aspx) * zoomx;
- *scaley = ((float)height * aspy) * zoomy;
+ *scalex *= aspx;
+ *scaley *= aspy;
break;
}
default:
diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c
index a1f2539..2a1bdee 100644
--- a/source/blender/editors/mask/mask_relationships.c
+++ b/source/blender/editors/mask/mask_relationships.c
@@ -31,6 +31,7 @@
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -143,8 +144,8 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
if (MASKPOINT_ISSEL_ANY(point)) {
point->parent.id_type = ID_MC;
point->parent.id = &clip->id;
- strcpy(point->parent.parent, tracking_object->name);
- strcpy(point->parent.sub_parent, track->name);
+ BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
+ BLI_strncpy(point->parent.sub_parent, track->name, sizeof(point->parent.sub_parent));
copy_v2_v2(point->parent.parent_orig, parmask_pos);
}
diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript
index 91ffdc9..11c90a4 100644
--- a/source/blender/editors/mesh/SConscript
+++ b/source/blender/editors/mesh/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 4350c00..3fbfaab 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -27,12 +27,9 @@
* \ingroup edmesh
*/
-#include <math.h>
-#include <string.h>
#include "MEM_guardedalloc.h"
-#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
@@ -41,9 +38,7 @@
#include "IMB_imbuf.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
@@ -61,7 +56,6 @@
#include "WM_types.h"
/* own include */
-#include "mesh_intern.h"
/* copy the face flags, most importantly selection from the mesh to the final derived mesh,
* use in object mode when selecting faces (while painting) */
@@ -75,7 +69,14 @@ void paintface_flush_flags(Object *ob)
int totface, totpoly;
int i;
- if (me == NULL || dm == NULL)
+ if (me == NULL)
+ return;
+
+ /* we could call this directly in all areas that change selection,
+ * since this could become slow for realtime updates (circle-select for eg) */
+ BKE_mesh_flush_select_from_polys(me);
+
+ if (dm == NULL)
return;
/*
@@ -483,7 +484,7 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in
/* Get the face under the cursor */
me = BKE_mesh_from_object(ob);
- if (!ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE))
+ if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE))
return 0;
if (index >= me->totpoly)
@@ -609,7 +610,14 @@ void paintvert_flush_flags(Object *ob)
int totvert;
int i;
- if (me == NULL || dm == NULL)
+ if (me == NULL)
+ return;
+
+ /* we could call this directly in all areas that change selection,
+ * since this could become slow for realtime updates (circle-select for eg) */
+ BKE_mesh_flush_select_from_verts(me);
+
+ if (dm == NULL)
return;
index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
@@ -852,7 +860,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
if (em) {
if (skip_em_vert_array_init == FALSE) {
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
}
}
@@ -888,11 +896,6 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to
last = a;
}
}
- if (em) {
- if (skip_em_vert_array_init == FALSE) {
- EDBM_index_arrays_free(em);
- }
- }
MEM_freeN(topo_pairs);
topo_pairs = NULL;
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 4a425c8..a356f9f 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -29,7 +29,6 @@
* \ingroup edmesh
*/
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -39,7 +38,6 @@
#include "BLI_math.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_library.h"
#include "BKE_tessmesh.h"
@@ -58,7 +56,7 @@
/* BMESH_TODO: 'state' is not a good name, should be flipped and called 'was_editmode',
* or at least something more descriptive */
static Object *make_prim_init(bContext *C, const char *idname,
- float *dia, float mat[][4],
+ float *dia, float mat[4][4],
int *state, const float loc[3], const float rot[3], const unsigned int layer)
{
Object *obedit = CTX_data_edit_object(C);
@@ -90,7 +88,7 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
/* only recalc editmode tessface if we are staying in editmode */
- EDBM_update_generic(C, em, !exit_editmode);
+ EDBM_update_generic(em, !exit_editmode, TRUE);
/* userdef */
if (exit_editmode) {
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index cbe2661..e49dc3c 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -38,14 +38,11 @@
#include "BLI_blenlib.h"
#include "BLI_array.h"
#include "BLI_math.h"
-#include "BLI_rand.h"
#include "BLI_smallhash.h"
-#include "BLI_scanfill.h"
#include "BLI_memarena.h"
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BIF_gl.h"
#include "BIF_glutil.h" /* for paint cursor */
@@ -59,7 +56,6 @@
#include "WM_types.h"
#include "DNA_scene_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BKE_tessmesh.h"
#include "UI_resources.h"
@@ -132,7 +128,7 @@ typedef struct KnifePosData {
BMFace *bmface;
int is_space;
- int mval[2]; /* mouse screen position */
+ float mval[2]; /* mouse screen position (may be non-integral if snapped to something) */
} KnifePosData;
/* struct for properties used while drawing */
@@ -208,10 +204,10 @@ typedef struct KnifeTool_OpData {
static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f);
#if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
float r_origin[3], float r_ray[3]);
#endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_dest[3]);
static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
@@ -229,6 +225,10 @@ static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
ED_area_headerprint(CTX_wm_area(C), header);
}
+BLI_INLINE int round_ftoi(float x)
+{
+ return x > 0.0f ? (int)(x + 0.5f) : (int)(x - 0.5f);
+}
static void knife_project_v3(KnifeTool_OpData *kcd, const float co[3], float sco[3])
{
@@ -242,8 +242,8 @@ static void knife_pos_data_clear(KnifePosData *kpd)
kpd->vert = NULL;
kpd->edge = NULL;
kpd->bmface = NULL;
- kpd->mval[0] = 0;
- kpd->mval[1] = 0;
+ kpd->mval[0] = 0.0f;
+ kpd->mval[1] = 0.0f;
}
static ListBase *knife_empty_list(KnifeTool_OpData *kcd)
@@ -1150,7 +1150,7 @@ static float len_v3_tri_side_max(const float v1[3], const float v2[3], const flo
const float s2 = len_squared_v3v3(v2, v3);
const float s3 = len_squared_v3v3(v3, v1);
- return sqrtf(MAX3(s1, s2, s3));
+ return sqrtf(max_fff(s1, s2, s3));
}
static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
@@ -1319,12 +1319,12 @@ static void knife_bgl_get_mats(KnifeTool_OpData *UNUSED(kcd), bglMats *mats)
//copy_m4_m4(mats->projection, kcd->vc.rv3d->winmat);
}
-/* Calculate maximum excursion (doubled) from (0,0,0) of mesh */
+/* Calculate maximum excursion from (0,0,0) of mesh */
static void calc_ortho_extent(KnifeTool_OpData *kcd)
{
BMIter iter;
BMVert *v;
- BMesh* bm = kcd->em->bm;
+ BMesh *bm = kcd->em->bm;
float max_xyz = 0.0f;
int i;
@@ -1332,7 +1332,19 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
for (i = 0; i < 3; i++)
max_xyz = max_ff(max_xyz, fabs(v->co[i]));
}
- kcd->ortho_extent = 2 * max_xyz;
+ kcd->ortho_extent = max_xyz;
+}
+
+/* Clip the line (v1, v2) to planes perpendicular to it and distances d from
+ * the closest point on the line to the origin */
+static void clip_to_ortho_planes(float v1[3], float v2[3], float d)
+{
+ float closest[3];
+ const float origin[3] = {0.0f, 0.0f, 0.0f};
+
+ closest_to_line_v3(closest, origin, v1, v2);
+ dist_ensure_v3_v3fl(v1, closest, d);
+ dist_ensure_v3_v3fl(v2, closest, d);
}
/* Finds visible (or all, if cutting through) edges that intersects the current screen drag line */
@@ -1379,8 +1391,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
if (kcd->is_ortho) {
if (kcd->ortho_extent == 0.0f)
calc_ortho_extent(kcd);
- limit_dist_v3(v1, v3, kcd->ortho_extent + 10.0f);
- limit_dist_v3(v2, v4, kcd->ortho_extent + 10.0f);
+ clip_to_ortho_planes(v1, v3, kcd->ortho_extent + 10.0f);
+ clip_to_ortho_planes(v2, v4, kcd->ortho_extent + 10.0f);
}
BLI_smallhash_init(ehash);
@@ -1412,17 +1424,14 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
/* this works but gives numeric problems [#33400] */
#if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
float r_origin[3], float r_ray[3])
{
bglMats mats;
- float mval[2], imat[3][3];
+ float imat[3][3];
knife_bgl_get_mats(kcd, &mats);
- mval[0] = (float)mval_i[0];
- mval[1] = (float)mval_i[1];
-
/* unproject to find view ray */
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
@@ -1444,23 +1453,19 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
}
#endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
float r_origin[3], float r_origin_ofs[3])
{
bglMats mats;
- float mval[2];
knife_bgl_get_mats(kcd, &mats);
- mval[0] = (float)mval_i[0];
- mval[1] = (float)mval_i[1];
-
/* unproject to find view ray */
ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
/* transform into object space */
- invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
+ invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
mul_m4_v3(kcd->ob->imat, r_origin);
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
@@ -1475,7 +1480,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
float ray[3];
/* unproject to find view ray */
- knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
f = BMBVH_RayCast(kcd->bmbvh, origin, ray, co, cageco);
@@ -1594,10 +1599,10 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
dis = dist_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco);
if (dis < curdis && dis < maxdist) {
if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) {
- float labda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
+ float lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
float vec[3];
- interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, labda);
+ interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, lambda);
if (ED_view3d_clipping_test(kcd->vc.rv3d, vec, TRUE) == 0) {
cure = kfe;
@@ -1633,8 +1638,8 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
/* update mouse coordinates to the snapped-to edge's screen coordinates
* this is important for angle snap, which uses the previous mouse position */
edgesnap = new_knife_vert(kcd, p, cagep);
- kcd->curr.mval[0] = (int)edgesnap->sco[0];
- kcd->curr.mval[1] = (int)edgesnap->sco[1];
+ kcd->curr.mval[0] = edgesnap->sco[0];
+ kcd->curr.mval[1] = edgesnap->sco[1];
}
else {
@@ -1712,8 +1717,8 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
/* update mouse coordinates to the snapped-to vertex's screen coordinates
* this is important for angle snap, which uses the previous mouse position */
- kcd->curr.mval[0] = (int)curv->sco[0];
- kcd->curr.mval[1] = (int)curv->sco[1];
+ kcd->curr.mval[0] = curv->sco[0];
+ kcd->curr.mval[1] = curv->sco[1];
}
return curv;
@@ -1732,48 +1737,56 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
return NULL;
}
+/* update both kcd->curr.mval and kcd->vc.mval to snap to required angle */
static void knife_snap_angle(KnifeTool_OpData *kcd)
{
- int dx, dy;
+ float dx, dy;
float w, abs_tan;
- dx = kcd->vc.mval[0] - kcd->prev.mval[0];
- dy = kcd->vc.mval[1] - kcd->prev.mval[1];
- if (dx == 0 || dy == 0)
+ dx = kcd->curr.mval[0] - kcd->prev.mval[0];
+ dy = kcd->curr.mval[1] - kcd->prev.mval[1];
+ if (dx == 0.0f && dy == 0.0f)
return;
- w = (float)dy / (float)dx;
+ if (dx == 0.0f) {
+ kcd->angle_snapping = ANGLE_90;
+ kcd->curr.mval[0] = kcd->prev.mval[0];
+ }
+
+ w = dy / dx;
abs_tan = fabsf(w);
if (abs_tan <= 0.4142f) { /* tan(22.5 degrees) = 0.4142 */
kcd->angle_snapping = ANGLE_0;
- kcd->vc.mval[1] = kcd->prev.mval[1];
+ kcd->curr.mval[1] = kcd->prev.mval[1];
}
else if (abs_tan < 2.4142f) { /* tan(67.5 degrees) = 2.4142 */
if (w > 0) {
kcd->angle_snapping = ANGLE_45;
- kcd->vc.mval[1] = kcd->prev.mval[1] + dx;
+ kcd->curr.mval[1] = kcd->prev.mval[1] + dx;
}
else {
kcd->angle_snapping = ANGLE_135;
- kcd->vc.mval[1] = kcd->prev.mval[1] - dx;
+ kcd->curr.mval[1] = kcd->prev.mval[1] - dx;
}
}
else {
kcd->angle_snapping = ANGLE_90;
- kcd->vc.mval[0] = kcd->prev.mval[0];
+ kcd->curr.mval[0] = kcd->prev.mval[0];
}
+
+ kcd->vc.mval[0] = round_ftoi(kcd->curr.mval[0]);
+ kcd->vc.mval[1] = round_ftoi(kcd->curr.mval[1]);
}
/* update active knife edge/vert pointers */
static int knife_update_active(KnifeTool_OpData *kcd)
{
+ knife_pos_data_clear(&kcd->curr);
+ kcd->curr.mval[0] = (float)kcd->vc.mval[0];
+ kcd->curr.mval[1] = (float)kcd->vc.mval[1];
if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
knife_snap_angle(kcd);
- knife_pos_data_clear(&kcd->curr);
- kcd->curr.mval[0] = kcd->vc.mval[0];
- kcd->curr.mval[1] = kcd->vc.mval[1];
-
/* XXX knife_snap_angle updates the view coordinate mouse values to constrained angles,
* which current mouse values are set to current mouse values are then used
* for vertex and edge snap detection, without regard to the exact angle constraint */
@@ -1791,7 +1804,7 @@ static int knife_update_active(KnifeTool_OpData *kcd)
float origin[3];
float origin_ofs[3];
- knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+ knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, origin_ofs, origin);
}
@@ -2591,10 +2604,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
BMLoop *lnew, *l_iter;
int i;
int nco = BLI_countlist(chain) - 1;
- float (*cos)[3] = NULL;
- KnifeVert **kverts;
- BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
- BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
+ float (*cos)[3] = BLI_array_alloca(cos, nco);
+ KnifeVert **kverts = BLI_array_alloca(kverts, nco);
kfe = ((Ref *)chain->first)->ref;
v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v;
@@ -2643,9 +2654,6 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
BM_edge_select_set(bm, lnew->e, TRUE);
}
}
-
- BLI_array_fixedstack_free(cos);
- BLI_array_fixedstack_free(kverts);
}
static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges)
@@ -2835,7 +2843,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
#endif
/* called on tool confirmation */
-static void knifetool_finish(bContext *C, wmOperator *op)
+static void knifetool_finish(wmOperator *op)
{
KnifeTool_OpData *kcd = op->customdata;
@@ -2846,7 +2854,7 @@ static void knifetool_finish(bContext *C, wmOperator *op)
#endif
EDBM_mesh_normals_update(kcd->em);
- EDBM_update_generic(C, kcd->em, TRUE);
+ EDBM_update_generic(kcd->em, TRUE, TRUE);
}
/* copied from paint_image.c */
@@ -2926,11 +2934,11 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co
}
}
-static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval_i[2])
{
knife_recalc_projmat(kcd);
- kcd->vc.mval[0] = mval[0];
- kcd->vc.mval[1] = mval[1];
+ kcd->vc.mval[0] = mval_i[0];
+ kcd->vc.mval[1] = mval_i[1];
if (knife_update_active(kcd)) {
ED_region_tag_redraw(kcd->ar);
@@ -3134,7 +3142,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
/* finish */
ED_region_tag_redraw(kcd->ar);
- knifetool_finish(C, op);
+ knifetool_finish(op);
knifetool_exit(C, op);
ED_area_headerprint(CTX_wm_area(C), NULL);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index dec45b7..5f923dd 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -28,46 +28,21 @@
* \ingroup edmesh
*/
-#include <float.h>
-#ifdef _MSC_VER
-# define _USE_MATH_DEFINES
-#endif
-#include <math.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#include "DNA_ID.h"
#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
-#include "DNA_userdef_types.h"
#include "MEM_guardedalloc.h"
-#include "PIL_time.h"
-
#include "BLI_array.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_dynstr.h" /*for WM_operator_pystring */
-#include "BLI_utildefines.h"
-#include "BKE_blender.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_tessmesh.h"
-#include "BKE_depsgraph.h"
#include "BIF_gl.h"
-#include "BIF_glutil.h" /* for paint cursor */
-
-#include "IMB_imbuf_types.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -78,8 +53,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "UI_interface.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -187,7 +160,6 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
BMWalker walker;
float (*edges)[2][3] = NULL;
BLI_array_declare(edges);
- float co[2][3];
int i, tot = 0;
memset(v, 0, sizeof(v));
@@ -245,16 +217,9 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
BLI_array_grow_items(edges, previewlines);
for (i = 1; i <= previewlines; i++) {
- co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0]) * (i / ((float)previewlines + 1)) + v[0][0]->co[0];
- co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1]) * (i / ((float)previewlines + 1)) + v[0][0]->co[1];
- co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2]) * (i / ((float)previewlines + 1)) + v[0][0]->co[2];
-
- co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0]) * (i / ((float)previewlines + 1)) + v[1][0]->co[0];
- co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1]) * (i / ((float)previewlines + 1)) + v[1][0]->co[1];
- co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2]) * (i / ((float)previewlines + 1)) + v[1][0]->co[2];
-
- copy_v3_v3(edges[tot][0], co[0]);
- copy_v3_v3(edges[tot][1], co[1]);
+ const float fac = (i / ((float)previewlines + 1));
+ interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
+ interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
tot++;
}
}
@@ -274,19 +239,14 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
BLI_array_grow_items(edges, previewlines);
for (i = 1; i <= previewlines; i++) {
- if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1])
+ const float fac = (i / ((float)previewlines + 1));
+
+ if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1]) {
continue;
-
- co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0]) * (i / ((float)previewlines + 1)) + v[0][0]->co[0];
- co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1]) * (i / ((float)previewlines + 1)) + v[0][0]->co[1];
- co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2]) * (i / ((float)previewlines + 1)) + v[0][0]->co[2];
+ }
- co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0]) * (i / ((float)previewlines + 1)) + v[1][0]->co[0];
- co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1]) * (i / ((float)previewlines + 1)) + v[1][0]->co[1];
- co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2]) * (i / ((float)previewlines + 1)) + v[1][0]->co[2];
-
- copy_v3_v3(edges[tot][0], co[0]);
- copy_v3_v3(edges[tot][1], co[1]);
+ interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
+ interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
tot++;
}
}
@@ -334,6 +294,9 @@ static void ringsel_finish(bContext *C, wmOperator *op)
SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE,
use_only_quads, 0);
+ /* tessface is already re-recalculated */
+ EDBM_update_generic(em, FALSE, TRUE);
+
/* force edge slide to edge select mode in in face select mode */
if (em->selectmode & SCE_SELECT_FACE) {
if (em->selectmode == SCE_SELECT_FACE)
@@ -345,11 +308,9 @@ static void ringsel_finish(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C));
}
- else
+ else {
EDBM_selectmode_flush(lcd->em);
-
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, lcd->ob->data);
- DAG_id_tag_update(lcd->ob->data, 0);
+ }
}
else {
/* XXX Is this piece of code ever used now? Simple loop select is now
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 2ecc20b..6cbf5e8 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -31,7 +31,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "RNA_define.h"
@@ -41,11 +40,9 @@
#include "BLI_array.h"
#include "BKE_context.h"
-#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
@@ -63,7 +60,7 @@
* point and would result in the same distance.
*/
#define INSET_DEFAULT 0.00001f
-static float edbm_rip_edgedist(ARegion *ar, float mat[][4],
+static float edbm_rip_edgedist(ARegion *ar, float mat[4][4],
const float co1[3], const float co2[3], const float mvalf[2],
const float inset)
{
@@ -83,7 +80,7 @@ static float edbm_rip_edgedist(ARegion *ar, float mat[][4],
}
#if 0
-static float edbm_rip_linedist(ARegion *ar, float mat[][4],
+static float edbm_rip_linedist(ARegion *ar, float mat[4][4],
const float co1[3], const float co2[3], const float mvalf[2])
{
float vec1[2], vec2[2];
@@ -1044,7 +1041,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 6fd8f0c..f552a7b 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -40,9 +40,9 @@
#include "BKE_context.h"
#include "BKE_displist.h"
-#include "BKE_depsgraph.h"
#include "BKE_report.h"
#include "BKE_paint.h"
+#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
#include "IMB_imbuf_types.h"
@@ -56,9 +56,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "ED_util.h"
#include "ED_uvedit.h"
-#include "ED_object.h"
#include "ED_view3d.h"
#include "BIF_gl.h"
@@ -107,21 +105,23 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, int extend)
void EDBM_automerge(Scene *scene, Object *obedit, int update)
{
- BMEditMesh *em;
if ((scene->toolsettings->automerge) &&
(obedit && obedit->type == OB_MESH))
{
- em = BMEdit_FromObject(obedit);
- if (!em)
+ int ok;
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+
+ if (!em) {
return;
+ }
+
+ ok = BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
+ "automerge verts=%hv dist=%f",
+ BM_ELEM_SELECT, scene->toolsettings->doublimit);
- BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
- "automerge verts=%hv dist=%f",
- BM_ELEM_SELECT, scene->toolsettings->doublimit);
- if (update) {
- DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
- BMEdit_RecalcTessellation(em);
+ if (LIKELY(ok) && update) {
+ EDBM_update_generic(em, TRUE, TRUE);
}
}
}
@@ -464,12 +464,12 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float
if (distance < data->dist) {
if (data->vc.rv3d->rflag & RV3D_CLIPPING) {
- float labda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b);
+ float lambda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b);
float vec[3];
- vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]);
- vec[1] = eed->v1->co[1] + labda * (eed->v2->co[1] - eed->v1->co[1]);
- vec[2] = eed->v1->co[2] + labda * (eed->v2->co[2] - eed->v1->co[2]);
+ vec[0] = eed->v1->co[0] + lambda * (eed->v2->co[0] - eed->v1->co[0]);
+ vec[1] = eed->v1->co[1] + lambda * (eed->v2->co[1] - eed->v1->co[1]);
+ vec[2] = eed->v1->co[2] + lambda * (eed->v2->co[2] - eed->v1->co[2]);
if (ED_view3d_clipping_test(data->vc.rv3d, vec, TRUE) == 0) {
data->dist = distance;
@@ -573,7 +573,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
data.mval_fl[0] = vc->mval[0];
data.mval_fl[1] = vc->mval[1];
- data.dist = 0x7FFF; /* largest short */
+ data.dist = FLT_MAX;
data.toFace = efa;
mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -725,7 +725,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -767,7 +767,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -812,7 +812,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1136,11 +1136,11 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
- if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
length_1 = len_squared_v2v2(mvalf, v1_co);
}
- if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
length_2 = len_squared_v2v2(mvalf, v2_co);
}
#if 0
@@ -1167,7 +1167,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
float co[2], tdist;
BM_face_calc_center_mean(f, cent);
- if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
tdist = len_squared_v2v2(mvalf, co);
if (tdist < best_dist) {
/* printf("Best face: %p (%f)\n", f, tdist);*/
@@ -1352,6 +1352,17 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge
/* note, would pass BM_EDGE except we are looping over all edges anyway */
BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */);
+ switch (scene->toolsettings->edge_mode) {
+ case EDGE_MODE_TAG_CREASE:
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_CREASE);
+ break;
+ case EDGE_MODE_TAG_BEVEL:
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_BWEIGHT);
+ break;
+ default:
+ break;
+ }
+
BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == FALSE) {
BM_elem_flag_disable(e, BM_ELEM_TAG);
@@ -1431,7 +1442,7 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge
/* ******************* mesh shortest path select, uses prev-selected edge ****************** */
/* since you want to create paths with multiple selects, it doesn't have extend option */
-static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc)
+static int mouse_mesh_shortest_path_edge(ViewContext *vc)
{
BMEditMesh *em = vc->em;
BMEdge *e_dst;
@@ -1470,7 +1481,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc)
BM_select_history_store(em->bm, e_dst);
/* force drawmode for mesh */
- switch (CTX_data_tool_settings(C)->edge_mode) {
+ switch (vc->scene->toolsettings->edge_mode) {
case EDGE_MODE_TAG_SEAM:
me->drawflag |= ME_DRAWSEAMS;
@@ -1487,7 +1498,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc)
break;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return TRUE;
}
@@ -1644,7 +1655,7 @@ static int facetag_shortest_path(Scene *scene, BMesh *bm, BMFace *f_src, BMFace
return 1;
}
-static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc)
+static int mouse_mesh_shortest_path_face(ViewContext *vc)
{
BMEditMesh *em = vc->em;
BMFace *f_dst;
@@ -1678,7 +1689,7 @@ static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc)
BM_active_face_set(em->bm, f_dst);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return TRUE;
}
@@ -1703,7 +1714,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op),
em = vc.em;
if (em->selectmode & SCE_SELECT_EDGE) {
- if (mouse_mesh_shortest_path_edge(C, &vc)) {
+ if (mouse_mesh_shortest_path_edge(&vc)) {
return OPERATOR_FINISHED;
}
else {
@@ -1711,7 +1722,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op),
}
}
else if (em->selectmode & SCE_SELECT_FACE) {
- if (mouse_mesh_shortest_path_face(C, &vc)) {
+ if (mouse_mesh_shortest_path_face(&vc)) {
return OPERATOR_FINISHED;
}
else {
@@ -1747,7 +1758,7 @@ void MESH_OT_select_shortest_path(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
/* ************************************************** */
@@ -2251,7 +2262,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
- e = BMW_begin(&walker, efa);
+ efa = BMW_begin(&walker, efa);
for (; efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, sel);
}
@@ -2345,7 +2356,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- e = BMW_begin(&walker, efa);
+ efa = BMW_begin(&walker, efa);
for (; efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, TRUE);
}
@@ -2382,8 +2393,9 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
}
}
BMW_end(&walker);
+
+ EDBM_selectmode_flush(em);
}
- EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
@@ -2636,7 +2648,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -2823,6 +2835,9 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
BMEdge *e;
BMIter iter;
+ if (!RNA_boolean_get(op->ptr, "extend"))
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
/* Selects isolated verts, and edges that do not have 2 neighboring
* faces
*/
@@ -2862,6 +2877,9 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend the selection");
}
static int edbm_select_random_exec(bContext *C, wmOperator *op)
@@ -2926,8 +2944,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
/* props */
RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f,
"Percent", "Percentage of elements to select randomly", 0.f, 100.0f);
- RNA_def_boolean(ot->srna, "extend", 0,
- "Extend Selection", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
static int edbm_select_next_loop_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c
index 4fbe9c2..eb0a212 100644
--- a/source/blender/editors/mesh/editmesh_slide.c
+++ b/source/blender/editors/mesh/editmesh_slide.c
@@ -264,7 +264,7 @@ static void vtx_slide_confirm(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
/* NC_GEOM | ND_DATA & Retess */
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
ED_region_tag_redraw(vso->active_region);
}
@@ -752,7 +752,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
if (do_update) {
/* Update Geometry */
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 3e03522..951c8b4 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -40,8 +40,8 @@
#include "RNA_define.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
-#include "BLI_array.h"
#include "BLI_blenlib.h"
#include "BLI_noise.h"
#include "BLI_math.h"
@@ -49,9 +49,7 @@
#include "BKE_material.h"
#include "BKE_context.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
-#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_texture.h"
@@ -112,7 +110,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE,
RNA_int_get(op->ptr, "seed"));
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -181,7 +179,7 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op)
}
EDBM_selectmode_flush(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -463,7 +461,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -585,7 +583,7 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
* done.*/
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -616,7 +614,7 @@ static int edbm_extrude_verts_exec(bContext *C, wmOperator *op)
edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -647,7 +645,7 @@ static int edbm_extrude_edges_exec(bContext *C, wmOperator *op)
edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -678,7 +676,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op)
edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -906,12 +904,12 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
BM_ELEM_SELECT, min);
}
else {
- float *curs = give_cursor(vc.scene, vc.v3d);
+ const float *curs = give_cursor(vc.scene, vc.v3d);
BMOperator bmop;
BMOIter oiter;
copy_v3_v3(min, curs);
- view3d_get_view_aligned_coordinate(&vc, min, event->mval, 0);
+ view3d_get_view_aligned_coordinate(&vc, min, event->mval, FALSE);
invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
mul_m4_v3(vc.obedit->imat, min); // back in object space
@@ -936,7 +934,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
* done. */
EDBM_mesh_normals_update(vc.em);
- EDBM_update_generic(C, vc.em, TRUE);
+ EDBM_update_generic(vc.em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1001,7 +999,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1034,7 +1032,7 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "collapse edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1062,7 +1060,7 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1121,7 +1119,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1176,7 +1174,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op)
}
ED_uvedit_live_unwrap(scene, obedit);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1230,7 +1228,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op)
}
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1272,7 +1270,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op)
else {
EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1310,7 +1308,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1349,7 +1347,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1388,7 +1386,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1469,7 +1467,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -1500,7 +1498,7 @@ static int edbm_hide_exec(bContext *C, wmOperator *op)
EDBM_mesh_hide(em, RNA_boolean_get(op->ptr, "unselected"));
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1530,7 +1528,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op))
EDBM_mesh_reveal(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1563,7 +1561,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "inside"))
EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1645,7 +1643,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
EDBM_verts_mirror_cache_end(em);
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1676,7 +1674,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BMEdit_FromObject(obedit);
int usex = TRUE, usey = TRUE, usez = TRUE, preserve_volume = TRUE;
int i, repeat;
- float lambda;
+ float lambda_factor;
float lambda_border;
BMIter fiter;
BMFace *f;
@@ -1697,7 +1695,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
}
repeat = RNA_int_get(op->ptr, "repeat");
- lambda = RNA_float_get(op->ptr, "lambda");
+ lambda_factor = RNA_float_get(op->ptr, "lambda_factor");
lambda_border = RNA_float_get(op->ptr, "lambda_border");
usex = RNA_boolean_get(op->ptr, "use_x");
usey = RNA_boolean_get(op->ptr, "use_y");
@@ -1708,8 +1706,8 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
for (i = 0; i < repeat; i++) {
if (!EDBM_op_callf(em, op,
- "smooth_laplacian_vert verts=%hv lambda=%f lambda_border=%f use_x=%b use_y=%b use_z=%b preserve_volume=%b",
- BM_ELEM_SELECT, lambda, lambda_border, usex, usey, usez, preserve_volume))
+ "smooth_laplacian_vert verts=%hv lambda_factor=%f lambda_border=%f use_x=%b use_y=%b use_z=%b preserve_volume=%b",
+ BM_ELEM_SELECT, lambda_factor, lambda_border, usex, usey, usez, preserve_volume))
{
return OPERATOR_CANCELLED;
}
@@ -1721,7 +1719,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
EDBM_verts_mirror_cache_end(em);
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1742,7 +1740,7 @@ void MESH_OT_vertices_smooth_laplacian(wmOperatorType *ot)
RNA_def_int(ot->srna, "repeat", 1, 1, 200,
"Number of iterations to smooth the mesh", "", 1, 200);
- RNA_def_float(ot->srna, "lambda", 0.00005f, 0.0000001f, 1000.0f,
+ RNA_def_float(ot->srna, "lambda_factor", 0.00005f, 0.0000001f, 1000.0f,
"Lambda factor", "", 0.0000001f, 1000.0f);
RNA_def_float(ot->srna, "lambda_border", 0.00005f, 0.0000001f, 1000.0f,
"Lambda factor in border", "", 0.0000001f, 1000.0f);
@@ -1775,7 +1773,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
mesh_set_smooth_faces(em, 1);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1802,7 +1800,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
mesh_set_smooth_faces(em, 0);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -1845,7 +1843,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1868,7 +1866,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1895,7 +1893,7 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
}
/* dependencies graph and notification stuff */
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -1919,7 +1917,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -2033,7 +2031,8 @@ static int merge_target(BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob,
{
BMIter iter;
BMVert *v;
- float *vco = NULL, co[3], cent[3] = {0.0f, 0.0f, 0.0f};
+ float co[3], cent[3] = {0.0f, 0.0f, 0.0f};
+ const float *vco = NULL;
if (target) {
vco = give_cursor(scene, v3d);
@@ -2104,7 +2103,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op)
if (!status)
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -2221,7 +2220,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
count = totvert_orig - em->bm->totvert;
BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -2328,7 +2327,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
EDBM_selectmode_flush(em);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
/* we succeeded */
return OPERATOR_FINISHED;
@@ -2403,7 +2402,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
shape_propagate(em, op);
- EDBM_update_generic(C, em, FALSE);
+ EDBM_update_generic(em, FALSE, FALSE);
return OPERATOR_FINISHED;
}
@@ -2474,7 +2473,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
}
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -2530,7 +2529,6 @@ static void edbm_blend_from_shape_ui(bContext *C, wmOperator *op)
void MESH_OT_blend_from_shape(wmOperatorType *ot)
{
PropertyRNA *prop;
- static EnumPropertyItem shape_items[] = {{0, NULL, 0, NULL, NULL}};
/* identifiers */
ot->name = "Blend From Shape";
@@ -2547,7 +2545,7 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_enum(ot->srna, "shape", shape_items, 0, "Shape", "Shape key to use for blending");
+ prop = RNA_def_enum(ot->srna, "shape", DummyRNA_NULL_items, 0, "Shape", "Shape key to use for blending");
RNA_def_enum_funcs(prop, shape_itemf);
RNA_def_float(ot->srna, "blend", 1.0f, -FLT_MAX, FLT_MAX, "Blend", "Blending factor", -2.0f, 2.0f);
RNA_def_boolean(ot->srna, "add", 1, "Add", "Add rather than blend between shapes");
@@ -2665,7 +2663,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -2930,7 +2928,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__);
BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK) {
copy_v2_fl(*sco, FLT_MAX); /* set error value */
}
BM_elem_index_set(bv, i); /* set_ok */
@@ -2990,7 +2988,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3232,7 +3230,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
else BLI_assert(0);
if (retval) {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
}
}
else {
@@ -3332,7 +3330,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
@@ -3361,7 +3359,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3392,7 +3390,7 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
if (!EDBM_op_callf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty))
return OPERATOR_CANCELLED;
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3433,7 +3431,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3489,7 +3487,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3561,7 +3559,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3584,7 +3582,7 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot)
prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, NULL, 0.0f, DEG2RADF(180.0f),
"Max Angle", "Angle limit", 0.0f, DEG2RADF(180.0f));
- RNA_def_property_float_default(prop, DEG2RADF(15.0f));
+ RNA_def_property_float_default(prop, DEG2RADF(5.0f));
RNA_def_boolean(ot->srna, "use_dissolve_boundaries", 0, "All Boundaries",
"Dissolve all vertices inbetween face boundaries");
}
@@ -3606,7 +3604,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
/* Geometry has changed, need to recalc normals and looptris */
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3665,7 +3663,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3788,7 +3786,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
@@ -3840,6 +3838,9 @@ static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
const int numverts = RNA_int_get(op->ptr, "number");
const int type = RNA_enum_get(op->ptr, "type");
+ if (!RNA_boolean_get(op->ptr, "extend"))
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int select;
@@ -3899,9 +3900,10 @@ void MESH_OT_select_face_by_sides(wmOperatorType *ot)
/* properties */
RNA_def_int(ot->srna, "number", 4, 3, INT_MAX, "Number of Vertices", "", 3, INT_MAX);
RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "Type of comparison to make");
+ RNA_def_boolean(ot->srna, "extend", TRUE, "Extend", "Extend the selection");
}
-static int edbm_select_loose_verts_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_select_loose_verts_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
@@ -3909,6 +3911,9 @@ static int edbm_select_loose_verts_exec(bContext *C, wmOperator *UNUSED(op))
BMEdge *eed;
BMIter iter;
+ if (!RNA_boolean_get(op->ptr, "extend"))
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!eve->e) {
BM_vert_select_set(em->bm, eve, TRUE);
@@ -3940,6 +3945,9 @@ void MESH_OT_select_loose_verts(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
@@ -4603,7 +4611,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op)
EDBM_mesh_normals_update(em);
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, FALSE);
return OPERATOR_FINISHED;
}
@@ -4762,7 +4770,7 @@ static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal)
return 1;
}
-static int edbm_bevel_calc(bContext *C, wmOperator *op)
+static int edbm_bevel_calc(wmOperator *op)
{
BevelData *opdata = op->customdata;
BMEditMesh *em = opdata->em;
@@ -4770,6 +4778,7 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op)
#ifdef NEW_BEVEL
float offset = RNA_float_get(op->ptr, "offset");
int segments = RNA_int_get(op->ptr, "segments");
+ int vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
/* revert to original mesh */
if (opdata->is_modal) {
@@ -4777,8 +4786,8 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op)
}
if (!EDBM_op_init(em, &bmop, op,
- "bevel geom=%hev offset=%f segments=%i",
- BM_ELEM_SELECT, offset, segments))
+ "bevel geom=%hev offset=%f segments=%i vertex_only=%b",
+ BM_ELEM_SELECT, offset, segments, vertex_only))
{
return 0;
}
@@ -4827,7 +4836,7 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op)
EDBM_mesh_normals_update(opdata->em);
- EDBM_update_generic(C, opdata->em, TRUE);
+ EDBM_update_generic(opdata->em, TRUE, TRUE);
return 1;
}
@@ -4859,7 +4868,7 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op)
BevelData *opdata = op->customdata;
if (opdata->is_modal) {
EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE);
- EDBM_update_generic(C, opdata->em, FALSE);
+ EDBM_update_generic(opdata->em, FALSE, TRUE);
}
edbm_bevel_exit(C, op);
@@ -4877,7 +4886,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (!edbm_bevel_calc(C, op)) {
+ if (!edbm_bevel_calc(op)) {
edbm_bevel_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -4914,7 +4923,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
edbm_bevel_update_header(op, C);
- if (!edbm_bevel_calc(C, op)) {
+ if (!edbm_bevel_calc(op)) {
edbm_bevel_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -4984,7 +4993,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
float value = RNA_float_get(op->ptr, "offset");
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
@@ -5017,7 +5026,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
RNA_float_set(op->ptr, "percent", factor);
#endif
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
}
break;
@@ -5025,7 +5034,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case PADENTER:
case RETKEY:
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_exit(C, op);
return OPERATOR_FINISHED;
@@ -5037,7 +5046,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
segments++;
RNA_int_set(op->ptr, "segments", segments);
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
break;
@@ -5048,7 +5057,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
segments = max_ii(segments - 1, 1);
RNA_int_set(op->ptr, "segments", segments);
- edbm_bevel_calc(C, op);
+ edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
break;
@@ -5103,6 +5112,7 @@ void MESH_OT_bevel(wmOperatorType *ot)
#ifdef NEW_BEVEL
RNA_def_float(ot->srna, "offset", 0.0f, -FLT_MAX, FLT_MAX, "Offset", "", 0.0f, 1.0f);
RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8);
+ RNA_def_boolean(ot->srna, "vertex_only", FALSE, "Vertex only", "Bevel only vertices");
#else
/* take note, used as a factor _and_ a distance depending on 'use_dist' */
RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f);
@@ -5140,7 +5150,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
}
@@ -5263,7 +5273,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op)
opdata = op->customdata;
if (opdata->is_modal) {
EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE);
- EDBM_update_generic(C, opdata->em, FALSE);
+ EDBM_update_generic(opdata->em, FALSE, TRUE);
}
edbm_inset_exit(C, op);
@@ -5273,7 +5283,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int edbm_inset_calc(bContext *C, wmOperator *op)
+static int edbm_inset_calc(wmOperator *op)
{
InsetData *opdata;
BMEditMesh *em;
@@ -5318,7 +5328,7 @@ static int edbm_inset_calc(bContext *C, wmOperator *op)
return 0;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return 1;
}
}
@@ -5327,7 +5337,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
{
edbm_inset_init(C, op, FALSE);
- if (!edbm_inset_calc(C, op)) {
+ if (!edbm_inset_calc(op)) {
edbm_inset_exit(C, op);
return OPERATOR_CANCELLED;
}
@@ -5358,7 +5368,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
opdata->initial_length = len_v2(mlen);
opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
- edbm_inset_calc(C, op);
+ edbm_inset_calc(op);
edbm_inset_update_header(op, C);
@@ -5381,7 +5391,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
RNA_float_set(op->ptr, "thickness", amounts[0]);
RNA_float_set(op->ptr, "depth", amounts[1]);
- if (edbm_inset_calc(C, op)) {
+ if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
@@ -5422,7 +5432,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
RNA_float_set(op->ptr, "thickness", amount);
}
- if (edbm_inset_calc(C, op))
+ if (edbm_inset_calc(op))
edbm_inset_update_header(op, C);
else {
edbm_inset_cancel(C, op);
@@ -5434,7 +5444,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case PADENTER:
case RETKEY:
- edbm_inset_calc(C, op);
+ edbm_inset_calc(op);
edbm_inset_exit(C, op);
return OPERATOR_FINISHED;
@@ -5483,7 +5493,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
int use_outset = RNA_boolean_get(op->ptr, "use_outset");
RNA_boolean_set(op->ptr, "use_outset", !use_outset);
- if (edbm_inset_calc(C, op)) {
+ if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
}
else {
@@ -5496,7 +5506,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
int use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
RNA_boolean_set(op->ptr, "use_boundary", !use_boundary);
- if (edbm_inset_calc(C, op)) {
+ if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
}
else {
@@ -5581,7 +5591,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
return OPERATOR_FINISHED;
}
}
@@ -5671,7 +5681,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
EDBM_selectmode_flush(em);
return OPERATOR_FINISHED;
}
@@ -5726,7 +5736,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- EDBM_update_generic(C, em, TRUE);
+ EDBM_update_generic(em, TRUE, TRUE);
EDBM_selectmode_flush(em);
return OPERATOR_FINISHED;
}
@@ -5734,18 +5744,6 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
void MESH_OT_symmetrize(struct wmOperatorType *ot)
{
- static EnumPropertyItem axis_direction_items[] = {
- {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
- {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
-
- {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
- {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
-
- {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
- {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
/* identifiers */
ot->name = "Symmetrize";
ot->description = "Enforce symmetry (both form and topological) across an axis";
@@ -5758,7 +5756,7 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items,
+ ot->prop = RNA_def_enum(ot->srna, "direction", symmetrize_direction_items,
BMO_SYMMETRIZE_NEGATIVE_X,
"Direction", "Which sides to copy from and to");
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 2cf6358..b95c8a0 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -35,15 +35,12 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_bmesh.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_key.h"
-#include "BKE_library.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -56,7 +53,6 @@
#include "ED_mesh.h"
#include "ED_util.h"
-#include "bmesh.h"
#include "mesh_intern.h"
@@ -391,81 +387,129 @@ void EDBM_mesh_free(BMEditMesh *em)
BMEdit_Free(em);
}
-void EDBM_index_arrays_init(BMEditMesh *tm, int forvert, int foredge, int forface)
+
+void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype)
{
- EDBM_index_arrays_free(tm);
+ /* assume if the array is non-null then its valid and no need to recalc */
+ const char htype_needed = ((em->vert_index ? 0 : BM_VERT) |
+ (em->edge_index ? 0 : BM_EDGE) |
+ (em->face_index ? 0 : BM_FACE)) & htype;
- if (forvert) {
- BMIter iter;
- BMVert *ele;
- int i = 0;
-
- tm->vert_index = MEM_mallocN(sizeof(void **) * tm->bm->totvert, "tm->vert_index");
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
- ele = BM_iter_new(&iter, tm->bm, BM_VERTS_OF_MESH, NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- tm->vert_index[i++] = ele;
+ /* in debug mode double check we didn't need to recalculate */
+ BLI_assert(EDBM_index_arrays_check(em) == TRUE);
+
+ if (htype_needed & BM_VERT) {
+ em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index");
+ }
+ if (htype_needed & BM_EDGE) {
+ em->edge_index = MEM_mallocN(sizeof(void **) * em->bm->totedge, "em->edge_index");
+ }
+ if (htype_needed & BM_FACE) {
+ em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index");
+ }
+
+#pragma omp parallel sections if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT)
+ {
+#pragma omp section
+ {
+ if (htype_needed & BM_VERT) {
+ BM_iter_as_array(em->bm, BM_VERTS_OF_MESH, NULL, (void **)em->vert_index, em->bm->totvert);
+ }
+ }
+#pragma omp section
+ {
+ if (htype_needed & BM_EDGE) {
+ BM_iter_as_array(em->bm, BM_EDGES_OF_MESH, NULL, (void **)em->edge_index, em->bm->totedge);
+ }
+ }
+#pragma omp section
+ {
+ if (htype_needed & BM_FACE) {
+ BM_iter_as_array(em->bm, BM_FACES_OF_MESH, NULL, (void **)em->face_index, em->bm->totface);
+ }
}
}
+}
- if (foredge) {
- BMIter iter;
- BMEdge *ele;
- int i = 0;
-
- tm->edge_index = MEM_mallocN(sizeof(void **) * tm->bm->totedge, "tm->edge_index");
+/* use EDBM_index_arrays_ensure where possible to avoid full rebuild */
+void EDBM_index_arrays_init(BMEditMesh *em, const char htype)
+{
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
- ele = BM_iter_new(&iter, tm->bm, BM_EDGES_OF_MESH, NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- tm->edge_index[i++] = ele;
- }
+ /* force recalc */
+ EDBM_index_arrays_free(em);
+ EDBM_index_arrays_ensure(em, htype);
+}
+
+void EDBM_index_arrays_free(BMEditMesh *em)
+{
+ if (em->vert_index) {
+ MEM_freeN(em->vert_index);
+ em->vert_index = NULL;
}
- if (forface) {
- BMIter iter;
- BMFace *ele;
- int i = 0;
-
- tm->face_index = MEM_mallocN(sizeof(void **) * tm->bm->totface, "tm->face_index");
+ if (em->edge_index) {
+ MEM_freeN(em->edge_index);
+ em->edge_index = NULL;
+ }
- ele = BM_iter_new(&iter, tm->bm, BM_FACES_OF_MESH, NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- tm->face_index[i++] = ele;
- }
+ if (em->face_index) {
+ MEM_freeN(em->face_index);
+ em->face_index = NULL;
}
}
-void EDBM_index_arrays_free(BMEditMesh *tm)
+/* debug check only - no need to optimize */
+#ifndef NDEBUG
+int EDBM_index_arrays_check(BMEditMesh *em)
{
- if (tm->vert_index) {
- MEM_freeN(tm->vert_index);
- tm->vert_index = NULL;
+ BMIter iter;
+ BMElem *ele;
+ int i;
+
+ if (em->vert_index) {
+ BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ if (ele != (BMElem *)em->vert_index[i]) {
+ return FALSE;
+ }
+ }
}
- if (tm->edge_index) {
- MEM_freeN(tm->edge_index);
- tm->edge_index = NULL;
+ if (em->edge_index) {
+ BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_EDGES_OF_MESH, i) {
+ if (ele != (BMElem *)em->edge_index[i]) {
+ return FALSE;
+ }
+ }
}
- if (tm->face_index) {
- MEM_freeN(tm->face_index);
- tm->face_index = NULL;
+ if (em->face_index) {
+ BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_FACES_OF_MESH, i) {
+ if (ele != (BMElem *)em->face_index[i]) {
+ return FALSE;
+ }
+ }
}
+
+ return TRUE;
}
+#endif
-BMVert *EDBM_vert_at_index(BMEditMesh *tm, int index)
+BMVert *EDBM_vert_at_index(BMEditMesh *em, int index)
{
- return tm->vert_index && index < tm->bm->totvert ? tm->vert_index[index] : NULL;
+ return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL;
}
-BMEdge *EDBM_edge_at_index(BMEditMesh *tm, int index)
+BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index)
{
- return tm->edge_index && index < tm->bm->totedge ? tm->edge_index[index] : NULL;
+ return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL;
}
-BMFace *EDBM_face_at_index(BMEditMesh *tm, int index)
+BMFace *EDBM_face_at_index(BMEditMesh *em, int index)
{
- return (tm->face_index && index < tm->bm->totface && index >= 0) ? tm->face_index[index] : NULL;
+ return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL;
}
void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
@@ -506,7 +550,7 @@ void EDBM_select_more(BMEditMesh *em)
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
BMO_op_finish(em->bm, &bmop);
- EDBM_select_flush(em);
+ EDBM_selectmode_flush(em);
}
void EDBM_select_less(BMEditMesh *em)
@@ -639,7 +683,7 @@ void undo_push_mesh(bContext *C, const char *name)
}
/* write comment here */
-UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2])
+UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, const float limit[2])
{
BMVert *ev;
BMFace *efa;
@@ -652,11 +696,8 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
MLoopUV *luv;
unsigned int a;
int totverts, i, totuv;
-
- if (do_face_idx_array)
- EDBM_index_arrays_init(em, 0, 0, 1);
- BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+ BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
totverts = em->bm->totvert;
totuv = 0;
@@ -668,14 +709,10 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
}
if (totuv == 0) {
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
return NULL;
}
vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap");
if (!vmap) {
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
return NULL;
}
@@ -684,8 +721,6 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
if (!vmap->vert || !vmap->buf) {
BKE_mesh_uv_vert_map_free(vmap);
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
return NULL;
}
@@ -762,10 +797,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx
vmap->vert[a] = newvlist;
a++;
}
-
- if (do_face_idx_array)
- EDBM_index_arrays_free(em);
-
+
return vmap;
}
@@ -840,7 +872,6 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
buf->l = l;
- buf->face = efa;
buf->separate = 0;
buf->island = INVALID_ISLAND;
buf->tfindex = i;
@@ -912,7 +943,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
for (i = 0; i < totuv; i++) {
if (element_map->buf[i].island == INVALID_ISLAND) {
element_map->buf[i].island = nislands;
- stack[0] = element_map->buf[i].face;
+ stack[0] = element_map->buf[i].l->f;
island_number[BM_elem_index_get(stack[0])] = nislands;
stacksize = 1;
@@ -926,12 +957,11 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
if (element->separate)
initelement = element;
- if (element->face == efa) {
+ if (element->l->f == efa) {
/* found the uv corresponding to our face and vertex. Now fill it to the buffer */
element->island = nislands;
map[element - element_map->buf] = islandbufsize;
islandbuf[islandbufsize].l = element->l;
- islandbuf[islandbufsize].face = element->face;
islandbuf[islandbufsize].separate = element->separate;
islandbuf[islandbufsize].tfindex = element->tfindex;
islandbuf[islandbufsize].island = nislands;
@@ -941,9 +971,9 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is
if (element->separate && element != initelement)
break;
- if (island_number[BM_elem_index_get(element->face)] == INVALID_ISLAND) {
- stack[stacksize++] = element->face;
- island_number[BM_elem_index_get(element->face)] = nislands;
+ if (island_number[BM_elem_index_get(element->l->f)] == INVALID_ISLAND) {
+ stack[stacksize++] = element->l->f;
+ island_number[BM_elem_index_get(element->l->f)] = nislands;
}
}
break;
@@ -1024,7 +1054,7 @@ UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
element = map->vert[BM_elem_index_get(l->v)];
for (; element; element = element->next)
- if (element->face == efa)
+ if (element->l->f == efa)
return element;
return NULL;
@@ -1110,10 +1140,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const short use_select)
topo = 1;
}
- if (!em->vert_index) {
- EDBM_index_arrays_init(em, 1, 0, 0);
- em->mirr_free_arrays = 1;
- }
+ EDBM_index_arrays_ensure(em, BM_VERT);
if (!CustomData_get_layer_named(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID)) {
BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
@@ -1205,11 +1232,6 @@ void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v)
void EDBM_verts_mirror_cache_end(BMEditMesh *em)
{
- if (em->mirr_free_arrays) {
- MEM_freeN(em->vert_index);
- em->vert_index = NULL;
- }
-
em->mirror_cdlayer = -1;
}
@@ -1276,14 +1298,15 @@ void EDBM_mesh_reveal(BMEditMesh *em)
int sels[3] = {(em->selectmode & SCE_SELECT_VERTEX),
(em->selectmode & SCE_SELECT_EDGE),
(em->selectmode & SCE_SELECT_FACE), };
-
- BMIter iter;
- BMElem *ele;
int i;
/* Use tag flag to remember what was hidden before all is revealed.
* BM_ELEM_HIDDEN --> BM_ELEM_TAG */
+#pragma omp parallel for schedule(dynamic) if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT)
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
BM_ITER_MESH (ele, &iter, em->bm, iter_types[i]) {
BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_HIDDEN));
}
@@ -1294,6 +1317,9 @@ void EDBM_mesh_reveal(BMEditMesh *em)
/* Select relevant just-revealed elements */
for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
if (!sels[i]) {
continue;
}
@@ -1313,14 +1339,22 @@ void EDBM_mesh_reveal(BMEditMesh *em)
/* so many tools call these that we better make it a generic function.
*/
-void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface)
+void EDBM_update_generic(BMEditMesh *em, const short do_tessface, const short is_destructive)
{
Object *ob = em->ob;
/* order of calling isn't important */
DAG_id_tag_update(ob->data, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data);
if (do_tessface) {
BMEdit_RecalcTessellation(em);
}
+
+ if (is_destructive) {
+ EDBM_index_arrays_free(em);
+ }
+ else {
+ /* in debug mode double check we didn't need to recalculate */
+ BLI_assert(EDBM_index_arrays_check(em) == TRUE);
+ }
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index e9906f8..1d13aa3 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -28,35 +28,23 @@
* \ingroup edmesh
*/
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "MEM_guardedalloc.h"
-#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
-#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_array.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
-#include "BLI_linklist.h"
-#include "BLI_listbase.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -72,10 +60,9 @@
#include "ED_uvedit.h"
#include "ED_view3d.h"
-#include "RE_render_ext.h"
-
#include "mesh_intern.h"
+
static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot)
{
CustomData *data;
@@ -475,7 +462,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
/* copy data from active vertex color layer */
if (layernum) {
const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL);
- BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
+ BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPCOL, layernum, layernum_dst);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index 83a1261..99fa85b 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -26,31 +26,22 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <math.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_ID.h"
#include "BLI_listbase.h"
-#include "BLI_utildefines.h"
#include "BLI_math_vector.h"
#include "BLI_linklist.h"
#include "BKE_library.h"
#include "BKE_depsgraph.h"
#include "BKE_context.h"
-#include "BKE_main.h"
#include "BKE_mesh.h"
-#include "BKE_modifier.h"
#include "BKE_scene.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -58,14 +49,13 @@
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "RNA_access.h"
-
#include "WM_api.h"
#include "WM_types.h"
#include "mesh_intern.h"
#include "recast-capi.h"
+
static void createVertsTrisData(bContext *C, LinkNode *obs, int *nverts_r, float **verts_r, int *ntris_r, int **tris_r)
{
MVert *mvert;
@@ -167,8 +157,9 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, int *nverts_r, float
*tris_r = tris;
}
-static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris,
- struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh)
+static bool buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris,
+ struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh,
+ ReportList *reports)
{
float bmin[3], bmax[3];
struct recast_heightfield *solid;
@@ -195,14 +186,20 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
/* Set the area where the navigation will be build. */
recast_calcGridSize(bmin, bmax, recastParams->cellsize, &width, &height);
+ /* zero dimensions cause zero alloc later on [#33758] */
+ if (width <= 0 || height <= 0) {
+ BKE_report(reports, RPT_ERROR, "Object has a width or height of zero");
+ return false;
+ }
+
/* ** Step 2: Rasterize input polygon soup ** */
/* Allocate voxel heightfield where we rasterize our input data to */
solid = recast_newHeightfield();
if (!recast_createHeightfield(solid, width, height, bmin, bmax, recastParams->cellsize, recastParams->cellheight)) {
recast_destroyHeightfield(solid);
-
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to create height field");
+ return false;
}
/* Allocate array that can hold triangle flags */
@@ -225,7 +222,8 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyHeightfield(solid);
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to create compact height field");
+ return false;
}
recast_destroyHeightfield(solid);
@@ -234,21 +232,24 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
if (!recast_erodeWalkableArea(walkableRadius, chf)) {
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to erode walkable area");
+ return false;
}
/* Prepare for region partitioning, by calculating distance field along the walkable surface */
if (!recast_buildDistanceField(chf)) {
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build distance field");
+ return false;
}
/* Partition the walkable surface into simple regions without holes */
if (!recast_buildRegions(chf, 0, minRegionArea, mergeRegionArea)) {
recast_destroyCompactHeightfield(chf);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build regions");
+ return false;
}
/* ** Step 5: Trace and simplify region contours ** */
@@ -259,7 +260,8 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyCompactHeightfield(chf);
recast_destroyContourSet(cset);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build contours");
+ return false;
}
/* ** Step 6: Build polygons mesh from contours ** */
@@ -269,7 +271,8 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyContourSet(cset);
recast_destroyPolyMesh(*pmesh);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build poly mesh");
+ return false;
}
@@ -282,13 +285,14 @@ static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts
recast_destroyPolyMesh(*pmesh);
recast_destroyPolyMeshDetail(*dmesh);
- return 0;
+ BKE_report(reports, RPT_ERROR, "Failed to build poly mesh detail");
+ return false;
}
recast_destroyCompactHeightfield(chf);
recast_destroyContourSet(cset);
- return 1;
+ return true;
}
static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base *base)
@@ -375,7 +379,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
BM_vert_create(em->bm, co, NULL, 0);
}
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
/* create faces */
for (j = 0; j < trinum; j++) {
@@ -399,8 +403,6 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
polygonIdx = (int *)CustomData_bmesh_get(&em->bm->pdata, newFace->head.data, CD_RECAST);
*polygonIdx = i + 1; /* add 1 to avoid zero idx */
}
-
- EDBM_index_arrays_free(em);
}
recast_destroyPolyMesh(pmesh);
@@ -449,6 +451,7 @@ static int navmesh_create_exec(bContext *C, wmOperator *op)
if (obs) {
struct recast_polyMesh *pmesh = NULL;
struct recast_polyMeshDetail *dmesh = NULL;
+ bool ok;
int nverts = 0, ntris = 0;
int *tris = 0;
@@ -456,13 +459,14 @@ static int navmesh_create_exec(bContext *C, wmOperator *op)
createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris);
BLI_linklist_free(obs, NULL);
- buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh);
- createRepresentation(C, pmesh, dmesh, navmeshBase);
+ if ((ok = buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh, op->reports))) {
+ createRepresentation(C, pmesh, dmesh, navmeshBase);
+ }
MEM_freeN(verts);
MEM_freeN(tris);
- return OPERATOR_FINISHED;
+ return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
else {
BKE_report(op->reports, RPT_ERROR, "No mesh objects found");
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index a413a60..09b190d 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -29,17 +29,11 @@
*/
-#include <stdlib.h>
-#include <math.h>
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BKE_context.h"
#include "RNA_access.h"
@@ -49,7 +43,6 @@
#include "ED_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
-#include "ED_view3d.h"
#include "mesh_intern.h"
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index c0b6327..96b8f10 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -27,35 +27,24 @@
/** \file blender/editors/mesh/meshtools.c
* \ingroup edmesh
+ *
+ * meshtools.c: no editmode (violated already :), mirror & join),
+ * tools operating on meshes
*/
-
-/*
- * meshtools.c: no editmode (violated already :), tools operating on meshes
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_rand.h" /* for randome face sorting */
-#include "BLI_threads.h"
#include "BKE_context.h"
@@ -71,7 +60,6 @@
#include "BKE_tessmesh.h"
#include "BKE_multires.h"
-#include "BLO_sys_types.h" // for intptr_t support
#include "ED_mesh.h"
#include "ED_object.h"
@@ -80,10 +68,6 @@
#include "WM_api.h"
#include "WM_types.h"
-/* own include */
-#include "mesh_intern.h"
-#include "uvedit_intern.h"
-
/* * ********************** no editmode!!! *********** */
/*********************** JOIN ***************************/
@@ -1080,7 +1064,7 @@ static float *editmesh_get_mirror_uv(BMEditMesh *em, int axis, float *uv, float
static unsigned int mirror_facehash(const void *ptr)
{
const MFace *mf = ptr;
- int v0, v1;
+ unsigned int v0, v1;
if (mf->v4) {
v0 = MIN4(mf->v1, mf->v2, mf->v3, mf->v4);
@@ -1183,9 +1167,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em)
*
* \return boolean TRUE == Found
*/
-int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size)
+int ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
{
ViewContext vc;
+ Mesh *me = ob->data;
+
+ BLI_assert(me && GS(me->id.name) == ID_ME);
if (!me || me->totpoly == 0)
return 0;
@@ -1215,11 +1202,14 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in
* Use when the back buffer stores face index values. but we want a vert.
* This gets the face then finds the closest vertex to mval.
*/
-int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], unsigned int *index, int size)
+int ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
{
unsigned int poly_index;
+ Mesh *me = ob->data;
+
+ BLI_assert(me && GS(me->id.name) == ID_ME);
- if (ED_mesh_pick_face(C, me, mval, &poly_index, size)) {
+ if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) {
Scene *scene = CTX_data_scene(C);
struct ARegion *ar = CTX_wm_region(C);
@@ -1228,6 +1218,8 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
int v_idx_best = -1;
if (dm->getVertCo) {
+ RegionView3D *rv3d = ar->regiondata;
+
/* find the vert closest to 'mval' */
const float mval_f[2] = {(float)mval[0],
(float)mval[1]};
@@ -1235,14 +1227,15 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
int fidx;
float len_best = FLT_MAX;
+ ED_view3d_init_mats_rv3d(ob, rv3d);
+
fidx = mp->totloop - 1;
do {
float co[3], sco[2], len;
const int v_idx = me->mloop[mp->loopstart + fidx].v;
dm->getVertCo(dm, v_idx, co);
- mul_m4_v3(ob->obmat, co);
- if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- len = len_squared_v2v2(mval_f, sco);
+ if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ len = len_manhattan_v2v2(mval_f, sco);
if (len < len_best) {
len_best = len;
v_idx_best = v_idx;
@@ -1268,31 +1261,97 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
*
* \return boolean TRUE == Found
*/
-int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size)
+typedef struct VertPickData {
+ const MVert *mvert;
+ const float *mval_f; /* [2] */
+ ARegion *ar;
+
+ /* runtime */
+ float len_best;
+ int v_idx_best;
+} VertPickData;
+
+static void ed_mesh_pick_vert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ VertPickData *data = userData;
+ if ((data->mvert[index].flag & ME_HIDE) == 0) {
+ float sco[2];
+
+ if (ED_view3d_project_float_object(data->ar, co, sco, V3D_PROJ_TEST_CLIP_DEFAULT) == V3D_PROJ_RET_OK) {
+ const float len = len_manhattan_v2v2(data->mval_f, sco);
+ if (len < data->len_best) {
+ data->len_best = len;
+ data->v_idx_best = index;
+ }
+ }
+ }
+}
+int ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf)
{
ViewContext vc;
+ Mesh *me = ob->data;
+
+ BLI_assert(me && GS(me->id.name) == ID_ME);
if (!me || me->totvert == 0)
return 0;
view3d_set_viewcontext(C, &vc);
- if (size > 0) {
- /* sample rect to increase chances of selecting, so that when clicking
- * on an face in the backbuf, we can still select a vert */
+ if (use_zbuf) {
+ if (size > 0) {
+ /* sample rect to increase chances of selecting, so that when clicking
+ * on an face in the backbuf, we can still select a vert */
- float dummy_dist;
- *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL);
+ float dummy_dist;
+ *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL);
+ }
+ else {
+ /* sample only on the exact position */
+ *index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
+ }
+
+ if ((*index) <= 0 || (*index) > (unsigned int)me->totvert)
+ return 0;
+
+ (*index)--;
}
else {
- /* sample only on the exact position */
- *index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
- }
+ /* derived mesh to find deformed locations */
+ DerivedMesh *dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH);
+ ARegion *ar = vc.ar;
+ RegionView3D *rv3d = ar->regiondata;
- if ((*index) <= 0 || (*index) > (unsigned int)me->totvert)
- return 0;
+ /* find the vert closest to 'mval' */
+ const float mval_f[2] = {(float)mval[0],
+ (float)mval[1]};
- (*index)--;
+ VertPickData data = {0};
+
+ ED_view3d_init_mats_rv3d(ob, rv3d);
+
+ if (dm == NULL) {
+ return 0;
+ }
+
+ /* setup data */
+ data.mvert = me->mvert;
+ data.ar = ar;
+ data.mval_f = mval_f;
+ data.len_best = FLT_MAX;
+ data.v_idx_best = -1;
+
+ dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data);
+
+ dm->release(dm);
+
+ if (data.v_idx_best == -1) {
+ return 0;
+ }
+
+ *index = data.v_idx_best;
+ }
return 1;
}
diff --git a/source/blender/editors/metaball/SConscript b/source/blender/editors/metaball/SConscript
index b1a1ce9..7083eff 100644
--- a/source/blender/editors/metaball/SConscript
+++ b/source/blender/editors/metaball/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript
index b53ea54..df51198 100644
--- a/source/blender/editors/object/SConscript
+++ b/source/blender/editors/object/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 7c4a547..4db416b 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -146,7 +146,7 @@ void ED_object_location_from_view(bContext *C, float loc[3])
{
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- float *cursor;
+ const float *cursor;
cursor = give_cursor(scene, v3d);
@@ -186,7 +186,7 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3],
/* Uses context to figure out transform for primitive.
* Returns standard diameter. */
float ED_object_new_primitive_matrix(bContext *C, Object *obedit,
- const float loc[3], const float rot[3], float primmat[][4],
+ const float loc[3], const float rot[3], float primmat[4][4],
int apply_diameter)
{
Scene *scene = CTX_data_scene(C);
@@ -802,10 +802,25 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot)
static int group_instance_add_exec(bContext *C, wmOperator *op)
{
- Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
-
+ Group *group;
unsigned int layer;
float loc[3], rot[3];
+
+ if (RNA_struct_property_is_set(op->ptr, "name")) {
+ char name[MAX_ID_NAME - 2];
+
+ RNA_string_get(op->ptr, "name", name);
+ group = (Group *)BKE_libblock_find_name(ID_GR, name);
+
+ if (0 == RNA_struct_property_is_set(op->ptr, "location")) {
+ wmEvent *event = CTX_wm_window(C)->eventstate;
+ ED_object_location_from_view(C, loc);
+ ED_view3d_cursor3d_position(C, loc, event->x, event->y);
+ RNA_float_set_array(op->ptr, "location", loc);
+ }
+ }
+ else
+ group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
if (!ED_object_add_generic_get_opts(C, op, loc, rot, NULL, &layer, NULL))
return OPERATOR_CANCELLED;
@@ -847,6 +862,7 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
+ RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Group name to add");
ot->prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
RNA_def_enum_funcs(ot->prop, RNA_group_itemf);
ED_object_add_generic_props(ot, FALSE);
@@ -936,6 +952,8 @@ static int object_delete_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win;
const short use_global = RNA_boolean_get(op->ptr, "use_global");
if (CTX_data_edit_object(C))
@@ -967,12 +985,22 @@ static int object_delete_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- DAG_scene_sort(bmain, scene);
+ /* delete has to handle all open scenes */
+ flag_listbase_ids(&bmain->scene, LIB_DOIT, 1);
+ for (win = wm->windows.first; win; win = win->next) {
+ scene = win->screen->scene;
+
+ if (scene->id.flag & LIB_DOIT) {
+ scene->id.flag &= ~LIB_DOIT;
+
+ DAG_scene_sort(bmain, scene);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
+ }
+ }
DAG_ids_flush_update(bmain, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
-
return OPERATOR_FINISHED;
}
@@ -1973,6 +2001,7 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
static int add_named_exec(bContext *C, wmOperator *op)
{
+ wmEvent *event = CTX_wm_window(C)->eventstate;
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Base *basen, *base;
@@ -2005,6 +2034,8 @@ static int add_named_exec(bContext *C, wmOperator *op)
basen->lay = basen->object->lay = scene->lay;
ED_object_location_from_view(C, basen->object->loc);
+ ED_view3d_cursor3d_position(C, basen->object->loc, event->x, event->y);
+
ED_base_object_activate(C, basen);
copy_object_set_idnew(C, dupflag);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index e144c38..f36c6d7 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -64,6 +64,7 @@
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
+#include "RE_multires_bake.h"
#include "PIL_time.h"
@@ -88,6 +89,7 @@ typedef struct MultiresBakerJobData {
struct MultiresBakerJobData *next, *prev;
DerivedMesh *lores_dm, *hires_dm;
int simple, lvl, tot_lvl;
+ ListBase images;
} MultiresBakerJobData;
/* data passing to multires-baker job */
@@ -95,829 +97,13 @@ typedef struct {
ListBase data;
int bake_clear, bake_filter;
short mode, use_lores_mesh;
+ int number_of_rays;
+ float bias;
+ int raytrace_structure;
+ int octree_resolution;
+ int threads;
} MultiresBakeJob;
-/* data passing to multires baker */
-typedef struct {
- DerivedMesh *lores_dm, *hires_dm;
- int simple, lvl, tot_lvl, bake_filter;
- short mode, use_lores_mesh;
-
- int tot_obj, tot_image;
- ListBase image;
-
- int baked_objects, baked_faces;
-
- short *stop;
- short *do_update;
- float *progress;
-} MultiresBakeRender;
-
-typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float tangmat[3][3], const int x, const int y);
-
-typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
-typedef void (*MApplyBakeData)(void *bake_data);
-typedef void (*MFreeBakeData)(void *bake_data);
-
-typedef struct {
- MVert *mvert;
- MFace *mface;
- MTFace *mtface;
- float *pvtangent;
- float *precomputed_normals;
- int w, h;
- int face_index;
- int i0, i1, i2;
- DerivedMesh *lores_dm, *hires_dm;
- int lvl;
- void *bake_data;
- ImBuf *ibuf;
- MPassKnownData pass_data;
-} MResolvePixelData;
-
-typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
-
-typedef struct {
- int w, h;
- char *texels;
- const MResolvePixelData *data;
- MFlushPixel flush_pixel;
-} MBakeRast;
-
-typedef struct {
- float *heights;
- float height_min, height_max;
- Image *ima;
- DerivedMesh *ssdm;
- const int *orig_index_mf_to_mpoly;
- const int *orig_index_mp_to_orig;
-} MHeightBakeData;
-
-typedef struct {
- const int *orig_index_mf_to_mpoly;
- const int *orig_index_mp_to_orig;
-} MNormalBakeData;
-
-static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
-{
- unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2,
- data->mface[face_num].v3, data->mface[face_num].v4};
- const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH);
-
- if (!smoothnormal) { /* flat */
- if (data->precomputed_normals) {
- copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]);
- }
- else {
- float nor[3];
- float *p0, *p1, *p2;
- const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3;
-
- p0 = data->mvert[indices[0]].co;
- p1 = data->mvert[indices[1]].co;
- p2 = data->mvert[indices[2]].co;
-
- if (iGetNrVerts == 4) {
- float *p3 = data->mvert[indices[3]].co;
- normal_quad_v3(nor, p0, p1, p2, p3);
- }
- else {
- normal_tri_v3(nor, p0, p1, p2);
- }
-
- copy_v3_v3(norm, nor);
- }
- }
- else {
- short *no = data->mvert[indices[vert_index]].no;
-
- normal_short_to_float_v3(norm, no);
- normalize_v3(norm);
- }
-}
-
-static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
-{
- memset(bake_rast, 0, sizeof(MBakeRast));
-
- bake_rast->texels = ibuf->userdata;
- bake_rast->w = ibuf->x;
- bake_rast->h = ibuf->y;
- bake_rast->data = data;
- bake_rast->flush_pixel = flush_pixel;
-}
-
-static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
-{
- float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
- float *st0, *st1, *st2;
- float *tang0, *tang1, *tang2;
- float no0[3], no1[3], no2[3];
- float fUV[2], from_tang[3][3], to_tang[3][3];
- float u, v, w, sign;
- int r;
-
- const int i0 = data->i0;
- const int i1 = data->i1;
- const int i2 = data->i2;
-
- st0 = data->mtface[data->face_index].uv[i0];
- st1 = data->mtface[data->face_index].uv[i1];
- st2 = data->mtface[data->face_index].uv[i2];
-
- tang0 = data->pvtangent + data->face_index * 16 + i0 * 4;
- tang1 = data->pvtangent + data->face_index * 16 + i1 * 4;
- tang2 = data->pvtangent + data->face_index * 16 + i2 * 4;
-
- multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */
- multiresbake_get_normal(data, no1, data->face_index, i1);
- multiresbake_get_normal(data, no2, data->face_index, i2);
-
- resolve_tri_uv(fUV, st, st0, st1, st2);
-
- u = fUV[0];
- v = fUV[1];
- w = 1 - u - v;
-
- /* the sign is the same at all face vertices for any non degenerate face.
- * Just in case we clamp the interpolated value though. */
- sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f;
-
- /* this sequence of math is designed specifically as is with great care
- * to be compatible with our shader. Please don't change without good reason. */
- for (r = 0; r < 3; r++) {
- from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w;
- from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w;
- }
-
- cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */
- mul_v3_fl(from_tang[1], sign);
- invert_m3_m3(to_tang, from_tang);
- /* sequence end */
-
- data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
- data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
-}
-
-static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
-{
- const int w = bake_rast->w;
- const int h = bake_rast->h;
-
- if (x >= 0 && x < w && y >= 0 && y < h) {
- if ((bake_rast->texels[y * w + x]) == 0) {
- flush_pixel(bake_rast->data, x, y);
- bake_rast->texels[y * w + x] = FILTER_MASK_USED;
- }
- }
-}
-
-static void rasterize_half(const MBakeRast *bake_rast,
- const float s0_s, const float t0_s, const float s1_s, const float t1_s,
- const float s0_l, const float t0_l, const float s1_l, const float t1_l,
- const int y0_in, const int y1_in, const int is_mid_right)
-{
- const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
- const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
- const int w = bake_rast->w;
- const int h = bake_rast->h;
- int y, y0, y1;
-
- if (y1_in <= 0 || y0_in >= h)
- return;
-
- y0 = y0_in < 0 ? 0 : y0_in;
- y1 = y1_in >= h ? h : y1_in;
-
- for (y = y0; y < y1; y++) {
- /*-b(x-x0) + a(y-y0) = 0 */
- int iXl, iXr, x;
- float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
- float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
-
- if (is_mid_right != 0)
- SWAP(float, x_l, x_r);
-
- iXl = (int)ceilf(x_l);
- iXr = (int)ceilf(x_r);
-
- if (iXr > 0 && iXl < w) {
- iXl = iXl < 0 ? 0 : iXl;
- iXr = iXr >= w ? w : iXr;
-
- for (x = iXl; x < iXr; x++)
- set_rast_triangle(bake_rast, x, y);
- }
- }
-}
-
-static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
-{
- const int w = bake_rast->w;
- const int h = bake_rast->h;
- float slo = st0_in[0] * w - 0.5f;
- float tlo = st0_in[1] * h - 0.5f;
- float smi = st1_in[0] * w - 0.5f;
- float tmi = st1_in[1] * h - 0.5f;
- float shi = st2_in[0] * w - 0.5f;
- float thi = st2_in[1] * h - 0.5f;
- int is_mid_right = 0, ylo, yhi, yhi_beg;
-
- /* skip degenerates */
- if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi))
- return;
-
- /* sort by T */
- if (tlo > tmi && tlo > thi) {
- SWAP(float, shi, slo);
- SWAP(float, thi, tlo);
- }
- else if (tmi > thi) {
- SWAP(float, shi, smi);
- SWAP(float, thi, tmi);
- }
-
- if (tlo > tmi) {
- SWAP(float, slo, smi);
- SWAP(float, tlo, tmi);
- }
-
- /* check if mid point is to the left or to the right of the lo-hi edge */
- is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
- ylo = (int) ceilf(tlo);
- yhi_beg = (int) ceilf(tmi);
- yhi = (int) ceilf(thi);
-
- /*if (fTmi>ceilf(fTlo))*/
- rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
- rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
-}
-
-static int multiresbake_test_break(MultiresBakeRender *bkr)
-{
- if (!bkr->stop) {
- /* this means baker is executed outside from job system */
- return 0;
- }
-
- return G.is_break;
-}
-
-static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData passKnownData,
- MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
-{
- DerivedMesh *dm = bkr->lores_dm;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- const int lvl = bkr->lvl;
- const int tot_face = dm->getNumTessFaces(dm);
- MVert *mvert = dm->getVertArray(dm);
- MFace *mface = dm->getTessFaceArray(dm);
- MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
- float *pvtangent = NULL;
-
- if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
- DM_add_tangent_layer(dm);
-
- pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT);
-
- if (tot_face > 0) { /* sanity check */
- int f = 0;
- MBakeRast bake_rast;
- MResolvePixelData data = {NULL};
-
- data.mface = mface;
- data.mvert = mvert;
- data.mtface = mtface;
- data.pvtangent = pvtangent;
- data.precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */
- data.w = ibuf->x;
- data.h = ibuf->y;
- data.lores_dm = dm;
- data.hires_dm = bkr->hires_dm;
- data.lvl = lvl;
- data.pass_data = passKnownData;
-
- if (initBakeData)
- data.bake_data = initBakeData(bkr, ima);
-
- init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
-
- for (f = 0; f < tot_face; f++) {
- MTFace *mtfate = &mtface[f];
- int verts[3][2], nr_tris, t;
-
- if (multiresbake_test_break(bkr))
- break;
-
- if (mtfate->tpage != ima)
- continue;
-
- data.face_index = f;
- data.ibuf = ibuf;
-
- /* might support other forms of diagonal splits later on such as
- * split by shortest diagonal.*/
- verts[0][0] = 0;
- verts[1][0] = 1;
- verts[2][0] = 2;
-
- verts[0][1] = 0;
- verts[1][1] = 2;
- verts[2][1] = 3;
-
- nr_tris = mface[f].v4 != 0 ? 2 : 1;
- for (t = 0; t < nr_tris; t++) {
- data.i0 = verts[0][t];
- data.i1 = verts[1][t];
- data.i2 = verts[2][t];
-
- bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
- }
-
- bkr->baked_faces++;
-
- if (bkr->do_update)
- *bkr->do_update = TRUE;
-
- if (bkr->progress)
- *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
- }
-
- if (applyBakeData)
- applyBakeData(data.bake_data);
-
- if (freeBakeData)
- freeBakeData(data.bake_data);
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-}
-
-/* mode = 0: interpolate normals,
- * mode = 1: interpolate coord */
-static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
-{
- int x0, x1, y0, y1;
- float u, v;
- float data[4][3];
-
- x0 = (int) crn_x;
- x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);
-
- y0 = (int) crn_y;
- y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);
-
- u = crn_x - x0;
- v = crn_y - y0;
-
- if (mode == 0) {
- copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
- copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
- copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
- copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
- }
- else {
- copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
- copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
- copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
- copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
- }
-
- interp_bilinear_quad_v3(data, u, v, res);
-}
-
-static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,
- const int *index_mf_to_mpoly, const int *index_mp_to_orig,
- const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
-{
- MFace mface;
- CCGElem **grid_data;
- CCGKey key;
- float crn_x, crn_y;
- int grid_size, S, face_side;
- int *grid_offset, g_index;
-
- lodm->getTessFace(lodm, face_index, &mface);
-
- grid_size = hidm->getGridSize(hidm);
- grid_data = hidm->getGridData(hidm);
- grid_offset = hidm->getGridOffset(hidm);
- hidm->getGridKey(hidm, &key);
-
- face_side = (grid_size << 1) - 1;
-
- if (lvl == 0) {
- g_index = grid_offset[face_index];
- S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y);
- }
- else {
- int side = (1 << (lvl - 1)) + 1;
- int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index);
- int loc_offs = face_index % (1 << (2 * lvl));
- int cell_index = loc_offs % ((side - 1) * (side - 1));
- int cell_side = (grid_size - 1) / (side - 1);
- int row = cell_index / (side - 1);
- int col = cell_index % (side - 1);
-
- S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index];
- g_index = grid_offset[grid_index];
-
- crn_y = (row * cell_side) + u * cell_side;
- crn_x = (col * cell_side) + v * cell_side;
- }
-
- CLAMP(crn_x, 0.0f, grid_size);
- CLAMP(crn_y, 0.0f, grid_size);
-
- if (n != NULL)
- interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n);
-
- if (co != NULL)
- interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co);
-}
-
-/* mode = 0: interpolate normals,
- * mode = 1: interpolate coord */
-static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
-{
- float data[4][3];
-
- if (mode == 0) {
- dm->getVertNo(dm, mface->v1, data[0]);
- dm->getVertNo(dm, mface->v2, data[1]);
- dm->getVertNo(dm, mface->v3, data[2]);
- dm->getVertNo(dm, mface->v4, data[3]);
- }
- else {
- dm->getVertCo(dm, mface->v1, data[0]);
- dm->getVertCo(dm, mface->v2, data[1]);
- dm->getVertCo(dm, mface->v3, data[2]);
- dm->getVertCo(dm, mface->v4, data[3]);
- }
-
- interp_bilinear_quad_v3(data, u, v, res);
-}
-
-/* mode = 0: interpolate normals,
- * mode = 1: interpolate coord */
-static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
-{
- float data[3][3];
-
- if (mode == 0) {
- dm->getVertNo(dm, mface->v1, data[0]);
- dm->getVertNo(dm, mface->v2, data[1]);
- dm->getVertNo(dm, mface->v3, data[2]);
- }
- else {
- dm->getVertCo(dm, mface->v1, data[0]);
- dm->getVertCo(dm, mface->v2, data[1]);
- dm->getVertCo(dm, mface->v3, data[2]);
- }
-
- interp_barycentric_tri_v3(data, u, v, res);
-}
-
-static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
-{
- MHeightBakeData *height_data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- DerivedMesh *lodm = bkr->lores_dm;
-
- height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
-
- height_data->ima = ima;
- height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
- height_data->height_max = -FLT_MAX;
- height_data->height_min = FLT_MAX;
-
- if (!bkr->use_lores_mesh) {
- SubsurfModifierData smd = {{NULL}};
- int ss_lvl = bkr->tot_lvl - bkr->lvl;
-
- CLAMP(ss_lvl, 0, 6);
-
- if (ss_lvl > 0) {
- smd.levels = smd.renderLevels = ss_lvl;
- smd.flags |= eSubsurfModifierFlag_SubsurfUv;
-
- if (bkr->simple)
- smd.subdivType = ME_SIMPLE_SUBSURF;
-
- height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0);
- }
- }
-
- height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
- height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
- return (void *)height_data;
-}
-
-static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
-{
- MNormalBakeData *normal_data;
- DerivedMesh *lodm = bkr->lores_dm;
-
- normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
-
- normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
- normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
-
- return (void *)normal_data;
-}
-
-static void free_normal_data(void *bake_data)
-{
- MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
-
- MEM_freeN(normal_data);
-}
-
-static void apply_heights_data(void *bake_data)
-{
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
- int x, y, i;
- float height, *heights = height_data->heights;
- float min = height_data->height_min, max = height_data->height_max;
-
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- i = ibuf->x * y + x;
-
- if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED)
- continue;
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + i * 4;
-
- if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
- else height = 0;
-
- rrgbf[0] = rrgbf[1] = rrgbf[2] = height;
- }
- else {
- char *rrgb = (char *)ibuf->rect + i * 4;
-
- if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
- else height = 0;
-
- rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height);
- }
- }
- }
-
- ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID;
-
- BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
-}
-
-static void free_heights_data(void *bake_data)
-{
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
-
- if (height_data->ssdm)
- height_data->ssdm->release(height_data->ssdm);
-
- MEM_freeN(height_data->heights);
- MEM_freeN(height_data);
-}
-
-/* MultiresBake callback for heights baking
- * general idea:
- * - find coord of point with specified UV in hi-res mesh (let's call it p1)
- * - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
- * mesh to make texture smoother) let's call this point p0 and n.
- * - height wound be dot(n, p1-p0) */
-static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float UNUSED(tangmat[3][3]), const int x, const int y)
-{
- MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
- MFace mface;
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- float uv[2], *st0, *st1, *st2, *st3;
- int pixel = ibuf->x * y + x;
- float vec[3], p0[3], p1[3], n[3], len;
-
- lores_dm->getTessFace(lores_dm, face_index, &mface);
-
- st0 = mtface[face_index].uv[0];
- st1 = mtface[face_index].uv[1];
- st2 = mtface[face_index].uv[2];
-
- if (mface.v4) {
- st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
- }
- else
- resolve_tri_uv(uv, st, st0, st1, st2);
-
- CLAMP(uv[0], 0.0f, 1.0f);
- CLAMP(uv[1], 0.0f, 1.0f);
-
- get_ccgdm_data(lores_dm, hires_dm,
- height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
- lvl, face_index, uv[0], uv[1], p1, 0);
-
- if (height_data->ssdm) {
- get_ccgdm_data(lores_dm, height_data->ssdm,
- height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
- 0, face_index, uv[0], uv[1], p0, n);
- }
- else {
- lores_dm->getTessFace(lores_dm, face_index, &mface);
-
- if (mface.v4) {
- interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
- interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
- }
- else {
- interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
- interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
- }
- }
-
- sub_v3_v3v3(vec, p1, p0);
- len = dot_v3v3(n, vec);
-
- height_data->heights[pixel] = len;
- if (len < height_data->height_min) height_data->height_min = len;
- if (len > height_data->height_max) height_data->height_max = len;
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + pixel * 4;
- rrgbf[3] = 1.0f;
-
- ibuf->userflags = IB_RECT_INVALID;
- }
- else {
- char *rrgb = (char *)ibuf->rect + pixel * 4;
- rrgb[3] = 255;
- }
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-}
-
-/* MultiresBake callback for normals' baking
- * general idea:
- * - find coord and normal of point with specified UV in hi-res mesh
- * - multiply it by tangmat
- * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
-static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float tangmat[3][3], const int x, const int y)
-{
- MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
- MFace mface;
- MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
- float uv[2], *st0, *st1, *st2, *st3;
- int pixel = ibuf->x * y + x;
- float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
-
- lores_dm->getTessFace(lores_dm, face_index, &mface);
-
- st0 = mtface[face_index].uv[0];
- st1 = mtface[face_index].uv[1];
- st2 = mtface[face_index].uv[2];
-
- if (mface.v4) {
- st3 = mtface[face_index].uv[3];
- resolve_quad_uv(uv, st, st0, st1, st2, st3);
- }
- else
- resolve_tri_uv(uv, st, st0, st1, st2);
-
- CLAMP(uv[0], 0.0f, 1.0f);
- CLAMP(uv[1], 0.0f, 1.0f);
-
- get_ccgdm_data(lores_dm, hires_dm,
- normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig,
- lvl, face_index, uv[0], uv[1], NULL, n);
-
- mul_v3_m3v3(vec, tangmat, n);
- normalize_v3(vec);
- mul_v3_fl(vec, 0.5);
- add_v3_v3(vec, tmp);
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + pixel * 4;
- rrgbf[0] = vec[0];
- rrgbf[1] = vec[1];
- rrgbf[2] = vec[2];
- rrgbf[3] = 1.0f;
-
- ibuf->userflags = IB_RECT_INVALID;
- }
- else {
- unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
- rgb_float_to_uchar(rrgb, vec);
- rrgb[3] = 255;
- }
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-}
-
-static void count_images(MultiresBakeRender *bkr)
-{
- int a, totface;
- DerivedMesh *dm = bkr->lores_dm;
- MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
-
- bkr->image.first = bkr->image.last = NULL;
- bkr->tot_image = 0;
-
- totface = dm->getNumTessFaces(dm);
-
- for (a = 0; a < totface; a++)
- mtface[a].tpage->id.flag &= ~LIB_DOIT;
-
- for (a = 0; a < totface; a++) {
- Image *ima = mtface[a].tpage;
- if ((ima->id.flag & LIB_DOIT) == 0) {
- LinkData *data = BLI_genericNodeN(ima);
- BLI_addtail(&bkr->image, data);
- bkr->tot_image++;
- ima->id.flag |= LIB_DOIT;
- }
- }
-
- for (a = 0; a < totface; a++)
- mtface[a].tpage->id.flag &= ~LIB_DOIT;
-}
-
-static void bake_images(MultiresBakeRender *bkr)
-{
- LinkData *link;
-
- for (link = bkr->image.first; link; link = link->next) {
- Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ibuf->x > 0 && ibuf->y > 0) {
- ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
-
- switch (bkr->mode) {
- case RE_BAKE_NORMALS:
- do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
- break;
- case RE_BAKE_DISPLACEMENT:
- do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
- apply_heights_data, free_heights_data);
- break;
- }
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
- ima->id.flag |= LIB_DOIT;
- }
-}
-
-static void finish_images(MultiresBakeRender *bkr)
-{
- LinkData *link;
-
- for (link = bkr->image.first; link; link = link->next) {
- Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ibuf->x <= 0 || ibuf->y <= 0)
- continue;
-
- RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
-
- ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
-
- if (ibuf->rect_float)
- ibuf->userflags |= IB_RECT_INVALID;
-
- if (ibuf->mipmap[0]) {
- ibuf->userflags |= IB_MIPMAP_INVALID;
- imb_freemipmapImBuf(ibuf);
- }
-
- if (ibuf->userdata) {
- MEM_freeN(ibuf->userdata);
- ibuf->userdata = NULL;
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-}
-
-static void multiresbake_start(MultiresBakeRender *bkr)
-{
- count_images(bkr);
- bake_images(bkr);
- finish_images(bkr);
-}
-
static int multiresbake_check(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@@ -1023,6 +209,9 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
if (*lvl == 0) {
DerivedMesh *tmp_dm = CDDM_from_mesh(me, ob);
+
+ DM_set_only_copy(tmp_dm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
+
dm = CDDM_copy(tmp_dm);
tmp_dm->release(tmp_dm);
}
@@ -1030,6 +219,8 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
MultiresModifierData tmp_mmd = *mmd;
DerivedMesh *cddm = CDDM_from_mesh(me, ob);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
+
tmp_mmd.lvl = *lvl;
tmp_mmd.sculptlvl = *lvl;
dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
@@ -1047,6 +238,14 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
DerivedMesh *cddm = CDDM_from_mesh(me, ob);
DerivedMesh *dm;
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+
+ /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data,
+ * but we really need BAREMESH only to save lots of memory
+ */
+ CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH);
+ CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH);
+
*lvl = mmd->totlvl;
*simple = mmd->simple;
@@ -1118,16 +317,17 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
bkr.bake_filter = scene->r.bake_filter;
bkr.mode = scene->r.bake_mode;
bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
+ bkr.bias = scene->r.bake_biasdist;
+ bkr.number_of_rays = scene->r.bake_samples;
+ bkr.raytrace_structure = scene->r.raytrace_structure;
+ bkr.octree_resolution = scene->r.ocres;
+ bkr.threads = scene->r.mode & R_FIXED_THREADS ? scene->r.threads : 0;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
- bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
-
- if (!bkr.lores_dm)
- continue;
-
bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
+ bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
- multiresbake_start(&bkr);
+ RE_multires_bake_images(&bkr);
BLI_freelistN(&bkr.image);
@@ -1155,24 +355,27 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
bkj->mode = scene->r.bake_mode;
bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR;
+ bkj->bias = scene->r.bake_biasdist;
+ bkj->number_of_rays = scene->r.bake_samples;
+ bkj->raytrace_structure = scene->r.raytrace_structure;
+ bkj->octree_resolution = scene->r.ocres;
+ bkj->threads = scene->r.mode & R_FIXED_THREADS ? scene->r.threads : 0;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
MultiresBakerJobData *data;
- DerivedMesh *lores_dm;
int lvl;
+
ob = base->object;
multires_force_update(ob);
- lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
- if (!lores_dm)
- continue;
-
data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
- data->lores_dm = lores_dm;
- data->lvl = lvl;
+
+ /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
+ data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
+ data->lvl = lvl;
BLI_addtail(&bkj->data, data);
}
@@ -1219,9 +422,15 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
bkr.do_update = do_update;
bkr.progress = progress;
- multiresbake_start(&bkr);
+ bkr.bias = bkj->bias;
+ bkr.number_of_rays = bkj->number_of_rays;
+ bkr.raytrace_structure = bkj->raytrace_structure;
+ bkr.octree_resolution = bkj->octree_resolution;
+ bkr.threads = bkj->threads;
- BLI_freelistN(&bkr.image);
+ RE_multires_bake_images(&bkr);
+
+ data->images = bkr.image;
baked_objects++;
}
@@ -1231,12 +440,22 @@ static void multiresbake_freejob(void *bkv)
{
MultiresBakeJob *bkj = bkv;
MultiresBakerJobData *data, *next;
+ LinkData *link;
data = bkj->data.first;
while (data) {
next = data->next;
data->lores_dm->release(data->lores_dm);
data->hires_dm->release(data->hires_dm);
+
+ /* delete here, since this delete will be called from main thread */
+ for (link = data->images.first; link; link = link->next) {
+ Image *ima = (Image *)link->data;
+ GPU_free_image(ima);
+ }
+
+ BLI_freelistN(&data->images);
+
MEM_freeN(data);
data = next;
}
@@ -1472,7 +691,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven
static int is_multires_bake(Scene *scene)
{
- if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT))
+ if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO))
return scene->r.bake_flag & R_BAKE_MULTIRES;
return 0;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index f78e120..6cb7cd5 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -141,7 +141,7 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **pchan_r
/* single constraint */
bConstraint *get_active_constraint(Object *ob)
{
- return constraints_get_active(get_active_constraints(ob));
+ return BKE_constraints_get_active(get_active_constraints(ob));
}
/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
@@ -225,7 +225,7 @@ static void update_pyconstraint_cb(void *arg1, void *arg2)
/* helper function for add_constriant - sets the last target for the active constraint */
static void set_constraint_nth_target(bConstraint *con, Object *target, const char subtarget[], int index)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
int num_targets, i;
@@ -297,7 +297,7 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
/* Check all constraints - is constraint valid? */
if (conlist) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -610,7 +610,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
list = get_active_constraints(ob);
}
- con = constraints_findByName(list, constraint_name);
+ con = BKE_constraints_findByName(list, constraint_name);
//if (G.debug & G_DEBUG)
//printf("constraint found = %p, %s\n", (void *)con, (con)?con->name:"<Not found>");
@@ -1123,7 +1123,7 @@ void ED_object_constraint_set_active(Object *ob, bConstraint *con)
if ((lb && con) && (con->flag & CONSTRAINT_ACTIVE))
return;
- constraints_set_active(lb, con);
+ BKE_constraints_set_active(lb, con);
}
void ED_object_constraint_update(Object *ob)
@@ -1162,9 +1162,9 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
const short is_ik = ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
/* free the constraint */
- if (remove_constraint(lb, con)) {
+ if (BKE_remove_constraint(lb, con)) {
/* there's no active constraint now, so make sure this is the case */
- constraints_set_active(lb, NULL);
+ BKE_constraints_set_active(lb, NULL);
ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
@@ -1308,7 +1308,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* free constraints for all selected bones */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
- free_constraints(&pchan->constraints);
+ BKE_free_constraints(&pchan->constraints);
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK | PCHAN_HAS_CONST);
}
CTX_DATA_END;
@@ -1346,7 +1346,7 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* do freeing */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
- free_constraints(&ob->constraints);
+ BKE_free_constraints(&ob->constraints);
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
@@ -1391,7 +1391,7 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
{
/* if we're not handling the object we're copying from, copy all constraints over */
if (pchan != chan) {
- copy_constraints(&chan->constraints, &pchan->constraints, TRUE);
+ BKE_copy_constraints(&chan->constraints, &pchan->constraints, TRUE);
/* update flags (need to add here, not just copy) */
chan->constflag |= pchan->constflag;
}
@@ -1432,7 +1432,7 @@ static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
/* if we're not handling the object we're copying from, copy all constraints over */
if (obact != ob) {
- copy_constraints(&ob->constraints, &obact->constraints, TRUE);
+ BKE_copy_constraints(&ob->constraints, &obact->constraints, TRUE);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
@@ -1642,9 +1642,9 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
/* create a new constraint of the type requried, and add it to the active/given constraints list */
if (pchan)
- con = add_pose_constraint(ob, pchan, NULL, type);
+ con = BKE_add_pose_constraint(ob, pchan, NULL, type);
else
- con = add_ob_constraint(ob, NULL, type);
+ con = BKE_add_ob_constraint(ob, NULL, type);
/* get the first selected object/bone, and make that the target
* - apart from the buttons-window add buttons, we shouldn't add in this way
@@ -1940,7 +1940,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
for (con = pchan->constraints.first; con; con = next) {
next = con->next;
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
- remove_constraint(&pchan->constraints, con);
+ BKE_remove_constraint(&pchan->constraints, con);
}
}
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index d39e348..fcc3b5d 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -429,6 +429,10 @@ void ED_object_enter_editmode(bContext *C, int flag)
ob = base->object;
+ /* this checks actual object->data, for cases when other scenes have it in editmode context */
+ if ( BKE_object_is_in_editmode(ob) )
+ return;
+
if (BKE_object_obdata_is_libdata(ob)) {
error_libdata();
return;
@@ -950,7 +954,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
}
else if (event == 22) {
/* Copy the constraint channels over */
- copy_constraints(&base->object->constraints, &ob->constraints, TRUE);
+ BKE_copy_constraints(&base->object->constraints, &ob->constraints, TRUE);
do_scene_sort = TRUE;
}
@@ -1672,10 +1676,6 @@ static EnumPropertyItem game_properties_copy_operations[] = {
{0, NULL, 0, NULL, NULL}
};
-static EnumPropertyItem gameprops_items[] = {
- {0, NULL, 0, NULL, NULL}
-};
-
static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
Object *ob = ED_object_active_context(C);
@@ -1685,7 +1685,7 @@ static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), P
int a, totitem = 0;
if (!ob)
- return gameprops_items;
+ return DummyRNA_NULL_items;
for (a = 1, prop = ob->prop.first; prop; prop = prop->next, a++) {
tmp.value = a;
@@ -1756,7 +1756,7 @@ void OBJECT_OT_game_property_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(ot->srna, "operation", game_properties_copy_operations, 3, "Operation", "");
- prop = RNA_def_enum(ot->srna, "property", gameprops_items, 0, "Property", "Properties to copy");
+ prop = RNA_def_enum(ot->srna, "property", DummyRNA_NULL_items, 0, "Property", "Properties to copy");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
RNA_def_enum_funcs(prop, gameprops_itemf);
ot->prop = prop;
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index a3bf27a..7bf1a5d 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -313,7 +313,7 @@ static int group_create_exec(bContext *C, wmOperator *op)
group = add_group(name);
- CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
+ CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
add_to_group(group, base->object, scene, base);
}
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index 4aa2e82..c9eae77 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -52,7 +52,7 @@
#include "BKE_depsgraph.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
-#include "BKE_mesh.h"
+#include "BKE_deform.h"
#include "ED_lattice.h"
#include "ED_object.h"
@@ -77,7 +77,7 @@ void free_editLatt(Object *ob)
if (editlt->def)
MEM_freeN(editlt->def);
if (editlt->dvert)
- free_dverts(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw);
+ BKE_defvert_array_free(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw);
MEM_freeN(editlt);
MEM_freeN(lt->editlatt);
@@ -104,7 +104,7 @@ void make_editLatt(Object *obedit)
if (lt->dvert) {
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
lt->editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(lt->editlatt->latt->dvert, lt->dvert, tot);
+ BKE_defvert_array_copy(lt->editlatt->latt->dvert, lt->dvert, tot);
}
if (lt->key) lt->editlatt->shapenr = obedit->shapenr;
@@ -156,7 +156,7 @@ void load_editLatt(Object *obedit)
}
if (lt->dvert) {
- free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
lt->dvert = NULL;
}
@@ -164,7 +164,7 @@ void load_editLatt(Object *obedit)
tot = lt->pntsu * lt->pntsv * lt->pntsw;
lt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(lt->dvert, editlt->dvert, tot);
+ BKE_defvert_array_copy(lt->dvert, editlt->dvert, tot);
}
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index d19277d..03b50c0 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -252,15 +252,6 @@ void ED_operatormacros_object(void)
RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
- /* XXX */
- ot = WM_operatortype_append_macro("OBJECT_OT_add_named_cursor", "Add Named At Cursor",
- "Add named object at cursor", OPTYPE_UNDO | OPTYPE_REGISTER);
- if (ot) {
- RNA_def_string(ot->srna, "name", "Cube", MAX_ID_NAME - 2, "Name", "Object name to add");
-
- WM_operatortype_macro_define(ot, "VIEW3D_OT_cursor3d");
- WM_operatortype_macro_define(ot, "OBJECT_OT_add_named");
- }
}
static int object_mode_poll(bContext *C)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 0988a19..fa44d3d 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -716,12 +716,12 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
bFollowPathConstraint *data;
float cmat[4][4], vec[3];
- con = add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
+ con = BKE_add_ob_constraint(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
data = con->data;
data->tar = par;
- get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
+ BKE_get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
ob->loc[0] = vec[0];
@@ -1051,7 +1051,7 @@ static int object_track_clear_exec(bContext *C, wmOperator *op)
for (con = ob->constraints.last; con; con = pcon) {
pcon = con->prev;
if (ELEM3(con->type, CONSTRAINT_TYPE_TRACKTO, CONSTRAINT_TYPE_LOCKTRACK, CONSTRAINT_TYPE_DAMPTRACK))
- remove_constraint(&ob->constraints, con);
+ BKE_remove_constraint(&ob->constraints, con);
}
if (type == 1)
@@ -1109,7 +1109,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
+ con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_DAMPTRACK);
data = con->data;
data->tar = obact;
@@ -1129,7 +1129,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
+ con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_TRACKTO);
data = con->data;
data->tar = obact;
@@ -1151,7 +1151,7 @@ static int track_set_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (ob != obact) {
- con = add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
+ con = BKE_add_ob_constraint(ob, "AutoTrack", CONSTRAINT_TYPE_LOCKTRACK);
data = con->data;
data->tar = obact;
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 2aa737d..07eca74 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -42,6 +42,7 @@
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
+#include "DNA_lamp_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
@@ -525,6 +526,7 @@ static EnumPropertyItem prop_select_grouped_types[] = {
{10, "COLOR", 0, "Color", "Object Color"},
{11, "PROPERTIES", 0, "Properties", "Game Properties"},
{12, "KEYINGSET", 0, "Keying Set", "Objects included in active Keying Set"},
+ {13, "LAMP_TYPE", 0, "Lamp Type", "Matching lamp types"},
{0, NULL, 0, NULL, NULL}
};
@@ -656,7 +658,25 @@ static short select_grouped_siblings(bContext *C, Object *ob)
CTX_DATA_END;
return changed;
}
+static short select_similar_lamps(bContext *C, Object *ob)
+{
+ Lamp *la = ob->data;
+
+ short changed = 0;
+ CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
+ {
+ if (base->object->type == OB_LAMP) {
+ Lamp *la_test = base->object->data;
+ if ((la->type == la_test->type) && !(base->flag & SELECT)) {
+ ED_base_object_select(base, BA_SELECT);
+ changed = 1;
+ }
+ }
+ }
+ CTX_DATA_END;
+ return changed;
+}
static short select_grouped_type(bContext *C, Object *ob)
{
short changed = 0;
@@ -803,7 +823,12 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
}
-
+
+ if (nr == 13 && ob->type != OB_LAMP) {
+ BKE_report(op->reports, RPT_ERROR, "Active object must be a lamp");
+ return OPERATOR_CANCELLED;
+ }
+
if (nr == 1) changed |= select_grouped_children(C, ob, 1);
else if (nr == 2) changed |= select_grouped_children(C, ob, 0);
else if (nr == 3) changed |= select_grouped_parent(C);
@@ -816,6 +841,7 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
else if (nr == 10) changed |= select_grouped_color(C, ob);
else if (nr == 11) changed |= select_grouped_gameprops(C, ob);
else if (nr == 12) changed |= select_grouped_keyingset(C, ob);
+ else if (nr == 13) changed |= select_similar_lamps(C, ob);
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 1b135c0..e7c619a 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -65,6 +65,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -87,7 +88,7 @@ static int vertex_group_use_vert_sel(Object *ob)
if (ob->mode == OB_MODE_EDIT) {
return TRUE;
}
- else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) {
+ else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) {
return TRUE;
}
else {
@@ -400,26 +401,34 @@ typedef enum WT_ReplaceMode {
} WT_ReplaceMode;
static EnumPropertyItem WT_vertex_group_mode_item[] = {
- {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"},
- {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"},
+ {WT_REPLACE_ACTIVE_VERTEX_GROUP,
+ "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"},
+ {WT_REPLACE_ALL_VERTEX_GROUPS,
+ "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem WT_method_item[] = {
- {WT_BY_INDEX, "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"},
- {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"},
- {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"},
- {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"},
+ {WT_BY_INDEX,
+ "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"},
+ {WT_BY_NEAREST_VERTEX,
+ "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"},
+ {WT_BY_NEAREST_FACE,
+ "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"},
+ {WT_BY_NEAREST_VERTEX_IN_FACE,
+ "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem WT_replace_mode_item[] = {
- {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"},
- {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"},
+ {WT_REPLACE_ALL_WEIGHTS,
+ "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"},
+ {WT_REPLACE_EMPTY_WEIGHTS,
+ "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"},
{0, NULL, 0, NULL, NULL}
};
-/*copy weight*/
+/* Copy weight.*/
static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode)
{
switch (replace_mode) {
@@ -439,7 +448,9 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src,
}
}
-/* could be exposed externally */
+/* Could be exposed externally by implementing it in header with the rest.
+ * Simple refactoring will break something.
+ * For now, naming is ed_ instead of ED_*/
static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene,
WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op)
{
@@ -457,53 +468,52 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4;
const int use_vert_sel = vertex_group_use_vert_sel(ob_dst);
- /* create new and overwrite vertex group on destination without data */
+ /* Ensure vertex group on target.*/
if (!defgroup_find_name(ob_dst, dg_src->name)) {
- ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
ED_vgroup_add_name(ob_dst, dg_src->name);
}
- /* get destination deformgroup */
+ /* Get destination deformgroup.*/
dg_dst = defgroup_find_name(ob_dst, dg_src->name);
- /* get meshes */
+ /* Get meshes.*/
dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH);
me_dst = ob_dst->data;
me_src = ob_src->data;
- /* sanity check */
+ /* Sanity check.*/
if (!me_src->dvert) {
BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)");
return 0;
}
- /* create data in memory when nothing there */
+ /* Create data in memory when nothing there.*/
if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data);
- /* get vertex group arrays */
+ /* Get vertex group arrays.*/
ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel);
- /* get indexes of vertex groups */
+ /* Get indexes of vertex groups.*/
index_src = BLI_findindex(&ob_src->defbase, dg_src);
index_dst = BLI_findindex(&ob_dst->defbase, dg_dst);
- /* get vertices */
+ /* Get vertices.*/
mv_dst = me_dst->mvert;
mv_src = dmesh_src->getVertArray(dmesh_src);
- /* prepare transformation matrix */
+ /* Prepare transformation matrix.*/
invert_m4_m4(ob_src->imat, ob_src->obmat);
mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
- /* clear weights */
+ /* Clear weights.*/
if (replace_mode == WT_REPLACE_ALL_WEIGHTS) {
for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) {
if (*dv_dst == NULL) continue;
dw_dst = defvert_find_index(*dv_dst, index_dst);
- /* remove vertex from group */
+ /* Remove vertex from group.*/
if (dw_dst) defvert_remove_group(*dv_dst, dw_dst);
}
}
@@ -511,7 +521,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
switch (method) {
case WT_BY_INDEX:
- /* check if indices are matching, delete and return if not */
+ /* Check if indices are matching, delete and return if not.*/
if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src ||
dv_array_src == NULL || dv_array_dst == NULL)
{
@@ -523,14 +533,15 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
return 0;
}
- /* loop through the vertices*/
- for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) {
+ /* Loop through the vertices.*/
+ for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert;
+ i++, dv_dst++, dv_src++, mv_src++, mv_dst++) {
if (*dv_dst == NULL) {
continue;
}
- /* copy weight */
+ /* Copy weight.*/
dw_src = defvert_find_index(*dv_src, index_src);
if (dw_src && dw_src->weight) {
dw_dst = defvert_verify_index(*dv_dst, index_dst);
@@ -540,29 +551,30 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
break;
case WT_BY_NEAREST_VERTEX:
- /* make node tree */
+ /* Make node tree.*/
bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6);
- /* loop trough vertices */
+ /* Loop trough vertices.*/
for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
if (*dv_dst == NULL) {
continue;
}
- /* reset nearest */
+ /* Reset nearest.*/
nearest.dist = FLT_MAX;
- /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ /* It is faster to start searching at the top of the tree instead of previous search result.*/
nearest.index = -1;
- /* transform into target space */
+ /* Transform into target space.*/
mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
- /* node tree accelerated search for closest vetex */
+ /* Node tree accelerated search for closest vetex.*/
BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co,
&nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src);
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are
+ * overwritten prior to this. See the "Clear weights." step above.*/
dw_src = defvert_find_index(dv_array_src[nearest.index], index_src);
if (dw_src && dw_src->weight) {
dw_dst = defvert_verify_index(*dv_dst, index_dst);
@@ -570,105 +582,108 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
}
}
- /* free memory */
+ /* Free memory.*/
free_bvhtree_from_mesh(&tree_mesh_vertices_src);
break;
case WT_BY_NEAREST_FACE:
- /* get faces */
+ /* Get faces.*/
DM_ensure_tessface(dmesh_src);
mface_src = dmesh_src->getTessFaceArray(dmesh_src);
- /* make node tree */
+ /* Make node tree.*/
bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
- /* loop through the vertices */
+ /* Loop through the vertices.*/
for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
if (*dv_dst == NULL) {
continue;
}
- /* reset nearest */
+ /* Reset nearest.*/
nearest.dist = FLT_MAX;
- /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ /* It is faster to start searching at the top of the tree instead of previous search result.*/
nearest.index = -1;
- /* transform into target space */
+ /* Transform into target space.*/
mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
- /* node tree accelerated search for closest face */
+ /* Node tree accelerated search for closest face.*/
BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
&nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
index_nearest = nearest.index;
- /* project onto face */
+ /* Project onto face.*/
mf = &mface_src[index_nearest];
normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co);
project_v3_plane(tmp_co, normal, mv_src[mf->v1].co);
- /* interpolate weights over face*/
+ /* Interpolate weights over face.*/
f_index = mf->v4 ? 3 : 2;
if (f_index == 3) {
- interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co);
+ interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co,
+ mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co);
}
else {
- interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co);
+ interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co,
+ mv_src[mf->v3].co, NULL, tmp_co);
}
- /* get weights from face*/
+ /* Get weights from face.*/
weight = 0;
do {
v_index = (&mf->v1)[f_index];
weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src);
} while (f_index--);
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are
+ * overwritten prior to this. See the "Clear weights." step above.*/
if (weight > 0) {
dw_dst = defvert_verify_index(*dv_dst, index_dst);
vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode);
}
}
- /* free memory */
+ /* Free memory.*/
free_bvhtree_from_mesh(&tree_mesh_faces_src);
break;
case WT_BY_NEAREST_VERTEX_IN_FACE:
- /* get faces */
+ /* Get faces.*/
DM_ensure_tessface(dmesh_src);
mface_src = dmesh_src->getTessFaceArray(dmesh_src);
- /* make node tree */
+ /* Make node tree.*/
bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
- /* loop through the vertices */
+ /* Loop through the vertices.*/
for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
if (*dv_dst == NULL) {
continue;
}
- /* reset nearest */
+ /* Reset nearest.*/
nearest.dist = FLT_MAX;
- /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ /* It is faster to start searching at the top of the tree instead of previous search result.*/
nearest.index = -1;
- /* transform into target space */
+ /* Transform into target space.*/
mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
- /* node tree accelerated search for closest face */
+ /* Node tree accelerated search for closest face.*/
BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
&nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
index_nearest = nearest.index;
- /* get distances */
+ /* Get distances.*/
mf = &mface_src[index_nearest];
dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co);
dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co);
dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co);
- /* get closest vertex */
+ /* Get closest vertex.*/
f_index = mf->v4 ? 3 : 2;
if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1;
else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2;
@@ -680,7 +695,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
}
}
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are
+ * overwritten prior to this. See the "Clear weights." step above.*/
dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src);
if (dw_src && dw_src->weight) {
dw_dst = defvert_verify_index(*dv_dst, index_dst);
@@ -688,7 +704,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
}
}
- /* free memory */
+ /* Free memory.*/
free_bvhtree_from_mesh(&tree_mesh_faces_src);
break;
@@ -697,7 +713,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou
break;
}
- /*free memory*/
+ /* Free memory.*/
if (dv_array_src) MEM_freeN(dv_array_src);
if (dv_array_dst) MEM_freeN(dv_array_dst);
dmesh_src->release(dmesh_src);
@@ -1394,7 +1410,7 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
Mesh *me = ob->data;
MVert *mvert = me->mvert;
int *verts = NULL;
- if (!(me->editflag & ME_EDIT_VERT_SEL))
+ if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL))
return;
for (i = 0; i < me->totvert && mvert; i++, mvert++) {
if (mvert->flag & SELECT) {
@@ -1516,16 +1532,30 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
}
}
+enum {
+ VGROUP_TOGGLE,
+ VGROUP_LOCK,
+ VGROUP_UNLOCK,
+ VGROUP_INVERT
+};
+
+static EnumPropertyItem vgroup_lock_actions[] = {
+ {VGROUP_TOGGLE, "TOGGLE", 0, "Toggle", "Unlock all vertex groups if there is at least one locked group, lock all in other case"},
+ {VGROUP_LOCK, "LOCK", 0, "Lock", "Lock all vertex groups"},
+ {VGROUP_UNLOCK, "UNLOCK", 0, "Unlock", "Unlock all vertex groups"},
+ {VGROUP_INVERT, "INVERT", 0, "Invert", "Invert the lock state of all vertex groups"},
+ {0, NULL, 0, NULL, NULL}
+};
static void vgroup_lock_all(Object *ob, int action)
{
bDeformGroup *dg;
- if (action == SEL_TOGGLE) {
- action = SEL_SELECT;
+ if (action == VGROUP_TOGGLE) {
+ action = VGROUP_LOCK;
for (dg = ob->defbase.first; dg; dg = dg->next) {
if (dg->flag & DG_LOCK_WEIGHT) {
- action = SEL_DESELECT;
+ action = VGROUP_UNLOCK;
break;
}
}
@@ -1533,13 +1563,13 @@ static void vgroup_lock_all(Object *ob, int action)
for (dg = ob->defbase.first; dg; dg = dg->next) {
switch (action) {
- case SEL_SELECT:
+ case VGROUP_LOCK:
dg->flag |= DG_LOCK_WEIGHT;
break;
- case SEL_DESELECT:
+ case VGROUP_UNLOCK:
dg->flag &= ~DG_LOCK_WEIGHT;
break;
- case SEL_INVERT:
+ case VGROUP_INVERT:
dg->flag ^= DG_LOCK_WEIGHT;
break;
}
@@ -2041,7 +2071,7 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v
/* object mode / weight paint */
MVert *mv, *mv_mirr;
int vidx, vidx_mirr;
- const int use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
if (me->dvert == NULL) {
goto cleanup;
@@ -2963,7 +2993,7 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_select_all(ot);
+ RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", "Lock action to execute on vertex groups");
}
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
@@ -3274,7 +3304,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
WT_Method method = RNA_enum_get(op->ptr, "WT_method");
WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode");
- /* Macro to loop through selected objects and perform operation depending on function, option and method */
+ /* Macro to loop through selected objects and perform operation depending on function, option and method.*/
CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects)
{
@@ -3282,8 +3312,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
switch (vertex_group_mode) {
case WT_REPLACE_ACTIVE_VERTEX_GROUP:
- if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
- BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1),
+ if (!ed_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1),
scene, method, replace_mode, op))
{
fail++;
@@ -3292,9 +3321,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
case WT_REPLACE_ALL_VERTEX_GROUPS:
for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) {
- if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
- dg_src, scene, method, replace_mode, op))
- {
+ if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) {
fail++;
}
}
@@ -3307,7 +3334,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
}
}
- /* Event notifiers for correct display of data */
+ /* Event notifiers for correct display of data.*/
DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data);
@@ -3325,28 +3352,24 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
/* transfers weight from active to selected */
void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot)
{
- /* identifiers */
+ /* Identifiers.*/
ot->name = "Transfer Weights";
ot->idname = "OBJECT_OT_vertex_group_transfer_weight";
ot->description = "Transfer weight paint to active from selected mesh";
- /* api callbacks */
+ /* API callbacks.*/
ot->poll = vertex_group_poll;
ot->exec = vertex_group_transfer_weight_exec;
- /* flags */
+ /* Flags.*/
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
+ /* Properties.*/
ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", "");
ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", "");
ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", "");
}
-static EnumPropertyItem vgroup_items[] = {
- {0, NULL, 0, NULL, NULL}
-};
-
static int set_active_group_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3370,7 +3393,7 @@ static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *UNUSED(ptr), Prop
int a, totitem = 0;
if (!ob)
- return vgroup_items;
+ return DummyRNA_NULL_items;
for (a = 0, def = ob->defbase.first; def; def = def->next, a++) {
tmp.value = a;
@@ -3404,7 +3427,7 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active");
+ prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "Vertex group to set as active");
RNA_def_enum_funcs(prop, vgroup_itemf);
ot->prop = prop;
}
diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript
index fffe05d..293f776 100644
--- a/source/blender/editors/physics/SConscript
+++ b/source/blender/editors/physics/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index f575429..9dbc0f9 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -53,10 +53,9 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.h"
-
#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_mesh.h"
@@ -193,6 +192,16 @@ ParticleEditSettings *PE_settings(Scene *scene)
return scene->toolsettings ? &scene->toolsettings->particle : NULL;
}
+static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *brush)
+{
+ // here we can enable unified brush size, needs more work...
+ // UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ // float size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
+
+ return brush->size * U.pixelsize;
+}
+
+
/* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set
*
* note: this function runs on poll, therefor it can runs many times a second
@@ -412,7 +421,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
/* used to calculate here but all callers have the screen_co already, so pass as arg */
#if 0
if (ED_view3d_project_int_global(data->vc.ar, co, screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK)
{
return 0;
}
@@ -516,7 +525,7 @@ static int point_is_selected(PTCacheEditPoint *point)
typedef void (*ForPointFunc)(PEData *data, int point_index);
typedef void (*ForKeyFunc)(PEData *data, int point_index, int key_index);
-typedef void (*ForKeyMatFunc)(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key);
+typedef void (*ForKeyMatFunc)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key);
static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest)
{
@@ -2500,7 +2509,8 @@ void PARTICLE_OT_weight_set(wmOperatorType *ot)
static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
{
- ParticleEditSettings *pset= PE_settings(CTX_data_scene(C));
+ Scene *scene = CTX_data_scene(C);
+ ParticleEditSettings *pset= PE_settings(scene);
ParticleBrushData *brush;
if (pset->brushtype < 0)
@@ -2516,7 +2526,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
glColor4ub(255, 255, 255, 128);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
+ glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
@@ -2766,7 +2776,7 @@ void PARTICLE_OT_mirror(wmOperatorType *ot)
/************************* brush edit callbacks ********************/
-static void brush_comb(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key)
+static void brush_comb(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key)
{
ParticleEditSettings *pset= PE_settings(data->scene);
float cvec[3], fac;
@@ -2802,7 +2812,7 @@ static void brush_cut(PEData *data, int pa_index)
if (edit->points[pa_index].flag & PEP_HIDE)
return;
- if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK)
+ if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK)
return;
rad2= data->rad * data->rad;
@@ -2827,7 +2837,7 @@ static void brush_cut(PEData *data, int pa_index)
/* calculate path time closest to root that was inside the circle */
for (k=1, key++; k<=keys; k++, key++) {
- if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) ||
+ if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_CLIP_NEAR) != V3D_PROJ_RET_OK) ||
key_test_depth(data, key->co, screen_co) == 0)
{
x0 = (float)screen_co[0];
@@ -3038,7 +3048,7 @@ static void brush_puff(PEData *data, int point_index)
}
-static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNUSED(imat[][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key))
+static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[4][4]), float UNUSED(imat[4][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key))
{
/* roots have full weight allways */
if (key_index) {
@@ -3052,7 +3062,7 @@ static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNU
}
}
-static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key)
+static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key)
{
if (key_index) {
float dvec[3];
@@ -3064,7 +3074,7 @@ static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4
}
}
-static void brush_smooth_do(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key)
+static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key)
{
float vec[3], dvec[3];
@@ -3466,11 +3476,16 @@ static int brush_edit_init(bContext *C, wmOperator *op)
PTCacheEdit *edit= PE_get_current(scene, ob);
ARegion *ar= CTX_wm_region(C);
BrushEdit *bedit;
-
+ float min[3], max[3];
+
if (pset->brushtype < 0)
return 0;
- initgrabz(ar->regiondata, ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2]);
+ /* set the 'distance factor' for grabbing (used in comb etc) */
+ INIT_MINMAX(min, max);
+ PE_minmax(scene, min, max);
+ mid_v3_v3v3(min, min, max);
+ initgrabz(ar->regiondata, min[0], min[1], min[2]);
bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit");
bedit->first= 1;
@@ -3535,7 +3550,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
selected= (short)count_selected_keys(scene, edit);
dmax = max_ff(fabsf(dx), fabsf(dy));
- tot_steps = dmax/(0.2f * brush->size) + 1;
+ tot_steps = dmax/(0.2f * pe_brush_size_get(scene, brush)) + 1;
dx /= (float)tot_steps;
dy /= (float)tot_steps;
@@ -3549,7 +3564,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
const float mval_f[2] = {dx, dy};
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.combfac= (brush->strength - 0.5f) * 2.0f;
if (data.combfac < 0.0f)
@@ -3569,7 +3584,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
if (edit->psys && edit->pathcache) {
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.cutfac= brush->strength;
if (selected)
@@ -3590,7 +3605,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.growfac= brush->strength / 50.0f;
if (brush->invert ^ flip)
@@ -3609,7 +3624,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (edit->psys) {
data.dm= psmd->dm;
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.select= selected;
data.pufffac= (brush->strength - 0.5f) * 2.0f;
@@ -3642,7 +3657,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
case PE_BRUSH_SMOOTH:
{
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.vec[0] = data.vec[1] = data.vec[2] = 0.0f;
data.tot= 0;
@@ -3665,7 +3680,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (edit->psys) {
data.dm= psmd->dm;
data.mval= mval;
- data.rad= (float)brush->size;
+ data.rad= pe_brush_size_get(scene, brush);
data.weightfac = brush->strength; /* note that this will never be zero */
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 221aad2..23069ab 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -49,6 +49,7 @@
#include "BKE_main.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
+#include "BKE_report.h"
#include "RNA_access.h"
@@ -625,7 +626,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
}
-static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static int connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
ParticleData *pa;
@@ -642,8 +643,8 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
float hairmat[4][4], imat[4][4];
float v[4][3], vec[3];
- if (!psys || !psys->part || psys->part->type != PART_HAIR)
- return;
+ if (!psys || !psys->part || psys->part->type != PART_HAIR || !psmd->dm)
+ return FALSE;
edit= psys->edit;
point= edit ? edit->points : NULL;
@@ -724,6 +725,8 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
psys->flag &= ~PSYS_GLOBAL_HAIR;
PE_update_object(scene, ob, 0);
+
+ return TRUE;
}
static int connect_hair_exec(bContext *C, wmOperator *op)
@@ -733,18 +736,24 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= NULL;
int all = RNA_boolean_get(op->ptr, "all");
+ int any_connected = FALSE;
if (!ob)
return OPERATOR_CANCELLED;
if (all) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- connect_hair(scene, ob, psys);
+ any_connected |= connect_hair(scene, ob, psys);
}
}
else {
psys = ptr.data;
- connect_hair(scene, ob, psys);
+ any_connected |= connect_hair(scene, ob, psys);
+ }
+
+ if (!any_connected) {
+ BKE_report(op->reports, RPT_ERROR, "Can't disconnect hair if particle system modifier is disabled");
+ return OPERATOR_CANCELLED;
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 5304c64..fc55b2b 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -127,7 +127,7 @@ static float get_fluid_size_m(Scene *scene, Object *domainob, FluidsimSettings *
float longest_axis;
BKE_object_dimensions_get(domainob, dim);
- longest_axis = MAX3(dim[0], dim[1], dim[2]);
+ longest_axis = max_fff(dim[0], dim[1], dim[2]);
return longest_axis * scene->unit.scale_length;
}
@@ -142,7 +142,7 @@ static int fluid_is_animated_mesh(FluidsimSettings *fss)
#if 0
/* helper function */
-void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname)
+void fluidsimGetGeometryObjFilename(Object *ob, char *dst) //, char *srcname)
{
//BLI_snprintf(dst, FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name);
BLI_snprintf(dst, FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name);
@@ -237,7 +237,7 @@ static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *chann
{
int i;
- channels->timeAtFrame = MEM_callocN((channels->length+1)*sizeof(float), "timeAtFrame channel");
+ channels->timeAtFrame = MEM_callocN((channels->length + 1) * sizeof(float), "timeAtFrame channel");
channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1
@@ -267,7 +267,7 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene,
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
float *verts;
int *tris=NULL, numVerts=0, numTris=0;
- int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+ int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd);
int framesize = (3*fobj->numVerts) + 1;
int j;
@@ -388,7 +388,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
if (fluid_is_animated_mesh(fluidmd->fss)) {
float *verts=NULL;
- int *tris=NULL, modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+ int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd);
initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex);
fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache");
@@ -491,7 +491,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length)
for (fobj=fobjects->first; fobj; fobj=fobj->next) {
Object *ob = fobj->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
- int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd);
+ int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd);
float *verts=NULL;
int *tris=NULL;
diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript
index 0b19ecd..c05b542 100644
--- a/source/blender/editors/render/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 73f8abd..7ba6a92 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -43,6 +43,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_world_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -192,7 +193,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
if ((scene->r.mode & R_OSA) == 0) {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf);
}
else {
@@ -206,7 +207,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BLI_jitter_init(jit_ofs[0], scene->r.osa);
/* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer);
/* skip the first sample */
@@ -216,7 +217,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
(jit_ofs[j][0] * 2.0f) / sizex,
(jit_ofs[j][1] * 2.0f) / sizey);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE);
GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp);
add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float));
}
@@ -232,7 +233,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
else {
/* shouldnt suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
- ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, TRUE, FALSE, err_out);
+ ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
+ IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out);
camera = scene->camera;
if (ibuf_view) {
@@ -243,7 +245,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
}
}
-
+
+ if (scene->r.alphamode == R_ADDSKY) {
+ float sky_color[3];
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+ IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color);
+ }
+
/* note on color management:
*
* OpenGL renders into sRGB colors, but render buffers are expected to be
@@ -281,7 +289,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
IMB_color_to_bw(ibuf);
}
- BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, FALSE);
+ BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, FALSE);
ok = BKE_imbuf_write_as(ibuf, name, &scene->r.im_format, TRUE); /* no need to stamp here */
if (ok) printf("OpenGL Render written to '%s'\n", name);
else printf("OpenGL Render failed to write '%s'\n", name);
@@ -505,7 +513,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
if (!is_movie) {
- BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index a864fe3..25ad1f6 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -84,6 +84,8 @@
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
+#include "GPU_extensions.h"
+
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -280,11 +282,6 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sce->r.tiley = sce->r.ysch / 4;
}
- /* exception: don't apply render part of display transform for texture previews or icons */
- if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) {
- BKE_scene_disable_color_management(sce);
- }
-
if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO)
sce->r.alphamode = R_ALPHAPREMUL;
else
@@ -488,24 +485,15 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
/* new UI convention: draw is in pixel space already. */
/* uses ROUNDBOX button in block to get the rect */
-static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int first, rcti *rect, rcti *newrect)
+static int ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
{
Render *re;
RenderResult rres;
char name[32];
- int do_gamma_correct = FALSE, do_predivide = FALSE;
int offx = 0;
int newx = BLI_rcti_size_x(rect);
int newy = BLI_rcti_size_y(rect);
- if (id && GS(id->name) != ID_TE) {
- /* exception: don't color manage texture previews - show the raw values */
- if (sce) {
- do_gamma_correct = TRUE;
- do_predivide = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE;
- }
- }
-
if (!split || first) sprintf(name, "Preview %p", (void *)sa);
else sprintf(name, "SecondPreview %p", (void *)sa);
@@ -520,8 +508,10 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
}
}
+ /* test if something rendered ok */
re = RE_GetRender(name);
RE_AcquireResultImage(re, &rres);
+ RE_ReleaseResultImage(re);
if (rres.rectf) {
@@ -531,40 +521,20 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
newrect->ymax = max_ii(newrect->ymax, rect->ymin + rres.recty);
if (rres.rectx && rres.recty) {
- /* temporary conversion to byte for drawing */
+ unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
float fx = rect->xmin + offx;
float fy = rect->ymin;
- int dither = 0;
- unsigned char *rect_byte;
-
- rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
-
- if (do_gamma_correct) {
- IMB_display_buffer_transform_apply(rect_byte, rres.rectf, rres.rectx, rres.recty, 4,
- &sce->view_settings, &sce->display_settings, do_predivide);
-
- }
- else {
- /* OCIO_TODO: currently seems an exception for textures (came fro mlegacish time),
- * but is it indeed expected behavior, or textures should be
- * color managed as well?
- */
- IMB_buffer_byte_from_float(rect_byte, rres.rectf,
- 4, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, do_predivide,
- rres.rectx, rres.recty, rres.rectx, rres.rectx);
- }
-
+
+ RE_ResultGet32(re, (unsigned int *)rect_byte);
glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
-
+
MEM_freeN(rect_byte);
+
+ return 1;
}
-
- RE_ReleaseResultImage(re);
- return 1;
}
}
- RE_ReleaseResultImage(re);
return 0;
}
@@ -572,7 +542,6 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
{
if (idp) {
ScrArea *sa = CTX_wm_area(C);
- Scene *sce = CTX_data_scene(C);
ID *id = (ID *)idp;
ID *parent = (ID *)parentp;
MTex *slot = (MTex *)slotp;
@@ -588,11 +557,11 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
newrect.ymax = rect->ymin;
if (parent) {
- ok = ed_preview_draw_rect(sa, sce, id, 1, 1, rect, &newrect);
- ok &= ed_preview_draw_rect(sa, sce, parent, 1, 0, rect, &newrect);
+ ok = ed_preview_draw_rect(sa, 1, 1, rect, &newrect);
+ ok &= ed_preview_draw_rect(sa, 1, 0, rect, &newrect);
}
else
- ok = ed_preview_draw_rect(sa, sce, id, 0, 0, rect, &newrect);
+ ok = ed_preview_draw_rect(sa, 0, 0, rect, &newrect);
if (ok)
*rect = newrect;
@@ -743,7 +712,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
else {
/* validate owner */
//if (ri->rect == NULL)
- // ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
+ // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
//RE_ResultGet32(re, ri->rect);
}
@@ -917,7 +886,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
ShaderPreview *sp = customdata;
ID *id = sp->id;
short idtype = GS(id->name);
-
+
if (idtype == ID_IM) {
Image *ima = (Image *)id;
ImBuf *ibuf = NULL;
@@ -1040,8 +1009,27 @@ static void icon_preview_endjob(void *customdata)
{
IconPreview *ip = customdata;
- if (ip->id && GS(ip->id->name) == ID_BR)
- WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+ if (ip->id) {
+
+ if (GS(ip->id->name) == ID_BR)
+ WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+#if 0
+ if (GS(ip->id->name) == ID_MA) {
+ Material *ma = (Material *)ip->id;
+ PreviewImage *prv_img = ma->preview;
+ int i;
+
+ /* signal to gpu texture */
+ for (i = 0; i < NUM_ICON_SIZES; ++i) {
+ if (prv_img->gputexture[i]) {
+ GPU_texture_free(prv_img->gputexture[i]);
+ prv_img->gputexture[i] = NULL;
+ WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id);
+ }
+ }
+ }
+#endif
+ }
}
static void icon_preview_free(void *customdata)
@@ -1077,7 +1065,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
/* setup job */
WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
- WM_jobs_timer(wm_job, 0.25, NC_MATERIAL, NC_MATERIAL);
+ WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
WM_jobs_start(CTX_wm_manager(C), wm_job);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index eef5e70..53e1f49 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -688,7 +688,7 @@ static int envmap_save_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", path);
if (scene->r.scemode & R_EXTENSION) {
- BKE_add_image_extension(path, imtype);
+ BKE_add_image_extension(path, &scene->r.im_format);
}
WM_cursor_wait(1);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 1ed1cbb..38535ec 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -33,6 +33,7 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -46,6 +47,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -56,6 +58,7 @@
#include "BKE_world.h"
#include "GPU_material.h"
+#include "GPU_buffers.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -232,6 +235,9 @@ static int nodes_use_material(bNodeTree *ntree, Material *ma)
static void material_changed(Main *bmain, Material *ma)
{
Material *parent;
+ Object *ob;
+ Scene *scene;
+ int texture_draw = FALSE;
/* icons */
BKE_icon_changed(BKE_icon_getid(&ma->id));
@@ -254,6 +260,33 @@ static void material_changed(Main *bmain, Material *ma)
if (parent->gpumaterial.first)
GPU_material_free(parent);
}
+
+ /* find if we have a scene with textured display */
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
+ if (scene->customdata_mask & CD_MASK_MTFACE) {
+ texture_draw = TRUE;
+ break;
+ }
+ }
+
+ /* find textured objects */
+ if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ DerivedMesh *dm = ob->derivedFinal;
+ Material ***material = give_matarar(ob);
+ short a, *totmaterial = give_totcolp(ob);
+
+ if (dm && totmaterial && material) {
+ for (a = 0; a < *totmaterial; a++) {
+ if ((*material)[a] == ma) {
+ GPU_drawobject_free(dm);
+ break;
+ }
+ }
+ }
+ }
+ }
+
}
static void lamp_changed(Main *bmain, Lamp *la)
@@ -277,28 +310,33 @@ static void lamp_changed(Main *bmain, Lamp *la)
GPU_material_free(&defmaterial);
}
+static int material_uses_texture(Material *ma, Tex *tex)
+{
+ if (mtex_use_tex(ma->mtex, MAX_MTEX, tex))
+ return TRUE;
+ else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex))
+ return TRUE;
+
+ return FALSE;
+}
+
static void texture_changed(Main *bmain, Tex *tex)
{
Material *ma;
Lamp *la;
World *wo;
Scene *scene;
+ Object *ob;
bNode *node;
+ int texture_draw = FALSE;
/* icons */
BKE_icon_changed(BKE_icon_getid(&tex->id));
/* find materials */
for (ma = bmain->mat.first; ma; ma = ma->id.next) {
- if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) {
- /* pass */
- }
- else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) {
- /* pass */
- }
- else {
+ if (!material_uses_texture(ma, tex))
continue;
- }
BKE_icon_changed(BKE_icon_getid(&ma->id));
@@ -342,6 +380,27 @@ static void texture_changed(Main *bmain, Tex *tex)
ED_node_changed_update(&scene->id, node);
}
}
+
+ if (scene->customdata_mask & CD_MASK_MTFACE)
+ texture_draw = TRUE;
+ }
+
+ /* find textured objects */
+ if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ DerivedMesh *dm = ob->derivedFinal;
+ Material ***material = give_matarar(ob);
+ short a, *totmaterial = give_totcolp(ob);
+
+ if (dm && totmaterial && material) {
+ for (a = 0; a < *totmaterial; a++) {
+ if (material_uses_texture((*material)[a], tex)) {
+ GPU_drawobject_free(dm);
+ break;
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 5ec7f4d..f15f7b5 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -35,6 +35,7 @@
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_blender.h"
#include "BKE_context.h"
@@ -151,9 +152,10 @@ void render_view_open(bContext *C, int mx, int my)
if (sizex < 320) sizex = 320;
if (sizey < 256) sizey = 256;
- /* XXX some magic to calculate postition */
- rect.xmin = mx + win->posx - sizex / 2;
- rect.ymin = my + win->posy - sizey / 2;
+ /* some magic to calculate postition */
+ /* pixelsize: mouse coords are in U.pixelsize units :/ */
+ rect.xmin = (mx / U.pixelsize) + win->posx - sizex / 2;
+ rect.ymin = (my / U.pixelsize) + win->posy - sizey / 2;
rect.xmax = rect.xmin + sizex;
rect.ymax = rect.ymin + sizey;
diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript
index 0e894a1..c0a14ce 100644
--- a/source/blender/editors/screen/SConscript
+++ b/source/blender/editors/screen/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f30e0ab..cea7b12 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -235,8 +235,8 @@ static void region_draw_azone_icon(AZone *az)
static void draw_azone_plus(float x1, float y1, float x2, float y2)
{
- float width = 2.0f;
- float pad = 4.0f;
+ float width = 0.1f * U.widget_unit;
+ float pad = 0.2f * U.widget_unit;
glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad);
glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f);
@@ -395,47 +395,14 @@ void ED_area_overdraw(bContext *C)
}
-/* get scissor rect, checking overlapping regions */
-void region_scissor_winrct(ARegion *ar, rcti *winrct)
-{
- *winrct = ar->winrct;
-
- if (ELEM(ar->alignment, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT))
- return;
-
- while (ar->prev) {
- ar = ar->prev;
-
- if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) {
- if (ar->flag & RGN_FLAG_HIDDEN) {
- /* pass */
- }
- else if (ar->alignment & RGN_SPLIT_PREV) {
- /* pass */
- }
- else if (ar->alignment == RGN_OVERLAP_LEFT) {
- winrct->xmin = ar->winrct.xmax + 1;
- }
- else if (ar->alignment == RGN_OVERLAP_RIGHT) {
- winrct->xmax = ar->winrct.xmin - 1;
- }
- else break;
- }
- }
-}
-
/* only exported for WM */
/* makes region ready for drawing, sets pixelspace */
void ED_region_set(const bContext *C, ARegion *ar)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
- rcti winrct;
-
- /* checks other overlapping regions */
- region_scissor_winrct(ar, &winrct);
- ar->drawrct = winrct;
+ ar->drawrct = ar->winrct;
/* note; this sets state, so we can use wmOrtho and friends */
wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
@@ -452,24 +419,20 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
ARegionType *at = ar->type;
- rcti winrct;
/* see BKE_spacedata_draw_locks() */
if (at->do_lock)
return;
- /* checks other overlapping regions */
- region_scissor_winrct(ar, &winrct);
-
/* if no partial draw rect set, full rect */
if (ar->drawrct.xmin == ar->drawrct.xmax)
- ar->drawrct = winrct;
+ ar->drawrct = ar->winrct;
else {
/* extra clip for safety (intersect the rects, could use API func) */
- ar->drawrct.xmin = max_ii(winrct.xmin, ar->drawrct.xmin);
- ar->drawrct.ymin = max_ii(winrct.ymin, ar->drawrct.ymin);
- ar->drawrct.xmax = min_ii(winrct.xmax, ar->drawrct.xmax);
- ar->drawrct.ymax = min_ii(winrct.ymax, ar->drawrct.ymax);
+ ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin);
+ ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin);
+ ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax);
+ ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax);
}
/* note; this sets state, so we can use wmOrtho and friends */
@@ -500,7 +463,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
uiFreeInactiveBlocks(C, &ar->uiblocks);
if (sa)
- region_draw_emboss(ar, &winrct);
+ region_draw_emboss(ar, &ar->winrct);
}
/* **********************************
@@ -611,8 +574,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa)
az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
BLI_addtail(&(sa->actionzones), az);
az->type = AZONE_AREA;
- az->x1 = sa->totrct.xmin - 1;
- az->y1 = sa->totrct.ymin - 1;
+ az->x1 = sa->totrct.xmin;
+ az->y1 = sa->totrct.ymin;
az->x2 = sa->totrct.xmin + (AZONESPOT - 1);
az->y2 = sa->totrct.ymin + (AZONESPOT - 1);
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
@@ -627,8 +590,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa)
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-#define AZONEPAD_EDGE 4
-#define AZONEPAD_ICON 9
+#define AZONEPAD_EDGE (0.2f * U.widget_unit)
+#define AZONEPAD_ICON (0.45f * U.widget_unit)
static void region_azone_edge(AZone *az, ARegion *ar)
{
switch (az->edge) {
@@ -720,8 +683,8 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar)
}
}
-#define AZONEPAD_TAB_PLUSW 14
-#define AZONEPAD_TAB_PLUSH 14
+#define AZONEPAD_TAB_PLUSW (0.7f * U.widget_unit)
+#define AZONEPAD_TAB_PLUSH (0.7f * U.widget_unit)
/* region already made zero sized, in shape of edge */
static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
@@ -736,28 +699,28 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0;
- az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW;
az->y1 = ar->winrct.ymax - add;
- az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW;
az->y2 = ar->winrct.ymax - add + AZONEPAD_TAB_PLUSH;
break;
case AE_BOTTOM_TO_TOPLEFT:
- az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW;
az->y1 = ar->winrct.ymin - AZONEPAD_TAB_PLUSH;
- az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW;
az->y2 = ar->winrct.ymin;
break;
case AE_LEFT_TO_TOPRIGHT:
az->x1 = ar->winrct.xmin - AZONEPAD_TAB_PLUSH;
- az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW;
az->x2 = ar->winrct.xmin;
- az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW;
break;
case AE_RIGHT_TO_TOPLEFT:
az->x1 = ar->winrct.xmax - 1;
- az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW;
+ az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW;
az->x2 = ar->winrct.xmax - 1 + AZONEPAD_TAB_PLUSH;
- az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW;
+ az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW;
break;
}
/* rect needed for mouse pointer test */
@@ -765,8 +728,8 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
}
-#define AZONEPAD_TABW 18
-#define AZONEPAD_TABH 7
+#define AZONEPAD_TABW (0.9f * U.widget_unit)
+#define AZONEPAD_TABH (0.35f * U.widget_unit)
/* region already made zero sized, in shape of edge */
static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar)
@@ -809,8 +772,8 @@ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar)
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-#define AZONEPAD_TRIAW 16
-#define AZONEPAD_TRIAH 9
+#define AZONEPAD_TRIAW (0.8f * U.widget_unit)
+#define AZONEPAD_TRIAH (0.45f * U.widget_unit)
/* region already made zero sized, in shape of edge */
@@ -892,9 +855,9 @@ static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment)
region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT);
else if (alignment == RGN_ALIGN_BOTTOM)
region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT);
- else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT))
+ else if (alignment == RGN_ALIGN_RIGHT)
region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT);
- else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT))
+ else if (alignment == RGN_ALIGN_LEFT)
region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT);
}
@@ -909,7 +872,58 @@ static int rct_fits(rcti *rect, char dir, int size)
}
}
-static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int quad)
+/* *************************************************************** */
+
+/* ar should be overlapping */
+/* function checks if some overlapping region was defined before - on same place */
+static void region_overlap_fix(ScrArea *sa, ARegion *ar)
+{
+ ARegion *ar1 = ar->prev;
+
+ /* find overlapping previous region on same place */
+ while (ar1) {
+ if (ar1->overlap) {
+ if ((ar1->alignment & RGN_SPLIT_PREV) == 0)
+ if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL))
+ break;
+ }
+ ar1 = ar1->prev;
+ }
+
+ /* translate or close */
+ if (ar1) {
+ int align1 = ar1->alignment & ~RGN_SPLIT_PREV;
+
+ if (align1 == RGN_ALIGN_LEFT) {
+ if (ar->winrct.xmax + ar1->winx > sa->winx - U.widget_unit)
+ ar->flag |= RGN_FLAG_TOO_SMALL;
+ else
+ BLI_rcti_translate(&ar->winrct, ar1->winx, 0);
+ }
+ else if (align1 == RGN_ALIGN_RIGHT) {
+ if (ar->winrct.xmin - ar1->winx < U.widget_unit)
+ ar->flag |= RGN_FLAG_TOO_SMALL;
+ else
+ BLI_rcti_translate(&ar->winrct, -ar1->winx, 0);
+ }
+ }
+
+
+
+}
+
+/* overlapping regions only in the following restricted cases */
+static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar)
+{
+ if (U.uiflag2 & USER_REGION_OVERLAP)
+ if (WM_is_draw_triple(win))
+ if (ELEM4(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP))
+ if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
+ return 1;
+ return 0;
+}
+
+static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, int quad)
{
rcti *remainder_prev = remainder;
int prefsizex, prefsizey;
@@ -928,22 +942,26 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
alignment = ar->alignment & ~RGN_SPLIT_PREV;
+ /* set here, assuming userpref switching forces to call this again */
+ ar->overlap = region_is_overlap(win, sa, ar);
+
/* clear state flags first */
ar->flag &= ~RGN_FLAG_TOO_SMALL;
/* user errors */
if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT)
alignment = RGN_ALIGN_NONE;
- /* prefsize, for header we stick to exception */
- prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex;
+ /* prefsize, for header we stick to exception (prevent dpi rounding error) */
+ prefsizex = UI_DPI_FAC * (ar->sizex > 1 ? ar->sizex + 0.5f : ar->type->prefsizex);
+
if (ar->regiontype == RGN_TYPE_HEADER) {
- prefsizey = ar->type->prefsizey;
+ prefsizey = ED_area_headersize();
}
else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) {
prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2);
}
else {
- prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey;
+ prefsizey = UI_DPI_FAC * (ar->sizey > 1 ? ar->sizey + 0.5f : ar->type->prefsizey);
}
@@ -985,7 +1003,7 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
}
}
}
- else if (ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) {
+ else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
if (rct_fits(remainder, 'h', prefsizex) < 0) {
ar->flag |= RGN_FLAG_TOO_SMALL;
@@ -998,14 +1016,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winrct = *remainder;
- if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) {
+ if (alignment == RGN_ALIGN_RIGHT) {
ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1;
- if (alignment == RGN_ALIGN_RIGHT)
+ if (ar->overlap == 0)
remainder->xmax = ar->winrct.xmin - 1;
}
else {
ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1;
- if (alignment == RGN_ALIGN_LEFT)
+ if (ar->overlap == 0)
remainder->xmin = ar->winrct.xmax + 1;
}
}
@@ -1082,6 +1100,15 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+ /* if region opened normally, we store this for hide/reveal usage */
+ /* prevent rounding errors for UI_DPI_FAC mult and divide */
+ if (ar->winx > 1) ar->sizex = (ar->winx + 0.5f) / UI_DPI_FAC;
+ if (ar->winy > 1) ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC;
+
+ /* exception for multiple overlapping regions on same spot */
+ if (ar->overlap)
+ region_overlap_fix(sa, ar);
+
/* set winrect for azones */
if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) {
ar->winrct = *remainder;
@@ -1090,9 +1117,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winrct.ymin = ar->winrct.ymax;
else if (alignment == RGN_ALIGN_BOTTOM)
ar->winrct.ymax = ar->winrct.ymin;
- else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT))
+ else if (alignment == RGN_ALIGN_RIGHT)
ar->winrct.xmin = ar->winrct.xmax;
- else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT))
+ else if (alignment == RGN_ALIGN_LEFT)
ar->winrct.xmax = ar->winrct.xmin;
else /* prevent winrct to be valid */
ar->winrct.xmax = ar->winrct.xmin;
@@ -1121,12 +1148,12 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
region_azone_add(sa, ar, alignment);
}
- region_rect_recursive(sa, ar->next, remainder, quad);
+ region_rect_recursive(win, sa, ar->next, remainder, quad);
}
static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
{
- short rt = 0; // CLAMPIS(G.debug_value, 0, 16);
+ short rt = U.pixelsize > 1.0f ? 1 : 0;
if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt;
else sa->totrct.xmin = sa->v1->vec.x;
@@ -1229,14 +1256,14 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype);
/* area sizes */
- area_calc_totrct(sa, win->sizex, win->sizey);
+ area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win));
/* clear all azones, add the area triange widgets */
area_azone_initialize(win->screen, sa);
/* region rect sizes */
rect = sa->totrct;
- region_rect_recursive(sa, sa->regionbase.first, &rect, 0);
+ region_rect_recursive(win, sa, sa->regionbase.first, &rect, 0);
/* default area handlers */
ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag);
@@ -1273,22 +1300,38 @@ void ED_region_init(bContext *C, ARegion *ar)
ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
+ /* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */
+ BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1);
+
/* UI convention */
wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
glLoadIdentity();
}
-void ED_region_toggle_hidden(bContext *C, ARegion *ar)
+/* for quick toggle, can skip fades */
+void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade)
{
ScrArea *sa = CTX_wm_area(C);
-
+
ar->flag ^= RGN_FLAG_HIDDEN;
+
+ if (do_fade && ar->overlap) {
+ /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */
+ region_blend_start(C, sa, ar);
+ }
+ else {
+ if (ar->flag & RGN_FLAG_HIDDEN)
+ WM_event_remove_handlers(C, &ar->handlers);
+
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
+ ED_area_tag_redraw(sa);
+ }
+}
- if (ar->flag & RGN_FLAG_HIDDEN)
- WM_event_remove_handlers(C, &ar->handlers);
-
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
- ED_area_tag_redraw(sa);
+/* exported to all editors, uses fading default */
+void ED_region_toggle_hidden(bContext *C, ARegion *ar)
+{
+ region_toggle_hidden(C, ar, 1);
}
/* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
@@ -1441,7 +1484,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
{
SpaceLink *sl = (sa) ? sa->spacedata.first : CTX_wm_space_data(C);
- if (sl->next) {
+ if (sl && sl->next) {
/* workaround for case of double prevspace, render window
* with a file browser on top of it */
if (sl->next->spacetype == SPACE_FILE && sl->next->next)
@@ -1515,22 +1558,22 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
{
ScrArea *sa = CTX_wm_area(C);
uiBut *but;
- int xco = 8;
+ int xco = 0.4 * U.widget_unit;
but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D,
- editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y,
+ editortype_pup(), xco, yco, 1.5 * U.widget_unit, U.widget_unit,
&(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0,
TIP_("Display current editor type (click for a menu of available types)"));
uiButSetFunc(but, spacefunc, NULL, NULL);
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- return xco + UI_UNIT_X + 14;
+ return xco + 1.7 * U.widget_unit;
}
int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
{
ScrArea *sa = CTX_wm_area(C);
- int xco = 8;
+ int xco = 0.4 * U.widget_unit;
uiBut *but;
if (!sa->full)
@@ -1541,14 +1584,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
if (sa->flag & HEADER_NO_PULLDOWN) {
but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_RIGHT,
- xco, yco, UI_UNIT_X, UI_UNIT_Y - 2,
+ xco, yco, U.widget_unit, U.widget_unit * 0.9f,
&(sa->flag), 0, 0, 0, 0,
"Show pulldown menus");
}
else {
but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_DOWN,
- xco, yco, UI_UNIT_X, UI_UNIT_Y - 2,
+ xco, yco, U.widget_unit, U.widget_unit * 0.9f,
&(sa->flag), 0, 0, 0, 0,
"Hide pulldown menus");
}
@@ -1557,7 +1600,7 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
uiBlockSetEmboss(block, UI_EMBOSS);
- return xco + UI_UNIT_X;
+ return xco + U.widget_unit;
}
/************************ standard UI regions ************************/
@@ -1565,127 +1608,162 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr)
{
ScrArea *sa = CTX_wm_area(C);
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiBlock *block;
PanelType *pt;
Panel *panel;
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
int x, y, xco, yco, w, em, triangle, open, newcontext = 0;
+ int redo;
+ int scroll;
if (contextnr >= 0)
newcontext = UI_view2d_tab_set(v2d, contextnr);
-
+
+ /* before setting the view */
if (vertical) {
- w = BLI_rctf_size_x(&v2d->cur);
- em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ /* only allow scrolling in vertical direction */
+ v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
+ v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
+ v2d->scroll &= ~(V2D_SCROLL_BOTTOM);
+ v2d->scroll |= (V2D_SCROLL_RIGHT);
}
else {
- w = UI_PANEL_WIDTH;
- em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ /* for now, allow scrolling in both directions (since layouts are optimized for vertical,
+ * they often don't fit in horizontal layout)
+ */
+ v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
+ v2d->scroll |= (V2D_SCROLL_BOTTOM);
+ v2d->scroll &= ~(V2D_SCROLL_RIGHT);
}
- /* create panels */
- uiBeginPanels(C, ar);
+ scroll = v2d->scroll;
+
+ /* sortof hack - but we cannot predict the height of panels, until it's being generated */
+ /* the layout engine works with fixed width (from v2d->cur), which is being set at end of the loop */
+ /* in case scroller settings (hide flags) differ from previous, the whole loop gets done again */
+ for (redo = 2; redo > 0; redo--) {
+
+ if (vertical) {
+ w = BLI_rctf_size_x(&v2d->cur);
+ em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ }
+ else {
+ w = UI_PANEL_WIDTH;
+ em = (ar->type->prefsizex) ? UI_UNIT_Y / 2 : UI_UNIT_Y;
+ }
+
+ /* create panels */
+ uiBeginPanels(C, ar);
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(v2d);
+ /* set view2d view matrix - uiBeginBlock() stores it */
+ UI_view2d_view_ortho(v2d);
- for (pt = ar->type->paneltypes.first; pt; pt = pt->next) {
- /* verify context */
- if (context)
- if (pt->context[0] && strcmp(context, pt->context) != 0)
- continue;
+ for (pt = ar->type->paneltypes.first; pt; pt = pt->next) {
+ /* verify context */
+ if (context)
+ if (pt->context[0] && strcmp(context, pt->context) != 0)
+ continue;
- /* draw panel */
- if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
- block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
- panel = uiBeginPanel(sa, ar, block, pt, &open);
+ /* draw panel */
+ if (pt->draw && (!pt->poll || pt->poll(C, pt))) {
+ block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
+ panel = uiBeginPanel(sa, ar, block, pt, &open);
- /* bad fixed values */
- triangle = (int)(UI_UNIT_Y * 1.1f);
+ /* bad fixed values */
+ triangle = (int)(UI_UNIT_Y * 1.1f);
- if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
- /* for enabled buttons */
- panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
- triangle, UI_UNIT_Y + style->panelspace + 2, UI_UNIT_Y, 1, style);
+ if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
+ /* for enabled buttons */
+ panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
+ triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style);
- pt->draw_header(C, panel);
+ pt->draw_header(C, panel);
- uiBlockLayoutResolve(block, &xco, &yco);
- panel->labelofs = xco - triangle;
- panel->layout = NULL;
- }
- else {
- panel->labelofs = 0;
- }
+ uiBlockLayoutResolve(block, &xco, &yco);
+ panel->labelofs = xco - triangle;
+ panel->layout = NULL;
+ }
+ else {
+ panel->labelofs = 0;
+ }
- if (open) {
- short panelContext;
-
- /* panel context can either be toolbar region or normal panels region */
- if (ar->regiontype == RGN_TYPE_TOOLS)
- panelContext = UI_LAYOUT_TOOLBAR;
- else
- panelContext = UI_LAYOUT_PANEL;
-
- panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext,
- style->panelspace, 0, w - 2 * style->panelspace, em, style);
+ if (open) {
+ short panelContext;
+
+ /* panel context can either be toolbar region or normal panels region */
+ if (ar->regiontype == RGN_TYPE_TOOLS)
+ panelContext = UI_LAYOUT_TOOLBAR;
+ else
+ panelContext = UI_LAYOUT_PANEL;
+
+ panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext,
+ style->panelspace, 0, w - 2 * style->panelspace, em, style);
- pt->draw(C, panel);
+ pt->draw(C, panel);
- uiBlockLayoutResolve(block, &xco, &yco);
- panel->layout = NULL;
+ uiBlockLayoutResolve(block, &xco, &yco);
+ panel->layout = NULL;
- yco -= 2 * style->panelspace;
- uiEndPanel(block, w, -yco);
- }
- else {
- yco = 0;
- uiEndPanel(block, w, 0);
+ yco -= 2 * style->panelspace;
+ uiEndPanel(block, w, -yco);
+ }
+ else {
+ yco = 0;
+ uiEndPanel(block, w, 0);
+ }
+
+ uiEndBlock(C, block);
}
+ }
- uiEndBlock(C, block);
+ /* align panels and return size */
+ uiEndPanels(C, ar, &x, &y);
+
+ /* before setting the view */
+ if (vertical) {
+ /* we always keep the scroll offset - so the total view gets increased with the scrolled away part */
+ if (v2d->cur.ymax < - 0.001f)
+ y = min_ii(y, v2d->cur.ymin);
+
+ y = -y;
+ }
+ else {
+ /* don't jump back when panels close or hide */
+ if (!newcontext)
+ x = max_ii(x, v2d->cur.xmax);
+ y = -y;
+ }
+
+ /* this also changes the 'cur' */
+ UI_view2d_totRect_set(v2d, x, y);
+
+ if (scroll != v2d->scroll) {
+ /* Note: this code scales fine, but because of rounding differences, positions of elements
+ * flip +1 or -1 pixel compared to redoing the entire layout again.
+ * Leaving in commented code for future tests */
+ /* uiScalePanels(ar, BLI_rctf_size_x(&v2d->cur));
+ break; */
}
+ else break;
}
-
- /* align panels and return size */
- uiEndPanels(C, ar, &x, &y);
-
- /* clear */
- UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
- glClear(GL_COLOR_BUFFER_BIT);
- /* before setting the view */
- if (vertical) {
- /* only allow scrolling in vertical direction */
- v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
- v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
-
- /* ensure tot is set correctly, to keep views on bottons, with sliders */
- y = min_ii(y, v2d->cur.ymin);
- y = -y;
+
+ /* clear */
+ if (ar->overlap) {
+ /* view should be in pixelspace */
+ UI_view2d_view_restore(C);
+ glEnable(GL_BLEND);
+ UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
+ glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+ glDisable(GL_BLEND);
}
else {
- /* for now, allow scrolling in both directions (since layouts are optimized for vertical,
- * they often don't fit in horizontal layout)
- */
- v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
- //v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X;
- //v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y);
- v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
- v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_HIDE;
-
- /* don't jump back when panels close or hide */
- if (!newcontext)
- x = max_ii(x, v2d->cur.xmax);
- y = -y;
+ UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
}
-
- /* +V2D_SCROLL_HEIGHT is workaround to set the actual height */
- UI_view2d_totRect_set(v2d, x + V2D_SCROLL_WIDTH, y + V2D_SCROLL_HEIGHT);
+
/* set the view */
UI_view2d_view_ortho(v2d);
@@ -1705,17 +1783,6 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
- /* XXX quick hacks for files saved with 2.5 already (i.e. the builtin defaults file)
- * scrollbars for button regions */
- ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
- ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- ar->v2d.scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
- ar->v2d.keepzoom |= V2D_KEEPZOOM;
-
- /* correctly initialized User-Prefs? */
- if (!(ar->v2d.align & V2D_ALIGN_NO_POS_Y))
- ar->v2d.flag &= ~V2D_IS_INITIALISED;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
@@ -1725,7 +1792,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
void ED_region_header(const bContext *C, ARegion *ar)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_GetStyleDraw();
uiBlock *block;
uiLayout *layout;
HeaderType *ht;
@@ -1740,8 +1807,8 @@ void ED_region_header(const bContext *C, ARegion *ar)
/* set view2d view matrix for scrolling (without scrollers) */
UI_view2d_view_ortho(&ar->v2d);
- xco = maxco = 8;
- yco = headery - 4;
+ xco = maxco = 0.4f * UI_UNIT_X;
+ yco = headery - floor(0.2f * UI_UNIT_Y);
/* draw all headers types */
for (ht = ar->type->headertypes.first; ht; ht = ht->next) {
@@ -1778,26 +1845,25 @@ void ED_region_header(const bContext *C, ARegion *ar)
void ED_region_header_init(ARegion *ar)
{
+ ar->v2d.flag &= ~V2D_IS_INITIALISED;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
}
/* UI_UNIT_Y is defined as U variable now, depending dpi */
int ED_area_headersize(void)
{
- return UI_UNIT_Y + 6;
+ return (int)(1.3f * UI_UNIT_Y);
}
void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha)
{
- const int header_height = 18;
- uiStyle *style = UI_GetStyle();
+ const int header_height = UI_UNIT_Y;
+ uiStyle *style = UI_GetStyleDraw();
int fontid = style->widget.uifont_id;
rcti rect;
- BLF_size(fontid, 11.0f, 72);
-
/* background box */
- rect = ar->winrct;
+ ED_region_visible_rect(ar, &rect);
rect.xmin = 0;
rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height;
@@ -1881,3 +1947,32 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
}
glEnd();
}
+
+/* If the area has overlapping regions, it returns visible rect for Region *ar */
+/* rect gets returned in local region coordinates */
+void ED_region_visible_rect(ARegion *ar, rcti *rect)
+{
+ ARegion *arn = ar;
+
+ /* allow function to be called without area */
+ while (arn->prev)
+ arn = arn->prev;
+
+ *rect = ar->winrct;
+
+ /* check if a region overlaps with the current one */
+ for (; arn; arn = arn->next) {
+ if (ar != arn && arn->overlap) {
+ if (BLI_rcti_isect(rect, &arn->winrct, NULL)) {
+ /* overlap left */
+ if (rect->xmin == arn->winrct.xmin)
+ rect->xmin = arn->winrct.xmax;
+ /* overlap right */
+ if (rect->xmax == arn->winrct.xmax)
+ rect->xmax = arn->winrct.xmin;
+ }
+ }
+ }
+ BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
+}
+
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index ce2d045..f073fdd 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -33,11 +33,13 @@
#include "MEM_guardedalloc.h"
+#include "DNA_userdef_types.h"
#include "DNA_vec_types.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
+#include "BKE_blender.h"
#include "BKE_colortools.h"
#include "BLI_math.h"
@@ -54,7 +56,7 @@
/* ******************************************** */
/* defined in BIF_gl.h */
-GLubyte stipple_halftone[128] = {
+const GLubyte stipple_halftone[128] = {
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
@@ -81,7 +83,7 @@ GLubyte stipple_halftone[128] = {
* 00000000 */
-GLubyte stipple_quarttone[128] = {
+const GLubyte stipple_quarttone[128] = {
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
@@ -92,7 +94,7 @@ GLubyte stipple_quarttone[128] = {
136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0};
-GLubyte stipple_diag_stripes_pos[128] = {
+const GLubyte stipple_diag_stripes_pos[128] = {
0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
@@ -111,7 +113,7 @@ GLubyte stipple_diag_stripes_pos[128] = {
0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f};
-GLubyte stipple_diag_stripes_neg[128] = {
+const GLubyte stipple_diag_stripes_neg[128] = {
0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
@@ -292,7 +294,10 @@ void setlinestyle(int nr)
else {
glEnable(GL_LINE_STIPPLE);
- glLineStipple(nr, 0xAAAA);
+ if (U.pixelsize > 1.0f)
+ glLineStipple(nr, 0xCCCC);
+ else
+ glLineStipple(nr, 0xAAAA);
}
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 60aad14..cca713e 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -263,6 +263,9 @@ int scredge_is_horizontal(ScrEdge *se)
ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
{
ScrEdge *se;
+ int safety = U.widget_unit / 10;
+
+ if (safety < 2) safety = 2;
for (se = sc->edgebase.first; se; se = se->next) {
if (scredge_is_horizontal(se)) {
@@ -270,7 +273,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
min = MIN2(se->v1->vec.x, se->v2->vec.x);
max = MAX2(se->v1->vec.x, se->v2->vec.x);
- if (abs(my - se->v1->vec.y) <= 2 && mx >= min && mx <= max)
+ if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max)
return se;
}
else {
@@ -278,7 +281,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
min = MIN2(se->v1->vec.y, se->v2->vec.y);
max = MAX2(se->v1->vec.y, se->v2->vec.y);
- if (abs(mx - se->v1->vec.x) <= 2 && my >= min && my <= max)
+ if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max)
return se;
}
}
@@ -428,9 +431,9 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
sc->winid = win->winid;
sv1 = screen_addvert(sc, 0, 0);
- sv2 = screen_addvert(sc, 0, win->sizey - 1);
- sv3 = screen_addvert(sc, win->sizex - 1, win->sizey - 1);
- sv4 = screen_addvert(sc, win->sizex - 1, 0);
+ sv2 = screen_addvert(sc, 0, WM_window_pixels_y(win) - 1);
+ sv3 = screen_addvert(sc, WM_window_pixels_x(win) - 1, WM_window_pixels_y(win) - 1);
+ sv4 = screen_addvert(sc, WM_window_pixels_x(win) - 1, 0);
screen_addedge(sc, sv1, sv2);
screen_addedge(sc, sv2, sv3);
@@ -628,7 +631,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
float facx, facy, tempf, min[2], max[2];
/* calculate size */
- min[0] = min[1] = 10000.0f;
+ min[0] = min[1] = 20000.0f;
max[0] = max[1] = 0.0f;
for (sv = sc->vertbase.first; sv; sv = sv->next) {
@@ -676,7 +679,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
/* make each window at least ED_area_headersize() high */
for (sa = sc->areabase.first; sa; sa = sa->next) {
- int headery = ED_area_headersize() + 1;
+ int headery = ED_area_headersize() + U.pixelsize;
if (sa->v1->vec.y + headery > sa->v2->vec.y) {
/* lower edge */
@@ -907,18 +910,18 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center)
short y1 = sa->v1->vec.y;
short x2 = sa->v3->vec.x;
short y2 = sa->v3->vec.y;
- short a, rt;
-
- rt = 0; // CLAMPIS(G.debug_value, 0, 16);
if (center == 0) {
- cpack(0x505050);
- for (a = -rt; a <= rt; a++)
- if (a != 0)
- drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, a);
+ if (U.pixelsize > 1.0f) {
+
+ glColor3ub(0x50, 0x50, 0x50);
+ glLineWidth(1.5f * U.pixelsize);
+ drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0);
+ glLineWidth(1.0f);
+ }
}
else {
- cpack(0x0);
+ glColor3ub(0, 0, 0);
drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0);
}
}
@@ -1002,10 +1005,10 @@ void ED_screen_draw(wmWindow *win)
if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa;
if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa;
if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa;
- drawscredge_area(sa, win->sizex, win->sizey, 0);
+ drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 0);
}
for (sa = win->screen->areabase.first; sa; sa = sa->next)
- drawscredge_area(sa, win->sizex, win->sizey, 1);
+ drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 1);
/* blended join arrow */
if (sa1 && sa2) {
@@ -1078,20 +1081,20 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
rcti winrct;
winrct.xmin = 0;
- winrct.xmax = win->sizex - 1;
+ winrct.xmax = WM_window_pixels_x(win) - 1;
winrct.ymin = 0;
- winrct.ymax = win->sizey - 1;
+ winrct.ymax = WM_window_pixels_y(win) - 1;
+
+ /* header size depends on DPI, let's verify */
+ screen_refresh_headersizes();
- screen_test_scale(win->screen, win->sizex, win->sizey);
+ screen_test_scale(win->screen, WM_window_pixels_x(win), WM_window_pixels_y(win));
if (win->screen->mainwin == 0)
win->screen->mainwin = wm_subwindow_open(win, &winrct);
else
wm_subwindow_position(win, win->screen->mainwin, &winrct);
- /* header size depends on DPI, let's verify */
- screen_refresh_headersizes();
-
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
@@ -1142,6 +1145,9 @@ void ED_region_exit(bContext *C, ARegion *ar)
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
+ if (ar->regiontimer)
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer);
+
CTX_wm_region_set(C, prevar);
}
@@ -1262,9 +1268,12 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
break;
}
if (sa) {
+ /* make overlap active when mouse over */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x))
+ if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
scr->subwinactive = ar->swinid;
+ break;
+ }
}
}
else
@@ -1293,6 +1302,7 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
screen_cursor_set(win, event);
}
else {
+ /* notifier invokes freeing the buttons... causing a bit too much redraws */
if (oldswin != scr->subwinactive) {
region_cursor_set(win, scr->subwinactive, TRUE);
WM_event_add_notifier(C, NC_SCREEN | ND_SUBWINACTIVE, scr);
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 86d9977..b811fc4 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -35,10 +35,11 @@
struct wmWindow;
struct Scene;
-#define AZONESPOT 12
+#define AZONESPOT (0.6f * U.widget_unit)
/* area.c */
void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space);
+void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade);
/* screen_edit.c */
ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
@@ -57,12 +58,16 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my);
struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]);
/* screen_context.c */
-int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
+int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
extern const char *screen_context_dir[]; /* doc access */
/* screendump.c */
-void SCREEN_OT_screenshot(struct wmOperatorType *ot);
-void SCREEN_OT_screencast(struct wmOperatorType *ot);
+void SCREEN_OT_screenshot(struct wmOperatorType *ot);
+void SCREEN_OT_screencast(struct wmOperatorType *ot);
+
+/* screen_ops.c */
+void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar);
+
#endif /* __SCREEN_INTERN_H__ */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 67d4af9..a22faea 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -140,9 +140,11 @@ static int screen_active_editable(bContext *C)
/* when mouse is over area-edge */
int ED_operator_screen_mainwinactive(bContext *C)
{
+ bScreen *screen;
if (CTX_wm_window(C) == NULL) return 0;
- if (CTX_wm_screen(C) == NULL) return 0;
- if (CTX_wm_screen(C)->subwinactive != CTX_wm_screen(C)->mainwin) return 0;
+ screen = CTX_wm_screen(C);
+ if (screen == NULL) return 0;
+ if (screen->subwinactive != screen->mainwin) return 0;
return 1;
}
@@ -965,7 +967,7 @@ typedef struct sAreaMoveData {
static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller)
{
ScrArea *sa;
- int areaminy = ED_area_headersize() + 1;
+ int areaminy = ED_area_headersize() + U.pixelsize; // pixelsize is used as area divider
/* we check all areas and test for free space with MINSIZE */
*bigger = *smaller = 100000;
@@ -975,18 +977,18 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller
int y1 = sa->v2->vec.y - sa->v1->vec.y - areaminy;
/* if top or down edge selected, test height */
- if (sa->v1->flag && sa->v4->flag)
+ if (sa->v1->editflag && sa->v4->editflag)
*bigger = min_ii(*bigger, y1);
- else if (sa->v2->flag && sa->v3->flag)
+ else if (sa->v2->editflag && sa->v3->editflag)
*smaller = min_ii(*smaller, y1);
}
else {
int x1 = sa->v4->vec.x - sa->v1->vec.x - AREAMINX;
/* if left or right edge selected, test width */
- if (sa->v1->flag && sa->v2->flag)
+ if (sa->v1->editflag && sa->v2->editflag)
*bigger = min_ii(*bigger, x1);
- else if (sa->v3->flag && sa->v4->flag)
+ else if (sa->v3->editflag && sa->v4->editflag)
*smaller = min_ii(*smaller, x1);
}
}
@@ -999,6 +1001,7 @@ static int area_move_init(bContext *C, wmOperator *op)
bScreen *sc = CTX_wm_screen(C);
ScrEdge *actedge;
sAreaMoveData *md;
+ ScrVert *v1;
int x, y;
/* required properties */
@@ -1017,7 +1020,9 @@ static int area_move_init(bContext *C, wmOperator *op)
else md->origval = actedge->v1->vec.x;
select_connected_scredge(sc, actedge);
- /* now all vertices with 'flag==1' are the ones that can be moved. */
+ /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */
+ for (v1 = sc->vertbase.first; v1; v1 = v1->next)
+ v1->editflag = v1->flag;
area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller);
@@ -1036,27 +1041,27 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int
delta = CLAMPIS(delta, -smaller, bigger);
for (v1 = sc->vertbase.first; v1; v1 = v1->next) {
- if (v1->flag) {
+ if (v1->editflag) {
/* that way a nice AREAGRID */
- if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < win->sizex - 1) {
+ if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) {
v1->vec.x = origval + delta;
if (delta != bigger && delta != -smaller) v1->vec.x -= (v1->vec.x % AREAGRID);
}
- if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < win->sizey - 1) {
+ if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < WM_window_pixels_y(win) - 1) {
v1->vec.y = origval + delta;
v1->vec.y += AREAGRID - 1;
v1->vec.y -= (v1->vec.y % AREAGRID);
/* prevent too small top header */
- if (v1->vec.y > win->sizey - areaminy)
- v1->vec.y = win->sizey - areaminy;
+ if (v1->vec.y > WM_window_pixels_y(win) - areaminy)
+ v1->vec.y = WM_window_pixels_y(win) - areaminy;
}
}
}
for (sa = sc->areabase.first; sa; sa = sa->next) {
- if (sa->v1->flag || sa->v2->flag || sa->v3->flag || sa->v4->flag)
+ if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag)
ED_area_tag_redraw(sa);
}
@@ -1334,10 +1339,10 @@ static int area_split_apply(bContext *C, wmOperator *op)
/* select newly created edge, prepare for moving edge */
for (sv = sc->vertbase.first; sv; sv = sv->next)
- sv->flag = 0;
+ sv->editflag = 0;
- sd->nedge->v1->flag = 1;
- sd->nedge->v2->flag = 1;
+ sd->nedge->v1->editflag = 1;
+ sd->nedge->v2->editflag = 1;
if (dir == 'h') sd->origval = sd->nedge->v1->vec.y;
else sd->origval = sd->nedge->v1->vec.x;
@@ -1720,9 +1725,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* if not set we do now, otherwise it uses type */
if (rmd->ar->sizex == 0)
- rmd->ar->sizex = rmd->ar->type->prefsizex;
+ rmd->ar->sizex = rmd->ar->winx;
if (rmd->ar->sizey == 0)
- rmd->ar->sizey = rmd->ar->type->prefsizey;
+ rmd->ar->sizey = rmd->ar->winy;
/* now copy to regionmovedata */
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
@@ -1734,7 +1739,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* limit headers to standard height for now */
if (rmd->ar->regiontype == RGN_TYPE_HEADER)
- maxsize = rmd->ar->type->prefsizey;
+ maxsize = ED_area_headersize();
else
maxsize = 1000;
@@ -1754,7 +1759,7 @@ static int region_scale_get_maxsize(RegionMoveData *rmd)
int maxsize = 0;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
- return rmd->sa->winx - UI_UNIT_X;
+ return (int) ( (rmd->sa->winx / UI_DPI_FAC) - UI_UNIT_X);
}
if (rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS) {
@@ -1786,7 +1791,7 @@ static void region_scale_validate_size(RegionMoveData *rmd)
static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd)
{
- ED_region_toggle_hidden(C, rmd->ar);
+ region_toggle_hidden(C, rmd->ar, 0);
region_scale_validate_size(rmd);
}
@@ -1803,6 +1808,9 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
delta = event->x - rmd->origx;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta;
+ /* region sizes now get multiplied */
+ delta /= UI_DPI_FAC;
+
rmd->ar->sizex = rmd->origval + delta;
CLAMP(rmd->ar->sizex, 0, rmd->maxsize);
@@ -1819,6 +1827,9 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
delta = event->y - rmd->origy;
if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) delta = -delta;
+ /* region sizes now get multiplied */
+ delta /= UI_DPI_FAC;
+
rmd->ar->sizey = rmd->origval + delta;
CLAMP(rmd->ar->sizey, 0, rmd->maxsize);
@@ -2797,7 +2808,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
}
-
/* ************** region flip operator ***************************** */
/* flip a region alignment */
@@ -3413,6 +3423,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
{
+ wmWindow *win = CTX_wm_window(C);
rcti rect;
int sizex, sizey;
@@ -3420,8 +3431,9 @@ static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *ev
sizey = 480;
/* some magic to calculate postition */
- rect.xmin = event->x + CTX_wm_window(C)->posx - sizex / 2;
- rect.ymin = event->y + CTX_wm_window(C)->posy - sizey / 2;
+ /* pixelsize: mouse coords are in U.pixelsize units :/ */
+ rect.xmin = (event->x / U.pixelsize) + win->posx - sizex / 2;
+ rect.ymin = (event->y / U.pixelsize) + win->posy - sizey / 2;
rect.xmax = rect.xmin + sizex;
rect.ymax = rect.ymin + sizey;
@@ -3506,7 +3518,7 @@ static int scene_new_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
if (type == SCE_COPY_NEW) {
- newscene = BKE_scene_add("Scene");
+ newscene = BKE_scene_add(bmain, "Scene");
}
else { /* different kinds of copying */
newscene = BKE_scene_copy(scene, type);
@@ -3583,6 +3595,149 @@ static void SCENE_OT_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* ***************** region alpha blending ***************** */
+
+/* implementation note: a disapplearing region needs at least 1 last draw with 100% backbuffer
+ texture over it- then triple buffer will clear it entirely.
+ This because flag RGN_HIDDEN is set in end - region doesnt draw at all then */
+
+typedef struct RegionAlphaInfo {
+ ScrArea *sa;
+ ARegion *ar, *child_ar; /* other region */
+ int hidden;
+} RegionAlphaInfo;
+
+#define TIMEOUT 0.2f
+#define TIMESTEP 0.04f
+
+float ED_region_blend_factor(ARegion *ar)
+{
+ /* check parent too */
+ if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) {
+ ar = ar->prev;
+ }
+
+ if (ar->regiontimer) {
+ RegionAlphaInfo *rgi = ar->regiontimer->customdata;
+ float alpha;
+
+ alpha = (float)ar->regiontimer->duration / TIMEOUT;
+ /* makes sure the blend out works 100% - without area redraws */
+ if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha;
+
+ CLAMP(alpha, 0.0f, 1.0f);
+ return alpha;
+ }
+ return 1.0f;
+}
+
+/* assumes region has running region-blend timer */
+static void region_blend_end(bContext *C, ARegion *ar, int is_running)
+{
+ RegionAlphaInfo *rgi = ar->regiontimer->customdata;
+
+ /* always send redraw */
+ ED_region_tag_redraw(ar);
+ if (rgi->child_ar)
+ ED_region_tag_redraw(rgi->child_ar);
+
+ /* if running timer was hiding, the flag toggle went wrong */
+ if (is_running) {
+ if (rgi->hidden)
+ rgi->ar->flag &= ~RGN_FLAG_HIDDEN;
+ }
+ else {
+ if (rgi->hidden) {
+ rgi->ar->flag |= rgi->hidden;
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->sa);
+ }
+ /* area decoration needs redraw in end */
+ ED_area_tag_redraw(rgi->sa);
+ }
+ WM_event_remove_timer(CTX_wm_manager(C), NULL, ar->regiontimer); /* frees rgi */
+ ar->regiontimer = NULL;
+
+}
+/* assumes that *ar itself is not a splitted version from previous region */
+void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ RegionAlphaInfo *rgi;
+
+ /* end running timer */
+ if (ar->regiontimer) {
+
+ region_blend_end(C, ar, 1);
+ }
+ rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo");
+
+ rgi->hidden = ar->flag & RGN_FLAG_HIDDEN;
+ rgi->sa = sa;
+ rgi->ar = ar;
+ ar->flag &= ~RGN_FLAG_HIDDEN;
+
+ /* blend in, reinitialize regions because it got unhidden */
+ if (rgi->hidden == 0)
+ ED_area_initialize(wm, win, sa);
+ else
+ WM_event_remove_handlers(C, &ar->handlers);
+
+ if (ar->next) {
+ if (ar->next->alignment & RGN_SPLIT_PREV) {
+ rgi->child_ar = ar->next;
+ }
+ }
+
+ /* new timer */
+ ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP);
+ ar->regiontimer->customdata = rgi;
+
+}
+
+/* timer runs in win->handlers, so it cannot use context to find area/region */
+static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+ RegionAlphaInfo *rgi;
+ wmTimer *timer = event->customdata;
+
+ /* event type is TIMERREGION, but we better check */
+ if (event->type != TIMERREGION || timer == NULL)
+ return OPERATOR_PASS_THROUGH;
+
+ rgi = timer->customdata;
+
+ /* always send redraws */
+ ED_region_tag_redraw(rgi->ar);
+ if (rgi->child_ar)
+ ED_region_tag_redraw(rgi->child_ar);
+
+ /* end timer? */
+ if (rgi->ar->regiontimer->duration > (double)TIMEOUT) {
+ region_blend_end(C, rgi->ar, 0);
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+ }
+
+ return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
+}
+
+static void SCREEN_OT_region_blend(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Region Alpha";
+ ot->idname = "SCREEN_OT_region_blend";
+ ot->description = "Blend in and out overlapping region";
+
+ /* api callbacks */
+ ot->invoke = region_blend_invoke;
+
+ /* flags */
+ ot->flag = 0;
+
+ /* properties */
+}
+
+
/* **************** Assigning operatortypes to global list, adding handlers **************** */
@@ -3615,6 +3770,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_screenshot);
WM_operatortype_append(SCREEN_OT_screencast);
WM_operatortype_append(SCREEN_OT_userpref_show);
+ WM_operatortype_append(SCREEN_OT_region_blend);
/*frame changes*/
WM_operatortype_append(SCREEN_OT_frame_offset);
@@ -3717,6 +3873,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* standard timers */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0);
+ WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index ca85daa..2982e1f 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -223,7 +223,7 @@ static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
static int screenshot_check(bContext *UNUSED(C), wmOperator *op)
{
ScreenshotData *scd = op->customdata;
- return WM_operator_filesel_ensure_ext_imtype(op, scd->im_format.imtype);
+ return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format);
}
static int screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
@@ -361,7 +361,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
char name[FILE_MAX];
int ok;
- BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, &rd.im_format, rd.scemode & R_EXTENSION, TRUE);
ibuf->rect = sj->dumprect;
ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index ae72dce..5bed31e 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
paint_cursor.c
paint_hide.c
paint_image.c
+ paint_image_2d.c
paint_mask.c
paint_ops.c
paint_stroke.c
diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript
index 21439e6..6767e06 100644
--- a/source/blender/editors/sculpt_paint/SConscript
+++ b/source/blender/editors/sculpt_paint/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index bdd73cd..d50261a 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -37,7 +37,6 @@
#include "BLI_bitmap.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
-#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
@@ -45,6 +44,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
@@ -112,8 +112,8 @@ static void partialvis_update_mesh(Object *ob,
int *vert_indices;
int any_changed = 0, any_visible = 0, totvert, i;
- BLI_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
- BLI_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
+ BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
+ BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
@@ -136,8 +136,8 @@ static void partialvis_update_mesh(Object *ob,
}
if (any_changed) {
- BLI_pbvh_node_mark_rebuild_draw(node);
- BLI_pbvh_node_fully_hidden_set(node, !any_visible);
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !any_visible);
}
}
@@ -157,11 +157,11 @@ static void partialvis_update_grids(Object *ob,
int *grid_indices, totgrid, any_changed, i;
/* get PBVH data */
- BLI_pbvh_node_get_grids(pbvh, node,
+ BKE_pbvh_node_get_grids(pbvh, node,
&grid_indices, &totgrid, NULL, NULL,
&grids, NULL);
- grid_hidden = BLI_pbvh_grid_hidden(pbvh);
- BLI_pbvh_get_grid_key(pbvh, &key);
+ grid_hidden = BKE_pbvh_grid_hidden(pbvh);
+ BKE_pbvh_get_grid_key(pbvh, &key);
sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
@@ -226,12 +226,81 @@ static void partialvis_update_grids(Object *ob,
/* mark updates if anything was hidden/shown */
if (any_changed) {
- BLI_pbvh_node_mark_rebuild_draw(node);
- BLI_pbvh_node_fully_hidden_set(node, !any_visible);
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !any_visible);
multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED);
}
}
+static void partialvis_update_bmesh_verts(BMesh *bm,
+ GHash *verts,
+ PartialVisAction action,
+ PartialVisArea area,
+ float planes[4][4],
+ int *any_changed,
+ int *any_visible)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ float *vmask = CustomData_bmesh_get(&bm->vdata,
+ v->head.data,
+ CD_PAINT_MASK);
+
+ /* hide vertex if in the hide volume */
+ if (is_effected(area, planes, v->co, *vmask)) {
+ if (action == PARTIALVIS_HIDE)
+ BM_elem_flag_enable(v, BM_ELEM_HIDDEN);
+ else
+ BM_elem_flag_disable(v, BM_ELEM_HIDDEN);
+ (*any_changed) = TRUE;
+ }
+
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ (*any_visible) = TRUE;
+ }
+}
+
+static void partialvis_update_bmesh(Object *ob,
+ PBVH *pbvh,
+ PBVHNode *node,
+ PartialVisAction action,
+ PartialVisArea area,
+ float planes[4][4])
+{
+ BMesh *bm;
+ GHash *unique, *other;
+ int any_changed = 0, any_visible = 0;
+
+ bm = BKE_pbvh_get_bmesh(pbvh);
+ unique = BKE_pbvh_bmesh_node_unique_verts(node);
+ other = BKE_pbvh_bmesh_node_other_verts(node);
+
+ sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
+
+ partialvis_update_bmesh_verts(bm,
+ unique,
+ action,
+ area,
+ planes,
+ &any_changed,
+ &any_visible);
+
+ partialvis_update_bmesh_verts(bm,
+ other,
+ action,
+ area,
+ planes,
+ &any_changed,
+ &any_visible);
+
+ if (any_changed) {
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, !any_visible);
+ }
+}
+
static void rect_from_props(rcti *rect, PointerRNA *ptr)
{
rect->xmin = RNA_int_get(ptr, "xmin");
@@ -265,22 +334,22 @@ static void get_pbvh_nodes(PBVH *pbvh,
float clip_planes[4][4],
PartialVisArea mode)
{
- BLI_pbvh_SearchCallback cb = NULL;
+ BKE_pbvh_SearchCallback cb = NULL;
/* select search callback */
switch (mode) {
case PARTIALVIS_INSIDE:
- cb = BLI_pbvh_node_planes_contain_AABB;
+ cb = BKE_pbvh_node_planes_contain_AABB;
break;
case PARTIALVIS_OUTSIDE:
- cb = BLI_pbvh_node_planes_exclude_AABB;
+ cb = BKE_pbvh_node_planes_exclude_AABB;
break;
case PARTIALVIS_ALL:
case PARTIALVIS_MASKED:
break;
}
- BLI_pbvh_search_gather(pbvh, cb, clip_planes, nodes, totnode);
+ BKE_pbvh_search_gather(pbvh, cb, clip_planes, nodes, totnode);
}
static int hide_show_exec(bContext *C, wmOperator *op)
@@ -310,7 +379,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
ob->sculpt->pbvh = pbvh;
get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area);
- pbvh_type = BLI_pbvh_type(pbvh);
+ pbvh_type = BKE_pbvh_type(pbvh);
/* start undo */
switch (action) {
@@ -330,6 +399,9 @@ static int hide_show_exec(bContext *C, wmOperator *op)
case PBVH_GRIDS:
partialvis_update_grids(ob, pbvh, nodes[i], action, area, clip_planes);
break;
+ case PBVH_BMESH:
+ partialvis_update_bmesh(ob, pbvh, nodes[i], action, area, clip_planes);
+ break;
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index b704414..d0f8e36 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -42,7 +42,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
#include "BLI_threads.h"
@@ -54,13 +53,9 @@
#include "IMB_imbuf_types.h"
#include "DNA_brush_types.h"
-#include "DNA_camera_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
#include "BKE_camera.h"
#include "BKE_context.h"
@@ -77,8 +72,7 @@
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_global.h"
-#include "BKE_deform.h"
+#include "BKE_colortools.h"
#include "BKE_tessmesh.h"
@@ -102,7 +96,6 @@
#include "RNA_enum_types.h"
#include "GPU_draw.h"
-#include "GPU_extensions.h"
#include "IMB_colormanagement.h"
@@ -3344,7 +3337,7 @@ static void project_paint_begin(ProjPaintState *ps)
tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
- if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_MASK) == 0 || mf->flag & ME_FACE_SEL)) {
+ if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
@@ -5104,7 +5097,7 @@ static int texture_paint_init(bContext *C, wmOperator *op)
}
pop->s.ob = ob;
- pop->s.do_facesel = (me->editflag & ME_EDIT_PAINT_MASK) != 0;
+ pop->s.do_facesel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
/* for non prohect paint we need */
/* fill in derived mesh */
@@ -5142,15 +5135,16 @@ static int texture_paint_init(bContext *C, wmOperator *op)
return 0;
}
}
-
- paint_brush_init_tex(pop->s.brush);
-
+
/* note, if we have no UVs on the derived mesh, then we must return here */
if (pop->mode == PAINT_MODE_3D_PROJECT) {
/* initialize all data from the context */
project_state_init(C, OBACT, &pop->ps);
-
+
+ /* needed so multiple threads don't try to initialize the brush at once (can leak memory) */
+ curvemapping_initialize(pop->ps.brush->curve);
+
paint_brush_init_tex(pop->ps.brush);
pop->ps.source = PROJ_SRC_VIEW;
@@ -5168,6 +5162,9 @@ static int texture_paint_init(bContext *C, wmOperator *op)
if (pop->ps.dm == NULL)
return 0;
}
+ else {
+ paint_brush_init_tex(pop->s.brush);
+ }
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
@@ -5237,8 +5234,6 @@ static void paint_exit(bContext *C, wmOperator *op)
if (pop->restore_projection)
settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
- paint_brush_exit_tex(pop->s.brush);
-
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
imapaint_canvas_free(&pop->s);
BKE_brush_painter_free(pop->painter);
@@ -5250,6 +5245,8 @@ static void paint_exit(bContext *C, wmOperator *op)
project_paint_end(&pop->ps);
}
else {
+ paint_brush_exit_tex(pop->s.brush);
+
/* non projection 3d paint, could move into own function of more needs adding */
if (pop->s.dm_release)
pop->s.dm->release(pop->s.dm);
@@ -5705,7 +5702,7 @@ static int image_paint_sample_color_poll(bContext *C)
if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
Mesh *me = BKE_mesh_from_object(obact);
if (me) {
- return !(me->editflag & ME_EDIT_PAINT_MASK);
+ return !(me->editflag & ME_EDIT_PAINT_FACE_SEL);
}
}
}
@@ -6041,7 +6038,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, FALSE, err_out);
+ ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
new file mode 100644
index 0000000..dd7412c
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -0,0 +1,561 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/sculpt_paint/paint_image_2d.c
+ * \ingroup bke
+ */
+//#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_brush.h"
+
+#include "BLI_math.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "RE_shader_ext.h"
+
+ /* Brush Painting for 2D image editor */
+
+typedef struct BrushPainterCache {
+ short enabled;
+
+ int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
+ short flt; /* need float imbuf? */
+ short texonly; /* no alpha, color or fallof, only texture in imbuf */
+
+ int lastsize;
+ float lastalpha;
+ float lastjitter;
+
+ ImBuf *ibuf;
+ ImBuf *texibuf;
+ ImBuf *maskibuf;
+} BrushPainterCache;
+
+struct BrushPainter {
+ Scene *scene;
+ Brush *brush;
+
+ float lastmousepos[2]; /* mouse position of last paint call */
+
+ float accumdistance; /* accumulated distance of brush since last paint op */
+ float lastpaintpos[2]; /* position of last paint op */
+ float startpaintpos[2]; /* position of first paint */
+
+ double accumtime; /* accumulated time since last paint op (airbrush) */
+ double lasttime; /* time of last update */
+
+ float lastpressure;
+
+ short firsttouch; /* first paint op */
+
+ float startsize;
+ float startalpha;
+ float startjitter;
+ float startspacing;
+
+ BrushPainterCache cache;
+};
+
+BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
+{
+ BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
+
+ painter->brush = brush;
+ painter->scene = scene;
+ painter->firsttouch = 1;
+ painter->cache.lastsize = -1; /* force ibuf create in refresh */
+
+ painter->startsize = BKE_brush_size_get(scene, brush);
+ painter->startalpha = BKE_brush_alpha_get(scene, brush);
+ painter->startjitter = brush->jitter;
+ painter->startspacing = brush->spacing;
+
+ return painter;
+}
+
+
+static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
+{
+ if (BKE_brush_use_alpha_pressure(painter->scene, brush))
+ BKE_brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
+ if (BKE_brush_use_size_pressure(painter->scene, brush))
+ BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
+ if (brush->flag & BRUSH_JITTER_PRESSURE)
+ brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
+ if (brush->flag & BRUSH_SPACING_PRESSURE)
+ brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
+}
+
+
+void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
+{
+ if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
+ ((painter->cache.texonly != texonly) && texonly))
+ {
+ if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
+ if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
+ painter->cache.ibuf = painter->cache.maskibuf = NULL;
+ painter->cache.lastsize = -1; /* force ibuf create in refresh */
+ }
+
+ if (painter->cache.flt != flt) {
+ if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
+ painter->cache.texibuf = NULL;
+ painter->cache.lastsize = -1; /* force ibuf create in refresh */
+ }
+
+ painter->cache.size = size;
+ painter->cache.flt = flt;
+ painter->cache.texonly = texonly;
+ painter->cache.enabled = 1;
+}
+
+void BKE_brush_painter_free(BrushPainter *painter)
+{
+ Brush *brush = painter->brush;
+
+ BKE_brush_size_set(painter->scene, brush, painter->startsize);
+ BKE_brush_alpha_set(painter->scene, brush, painter->startalpha);
+ brush->jitter = painter->startjitter;
+ brush->spacing = painter->startspacing;
+
+ if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
+ if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
+ if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
+ MEM_freeN(painter);
+}
+
+static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
+ int x, int y, int w, int h, int xt, int yt,
+ const float pos[2])
+{
+ Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ ImBuf *ibuf, *maskibuf, *texibuf;
+ float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
+ unsigned char *b, *m, *t, *ot = NULL;
+ int dotexold, origx = x, origy = y;
+ const int radius = BKE_brush_size_get(painter->scene, brush);
+
+ xoff = -radius + 0.5f;
+ yoff = -radius + 0.5f;
+ xoff += (int)pos[0] - (int)painter->startpaintpos[0];
+ yoff += (int)pos[1] - (int)painter->startpaintpos[1];
+
+ ibuf = painter->cache.ibuf;
+ texibuf = painter->cache.texibuf;
+ maskibuf = painter->cache.maskibuf;
+
+ dotexold = (oldtexibuf != NULL);
+
+ /* not sure if it's actually needed or it's a mistake in coords/sizes
+ * calculation in brush_painter_fixed_tex_partial_update(), but without this
+ * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
+ w = min_ii(w, ibuf->x);
+ h = min_ii(h, ibuf->y);
+
+ if (painter->cache.flt) {
+ for (; y < h; y++) {
+ bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
+ tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
+ mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;
+
+ if (dotexold)
+ otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
+
+ for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
+ if (dotexold) {
+ copy_v3_v3(tf, otf);
+ tf[3] = otf[3];
+ otf += 4;
+ }
+ else {
+ xy[0] = x + xoff;
+ xy[1] = y + yoff;
+
+ BKE_brush_sample_tex(scene, brush, xy, tf, 0);
+ }
+
+ bf[0] = tf[0] * mf[0];
+ bf[1] = tf[1] * mf[1];
+ bf[2] = tf[2] * mf[2];
+ bf[3] = tf[3] * mf[3];
+ }
+ }
+ }
+ else {
+ for (; y < h; y++) {
+ b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
+ t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
+ m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;
+
+ if (dotexold)
+ ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
+
+ for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
+ if (dotexold) {
+ t[0] = ot[0];
+ t[1] = ot[1];
+ t[2] = ot[2];
+ t[3] = ot[3];
+ ot += 4;
+ }
+ else {
+ xy[0] = x + xoff;
+ xy[1] = y + yoff;
+
+ BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
+ rgba_float_to_uchar(t, rgba);
+ }
+
+ b[0] = t[0] * m[0] / 255;
+ b[1] = t[1] * m[1] / 255;
+ b[2] = t[2] * m[2] / 255;
+ b[3] = t[3] * m[3] / 255;
+ }
+ }
+ }
+}
+
+static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, const float pos[2])
+{
+ const Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ BrushPainterCache *cache = &painter->cache;
+ ImBuf *oldtexibuf, *ibuf;
+ int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
+ const int diameter = 2 * BKE_brush_size_get(scene, brush);
+
+ imbflag = (cache->flt) ? IB_rectfloat : IB_rect;
+ if (!cache->ibuf)
+ cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
+ ibuf = cache->ibuf;
+
+ oldtexibuf = cache->texibuf;
+ cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
+
+ if (oldtexibuf) {
+ srcx = srcy = 0;
+ destx = (int)painter->lastpaintpos[0] - (int)pos[0];
+ desty = (int)painter->lastpaintpos[1] - (int)pos[1];
+ w = oldtexibuf->x;
+ h = oldtexibuf->y;
+
+ IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ }
+ else {
+ srcx = srcy = 0;
+ destx = desty = 0;
+ w = h = 0;
+ }
+
+ x1 = destx;
+ y1 = desty;
+ x2 = destx + w;
+ y2 = desty + h;
+
+ /* blend existing texture in new position */
+ if ((x1 < x2) && (y1 < y2))
+ brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
+
+ if (oldtexibuf)
+ IMB_freeImBuf(oldtexibuf);
+
+ /* sample texture in new areas */
+ if ((0 < x1) && (0 < ibuf->y))
+ brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
+ if ((x2 < ibuf->x) && (0 < ibuf->y))
+ brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
+ if ((x1 < x2) && (0 < y1))
+ brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
+ if ((x1 < x2) && (y2 < ibuf->y))
+ brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
+}
+
+static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
+{
+ const Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ BrushPainterCache *cache = &painter->cache;
+ MTex *mtex = &brush->mtex;
+ int size;
+ short flt;
+ const int diameter = 2 * BKE_brush_size_get(scene, brush);
+ const float alpha = BKE_brush_alpha_get(scene, brush);
+
+ if (diameter != cache->lastsize ||
+ alpha != cache->lastalpha ||
+ brush->jitter != cache->lastjitter)
+ {
+ if (cache->ibuf) {
+ IMB_freeImBuf(cache->ibuf);
+ cache->ibuf = NULL;
+ }
+ if (cache->maskibuf) {
+ IMB_freeImBuf(cache->maskibuf);
+ cache->maskibuf = NULL;
+ }
+
+ flt = cache->flt;
+ size = (cache->size) ? cache->size : diameter;
+
+ if (brush->flag & BRUSH_FIXED_TEX) {
+ BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
+ brush_painter_fixed_tex_partial_update(painter, pos);
+ }
+ else
+ BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
+
+ cache->lastsize = diameter;
+ cache->lastalpha = alpha;
+ cache->lastjitter = brush->jitter;
+ }
+ else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
+ int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
+ int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
+
+ if ((dx != 0) || (dy != 0))
+ brush_painter_fixed_tex_partial_update(painter, pos);
+ }
+}
+
+void BKE_brush_painter_break_stroke(BrushPainter *painter)
+{
+ painter->firsttouch = 1;
+}
+
+
+int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
+ void *user, int use_color_correction)
+{
+ Scene *scene = painter->scene;
+ Brush *brush = painter->brush;
+ int totpaintops = 0;
+
+ if (pressure == 0.0f) {
+ if (painter->lastpressure) // XXX - hack, operator misses
+ pressure = painter->lastpressure;
+ else
+ pressure = 1.0f; /* zero pressure == not using tablet */
+ }
+ if (painter->firsttouch) {
+ /* paint exactly once on first touch */
+ painter->startpaintpos[0] = pos[0];
+ painter->startpaintpos[1] = pos[1];
+
+ brush_pressure_apply(painter, brush, pressure);
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, pos, use_color_correction);
+ totpaintops += func(user, painter->cache.ibuf, pos, pos);
+
+ painter->lasttime = time;
+ painter->firsttouch = 0;
+ painter->lastpaintpos[0] = pos[0];
+ painter->lastpaintpos[1] = pos[1];
+ }
+#if 0
+ else if (painter->brush->flag & BRUSH_AIRBRUSH) {
+ float spacing, step, paintpos[2], dmousepos[2], len;
+ double starttime, curtime = time;
+
+ /* compute brush spacing adapted to brush size */
+ spacing = brush->rate; //radius*brush->spacing * 0.01f;
+
+ /* setup starting time, direction vector and accumulated time */
+ starttime = painter->accumtime;
+ sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
+ len = normalize_v2(dmousepos);
+ painter->accumtime += curtime - painter->lasttime;
+
+ /* do paint op over unpainted time distance */
+ while (painter->accumtime >= spacing) {
+ step = (spacing - starttime) * len;
+ paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
+ paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter);
+ totpaintops += func(user, painter->cache.ibuf,
+ painter->lastpaintpos, paintpos);
+
+ painter->lastpaintpos[0] = paintpos[0];
+ painter->lastpaintpos[1] = paintpos[1];
+ painter->accumtime -= spacing;
+ starttime -= spacing;
+ }
+
+ painter->lasttime = curtime;
+ }
+#endif
+ else {
+ float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
+ float t, len, press;
+ const int radius = BKE_brush_size_get(scene, brush);
+
+ /* compute brush spacing adapted to brush radius, spacing may depend
+ * on pressure, so update it */
+ brush_pressure_apply(painter, brush, painter->lastpressure);
+ spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
+
+ /* setup starting distance, direction vector and accumulated distance */
+ startdistance = painter->accumdistance;
+ sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
+ len = normalize_v2(dmousepos);
+ painter->accumdistance += len;
+
+ if (brush->flag & BRUSH_SPACE) {
+ /* do paint op over unpainted distance */
+ while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
+ step = spacing - startdistance;
+ paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
+ paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
+
+ t = step / len;
+ press = (1.0f - t) * painter->lastpressure + t * pressure;
+ brush_pressure_apply(painter, brush, press);
+ spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
+
+ BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+
+ totpaintops +=
+ func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
+
+ painter->lastpaintpos[0] = paintpos[0];
+ painter->lastpaintpos[1] = paintpos[1];
+ painter->accumdistance -= spacing;
+ startdistance -= spacing;
+ }
+ }
+ else {
+ BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+
+ totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
+
+ painter->lastpaintpos[0] = pos[0];
+ painter->lastpaintpos[1] = pos[1];
+ painter->accumdistance = 0;
+ }
+
+ /* do airbrush paint ops, based on the number of paint ops left over
+ * from regular painting. this is a temporary solution until we have
+ * accurate time stamps for mouse move events */
+ if (brush->flag & BRUSH_AIRBRUSH) {
+ double curtime = time;
+ double painttime = brush->rate * totpaintops;
+
+ painter->accumtime += curtime - painter->lasttime;
+ if (painter->accumtime <= painttime)
+ painter->accumtime = 0.0;
+ else
+ painter->accumtime -= painttime;
+
+ while (painter->accumtime >= (double)brush->rate) {
+ brush_pressure_apply(painter, brush, pressure);
+
+ BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+
+ totpaintops +=
+ func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
+ painter->accumtime -= (double)brush->rate;
+ }
+
+ painter->lasttime = curtime;
+ }
+ }
+
+ painter->lastmousepos[0] = pos[0];
+ painter->lastmousepos[1] = pos[1];
+ painter->lastpressure = pressure;
+
+ BKE_brush_alpha_set(scene, brush, painter->startalpha);
+ BKE_brush_size_set(scene, brush, painter->startsize);
+ brush->jitter = painter->startjitter;
+ brush->spacing = painter->startspacing;
+
+ return totpaintops;
+}
+
+
+/* TODO: should probably be unified with BrushPainter stuff? */
+unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
+{
+ unsigned int *texcache = NULL;
+ MTex *mtex = &br->mtex;
+ TexResult texres = {0};
+ int hasrgb, ix, iy;
+ int side = half_side * 2;
+
+ if (mtex->tex) {
+ float x, y, step = 2.0 / side, co[3];
+
+ texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
+
+ /*do normalized cannonical view coords for texture*/
+ for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
+ for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
+ co[0] = x;
+ co[1] = y;
+ co[2] = 0.0f;
+
+ /* This is copied from displace modifier code */
+ hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
+
+ /* if the texture gave an RGB value, we assume it didn't give a valid
+ * intensity, so calculate one (formula from do_material_tex).
+ * if the texture didn't give an RGB value, copy the intensity across
+ */
+ if (hasrgb & TEX_RGB)
+ texres.tin = rgb_to_grayscale(&texres.tr);
+
+ ((char *)texcache)[(iy * side + ix) * 4] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 1] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 2] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
+ }
+ }
+ }
+
+ return texcache;
+}
+
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 162e2fa..cf55c93 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -89,6 +89,12 @@ void PAINT_OT_weight_from_bones(struct wmOperatorType *ot);
void PAINT_OT_weight_sample(struct wmOperatorType *ot);
void PAINT_OT_weight_sample_group(struct wmOperatorType *ot);
+enum {
+ WPAINT_GRADIENT_TYPE_LINEAR,
+ WPAINT_GRADIENT_TYPE_RADIAL
+};
+void PAINT_OT_weight_gradient(struct wmOperatorType *ot);
+
void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 697d7c6..3cf6766 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -38,8 +38,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BLI_pbvh.h"
-
+#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
@@ -97,7 +96,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
pbvh = dm->getPBVH(ob, dm);
ob->sculpt->pbvh = pbvh;
- BLI_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
sculpt_undo_push_begin("Mask flood fill");
@@ -106,12 +105,12 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
- BLI_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) {
+ BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) {
mask_flood_fill_set_elem(vi.mask, mode, value);
- } BLI_pbvh_vertex_iter_end;
+ } BKE_pbvh_vertex_iter_end;
- BLI_pbvh_node_mark_update(nodes[i]);
- if (BLI_pbvh_type(pbvh) == PBVH_GRIDS)
+ BKE_pbvh_node_mark_update(nodes[i]);
+ if (BKE_pbvh_type(pbvh) == PBVH_GRIDS)
multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
}
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 40dcb92..e5d6a18 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -475,6 +475,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_weight_paint);
WM_operatortype_append(PAINT_OT_weight_set);
WM_operatortype_append(PAINT_OT_weight_from_bones);
+ WM_operatortype_append(PAINT_OT_weight_gradient);
WM_operatortype_append(PAINT_OT_weight_sample);
WM_operatortype_append(PAINT_OT_weight_sample_group);
@@ -647,6 +648,17 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "PAINT_OT_mask_flood_fill", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "mode", PAINT_MASK_INVERT);
+ /* Toggle dynamic topology */
+ WM_keymap_add_item(keymap, "SCULPT_OT_dynamic_topology_toggle", DKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* Dynamic-topology detail size
+ *
+ * This should be improved further, perhaps by showing a triangle
+ * grid rather than brush alpha */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", DKEY, KM_PRESS, KM_SHIFT, 0);
+ set_brush_rc_props(kmi->ptr, "sculpt", "detail_size", NULL, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
+
/* multires switch */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0);
RNA_int_set(kmi->ptr, "level", 1);
@@ -710,6 +722,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "PAINT_OT_weight_sample", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "PAINT_OT_weight_sample_group", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_gradient", LEFTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "type", WPAINT_GRADIENT_TYPE_LINEAR);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_weight_gradient", LEFTMOUSE, KM_PRESS, KM_ALT | KM_CTRL, 0)->ptr, "type", WPAINT_GRADIENT_TYPE_RADIAL);
+
WM_keymap_add_item(keymap,
"PAINT_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 9ebeb61..2f4115d 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -416,6 +416,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
if (!stroke->stroke_started) {
copy_v2_v2(stroke->last_mouse_position, sample_average.mouse);
stroke->stroke_started = stroke->test_start(C, op, sample_average.mouse);
+ BLI_assert((stroke->stroke_started & ~1) == 0); /* 0/1 */
if (stroke->stroke_started) {
stroke->smooth_stroke_cursor =
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index cb4b634..e7d13bd 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -189,7 +189,7 @@ float paint_get_tex_pixel(Brush *br, float u, float v)
/* 3D Paint */
-static void imapaint_project(Object *ob, float model[][4], float proj[][4], const float co[3], float pco[4])
+static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4])
{
copy_v3_v3(pco, co);
pco[3] = 1.0f;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 194e42e..08c26aa 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -224,7 +224,7 @@ static void do_shared_vertex_tesscol(Mesh *me)
{
/* if no mcol: do not do */
/* if tface: only the involved faces, otherwise all */
- const int use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK);
+ const int use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
MFace *mface;
int a;
short *scolmain, *scol;
@@ -284,7 +284,7 @@ static void do_shared_vertex_tesscol(Mesh *me)
static void do_shared_vertexcol(Mesh *me, int do_tessface)
{
- const int use_face_sel = (me->editflag & ME_EDIT_PAINT_MASK);
+ const int use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
MPoly *mp;
float (*scol)[4];
int i, j, has_shared = 0;
@@ -372,42 +372,49 @@ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, vgroup_active);
if (defgroup) {
- bDeformGroup *curdef;
int mirrdef;
char name[MAXBONENAME];
flip_side_name(name, defgroup->name, FALSE);
-
- if (strcmp(name, defgroup->name) != 0) {
- for (curdef = ob->defbase.first, mirrdef = 0; curdef; curdef = curdef->next, mirrdef++) {
- if (!strcmp(curdef->name, name)) {
- break;
- }
- }
-
- if (curdef == NULL) {
- int olddef = ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */
- curdef = ED_vgroup_add_name(ob, name);
- ob->actdef = olddef;
- }
-
- /* curdef should never be NULL unless this is
- * a lamp and ED_vgroup_add_name fails */
- if (curdef) {
- return mirrdef;
+ mirrdef = defgroup_name_index(ob, name);
+ if (mirrdef == -1) {
+ int olddef = ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */
+ if (ED_vgroup_add_name(ob, name)) {
+ mirrdef = BLI_countlist(&ob->defbase) - 1;
}
+ ob->actdef = olddef;
}
+
+ /* curdef should never be NULL unless this is
+ * a lamp and ED_vgroup_add_name fails */
+ return mirrdef;
}
return -1;
}
-static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
+static void free_vpaint_prev(VPaint *vp)
{
if (vp->vpaint_prev) {
MEM_freeN(vp->vpaint_prev);
vp->vpaint_prev = NULL;
+ vp->tot = 0;
}
+}
+
+static void free_wpaint_prev(VPaint *vp)
+{
+ if (vp->wpaint_prev) {
+ BKE_defvert_array_free(vp->wpaint_prev, vp->tot);
+ vp->wpaint_prev = NULL;
+ vp->tot = 0;
+ }
+}
+
+static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
+{
+ free_vpaint_prev(vp);
+
vp->tot = tot;
if (lcol == NULL || tot == 0) return;
@@ -419,20 +426,16 @@ static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
static void copy_wpaint_prev(VPaint *wp, MDeformVert *dverts, int dcount)
{
- if (wp->wpaint_prev) {
- free_dverts(wp->wpaint_prev, wp->tot);
- wp->wpaint_prev = NULL;
- }
+ free_wpaint_prev(wp);
if (dverts && dcount) {
wp->wpaint_prev = MEM_mallocN(sizeof(MDeformVert) * dcount, "wpaint prev");
wp->tot = dcount;
- copy_dverts(wp->wpaint_prev, dverts, dcount);
+ BKE_defvert_array_copy(wp->wpaint_prev, dverts, dcount);
}
}
-
void vpaint_fill(Object *ob, unsigned int paintcol)
{
Mesh *me;
@@ -447,7 +450,7 @@ void vpaint_fill(Object *ob, unsigned int paintcol)
if (!me->mloopcol) return; /* possible we can't make mcol's */
- selected = (me->editflag & ME_EDIT_PAINT_MASK);
+ selected = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
mp = me->mpoly;
for (i = 0; i < me->totpoly; i++, mp++) {
@@ -851,12 +854,15 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x
}
/* whats _dl mean? */
-static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_nor[3],
+static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3],
const float mval[2], const float brush_size_pressure)
{
float vertco[2];
- if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc->ar,
+ co, vertco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
float delta[2];
float dist_squared;
@@ -873,24 +879,23 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n
}
static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
- float vpimat[][3], const float *vert_nor,
+ float vpimat[3][3], const DMCoNo *v_co_no,
const float mval[2],
const float brush_size_pressure, const float brush_alpha_pressure)
{
- float strength = calc_vp_strength_dl(vp, vc, vert_nor, mval, brush_size_pressure);
+ float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure);
if (strength > 0.0f) {
float alpha = brush_alpha_pressure * strength;
if (vp->flag & VP_NORMALS) {
float dvec[3];
- const float *no = vert_nor + 3;
/* transpose ! */
- dvec[2] = dot_v3v3(vpimat[2], no);
+ dvec[2] = dot_v3v3(vpimat[2], v_co_no->no);
if (dvec[2] > 0.0f) {
- dvec[0] = dot_v3v3(vpimat[0], no);
- dvec[1] = dot_v3v3(vpimat[1], no);
+ dvec[0] = dot_v3v3(vpimat[0], v_co_no->no);
+ dvec[1] = dot_v3v3(vpimat[1], v_co_no->no);
alpha *= dvec[2] / len_v3(dvec);
}
@@ -1019,22 +1024,22 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
me = BKE_mesh_from_object(vc.obact);
if (me && me->dvert && vc.v3d && vc.rv3d) {
- const int use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int v_idx_best = -1;
unsigned int index;
view3d_operator_needs_opengl(C);
if (use_vert_sel) {
- if (ED_mesh_pick_vert(C, me, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) {
+ if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) {
v_idx_best = index;
}
}
else {
- if (ED_mesh_pick_face_vert(C, me, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
+ if (ED_mesh_pick_face_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
v_idx_best = index;
}
- else if (ED_mesh_pick_face(C, me, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
+ else if (ED_mesh_pick_face(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
/* this relies on knowning the internal worksings of ED_mesh_pick_face_vert() */
BKE_report(op->reports, RPT_WARNING, "The modifier used does not support deformed locations");
}
@@ -1104,7 +1109,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
if (me && me->dvert && vc.v3d && vc.rv3d && vc.obact->defbase.first) {
const int defbase_tot = BLI_countlist(&vc.obact->defbase);
- const int use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
int found = FALSE;
unsigned int index;
@@ -1115,13 +1120,13 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
view3d_operator_needs_opengl(C);
if (use_vert_sel) {
- if (ED_mesh_pick_vert(C, me, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) {
+ if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) {
MDeformVert *dvert = &me->dvert[index];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
}
}
else {
- if (ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
+ if (ED_mesh_pick_face(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) {
MPoly *mp = &me->mpoly[index];
unsigned int fidx = mp->totloop - 1;
@@ -1994,6 +1999,13 @@ static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */
else {
mesh_octree_table(NULL, NULL, NULL, 'e');
mesh_mirrtopo_table(NULL, 'e');
+
+ if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
+ BKE_mesh_flush_select_from_verts(me);
+ }
+ else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
}
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
@@ -2038,34 +2050,30 @@ struct WPaintData {
int *indexar;
int vgroup_active;
int vgroup_mirror;
- float *vertexcosnos;
+ DMCoNo *vertexcosnos;
float wpimat[3][3];
-
+
/* variables for auto normalize */
const char *vgroup_validmap; /* stores if vgroups tie to deforming bones or not */
const char *lock_flags;
int defbase_tot;
};
-static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNUSED(mouse[2]))
+/* ensure we have data on wpaint start, add if needed */
+static int wpaint_ensure_data(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- struct PaintStroke *stroke = op->customdata;
- ToolSettings *ts = scene->toolsettings;
- VPaint *wp = ts->wpaint;
Object *ob = CTX_data_active_object(C);
- struct WPaintData *wpd;
- Mesh *me;
+ Mesh *me = BKE_mesh_from_object(ob);
- float mat[4][4], imat[4][4];
-
if (scene->obedit) {
return FALSE;
}
-
- me = BKE_mesh_from_object(ob);
- if (me == NULL || me->totpoly == 0) return OPERATOR_PASS_THROUGH;
-
+
+ if (me == NULL || me->totpoly == 0) {
+ return FALSE;
+ }
+
/* if nothing was added yet, we make dverts and a vertex deform group */
if (!me->dvert) {
ED_vgroup_data_create(&me->id);
@@ -2104,6 +2112,25 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU
return FALSE;
}
+ return TRUE;
+}
+
+static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNUSED(mouse[2]))
+{
+ Scene *scene = CTX_data_scene(C);
+ struct PaintStroke *stroke = op->customdata;
+ ToolSettings *ts = scene->toolsettings;
+ VPaint *wp = ts->wpaint;
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = BKE_mesh_from_object(ob);
+ struct WPaintData *wpd;
+
+ float mat[4][4], imat[4][4];
+
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return FALSE;
+ }
+
{
/* check if we are attempting to paint onto a locked vertex group,
* and other options disallow it from doing anything useful */
@@ -2166,7 +2193,15 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
unsigned int index, totindex;
float alpha;
float mval[2];
- int use_vert_sel;
+ bool use_vert_sel;
+ bool use_face_sel;
+ bool use_depth;
+
+ MDeformWeight *(*dw_func)(MDeformVert *, const int) =
+ (brush->vertexpaint_tool == PAINT_BLEND_BLUR) ?
+ ((wp->flag & VP_ONLYVGROUP) ?
+ (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index :
+ defvert_verify_index) : NULL;
const float pressure = RNA_float_get(itemptr, "pressure");
const float brush_size_pressure = BKE_brush_size_get(scene, brush) * (BKE_brush_use_size_pressure(scene, brush) ? pressure : 1.0f);
@@ -2183,7 +2218,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
ED_region_tag_redraw(CTX_wm_region(C));
return;
}
-
+
vc = &wpd->vc;
ob = vc->obact;
me = ob->data;
@@ -2223,32 +2258,39 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
swap_m4m4(wpd->vc.rv3d->persmat, mat);
- use_vert_sel = (me->editflag & ME_EDIT_VERT_SEL) != 0;
+ use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
+ use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
+ use_depth = (vc->v3d->flag & V3D_ZBUF_SELECT);
/* which faces are involved */
- if (wp->flag & VP_AREA) {
- /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */
- me->editflag &= ~ME_EDIT_VERT_SEL;
- totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
- me->editflag |= use_vert_sel ? ME_EDIT_VERT_SEL : 0;
- }
- else {
- indexar[0] = view3d_sample_backbuf(vc, mval[0], mval[1]);
- if (indexar[0]) totindex = 1;
- else totindex = 0;
- }
+ if (use_depth) {
+ if (wp->flag & VP_AREA) {
+ /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */
+ me->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
+ totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
+ me->editflag |= use_vert_sel ? ME_EDIT_PAINT_VERT_SEL : 0;
+ }
+ else {
+ indexar[0] = view3d_sample_backbuf(vc, mval[0], mval[1]);
+ if (indexar[0]) totindex = 1;
+ else totindex = 0;
+ }
- if ((me->editflag & ME_EDIT_PAINT_MASK) && me->mpoly) {
- for (index = 0; index < totindex; index++) {
- if (indexar[index] && indexar[index] <= me->totpoly) {
- MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1);
-
- if ((mpoly->flag & ME_FACE_SEL) == 0) {
- indexar[index] = 0;
+ if (use_face_sel && me->mpoly) {
+ for (index = 0; index < totindex; index++) {
+ if (indexar[index] && indexar[index] <= me->totpoly) {
+ MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1);
+
+ if ((mpoly->flag & ME_FACE_SEL) == 0) {
+ indexar[index] = 0;
+ }
}
}
}
}
+ else {
+ indexar = NULL;
+ }
/* make sure each vertex gets treated only once */
/* and calculate filter weight */
@@ -2257,80 +2299,121 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
paintweight = 0.0f;
else
paintweight = BKE_brush_weight_get(scene, brush);
-
- for (index = 0; index < totindex; index++) {
- if (indexar[index] && indexar[index] <= me->totpoly) {
- MPoly *mpoly = me->mpoly + (indexar[index] - 1);
- MLoop *ml = me->mloop + mpoly->loopstart;
- int i;
- if (use_vert_sel) {
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- me->dvert[ml->v].flag = (me->mvert[ml->v].flag & SELECT);
+#define WP_BLUR_ACCUM(v_idx_var) \
+ { \
+ const unsigned int vidx = v_idx_var; \
+ const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); \
+ if (fac > 0.0f) { \
+ MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \
+ paintweight += dw ? (dw->weight * fac) : 0.0f; \
+ totw += fac; \
+ } \
+ } (void)0
+
+
+ if (use_depth) {
+ for (index = 0; index < totindex; index++) {
+ if (indexar[index] && indexar[index] <= me->totpoly) {
+ MPoly *mpoly = me->mpoly + (indexar[index] - 1);
+ MLoop *ml = me->mloop + mpoly->loopstart;
+ int i;
+
+ if (use_vert_sel) {
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ me->dvert[ml->v].flag = (me->mvert[ml->v].flag & SELECT);
+ }
}
- }
- else {
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- me->dvert[ml->v].flag = 1;
+ else {
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ me->dvert[ml->v].flag = 1;
+ }
}
- }
-
- if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
- MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int);
-
- if (wp->flag & VP_ONLYVGROUP)
- dw_func = (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index;
- else
- dw_func = defvert_verify_index;
-
- ml = me->mloop + mpoly->loopstart;
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- unsigned int vidx = ml->v;
- const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos + 6 * vidx, mval, brush_size_pressure);
- if (fac > 0.0f) {
- dw = dw_func(&me->dvert[vidx], wpi.vgroup_active);
- paintweight += dw ? (dw->weight * fac) : 0.0f;
- totw += fac;
+
+ if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
+ ml = me->mloop + mpoly->loopstart;
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ WP_BLUR_ACCUM(ml->v);
}
}
}
}
}
-
+ else {
+ const unsigned int totvert = me->totvert;
+ unsigned int i;
+
+ /* in the case of face selection we need to flush */
+ if (use_vert_sel || use_face_sel) {
+ for (i = 0; i < totvert; i++) {
+ me->dvert[i].flag = me->mvert[i].flag & SELECT;
+ }
+ }
+ else {
+ for (i = 0; i < totvert; i++) {
+ me->dvert[i].flag = SELECT;
+ }
+ }
+
+ if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
+ for (i = 0; i < totvert; i++) {
+ WP_BLUR_ACCUM(i);
+ }
+ }
+ }
+
+#undef WP_BLUR_ACCUM
+
+
if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
paintweight /= totw;
}
- for (index = 0; index < totindex; index++) {
+#define WP_PAINT(v_idx_var) \
+ { \
+ unsigned int vidx = v_idx_var; \
+ if (me->dvert[vidx].flag) { \
+ alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
+ mval, brush_size_pressure, brush_alpha_pressure); \
+ if (alpha) { \
+ do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \
+ } \
+ me->dvert[vidx].flag = 0; \
+ } \
+ } (void)0
+
+ if (use_depth) {
+ for (index = 0; index < totindex; index++) {
- if (indexar[index] && indexar[index] <= me->totpoly) {
- MPoly *mpoly = me->mpoly + (indexar[index] - 1);
- MLoop *ml = me->mloop + mpoly->loopstart;
- int i;
-
- for (i = 0; i < mpoly->totloop; i++, ml++) {
- unsigned int vidx = ml->v;
-
- if (me->dvert[vidx].flag) {
- alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos + 6 * vidx,
- mval, brush_size_pressure, brush_alpha_pressure);
- if (alpha) {
- do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight);
- }
- me->dvert[vidx].flag = 0;
+ if (indexar[index] && indexar[index] <= me->totpoly) {
+ MPoly *mpoly = me->mpoly + (indexar[index] - 1);
+ MLoop *ml = me->mloop + mpoly->loopstart;
+ int i;
+
+ for (i = 0; i < mpoly->totloop; i++, ml++) {
+ WP_PAINT(ml->v);
}
}
}
}
+ else {
+ const unsigned int totvert = me->totvert;
+ unsigned int i;
+
+ for (i = 0; i < totvert; i++) {
+ WP_PAINT(i);
+ }
+ }
+#undef WP_PAINT
/* *** free wpi members */
MEM_freeN((void *)wpi.defbase_sel);
- /* *** don't freeing wpi members */
+ /* *** done freeing wpi members */
swap_m4m4(vc->rv3d->persmat, mat);
-
+
DAG_id_tag_update(ob->data, 0);
ED_region_tag_redraw(vc->ar);
}
@@ -2424,7 +2507,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
}
-static int weight_paint_set_exec(bContext *C, wmOperator *UNUSED(op))
+static int weight_paint_set_exec(bContext *C, wmOperator *op)
{
struct Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
@@ -2432,6 +2515,10 @@ static int weight_paint_set_exec(bContext *C, wmOperator *UNUSED(op))
Brush *brush = paint_brush(&ts->wpaint->paint);
float vgroup_weight = BKE_brush_weight_get(scene, brush);
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return OPERATOR_CANCELLED;
+ }
+
wpaint_fill(scene->toolsettings->wpaint, obact, vgroup_weight);
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
return OPERATOR_FINISHED;
@@ -2477,6 +2564,10 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
if (ob->mode & OB_MODE_VERTEX_PAINT) {
ob->mode &= ~OB_MODE_VERTEX_PAINT;
+
+ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
}
else {
ob->mode |= OB_MODE_VERTEX_PAINT;
@@ -2548,7 +2639,7 @@ typedef struct VPaintData {
ViewContext vc;
unsigned int paintcol;
int *indexar;
- float *vertexcosnos;
+ DMCoNo *vertexcosnos;
float vpimat[3][3];
/* modify 'me->mcol' directly, since the derived mesh is drawing from this array,
@@ -2647,13 +2738,12 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
return 1;
}
-static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob,
+static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
const unsigned int index, const float mval[2],
const float brush_size_pressure, const float brush_alpha_pressure)
{
ViewContext *vc = &vpd->vc;
Brush *brush = paint_brush(&vp->paint);
- Mesh *me = BKE_mesh_from_object(ob);
MPoly *mpoly = &me->mpoly[index];
MFace *mf;
MCol *mc;
@@ -2696,7 +2786,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob,
ml = me->mloop + mpoly->loopstart;
for (i = 0; i < mpoly->totloop; i++, ml++) {
alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat,
- vpd->vertexcosnos + 6 * ml->v, mval,
+ &vpd->vertexcosnos[ml->v], mval,
brush_size_pressure, brush_alpha_pressure);
if (alpha > 0.0f) {
const int alpha_i = (int)(alpha * 255.0f);
@@ -2772,7 +2862,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
else totindex = 0;
}
- if ((me->editflag & ME_EDIT_PAINT_MASK) && me->mpoly) {
+ if ((me->editflag & ME_EDIT_PAINT_FACE_SEL) && me->mpoly) {
for (index = 0; index < totindex; index++) {
if (indexar[index] && indexar[index] <= me->totpoly) {
MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1);
@@ -2787,7 +2877,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
for (index = 0; index < totindex; index++) {
if (indexar[index] && indexar[index] <= me->totpoly) {
- vpaint_paint_poly(vp, vpd, ob, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure);
+ vpaint_paint_poly(vp, vpd, me, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure);
}
}
@@ -2929,3 +3019,260 @@ void PAINT_OT_weight_from_bones(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "Method to use for assigning weights");
}
+
+/* *** VGroups Gradient *** */
+typedef struct DMGradient_vertStore {
+ float sco[2];
+ float weight_orig;
+ enum {
+ VGRAD_STORE_NOP = 0,
+ VGRAD_STORE_DW_EXIST = (1 << 0)
+ } flag;
+} DMGradient_vertStore;
+
+typedef struct DMGradient_userData {
+ struct ARegion *ar;
+ Scene *scene;
+ Mesh *me;
+ Brush *brush;
+ const float *sco_start; /* [2] */
+ const float *sco_end; /* [2] */
+ float sco_line_div; /* store (1.0f / len_v2v2(sco_start, sco_end)) */
+ int def_nr;
+ short is_init;
+ DMGradient_vertStore *vert_cache;
+
+ /* options */
+ short use_select;
+ short type;
+ float weightpaint;
+} DMGradient_userData;
+
+static void gradientVert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ DMGradient_userData *grad_data = userData;
+ Mesh *me = grad_data->me;
+
+ if (grad_data->use_select == FALSE || (me->mvert[index].flag & SELECT)) {
+ DMGradient_vertStore *vs = &grad_data->vert_cache[index];
+
+ /* run first pass only, could be split into its own mapFunc
+ * the screen coords of the verts need to be cached because
+ * updating the mesh may move them about (entering feedback loop) */
+ if (grad_data->is_init) {
+ if (ED_view3d_project_float_object(grad_data->ar,
+ co, vs->sco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
+ /* ok */
+ MDeformVert *dv = &me->dvert[index];
+ MDeformWeight *dw;
+ dw = defvert_find_index(dv, grad_data->def_nr);
+ if (dw) {
+ vs->weight_orig = dw->weight;
+ vs->flag = VGRAD_STORE_DW_EXIST;
+ }
+ else {
+ vs->weight_orig = 0.0f;
+ vs->flag = VGRAD_STORE_NOP;
+ }
+ }
+ else {
+ /* no go */
+ copy_v2_fl(vs->sco, FLT_MAX);
+ }
+ }
+ /* end init */
+
+ if (vs->sco[0] != FLT_MAX) {
+ float alpha;
+
+ if (grad_data->type == WPAINT_GRADIENT_TYPE_LINEAR) {
+ alpha = line_point_factor_v2(vs->sco, grad_data->sco_start, grad_data->sco_end);
+ }
+ else {
+ BLI_assert(grad_data->type == WPAINT_GRADIENT_TYPE_RADIAL);
+ alpha = len_v2v2(grad_data->sco_start, vs->sco) * grad_data->sco_line_div;
+ }
+ /* no need to clamp 'alpha' yet */
+
+ /* adjust weight */
+ alpha = BKE_brush_curve_strength_clamp(grad_data->brush, alpha, 1.0f);
+
+ if (alpha != 0.0f) {
+ MDeformVert *dv = &me->dvert[index];
+ MDeformWeight *dw = defvert_verify_index(dv, grad_data->def_nr);
+ // dw->weight = alpha; // testing
+ int tool = grad_data->brush->vertexpaint_tool;
+ float testw;
+
+ /* init if we just added */
+ testw = wpaint_blend_tool(tool, vs->weight_orig, grad_data->weightpaint, alpha * grad_data->brush->alpha);
+ CLAMP(testw, 0.0f, 1.0f);
+ dw->weight = testw;
+ }
+ else {
+ MDeformVert *dv = &me->dvert[index];
+ if (vs->flag & VGRAD_STORE_DW_EXIST) {
+ /* normally we NULL check, but in this case we know it exists */
+ MDeformWeight *dw = defvert_find_index(dv, grad_data->def_nr);
+ dw->weight = vs->weight_orig;
+ }
+ else {
+ /* wasn't originally existing, remove */
+ MDeformWeight *dw = defvert_find_index(dv, grad_data->def_nr);
+ if (dw) {
+ defvert_remove_group(dv, dw);
+ }
+ }
+ }
+ }
+ }
+}
+
+static int paint_weight_gradient_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int ret = WM_gesture_straightline_modal(C, op, event);
+
+ if (ret & OPERATOR_RUNNING_MODAL) {
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { /* XXX, hardcoded */
+ /* generally crap! redo! */
+ WM_gesture_straightline_cancel(C, op);
+ ret &= ~OPERATOR_RUNNING_MODAL;
+ ret |= OPERATOR_FINISHED;
+ }
+ }
+
+ if (ret & OPERATOR_CANCELLED) {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ VPaint *wp = ts->wpaint;
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+ BKE_defvert_array_copy(me->dvert, wp->wpaint_prev, me->totvert);
+ free_wpaint_prev(wp);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+ else if (ret & OPERATOR_FINISHED) {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ VPaint *wp = ts->wpaint;
+ free_wpaint_prev(wp);
+ }
+
+ return ret;
+}
+
+static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
+{
+ wmGesture *gesture = op->customdata;
+ struct ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+ int x_start = RNA_int_get(op->ptr, "xstart");
+ int y_start = RNA_int_get(op->ptr, "ystart");
+ int x_end = RNA_int_get(op->ptr, "xend");
+ int y_end = RNA_int_get(op->ptr, "yend");
+ float sco_start[2] = {x_start, y_start};
+ float sco_end[2] = {x_end, y_end};
+
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+
+ DMGradient_userData data = {0};
+
+ if (gesture->userdata == NULL) {
+ VPaint *wp = scene->toolsettings->wpaint;
+
+ gesture->userdata = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
+ data.is_init = TRUE;
+
+ copy_wpaint_prev(wp, me->dvert, me->totvert);
+
+ /* on init only, convert face -> vert sel */
+ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+ BKE_mesh_flush_select_from_polys(me);
+ }
+
+ }
+
+ data.ar = ar;
+ data.scene = scene;
+ data.me = ob->data;
+ data.sco_start = sco_start;
+ data.sco_end = sco_end;
+ data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end);
+ data.def_nr = ob->actdef - 1;
+ data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL));
+ data.vert_cache = gesture->userdata;
+ data.type = RNA_enum_get(op->ptr, "type");
+
+ {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ VPaint *wp = ts->wpaint;
+ struct Brush *brush = paint_brush(&wp->paint);
+ data.brush = brush;
+ data.weightpaint = BKE_brush_weight_get(scene, brush);
+ }
+
+ dm->foreachMappedVert(dm, gradientVert__mapFunc, &data);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ int ret;
+
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ret = WM_gesture_straightline_invoke(C, op, event);
+ if (ret & OPERATOR_RUNNING_MODAL) {
+ struct ARegion *ar = CTX_wm_region(C);
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) { /* TODO, hardcoded, extend WM_gesture_straightline_ */
+ wmGesture *gesture = op->customdata;
+ gesture->mode = 1;
+ }
+ }
+ }
+ return ret;
+}
+
+void PAINT_OT_weight_gradient(wmOperatorType *ot)
+{
+ /* defined in DNA_space_types.h */
+ static EnumPropertyItem gradient_types[] = {
+ {WPAINT_GRADIENT_TYPE_LINEAR, "LINEAR", 0, "Linear", ""},
+ {WPAINT_GRADIENT_TYPE_RADIAL, "RADIAL", 0, "Radial", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Weight Gradient";
+ ot->idname = "PAINT_OT_weight_gradient";
+ ot->description = "Sample a line and show it in Scope panels";
+
+ /* api callbacks */
+ ot->invoke = paint_weight_gradient_invoke;
+ ot->modal = paint_weight_gradient_modal;
+ ot->exec = paint_weight_gradient_exec;
+ ot->poll = weight_paint_poll;
+ ot->cancel = WM_gesture_straightline_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ prop = RNA_def_enum(ot->srna, "type", gradient_types, 0, "Type", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);
+}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e2ed777..2dc4176 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -40,7 +40,6 @@
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
-#include "BLI_pbvh.h"
#include "BLI_threads.h"
#include "BLI_rand.h"
@@ -51,6 +50,7 @@
#include "DNA_scene_types.h"
#include "DNA_brush_types.h"
+#include "BKE_pbvh.h"
#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_cdderivedmesh.h"
@@ -65,6 +65,7 @@
#include "BKE_report.h"
#include "BKE_lattice.h" /* for armature_deform_verts */
#include "BKE_node.h"
+#include "BKE_object.h"
#include "BKE_subsurf.h"
#include "BIF_glutil.h"
@@ -86,6 +87,8 @@
#include "GPU_buffers.h"
+#include "bmesh.h"
+
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -98,8 +101,13 @@ void ED_sculpt_force_update(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (ob && (ob->mode & OB_MODE_SCULPT))
+ if (ob && (ob->mode & OB_MODE_SCULPT)) {
multires_force_update(ob);
+
+ /* Set reorder=false so that saving the file doesn't reorder
+ * the BMesh's elements */
+ sculptsession_bm_to_me(ob, FALSE);
+ }
}
float *ED_sculpt_get_last_stroke(struct Object *ob)
@@ -129,6 +137,11 @@ MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
Mesh *me = (Mesh *)ob->data;
ModifierData *md;
+ if (ob->sculpt && ob->sculpt->bm) {
+ /* can't combine multires and dynamic topology */
+ return NULL;
+ }
+
if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
/* multires can't work without displacement layer */
return NULL;
@@ -172,7 +185,8 @@ static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
Mesh *me = (Mesh *)ob->data;
MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
- if (mmd) return 0;
+ if (mmd || ob->sculpt->bm)
+ return 0;
/* non-locked shape keys could be handled in the same way as deformed mesh */
if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr)
@@ -281,12 +295,130 @@ typedef struct StrokeCache {
rcti previous_r; /* previous redraw rectangle */
} StrokeCache;
+/************** Access to original unmodified vertex data *************/
+
+typedef struct {
+ BMLog *bm_log;
+
+ SculptUndoNode *unode;
+ float (*coords)[3];
+ short (*normals)[3];
+ float *vmasks;
+
+ /* Original coordinate, normal, and mask */
+ const float *co;
+ float mask;
+ short no[3];
+} SculptOrigVertData;
+
+
+/* Initialize a SculptOrigVertData for accessing original vertex data;
+ * handles BMesh, mesh, and multires */
+static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
+ Object *ob,
+ SculptUndoNode *unode)
+{
+ SculptSession *ss = ob->sculpt;
+ BMesh *bm = ss->bm;
+
+ memset(data, 0, sizeof(*data));
+ data->unode = unode;
+
+ if (bm) {
+ data->bm_log = ss->bm_log;
+ }
+ else {
+ data->coords = data->unode->co;
+ data->normals = data->unode->no;
+ data->vmasks = data->unode->mask;
+ }
+}
+
+/* Initialize a SculptOrigVertData for accessing original vertex data;
+ * handles BMesh, mesh, and multires */
+static void sculpt_orig_vert_data_init(SculptOrigVertData *data,
+ Object *ob,
+ PBVHNode *node)
+{
+ SculptUndoNode *unode;
+ unode = sculpt_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
+ sculpt_orig_vert_data_unode_init(data, ob, unode);
+
+}
+
+/* Update a SculptOrigVertData for a particular vertex from the PBVH
+ * iterator */
+static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data,
+ PBVHVertexIter *iter)
+{
+ if (orig_data->unode->type == SCULPT_UNDO_COORDS) {
+ if (orig_data->coords) {
+ orig_data->co = orig_data->coords[iter->i];
+ }
+ else {
+ orig_data->co = BM_log_original_vert_co(orig_data->bm_log, iter->bm_vert);
+ }
+
+ if (orig_data->normals) {
+ copy_v3_v3_short(orig_data->no, orig_data->normals[iter->i]);
+ }
+ else {
+ /* TODO: log doesn't store normals yet */
+ normal_float_to_short_v3(orig_data->no, iter->bm_vert->no);
+ }
+ }
+ else if (orig_data->unode->type == SCULPT_UNDO_MASK) {
+ if (orig_data->vmasks) {
+ orig_data->mask = orig_data->vmasks[iter->i];
+ }
+ else {
+ orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert);
+ }
+ }
+}
+
+/**********************************************************************/
+
+/* Returns true if the stroke will use dynamic topology, false
+ otherwise.
+
+ Factors: some brushes like grab cannot do dynamic topology.
+ Others, like smooth, are better without. Same goes for alt-
+ key smoothing. */
+static int sculpt_stroke_dynamic_topology(const SculptSession *ss,
+ const Brush *brush)
+{
+ return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
+
+ (!ss->cache || (!ss->cache->alt_smooth)) &&
+
+ /* Requires mesh restore, which doesn't work with
+ * dynamic-topology */
+ !(brush->flag & BRUSH_ANCHORED) &&
+ !(brush->flag & BRUSH_RESTORE_MESH) &&
+
+ (!ELEM6(brush->sculpt_tool,
+ /* These brushes, as currently coded, cannot
+ * support dynamic topology */
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER,
+
+ /* These brushes could handle dynamic topology,
+ * but user feedback indicates it's better not
+ * to */
+ SCULPT_TOOL_SMOOTH,
+ SCULPT_TOOL_MASK)));
+}
/*** paint mesh ***/
-static void paint_mesh_restore_co(Sculpt *sd, SculptSession *ss)
+static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
+ const Brush *brush = paint_brush(&sd->paint);
int i;
PBVHNode **nodes;
@@ -296,31 +428,38 @@ static void paint_mesh_restore_co(Sculpt *sd, SculptSession *ss)
(void)sd; /* quied unused warning */
#endif
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
SculptUndoNode *unode;
-
- unode = sculpt_undo_get_node(nodes[n]);
+ SculptUndoType type = (brush->sculpt_tool == SCULPT_TOOL_MASK ?
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
+
+ unode = sculpt_undo_push_node(ob, nodes[n], type);
if (unode) {
PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ sculpt_orig_vert_data_unode_init(&orig_data, ob, unode);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (unode->type == SCULPT_UNDO_COORDS) {
- copy_v3_v3(vd.co, unode->co[vd.i]);
- if (vd.no) copy_v3_v3_short(vd.no, unode->no[vd.i]);
- else normal_short_to_float_v3(vd.fno, unode->no[vd.i]);
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
+ copy_v3_v3(vd.co, orig_data.co);
+ if (vd.no) copy_v3_v3_short(vd.no, orig_data.no);
+ else normal_short_to_float_v3(vd.fno, orig_data.no);
}
- else if (unode->type == SCULPT_UNDO_MASK) {
- *vd.mask = unode->mask[vd.i];
+ else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
+ *vd.mask = orig_data.mask;
}
if (vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
}
}
@@ -347,7 +486,7 @@ static int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
if (!pbvh)
return 0;
- BLI_pbvh_redraw_BB(pbvh, bb_min, bb_max);
+ BKE_pbvh_redraw_BB(pbvh, bb_min, bb_max);
/* convert 3D bounding box to screen space */
if (!paint_convert_bb_to_rect(rect,
@@ -387,7 +526,7 @@ void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar,
/* clear redraw flag from nodes */
if (pbvh)
- BLI_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL);
}
/************************ Brush Testing *******************/
@@ -405,7 +544,7 @@ static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
test->dist = 0.0f; /* just for initialize */
}
-static int sculpt_brush_test(SculptBrushTest *test, float co[3])
+static int sculpt_brush_test(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
@@ -418,7 +557,7 @@ static int sculpt_brush_test(SculptBrushTest *test, float co[3])
}
}
-static int sculpt_brush_test_sq(SculptBrushTest *test, float co[3])
+static int sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
@@ -734,7 +873,8 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
}
/* Return a multiplier for brush strength on a particular vertex. */
-static float tex_strength(SculptSession *ss, Brush *br, float point[3],
+static float tex_strength(SculptSession *ss, Brush *br,
+ const float point[3],
const float len,
const float sculpt_normal[3],
const short vno[3],
@@ -871,9 +1011,9 @@ static int sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
int i;
if (data->original)
- BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
else
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
for (i = 0; i < 3; ++i) {
if (bb_min[i] > center[i])
@@ -926,6 +1066,11 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
original = (paint_brush(&sd->paint)->sculpt_tool == SCULPT_TOOL_GRAB ?
TRUE : ss->cache->original);
+ /* In general the original coords are not available with dynamic
+ * topology */
+ if (ss->bm)
+ original = FALSE;
+
(void)sd; /* unused w/o openmp */
zero_v3(an);
@@ -942,7 +1087,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
sculpt_brush_test_init(ss, &test);
if (original) {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
float fno[3];
@@ -951,10 +1096,10 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno);
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, vd.co)) {
if (vd.no) {
@@ -968,7 +1113,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
#pragma omp critical
@@ -1210,6 +1355,71 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert)
return vmask[vert];
}
+/* Same logic as neighbor_average(), but for bmesh rather than mesh */
+static void bmesh_neighbor_average(float avg[3], BMVert *v)
+{
+ const int vfcount = BM_vert_face_count(v);
+
+ zero_v3(avg);
+
+ /* Don't modify corner vertices */
+ if (vfcount > 1) {
+ BMIter liter;
+ BMLoop *l;
+ int i, total = 0;
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BMVert *adj_v[3] = {l->prev->v, v, l->next->v};
+
+ for (i = 0; i < 3; i++) {
+ if (vfcount != 2 || BM_vert_face_count(adj_v[i]) <= 2) {
+ add_v3_v3(avg, adj_v[i]->co);
+ total++;
+ }
+ }
+ }
+
+ if (total > 0) {
+ mul_v3_fl(avg, 1.0f / total);
+ return;
+ }
+ }
+
+ copy_v3_v3(avg, v->co);
+}
+
+/* Same logic as neighbor_average_mask(), but for bmesh rather than mesh */
+static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v)
+{
+ BMIter liter;
+ BMLoop *l;
+ float avg = 0;
+ int i, total = 0;
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BMVert *adj_v[3] = {l->prev->v, v, l->next->v};
+
+ for (i = 0; i < 3; i++) {
+ BMVert *v2 = adj_v[i];
+ float *vmask = CustomData_bmesh_get(&bm->vdata,
+ v2->head.data,
+ CD_PAINT_MASK);
+ avg += (*vmask);
+ total++;
+ }
+ }
+
+ if (total > 0) {
+ return avg / (float)total;
+ }
+ else {
+ float *vmask = CustomData_bmesh_get(&bm->vdata,
+ v->head.data,
+ CD_PAINT_MASK);
+ return (*vmask);
+ }
+}
+
static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
{
Brush *brush = paint_brush(&sd->paint);
@@ -1220,7 +1430,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1248,7 +1458,48 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
+{
+ Brush *brush = paint_brush(&sd->paint);
+ PBVHVertexIter vd;
+ SculptBrushTest test;
+
+ CLAMP(bstrength, 0.0f, 1.0f);
+
+ sculpt_brush_test_init(ss, &test);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test(&test, vd.co)) {
+ const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
+ ss->cache->view_normal, vd.no, vd.fno,
+ smooth_mask ? 0 : *vd.mask);
+ if (smooth_mask) {
+ float val = bmesh_neighbor_average_mask(ss->bm, vd.bm_vert) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0, 1);
+ }
+ else {
+ float avg[3], val[3];
+
+ bmesh_neighbor_average(avg, vd.bm_vert);
+ sub_v3_v3v3(val, avg, vd.co);
+ mul_v3_fl(val, fade);
+
+ add_v3_v3(val, vd.co);
+
+ sculpt_clip(sd, ss, vd.co, val);
+ }
+
+ if (vd.mvert)
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
}
static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
@@ -1269,9 +1520,9 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
CLAMP(bstrength, 0.0f, 1.0f);
- BLI_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid,
+ BKE_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid,
NULL, &gridsize, &griddata, &gridadj);
- BLI_pbvh_get_grid_key(ss->pbvh, &key);
+ BKE_pbvh_get_grid_key(ss->pbvh, &key);
thread_num = 0;
#ifdef _OPENMP
@@ -1405,7 +1656,7 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
SculptSession *ss = ob->sculpt;
const int max_iterations = 4;
const float fract = 1.0f / max_iterations;
- PBVHType type = BLI_pbvh_type(ss->pbvh);
+ PBVHType type = BKE_pbvh_type(ss->pbvh);
int iteration, n, count;
float last;
@@ -1433,6 +1684,9 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
do_mesh_smooth_brush(sd, ss, nodes[n], strength,
smooth_mask);
break;
+ case PBVH_BMESH:
+ do_bmesh_smooth_brush(sd, ss, nodes[n], strength, smooth_mask);
+ break;
}
}
@@ -1462,7 +1716,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
float fade = tex_strength(ss, brush, vd.co, test.dist,
@@ -1474,7 +1728,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
if (vd.mvert)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
}
@@ -1514,11 +1768,11 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
/* offset vertex */
@@ -1532,7 +1786,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1570,11 +1824,11 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
/* offset vertex */
@@ -1597,7 +1851,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1614,11 +1868,11 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1633,7 +1887,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1659,26 +1913,27 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- SculptUndoNode *unode;
SculptBrushTest test;
- float (*origco)[3];
- short (*origno)[3];
+ SculptOrigVertData orig_data;
float (*proxy)[3];
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- origno = unode->no;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
- const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
- ss->cache->sculpt_normal_symm, origno[vd.i],
- NULL, vd.mask ? *vd.mask : 0.0f);
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
+ const float fade = bstrength * tex_strength(ss, brush,
+ orig_data.co,
+ test.dist,
+ ss->cache->sculpt_normal_symm,
+ orig_data.no,
+ NULL, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -1686,7 +1941,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1710,11 +1965,11 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1727,7 +1982,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1759,11 +2014,11 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1776,7 +2031,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1797,26 +2052,27 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- SculptUndoNode *unode;
SculptBrushTest test;
- float (*origco)[3];
- short (*origno)[3];
+ SculptOrigVertData orig_data;
float (*proxy)[3];
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- origno = unode->no;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
- const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
+ const float fade = bstrength * tex_strength(ss, brush,
+ orig_data.co,
+ test.dist,
ss->cache->sculpt_normal_symm,
- origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f);
+ orig_data.no,
+ NULL, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], cono, fade);
@@ -1824,7 +2080,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1850,36 +2106,37 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- SculptUndoNode *unode;
SculptBrushTest test;
- float (*origco)[3];
- short (*origno)[3];
+ SculptOrigVertData orig_data;
float (*proxy)[3];
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- origno = unode->no;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
- const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
+ const float fade = bstrength * tex_strength(ss, brush,
+ orig_data.co,
+ test.dist,
ss->cache->sculpt_normal_symm,
- origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f);
+ orig_data.no,
+ NULL, vd.mask ? *vd.mask : 0.0f);
- mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]);
- sub_v3_v3(proxy[vd.i], origco[vd.i]);
+ mul_v3_m4v3(proxy[vd.i], m, orig_data.co);
+ sub_v3_v3(proxy[vd.i], orig_data.co);
mul_v3_fl(proxy[vd.i], fade);
if (vd.mvert)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1901,25 +2158,25 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
SculptBrushTest test;
- SculptUndoNode *unode;
- float (*origco)[3], *layer_disp;
+ SculptOrigVertData orig_data;
+ float *layer_disp;
/* XXX: layer brush needs conversion to proxy but its more complicated */
- /* proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
+ /* proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
- unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
- origco = unode->co;
- if (!unode->layer_disp) {
- #pragma omp critical
- unode->layer_disp = MEM_callocN(sizeof(float) * unode->totvert, "layer disp");
- }
-
- layer_disp = unode->layer_disp;
+ sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]);
+ #pragma omp critical
+ {
+ layer_disp = BKE_pbvh_node_layer_disp_get(ss->pbvh, nodes[n]);
+ }
+
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test(&test, origco[vd.i])) {
+ sculpt_orig_vert_data_update(&orig_data, &vd);
+
+ if (sculpt_brush_test(&test, orig_data.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
ss->cache->sculpt_normal_symm,
vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
@@ -1941,7 +2198,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
add_v3_v3(val, ss->layer_co[index]);
}
else {
- add_v3_v3(val, origco[vd.i]);
+ add_v3_v3(val, orig_data.co);
}
sculpt_clip(sd, ss, vd.co, val);
@@ -1950,7 +2207,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -1967,11 +2224,11 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
@@ -1989,7 +2246,7 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2016,24 +2273,24 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
sculpt_brush_test_init(ss, &test);
if (ss->cache->original) {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
add_v3_v3(private_fc, unode->co[vd.i]);
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, vd.co)) {
add_v3_v3(private_fc, vd.co);
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
#pragma omp critical
@@ -2082,8 +2339,8 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
sculpt_brush_test_init(ss, &test);
- if (ss->cache->original) {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ if (ss->cache->original && unode->co) {
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
/* for area normal */
@@ -2097,10 +2354,10 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, vd.co)) {
/* for area normal */
@@ -2119,7 +2376,7 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob,
private_count++;
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
#pragma omp critical
@@ -2301,11 +2558,11 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
float intr[3];
@@ -2326,7 +2583,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2373,11 +2630,11 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (plane_point_side_flip(vd.co, an, fc, flip)) {
@@ -2401,7 +2658,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2475,11 +2732,11 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_cube(&test, vd.co, mat)) {
if (plane_point_side_flip(vd.co, sn, fc, flip)) {
@@ -2503,7 +2760,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2539,11 +2796,11 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (plane_point_side(vd.co, an, fc)) {
@@ -2567,7 +2824,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2603,11 +2860,11 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptBrushTest test;
float (*proxy)[3];
- proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
+ proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
sculpt_brush_test_init(ss, &test);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (!plane_point_side(vd.co, an, fc)) {
@@ -2631,7 +2888,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
}
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
}
@@ -2688,6 +2945,65 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
BKE_key_convert_from_vertcos(ob, kb, vertCos);
}
+/* Note: we do the topology update before any brush actions to avoid
+ * issues with the proxies. The size of the proxy can't change, so
+ * topology must be updated first. */
+static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush)
+{
+ SculptSession *ss = ob->sculpt;
+ SculptSearchSphereData data;
+ PBVHNode **nodes = NULL;
+ float radius;
+ int n, totnode;
+
+ /* Build a list of all nodes that are potentially within the
+ * brush's area of influence */
+ data.ss = ss;
+ data.sd = sd;
+
+ radius = ss->cache->radius * 1.25f;
+
+ data.radius_squared = radius * radius;
+ data.original = ELEM4(brush->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER);
+
+ BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+
+ /* Only act if some verts are inside the brush area */
+ if (totnode) {
+ PBVHTopologyUpdateMode mode = PBVH_Subdivide;
+
+ if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) ||
+ (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY))
+ {
+ mode |= PBVH_Collapse;
+ }
+
+ for (n = 0; n < totnode; n++) {
+ sculpt_undo_push_node(ob, nodes[n],
+ brush->sculpt_tool == SCULPT_TOOL_MASK ?
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
+ BKE_pbvh_node_mark_update(nodes[n]);
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_node_mark_topology_update(nodes[n]);
+ BKE_pbvh_bmesh_node_save_orig(nodes[n]);
+ }
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BKE_pbvh_bmesh_update_topology(ss->pbvh, mode,
+ ss->cache->location,
+ ss->cache->radius);
+ }
+
+ MEM_freeN(nodes);
+ }
+}
+
static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
{
SculptSession *ss = ob->sculpt;
@@ -2704,7 +3020,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
SCULPT_TOOL_ROTATE,
SCULPT_TOOL_THUMB,
SCULPT_TOOL_LAYER);
- BLI_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
/* Only act if some verts are inside the brush area */
if (totnode) {
@@ -2713,7 +3029,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
sculpt_undo_push_node(ob, nodes[n],
brush->sculpt_tool == SCULPT_TOOL_MASK ?
SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
}
if (brush_needs_sculpt_normal(brush))
@@ -2821,7 +3137,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
PBVHNode **nodes;
int totnode, n;
- BLI_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+ BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER)) {
/* these brushes start from original coordinates */
@@ -2835,18 +3151,25 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
int proxy_count;
float (*orco)[3];
- if (use_orco)
+ if (use_orco && !ss->bm)
orco = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS)->co;
- BLI_pbvh_node_get_proxies(nodes[n], &proxies, &proxy_count);
+ BKE_pbvh_node_get_proxies(nodes[n], &proxies, &proxy_count);
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
float val[3];
int p;
- if (use_orco)
- copy_v3_v3(val, orco[vd.i]);
+ if (use_orco) {
+ if (ss->bm) {
+ copy_v3_v3(val,
+ BM_log_original_vert_co(ss->bm_log,
+ vd.bm_vert));
+ }
+ else
+ copy_v3_v3(val, orco[vd.i]);
+ }
else
copy_v3_v3(val, vd.co);
@@ -2858,9 +3181,9 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
if (ss->modifiers_active)
sculpt_flush_pbvhvert_deform(ob, &vd);
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
- BLI_pbvh_node_free_proxies(nodes[n]);
+ BKE_pbvh_node_free_proxies(nodes[n]);
}
}
@@ -2877,7 +3200,7 @@ static void sculpt_update_keyblock(Object *ob)
/* Keyblock update happens after handling deformation caused by modifiers,
* so ss->orig_cos would be updated with new stroke */
if (ss->orig_cos) vertCos = ss->orig_cos;
- else vertCos = BLI_pbvh_get_vertCos(ss->pbvh);
+ else vertCos = BKE_pbvh_get_vertCos(ss->pbvh);
if (vertCos) {
sculpt_vertcos_to_key(ob, ss->kb, vertCos);
@@ -2905,13 +3228,13 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
if (ss->kb)
vertCos = MEM_callocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts");
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
sculpt_flush_pbvhvert_deform(ob, &vd);
@@ -2920,7 +3243,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
copy_v3_v3(vertCos[index], ss->orig_cos[index]);
}
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
if (vertCos) {
@@ -2978,7 +3301,10 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
}
+typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush);
+
static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush,
+ BrushActionFunc action,
const char symm, const int axis,
const float feather)
{
@@ -2989,7 +3315,7 @@ static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush,
const float angle = 2 * M_PI * i / sd->radial_symm[axis - 'X'];
ss->cache->radial_symmetry_pass = i;
calc_brushdata_symm(sd, ss->cache, symm, axis, angle, feather);
- do_brush_action(sd, ob, brush);
+ action(sd, ob, brush);
}
}
@@ -3006,7 +3332,8 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
multires_stitch_grids(ob);
}
-static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
+static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
+ BrushActionFunc action)
{
Brush *brush = paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
@@ -3017,7 +3344,6 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
float feather = calc_symmetry_feather(sd, ss->cache);
cache->bstrength = brush_strength(sd, cache, feather);
-
cache->symmetry = symm;
/* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
@@ -3027,23 +3353,13 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
cache->radial_symmetry_pass = 0;
calc_brushdata_symm(sd, cache, i, 0, 0, feather);
- do_brush_action(sd, ob, brush);
+ action(sd, ob, brush);
- do_radial_symmetry(sd, ob, brush, i, 'X', feather);
- do_radial_symmetry(sd, ob, brush, i, 'Y', feather);
- do_radial_symmetry(sd, ob, brush, i, 'Z', feather);
+ do_radial_symmetry(sd, ob, brush, action, i, 'X', feather);
+ do_radial_symmetry(sd, ob, brush, action, i, 'Y', feather);
+ do_radial_symmetry(sd, ob, brush, action, i, 'Z', feather);
}
}
-
- sculpt_combine_proxies(sd, ob);
-
- /* hack to fix noise texture tearing mesh */
- sculpt_fix_noise_tear(sd, ob);
-
- if (ss->modifiers_active)
- sculpt_flush_stroke_deform(sd, ob);
-
- cache->first_time = 0;
}
static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
@@ -3142,7 +3458,7 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : mesh_getVertexCos(me, NULL);
crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
- BLI_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
for (a = 0; a < me->totvert; ++a) {
invert_m3(ss->deform_imats[a]);
@@ -3152,12 +3468,12 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
else free_sculptsession_deformMats(ss);
/* if pbvh is deformed, key block is already applied to it */
- if (ss->kb && !BLI_pbvh_isDeformed(ss->pbvh)) {
+ if (ss->kb && !BKE_pbvh_isDeformed(ss->pbvh)) {
float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb);
if (vertCos) {
/* apply shape keys coordinates to PBVH */
- BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
MEM_freeN(vertCos);
}
}
@@ -3220,6 +3536,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
return "Rotate Brush";
case SCULPT_TOOL_MASK:
return "Mask Brush";
+ case SCULPT_TOOL_SIMPLIFY:
+ return "Simplify Brush";
}
return "Sculpting";
@@ -3291,7 +3609,7 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
if (ss->multires) {
int i, gridsize, array_mem_size;
- BLI_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
+ BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
&gridsize, NULL, NULL);
array_mem_size = cache->num_threads * sizeof(void *);
@@ -3406,8 +3724,9 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
ED_view3d_global_to_vector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal);
/* Initialize layer brush displacements and persistent coords */
if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
- /* not supported yet for multires */
- if (!ss->multires && !ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+ /* not supported yet for multires or dynamic topology */
+ if (!ss->multires && !ss->bm && !ss->layer_co &&
+ (brush->flag & BRUSH_PERSISTENT)) {
if (!ss->layer_co)
ss->layer_co = MEM_mallocN(sizeof(float) * 3 * ss->totvert,
"sculpt mesh vertices copy");
@@ -3721,17 +4040,26 @@ typedef struct {
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
- if (BLI_pbvh_node_get_tmin(node) < *tmin) {
+ if (BKE_pbvh_node_get_tmin(node) < *tmin) {
SculptRaycastData *srd = data_v;
float (*origco)[3] = NULL;
+ int use_origco = FALSE;
if (srd->original && srd->ss->cache) {
- /* intersect with coordinates from before we started stroke */
- SculptUndoNode *unode = sculpt_undo_get_node(node);
- origco = (unode) ? unode->co : NULL;
+ if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
+ use_origco = TRUE;
+ }
+ else {
+ /* intersect with coordinates from before we started stroke */
+ SculptUndoNode *unode = sculpt_undo_get_node(node);
+ origco = (unode) ? unode->co : NULL;
+ use_origco = origco ? TRUE : FALSE;
+ }
}
- if (BLI_pbvh_node_raycast(srd->ss->pbvh, node, origco, srd->ray_start, srd->ray_normal, &srd->dist)) {
+ if (BKE_pbvh_node_raycast(srd->ss->pbvh, node, origco, use_origco,
+ srd->ray_start, srd->ray_normal, &srd->dist))
+ {
srd->hit = 1;
*tmin = srd->dist;
}
@@ -3780,7 +4108,7 @@ int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
srd.dist = dist;
srd.hit = 0;
srd.original = (cache) ? cache->original : 0;
- BLI_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd,
+ BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd,
ray_start, ray_normal, srd.original);
copy_v3_v3(out, ray_normal);
@@ -3829,8 +4157,9 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
return 1;
}
-static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
+static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
/* Restore the mesh before continuing with anchored stroke */
@@ -3839,7 +4168,7 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
BKE_brush_use_size_pressure(ss->cache->vc->scene, brush)) ||
(brush->flag & BRUSH_RESTORE_MESH))
{
- paint_mesh_restore_co(sd, ss);
+ paint_mesh_restore_co(sd, ob);
}
}
@@ -3862,7 +4191,7 @@ static void sculpt_flush_update(bContext *C)
else {
rcti r;
- BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
if (sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r)) {
if (ss->cache)
ss->cache->previous_r = r;
@@ -3917,11 +4246,33 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
+ const Brush *brush = paint_brush(&sd->paint);
sculpt_stroke_modifiers_check(C, ob);
sculpt_update_cache_variants(C, sd, ob, stroke, itemptr);
- sculpt_restore_mesh(sd, ss);
- do_symmetrical_brush_actions(sd, ob);
+ sculpt_restore_mesh(sd, ob);
+
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
+ (ss->cache->radius /
+ (float)ss->cache->pixel_radius) *
+ (float)sd->detail_size);
+
+ if (sculpt_stroke_dynamic_topology(ss, brush)) {
+ do_symmetrical_brush_actions(sd, ob, sculpt_topology_update);
+ }
+
+ if (paint_brush(&sd->paint)->sculpt_tool != SCULPT_TOOL_SIMPLIFY)
+ do_symmetrical_brush_actions(sd, ob, do_brush_action);
+
+ sculpt_combine_proxies(sd, ob);
+
+ /* hack to fix noise texture tearing mesh */
+ sculpt_fix_noise_tear(sd, ob);
+
+ if (ss->modifiers_active)
+ sculpt_flush_stroke_deform(sd, ob);
+
+ ss->cache->first_time = FALSE;
/* Cleanup */
sculpt_flush_update(C);
@@ -3980,7 +4331,10 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_undo_push_end();
- BLI_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH)
+ BKE_pbvh_bmesh_after_stroke(ss->pbvh);
/* optimization: if there is locked key and active modifiers present in */
/* the stack, keyblock is updating at each step. otherwise we could update */
@@ -4055,7 +4409,7 @@ static int sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
if (ss->cache) {
- paint_mesh_restore_co(sd, ss);
+ paint_mesh_restore_co(sd, ob);
}
paint_stroke_cancel(C, op);
@@ -4137,6 +4491,267 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/************************** Dynamic Topology **************************/
+
+static void sculpt_dynamic_topology_triangulate(BMesh *bm)
+{
+ BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "triangulate faces=%af");
+}
+
+void sculpt_pbvh_clear(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ DerivedMesh *dm = ob->derivedFinal;
+
+ /* Clear out any existing DM and PBVH */
+ if (ss->pbvh)
+ BKE_pbvh_free(ss->pbvh);
+ ss->pbvh = NULL;
+ if (dm)
+ dm->getPBVH(NULL, dm);
+ BKE_object_free_display(ob);
+}
+
+void sculpt_update_after_dynamic_topology_toggle(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ Sculpt *sd = scene->toolsettings->sculpt;
+
+ /* Create the PBVH */
+ sculpt_update_mesh_elements(scene, sd, ob, FALSE, FALSE);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+}
+
+void sculpt_dynamic_topology_enable(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+
+ sculpt_pbvh_clear(ob);
+
+ ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
+
+ /* Create triangles-only BMesh */
+ ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
+
+ BM_mesh_bm_from_me(ss->bm, me, TRUE, ob->shapenr);
+ sculpt_dynamic_topology_triangulate(ss->bm);
+ BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
+ BM_mesh_normals_update(ss->bm, TRUE);
+
+ /* Enable dynamic topology */
+ me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
+
+ /* Enable logging for undo/redo */
+ ss->bm_log = BM_log_create(ss->bm);
+
+ /* Refresh */
+ sculpt_update_after_dynamic_topology_toggle(C);
+}
+
+/* Free the sculpt BMesh and BMLog
+ *
+ * If 'unode' is given, the BMesh's data is copied out to the unode
+ * before the BMesh is deleted so that it can be restored from */
+void sculpt_dynamic_topology_disable(bContext *C,
+ SculptUndoNode *unode)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+
+ sculpt_pbvh_clear(ob);
+
+ if (unode) {
+ /* Free all existing custom data */
+ CustomData_free(&me->vdata, me->totvert);
+ CustomData_free(&me->edata, me->totedge);
+ CustomData_free(&me->fdata, me->totface);
+ CustomData_free(&me->ldata, me->totloop);
+ CustomData_free(&me->pdata, me->totpoly);
+
+ /* Copy over stored custom data */
+ me->totvert = unode->bm_enter_totvert;
+ me->totloop = unode->bm_enter_totloop;
+ me->totpoly = unode->bm_enter_totpoly;
+ me->totedge = unode->bm_enter_totedge;
+ me->totface = 0;
+ CustomData_copy(&unode->bm_enter_vdata, &me->vdata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totvert);
+ CustomData_copy(&unode->bm_enter_edata, &me->edata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totedge);
+ CustomData_copy(&unode->bm_enter_ldata, &me->ldata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totloop);
+ CustomData_copy(&unode->bm_enter_pdata, &me->pdata, CD_MASK_MESH,
+ CD_DUPLICATE, unode->bm_enter_totpoly);
+
+ mesh_update_customdata_pointers(me, FALSE);
+ }
+ else {
+ sculptsession_bm_to_me(ob, TRUE);
+ }
+
+ BM_mesh_free(ss->bm);
+
+ /* Clear data */
+ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
+ ss->bm = NULL;
+ BM_log_free(ss->bm_log);
+ ss->bm_log = NULL;
+
+ /* Refresh */
+ sculpt_update_after_dynamic_topology_toggle(C);
+}
+
+static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->bm) {
+ sculpt_undo_push_begin("Dynamic topology disable");
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
+ sculpt_dynamic_topology_disable(C, NULL);
+ }
+ else {
+ sculpt_undo_push_begin("Dynamic topology enable");
+ sculpt_dynamic_topology_enable(C);
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+ }
+ sculpt_undo_push_end();
+
+ return OPERATOR_FINISHED;
+}
+
+static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op,
+ wmEvent *UNUSED(event))
+{
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+ SculptSession *ss = ob->sculpt;
+ const char *msg = "Dynamic-topology sculpting will not preserve"
+ "vertex colors, UVs, or other customdata";
+
+ if (!ss->bm) {
+ int i;
+
+ for (i = 0; i < CD_NUMTYPES; i++) {
+ if (!ELEM7(i, CD_MVERT, CD_MEDGE, CD_MFACE,
+ CD_MLOOP, CD_MPOLY, CD_PAINT_MASK,
+ CD_ORIGINDEX) &&
+ (CustomData_has_layer(&me->vdata, i) ||
+ CustomData_has_layer(&me->edata, i) ||
+ CustomData_has_layer(&me->fdata, i))) {
+ /* The mesh has customdata that will be lost, let the
+ * user confirm this is OK */
+ return WM_operator_confirm_message(C, op, msg);
+ }
+ }
+ }
+
+ return sculpt_dynamic_topology_toggle_exec(C, op);
+}
+
+static void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Dynamic Topology Toggle";
+ ot->idname = "SCULPT_OT_dynamic_topology_toggle";
+ ot->description = "Dynamic topology alters the mesh topology while sculpting";
+
+ /* api callbacks */
+ ot->invoke = sculpt_dynamic_topology_toggle_invoke;
+ ot->exec = sculpt_dynamic_topology_toggle_exec;
+ ot->poll = sculpt_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/************************* SCULPT_OT_optimize *************************/
+
+static int sculpt_optimize_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ sculpt_pbvh_clear(ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int sculpt_and_dynamic_topology_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ return sculpt_mode_poll(C) && ob->sculpt->bm;
+}
+
+/* The BVH gets less optimal more quickly with dynamic topology than
+ * regular sculpting. There is no doubt more clever stuff we can do to
+ * optimize it on the fly, but for now this gives the user a nicer way
+ * to recalculate it than toggling modes. */
+static void SCULPT_OT_optimize(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Optimize";
+ ot->idname = "SCULPT_OT_optimize";
+ ot->description = "Recalculate the sculpt BVH to improve performance";
+
+ /* api callbacks */
+ ot->exec = sculpt_optimize_exec;
+ ot->poll = sculpt_and_dynamic_topology_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/********************* Dynamic topology symmetrize ********************/
+
+static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+ const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = ob->sculpt;
+
+ /* To simplify undo for symmetrize, all BMesh elements are logged
+ * as deleted, then after symmetrize operation all BMesh elements
+ * are logged as added (as opposed to attempting to store just the
+ * parts that symmetrize modifies) */
+ sculpt_undo_push_begin("Dynamic topology symmetrize");
+ sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_SYMMETRIZE);
+ BM_log_before_all_removed(ss->bm, ss->bm_log);
+
+ /* Symmetrize and re-triangulate */
+ BMO_op_callf(ss->bm, BMO_FLAG_DEFAULTS,
+ "symmetrize input=%avef direction=%i",
+ sd->symmetrize_direction);
+ sculpt_dynamic_topology_triangulate(ss->bm);
+
+ /* Finish undo */
+ BM_log_all_added(ss->bm, ss->bm_log);
+ sculpt_undo_push_end();
+
+ /* Redraw */
+ sculpt_pbvh_clear(ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_symmetrize(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Symmetrize";
+ ot->idname = "SCULPT_OT_symmetrize";
+
+ /* api callbacks */
+ ot->exec = sculpt_symmetrize_exec;
+ ot->poll = sculpt_and_dynamic_topology_poll;
+}
+
/**** Toggle operator for turning sculpt mode on or off ****/
static void sculpt_init_session(Scene *scene, Object *ob)
@@ -4222,6 +4837,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
MultiresModifierData *mmd = sculpt_multires_active(scene, ob);
int flush_recalc = 0;
@@ -4234,9 +4850,16 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
if (mmd)
multires_force_update(ob);
- if (flush_recalc)
+ if (flush_recalc || (ob->sculpt && ob->sculpt->bm))
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
+ /* Dynamic topology must be disabled before exiting sculpt
+ * mode to ensure the undo stack stays in a consistent
+ * state */
+ sculpt_dynamic_topology_toggle_exec(C, NULL);
+ }
+
/* Leave sculptmode */
ob->mode &= ~OB_MODE_SCULPT;
@@ -4257,6 +4880,9 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
ts->sculpt->flags |= SCULPT_SYMM_X;
}
+ if (!ts->sculpt->detail_size)
+ ts->sculpt->detail_size = 30;
+
/* Create sculpt mode session data */
if (ob->sculpt)
free_sculptsession(ob);
@@ -4271,7 +4897,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
}
BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT);
-
+
paint_cursor_start(C, sculpt_poll);
}
@@ -4299,4 +4925,7 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_brush_stroke);
WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
WM_operatortype_append(SCULPT_OT_set_persistent_base);
+ WM_operatortype_append(SCULPT_OT_dynamic_topology_toggle);
+ WM_operatortype_append(SCULPT_OT_optimize);
+ WM_operatortype_append(SCULPT_OT_symmetrize);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index acb906e..e56962a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -38,7 +38,7 @@
#include "DNA_key_types.h"
#include "BLI_bitmap.h"
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
struct bContext;
struct Brush;
@@ -49,6 +49,7 @@ struct Object;
struct Scene;
struct Sculpt;
struct SculptStroke;
+struct SculptUndoNode;
/* Interface */
struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct Object *ob);
@@ -67,12 +68,22 @@ void free_sculptsession_deformMats(struct SculptSession *ss);
/* Stroke */
int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]);
+/* Dynamic topology */
+void sculpt_pbvh_clear(Object *ob);
+void sculpt_update_after_dynamic_topology_toggle(bContext *C);
+void sculpt_dynamic_topology_enable(struct bContext *C);
+void sculpt_dynamic_topology_disable(struct bContext *C,
+ struct SculptUndoNode *unode);
+
/* Undo */
typedef enum {
SCULPT_UNDO_COORDS,
SCULPT_UNDO_HIDDEN,
- SCULPT_UNDO_MASK
+ SCULPT_UNDO_MASK,
+ SCULPT_UNDO_DYNTOPO_BEGIN,
+ SCULPT_UNDO_DYNTOPO_END,
+ SCULPT_UNDO_DYNTOPO_SYMMETRIZE,
} SculptUndoType;
typedef struct SculptUndoNode {
@@ -101,8 +112,17 @@ typedef struct SculptUndoNode {
int *grids; /* to restore into right location */
BLI_bitmap *grid_hidden;
- /* layer brush */
- float *layer_disp;
+ /* bmesh */
+ struct BMLogEntry *bm_entry;
+ int applied;
+ CustomData bm_enter_vdata;
+ CustomData bm_enter_edata;
+ CustomData bm_enter_ldata;
+ CustomData bm_enter_pdata;
+ int bm_enter_totvert;
+ int bm_enter_totedge;
+ int bm_enter_totloop;
+ int bm_enter_totpoly;
/* shape keys */
char shapeName[sizeof(((KeyBlock *)0))->name];
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 1b3fd24..c828e8c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -65,6 +65,7 @@
#include "GPU_buffers.h"
#include "ED_sculpt.h"
+#include "bmesh.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -72,10 +73,10 @@
static void update_cb(PBVHNode *node, void *rebuild)
{
- BLI_pbvh_node_mark_update(node);
+ BKE_pbvh_node_mark_update(node);
if (*((int *)rebuild))
- BLI_pbvh_node_mark_rebuild_draw(node);
- BLI_pbvh_node_fully_hidden_set(node, 0);
+ BKE_pbvh_node_mark_rebuild_draw(node);
+ BKE_pbvh_node_fully_hidden_set(node, 0);
}
static void sculpt_undo_restore_deformed(const SculptSession *ss,
@@ -142,7 +143,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
/* pbvh uses it's own mvert array, so coords should be */
/* propagated to pbvh here */
- BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
MEM_freeN(vertCos);
}
@@ -261,6 +262,111 @@ static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode
return 1;
}
+static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ if (unode->applied) {
+ BM_log_undo(ss->bm, ss->bm_log);
+ unode->applied = FALSE;
+ }
+ else {
+ BM_log_redo(ss->bm, ss->bm_log);
+ unode->applied = TRUE;
+ }
+
+ /* A bit lame, but for now just recreate the PBVH. The alternative
+ * is to store changes to the PBVH in the undo stack. */
+ sculpt_pbvh_clear(ob);
+}
+
+/* Create empty sculpt BMesh and enable logging */
+static void sculpt_undo_bmesh_enable(Object *ob,
+ SculptUndoNode *unode)
+{
+ SculptSession *ss = ob->sculpt;
+ Mesh *me = ob->data;
+
+ sculpt_pbvh_clear(ob);
+
+ /* Create empty BMesh and enable logging */
+ ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
+ BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
+ me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
+
+ /* Restore the BMLog using saved entries */
+ ss->bm_log = BM_log_from_existing_entries_create(ss->bm,
+ unode->bm_entry);
+}
+
+static void sculpt_undo_bmesh_restore_begin(bContext *C,
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ if (unode->applied) {
+ sculpt_dynamic_topology_disable(C, unode);
+ unode->applied = FALSE;
+ }
+ else {
+ sculpt_undo_bmesh_enable(ob, unode);
+
+ /* Restore the mesh from the first log entry */
+ BM_log_redo(ss->bm, ss->bm_log);
+
+ unode->applied = TRUE;
+ }
+}
+
+static void sculpt_undo_bmesh_restore_end(bContext *C,
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ if (unode->applied) {
+ sculpt_undo_bmesh_enable(ob, unode);
+
+ /* Restore the mesh from the last log entry */
+ BM_log_undo(ss->bm, ss->bm_log);
+
+ unode->applied = FALSE;
+ }
+ else {
+ /* Disable dynamic topology sculpting */
+ sculpt_dynamic_topology_disable(C, NULL);
+ unode->applied = TRUE;
+ }
+}
+
+/* Handle all dynamic-topology updates
+ *
+ * Returns TRUE if this was a dynamic-topology undo step, otherwise
+ * returns FALSE to indicate the non-dyntopo code should run. */
+static int sculpt_undo_bmesh_restore(bContext *C,
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
+{
+ switch (unode->type) {
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
+ return TRUE;
+
+ case SCULPT_UNDO_DYNTOPO_END:
+ sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
+ return TRUE;
+
+ default:
+ if (ss->bm_log) {
+ sculpt_undo_bmesh_restore_generic(unode, ob, ss);
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
static void sculpt_undo_restore(bContext *C, ListBase *lb)
{
Scene *scene = CTX_data_scene(C);
@@ -289,6 +395,9 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
/* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */
dm = mesh_get_derived_final(scene, ob, 0);
+ if (lb->first && sculpt_undo_bmesh_restore(C, lb->first, ob, ss))
+ return;
+
for (unode = lb->first; unode; unode = unode->next) {
if (!(strcmp(unode->idname, ob->id.name) == 0))
continue;
@@ -306,9 +415,6 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
continue;
}
}
- else {
- continue;
- }
switch (unode->type) {
case SCULPT_UNDO_COORDS:
@@ -323,6 +429,12 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
if (sculpt_undo_restore_mask(C, dm, unode))
update = TRUE;
break;
+
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ BLI_assert(!"Dynamic topology should've already been handled");
+ break;
}
}
@@ -331,8 +443,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
/* we update all nodes still, should be more clever, but also
* needs to work correct when exiting/entering sculpt mode and
* the nodes get recreated, though in that case it could do all */
- BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
- BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
+ BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
if ((mmd = sculpt_multires_active(scene, ob))) {
if (rebuild)
@@ -374,8 +486,6 @@ static void sculpt_undo_free(ListBase *lb)
MEM_freeN(unode->index);
if (unode->grids)
MEM_freeN(unode->grids);
- if (unode->layer_disp)
- MEM_freeN(unode->layer_disp);
if (unode->orig_co)
MEM_freeN(unode->orig_co);
if (unode->vert_hidden)
@@ -389,6 +499,17 @@ static void sculpt_undo_free(ListBase *lb)
}
if (unode->mask)
MEM_freeN(unode->mask);
+ if (unode->bm_entry) {
+ BM_log_entry_drop(unode->bm_entry);
+ }
+ if (unode->bm_enter_totvert)
+ CustomData_free(&unode->bm_enter_vdata, unode->bm_enter_totvert);
+ if (unode->bm_enter_totedge)
+ CustomData_free(&unode->bm_enter_edata, unode->bm_enter_totedge);
+ if (unode->bm_enter_totloop)
+ CustomData_free(&unode->bm_enter_ldata, unode->bm_enter_totloop);
+ if (unode->bm_enter_totpoly)
+ CustomData_free(&unode->bm_enter_pdata, unode->bm_enter_totpoly);
}
}
@@ -410,9 +531,9 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh,
BLI_bitmap *grid_hidden;
int i, *grid_indices, totgrid;
- grid_hidden = BLI_pbvh_grid_hidden(pbvh);
+ grid_hidden = BKE_pbvh_grid_hidden(pbvh);
- BLI_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
+ BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
NULL, NULL, NULL, NULL);
unode->grid_hidden = MEM_mapallocN(sizeof(BLI_bitmap) * totgrid,
@@ -439,11 +560,13 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
unode->type = type;
unode->node = node;
- BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
- BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
- &maxgrid, &gridsize, NULL, NULL);
+ if (node) {
+ BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
+ BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
+ &maxgrid, &gridsize, NULL, NULL);
- unode->totvert = totvert;
+ unode->totvert = totvert;
+ }
/* we will use this while sculpting, is mapalloc slow to access then? */
@@ -468,6 +591,11 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
unode->mask = MEM_mapallocN(sizeof(float) * allvert, "SculptUndoNode.mask");
undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float) * sizeof(int)) * allvert);
break;
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ BLI_assert(!"Dynamic topology should've already been handled");
+ break;
}
BLI_addtail(lb, unode);
@@ -496,7 +624,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
SculptSession *ss = ob->sculpt;
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
{
copy_v3_v3(unode->co[vd.i], vd.co);
if (vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no);
@@ -505,7 +633,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
if (ss->modifiers_active)
copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
@@ -521,8 +649,8 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
int *vert_indices, allvert;
int i;
- BLI_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
- BLI_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
+ BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
+ BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
for (i = 0; i < allvert; i++) {
BLI_BITMAP_MODIFY(unode->vert_hidden, i,
mvert[vert_indices[i]].flag & ME_HIDE);
@@ -535,11 +663,85 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
SculptSession *ss = ob->sculpt;
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
{
unode->mask[vd.i] = *vd.mask;
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
+}
+
+static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
+ PBVHNode *node,
+ SculptUndoType type)
+{
+ ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
+ SculptUndoNode *unode = lb->first;
+ SculptSession *ss = ob->sculpt;
+ PBVHVertexIter vd;
+
+ if (!lb->first) {
+ unode = MEM_callocN(sizeof(*unode), AT);
+
+ BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
+ unode->type = type;
+ unode->applied = TRUE;
+
+ if (type == SCULPT_UNDO_DYNTOPO_END) {
+ unode->bm_entry = BM_log_entry_add(ss->bm_log);
+ BM_log_before_all_removed(ss->bm, ss->bm_log);
+ }
+ else if (type == SCULPT_UNDO_DYNTOPO_BEGIN) {
+ Mesh *me = ob->data;
+
+ /* Store a copy of the mesh's current vertices, loops, and
+ * polys. A full copy like this is needed because entering
+ * dynamic-topology immediately does topological edits
+ * (converting polys to triangles) that the BMLog can't
+ * fully restore from */
+ CustomData_copy(&me->vdata, &unode->bm_enter_vdata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totvert);
+ CustomData_copy(&me->edata, &unode->bm_enter_edata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totedge);
+ CustomData_copy(&me->ldata, &unode->bm_enter_ldata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totloop);
+ CustomData_copy(&me->pdata, &unode->bm_enter_pdata, CD_MASK_MESH,
+ CD_DUPLICATE, me->totpoly);
+ unode->bm_enter_totvert = me->totvert;
+ unode->bm_enter_totedge = me->totedge;
+ unode->bm_enter_totloop = me->totloop;
+ unode->bm_enter_totpoly = me->totpoly;
+
+ unode->bm_entry = BM_log_entry_add(ss->bm_log);
+ BM_log_all_added(ss->bm, ss->bm_log);
+ }
+ else {
+ unode->bm_entry = BM_log_entry_add(ss->bm_log);
+ }
+
+ BLI_addtail(lb, unode);
+ }
+
+ if (node) {
+ switch (type) {
+ case SCULPT_UNDO_COORDS:
+ case SCULPT_UNDO_HIDDEN:
+ case SCULPT_UNDO_MASK:
+ /* Before any vertex values get modified, ensure their
+ * original positions are logged */
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
+ BM_log_vert_before_modified(ss->bm, ss->bm_log, vd.bm_vert);
+ }
+ BKE_pbvh_vertex_iter_end;
+ break;
+
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ break;
+ }
+ }
+
+ return unode;
}
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
@@ -551,7 +753,18 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
/* list is manipulated by multiple threads, so we lock */
BLI_lock_thread(LOCK_CUSTOM1);
- if ((unode = sculpt_undo_get_node(node))) {
+ if (ss->bm ||
+ ELEM(type,
+ SCULPT_UNDO_DYNTOPO_BEGIN,
+ SCULPT_UNDO_DYNTOPO_END))
+ {
+ /* Dynamic topology stores only one undo node per stroke,
+ * regardless of the number of PBVH nodes modified */
+ unode = sculpt_undo_bmesh_push(ob, node, type);
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return unode;
+ }
+ else if ((unode = sculpt_undo_get_node(node))) {
BLI_unlock_thread(LOCK_CUSTOM1);
return unode;
}
@@ -564,14 +777,14 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
if (unode->grids) {
int totgrid, *grids;
- BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
+ BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
NULL, NULL, NULL, NULL);
memcpy(unode->grids, grids, sizeof(int) * totgrid);
}
else {
int *vert_indices, allvert;
- BLI_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
- BLI_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
+ BKE_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
+ BKE_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
memcpy(unode->index, vert_indices, sizeof(int) * unode->totvert);
}
@@ -585,6 +798,11 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
case SCULPT_UNDO_MASK:
sculpt_undo_store_mask(ob, unode);
break;
+ case SCULPT_UNDO_DYNTOPO_BEGIN:
+ case SCULPT_UNDO_DYNTOPO_END:
+ case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+ BLI_assert(!"Dynamic topology should've already been handled");
+ break;
}
/* store active shape key */
@@ -612,10 +830,8 @@ void sculpt_undo_push_end(void)
unode->no = NULL;
}
- if (unode->layer_disp) {
- MEM_freeN(unode->layer_disp);
- unode->layer_disp = NULL;
- }
+ if (unode->node)
+ BKE_pbvh_node_layer_disp_free(unode->node);
}
undo_paint_push_end(UNDO_PAINT_MESH);
diff --git a/source/blender/editors/sound/SConscript b/source/blender/editors/sound/SConscript
index e17bccd..1eaf9c2 100644
--- a/source/blender/editors/sound/SConscript
+++ b/source/blender/editors/sound/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_action/SConscript b/source/blender/editors/space_action/SConscript
index 0fee8ff..abaf615 100644
--- a/source/blender/editors/space_action/SConscript
+++ b/source/blender/editors/space_action/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 9bd7d2a..4b1954c 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -82,13 +82,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Update max-extent of channels here (taking into account scrollers):
- * - this is done to allow the channel list to be scrollable, but must be done here
- * to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
- * start of list offset, and the second is as a correction for the scrollers.
- */
- height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT * 2));
+ height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT));
if (height > BLI_rcti_size_y(&v2d->mask)) {
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
@@ -199,13 +193,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Update max-extent of channels here (taking into account scrollers):
- * - this is done to allow the channel list to be scrollable, but must be done here
- * to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
- * start of list offset, and the second is as a correction for the scrollers.
- */
- height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT * 2));
+ height = ((items * ACHANNEL_STEP) + (ACHANNEL_HEIGHT));
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index c5f3cce..e0ca589 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -219,6 +219,9 @@ static void action_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ /* ensure the 2d view sync works - main region has bottom scroller */
+ ar->v2d.scroll = V2D_SCROLL_BOTTOM;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
@@ -231,7 +234,6 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar)
/* draw entirely, view changes should be handled here */
bAnimContext ac;
View2D *v2d = &ar->v2d;
- View2DScrollers *scrollers;
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
@@ -247,10 +249,7 @@ static void action_channel_area_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
- /* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ /* no scrollers here */
}
diff --git a/source/blender/editors/space_api/SConscript b/source/blender/editors/space_api/SConscript
index 9b818b0..a07be05 100644
--- a/source/blender/editors/space_api/SConscript
+++ b/source/blender/editors/space_api/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript
index 92579b6..5250a12 100644
--- a/source/blender/editors/space_buttons/SConscript
+++ b/source/blender/editors/space_buttons/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index abfefba..935b15f 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -358,7 +358,17 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS
}
/* create button */
- BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name);
+ if (user->prop) {
+ PointerRNA texptr = RNA_property_pointer_get(&user->ptr, user->prop);
+ Tex *tex = texptr.data;
+
+ if (tex)
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s - %s", user->name, tex->id.name + 2);
+ else
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name);
+ }
+ else
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name);
but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "");
diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript
index c9c82ae..2cbefee 100644
--- a/source/blender/editors/space_clip/SConscript
+++ b/source/blender/editors/space_clip/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 969b0e2..2cb6d8c 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -78,6 +78,7 @@ void ED_clip_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil");
strcpy(pt->idname, "CLIP_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
pt->flag |= PNL_DEFAULT_CLOSED;
pt->poll = clip_grease_pencil_panel_poll;
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 9cf389c..56f2998 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -103,11 +103,11 @@ static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int wid
if (width == 1) {
glBegin(GL_LINES);
glVertex2i(x, 0);
- glVertex2i(x, height);
+ glVertex2i(x, height * UI_DPI_FAC);
glEnd();
}
else {
- glRecti(x, 0, x + width, height);
+ glRecti(x, 0, x + width, height * UI_DPI_FAC);
}
}
@@ -125,7 +125,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
/* cache background */
glColor4ub(128, 128, 255, 64);
- glRecti(0, 0, ar->winx, 8);
+ glRecti(0, 0, ar->winx, 8 * UI_DPI_FAC);
/* cached segments -- could be usefu lto debug caching strategies */
BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
@@ -138,7 +138,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
- glRecti(x1, 0, x2, 8);
+ glRecti(x1, 0, x2, 8 * UI_DPI_FAC);
}
}
@@ -175,7 +175,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
else
glColor4ub(255, 255, 0, 96);
- glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4);
+ glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
}
}
}
@@ -203,7 +203,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
}
if (!ok)
- glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8);
+ glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
}
}
@@ -213,9 +213,9 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
UI_ThemeColor(TH_CFRAME);
- glRecti(x, 0, x + ceilf(framelen), 8);
+ glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
- clip_draw_curfra_label(sc->user.framenr, x, 8.0f);
+ clip_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
/* solver keyframes */
glColor4ub(175, 255, 0, 255);
@@ -796,11 +796,11 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo
dy = 6.0f / height / sc->zoom;
side = get_shortest_pattern_side(marker);
- patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f);
- patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f);
+ patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC;
+ patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC;
- searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f);
- searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f);
+ searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC;
+ searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC;
px[0] = 1.0f / sc->zoom / width / sc->scale;
px[1] = 1.0f / sc->zoom / height / sc->scale;
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 3088243..04154a2 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -82,7 +82,7 @@ int ED_space_clip_view_clip_poll(bContext *C)
{
SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc && sc->clip) {
+ if (sc) {
return sc->view == SC_VIEW_CLIP;
}
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index d33f77c..432032e 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -43,10 +43,10 @@ struct SpaceClip;
struct wmOperatorType;
/* channel heights */
-#define CHANNEL_FIRST -UI_UNIT_Y
-#define CHANNEL_HEIGHT UI_UNIT_Y
-#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f)
-#define CHANNEL_SKIP 2
+#define CHANNEL_FIRST (-0.8f * U.widget_unit)
+#define CHANNEL_HEIGHT (0.8f * U.widget_unit)
+#define CHANNEL_HEIGHT_HALF (0.4f * U.widget_unit)
+#define CHANNEL_SKIP (0.1f * U.widget_unit)
#define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP)
#define CHANNEL_PAD 4
@@ -54,7 +54,7 @@ struct wmOperatorType;
/* extra padding for lengths (to go under scrollers) */
#define EXTRA_SCROLL_PAD 100.0f
-#define STRIP_HEIGHT_HALF 5
+#define STRIP_HEIGHT_HALF (0.25f * UI_UNIT_Y)
/* internal exports only */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 4e53f34..26bae6e 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -382,8 +382,8 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceClip *sc = CTX_wm_space_clip(C);
float offset[2];
- offset[0] = (event->x - event->prevx) / sc->zoom;
- offset[1] = (event->y - event->prevy) / sc->zoom;
+ offset[0] = (event->prevx - event->x) / sc->zoom;
+ offset[1] = (event->prevy - event->y) / sc->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
@@ -515,10 +515,10 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float delta, factor;
- delta = event->x - event->prevx + event->y - event->prevy;
+ delta = event->prevx - event->x + event->prevy - event->y;
if (U.uiflag & USER_ZOOM_INVERT)
delta *= -1;
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 7befa49..9d04213 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -246,7 +246,7 @@ static SpaceLink *clip_new(const bContext *C)
sc = MEM_callocN(sizeof(SpaceClip), "initclip");
sc->spacetype = SPACE_CLIP;
sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION |
- SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES;
+ SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL;
sc->zoom = 1.0f;
sc->path_length = 20;
sc->scopes.track_preview_height = 120;
@@ -587,6 +587,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
@@ -1151,14 +1152,18 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
}
- /* Grease Pencil */
- clip_draw_grease_pencil((bContext *)C, 1);
+ if (sc->flag & SC_SHOW_GPENCIL) {
+ /* Grease Pencil */
+ clip_draw_grease_pencil((bContext *)C, TRUE);
+ }
/* reset view matrix */
UI_view2d_view_restore(C);
- /* draw Grease Pencil - screen space only */
- clip_draw_grease_pencil((bContext *)C, 0);
+ if (sc->flag & SC_SHOW_GPENCIL) {
+ /* draw Grease Pencil - screen space only */
+ clip_draw_grease_pencil((bContext *)C, FALSE);
+ }
}
static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn)
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 77662d8..56a890c 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1801,7 +1801,7 @@ static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat
int found = FALSE;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (!cti)
continue;
@@ -1832,7 +1832,7 @@ static Object *object_solver_camera(Scene *scene, Object *ob)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (!cti)
continue;
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index b8e162b..bec5013 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -123,10 +123,10 @@ static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
- epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0],
- fabsf(pat_min[0]), fabsf(pat_max[0])) / 2;
- epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1],
- fabsf(pat_min[1]), fabsf(pat_max[1])) / 2;
+ epsx = min_ffff(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0],
+ fabsf(pat_min[0]), fabsf(pat_max[0])) / 2;
+ epsy = min_ffff(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1],
+ fabsf(pat_min[1]), fabsf(pat_max[1])) / 2;
epsx = max_ff(epsx, 2.0f / width);
epsy = max_ff(epsy, 2.0f / height);
@@ -166,7 +166,7 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
d3 = dist_squared_to_line_segment_v2(p, v3, v4);
d4 = dist_squared_to_line_segment_v2(p, v4, v1);
- return sqrtf(MIN4(d1, d2, d3, d4));
+ return sqrtf(min_ffff(d1, d2, d3, d4));
}
static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
@@ -181,7 +181,7 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
d3 = dist_squared_to_line_segment_v2(p, v3, v4);
d4 = dist_squared_to_line_segment_v2(p, v4, v1);
- return sqrtf(MIN4(d1, d2, d3, d4));
+ return sqrtf(min_ffff(d1, d2, d3, d4));
}
static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2])
@@ -210,7 +210,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas
d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max);
/* choose minimal distance. useful for cases of overlapped markers. */
- dist = MIN3(d1, d2, d3);
+ dist = min_fff(d1, d2, d3);
if (track == NULL || dist < mindist) {
track = cur;
diff --git a/source/blender/editors/space_console/SConscript b/source/blender/editors/space_console/SConscript
index f246f08..3e2c9d6 100644
--- a/source/blender/editors/space_console/SConscript
+++ b/source/blender/editors/space_console/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index a215b47..22c260d 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -50,7 +50,9 @@
#include "ED_datafiles.h"
#include "ED_types.h"
+#include "UI_interface.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "console_intern.h"
@@ -79,9 +81,9 @@ typedef struct ConsoleDrawContext {
int cwidth;
int lheight;
int console_width;
- int winx;
int ymin, ymax;
#if 0 /* used by textview, may use later */
+ int winx;
int *xy; // [2]
int *sel; // [2]
int *pos_pick; /* bottom of view == 0, top of file == combine chars, end of line is lower then start. */
@@ -111,15 +113,12 @@ void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dumm
}
#define CONSOLE_DRAW_MARGIN 4
-#define CONSOLE_DRAW_SCROLL 16
-
-
/* console textview callbacks */
static int console_textview_begin(TextViewContext *tvc)
{
SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
- tvc->lheight = sc->lheight;
+ tvc->lheight = sc->lheight * UI_DPI_FAC;
tvc->sel_start = sc->sel_start;
tvc->sel_end = sc->sel_end;
@@ -195,7 +194,8 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
}
-static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick)
+static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw,
+ int mval[2], void **mouse_pick, int *pos_pick)
{
ConsoleLine cl_dummy = {NULL};
int ret = 0;
@@ -217,10 +217,10 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar,
/* view */
tvc.sel_start = sc->sel_start;
tvc.sel_end = sc->sel_end;
- tvc.lheight = sc->lheight;
+ tvc.lheight = sc->lheight * UI_DPI_FAC;
tvc.ymin = v2d->cur.ymin;
tvc.ymax = v2d->cur.ymax;
- tvc.winx = ar->winx;
+ tvc.winx = ar->winx - V2D_SCROLL_WIDTH;
console_scrollback_prompt_begin(sc, &cl_dummy);
ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
@@ -242,13 +242,13 @@ int console_textview_height(struct SpaceConsole *sc, ARegion *ar)
return console_textview_main__internal(sc, ar, 0, mval, NULL, NULL);
}
-int console_char_pick(struct SpaceConsole *sc, ARegion *ar, int mval[2])
+int console_char_pick(struct SpaceConsole *sc, ARegion *ar, const int mval[2])
{
int pos_pick = 0;
void *mouse_pick = NULL;
int mval_clamp[2];
- mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN));
+ mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - CONSOLE_DRAW_MARGIN);
mval_clamp[1] = CLAMPIS(mval[1], CONSOLE_DRAW_MARGIN, ar->winy - CONSOLE_DRAW_MARGIN);
console_textview_main__internal(sc, ar, 0, mval_clamp, &mouse_pick, &pos_pick);
diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h
index 3d30dca..1e79e4b 100644
--- a/source/blender/editors/space_console/console_intern.h
+++ b/source/blender/editors/space_console/console_intern.h
@@ -37,7 +37,7 @@ struct bContext;
/* console_draw.c */
void console_textview_main(struct SpaceConsole *sc, struct ARegion *ar);
int console_textview_height(struct SpaceConsole *sc, struct ARegion *ar); /* needed to calculate the scrollbar */
-int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, int mval[2]);
+int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, const int mval[2]);
void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy);
void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy);
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index be8febd..eed269f 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -174,7 +174,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
ID *id = drag->poin;
/* copy drag path to properties */
- text = RNA_path_from_ID_python(id);
+ text = RNA_path_full_ID_py(id);
RNA_string_set(drop->ptr, "text", text);
MEM_freeN(text);
}
diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript
index b387d48..c3f8c66 100644
--- a/source/blender/editors/space_file/SConscript
+++ b/source/blender/editors/space_file/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index fb438ae..08f01b4 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -321,8 +321,7 @@ void file_calc_previews(const bContext *C, ARegion *ar)
View2D *v2d = &ar->v2d;
ED_fileselect_init_layout(sfile, ar);
- /* +SCROLL_HEIGHT is bad hack to work around issue in UI_view2d_totRect_set */
- UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height + V2D_SCROLL_HEIGHT);
+ UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
}
static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow)
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 763b187..9349abb 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -28,6 +28,8 @@
* \ingroup spfile
*/
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -35,9 +37,6 @@
#include "BKE_report.h"
#include "BKE_main.h"
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index a5647c0..5f1f9a3 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -350,7 +350,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
#else
#ifdef __APPLE__
{
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
+#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040)
OSErr err = noErr;
int i;
const char *home;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index be037a0..7cc322c 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -533,7 +533,7 @@ static void file_ui_area_draw(const bContext *C, ARegion *ar)
{
float col[3];
/* clear */
- UI_GetThemeColor3fv(TH_PANEL, col);
+ UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
diff --git a/source/blender/editors/space_graph/SConscript b/source/blender/editors/space_graph/SConscript
index 83239a5..84ac27a 100644
--- a/source/blender/editors/space_graph/SConscript
+++ b/source/blender/editors/space_graph/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index f665b97..256c90a 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -516,7 +516,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
*/
/* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */
/* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */
- samplefreq = dx / U.v2d_min_gridsize;
+ samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
if (samplefreq < 0.00001f) samplefreq = 0.00001f;
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 21b0ed9..b92430c 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -217,7 +217,6 @@ void GRAPH_OT_previewrange_set(wmOperatorType *ot)
static int graphkeys_viewall(bContext *C, const short do_sel_only, const short include_handles)
{
bAnimContext ac;
- float extra;
rctf cur_new;
/* get editor data */
@@ -230,13 +229,7 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i
&cur_new.ymin, &cur_new.ymax,
do_sel_only, include_handles);
- extra = 0.1f * BLI_rctf_size_x(&cur_new);
- cur_new.xmin -= extra;
- cur_new.xmax += extra;
-
- extra = 0.1f * BLI_rctf_size_y(&cur_new);
- cur_new.ymin -= extra;
- cur_new.ymax += extra;
+ BLI_rctf_scale(&cur_new, 1.1f);
UI_view2d_smooth_view(C, ac.ar, &cur_new);
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index fa7c6bd..734c0e6 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -309,6 +309,12 @@ static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
+ /* make sure we keep the hide flags */
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
+ ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript
index 737da4a..6e7c598 100644
--- a/source/blender/editors/space_image/SConscript
+++ b/source/blender/editors/space_image/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 0a3db59..060a181 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -219,7 +219,7 @@ static void preview_cb(ScrArea *sa, struct uiBlock *block)
BLI_rcti_translate(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
calc_image_view(sima, 'p');
-// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax);
+// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
/* map to image space coordinates */
mval[0] = disprect->xmin; mval[1] = disprect->ymin;
areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin);
@@ -236,7 +236,7 @@ static void preview_cb(ScrArea *sa, struct uiBlock *block)
CLAMP(disprect->xmax, 0, winx);
CLAMP(disprect->ymin, 0, winy);
CLAMP(disprect->ymax, 0, winy);
-// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax);
+// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
}
@@ -674,6 +674,24 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) { /* background image view doesnt need these */
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ int has_alpha = TRUE;
+
+ if (ibuf) {
+ int imtype = BKE_ftype_to_imtype(ibuf->ftype);
+ char valid_channels = BKE_imtype_valid_channels(imtype);
+
+ has_alpha = valid_channels & IMA_CHAN_FLAG_ALPHA;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ if (has_alpha) {
+ col = uiLayoutColumn(layout, FALSE);
+ uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE);
+ uiItemR(col, &imaptr, "alpha_mode", 0, "Alpha", ICON_NONE);
+ }
+
uiItemS(layout);
split = uiLayoutSplit(layout, 0.0f, FALSE);
@@ -694,10 +712,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
row = uiLayoutRow(col, FALSE);
uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields"));
uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- row = uiLayoutRow(layout, FALSE);
- uiItemR(row, &imaptr, "use_premultiply", 0, NULL, ICON_NONE);
- uiItemR(row, &imaptr, "use_color_unpremultiply", 0, NULL, ICON_NONE);
}
}
@@ -796,6 +810,8 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
}
if (imf->imtype == R_IMF_IMTYPE_JP2) {
+ uiItemR(col, imfptr, "jpeg2k_codec", 0, NULL, ICON_NONE);
+
row = uiLayoutRow(col, FALSE);
uiItemR(row, imfptr, "use_jpeg2k_cinema_preset", 0, NULL, ICON_NONE);
uiItemR(row, imfptr, "use_jpeg2k_cinema_48", 0, NULL, ICON_NONE);
@@ -858,6 +874,7 @@ void image_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil");
strcpy(pt->idname, "IMAGE_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index d565e6f..7b4814d 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -75,13 +75,15 @@
#include "WM_types.h"
#include "RE_pipeline.h"
+#include "RE_engine.h"
#include "image_intern.h"
-static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
+static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx, float zoomy)
{
RenderResult *rr;
-
+ Render *re = RE_GetRender(scene->id.name);
+
rr = BKE_image_acquire_renderresult(scene, ima);
if (rr && rr->text) {
@@ -89,6 +91,73 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar)
}
BKE_image_release_renderresult(scene, ima);
+
+ if (re) {
+ int total_tiles;
+ rcti *tiles;
+
+ RE_engine_get_current_tiles(re, &total_tiles, &tiles);
+
+ if (total_tiles) {
+ int i, x, y;
+ rcti *tile;
+
+ /* find window pixel coordinates of origin */
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0.0f);
+ glScalef(zoomx, zoomy, 1.0f);
+
+ if (scene->r.mode & R_BORDER) {
+ glTranslatef(-scene->r.border.xmin * scene->r.xsch * scene->r.size / 100.0f,
+ -scene->r.border.ymin * scene->r.ysch * scene->r.size / 100.0f,
+ 0.0f);
+ }
+
+ UI_ThemeColor(TH_FACE_SELECT);
+
+ for (i = 0, tile = tiles; i < total_tiles; i++, tile++) {
+ float delta_x = 4.0f * UI_DPI_FAC / zoomx;
+ float delta_y = 4.0f * UI_DPI_FAC / zoomy;
+
+ delta_x = min_ff(delta_x, tile->xmax - tile->xmin);
+ delta_y = min_ff(delta_y, tile->ymax - tile->ymin);
+
+ /* left bottom corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmin, tile->ymin + delta_y);
+ glVertex2f(tile->xmin, tile->ymin);
+ glVertex2f(tile->xmin + delta_x, tile->ymin);
+ glEnd();
+
+ /* left top corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmin, tile->ymax - delta_y);
+ glVertex2f(tile->xmin, tile->ymax);
+ glVertex2f(tile->xmin + delta_x, tile->ymax);
+ glEnd();
+
+ /* right bottom corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmax - delta_x, tile->ymin);
+ glVertex2f(tile->xmax, tile->ymin);
+ glVertex2f(tile->xmax, tile->ymin + delta_y);
+ glEnd();
+
+ /* right top corner */
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tile->xmax - delta_x, tile->ymax);
+ glVertex2f(tile->xmax, tile->ymax);
+ glVertex2f(tile->xmax, tile->ymax - delta_y);
+ glEnd();
+ }
+
+ MEM_freeN(tiles);
+
+ glPopMatrix();
+ }
+ }
}
/* used by node view too */
@@ -146,7 +215,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
if (channels >= 3) {
glColor3ubv(red);
if (fp)
- BLI_snprintf(str, sizeof(str), " R:%-.4f", fp[0]);
+ BLI_snprintf(str, sizeof(str), " R:%-.5f", fp[0]);
else if (cp)
BLI_snprintf(str, sizeof(str), " R:%-3d", cp[0]);
else
@@ -157,7 +226,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
glColor3ubv(green);
if (fp)
- BLI_snprintf(str, sizeof(str), " G:%-.4f", fp[1]);
+ BLI_snprintf(str, sizeof(str), " G:%-.5f", fp[1]);
else if (cp)
BLI_snprintf(str, sizeof(str), " G:%-3d", cp[1]);
else
@@ -168,7 +237,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
glColor3ubv(blue);
if (fp)
- BLI_snprintf(str, sizeof(str), " B:%-.4f", fp[2]);
+ BLI_snprintf(str, sizeof(str), " B:%-.5f", fp[2]);
else if (cp)
BLI_snprintf(str, sizeof(str), " B:%-3d", cp[2]);
else
@@ -445,11 +514,15 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
unsigned char *display_buffer;
void *cache_handle;
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
if (sima->flag & SI_USE_ALPHA) {
fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glRecti(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
}
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
@@ -463,8 +536,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
IMB_display_buffer_release(cache_handle);
- if (sima->flag & SI_USE_ALPHA)
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
}
/* reset zoom */
@@ -518,8 +590,8 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
sima->curtile = ima->xrep * ima->yrep - 1;
/* retrieve part of image buffer */
- dx = ibuf->x / ima->xrep;
- dy = ibuf->y / ima->yrep;
+ dx = max_ii(ibuf->x / ima->xrep, 1);
+ dy = max_ii(ibuf->y / ima->yrep, 1);
sx = (sima->curtile % ima->xrep) * dx;
sy = (sima->curtile / ima->xrep) * dy;
rect = get_part_from_buffer((unsigned int *)display_buffer, ibuf->x, sx, sy, sx + dx, sy + dy);
@@ -786,7 +858,6 @@ void draw_image_main(const bContext *C, ARegion *ar)
if (sima->mode == SI_MODE_PAINT)
draw_image_paint_helpers(C, ar, scene, zoomx, zoomy);
-
/* XXX integrate this code */
#if 0
if (ibuf) {
@@ -812,5 +883,5 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* render info */
if (ima && show_render)
- draw_render_info(scene, ima, ar);
+ draw_render_info(scene, ima, ar, zoomx, zoomy);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 0d0fdc6..23adf7e 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -299,8 +299,8 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
SpaceImage *sima = CTX_wm_space_image(C);
float offset[2];
- offset[0] = (event->x - event->prevx) / sima->zoom;
- offset[1] = (event->y - event->prevy) / sima->zoom;
+ offset[0] = (event->prevx - event->x) / sima->zoom;
+ offset[1] = (event->prevy - event->y) / sima->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
image_view_pan_exec(C, op);
@@ -457,14 +457,14 @@ enum {
static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type == MOUSEZOOM) {
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
float delta, factor, location[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
- delta = event->x - event->prevx + event->y - event->prevy;
+ delta = event->prevx - event->x + event->prevy - event->y;
if (U.uiflag & USER_ZOOM_INVERT)
delta *= -1;
@@ -1109,6 +1109,11 @@ static int image_replace_exec(bContext *C, wmOperator *op)
/* we cant do much if the str is longer then FILE_MAX :/ */
BLI_strncpy(sima->image->name, str, sizeof(sima->image->name));
+ if (sima->image->source == IMA_SRC_GENERATED) {
+ sima->image->source = IMA_SRC_FILE;
+ BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_SRC_CHANGE);
+ }
+
if (BLI_testextensie_array(str, imb_ext_movie))
sima->image->source = IMA_SRC_MOVIE;
else
@@ -1217,7 +1222,7 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
simopts->im_format.imtype = R_IMF_IMTYPE_PNG;
}
else {
- simopts->im_format.imtype = BKE_ftype_to_imtype(ibuf->ftype);
+ BKE_imbuf_to_image_format(&simopts->im_format, ibuf);
}
//simopts->subimtype = scene->r.subimtype; /* XXX - this is lame, we need to make these available too! */
simopts->im_format.quality = ibuf->ftype & 0xff;
@@ -1434,7 +1439,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
ImageFormatData *imf = op->customdata;
- return WM_operator_filesel_ensure_ext_imtype(op, imf->imtype);
+ return WM_operator_filesel_ensure_ext_imtype(op, imf);
}
static int image_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
@@ -1559,6 +1564,7 @@ static int image_save_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SaveImageOptions simopts;
+ save_image_options_defaults(&simopts);
if (save_image_options_init(&simopts, sima, scene, FALSE) == 0)
return OPERATOR_CANCELLED;
save_image_options_from_op(&simopts, op);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 5616c02..9492e29 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -151,6 +151,7 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
simage->spacetype = SPACE_IMAGE;
simage->zoom = 1.0f;
simage->lock = TRUE;
+ simage->flag = SI_SHOW_GPENCIL;
simage->iuser.ok = TRUE;
simage->iuser.fie_ima = 2;
@@ -291,6 +292,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0);
/* ctrl now works as well, shift + numpad works as arrow keys on Windows */
RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f);
@@ -674,16 +676,20 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
- /* Grease Pencil too (in addition to UV's) */
- draw_image_grease_pencil((bContext *)C, 1);
+ if (sima->flag & SI_SHOW_GPENCIL) {
+ /* Grease Pencil too (in addition to UV's) */
+ draw_image_grease_pencil((bContext *)C, TRUE);
+ }
/* sample line */
draw_image_sample_line(sima);
UI_view2d_view_restore(C);
- /* draw Grease Pencil - screen space only */
- draw_image_grease_pencil((bContext *)C, 0);
+ if (sima->flag & SI_SHOW_GPENCIL) {
+ /* draw Grease Pencil - screen space only */
+ draw_image_grease_pencil((bContext *)C, FALSE);
+ }
if (mask) {
int width, height;
diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript
index e4746ae..bacc281 100644
--- a/source/blender/editors/space_info/SConscript
+++ b/source/blender/editors/space_info/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 5830c45..54afc9a 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -56,6 +56,8 @@
#include "ED_types.h"
#include "UI_resources.h"
+#include "UI_interface.h"
+#include "UI_view2d.h"
#include "info_intern.h"
#include "../space_info/textview.h"
@@ -139,7 +141,7 @@ static int report_textview_begin(TextViewContext *tvc)
// SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
ReportList *reports = (ReportList *)tvc->arg2;
- tvc->lheight = 14; //sc->lheight;
+ tvc->lheight = 14 * UI_DPI_FAC; //sc->lheight;
tvc->sel_start = 0;
tvc->sel_end = 0;
@@ -269,10 +271,10 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re
/* view */
tvc.sel_start = 0;
tvc.sel_end = 0;
- tvc.lheight = 14; //sc->lheight;
+ tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight;
tvc.ymin = v2d->cur.ymin;
tvc.ymax = v2d->cur.ymax;
- tvc.winx = ar->winx;
+ tvc.winx = ar->winx - V2D_SCROLL_WIDTH;
ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h
index 80018e8..62e9a3a 100644
--- a/source/blender/editors/space_info/info_intern.h
+++ b/source/blender/editors/space_info/info_intern.h
@@ -39,11 +39,15 @@ struct ReportList;
void FILE_OT_pack_all(struct wmOperatorType *ot);
void FILE_OT_unpack_all(struct wmOperatorType *ot);
+void FILE_OT_pack_libraries(struct wmOperatorType *ot);
+void FILE_OT_unpack_libraries(struct wmOperatorType *ot);
+
void FILE_OT_make_paths_relative(struct wmOperatorType *ot);
void FILE_OT_make_paths_absolute(struct wmOperatorType *ot);
void FILE_OT_report_missing_files(struct wmOperatorType *ot);
void FILE_OT_find_missing_files(struct wmOperatorType *ot);
+
void INFO_OT_reports_display_update(struct wmOperatorType *ot);
/* info_draw.c */
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 48b5eaf..104349e 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -40,7 +40,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_bpath.h"
+#include "BKE_bpath.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -66,15 +66,70 @@
#include "info_intern.h"
+/********************* pack blend file libararies operator *********************/
+
+static int pack_libraries_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+
+ packLibraries(bmain, op->reports);
+
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_pack_libraries(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Pack Blender Libraries";
+ ot->idname = "FILE_OT_pack_libraries";
+ ot->description = "Pack all used Blender library files into the current .blend";
+
+ /* api callbacks */
+ ot->exec = pack_libraries_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int unpack_libraries_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+
+ unpackLibraries(bmain, op->reports);
+
+ return OPERATOR_FINISHED;
+}
+
+static int unpack_libraries_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ return WM_operator_confirm_message(C, op, "Unpack Blender Libraries - creates directories, all new paths should work");
+}
+
+void FILE_OT_unpack_libraries(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unpack Blender Libraries";
+ ot->idname = "FILE_OT_unpack_libraries";
+ ot->description = "Unpack all used Blender library files from this .blend file";
+
+ /* api callbacks */
+ ot->invoke = unpack_libraries_invoke;
+ ot->exec = unpack_libraries_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
/********************* pack all operator *********************/
static int pack_all_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
-
+
packAll(bmain, op->reports);
G.fileflags |= G_AUTOPACK;
-
+
return OPERATOR_FINISHED;
}
@@ -83,7 +138,7 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
Main *bmain = CTX_data_main(C);
Image *ima;
ImBuf *ibuf;
-
+
// first check for dirty images
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->ibufs.first) { /* XXX FIX */
@@ -93,16 +148,16 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
BKE_image_release_ibuf(ima, ibuf, NULL);
break;
}
-
+
BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
-
+
if (ima) {
uiPupMenuOkee(C, "FILE_OT_pack_all", "Some images are painted on. These changes will be lost. Continue?");
return OPERATOR_CANCELLED;
}
-
+
return pack_all_exec(C, op);
}
@@ -116,11 +171,12 @@ void FILE_OT_pack_all(wmOperatorType *ot)
/* api callbacks */
ot->exec = pack_all_exec;
ot->invoke = pack_all_invoke;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
/********************* unpack all operator *********************/
static const EnumPropertyItem unpack_all_method_items[] = {
@@ -204,7 +260,7 @@ static int make_paths_relative_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BLI_bpath_relative_convert(bmain, bmain->name, op->reports);
+ BKE_bpath_relative_convert(bmain, bmain->name, op->reports);
/* redraw everything so any changed paths register */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -237,7 +293,7 @@ static int make_paths_absolute_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BLI_bpath_absolute_convert(bmain, bmain->name, op->reports);
+ BKE_bpath_absolute_convert(bmain, bmain->name, op->reports);
/* redraw everything so any changed paths register */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -266,7 +322,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
/* run the missing file check */
- BLI_bpath_missing_files_check(bmain, op->reports);
+ BKE_bpath_missing_files_check(bmain, op->reports);
return OPERATOR_FINISHED;
}
@@ -291,7 +347,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
const char *searchpath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
- BLI_bpath_missing_files_find(bmain, searchpath, op->reports);
+ BKE_bpath_missing_files_find(bmain, searchpath, op->reports);
MEM_freeN((void *)searchpath);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 049a50f..023ffa5 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -62,7 +62,7 @@ int info_report_mask(SpaceInfo *UNUSED(sinfo))
return report_mask;
#endif
- return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL;
+ return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_PROPERTY_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL;
}
// TODO, get this working again!
@@ -77,7 +77,10 @@ static int report_replay_exec(bContext *C, wmOperator *UNUSED(op))
sc->type = CONSOLE_TYPE_PYTHON;
for (report = reports->list.last; report; report = report->prev) {
- if ((report->type & report_mask) && (report->type & RPT_OPERATOR_ALL) && (report->flag & SELECT)) {
+ if ((report->type & report_mask) &&
+ (report->type & RPT_OPERATOR_ALL | RPT_PROPERTY_ALL) &&
+ (report->flag & SELECT))
+ {
console_history_add_str(sc, report->message, 0);
WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL);
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 5e5e0c8..3f73fc2 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -39,6 +39,7 @@
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
+#include "BLI_math.h"
#include "BKE_anim.h"
#include "BKE_blender.h"
@@ -47,6 +48,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_tessmesh.h"
@@ -62,7 +64,7 @@ typedef struct SceneStats {
int totbone, totbonesel;
int totobj, totobjsel;
int totlamp, totlampsel;
- int tottri, totmesh, totcurve;
+ int tottri, totmesh;
char infostr[512];
} SceneStats;
@@ -74,7 +76,7 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
{
/* we assume derivedmesh is already built, this strictly does stats now. */
DerivedMesh *dm = ob->derivedFinal;
- int totvert, totedge, totface;
+ int totvert, totedge, totface, totloop;
stats->totmesh += totob;
@@ -82,10 +84,12 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
totface = dm->getNumPolys(dm);
+ totloop = dm->getNumLoops(dm);
stats->totvert += totvert * totob;
stats->totedge += totedge * totob;
stats->totface += totface * totob;
+ stats->tottri += poly_to_tri_count(totface, totloop) * totob;
if (sel) {
stats->totvertsel += totvert;
@@ -103,40 +107,23 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
case OB_SURF:
case OB_CURVE:
case OB_FONT:
- {
- int tot = 0, totf = 0;
-
- stats->totcurve += totob;
-
- if (ob->disp.first)
- BKE_displist_count(&ob->disp, &tot, &totf);
-
- tot *= totob;
- totf *= totob;
-
- stats->totvert += tot;
- stats->totface += totf;
-
- if (sel) {
- stats->totvertsel += tot;
- stats->totfacesel += totf;
- }
- break;
- }
case OB_MBALL:
{
- int tot = 0, totf = 0;
+ int totv = 0, totf = 0, tottri = 0;
- BKE_displist_count(&ob->disp, &tot, &totf);
+ if (ob->disp.first)
+ BKE_displist_count(&ob->disp, &totv, &totf, &tottri);
- tot *= totob;
- totf *= totob;
+ totv *= totob;
+ totf *= totob;
+ tottri *= totob;
- stats->totvert += tot;
+ stats->totvert += totv;
stats->totface += totf;
+ stats->tottri += tottri;
if (sel) {
- stats->totvertsel += tot;
+ stats->totvertsel += totv;
stats->totfacesel += totf;
}
break;
@@ -260,6 +247,12 @@ static void stats_object_pose(Object *ob, SceneStats *stats)
}
}
+static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
+{
+ stats->totvert = ob->sculpt->bm->totvert;
+ stats->tottri = ob->sculpt->bm->totface;
+}
+
static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
{
if (base->flag & SELECT) stats->totobjsel++;
@@ -319,6 +312,12 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
}
}
+static int stats_is_object_dynamic_topology_sculpt(Object *ob)
+{
+ return (ob && (ob->mode & OB_MODE_SCULPT) &&
+ ob->sculpt && ob->sculpt->bm);
+}
+
/* Statistics displayed in info header. Called regularly on scene changes. */
static void stats_update(Scene *scene)
{
@@ -334,6 +333,10 @@ static void stats_update(Scene *scene)
/* Pose Mode */
stats_object_pose(ob, &stats);
}
+ else if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ /* Dynamic-topology sculpt mode */
+ stats_object_sculpt_dynamic_topology(ob, &stats);
+ }
else {
/* Objects */
for (base = scene->base.first; base; base = base->next)
@@ -388,9 +391,12 @@ static void stats_string(Scene *scene)
s += sprintf(s, "Bones:%d/%d %s",
stats->totbonesel, stats->totbone, memstr);
}
+ else if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ s += sprintf(s, "Verts:%d | Tris:%d", stats->totvert, stats->tottri);
+ }
else {
- s += sprintf(s, "Verts:%d | Faces:%d | Objects:%d/%d | Lamps:%d/%d%s",
- stats->totvert, stats->totface, stats->totobjsel, stats->totobj, stats->totlampsel, stats->totlamp, memstr);
+ s += sprintf(s, "Verts:%d | Faces:%d| Tris:%d | Objects:%d/%d | Lamps:%d/%d%s",
+ stats->totvert, stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel, stats->totlamp, memstr);
}
if (ob)
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index cba0a80..60b04f7 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -178,7 +178,10 @@ static void info_main_area_draw(const bContext *C, ARegion *ar)
static void info_operatortypes(void)
{
WM_operatortype_append(FILE_OT_pack_all);
+ WM_operatortype_append(FILE_OT_pack_libraries);
WM_operatortype_append(FILE_OT_unpack_all);
+ WM_operatortype_append(FILE_OT_unpack_libraries);
+
WM_operatortype_append(FILE_OT_make_paths_relative);
WM_operatortype_append(FILE_OT_make_paths_absolute);
WM_operatortype_append(FILE_OT_report_missing_files);
@@ -272,7 +275,7 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn)
static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu)
{
struct RecentFile *recent;
- char file [FILE_MAX];
+ char file[FILE_MAX];
uiLayout *layout = menu->layout;
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
if (G.recent_files.first) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index f454b1d..fc0a7b3 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -45,7 +45,8 @@
static void console_font_begin(TextViewContext *sc)
{
- BLF_size(blf_mono_font, sc->lheight - 2, 72);
+ /* 0.875 is based on: 16 pixels lines get 14 pixel text */
+ BLF_size(blf_mono_font, 0.875 * sc->lheight, 72);
}
typedef struct ConsoleDrawContext {
@@ -61,17 +62,23 @@ typedef struct ConsoleDrawContext {
int draw;
} ConsoleDrawContext;
-static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth, int lheight)
+BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step)
+{
+ cdc->sel[0] += step;
+ cdc->sel[1] += step;
+}
+
+static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight)
{
if (sel[0] <= str_len_draw && sel[1] >= 0) {
- int sta = max_ii(sel[0], 0);
- int end = min_ii(sel[1], str_len_draw);
+ const int sta = max_ii(sel[0], 0);
+ const int end = min_ii(sel[1], str_len_draw);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_halftone);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(255, 255, 255, 96);
+ glColor4ub(255, 255, 255, 48);
glRecti(xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2);
@@ -84,9 +91,9 @@ static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth
/* return 0 if the last line is off the screen
* should be able to use this for any string type */
-static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str_len, unsigned char *fg, unsigned char *bg)
+static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const int str_len,
+ const unsigned char *fg, const unsigned char *bg)
{
-#define STEP_SEL(value) cdc->sel[0] += (value); cdc->sel[1] += (value)
int rct_ofs = cdc->lheight / 4;
int tot_lines = (str_len / cdc->console_width) + 1; /* total number of lines for wrapping */
int y_next = (str_len > cdc->console_width) ? cdc->xy[1] + cdc->lheight * tot_lines : cdc->xy[1] + cdc->lheight;
@@ -120,7 +127,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
/* adjust selection even if not drawing */
if (cdc->sel[0] != cdc->sel[1]) {
- STEP_SEL(-(str_len + 1));
+ console_step_sel(cdc, -(str_len + 1));
}
return 1;
@@ -149,10 +156,10 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
BLF_draw(mono, line_stride, str_len - initial_offset);
if (cdc->sel[0] != cdc->sel[1]) {
- STEP_SEL(-initial_offset);
+ console_step_sel(cdc, -initial_offset);
// glColor4ub(255, 0, 0, 96); // debug
console_draw_sel(cdc->sel, cdc->xy, str_len % cdc->console_width, cdc->cwidth, cdc->lheight);
- STEP_SEL(cdc->console_width);
+ console_step_sel(cdc, cdc->console_width);
glColor3ubv(fg);
}
@@ -167,7 +174,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
if (cdc->sel[0] != cdc->sel[1]) {
// glColor4ub(0, 255, 0, 96); // debug
console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight);
- STEP_SEL(cdc->console_width);
+ console_step_sel(cdc, cdc->console_width);
glColor3ubv(fg);
}
@@ -179,7 +186,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
}
copy_v2_v2_int(cdc->sel, sel_orig);
- STEP_SEL(-(str_len + 1));
+ console_step_sel(cdc, -(str_len + 1));
}
else { /* simple, no wrap */
@@ -201,7 +208,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
// glColor4ub(255, 255, 0, 96); // debug
console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight);
- STEP_SEL(-(str_len + 1));
+ console_step_sel(cdc, -(str_len + 1));
}
cdc->xy[1] += cdc->lheight;
@@ -211,13 +218,11 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
}
return 1;
-#undef STEP_SEL
}
#define CONSOLE_DRAW_MARGIN 4
-#define CONSOLE_DRAW_SCROLL 16
-int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick)
+int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick)
{
ConsoleDrawContext cdc = {0};
@@ -241,9 +246,10 @@ int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick
cdc.cwidth = (int)BLF_fixed_width(mono);
assert(cdc.cwidth > 0);
cdc.lheight = tvc->lheight;
- cdc.console_width = (tvc->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth;
+ /* note, scroll bar must be already subtracted () */
+ cdc.console_width = (tvc->winx - (CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth;
CLAMP(cdc.console_width, 1, INT_MAX); /* avoid divide by zero on small windows */
- cdc.winx = tvc->winx - (CONSOLE_DRAW_MARGIN + CONSOLE_DRAW_SCROLL);
+ cdc.winx = tvc->winx - CONSOLE_DRAW_MARGIN;
cdc.ymin = tvc->ymin;
cdc.ymax = tvc->ymax;
cdc.xy = xy;
diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h
index 33fbe55..d0fab88 100644
--- a/source/blender/editors/space_info/textview.h
+++ b/source/blender/editors/space_info/textview.h
@@ -54,7 +54,7 @@ typedef struct TextViewContext {
} TextViewContext;
-int textview_draw(struct TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick);
+int textview_draw(struct TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick);
#define TVC_LINE_FG (1<<0)
#define TVC_LINE_BG (1<<1)
diff --git a/source/blender/editors/space_logic/SConscript b/source/blender/editors/space_logic/SConscript
index e63d88e..e5a19b7 100644
--- a/source/blender/editors/space_logic/SConscript
+++ b/source/blender/editors/space_logic/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 5a8a7ce..a7599f2 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -1006,7 +1006,7 @@ static void draw_sensor_actuator(uiLayout *layout, PointerRNA *ptr)
static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
{
- bSensor *sens = (bSensor*)ptr->data;
+ bSensor *sens = (bSensor *)ptr->data;
bArmatureSensor *as = (bArmatureSensor *) sens->data;
Object *ob = (Object *)ptr->id.data;
PointerRNA pose_ptr, pchan_ptr;
@@ -1476,7 +1476,7 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr)
{
- bActuator *act = (bActuator*)ptr->data;
+ bActuator *act = (bActuator *)ptr->data;
bArmatureActuator *aa = (bArmatureActuator *) act->data;
Object *ob = (Object *)ptr->id.data;
bConstraint *constraint = NULL;
@@ -2270,11 +2270,11 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Controllers ****************** */
- xco= 420; yco= -10; width= 300;
+ xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit;
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle());
row = uiLayoutRow(layout, TRUE);
- uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
+ uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, IFACE_("Act"), ICON_NONE);
@@ -2301,7 +2301,7 @@ void logic_buttons(bContext *C, ARegion *ar)
uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT);
row = uiLayoutRow(split, TRUE);
- uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
+ uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2377,11 +2377,11 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Sensors ****************** */
- xco= 10; yco= -10; width= 340;
+ xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle());
row = uiLayoutRow(layout, TRUE);
- uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
+ uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, IFACE_("Act"), ICON_NONE);
@@ -2398,7 +2398,7 @@ void logic_buttons(bContext *C, ARegion *ar)
if ((ob->scavisflag & OB_VIS_SENS) == 0) continue;
row = uiLayoutRow(layout, TRUE);
- uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
+ uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2446,11 +2446,11 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Actuators ****************** */
- xco= 800; yco= -10; width= 340;
+ xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle());
row = uiLayoutRow(layout, TRUE);
- uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
+ uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, IFACE_("Sel"), ICON_NONE);
uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, IFACE_("Act"), ICON_NONE);
@@ -2469,7 +2469,7 @@ void logic_buttons(bContext *C, ARegion *ar)
}
row = uiLayoutRow(layout, TRUE);
- uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
+ uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2516,7 +2516,7 @@ void logic_buttons(bContext *C, ARegion *ar)
uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */
height = MIN2(height, yco);
- UI_view2d_totRect_set(&ar->v2d, 1150, height);
+ UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height);
/* set the view */
UI_view2d_view_ortho(&ar->v2d);
diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c
index 4cd5321..8795d65 100644
--- a/source/blender/editors/space_logic/space_logic.c
+++ b/source/blender/editors/space_logic/space_logic.c
@@ -148,7 +148,7 @@ static SpaceLink *logic_new(const bContext *C)
/* not spacelink itself */
static void logic_free(SpaceLink *UNUSED(sl))
{
-// Spacelogic *slogic= (SpaceLogic*) sl;
+// Spacelogic *slogic= (SpaceLogic *) sl;
// if (slogic->gpd)
// XXX BKE_gpencil_free(slogic->gpd);
diff --git a/source/blender/editors/space_nla/SConscript b/source/blender/editors/space_nla/SConscript
index ee010e6..18c6392 100644
--- a/source/blender/editors/space_nla/SConscript
+++ b/source/blender/editors/space_nla/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index fd999bf..0c89e3e 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -632,7 +632,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
for (ale = anim_data->first; ale; ale = ale->next) {
const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
- const float ydatac = (float)(y - 7);
+ const float ydatac = (float)(y - 0.35f * U.widget_unit);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
@@ -716,7 +716,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
if (ale->id) {
/* special exception for textures */
if (GS(ale->id->name) == ID_TE) {
- offset = 14;
+ offset = 0.7f * U.widget_unit;
indent = 1;
}
/* special exception for nodetrees */
@@ -727,7 +727,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
case NTREE_SHADER:
{
/* same as for textures */
- offset = 14;
+ offset = 0.7f * U.widget_unit;
indent = 1;
}
break;
@@ -735,19 +735,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
case NTREE_TEXTURE:
{
/* even more */
- offset = 21;
+ offset = U.widget_unit;
indent = 1;
}
break;
default:
/* normal will do */
- offset = 14;
+ offset = 0.7f * U.widget_unit;
break;
}
}
else {
- offset = 14;
+ offset = 0.7f * U.widget_unit;
}
}
else {
@@ -779,7 +779,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
glColor4f(color[0], color[1], color[2], alpha);
}
- offset += 7 * indent;
+ offset += 0.35f * U.widget_unit * indent;
/* only on top two corners, to show that this channel sits on top of the preceding ones */
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
@@ -797,7 +797,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
UI_ThemeColorShade(TH_HEADER, ((nonSolo == 0) ? 20 : -20));
indent += group;
- offset += 7 * indent;
+ offset += 0.35f * U.widget_unit * indent;
glBegin(GL_QUADS);
glVertex2f(x + offset, yminc);
glVertex2f(x + offset, ymaxc);
@@ -809,14 +809,14 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
/* draw expand/collapse triangle */
if (expand > 0) {
UI_icon_draw(x + offset, ydatac, expand);
- offset += 17;
+ offset += 0.85f * U.widget_unit;
}
/* draw special icon indicating certain data-types */
if (special > -1) {
/* for normal channels */
UI_icon_draw(x + offset, ydatac, special);
- offset += 17;
+ offset += 0.85f * U.widget_unit;
}
glDisable(GL_BLEND);
@@ -837,19 +837,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
/* draw protect 'lock' */
if (protect > -1) {
- offset = 16;
+ offset = 0.8f * U.widget_unit;
UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, protect);
}
/* draw mute 'eye' */
if (mute > -1) {
- offset += 16;
+ offset += 0.8f * U.widget_unit;
UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, mute);
}
/* draw NLA-action line 'status-icons' - only when there's an action */
if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) {
- offset += 16;
+ offset += 0.8f * U.widget_unit;
/* now draw some indicator icons */
if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
@@ -862,7 +862,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
fdrawline((float)(v2d->cur.xmax - offset), yminc,
(float)(v2d->cur.xmax - offset), ymaxc);
- offset += 16;
+ offset += 0.8f * U.widget_unit;
/* 'tweaking action' indicator - not a button */
UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_EDIT);
@@ -870,10 +870,10 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
else {
/* XXX firstly draw a little rect to help identify that it's different from the toggles */
glBegin(GL_LINE_LOOP);
- glVertex2f((float)v2d->cur.xmax - offset - 1, y - 7);
- glVertex2f((float)v2d->cur.xmax - offset - 1, y + 9);
- glVertex2f((float)v2d->cur.xmax - 1, y + 9);
- glVertex2f((float)v2d->cur.xmax - 1, y - 7);
+ glVertex2f((float)v2d->cur.xmax - offset - 1, y - 0.35f * U.widget_unit);
+ glVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45f * U.widget_unit);
+ glVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit);
+ glVertex2f((float)v2d->cur.xmax - 1, y - 0.35f * U.widget_unit);
glEnd(); // GL_LINES
/* 'push down' icon for normal active-actions */
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 996c6fb..3803f89 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
node_relationships.c
node_select.c
node_templates.c
+ node_toolbar.c
node_view.c
space_node.c
diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript
index 7e311b1..70837fa 100644
--- a/source/blender/editors/space_node/SConscript
+++ b/source/blender/editors/space_node/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 381393e..981a177 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -123,10 +123,10 @@ static void node_socket_button_string(const bContext *C, uiBlock *block,
float slen;
UI_ThemeColor(TH_TEXT);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect; /* XXX, check for dpis */
while (slen > (width * 0.5f) && *ui_name) {
ui_name = BLI_str_find_next_char_utf8(ui_name, NULL);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect;
}
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr);
@@ -208,7 +208,7 @@ static void node_socket_button_color(const bContext *C, uiBlock *block,
bt = uiDefButR(block, COLOR, B_NODE_EXEC, "",
x, y + 2, (labelw > 0 ? 40 : width), NODE_DY - 2,
- &ptr, "default_value", 0, 0, 0, -1, -1, NULL);
+ &ptr, "default_value", -1, 0, 0, -1, -1, NULL);
if (node)
uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node);
@@ -229,19 +229,18 @@ static void node_draw_input_default(const bContext *C, uiBlock *block,
node_socket_button_label(C, block, ntree, node, sock, IFACE_(name), x, y, width);
}
-static void node_draw_output_default(const bContext *C, uiBlock *block,
+static void node_draw_output_default(const bContext *UNUSED(C), uiBlock *block,
bNodeTree *UNUSED(ntree), bNode *node, bNodeSocket *sock,
const char *name, int UNUSED(x), int UNUSED(y), int UNUSED(width))
{
- SpaceNode *snode = CTX_wm_space_node(C);
const char *ui_name = IFACE_(name);
float slen;
UI_ThemeColor(TH_TEXT);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
- while (slen > node->width && *ui_name) {
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) ;
+ while (slen > NODE_WIDTH(node) && *ui_name) {
ui_name = BLI_str_find_next_char_utf8(ui_name, NULL);
- slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
+ slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X);
}
if (*ui_name) {
@@ -400,8 +399,8 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- bNodeTree *ntree = (bNodeTree*)ptr->id.data;
- bNode *node = (bNode*)ptr->data;
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
bNodeSocket *sock = node->outputs.first; /* first socket stores normal */
PointerRNA sockptr;
@@ -509,14 +508,14 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode)
bNodeSocket *sock, *gsock;
float locx, locy;
rctf *rect = &gnode->totr;
- const float dpi_fac = UI_DPI_ICON_FAC;
+ const float dpi_fac = UI_DPI_FAC;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
const float group_header = 26 * dpi_fac;
int counter;
int dy;
/* get "global" coords */
- nodeToView(gnode, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(gnode, 0.0f, 0.0f, &locx, &locy);
/* center them, is a bit of abuse of locx and locy though */
node_update_nodetree(C, ngroup, locx, locy);
@@ -688,7 +687,7 @@ static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket *
static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode,
bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out)
{
- const float dpi_fac = UI_DPI_ICON_FAC;
+ const float dpi_fac = 1.0f;
bNodeTree *ngroup = (bNodeTree *)gnode->id;
bNodeSocketType *stype = ntreeGetSocketType(gsock ? gsock->type : sock->type);
uiBut *bt;
@@ -800,7 +799,7 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN
uiLayout *layout;
PointerRNA ptr;
rctf rect = gnode->totr;
- const float dpi_fac = UI_DPI_ICON_FAC;
+ const float dpi_fac = 1.0f;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
const float group_header = 26 * dpi_fac;
@@ -925,7 +924,7 @@ static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
*/
static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
{
- const float margin = 30.0f;
+ const float margin = 1.5f * U.widget_unit;
NodeFrame *data = (NodeFrame *)node->storage;
int bbinit;
bNode *tnode;
@@ -933,8 +932,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode
float xmax, ymax;
/* init rect from current frame size */
- nodeToView(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
- nodeToView(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
+ node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
+ node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
/* frame can be resized manually only if shrinking is disabled or no children are attached */
data->flag |= NODE_FRAME_RESIZEABLE;
@@ -963,8 +962,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode
}
/* now adjust the frame size from view-space bounding box */
- nodeFromView(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
- nodeFromView(node, rect.xmax, rect.ymin, &xmax, &ymax);
+ node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
+ node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax);
node->width = xmax - node->offsetx;
node->height = -ymax + node->offsety;
@@ -1101,7 +1100,7 @@ static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntr
float size = NODE_REROUTE_SIZE;
/* get "global" coords */
- nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
/* reroute node has exactly one input and one output, both in the same place */
nsock = node->outputs.first;
@@ -1933,9 +1932,9 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po
static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "type", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE);
- switch (RNA_enum_get(ptr, "type")) {
+ switch (RNA_enum_get(ptr, "mode")) {
case CMP_NODE_DILATEERODE_DISTANCE_THRESH:
uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE);
break;
@@ -2153,12 +2152,12 @@ static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C
active_index = RNA_int_get(ptr, "active_input_index");
/* using different collection properties if multilayer format is enabled */
if (multilayer) {
- uiTemplateList(col, C, ptr, "layer_slots", ptr, "active_input_index", NULL, 0, 0, 0);
+ uiTemplateList(col, C, "UI_UL_list", "", ptr, "layer_slots", ptr, "active_input_index", 0, 0, 0);
RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"),
active_index, &active_input_ptr);
}
else {
- uiTemplateList(col, C, ptr, "file_slots", ptr, "active_input_index", NULL, 0, 0, 0);
+ uiTemplateList(col, C, "UI_UL_list", "", ptr, "file_slots", ptr, "active_input_index", 0, 0, 0);
RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"),
active_index, &active_input_ptr);
}
@@ -3272,10 +3271,18 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
else {
glPixelZoom(snode->zoom, snode->zoom);
-
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glRecti(x, y, x + ibuf->x * snode->zoom, y + ibuf->y * snode->zoom);
+
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
glPixelZoom(1.0f, 1.0f);
+
+ glDisable(GL_BLEND);
}
}
@@ -3417,10 +3424,10 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa
vec[2][0] = vec[3][0] - dist;
vec[2][1] = vec[3][1];
}
- if (v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
+ if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
/* clipped */
}
- else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
+ else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
/* clipped */
}
else {
@@ -3532,7 +3539,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
glDisable(GL_LINE_SMOOTH);
/* restore previuos linewidth */
- glLineWidth(linew);
+ glLineWidth(1.0f);
}
}
@@ -3618,7 +3625,7 @@ void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link,
glDisable(GL_LINE_SMOOTH);
/* restore previuos linewidth */
- glLineWidth(linew);
+ glLineWidth(1.0f);
}
#endif
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 96ac716..18ce2c8 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -76,10 +76,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene,
if (node) {
node_select(node);
+ /* node location is mapped */
+ locx /= UI_DPI_FAC;
+ locy /= UI_DPI_FAC;
+
gnode = node_tree_get_editgroup(snode->nodetree);
// arbitrary y offset of 60 so its visible
if (gnode) {
- nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy);
+ node_from_view(gnode, locx, locy + 60.0f, &node->locx, &node->locy);
}
else {
node->locx = locx;
@@ -203,7 +207,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
}
add_v2_v2(insert_point, socklink->point);
- ++num_links;
+ num_links++;
}
socklink = socklink->next;
}
@@ -215,7 +219,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
mul_v2_fl(insert_point, 1.0f / num_links);
if (gnode) {
- nodeFromView(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy);
+ node_from_view(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy);
}
else {
reroute_node->locx = insert_point[0];
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index da077d9..300328f 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -184,6 +184,7 @@ void node_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil");
strcpy(pt->idname, "NODE_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
pt->poll = active_nodetree_poll;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 72461cf..2b10637 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -278,6 +278,21 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
}
}
+void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry)
+{
+ nodeToView(node, x, y, rx, ry);
+ *rx *= UI_DPI_FAC;
+ *ry *= UI_DPI_FAC;
+}
+
+void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry)
+{
+ x /= UI_DPI_FAC;
+ y /= UI_DPI_FAC;
+ nodeFromView(node, x, y, rx, ry);
+}
+
+
/* based on settings in node, sets drawing rect info. each redraw! */
static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
{
@@ -289,7 +304,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
int buty;
/* get "global" coords */
- nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
dy = locy;
/* header */
@@ -302,14 +317,14 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* output sockets */
for (nsock = node->outputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
- nsock->locx = locx + node->width;
+ nsock->locx = locx + NODE_WIDTH(node);
nsock->locy = dy - NODE_DYS;
dy -= NODE_DY;
}
}
node->prvr.xmin = locx + NODE_DYS;
- node->prvr.xmax = locx + node->width - NODE_DYS;
+ node->prvr.xmax = locx + NODE_WIDTH(node) - NODE_DYS;
/* preview rect? */
if (node->flag & NODE_PREVIEW) {
@@ -323,12 +338,13 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
node->prvr.ymax = dy;
if (aspect <= 1.0f)
- node->prvr.ymin = dy - aspect * (node->width - NODE_DY);
+ node->prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY);
else {
/* width correction of image */
- float dx = (node->width - NODE_DYS) - (node->width - NODE_DYS) / aspect;
+ /* XXX huh? (ton) */
+ float dx = (NODE_WIDTH(node) - NODE_DYS) - (NODE_WIDTH(node) - NODE_DYS) / aspect;
- node->prvr.ymin = dy - (node->width - NODE_DY);
+ node->prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY);
node->prvr.xmin += 0.5f * dx;
node->prvr.xmax -= 0.5f * dx;
@@ -343,7 +359,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
else {
float oldh = BLI_rctf_size_y(&node->prvr);
if (oldh == 0.0f)
- oldh = 0.6f * node->width - NODE_DY;
+ oldh = 0.6f * NODE_WIDTH(node) - NODE_DY;
dy -= NODE_DYS / 2;
node->prvr.ymax = dy;
node->prvr.ymin = dy - oldh;
@@ -357,21 +373,22 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* set this for uifunc() that don't use layout engine yet */
node->butr.xmin = 0;
- node->butr.xmax = node->width - 2 * NODE_DYS;
+ node->butr.xmax = NODE_WIDTH(node) - 2 * NODE_DYS;
node->butr.ymin = 0;
node->butr.ymax = 0;
RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+
layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
- locx + NODE_DYS, dy, node->butr.xmax, NODE_DY, UI_GetStyle());
+ locx + NODE_DYS, dy, node->butr.xmax, 0, UI_GetStyle());
uiLayoutSetContextPointer(layout, "node", &ptr);
node->typeinfo->uifunc(layout, (bContext *)C, &ptr);
uiBlockEndAlign(node->block);
uiBlockLayoutResolve(node->block, NULL, &buty);
-
+
dy = buty - NODE_DYS / 2;
}
@@ -389,7 +406,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
dy -= NODE_DYS / 2;
node->totr.xmin = locx;
- node->totr.xmax = locx + node->width;
+ node->totr.xmax = locx + NODE_WIDTH(node);
node->totr.ymax = locy;
node->totr.ymin = min_ff(dy, locy - 2 * NODE_DY);
@@ -412,7 +429,7 @@ static void node_update_hidden(bNode *node)
int totin = 0, totout = 0, tot;
/* get "global" coords */
- nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
/* calculate minimal radius */
for (nsock = node->inputs.first; nsock; nsock = nsock->next)
@@ -437,8 +454,8 @@ static void node_update_hidden(bNode *node)
for (nsock = node->outputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
- nsock->locx = node->totr.xmax - hiddenrad + (float)sin(rad) * hiddenrad;
- nsock->locy = node->totr.ymin + hiddenrad + (float)cos(rad) * hiddenrad;
+ nsock->locx = node->totr.xmax - hiddenrad + sinf(rad) * hiddenrad;
+ nsock->locy = node->totr.ymin + hiddenrad + cosf(rad) * hiddenrad;
rad += drad;
}
}
@@ -448,8 +465,8 @@ static void node_update_hidden(bNode *node)
for (nsock = node->inputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
- nsock->locx = node->totr.xmin + hiddenrad + (float)sin(rad) * hiddenrad;
- nsock->locy = node->totr.ymin + hiddenrad + (float)cos(rad) * hiddenrad;
+ nsock->locx = node->totr.xmin + hiddenrad + sinf(rad) * hiddenrad;
+ nsock->locy = node->totr.ymin + hiddenrad + cosf(rad) * hiddenrad;
rad += drad;
}
}
@@ -700,7 +717,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
/* show/hide icons */
- iconofs = rct->xmax - 7.0f;
+ iconofs = rct->xmax - 0.35f * U.widget_unit;
/* preview */
if (node->typeinfo->flag & NODE_PREVIEW) {
@@ -742,13 +759,13 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
uiBlockSetEmboss(node->block, UI_EMBOSSN);
but = uiDefBut(node->block, TOGBUT, B_REDR, "",
- rct->xmin + 10.0f - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2,
+ rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2,
but_size, but_size, NULL, 0, 0, 0, 0, "");
uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
uiBlockSetEmboss(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_DrawTriIcon(rct->xmin + 10.0f, rct->ymax - NODE_DY / 2.0f, 'v');
+ UI_DrawTriIcon(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v');
}
/* this isn't doing anything for the label, so commenting out */
@@ -765,7 +782,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
uiDefBut(node->block, LABEL, 0, showname,
- (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(rct->ymax - NODE_DY),
+ (int)(rct->xmin + (NODE_MARGIN_X)), (int)(rct->ymax - NODE_DY),
(short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY,
NULL, 0, 0, 0, 0, "");
@@ -808,8 +825,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT);
node->typeinfo->drawinputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name),
- sock->locx + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS,
- node->width - NODE_DY);
+ sock->locx + (NODE_DYS), sock->locy - NODE_DYS,
+ NODE_WIDTH(node) - NODE_DY);
}
/* socket outputs */
@@ -820,8 +837,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT);
node->typeinfo->drawoutputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name),
- sock->locx - node->width + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS,
- node->width - NODE_DY);
+ sock->locx - NODE_WIDTH(node) + (NODE_DYS), sock->locy - NODE_DYS,
+ NODE_WIDTH(node) - NODE_DY);
}
/* preview */
@@ -843,7 +860,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
rctf *rct = &node->totr;
float dx, centy = BLI_rctf_cent_y(rct);
float hiddenrad = BLI_rctf_size_y(rct) / 2.0f;
- float socket_size = NODE_SOCKSIZE * UI_DPI_ICON_FAC;
+ float socket_size = NODE_SOCKSIZE;
int color_id = node_get_colorid(node);
char showname[128]; /* 128 is used below */
@@ -920,7 +937,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
uiDefBut(node->block, LABEL, 0, showname,
- (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(centy - 10),
+ (int)(rct->xmin + (NODE_MARGIN_X)), (int)(centy - 10),
(short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY,
NULL, 0, 0, 0, 0, "");
}
@@ -1011,7 +1028,7 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, fl
/* update nodes front to back, so children sizes get updated before parents */
for (node = ntree->nodes.last; node; node = node->prev) {
- /* XXX little hack */
+ /* XXX little hack (not used anyore?) */
node->locx += offsetx;
node->locy += offsety;
@@ -1082,7 +1099,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLinkDrag *nldrag;
LinkData *linkdata;
-
+
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
@@ -1098,11 +1115,10 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
/* aspect+font, set each time */
snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)ar->winx;
- snode->aspect_sqrt = sqrtf(snode->aspect);
// XXX snode->curfont = uiSetCurFont_ext(snode->aspect);
/* grid */
- UI_view2d_multi_grid_draw(v2d, 25.0f, 5, 2);
+ UI_view2d_multi_grid_draw(v2d, U.widget_unit, 5, 2);
/* backdrop */
draw_nodespace_back_pix(C, ar, snode);
@@ -1156,16 +1172,22 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
- /* draw grease-pencil ('canvas' strokes) */
- if (snode->nodetree)
- draw_gpencil_view2d(C, 1);
+ if (snode->flag & SNODE_SHOW_GPENCIL) {
+ /* draw grease-pencil ('canvas' strokes) */
+ if (snode->nodetree) {
+ draw_gpencil_view2d(C, TRUE);
+ }
+ }
/* reset view matrix */
UI_view2d_view_restore(C);
- /* draw grease-pencil (screen strokes, and also paintbuffer) */
- if (snode->nodetree)
- draw_gpencil_view2d(C, 0);
+ if (snode->flag & SNODE_SHOW_GPENCIL) {
+ /* draw grease-pencil (screen strokes, and also paintbuffer) */
+ if (snode->nodetree) {
+ draw_gpencil_view2d(C, FALSE);
+ }
+ }
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index f757345..ae95d9a 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -874,8 +874,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
case MOUSEMOVE:
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
- dx = mx - nsw->mxstart;
- dy = my - nsw->mystart;
+ dx = (mx - nsw->mxstart) / UI_DPI_FAC;
+ dy = (my - nsw->mystart) / UI_DPI_FAC;
if (node) {
if (node->flag & NODE_HIDDEN) {
@@ -894,8 +894,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
}
}
else {
- float widthmin = UI_DPI_FAC * node->typeinfo->minwidth;
- float widthmax = UI_DPI_FAC * node->typeinfo->maxwidth;
+ float widthmin = node->typeinfo->minwidth;
+ float widthmax = node->typeinfo->maxwidth;
if (nsw->directions & NODE_RESIZE_RIGHT) {
node->width = nsw->oldwidth + dx;
CLAMP(node->width, widthmin, widthmax);
@@ -1967,7 +1967,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
/* get group node offset */
if (gnode)
- nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y);
+ node_to_view(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y);
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
@@ -2080,7 +2080,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* get group node offset */
if (gnode) {
- nodeToView(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]);
+ node_to_view(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]);
}
else {
zero_v2(gnode_center);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 45509e0..e8dd1cf 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -48,6 +48,7 @@ struct bNode;
struct bNodeSocket;
struct bNodeLink;
struct Main;
+struct wmKeyConfig;
/* temp data to pass on to modal */
typedef struct bNodeLinkDrag {
@@ -63,6 +64,7 @@ typedef struct bNodeLinkDrag {
/* space_node.c */
ARegion *node_has_buttons_region(ScrArea *sa);
+ARegion *node_has_tools_region(ScrArea *sa);
/* node_header.c */
void node_menus_register(void);
@@ -81,14 +83,21 @@ void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct Spa
void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode);
+ /* DPI scaled coords */
+void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
+void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
/* node_buttons.c */
void node_buttons_register(struct ARegionType *art);
void NODE_OT_properties(struct wmOperatorType *ot);
+/* node_toolbar.c */
+void node_toolbar_register(struct ARegionType *art);
+void NODE_OT_toolbar(struct wmOperatorType *ot);
+
/* node_ops.c */
void node_operatortypes(void);
-void node_keymap(wmKeyConfig *keyconf);
+void node_keymap(struct wmKeyConfig *keyconf);
/* node_select.c */
void node_select(struct bNode *node);
@@ -103,14 +112,14 @@ int node_select_same_type_np(struct SpaceNode *snode, int dir);
void node_select_single(struct bContext *C, struct bNode *node);
void NODE_OT_select(struct wmOperatorType *ot);
-void NODE_OT_select_all(wmOperatorType *ot);
-void NODE_OT_select_linked_to(wmOperatorType *ot);
-void NODE_OT_select_linked_from(wmOperatorType *ot);
+void NODE_OT_select_all(struct wmOperatorType *ot);
+void NODE_OT_select_linked_to(struct wmOperatorType *ot);
+void NODE_OT_select_linked_from(struct wmOperatorType *ot);
void NODE_OT_select_border(struct wmOperatorType *ot);
void NODE_OT_select_lasso(struct wmOperatorType *ot);
void NODE_OT_select_same_type(struct wmOperatorType *ot);
-void NODE_OT_select_same_type_next(wmOperatorType *ot);
-void NODE_OT_select_same_type_prev(wmOperatorType *ot);
+void NODE_OT_select_same_type_next(struct wmOperatorType *ot);
+void NODE_OT_select_same_type_prev(struct wmOperatorType *ot);
/* node_view.c */
void NODE_OT_view_all(struct wmOperatorType *ot);
@@ -118,14 +127,14 @@ void NODE_OT_view_selected(struct wmOperatorType *ot);
void NODE_OT_backimage_move(struct wmOperatorType *ot);
void NODE_OT_backimage_zoom(struct wmOperatorType *ot);
-void NODE_OT_backimage_sample(wmOperatorType *ot);
+void NODE_OT_backimage_sample(struct wmOperatorType *ot);
/* drawnode.c */
-void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link);
-void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3);
-int node_link_bezier_points(View2D * v2d, SpaceNode * snode, bNodeLink * link, float coord_array[][2], int resol);
+void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link);
+void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3);
+int node_link_bezier_points(struct View2D * v2d, struct SpaceNode * snode, struct bNodeLink * link, float coord_array[][2], int resol);
// void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 );
-void draw_nodespace_back_pix(const struct bContext *C, ARegion *ar, SpaceNode *snode);
+void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode);
/* node_add.c */
@@ -167,10 +176,10 @@ void NODE_OT_link_viewer(struct wmOperatorType *ot);
/* node_edit.c */
void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype);
-void snode_notify(bContext *C, SpaceNode *snode);
-void snode_dag_update(bContext *C, SpaceNode *snode);
-void snode_set_context(SpaceNode *snode, Scene *scene);
-void snode_make_group_editable(SpaceNode *snode, bNode *gnode);
+void snode_notify(struct bContext *C, struct SpaceNode *snode);
+void snode_dag_update(struct bContext *C, struct SpaceNode *snode);
+void snode_set_context(struct SpaceNode *snode, Scene *scene);
+void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode);
bNode *node_tree_get_editgroup(bNodeTree *ntree);
void snode_update(struct SpaceNode *snode, struct bNode *node);
@@ -179,7 +188,7 @@ int composite_node_active(struct bContext *C);
int node_has_hidden_sockets(bNode *node);
void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set);
-int node_render_changed_exec(bContext *, wmOperator *);
+int node_render_changed_exec(bContext *, struct wmOperator *);
int node_find_indicated_socket(struct SpaceNode *snode, struct bNode **nodep, struct bNodeSocket **sockp, int in_out);
void NODE_OT_duplicate(struct wmOperatorType *ot);
@@ -212,13 +221,14 @@ extern const char *node_context_dir[];
// XXXXXX
-// XXX from BSE_node.h
-#define HIDDEN_RAD 15.0f
-#define BASIS_RAD 8.0f
+// nodes draw without dpi - the view zoom is flexible
+#define HIDDEN_RAD (0.75f * U.widget_unit)
+#define BASIS_RAD (0.4f * U.widget_unit)
#define NODE_DYS (U.widget_unit / 2)
#define NODE_DY U.widget_unit
-#define NODE_MARGIN_X 15
-#define NODE_SOCKSIZE 5
+#define NODE_WIDTH(node) (node->width * UI_DPI_FAC)
+#define NODE_MARGIN_X (0.75f * U.widget_unit)
+#define NODE_SOCKSIZE (0.25f * U.widget_unit)
#define NODE_LINK_RESOL 12
// XXX button events (butspace)
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 64e5f67..8adccd9 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -49,6 +49,7 @@
void node_operatortypes(void)
{
WM_operatortype_append(NODE_OT_properties);
+ WM_operatortype_append(NODE_OT_toolbar);
WM_operatortype_append(NODE_OT_select);
WM_operatortype_append(NODE_OT_select_all);
@@ -204,6 +205,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Node Generic", SPACE_NODE, 0);
WM_keymap_add_item(keymap, "NODE_OT_properties", NKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_toolbar", TKEY, KM_PRESS, 0, 0);
/* Main Area only ----------------- */
keymap = WM_keymap_find(keyconf, "Node Editor", SPACE_NODE, 0);
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 23f4e94..ca85415 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -30,6 +30,7 @@
#include "DNA_node_types.h"
#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -52,6 +53,8 @@
#include "ED_util.h"
+#include "node_intern.h"
+
/************************* Node Socket Manipulation **************************/
static void node_tag_recursive(bNode *node)
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
new file mode 100644
index 0000000..86da400
--- /dev/null
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -0,0 +1,92 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_node/node_toolbar.c
+ * \ingroup nodes
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "DNA_node_types.h"
+
+#include "BKE_context.h"
+#include "BKE_node.h"
+#include "BKE_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_intern.h" /* own include */
+
+
+/* ******************* node toolbar registration ************** */
+
+void node_toolbar_register(ARegionType *UNUSED(art))
+{
+}
+
+/* ********** operator to open/close toolshelf region */
+
+static int node_toolbar(bContext *C, wmOperator *UNUSED(op))
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = node_has_tools_region(sa);
+
+ if (ar)
+ ED_region_toggle_hidden(C, ar);
+
+ return OPERATOR_FINISHED;
+}
+
+/* non-standard poll operator which doesn't care if there are any nodes */
+static int node_toolbar_poll(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ return (sa && (sa->spacetype == SPACE_NODE));
+}
+
+void NODE_OT_toolbar(wmOperatorType *ot)
+{
+ ot->name = "Tool Shelf";
+ ot->description = "Toggles tool shelf display";
+ ot->idname = "NODE_OT_toolbar";
+
+ ot->exec = node_toolbar;
+ ot->poll = node_toolbar_poll;
+
+ /* flags */
+ ot->flag = 0;
+}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index f386657..a69e73c 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -69,12 +69,15 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
bNode *node;
rctf cur_new;
float oldwidth, oldheight, width, height;
+ float oldasp, asp;
int tot = 0;
int has_frame = FALSE;
oldwidth = BLI_rctf_size_x(&ar->v2d.cur);
oldheight = BLI_rctf_size_y(&ar->v2d.cur);
+ oldasp = oldwidth / oldheight;
+
BLI_rctf_init_minmax(&cur_new);
if (snode->edittree) {
@@ -93,6 +96,7 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
if (tot) {
width = BLI_rctf_size_x(&cur_new);
height = BLI_rctf_size_y(&cur_new);
+ asp = width / height;
/* for single non-frame nodes, don't zoom in, just pan view,
* but do allow zooming out, this allows for big nodes to be zoomed out */
@@ -104,18 +108,19 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons
BLI_rctf_resize(&cur_new, oldwidth, oldheight);
}
else {
- if (width > height) {
- float newheight;
- newheight = oldheight * width / oldwidth;
- cur_new.ymin = cur_new.ymin - newheight / 4;
- cur_new.ymax = cur_new.ymax + newheight / 4;
+ if (oldasp < asp) {
+ const float height_new = width / oldasp;
+ cur_new.ymin = cur_new.ymin - height_new / 2.0f;
+ cur_new.ymax = cur_new.ymax + height_new / 2.0f;
}
else {
- float newwidth;
- newwidth = oldwidth * height / oldheight;
- cur_new.xmin = cur_new.xmin - newwidth / 4;
- cur_new.xmax = cur_new.xmax + newwidth / 4;
+ const float width_new = height * oldasp;
+ cur_new.xmin = cur_new.xmin - width_new / 2.0f;
+ cur_new.xmax = cur_new.xmax + width_new / 2.0f;
}
+
+ /* add some padding */
+ BLI_rctf_scale(&cur_new, 1.1f);
}
UI_view2d_smooth_view(C, ar, &cur_new);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index f7e0d51..513f6b4 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -85,6 +85,30 @@ ARegion *node_has_buttons_region(ScrArea *sa)
return arnew;
}
+ARegion *node_has_tools_region(ScrArea *sa)
+{
+ ARegion *ar, *arnew;
+
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
+ if (ar) return ar;
+
+ /* add subdiv level; after header */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+
+ /* is error! */
+ if (ar == NULL) return NULL;
+
+ arnew = MEM_callocN(sizeof(ARegion), "node tools");
+
+ BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+ arnew->regiontype = RGN_TYPE_TOOLS;
+ arnew->alignment = RGN_ALIGN_LEFT;
+
+ arnew->flag = RGN_FLAG_HIDDEN;
+
+ return arnew;
+}
+
/* ******************** default callbacks for node space ***************** */
static SpaceLink *node_new(const bContext *UNUSED(C))
@@ -95,6 +119,8 @@ static SpaceLink *node_new(const bContext *UNUSED(C))
snode = MEM_callocN(sizeof(SpaceNode), "initnode");
snode->spacetype = SPACE_NODE;
+ snode->flag = SNODE_SHOW_GPENCIL;
+
/* backdrop */
snode->zoom = 1.0f;
@@ -118,15 +144,12 @@ static SpaceLink *node_new(const bContext *UNUSED(C))
BLI_addtail(&snode->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.tot.xmin = -256.0f;
- ar->v2d.tot.ymin = -256.0f;
- ar->v2d.tot.xmax = 768.0f;
- ar->v2d.tot.ymax = 768.0f;
+ ar->v2d.tot.xmin = -12.8f * U.widget_unit;
+ ar->v2d.tot.ymin = -12.8f * U.widget_unit;
+ ar->v2d.tot.xmax = 38.4f * U.widget_unit;
+ ar->v2d.tot.ymax = 38.4f * U.widget_unit;
- ar->v2d.cur.xmin = -256.0f;
- ar->v2d.cur.ymin = -256.0f;
- ar->v2d.cur.xmax = 768.0f;
- ar->v2d.cur.ymax = 768.0f;
+ ar->v2d.cur = ar->v2d.tot;
ar->v2d.min[0] = 1.0f;
ar->v2d.min[1] = 1.0f;
@@ -342,6 +365,22 @@ static void node_buttons_area_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, 1, NULL, -1);
}
+/* add handlers, stuff you only do once or on area/region changes */
+static void node_toolbar_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ wmKeyMap *keymap;
+
+ ED_region_panels_init(wm, ar);
+
+ keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+}
+
+static void node_toolbar_area_draw(const bContext *C, ARegion *ar)
+{
+ ED_region_panels(C, ar, 1, NULL, -1);
+}
+
static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
{
SpaceNode *snode = sa->spacedata.first;
@@ -570,6 +609,19 @@ void ED_spacetype_node(void)
node_buttons_register(art);
+ /* regions: toolbar */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
+ art->regionid = RGN_TYPE_TOOLS;
+ art->prefsizex = 160; /* XXX */
+ art->prefsizey = 50; /* XXX */
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+ art->listener = node_region_listener;
+ art->init = node_toolbar_area_init;
+ art->draw = node_toolbar_area_draw;
+ BLI_addhead(&st->regiontypes, art);
+
+ node_toolbar_register(art);
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_outliner/SConscript b/source/blender/editors/space_outliner/SConscript
index a6f2e3c..1bb7194 100644
--- a/source/blender/editors/space_outliner/SConscript
+++ b/source/blender/editors/space_outliner/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index d37cb4b..1a05810 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -421,17 +421,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
@@ -445,15 +445,21 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
+ bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -463,7 +469,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -476,13 +483,18 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, layflag, 0, 0, 0, 0, "Render this Pass");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ layflag, 0, 0, 0, 0, "Render this Pass");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
layflag++; /* is lay_xor */
- if (ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
+ if (ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT,
+ SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
+ {
bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ }
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -493,11 +505,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
}
else if (tselem->type == TSE_POSE_CHANNEL) {
@@ -506,11 +520,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
}
else if (tselem->type == TSE_EBONE) {
@@ -518,11 +534,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL);
}
}
@@ -535,7 +553,7 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
{
View2D *v2d = &ar->v2d;
- float miny = v2d->cur.ymin - V2D_SCROLL_HEIGHT;
+ float miny = v2d->cur.ymin;
if (miny < v2d->tot.ymin) miny = v2d->tot.ymin;
UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
@@ -832,7 +850,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
/* rna property */
if (kmi->ptr && kmi->ptr->data) {
- uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->oskey, 0, 0, 0, 0, ""); xstart += butw2;
+ uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, ""); xstart += butw2;
}
(void)xstart;
@@ -893,7 +911,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
struct DrawIconArg {
uiBlock *block;
ID *id;
- int xmax, x, y;
+ float xmax, x, y, xb, yb;
float alpha;
};
@@ -902,13 +920,11 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
/* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */
if (arg->x >= arg->xmax) {
glEnable(GL_BLEND);
- UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f, arg->alpha);
+ UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_FAC, arg->alpha);
glDisable(GL_BLEND);
}
else {
- /* XXX investigate: button placement of icons is way different than UI_icon_draw? */
- float ufac = UI_UNIT_X / 20.0f;
- uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->x - 3.0f * ufac, arg->y, UI_UNIT_X - 4.0f * ufac, UI_UNIT_Y - 4.0f * ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+ uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
if (arg->id)
uiButSetDragID(but, arg->id);
@@ -919,15 +935,24 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha)
{
struct DrawIconArg arg;
+ float aspect;
+
+ /* icons tiny bit away from text */
+ x -= 0.15f * UI_UNIT_Y;
/* make function calls a bit compacter */
arg.block = block;
arg.id = tselem->id;
arg.xmax = xmax;
- arg.x = x;
- arg.y = y;
+ arg.xb = x; /* for ui buttons */
+ arg.yb = y;
arg.alpha = alpha;
+ /* placement of icons, copied from interface_widgets.c */
+ aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
+ arg.x = x = x + 4.0f * aspect;
+ arg.y = y = y + 0.1f * UI_UNIT_Y;
+
if (tselem->type) {
switch (tselem->type) {
case TSE_ANIM_DATA:
@@ -989,6 +1014,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
case eModifierType_Array:
UI_icon_draw(x, y, ICON_MOD_ARRAY); break;
case eModifierType_UVProject:
+ case eModifierType_UVWarp: /* TODO, get own icon */
UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break;
case eModifierType_Displace:
UI_icon_draw(x, y, ICON_MOD_DISPLACE); break;
@@ -1220,11 +1246,11 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
uiSetRoundBox(UI_CNR_ALL);
glColor4ub(255, 255, 255, 100);
- uiRoundBox((float) *offsx - 0.5f * ufac,
- (float)ys - 1.0f * ufac,
- (float)*offsx + UI_UNIT_Y - 3.0f * ufac,
- (float)ys + UI_UNIT_Y - 3.0f * ufac,
- (float)UI_UNIT_Y / 2.0f - 2.0f * ufac);
+ uiRoundBox((float) *offsx - 1.0f * ufac,
+ (float)ys + 1.0f * ufac,
+ (float)*offsx + UI_UNIT_X - 2.0f * ufac,
+ (float)ys + UI_UNIT_Y - ufac,
+ (float)UI_UNIT_Y / 2.0f - ufac);
glEnable(GL_BLEND); /* roundbox disables */
}
@@ -1270,6 +1296,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) {
int xmax = ar->v2d.cur.xmax;
+ unsigned char alpha = 128;
/* icons can be ui buts, we don't want it to overlap with restrict */
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
@@ -1286,16 +1313,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
{
char col[4];
UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col);
- col[3] = 100;
+ col[3] = alpha;
glColor4ubv((GLubyte *)col);
glRecti(startx, *starty + 1, ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
}
/* colors for active/selected data */
if (tselem->type == 0) {
+
if (te->idcode == ID_SCE) {
if (tselem->id == (ID *)scene) {
- glColor4ub(255, 255, 255, 100);
+ glColor4ub(255, 255, 255, alpha);
active = 2;
}
}
@@ -1304,7 +1332,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (group_select_flag(gr)) {
char col[4];
UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
- col[3] = 100;
+ col[3] = alpha;
glColor4ubv((GLubyte *)col);
active = 2;
@@ -1322,14 +1350,14 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (ob == OBACT) {
if (ob->flag & SELECT) {
UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
- col[3] = 100;
+ col[3] = alpha;
}
active = 1; /* means it draws white text */
}
else if (ob->flag & SELECT) {
UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col);
- col[3] = 100;
+ col[3] = alpha;
}
glColor4ubv((GLubyte *)col);
@@ -1337,29 +1365,29 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
}
else if (scene->obedit && scene->obedit->data == tselem->id) {
- glColor4ub(255, 255, 255, 100);
+ glColor4ub(255, 255, 255, alpha);
active = 2;
}
else {
if (tree_element_active(C, scene, soops, te, 0)) {
- glColor4ub(220, 220, 255, 100);
+ glColor4ub(220, 220, 255, alpha);
active = 2;
}
}
}
else {
if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2;
- glColor4ub(220, 220, 255, 100);
+ glColor4ub(220, 220, 255, alpha);
}
/* active circle */
if (active) {
uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox((float)startx + UI_UNIT_Y - 1.5f * ufac,
- (float)*starty + 2.0f * ufac,
- (float)startx + 2.0f * UI_UNIT_Y - 4.0f * ufac,
+ uiRoundBox((float)startx + UI_UNIT_X,
+ (float)*starty + 1.0f * ufac,
+ (float)startx + 2.0f * UI_UNIT_X - 2.0f * ufac,
(float)*starty + UI_UNIT_Y - 1.0f * ufac,
- UI_UNIT_Y / 2.0f - 2.0f * ufac);
+ UI_UNIT_Y / 2.0f - 1.0f * ufac);
glEnable(GL_BLEND); /* roundbox disables it */
te->flag |= TE_ACTIVE; // for lookup in display hierarchies
@@ -1384,8 +1412,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* datatype icon */
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) {
- // icons a bit higher
- tselem_draw_icon(block, xmax, (float)startx + offsx - 0.5f * ufac, (float)*starty + 2.0f * ufac, tselem, te, 1.0f);
+
+ tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, 1.0f);
offsx += UI_UNIT_X;
}
@@ -1425,12 +1453,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* divider */
UI_ThemeColorShade(TH_BACK, -40);
- glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4);
+ glRecti(tempx - 10.0f * ufac,
+ *starty + 4.0f * ufac,
+ tempx - 8.0f * ufac,
+ *starty + UI_UNIT_Y - 4.0f * ufac);
glEnable(GL_BLEND);
glPixelTransferf(GL_ALPHA_SCALE, 0.5);
- outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty + 2);
+ outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty);
glPixelTransferf(GL_ALPHA_SCALE, 1.0);
glDisable(GL_BLEND);
@@ -1502,13 +1533,13 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
/* selection status */
if (TSELEM_OPEN(tselem, soops))
if (tselem->type == TSE_RNA_STRUCT)
- glRecti(0, *starty + 1, (int)ar->v2d.cur.xmax + V2D_SCROLL_WIDTH, *starty + UI_UNIT_Y - 1);
+ glRecti(0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
*starty -= UI_UNIT_Y;
if (TSELEM_OPEN(tselem, soops)) {
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
if (tselem->type == TSE_RNA_STRUCT)
- fdrawline(0, (float)*starty + UI_UNIT_Y, ar->v2d.cur.xmax + V2D_SCROLL_WIDTH, (float)*starty + UI_UNIT_Y);
+ fdrawline(0, (float)*starty + UI_UNIT_Y, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
}
}
}
@@ -1577,7 +1608,7 @@ static void outliner_back(ARegion *ar)
ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
while (ystart + 2 * UI_UNIT_Y > ar->v2d.cur.ymin) {
- glRecti(0, ystart, (int)ar->v2d.cur.xmax + V2D_SCROLL_WIDTH, ystart + UI_UNIT_Y);
+ glRecti(0, ystart, (int)ar->v2d.cur.xmax, ystart + UI_UNIT_Y);
ystart -= 2 * UI_UNIT_Y;
}
}
@@ -1588,10 +1619,8 @@ static void outliner_draw_restrictcols(ARegion *ar)
/* background underneath */
UI_ThemeColor(TH_BACK);
- glRecti((int)ar->v2d.cur.xmax - OL_TOGW,
- (int)ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT - 1,
- (int)ar->v2d.cur.xmax + V2D_SCROLL_WIDTH,
- (int)ar->v2d.cur.ymax);
+ glRecti((int)(ar->v2d.cur.xmax - OL_TOGW),
+ (int)(ar->v2d.cur.ymin - 1), (int)ar->v2d.cur.xmax, (int)ar->v2d.cur.ymax);
UI_ThemeColorShade(TH_BACK, 6);
ystart = (int)ar->v2d.tot.ymax;
@@ -1605,38 +1634,38 @@ static void outliner_draw_restrictcols(ARegion *ar)
UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
/* view */
- fdrawline(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX,
- ar->v2d.cur.ymax,
- ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX,
- ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT);
+ sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)ar->v2d.cur.ymax,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX),
+ (int)ar->v2d.cur.ymin);
/* render */
- fdrawline(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX,
- ar->v2d.cur.ymax,
- ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX,
- ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT);
+ sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ (int)ar->v2d.cur.ymax,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX),
+ (int)ar->v2d.cur.ymin);
/* render */
- fdrawline(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX,
- ar->v2d.cur.ymax,
- ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX,
- ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT);
+ sdrawline((int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ (int)ar->v2d.cur.ymax,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX),
+ (int)ar->v2d.cur.ymin);
}
/* ****************************************************** */
/* Main Entrypoint - Draw contents of Outliner editor */
-
+
void draw_outliner(const bContext *C)
{
- Main *mainvar = CTX_data_main(C);
+ Main *mainvar = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
SpaceOops *soops = CTX_wm_space_outliner(C);
uiBlock *block;
int sizey = 0, sizex = 0, sizex_rna = 0;
-
- outliner_build_tree(mainvar, scene, soops); // always
+
+ outliner_build_tree(mainvar, scene, soops); // always
/* get extents of data */
outliner_height(soops, &soops->tree, &sizey);
@@ -1669,11 +1698,9 @@ void draw_outliner(const bContext *C)
// XXX this isn't that great yet...
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
sizex += OL_TOGW * 3;
+
}
- /* tweak to display last line (when list bigger than window) */
- sizey += V2D_SCROLL_HEIGHT;
-
/* adds vertical offset */
sizey += OL_Y_OFFSET;
@@ -1709,7 +1736,7 @@ void draw_outliner(const bContext *C)
uiEndBlock(C, block);
uiDrawBlock(C, block);
-
+
/* clear flag that allows quick redraws */
soops->storeflag &= ~SO_TREESTORE_REDRAW;
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index d11a8ed..a087ff6 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -183,8 +183,8 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, ReportList *reports)
{
- /* can't rename rna datablocks entries */
- if (ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ /* can't rename rna datablocks entries or listbases */
+ if (ELEM4(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE)) {
/* do nothing */;
}
else if (ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE,
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 65de2a2..63452de 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -103,6 +103,7 @@ typedef struct TreeElement {
#define TSE_NLA_TRACK 33
#define TSE_KEYMAP 34
#define TSE_KEYMAP_ITEM 35
+#define TSE_ID_BASE 36
/* button events */
#define OL_NAMEBUTTON 1
@@ -115,8 +116,8 @@ typedef struct TreeElement {
/* size constants */
#define OL_Y_OFFSET 2
-#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 3)
-#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 2)
+#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 3.0f)
+#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 2.0f)
#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X
#define OL_TOGW OL_TOG_RESTRICT_VIEWX
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 0b585e1..fa337ba 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -336,7 +336,8 @@ static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops
tep = te->parent;
if (tep) {
tselem = TREESTORE(tep);
- sce = (Scene *)tselem->id;
+ if (tselem->type == 0)
+ sce = (Scene *)tselem->id;
}
if (set) { // make new scene active
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 3b83279..b2070cc 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -764,7 +764,7 @@ static EnumPropertyItem prop_id_op_types[] = {
{OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
{OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
{OUTLINER_IDOP_FAKE_ADD, "ADD_FAKE", 0, "Add Fake User",
- "Ensure datablock gets saved even if it isn't in use (e.g. for motion and material libraries)"},
+ "Ensure datablock gets saved even if it isn't in use (e.g. for motion and material libraries)"},
{OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""},
{OUTLINER_IDOP_RENAME, "RENAME", 0, "Rename", ""},
{OUTLINER_IDOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index e691028..f723fbe 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -66,8 +66,10 @@
#include "BKE_fcurve.h"
#include "BKE_main.h"
+#include "BKE_library.h"
#include "BKE_modifier.h"
#include "BKE_sequencer.h"
+#include "BKE_idcode.h"
#include "ED_armature.h"
#include "ED_screen.h"
@@ -593,6 +595,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0);
}
+
// can be inlined if necessary
static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, ID *id)
{
@@ -785,6 +788,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
}
// TODO: this function needs to be split up! It's getting a bit too large...
+// Note: "ID" is not always a real ID
static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
TreeElement *parent, short type, short index)
{
@@ -798,7 +802,13 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (!id) id = ((PointerRNA *)idv)->data;
}
- if (id == NULL) return NULL;
+ /* One exception */
+ if (type == TSE_ID_BASE) {
+ /* pass */
+ }
+ else if (id == NULL) {
+ return NULL;
+ }
te = MEM_callocN(sizeof(TreeElement), "tree elem");
/* add to the visual tree */
@@ -822,14 +832,24 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if (type == TSE_ANIM_DATA) {
/* pass */
}
+ else if (type == TSE_ID_BASE) {
+ /* pass */
+ }
else {
- te->name = id->name + 2; // default, can be overridden by Library or non-ID data
+ /* do here too, for blend file viewer, own ID_LI then shows file name */
+ if (GS(id->name) == ID_LI)
+ te->name = ((Library *)id)->name;
+ else
+ te->name = id->name + 2; // default, can be overridden by Library or non-ID data
te->idcode = GS(id->name);
}
if (type == 0) {
+ TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
+
/* ID datablock */
- outliner_add_id_contents(soops, te, tselem, id);
+ if (tsepar == NULL || tsepar->type != TSE_ID_BASE)
+ outliner_add_id_contents(soops, te, tselem, id);
}
else if (type == TSE_ANIM_DATA) {
IdAdtTemplate *iat = (IdAdtTemplate *)idv;
@@ -1194,8 +1214,8 @@ typedef struct tTreeSort {
short idcode;
} tTreeSort;
-/* alphabetical comparator */
-static int treesort_alpha(const void *v1, const void *v2)
+/* alphabetical comparator, tryping to put objects first */
+static int treesort_alpha_ob(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
int comp;
@@ -1216,6 +1236,20 @@ static int treesort_alpha(const void *v1, const void *v2)
return 0;
}
+/* alphabetical comparator */
+static int treesort_alpha(const void *v1, const void *v2)
+{
+ const tTreeSort *x1 = v1, *x2 = v2;
+ int comp;
+
+ comp = strcmp(x1->name, x2->name);
+
+ if (comp > 0) return 1;
+ else if (comp < 0) return -1;
+ return 0;
+}
+
+
/* this is nice option for later? doesnt look too useful... */
#if 0
static int treesort_obtype_alpha(const void *v1, const void *v2)
@@ -1254,8 +1288,8 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
if (te == NULL) return;
tselem = TREESTORE(te);
- /* sorting rules; only object lists or deformgroups */
- if ((tselem->type == TSE_DEFGROUP) || (tselem->type == 0 && te->idcode == ID_OB)) {
+ /* sorting rules; only object lists, ID lists, or deformgroups */
+ if ( ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) {
/* count first */
for (te = lb->first; te; te = te->next) totelem++;
@@ -1270,15 +1304,27 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
tp->te = te;
tp->name = te->name;
tp->idcode = te->idcode;
- if (tselem->type && tselem->type != TSE_DEFGROUP) tp->idcode = 0; // don't sort this
+
+ if (tselem->type && tselem->type != TSE_DEFGROUP)
+ tp->idcode = 0; // don't sort this
+ if (tselem->type == TSE_ID_BASE)
+ tp->idcode = 1; // do sort this
+
tp->id = tselem->id;
}
- /* keep beginning of list */
- for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
- if (tp->idcode) break;
- if (skip < totelem)
- qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha);
+ /* just sort alphabetically */
+ if (tear->idcode == 1) {
+ qsort(tear, totelem, sizeof(tTreeSort), treesort_alpha);
+ }
+ else {
+ /* keep beginning of list */
+ for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
+ if (tp->idcode) break;
+
+ if (skip < totelem)
+ qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha_ob);
+ }
lb->first = lb->last = NULL;
tp = tear;
@@ -1384,6 +1430,42 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
return (lb->first != NULL);
}
+static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib)
+{
+ TreeElement *ten;
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a, tot;
+
+ tot = set_listbasepointers(mainvar, lbarray);
+ for (a = 0; a < tot; a++) {
+ if (lbarray[a]->first) {
+ ID *id = lbarray[a]->first;
+
+ /* check if there's data in current lib */
+ for (; id; id = id->next)
+ if (id->lib == lib)
+ break;
+
+ if (id) {
+
+ ten = outliner_add_element(soops, &te->subtree, (void *)lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten->directdata = lbarray[a];
+
+ ten->name = (char *)BKE_idcode_to_name_plural(GS(id->name));
+ if (ten->name == NULL)
+ ten->name = "UNKNOWN";
+
+ for (id = lbarray[a]->first; id; id = id->next) {
+ if (id->lib == lib)
+ outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+ }
+ }
+ }
+ }
+
+}
+
+
/* ======================================================= */
/* Main Tree Building API */
@@ -1418,17 +1500,31 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
if (soops->outlinevis == SO_LIBRARIES) {
Library *lib;
+ /* current file first - mainvar provides tselem with unique pointer - not used */
+ ten = outliner_add_element(soops, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0);
+ ten->name = "Current File";
+
+ tselem = TREESTORE(ten);
+ if (!tselem->used)
+ tselem->flag &= ~TSE_CLOSED;
+
+ outliner_add_library_contents(mainvar, soops, ten, NULL);
+
for (lib = mainvar->library.first; lib; lib = lib->id.next) {
ten = outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0);
lib->id.newid = (ID *)ten;
+
+ outliner_add_library_contents(mainvar, soops, ten, lib);
+
}
/* make hierarchy */
ten = soops->tree.first;
+ ten = ten->next; /* first one is main */
while (ten) {
TreeElement *nten = ten->next, *par;
tselem = TREESTORE(ten);
lib = (Library *)tselem->id;
- if (lib->parent) {
+ if (lib && lib->parent) {
BLI_remlink(&soops->tree, ten);
par = (TreeElement *)lib->parent->id.newid;
BLI_addtail(&par->subtree, ten);
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index ecc09a3..4bf8837 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -67,6 +67,17 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
ListBase *lb;
wmKeyMap *keymap;
+ /* make sure we keep the hide flags */
+ ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
+ ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+
+ ar->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ ar->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
+ ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
@@ -410,12 +421,6 @@ static SpaceLink *outliner_new(const bContext *UNUSED(C))
BLI_addtail(&soutliner->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM_O);
- ar->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- ar->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
- ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
-
return (SpaceLink *)soutliner;
}
diff --git a/source/blender/editors/space_script/SConscript b/source/blender/editors/space_script/SConscript
index c30e204..eff603a 100644
--- a/source/blender/editors/space_script/SConscript
+++ b/source/blender/editors/space_script/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript
index bc72786..060c789 100644
--- a/source/blender/editors/space_sequencer/SConscript
+++ b/source/blender/editors/space_sequencer/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 8155f9d..29a6a1f 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -49,6 +49,8 @@
#include "DNA_mask_types.h"
#include "DNA_userdef_types.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -400,6 +402,7 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot)
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", "");
RNA_def_enum_funcs(prop, RNA_movieclip_itemf);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
ot->prop = prop;
}
@@ -859,9 +862,9 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
* the other strips. */
if (!RNA_struct_property_is_set(op->ptr, "channel")) {
if (seq->seq1) {
- int chan = MAX3(seq->seq1 ? seq->seq1->machine : 0,
- seq->seq2 ? seq->seq2->machine : 0,
- seq->seq3 ? seq->seq3->machine : 0);
+ int chan = max_iii(seq->seq1 ? seq->seq1->machine : 0,
+ seq->seq2 ? seq->seq2->machine : 0,
+ seq->seq3 ? seq->seq3->machine : 0);
if (chan < MAXSEQ)
seq->machine = chan;
}
@@ -871,7 +874,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
- BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */
+ BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); /* runs BKE_sequence_calc */
/* not sure if this is needed with update_changed_seq_and_deps.
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index 7dbcabe..2112840 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -41,6 +41,7 @@
#include "ED_screen.h"
#include "ED_gpencil.h"
+#include "ED_sequencer.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -51,6 +52,14 @@
/* **************************** buttons ********************************* */
+static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ SpaceSeq *sseq = CTX_wm_space_seq(C);
+
+ /* don't show the gpencil if we are not showing the image */
+ return ED_space_sequencer_check_show_imbuf(sseq);
+}
+
void sequencer_buttons_register(ARegionType *art)
{
PanelType *pt;
@@ -58,7 +67,9 @@ void sequencer_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil");
strcpy(pt->idname, "SEQUENCER_PT_gpencil");
strcpy(pt->label, N_("Grease Pencil"));
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
+ pt->poll = sequencer_grease_pencil_panel_poll;
BLI_addtail(&art->paneltypes, pt);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 1a84efa..249ba98 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -62,6 +62,7 @@
#include "ED_gpencil.h"
#include "ED_markers.h"
#include "ED_mask.h"
+#include "ED_sequencer.h"
#include "ED_types.h"
#include "ED_space_api.h"
@@ -921,12 +922,20 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
GLuint last_texid;
unsigned char *display_buffer;
void *cache_handle = NULL;
+ const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
- if (G.is_rendering == FALSE) {
+ if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE);
+
+ if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
+ /* in case of final rendering used for preview, kill all previews,
+ * otherwise threading conflict will happen in rendering module
+ */
+ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW);
+ }
}
render_size = sseq->render_size;
@@ -1049,6 +1058,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
glBegin(GL_QUADS);
if (draw_overlay) {
@@ -1080,6 +1093,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glEnd();
glBindTexture(GL_TEXTURE_2D, last_texid);
glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
glDeleteTextures(1, &texid);
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
@@ -1125,8 +1139,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
setlinestyle(0);
}
- /* draw grease-pencil (image aligned) */
- draw_gpencil_2dimage(C);
+ if (sseq->flag & SEQ_SHOW_GPENCIL) {
+ if (is_imbuf) {
+ /* draw grease-pencil (image aligned) */
+ draw_gpencil_2dimage(C);
+ }
+ }
if (!scope)
IMB_freeImBuf(ibuf);
@@ -1134,9 +1152,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* ortho at pixel level */
UI_view2d_view_restore(C);
- /* draw grease-pencil (screen aligned) */
- draw_gpencil_view2d(C, 0);
-
+ if (sseq->flag & SEQ_SHOW_GPENCIL) {
+ if (is_imbuf) {
+ /* draw grease-pencil (screen aligned) */
+ draw_gpencil_view2d(C, 0);
+ }
+ }
/* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not,
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index e7f77db..c6c70cc 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -496,6 +496,13 @@ int ED_space_sequencer_maskedit_poll(bContext *C)
return FALSE;
}
+/* are we displaying the seq output (not channels or histogram)*/
+int ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
+{
+ return (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) &&
+ ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
+}
+
int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str)
{
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -918,7 +925,7 @@ static void set_filter_seq(Scene *scene)
if (seq->type == SEQ_TYPE_MOVIE) {
seq->flag |= SEQ_FILTERY;
reload_sequence_new_file(scene, seq, FALSE);
- calc_sequence(scene, seq);
+ BKE_sequence_calc(scene, seq);
}
}
@@ -1899,6 +1906,9 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
for (seq = ed->seqbasep->first; seq; seq = seq->next)
BKE_sequence_calc(scene, seq);
+ if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq))
+ BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene);
+
BKE_sequencer_active_set(scene, ms->parseq);
ms->parseq->flag |= SELECT;
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index e8d4701..d541e1d 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -120,6 +120,8 @@ static SpaceLink *sequencer_new(const bContext *C)
sseq->chanshown = 0;
sseq->view = SEQ_VIEW_SEQUENCE;
sseq->mainb = SEQ_DRAW_IMG_IMBUF;
+ sseq->flag = SEQ_SHOW_GPENCIL;
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for sequencer");
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index 9cc407f..a33a9ab 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -36,11 +36,15 @@ set(INC_SYS
set(SRC
space_text.c
+ text_autocomplete.c
text_draw.c
+ text_format.c
+ text_format_osl.c
+ text_format_py.c
text_header.c
text_ops.c
- text_python.c
+ text_format.h
text_intern.h
)
diff --git a/source/blender/editors/space_text/SConscript b/source/blender/editors/space_text/SConscript
index 3735645..4b6d9fb 100644
--- a/source/blender/editors/space_text/SConscript
+++ b/source/blender/editors/space_text/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index d74e326..fa3eefc 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -30,17 +30,12 @@
#include <string.h>
-#include <stdio.h>
#include "DNA_text_types.h"
-#include "DNA_object_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_rand.h"
-#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -61,7 +56,8 @@
#include "RNA_access.h"
-#include "text_intern.h" // own include
+#include "text_format.h"
+#include "text_intern.h" /* own include */
/* ******************** default callbacks for text space ***************** */
@@ -227,6 +223,8 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_to_3d_object);
WM_operatortype_append(TEXT_OT_resolve_conflict);
+
+ WM_operatortype_append(TEXT_OT_autocomplete);
}
static void text_keymap(struct wmKeyConfig *keyconf)
@@ -280,7 +278,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", TRUE);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
@@ -379,6 +377,8 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_line_break", PADENTER, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "TEXT_MT_toolbox", RIGHTMOUSE, KM_PRESS, KM_ANY, 0);
+
+ WM_keymap_add_item(keymap, "TEXT_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
@@ -556,5 +556,9 @@ void ED_spacetype_text(void)
BLI_addhead(&st->regiontypes, art);
BKE_spacetype_register(st);
+
+ /* register formatters */
+ ED_text_format_register_py();
+ ED_text_format_register_osl();
}
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
new file mode 100644
index 0000000..e406a1b
--- /dev/null
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -0,0 +1,541 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_autocomplete.c
+ * \ingroup sptext
+ */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_text_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+
+#include "BKE_context.h"
+#include "BKE_text.h"
+#include "BKE_screen.h"
+#include "BKE_suggestions.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "UI_interface.h"
+
+#include "text_format.h"
+#include "text_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+/* Public API */
+
+int text_do_suggest_select(SpaceText *st, ARegion *ar)
+{
+ SuggItem *item, *first, *last /* , *sel */ /* UNUSED */;
+ TextLine *tmp;
+ int l, x, y, w, h, i;
+ int tgti, *top;
+ int mval[2] = {0, 0};
+
+ if (!st || !st->text) return 0;
+ if (!texttool_text_is_active(st->text)) return 0;
+
+ first = texttool_suggest_first();
+ last = texttool_suggest_last();
+ /* sel = texttool_suggest_selected(); */ /* UNUSED */
+ top = texttool_suggest_top();
+
+ if (!last || !first)
+ return 0;
+
+ /* Count the visible lines to the cursor */
+ for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
+ if (l < 0) return 0;
+
+ text_update_character_width(st);
+
+ if (st->showlinenrs) {
+ x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
+ }
+ else {
+ x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
+ }
+ y = ar->winy - st->lheight_dpi * l - 2;
+
+ w = SUGG_LIST_WIDTH * st->cwidth + U.widget_unit;
+ h = SUGG_LIST_SIZE * st->lheight_dpi + 0.4f * U.widget_unit;
+
+ // XXX getmouseco_areawin(mval);
+
+ if (mval[0] < x || x + w < mval[0] || mval[1] < y - h || y < mval[1])
+ return 0;
+
+ /* Work out which of the items is at the top of the visible list */
+ for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
+
+ /* Work out the target item index in the visible list */
+ tgti = (y - mval[1] - 4) / st->lheight_dpi;
+ if (tgti < 0 || tgti > SUGG_LIST_SIZE)
+ return 1;
+
+ for (i = tgti; i > 0 && item->next; i--, item = item->next) ;
+ if (item)
+ texttool_suggest_select(item);
+ return 1;
+}
+
+void text_pop_suggest_list(void)
+{
+ SuggItem *item, *sel;
+ int *top, i;
+
+ item = texttool_suggest_first();
+ sel = texttool_suggest_selected();
+ top = texttool_suggest_top();
+
+ i = 0;
+ while (item && item != sel) {
+ item = item->next;
+ i++;
+ }
+ if (i > *top + SUGG_LIST_SIZE - 1)
+ *top = i - SUGG_LIST_SIZE + 1;
+ else if (i < *top)
+ *top = i;
+}
+
+/* -------------------------------------------------------------------- */
+/* Private API */
+
+static void text_autocomplete_free(bContext *C, wmOperator *op);
+
+static GHash *text_autocomplete_build(Text *text)
+{
+ GHash *gh;
+ int seek_len = 0;
+ const char *seek;
+ texttool_text_clear();
+
+ texttool_text_set_active(text);
+
+ /* first get the word we're at */
+ {
+ const int i = text_find_identifier_start(text->curl->line, text->curc);
+ seek_len = text->curc - i;
+ seek = text->curl->line + i;
+
+ // BLI_strncpy(seek, seek_ptr, seek_len);
+ }
+
+ /* now walk over entire doc and suggest words */
+ {
+ TextLine *linep;
+
+ gh = BLI_ghash_str_new(__func__);
+
+ for (linep = text->lines.first; linep; linep = linep->next) {
+ int i_start = 0;
+ int i_end = 0;
+
+ while (i_start < linep->len) {
+ /* seek identifier beginning */
+ while (i_start < linep->len && !text_check_identifier(linep->line[i_start])) {
+ i_start++;
+ }
+ i_end = i_start;
+ while (i_end < linep->len && text_check_identifier(linep->line[i_end])) {
+ i_end++;
+ }
+
+ if (i_start != i_end) {
+ char *str_sub = &linep->line[i_start];
+ const int choice_len = i_end - i_start;
+
+ if ((choice_len > seek_len) &&
+ (seek_len == 0 || strncmp(seek, str_sub, seek_len) == 0) &&
+ (seek != str_sub))
+ {
+ // printf("Adding: %s\n", s);
+ char str_sub_last = str_sub[choice_len];
+ str_sub[choice_len] = '\0';
+ if (!BLI_ghash_lookup(gh, str_sub)) {
+ char *str_dup = BLI_strdupn(str_sub, choice_len);
+ BLI_ghash_insert(gh, str_dup, str_dup); /* A 'set' would make more sense here */
+ }
+ str_sub[choice_len] = str_sub_last;
+ }
+ }
+ i_start = i_end;
+ }
+ }
+
+ {
+ GHashIterator *iter = BLI_ghashIterator_new(gh);
+
+ /* get the formatter for highlighting */
+ TextFormatType *tft;
+ tft = ED_text_format_get(text);
+
+ for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ const char *s = BLI_ghashIterator_getValue(iter);
+ texttool_suggest_add(s, tft->format_identifier(s));
+ }
+ BLI_ghashIterator_free(iter);
+
+ }
+ }
+
+ texttool_suggest_prefix(seek, seek_len);
+
+ return gh;
+}
+
+/* -- */
+
+static void get_suggest_prefix(Text *text, int offset)
+{
+ int i, len;
+ char *line;
+
+ if (!text) return;
+ if (!texttool_text_is_active(text)) return;
+
+ line = text->curl->line;
+ i = text_find_identifier_start(line, text->curc + offset);
+ len = text->curc - i + offset;
+ texttool_suggest_prefix(line + i, len);
+}
+
+static void confirm_suggestion(Text *text)
+{
+ SuggItem *sel;
+ int i, over = 0;
+ const char *line;
+
+ if (!text) return;
+ if (!texttool_text_is_active(text)) return;
+
+ sel = texttool_suggest_selected();
+ if (!sel) return;
+
+ line = text->curl->line;
+ i = text_find_identifier_start(line, text->curc /* - skipleft */);
+ over = text->curc - i;
+
+// for (i = 0; i < skipleft; i++)
+// txt_move_left(text, 0);
+ for (i = 0; i < over; i++)
+ txt_move_left(text, 1);
+
+ txt_insert_buf(text, sel->name);
+
+// for (i = 0; i < skipleft; i++)
+// txt_move_right(text, 0);
+
+ texttool_text_clear();
+}
+
+/* -- */
+
+
+static int text_autocomplete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ SpaceText *st = CTX_wm_space_text(C);
+ Text *text = CTX_data_edit_text(C);
+
+ st->doplugins = TRUE;
+ op->customdata = text_autocomplete_build(text);
+
+ if (texttool_suggest_first()) {
+
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ if (texttool_suggest_first() == texttool_suggest_last()) {
+ confirm_suggestion(st->text);
+ text_update_line_edited(st->text->curl);
+ text_autocomplete_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ else {
+ text_autocomplete_free(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int doc_scroll = 0;
+
+static int text_autocomplete_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceText *st = CTX_wm_space_text(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+
+ int draw = 0, tools = 0, swallow = 0, scroll = 1;
+ Text *text = CTX_data_edit_text(C);
+ int retval = OPERATOR_RUNNING_MODAL;
+
+ (void)text;
+
+ if (st->doplugins && texttool_text_is_active(st->text)) {
+ if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST;
+ if (texttool_docs_get()) tools |= TOOL_DOCUMENT;
+ }
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ if (event->val == KM_PRESS) {
+ if (text_do_suggest_select(st, ar))
+ swallow = 1;
+ else {
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ retval = OPERATOR_FINISHED;
+ }
+ draw = 1;
+ }
+ break;
+ case MIDDLEMOUSE:
+ if (event->val == KM_PRESS) {
+ if (text_do_suggest_select(st, ar)) {
+ confirm_suggestion(st->text);
+ text_update_line_edited(st->text->curl);
+ swallow = 1;
+ }
+ else {
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ retval = OPERATOR_FINISHED;
+ }
+ draw = 1;
+ }
+ break;
+ case ESCKEY:
+ if (event->val == KM_PRESS) {
+ draw = swallow = 1;
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
+ else if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ else draw = swallow = 0;
+ retval = OPERATOR_CANCELLED;
+ }
+ break;
+ case RETKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_SUGG_LIST) {
+ confirm_suggestion(st->text);
+ text_update_line_edited(st->text->curl);
+ swallow = 1;
+ draw = 1;
+ }
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
+ retval = OPERATOR_FINISHED;
+ }
+ break;
+ case LEFTARROWKEY:
+ case BACKSPACEKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_SUGG_LIST) {
+ if (event->ctrl) {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ else {
+ /* Work out which char we are about to delete/pass */
+ if (st->text->curl && st->text->curc > 0) {
+ char ch = st->text->curl->line[st->text->curc - 1];
+ if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
+ get_suggest_prefix(st->text, -1);
+ text_pop_suggest_list();
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ }
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ }
+ break;
+ case RIGHTARROWKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_SUGG_LIST) {
+ if (event->ctrl) {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ else {
+ /* Work out which char we are about to pass */
+ if (st->text->curl && st->text->curc < st->text->curl->len) {
+ char ch = st->text->curl->line[st->text->curc + 1];
+ if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
+ get_suggest_prefix(st->text, 1);
+ text_pop_suggest_list();
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ texttool_suggest_clear();
+ retval = OPERATOR_CANCELLED;
+ }
+ }
+ }
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
+ }
+ break;
+ case PAGEDOWNKEY:
+ scroll = SUGG_LIST_SIZE - 1;
+ case WHEELDOWNMOUSE:
+ case DOWNARROWKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_DOCUMENT) {
+ doc_scroll++;
+ swallow = 1;
+ draw = 1;
+ }
+ else if (tools & TOOL_SUGG_LIST) {
+ SuggItem *sel = texttool_suggest_selected();
+ if (!sel) {
+ texttool_suggest_select(texttool_suggest_first());
+ }
+ else {
+ while (sel && sel != texttool_suggest_last() && sel->next && scroll--) {
+ texttool_suggest_select(sel->next);
+ sel = sel->next;
+ }
+ }
+ text_pop_suggest_list();
+ swallow = 1;
+ draw = 1;
+ }
+ }
+ break;
+ case PAGEUPKEY:
+ scroll = SUGG_LIST_SIZE - 1;
+ case WHEELUPMOUSE:
+ case UPARROWKEY:
+ if (event->val == KM_PRESS) {
+ if (tools & TOOL_DOCUMENT) {
+ if (doc_scroll > 0) doc_scroll--;
+ swallow = 1;
+ draw = 1;
+ }
+ else if (tools & TOOL_SUGG_LIST) {
+ SuggItem *sel = texttool_suggest_selected();
+ while (sel && sel != texttool_suggest_first() && sel->prev && scroll--) {
+ texttool_suggest_select(sel->prev);
+ sel = sel->prev;
+ }
+ text_pop_suggest_list();
+ swallow = 1;
+ draw = 1;
+ }
+ }
+ break;
+ case RIGHTSHIFTKEY:
+ case LEFTSHIFTKEY:
+ break;
+#if 0
+ default:
+ if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(), draw = 1;
+ if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
+#endif
+ }
+
+ if (draw) {
+ ED_area_tag_redraw(CTX_wm_area(C));
+ }
+
+// if (swallow) {
+// retval = OPERATOR_RUNNING_MODAL;
+// }
+
+ if (texttool_suggest_first()) {
+ if (retval != OPERATOR_RUNNING_MODAL) {
+ text_autocomplete_free(C, op);
+ }
+ return retval;
+ }
+ else {
+ text_autocomplete_free(C, op);
+ return OPERATOR_FINISHED;
+ }
+}
+
+static void text_autocomplete_free(bContext *C, wmOperator *op)
+{
+ GHash *gh = op->customdata;
+ if (gh) {
+ BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+ op->customdata = NULL;
+ }
+
+ /* other stuff */
+ {
+ SpaceText *st = CTX_wm_space_text(C);
+ st->doplugins = FALSE;
+ texttool_text_clear();
+ }
+}
+
+static int text_autocomplete_cancel(bContext *C, wmOperator *op)
+{
+ text_autocomplete_free(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+void TEXT_OT_autocomplete(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Text Auto Complete";
+ ot->description = "Show a list of used text in the open document";
+ ot->idname = "TEXT_OT_autocomplete";
+
+ /* api callbacks */
+ ot->invoke = text_autocomplete_invoke;
+ ot->cancel = text_autocomplete_cancel;
+ ot->modal = text_autocomplete_modal;
+ ot->poll = text_space_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
+}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 46ab2d9..c264368 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -29,10 +29,6 @@
*/
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
#include "MEM_guardedalloc.h"
@@ -40,12 +36,10 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_utildefines.h"
#include "DNA_text_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_suggestions.h"
@@ -53,11 +47,12 @@
#include "BIF_gl.h"
-#include "ED_datafiles.h"
#include "UI_interface.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "text_intern.h"
+#include "text_format.h"
/******************** text font drawing ******************/
// XXX, fixme
@@ -65,7 +60,7 @@
static void text_font_begin(SpaceText *st)
{
- BLF_size(mono, st->lheight, 72);
+ BLF_size(mono, st->lheight_dpi, 72);
}
static void text_font_end(SpaceText *UNUSED(st))
@@ -82,373 +77,20 @@ static int text_font_draw(SpaceText *UNUSED(st), int x, int y, const char *str)
static int text_font_draw_character(SpaceText *st, int x, int y, char c)
{
- char str[2];
- str[0] = c;
- str[1] = '\0';
-
BLF_position(mono, x, y, 0);
- BLF_draw(mono, str, 1);
+ BLF_draw(mono, &c, 1);
return st->cwidth;
}
static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c)
{
- char str[BLI_UTF8_MAX + 1];
- size_t len = BLI_str_utf8_size_safe(c);
- memcpy(str, c, len);
- str[len] = '\0';
-
+ const size_t len = BLI_str_utf8_size_safe(c);
BLF_position(mono, x, y, 0);
- BLF_draw(mono, str, len);
-
+ BLF_draw(mono, c, len);
return st->cwidth;
}
-/****************** flatten string **********************/
-
-static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
-{
- int i;
-
- if (fs->pos + len > fs->len) {
- char *nbuf; int *naccum;
- fs->len *= 2;
-
- nbuf = MEM_callocN(sizeof(*fs->buf) * fs->len, "fs->buf");
- naccum = MEM_callocN(sizeof(*fs->accum) * fs->len, "fs->accum");
-
- memcpy(nbuf, fs->buf, fs->pos * sizeof(*fs->buf));
- memcpy(naccum, fs->accum, fs->pos * sizeof(*fs->accum));
-
- if (fs->buf != fs->fixedbuf) {
- MEM_freeN(fs->buf);
- MEM_freeN(fs->accum);
- }
-
- fs->buf = nbuf;
- fs->accum = naccum;
- }
-
- for (i = 0; i < len; i++) {
- fs->buf[fs->pos + i] = c[i];
- fs->accum[fs->pos + i] = accum;
- }
-
- fs->pos += len;
-}
-
-int flatten_string(SpaceText *st, FlattenString *fs, const char *in)
-{
- int r, i, total = 0;
-
- memset(fs, 0, sizeof(FlattenString));
- fs->buf = fs->fixedbuf;
- fs->accum = fs->fixedaccum;
- fs->len = sizeof(fs->fixedbuf);
-
- for (r = 0, i = 0; *in; r++) {
- if (*in == '\t') {
- i = st->tabnumber - (total % st->tabnumber);
- total += i;
-
- while (i--)
- flatten_string_append(fs, " ", r, 1);
-
- in++;
- }
- else {
- size_t len = BLI_str_utf8_size_safe(in);
- flatten_string_append(fs, in, r, len);
- in += len;
- total++;
- }
- }
-
- flatten_string_append(fs, "\0", r, 1);
-
- return total;
-}
-
-void flatten_string_free(FlattenString *fs)
-{
- if (fs->buf != fs->fixedbuf)
- MEM_freeN(fs->buf);
- if (fs->accum != fs->fixedaccum)
- MEM_freeN(fs->accum);
-}
-
-/* Checks the specified source string for a Python built-in function name. This
- * name must start at the beginning of the source string and must be followed by
- * a non-identifier (see text_check_identifier(char)) or null character.
- *
- * If a built-in function is found, the length of the matching name is returned.
- * Otherwise, -1 is returned.
- *
- * See:
- * http://docs.python.org/py3k/reference/lexical_analysis.html#keywords
- */
-
-static int find_builtinfunc(char *string)
-{
- int a, i;
- const char *builtinfuncs[] = {
- /* "False", "None", "True", */ /* see find_bool() */
- "and", "as", "assert", "break",
- "class", "continue", "def", "del", "elif", "else", "except",
- "finally", "for", "from", "global", "if", "import", "in",
- "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
- "return", "try", "while", "with", "yield",
- };
-
- for (a = 0; a < sizeof(builtinfuncs) / sizeof(builtinfuncs[0]); a++) {
- i = 0;
- while (1) {
- /* If we hit the end of a keyword... (eg. "def") */
- if (builtinfuncs[a][i] == '\0') {
- /* If we still have identifier chars in the source (eg. "definate") */
- if (text_check_identifier(string[i]))
- i = -1; /* No match */
- break; /* Next keyword if no match, otherwise we're done */
-
- /* If chars mismatch, move on to next keyword */
- }
- else if (string[i] != builtinfuncs[a][i]) {
- i = -1;
- break; /* Break inner loop, start next keyword */
- }
- i++;
- }
- if (i > 0) break; /* If we have a match, we're done */
- }
- return i;
-}
-
-/* Checks the specified source string for a Python special name. This name must
- * start at the beginning of the source string and must be followed by a non-
- * identifier (see text_check_identifier(char)) or null character.
- *
- * If a special name is found, the length of the matching name is returned.
- * Otherwise, -1 is returned. */
-
-static int find_specialvar(char *string)
-{
- int i = 0;
- /* Check for "def" */
- if (string[0] == 'd' && string[1] == 'e' && string[2] == 'f')
- i = 3;
- /* Check for "class" */
- else if (string[0] == 'c' && string[1] == 'l' && string[2] == 'a' && string[3] == 's' && string[4] == 's')
- i = 5;
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- if (i == 0 || text_check_identifier(string[i]))
- return -1;
- return i;
-}
-
-static int find_decorator(char *string)
-{
- if (string[0] == '@') {
- int i = 1;
- while (text_check_identifier(string[i])) {
- i++;
- }
- return i;
- }
- return -1;
-}
-
-static int find_bool(char *string)
-{
- int i = 0;
- /* Check for "False" */
- if (string[0] == 'F' && string[1] == 'a' && string[2] == 'l' && string[3] == 's' && string[4] == 'e')
- i = 5;
- /* Check for "True" */
- else if (string[0] == 'T' && string[1] == 'r' && string[2] == 'u' && string[3] == 'e')
- i = 4;
- /* Check for "None" */
- else if (string[0] == 'N' && string[1] == 'o' && string[2] == 'n' && string[3] == 'e')
- i = 4;
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- if (i == 0 || text_check_identifier(string[i]))
- return -1;
- return i;
-}
-
-/* Ensures the format string for the given line is long enough, reallocating
- * as needed. Allocation is done here, alone, to ensure consistency. */
-static int text_check_format_len(TextLine *line, unsigned int len)
-{
- if (line->format) {
- if (strlen(line->format) < len) {
- MEM_freeN(line->format);
- line->format = MEM_mallocN(len + 2, "SyntaxFormat");
- if (!line->format) return 0;
- }
- }
- else {
- line->format = MEM_mallocN(len + 2, "SyntaxFormat");
- if (!line->format) return 0;
- }
-
- return 1;
-}
-
-/* Formats the specified line. If do_next is set, the process will move on to
- * the succeeding line if it is affected (eg. multiline strings). Format strings
- * may contain any of the following characters:
- * '_' Whitespace
- * '#' Comment text
- * '!' Punctuation and other symbols
- * 'n' Numerals
- * 'l' String letters
- * 'v' Special variables (class, def)
- * 'b' Built-in names (print, for, etc.)
- * 'q' Other text (identifiers, etc.)
- * It is terminated with a null-terminator '\0' followed by a continuation
- * flag indicating whether the line is part of a multi-line string. */
-
-static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
-{
- FlattenString fs;
- char *str, *fmt, orig, cont, find, prev = ' ';
- int len, i;
-
- /* Get continuation from previous line */
- if (line->prev && line->prev->format != NULL) {
- fmt = line->prev->format;
- cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
- }
- else cont = 0;
-
- /* Get original continuation from this line */
- if (line->format != NULL) {
- fmt = line->format;
- orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
- }
- else orig = 0xFF;
-
- len = flatten_string(st, &fs, line->line);
- str = fs.buf;
- if (!text_check_format_len(line, len)) {
- flatten_string_free(&fs);
- return;
- }
- fmt = line->format;
-
- while (*str) {
- /* Handle escape sequences by skipping both \ and next char */
- if (*str == '\\') {
- *fmt = prev; fmt++; str++;
- if (*str == '\0') break;
- *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
- continue;
- }
- /* Handle continuations */
- else if (cont) {
- /* Triple strings ("""...""" or '''...''') */
- if (cont & TXT_TRISTR) {
- find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
- if (*str == find && *(str + 1) == find && *(str + 2) == find) {
- *fmt = 'l'; fmt++; str++;
- *fmt = 'l'; fmt++; str++;
- cont = 0;
- }
- /* Handle other strings */
- }
- else {
- find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
- if (*str == find) cont = 0;
- }
-
- *fmt = 'l';
- str += BLI_str_utf8_size_safe(str) - 1;
- }
- /* Not in a string... */
- else {
- /* Deal with comments first */
- if (prev == '#' || *str == '#') {
- *fmt = '#';
- str += BLI_str_utf8_size_safe(str) - 1;
- }
- else if (*str == '"' || *str == '\'') {
- /* Strings */
- find = *str;
- cont = (*str == '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR;
- if (*(str + 1) == find && *(str + 2) == find) {
- *fmt = 'l'; fmt++; str++;
- *fmt = 'l'; fmt++; str++;
- cont |= TXT_TRISTR;
- }
- *fmt = 'l';
- }
- /* Whitespace (all ws. has been converted to spaces) */
- else if (*str == ' ')
- *fmt = '_';
- /* Numbers (digits not part of an identifier and periods followed by digits) */
- else if ((prev != 'q' && text_check_digit(*str)) || (*str == '.' && text_check_digit(*(str + 1))))
- *fmt = 'n';
- /* Booleans */
- else if (prev != 'q' && (i = find_bool(str)) != -1)
- if (i > 0) {
- while (i > 1) {
- *fmt = 'n'; fmt++; str++;
- i--;
- }
- *fmt = 'n';
- }
- else {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- /* Punctuation */
- else if (text_check_delim(*str))
- *fmt = '!';
- /* Identifiers and other text (no previous ws. or delims. so text continues) */
- else if (prev == 'q') {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
- else {
- /* Special vars(v) or built-in keywords(b) */
- if ((i = find_specialvar(str)) != -1)
- prev = 'v';
- else if ((i = find_builtinfunc(str)) != -1)
- prev = 'b';
- else if ((i = find_decorator(str)) != -1)
- prev = 'v'; /* could have a new color for this */
- if (i > 0) {
- while (i > 1) {
- *fmt = prev; fmt++; str++;
- i--;
- }
- *fmt = prev;
- }
- else {
- str += BLI_str_utf8_size_safe(str) - 1;
- *fmt = 'q';
- }
- }
- }
- prev = *fmt;
- fmt++;
- str++;
- }
-
- /* Terminate and add continuation char */
- *fmt = '\0'; fmt++;
- *fmt = cont;
-
- /* If continuation has changed and we're allowed, process the next line */
- if (cont != orig && do_next && line->next) {
- txt_format_line(st, line->next, do_next);
- }
-
- flatten_string_free(&fs);
-}
-
#if 0
/* Formats every line of the current text */
static void txt_format_text(SpaceText *st)
@@ -466,27 +108,33 @@ static void txt_format_text(SpaceText *st)
static void format_draw_color(char formatchar)
{
switch (formatchar) {
- case '_': /* Whitespace */
+ case FMT_TYPE_WHITESPACE:
break;
- case '!': /* Symbols */
- UI_ThemeColorBlend(TH_TEXT, TH_BACK, 0.5f);
+ case FMT_TYPE_SYMBOL:
+ UI_ThemeColor(TH_SYNTAX_S);
break;
- case '#': /* Comments */
+ case FMT_TYPE_COMMENT:
UI_ThemeColor(TH_SYNTAX_C);
break;
- case 'n': /* Numerals */
+ case FMT_TYPE_NUMERAL:
UI_ThemeColor(TH_SYNTAX_N);
break;
- case 'l': /* Strings */
+ case FMT_TYPE_STRING:
UI_ThemeColor(TH_SYNTAX_L);
break;
- case 'v': /* Specials: class, def */
+ case FMT_TYPE_DIRECTIVE:
+ UI_ThemeColor(TH_SYNTAX_D);
+ break;
+ case FMT_TYPE_SPECIAL:
UI_ThemeColor(TH_SYNTAX_V);
break;
- case 'b': /* Keywords: for, print, etc. */
+ case FMT_TYPE_RESERVED:
+ UI_ThemeColor(TH_SYNTAX_R);
+ break;
+ case FMT_TYPE_KEYWORD:
UI_ThemeColor(TH_SYNTAX_B);
break;
- case 'q': /* Other text (identifiers) */
+ case FMT_TYPE_DEFAULT:
default:
UI_ThemeColor(TH_TEXT);
break;
@@ -708,6 +356,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
FlattenString fs;
int basex, i, a, start, end, max, lines; /* view */
int mi, ma, mstart, mend; /* mem */
+ char fmt_prev = 0xff;
flatten_string(st, &fs, str);
str = fs.buf;
@@ -731,10 +380,12 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* Draw the visible portion of text on the overshot line */
for (a = start, ma = mstart; a < end; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
- if (st->showsyntax && format) format_draw_color(format[a]);
+ if (st->showsyntax && format) {
+ if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
+ }
x += text_font_draw_character_utf8(st, x, y, str + ma);
}
- y -= st->lheight + TXT_LINE_SPACING;
+ y -= st->lheight_dpi + TXT_LINE_SPACING;
x = basex;
lines++;
start = end; mstart = mend;
@@ -749,8 +400,9 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* Draw the remaining text */
for (a = start, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
- if (st->showsyntax && format)
- format_draw_color(format[a]);
+ if (st->showsyntax && format) {
+ if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
+ }
x += text_font_draw_character_utf8(st, x, y, str + ma);
}
@@ -781,15 +433,18 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra
if (st->showsyntax && format) {
int a, str_shift = 0;
+ char fmt_prev = 0xff;
format = format + cshift;
for (a = 0; a < amount; a++) {
- format_draw_color(format[a]);
+ if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
x += text_font_draw_character_utf8(st, x, y, in + str_shift);
str_shift += BLI_str_utf8_size_safe(in + str_shift);
}
}
- else text_font_draw(st, x, y, in);
+ else {
+ text_font_draw(st, x, y, in);
+ }
}
else {
while (w-- && *acc++ < maxwidth)
@@ -852,7 +507,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
full_update |= drawcache->wordwrap != st->wordwrap; /* word-wrapping option was toggled */
full_update |= drawcache->showlinenrs != st->showlinenrs; /* word-wrapping option was toggled */
full_update |= drawcache->tabnumber != st->tabnumber; /* word-wrapping option was toggled */
- full_update |= drawcache->lheight != st->lheight; /* word-wrapping option was toggled */
+ full_update |= drawcache->lheight != st->lheight_dpi; /* word-wrapping option was toggled */
full_update |= drawcache->cwidth != st->cwidth; /* word-wrapping option was toggled */
full_update |= strncmp(drawcache->text_id, txt->id.name, MAX_ID_NAME); /* text datablock was changed */
@@ -928,7 +583,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
/* store settings */
drawcache->winx = ar->winx;
drawcache->wordwrap = st->wordwrap;
- drawcache->lheight = st->lheight;
+ drawcache->lheight = st->lheight_dpi;
drawcache->cwidth = st->cwidth;
drawcache->showlinenrs = st->showlinenrs;
drawcache->tabnumber = st->tabnumber;
@@ -1085,12 +740,12 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
blank_lines = st->viewlines / 2;
/* nicer code: use scroll rect for entire bar */
- back->xmin = ar->winx - 18;
+ back->xmin = ar->winx - (V2D_SCROLL_WIDTH + 1);
back->xmax = ar->winx;
back->ymin = 0;
back->ymax = ar->winy;
- scroll->xmin = ar->winx - 17;
+ scroll->xmin = ar->winx - V2D_SCROLL_WIDTH;
scroll->xmax = ar->winx - 5;
scroll->ymin = 4;
scroll->ymax = 4 + pix_available;
@@ -1237,9 +892,9 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
x += SUGG_LIST_WIDTH * st->cwidth + 50;
}
- /* top = */ /* UNUSED */ y = ar->winy - st->lheight * l - 2;
+ /* top = */ /* UNUSED */ y = ar->winy - st->lheight_dpi * l - 2;
boxw = DOC_WIDTH * st->cwidth + 20;
- boxh = (DOC_HEIGHT + 1) * st->lheight;
+ boxh = (DOC_HEIGHT + 1) * (st->lheight_dpi + TXT_LINE_SPACING);
/* Draw panel */
UI_ThemeColor(TH_BACK);
@@ -1271,7 +926,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
else if (*p == '\n') {
buf[i] = '\0';
if (lines >= 0) {
- y -= st->lheight;
+ y -= st->lheight_dpi;
text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
}
i = 0; br = DOC_WIDTH; lines++;
@@ -1280,7 +935,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
if (i == DOC_WIDTH) { /* Reached the width, go to last break and wrap there */
buf[br] = '\0';
if (lines >= 0) {
- y -= st->lheight;
+ y -= st->lheight_dpi;
text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
}
p -= i - br - 1; /* Rewind pointer to last break */
@@ -1302,9 +957,11 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
SuggItem *item, *first, *last, *sel;
TextLine *tmp;
char str[SUGG_LIST_WIDTH + 1];
- int w, boxw = 0, boxh, i, l, x, y, b, *top;
+ int w, boxw = 0, boxh, i, l, x, y, *top;
+ const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
+ const int margin_x = 2;
- if (!st || !st->text) return;
+ if (!st->text) return;
if (!texttool_text_is_active(st->text)) return;
first = texttool_suggest_first();
@@ -1326,14 +983,20 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
else {
x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
}
- y = ar->winy - st->lheight * l - 2;
+ /* offset back so the start of the text lines up with the suggestions,
+ * not essential but makes suggestions easier to follow */
+ x -= st->cwidth * (st->text->curc - text_find_identifier_start(st->text->curl->line, st->text->curc));
+ y = ar->winy - lheight * l - 2;
boxw = SUGG_LIST_WIDTH * st->cwidth + 20;
- boxh = SUGG_LIST_SIZE * st->lheight + 8;
+ boxh = SUGG_LIST_SIZE * lheight + 8;
+ /* not needed but stands out nicer */
+ uiDrawBoxShadow(220, x, y - boxh, x + boxw, y);
+
UI_ThemeColor(TH_SHADE1);
glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1);
- UI_ThemeColor(TH_BACK);
+ UI_ThemeColorShade(TH_BACK, 16);
glRecti(x, y, x + boxw, y - boxh);
/* Set the top 'item' of the visible list */
@@ -1341,7 +1004,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) {
- y -= st->lheight;
+ y -= lheight;
BLI_strncpy(str, item->name, SUGG_LIST_WIDTH);
@@ -1349,21 +1012,11 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
if (item == sel) {
UI_ThemeColor(TH_SHADE2);
- glRecti(x + 16, y - 3, x + 16 + w, y + st->lheight - 3);
+ glRecti(x + margin_x, y - 3, x + margin_x + w, y + lheight - 3);
}
- b = 1; /* b=1 color block, text is default. b=0 no block, color text */
- switch (item->type) {
- case 'k': UI_ThemeColor(TH_SYNTAX_B); b = 0; break;
- case 'm': UI_ThemeColor(TH_TEXT); break;
- case 'f': UI_ThemeColor(TH_SYNTAX_L); break;
- case 'v': UI_ThemeColor(TH_SYNTAX_N); break;
- case '?': UI_ThemeColor(TH_TEXT); b = 0; break;
- }
- if (b) {
- glRecti(x + 8, y + 2, x + 11, y + 5);
- UI_ThemeColor(TH_TEXT);
- }
- text_draw(st, str, 0, 0, 1, x + 16, y - 1, NULL);
+
+ format_draw_color(item->type);
+ text_draw(st, str, 0, 0, 1, x + margin_x, y - 1, NULL);
if (item == last) break;
}
@@ -1376,7 +1029,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
Text *text = st->text;
int vcurl, vcurc, vsell, vselc, hidden = 0;
int x, y, w, i;
- int lheight = st->lheight + TXT_LINE_SPACING;
+ const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
/* Draw the selection */
if (text->curl != text->sell || text->curc != text->selc) {
@@ -1394,14 +1047,14 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
UI_ThemeColor(TH_SHADE2);
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
- y = ar->winy - 2;
+ y = ar->winy;
if (vcurl == vsell) {
y -= vcurl * lheight;
if (vcurc < vselc)
- glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight + TXT_LINE_SPACING);
+ glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight);
else
- glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight + TXT_LINE_SPACING);
+ glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight);
}
else {
int froml, fromc, tol, toc;
@@ -1420,7 +1073,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
for (i = froml + 1; i < tol; i++)
glRecti(x - 4, y, ar->winx, y - lheight), y -= lheight;
- glRecti(x - 4, y, x + toc * st->cwidth, y - lheight + TXT_LINE_SPACING); y -= lheight;
+ glRecti(x - 4, y, x + toc * st->cwidth, y - lheight); y -= lheight;
}
}
else {
@@ -1445,11 +1098,11 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc);
y1 = ar->winy - 2 - (vsell - offl) * lheight;
- y2 = y1 - lheight * visible_lines + 1;
+ y2 = y1 - (lheight * visible_lines + TXT_LINE_SPACING);
}
else {
y1 = ar->winy - 2 - vsell * lheight;
- y2 = y1 - lheight + 1;
+ y2 = y1 - (lheight + TXT_LINE_SPACING);
}
if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */
@@ -1469,7 +1122,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
/* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
x += vselc * st->cwidth;
- y = ar->winy - 2 - vsell * lheight;
+ y = ar->winy - vsell * lheight;
if (st->overwrite) {
char ch = text->sell->line[text->selc];
@@ -1483,7 +1136,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
}
else {
UI_ThemeColor(TH_HILITE);
- glRecti(x - 1, y, x + 1, y - lheight + TXT_LINE_SPACING);
+ glRecti(x - 1, y, x + 1, y - lheight);
}
}
}
@@ -1517,7 +1170,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
stack = 0;
/* Don't highlight backets if syntax HL is off or bracket in string or comment. */
- if (!linep->format || linep->format[fc] == 'l' || linep->format[fc] == '#')
+ if (!linep->format || linep->format[fc] == FMT_TYPE_STRING || linep->format[fc] == FMT_TYPE_COMMENT)
return;
if (b > 0) {
@@ -1526,7 +1179,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
c += BLI_str_utf8_size_safe(linep->line + c);
while (linep) {
while (c < linep->len) {
- if (linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') {
+ if (linep->format && linep->format[fc] != FMT_TYPE_STRING && linep->format[fc] != FMT_TYPE_COMMENT) {
b = text_check_bracket(linep->line[c]);
if (b == find) {
if (stack == 0) {
@@ -1555,7 +1208,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (c > 0) c -= linep->line + c - BLI_str_prev_char_utf8(linep->line + c);
while (linep) {
while (fc >= 0) {
- if (linep->format && linep->format[fc] != 'l' && linep->format[fc] != '#') {
+ if (linep->format && linep->format[fc] != FMT_TYPE_STRING && linep->format[fc] != FMT_TYPE_COMMENT) {
b = text_check_bracket(linep->line[c]);
if (b == find) {
if (stack == 0) {
@@ -1588,7 +1241,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
UI_ThemeColor(TH_HILITE);
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
- y = ar->winy - st->lheight;
+ y = ar->winy - st->lheight_dpi;
/* draw opening bracket */
ch = startl->line[startc];
@@ -1598,8 +1251,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (viewc >= 0) {
viewl = txt_get_span(text->lines.first, startl) - st->top + offl;
- text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
- text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
}
/* draw closing bracket */
@@ -1610,8 +1263,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (viewc >= 0) {
viewl = txt_get_span(text->lines.first, endl) - st->top + offl;
- text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
- text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch);
}
}
@@ -1620,6 +1273,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
void draw_text_main(SpaceText *st, ARegion *ar)
{
Text *text = st->text;
+ TextFormatType *tft;
TextLine *tmp;
rcti scroll, back;
char linenr[12];
@@ -1627,7 +1281,10 @@ void draw_text_main(SpaceText *st, ARegion *ar)
int wraplinecount = 0, wrap_skip = 0;
int margin_column_x;
- if (st->lheight) st->viewlines = (int)ar->winy / (st->lheight + TXT_LINE_SPACING);
+ /* dpi controlled line height and font size */
+ st->lheight_dpi = (U.widget_unit * st->lheight) / 20;
+
+ if (st->lheight_dpi) st->viewlines = (int)ar->winy / (st->lheight_dpi + TXT_LINE_SPACING);
else st->viewlines = 0;
/* if no text, nothing to do */
@@ -1644,11 +1301,12 @@ void draw_text_main(SpaceText *st, ARegion *ar)
calc_text_rcts(st, ar, &scroll, &back); /* scroll will hold the entire bar size */
/* update syntax formatting if needed */
+ tft = ED_text_format_get(text);
tmp = text->lines.first;
lineno = 0;
for (i = 0; i < st->top && tmp; i++) {
if (st->showsyntax && !tmp->format)
- txt_format_line(st, tmp, 0);
+ tft->format_line(st, tmp, 0);
if (st->wordwrap) {
int lines = text_get_visible_lines_no(st, lineno);
@@ -1686,7 +1344,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
st->linenrs_tot = 0; /* not used */
x = TXT_OFFSET;
}
- y = ar->winy - st->lheight;
+ y = ar->winy - st->lheight_dpi;
winx = ar->winx - TXT_SCROLL_WIDTH;
/* draw cursor */
@@ -1697,7 +1355,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
for (i = 0; y > 0 && i < st->viewlines && tmp; i++, tmp = tmp->next) {
if (st->showsyntax && !tmp->format)
- txt_format_line(st, tmp, 0);
+ tft->format_line(st, tmp, 0);
if (st->showlinenrs && !wrap_skip) {
/* draw line number */
@@ -1716,12 +1374,12 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->wordwrap) {
/* draw word wrapped text */
int lines = text_draw_wrapped(st, tmp->line, x, y, winx - x, tmp->format, wrap_skip);
- y -= lines * (st->lheight + TXT_LINE_SPACING);
+ y -= lines * (st->lheight_dpi + TXT_LINE_SPACING);
}
else {
/* draw unwrapped text */
text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format);
- y -= st->lheight + TXT_LINE_SPACING;
+ y -= st->lheight_dpi + TXT_LINE_SPACING;
}
wrap_skip = 0;
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
new file mode 100644
index 0000000..294f94d
--- /dev/null
+++ b/source/blender/editors/space_text/text_format.c
@@ -0,0 +1,162 @@
+/*
+ * ***** 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
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "text_format.h"
+
+
+/****************** flatten string **********************/
+
+static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
+{
+ int i;
+
+ if (fs->pos + len > fs->len) {
+ char *nbuf; int *naccum;
+ fs->len *= 2;
+
+ nbuf = MEM_callocN(sizeof(*fs->buf) * fs->len, "fs->buf");
+ naccum = MEM_callocN(sizeof(*fs->accum) * fs->len, "fs->accum");
+
+ memcpy(nbuf, fs->buf, fs->pos * sizeof(*fs->buf));
+ memcpy(naccum, fs->accum, fs->pos * sizeof(*fs->accum));
+
+ if (fs->buf != fs->fixedbuf) {
+ MEM_freeN(fs->buf);
+ MEM_freeN(fs->accum);
+ }
+
+ fs->buf = nbuf;
+ fs->accum = naccum;
+ }
+
+ for (i = 0; i < len; i++) {
+ fs->buf[fs->pos + i] = c[i];
+ fs->accum[fs->pos + i] = accum;
+ }
+
+ fs->pos += len;
+}
+
+int flatten_string(SpaceText *st, FlattenString *fs, const char *in)
+{
+ int r, i, total = 0;
+
+ memset(fs, 0, sizeof(FlattenString));
+ fs->buf = fs->fixedbuf;
+ fs->accum = fs->fixedaccum;
+ fs->len = sizeof(fs->fixedbuf);
+
+ for (r = 0, i = 0; *in; r++) {
+ if (*in == '\t') {
+ i = st->tabnumber - (total % st->tabnumber);
+ total += i;
+
+ while (i--)
+ flatten_string_append(fs, " ", r, 1);
+
+ in++;
+ }
+ else {
+ size_t len = BLI_str_utf8_size_safe(in);
+ flatten_string_append(fs, in, r, len);
+ in += len;
+ total++;
+ }
+ }
+
+ flatten_string_append(fs, "\0", r, 1);
+
+ return total;
+}
+
+void flatten_string_free(FlattenString *fs)
+{
+ if (fs->buf != fs->fixedbuf)
+ MEM_freeN(fs->buf);
+ if (fs->accum != fs->fixedaccum)
+ MEM_freeN(fs->accum);
+}
+
+/* takes a string within fs->buf and returns its length */
+int flatten_string_strlen(FlattenString *fs, const char *str)
+{
+ const int len = (fs->pos - (int)(str - fs->buf)) - 1;
+ BLI_assert(strlen(str) == len);
+ return len;
+}
+
+/* Ensures the format string for the given line is long enough, reallocating
+ * as needed. Allocation is done here, alone, to ensure consistency. */
+int text_check_format_len(TextLine *line, unsigned int len)
+{
+ if (line->format) {
+ if (strlen(line->format) < len) {
+ MEM_freeN(line->format);
+ line->format = MEM_mallocN(len + 2, "SyntaxFormat");
+ if (!line->format) return 0;
+ }
+ }
+ else {
+ line->format = MEM_mallocN(len + 2, "SyntaxFormat");
+ if (!line->format) return 0;
+ }
+
+ return 1;
+}
+
+/* *** Registration *** */
+static ListBase tft_lb = {NULL, NULL};
+void ED_text_format_register(TextFormatType *tft)
+{
+ BLI_addtail(&tft_lb, tft);
+}
+
+TextFormatType *ED_text_format_get(Text *text)
+{
+ /* NOTE: once more types are added we'll need to return some type based on 'text'
+ * for now this function is more of a placeholder */
+
+ /* XXX, wrong, but OK for testing */
+ if (text && BLI_testextensie(text->id.name + 2, ".osl")) {
+ return tft_lb.last;
+ }
+ else {
+ return tft_lb.first;
+ }
+}
diff --git a/source/blender/editors/space_text/text_format.h b/source/blender/editors/space_text/text_format.h
new file mode 100644
index 0000000..e593e41
--- /dev/null
+++ b/source/blender/editors/space_text/text_format.h
@@ -0,0 +1,108 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format.h
+ * \ingroup sptext
+ */
+
+#ifndef __TEXT_FORMAT_H__
+#define __TEXT_FORMAT_H__
+
+/* *** Flatten String *** */
+typedef struct FlattenString {
+ char fixedbuf[256];
+ int fixedaccum[256];
+
+ char *buf;
+ int *accum;
+ int pos, len;
+} FlattenString;
+
+/* format continuation flags (stored just after the NULL terminator) */
+enum {
+ FMT_CONT_NOP = 0, /* no continuation */
+ FMT_CONT_QUOTESINGLE = (1 << 0), /* single quotes */
+ FMT_CONT_QUOTEDOUBLE = (1 << 1), /* double quotes */
+ FMT_CONT_TRIPLE = (1 << 2), /* triplets of quotes: """ or ''' */
+ FMT_CONT_QUOTESINGLE_TRIPLE = (FMT_CONT_TRIPLE | FMT_CONT_QUOTESINGLE),
+ FMT_CONT_QUOTEDOUBLE_TRIPLE = (FMT_CONT_TRIPLE | FMT_CONT_QUOTEDOUBLE),
+ FMT_CONT_COMMENT_C = (1 << 3), /* multi-line comments, OSL only (C style) */
+ FMT_CONT_COMMENT_CXX = (1 << 4), /* single-line comments, OSL only (C++ style) */
+};
+#define FMT_CONT_ALL \
+ (FMT_CONT_QUOTESINGLE | FMT_CONT_QUOTEDOUBLE | FMT_CONT_TRIPLE | FMT_CONT_COMMENT_C | FMT_CONT_COMMENT_CXX)
+
+int flatten_string(struct SpaceText *st, FlattenString *fs, const char *in);
+void flatten_string_free(FlattenString *fs);
+int flatten_string_strlen(FlattenString *fs, const char *str);
+
+int text_check_format_len(TextLine *line, unsigned int len);
+
+
+/* *** Generalize Formatting *** */
+typedef struct TextFormatType {
+ struct TextFormatType *next, *prev;
+
+ char (*format_identifier)(const char *string);
+
+ /* Formats the specified line. If do_next is set, the process will move on to
+ * the succeeding line if it is affected (eg. multiline strings). Format strings
+ * may contain any of the following characters:
+ *
+ * It is terminated with a null-terminator '\0' followed by a continuation
+ * flag indicating whether the line is part of a multi-line string.
+ *
+ * See: FMT_TYPE_ enums below
+ */
+ void (*format_line)(SpaceText *st, TextLine *line, int do_next);
+
+ const char **ext; /* NULL terminated extensions */
+} TextFormatType;
+
+enum {
+ FMT_TYPE_WHITESPACE = '_', /* Whitespace */
+ FMT_TYPE_COMMENT = '#', /* Comment text */
+ FMT_TYPE_SYMBOL = '!', /* Punctuation and other symbols */
+ FMT_TYPE_NUMERAL = 'n', /* Numerals */
+ FMT_TYPE_STRING = 'l', /* String letters */
+ FMT_TYPE_DIRECTIVE = 'd', /* Decorator / Preprocessor directive */
+ FMT_TYPE_SPECIAL = 'v', /* Special variables (class, def) */
+ FMT_TYPE_RESERVED = 'r', /* Reserved keywords currently not in use, but still prohibited (OSL -> switch e.g.) */
+ FMT_TYPE_KEYWORD = 'b', /* Built-in names (return, for, etc.) */
+ FMT_TYPE_DEFAULT = 'q', /* Regular text (identifiers, etc.) */
+};
+
+TextFormatType *ED_text_format_get(Text *text);
+void ED_text_format_register(TextFormatType *tft);
+
+/* formatters */
+void ED_text_format_register_py(void);
+void ED_text_format_register_osl(void);
+
+#define STR_LITERAL_STARTSWITH(str, str_literal, len_var) \
+ (strncmp(str, str_literal, len_var = (sizeof(str_literal) - 1)) == 0)
+
+#endif /* __TEXT_FORMAT_H__ */
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
new file mode 100644
index 0000000..3120e88
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -0,0 +1,335 @@
+/*
+ * ***** 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
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format_osl.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** Local Functions (for format_line) *** */
+
+static int txtfmt_osl_find_builtinfunc(const char *string)
+{
+ int i, len;
+ /* list is from
+ * https://github.com/imageworks/OpenShadingLanguage/raw/master/src/doc/osl-languagespec.pdf
+ */
+ if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "closure", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "continue", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "do", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "emit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "float", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "illuminance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "illuminate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "int", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "output", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "point", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "public", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "string", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "struct", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vector", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "void", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static int txtfmt_osl_find_reserved(const char *string)
+{
+ int i, len;
+ /* list is from...
+ * https://github.com/imageworks/OpenShadingLanguage/raw/master/src/doc/osl-languagespec.pdf
+ */
+ if (STR_LITERAL_STARTSWITH(string, "bool", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "catch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "char", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "const", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "delete", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "default", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "double", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "enum", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "extern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "friend", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "goto", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "long", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "new", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "operator", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "private", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "protected", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "short", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "signed", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sizeof", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "static", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "switch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "template", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "this", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "throw", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "try", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "typedef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uniform", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "union", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "unsigned", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "varying", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "virtual", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "volatile", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* Checks the specified source string for a OSL special name. This name must
+ * start at the beginning of the source string and must be followed by a non-
+ * identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a special name is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned. */
+
+static int txtfmt_osl_find_specialvar(const char *string)
+{
+ int i, len;
+
+ /* OSL shader types */
+ if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "volume", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "displacement", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* matches py 'txtfmt_osl_find_decorator' */
+static int txtfmt_osl_find_preprocessor(const char *string)
+{
+ if (string[0] == '#') {
+ int i = 1;
+ /* Whitespace is ok '# foo' */
+ while (text_check_whitespace(string[i])) {
+ i++;
+ }
+ while (text_check_identifier(string[i])) {
+ i++;
+ }
+ return i;
+ }
+ return -1;
+}
+
+static char txtfmt_osl_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_osl_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
+ else if ((txtfmt_osl_find_builtinfunc(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else if ((txtfmt_osl_find_reserved(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else if ((txtfmt_osl_find_preprocessor(str)) != -1) fmt = FMT_TYPE_DIRECTIVE;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const int do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* C-Style comments */
+ if (cont & FMT_CONT_COMMENT_CXX) {
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ else if (cont & FMT_CONT_COMMENT_C) {
+ if (*str == '*' && *(str + 1) == '/') {
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ cont = FMT_CONT_NOP;
+ }
+ else {
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Handle other comments */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = 0;
+ *fmt = FMT_TYPE_STRING;
+ }
+
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* Deal with comments first */
+ if (*str == '/' && *(str + 1) == '/') {
+ cont = FMT_CONT_COMMENT_CXX;
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* C-Style (multi-line) comments */
+ else if (*str == '/' && *(str + 1) == '*') {
+ cont = FMT_CONT_COMMENT_C;
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Punctuation */
+ else if ((*str != '#') && text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_osl_format_identifier()' */
+ if ((i = txtfmt_osl_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
+ else if ((i = txtfmt_osl_find_builtinfunc(str)) != -1) prev = FMT_TYPE_KEYWORD;
+ else if ((i = txtfmt_osl_find_reserved(str)) != -1) prev = FMT_TYPE_RESERVED;
+ else if ((i = txtfmt_osl_find_preprocessor(str)) != -1) prev = FMT_TYPE_DIRECTIVE;
+
+ if (i > 0) {
+ memset(fmt, prev, i);
+ i--; fmt += i; str += i;
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_osl_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_osl(void)
+{
+ static TextFormatType tft = {0};
+ static const char *ext[] = {"osl", NULL};
+
+ tft.format_identifier = txtfmt_osl_format_identifier;
+ tft.format_line = txtfmt_osl_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
new file mode 100644
index 0000000..cbccc6a
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -0,0 +1,322 @@
+/*
+ * ***** 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
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format_py.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** Local Functions (for format_line) *** */
+
+/* Checks the specified source string for a Python built-in function name. This
+ * name must start at the beginning of the source string and must be followed by
+ * a non-identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a built-in function is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://docs.python.org/py3k/reference/lexical_analysis.html#keywords
+ */
+
+static int txtfmt_py_find_builtinfunc(const char *string)
+{
+ int i, len;
+ /* list is from...
+ * ", ".join(['"%s"' % kw
+ * for kw in __import__("keyword").kwlist
+ * if kw not in {"False", "None", "True", "def", "class"}])
+ *
+ * ... and for this code:
+ * print("\n".join(['else if (STR_LITERAL_STARTSWITH(string, "%s", len)) i = len;' % kw
+ * for kw in __import__("keyword").kwlist
+ * if kw not in {"False", "None", "True", "def", "class"}]))
+ */
+
+ if (STR_LITERAL_STARTSWITH(string, "and", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "as", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "assert", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "continue", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "del", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "elif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "except", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "finally", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "from", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "global", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "import", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "in", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "is", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lambda", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "nonlocal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "not", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "or", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pass", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "raise", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "try", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "with", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "yield", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+/* Checks the specified source string for a Python special name. This name must
+ * start at the beginning of the source string and must be followed by a non-
+ * identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a special name is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned. */
+
+static int txtfmt_py_find_specialvar(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "def", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "class", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static int txtfmt_py_find_decorator(const char *string)
+{
+ if (string[0] == '@') {
+ int i = 1;
+ /* Whitespace is ok '@ foo' */
+ while (text_check_whitespace(string[i])) {
+ i++;
+ }
+ while (text_check_identifier(string[i])) {
+ i++;
+ }
+ return i;
+ }
+ return -1;
+}
+
+static int txtfmt_py_find_bool(const char *string)
+{
+ int i, len;
+
+ if (STR_LITERAL_STARTSWITH(string, "None", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "True", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "False", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
+ if (i == 0 || text_check_identifier(string[i]))
+ return -1;
+ return i;
+}
+
+static char txtfmt_py_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_py_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
+ else if ((txtfmt_py_find_builtinfunc(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else if ((txtfmt_py_find_decorator(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const int do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* Triple strings ("""...""" or '''...''') */
+ if (cont & FMT_CONT_TRIPLE) {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find && *(str + 1) == find && *(str + 2) == find) {
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ cont = FMT_CONT_NOP;
+ }
+ /* Handle other strings */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = FMT_CONT_NOP;
+ }
+
+ *fmt = FMT_TYPE_STRING;
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* Deal with comments first */
+ if (prev == FMT_TYPE_COMMENT || *str == '#') {
+ *fmt = FMT_TYPE_COMMENT;
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ if (*(str + 1) == find && *(str + 2) == find) {
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ *fmt = FMT_TYPE_STRING; fmt++; str++;
+ cont |= FMT_CONT_TRIPLE;
+ }
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Booleans */
+ else if (prev != FMT_TYPE_DEFAULT && (i = txtfmt_py_find_bool(str)) != -1) {
+ if (i > 0) {
+ memset(fmt, FMT_TYPE_NUMERAL, i);
+ i--; fmt += i; str += i;
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ /* Punctuation */
+ else if ((*str != '@') && text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_py_format_identifier()' */
+ if ((i = txtfmt_py_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
+ else if ((i = txtfmt_py_find_builtinfunc(str)) != -1) prev = FMT_TYPE_KEYWORD;
+ else if ((i = txtfmt_py_find_decorator(str)) != -1) prev = FMT_TYPE_DIRECTIVE;
+
+ if (i > 0) {
+ memset(fmt, prev, i);
+ i--; fmt += i; str += i;
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_py_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_py(void)
+{
+ static TextFormatType tft = {0};
+ static const char *ext[] = {"py", NULL};
+
+ tft.format_identifier = txtfmt_py_format_identifier;
+ tft.format_line = txtfmt_py_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index 7dc3ec1..52253b2 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -29,20 +29,11 @@
*/
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
/* file time checking */
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#ifndef _WIN32
-# include <unistd.h>
#else
-# include <io.h>
-# include "BLI_winstuff.h"
#endif
#include "DNA_windowmanager_types.h"
@@ -50,7 +41,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_screen.h"
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index ea61644..799bc49 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -54,12 +54,11 @@ void text_scroll_to_cursor(struct SpaceText *st, struct ScrArea *sa);
void text_update_cursor_moved(struct bContext *C);
/* TXT_OFFSET used to be 35 when the scrollbar was on the left... */
-#define TXT_OFFSET 15
-#define TXT_SCROLL_WIDTH 20
-#define TXT_SCROLL_SPACE 2
-#define TXT_LINE_SPACING 4 /* space between lines */
-
-#define TEXTXLOC (st->cwidth * st->linenrs_tot)
+#define TXT_OFFSET ((int)(0.75f * U.widget_unit))
+#define TXT_SCROLL_WIDTH U.widget_unit
+#define TXT_SCROLL_SPACE ((int)(0.1f * U.widget_unit))
+#define TXT_LINE_SPACING ((int)(0.2f * U.widget_unit)) /* space between lines */
+#define TEXTXLOC (st->cwidth * st->linenrs_tot)
#define SUGG_LIST_SIZE 7
#define SUGG_LIST_WIDTH 20
@@ -69,18 +68,6 @@ void text_update_cursor_moved(struct bContext *C);
#define TOOL_SUGG_LIST 0x01
#define TOOL_DOCUMENT 0x02
-typedef struct FlattenString {
- char fixedbuf[256];
- int fixedaccum[256];
-
- char *buf;
- int *accum;
- int pos, len;
-} FlattenString;
-
-int flatten_string(struct SpaceText *st, FlattenString *fs, const char *in);
-void flatten_string_free(FlattenString *fs);
-
int wrap_width(struct SpaceText *st, struct ARegion *ar);
void wrap_offset(struct SpaceText *st, struct ARegion *ar, struct TextLine *linein, int cursin, int *offl, int *offc);
void wrap_offset_in_line(struct SpaceText *st, struct ARegion *ar, struct TextLine *linep, int cursin, int *offl, int *offc);
@@ -156,6 +143,11 @@ void TEXT_OT_to_3d_object(struct wmOperatorType *ot);
void TEXT_OT_resolve_conflict(struct wmOperatorType *ot);
+int text_space_edit_poll(struct bContext *C);
+
+/* text_autocomplete.c */
+void TEXT_OT_autocomplete(struct wmOperatorType *ot);
+
/* space_text.c */
extern const char *text_context_dir[]; /* doc access */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 5b7f927..21966ef 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -30,19 +30,14 @@
*/
-#include <stdlib.h>
#include <string.h>
-#include <ctype.h> /* ispunct */
-#include <sys/stat.h>
#include <errno.h>
#include "MEM_guardedalloc.h"
#include "DNA_text_types.h"
-#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -72,6 +67,7 @@
#endif
#include "text_intern.h"
+#include "text_format.h"
/************************ poll ***************************/
@@ -102,7 +98,7 @@ static int text_edit_poll(bContext *C)
return 1;
}
-static int text_space_edit_poll(bContext *C)
+int text_space_edit_poll(bContext *C)
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -1131,21 +1127,20 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
TextLine *tmp;
FlattenString fs;
size_t a, j;
- char *text_check_line, *new_line;
+ char *new_line;
int extra, number; //unknown for now
int type = RNA_enum_get(op->ptr, "type");
-
- tmp = text->lines.first;
-
+
/* first convert to all space, this make it a lot easier to convert to tabs
* because there is no mixtures of ' ' && '\t' */
- while (tmp) {
- text_check_line = tmp->line;
+ for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+ const char *text_check_line = tmp->line;
+ const int text_check_line_len = tmp->len;
number = flatten_string(st, &fs, text_check_line) + 1;
flatten_string_free(&fs);
new_line = MEM_callocN(number, "Converted_Line");
j = 0;
- for (a = 0; a < strlen(text_check_line); a++) { //foreach char in line
+ for (a = 0; a < text_check_line_len; a++) { //foreach char in line
if (text_check_line[a] == '\t') { //checking for tabs
//get the number of spaces this tabs is showing
//i don't like doing it this way but will look into it later
@@ -1175,20 +1170,19 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
tmp->line = new_line;
tmp->len = strlen(new_line);
tmp->format = NULL;
- tmp = tmp->next;
}
if (type == TO_TABS) { // Converting to tabs
//start over from the beginning
- tmp = text->lines.first;
- while (tmp) {
- text_check_line = tmp->line;
+ for (tmp = text->lines.first; tmp; tmp = tmp->next) {
+ const char *text_check_line = tmp->line;
+ const int text_check_line_len = tmp->len;
extra = 0;
- for (a = 0; a < strlen(text_check_line); a++) {
+ for (a = 0; a < text_check_line_len; a++) {
number = 0;
for (j = 0; j < (size_t)st->tabnumber; j++) {
- if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line
+ if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
if (text_check_line[a + j] != ' ') {
number = 1;
}
@@ -1201,12 +1195,12 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
}
if (extra > 0) { //got tabs make malloc and do what you have to do
- new_line = MEM_callocN(strlen(text_check_line) - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
+ new_line = MEM_callocN(text_check_line_len - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
extra = 0; //reuse vars
- for (a = 0; a < strlen(text_check_line); a++) {
+ for (a = 0; a < text_check_line_len; a++) {
number = 0;
for (j = 0; j < (size_t)st->tabnumber; j++) {
- if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line
+ if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
if (text_check_line[a + j] != ' ') {
number = 1;
}
@@ -1233,7 +1227,6 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
tmp->len = strlen(new_line);
tmp->format = NULL;
}
- tmp = tmp->next;
}
}
@@ -1938,6 +1931,8 @@ static int text_jump_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
void TEXT_OT_jump(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Jump";
ot->idname = "TEXT_OT_jump";
@@ -1949,7 +1944,8 @@ void TEXT_OT_jump(wmOperatorType *ot)
ot->poll = text_edit_poll;
/* properties */
- RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to", 1, 10000);
+ prop = RNA_def_int(ot->srna, "line", 1, 1, INT_MAX, "Line", "Line number to jump to", 1, 10000);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
}
/******************* delete operator **********************/
@@ -2106,10 +2102,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
if (!tsc->scrollbar) {
txtdelta[0] = -tsc->delta[0] / st->cwidth;
- txtdelta[1] = tsc->delta[1] / (st->lheight + TXT_LINE_SPACING);
+ txtdelta[1] = tsc->delta[1] / (st->lheight_dpi + TXT_LINE_SPACING);
tsc->delta[0] %= st->cwidth;
- tsc->delta[1] %= (st->lheight + TXT_LINE_SPACING);
+ tsc->delta[1] %= (st->lheight_dpi + TXT_LINE_SPACING);
}
else {
txtdelta[1] = -tsc->delta[1] * st->pix_per_line;
@@ -2204,7 +2200,7 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
tsc->old[1] = event->y;
/* Sensitivity of scroll set to 4pix per line/char */
tsc->delta[0] = (event->x - event->prevx) * st->cwidth / 4;
- tsc->delta[1] = (event->y - event->prevy) * st->lheight / 4;
+ tsc->delta[1] = (event->y - event->prevy) * st->lheight_dpi / 4;
tsc->first = 0;
tsc->scrollbar = 0;
text_scroll_apply(C, op, event);
@@ -2503,7 +2499,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
{
Text *text = st->text;
text_update_character_width(st);
- y = (ar->winy - 2 - y) / (st->lheight + TXT_LINE_SPACING);
+ y = (ar->winy - 2 - y) / (st->lheight_dpi + TXT_LINE_SPACING);
if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC;
else x -= TXT_OFFSET;
diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c
deleted file mode 100644
index 4c9b4b9..0000000
--- a/source/blender/editors/space_text/text_python.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- *
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/space_text/text_python.c
- * \ingroup sptext
- */
-
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_text_types.h"
-
-#include "BKE_suggestions.h"
-#include "BKE_text.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
-#include "WM_types.h"
-
-#include "text_intern.h"
-
-int text_do_suggest_select(SpaceText *st, ARegion *ar)
-{
- SuggItem *item, *first, *last /* , *sel */ /* UNUSED */;
- TextLine *tmp;
- int l, x, y, w, h, i;
- int tgti, *top;
- int mval[2] = {0, 0};
-
- if (!st || !st->text) return 0;
- if (!texttool_text_is_active(st->text)) return 0;
-
- first = texttool_suggest_first();
- last = texttool_suggest_last();
- /* sel = texttool_suggest_selected(); */ /* UNUSED */
- top = texttool_suggest_top();
-
- if (!last || !first)
- return 0;
-
- /* Count the visible lines to the cursor */
- for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
- if (l < 0) return 0;
-
- text_update_character_width(st);
-
- if (st->showlinenrs) {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
- }
- else {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
- }
- y = ar->winy - st->lheight * l - 2;
-
- w = SUGG_LIST_WIDTH * st->cwidth + 20;
- h = SUGG_LIST_SIZE * st->lheight + 8;
-
- // XXX getmouseco_areawin(mval);
-
- if (mval[0] < x || x + w < mval[0] || mval[1] < y - h || y < mval[1])
- return 0;
-
- /* Work out which of the items is at the top of the visible list */
- for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
-
- /* Work out the target item index in the visible list */
- tgti = (y - mval[1] - 4) / st->lheight;
- if (tgti < 0 || tgti > SUGG_LIST_SIZE)
- return 1;
-
- for (i = tgti; i > 0 && item->next; i--, item = item->next) ;
- if (item)
- texttool_suggest_select(item);
- return 1;
-}
-
-void text_pop_suggest_list(void)
-{
- SuggItem *item, *sel;
- int *top, i;
-
- item = texttool_suggest_first();
- sel = texttool_suggest_selected();
- top = texttool_suggest_top();
-
- i = 0;
- while (item && item != sel) {
- item = item->next;
- i++;
- }
- if (i > *top + SUGG_LIST_SIZE - 1)
- *top = i - SUGG_LIST_SIZE + 1;
- else if (i < *top)
- *top = i;
-}
-
-static void get_suggest_prefix(Text *text, int offset)
-{
- int i, len;
- char *line, tmp[256];
-
- if (!text) return;
- if (!texttool_text_is_active(text)) return;
-
- line = text->curl->line;
- for (i = text->curc - 1 + offset; i >= 0; i--)
- if (!text_check_identifier(line[i]))
- break;
- i++;
- len = text->curc - i + offset;
- if (len > 255) {
- printf("Suggestion prefix too long\n");
- len = 255;
- }
- BLI_strncpy(tmp, line + i, len);
- tmp[len] = '\0';
- texttool_suggest_prefix(tmp);
-}
-
-static void confirm_suggestion(Text *text, int skipleft)
-{
- SuggItem *sel;
- int i, over = 0;
- char *line;
-
- if (!text) return;
- if (!texttool_text_is_active(text)) return;
-
- sel = texttool_suggest_selected();
- if (!sel) return;
-
- line = text->curl->line;
- i = text->curc - skipleft - 1;
- while (i >= 0) {
- if (!text_check_identifier(line[i]))
- break;
- over++;
- i--;
- }
-
- for (i = 0; i < skipleft; i++)
- txt_move_left(text, 0);
- for (i = 0; i < over; i++)
- txt_move_left(text, 1);
-
- txt_insert_buf(text, sel->name);
-
- for (i = 0; i < skipleft; i++)
- txt_move_right(text, 0);
-
- texttool_text_clear();
-}
-
-// XXX
-#define LR_SHIFTKEY 0
-#define LR_ALTKEY 0
-#define LR_CTRLKEY 0
-
-// XXX
-static int doc_scroll = 0;
-
-static short UNUSED_FUNCTION(do_texttools) (SpaceText * st, char ascii, unsigned short evnt, short val)
-{
- ARegion *ar = NULL; // XXX
- int qual = 0; // XXX
- int draw = 0, tools = 0, swallow = 0, scroll = 1;
- if (!texttool_text_is_active(st->text)) return 0;
- if (!st->text || st->text->id.lib) return 0;
-
- if (st->doplugins && texttool_text_is_active(st->text)) {
- if (texttool_suggest_first()) tools |= TOOL_SUGG_LIST;
- if (texttool_docs_get()) tools |= TOOL_DOCUMENT;
- }
-
- if (ascii) {
- if (tools & TOOL_SUGG_LIST) {
- if ((ascii != '_' && ascii != '*' && ispunct(ascii)) || text_check_whitespace(ascii)) {
- confirm_suggestion(st->text, 0);
- text_update_line_edited(st->text->curl);
- }
- else if ((st->overwrite && txt_replace_char(st->text, ascii)) || txt_add_char(st->text, ascii)) {
- get_suggest_prefix(st->text, 0);
- text_pop_suggest_list();
- swallow = 1;
- draw = 1;
- }
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
-
- }
- else if (val == 1 && evnt) {
- switch (evnt) {
- case LEFTMOUSE:
- if (text_do_suggest_select(st, ar))
- swallow = 1;
- else {
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- }
- draw = 1;
- break;
- case MIDDLEMOUSE:
- if (text_do_suggest_select(st, ar)) {
- confirm_suggestion(st->text, 0);
- text_update_line_edited(st->text->curl);
- swallow = 1;
- }
- else {
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- }
- draw = 1;
- break;
- case ESCKEY:
- draw = swallow = 1;
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear();
- else if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- else draw = swallow = 0;
- break;
- case RETKEY:
- if (tools & TOOL_SUGG_LIST) {
- confirm_suggestion(st->text, 0);
- text_update_line_edited(st->text->curl);
- swallow = 1;
- draw = 1;
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
- break;
- case LEFTARROWKEY:
- case BACKSPACEKEY:
- if (tools & TOOL_SUGG_LIST) {
- if (qual)
- texttool_suggest_clear();
- else {
- /* Work out which char we are about to delete/pass */
- if (st->text->curl && st->text->curc > 0) {
- char ch = st->text->curl->line[st->text->curc - 1];
- if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
- get_suggest_prefix(st->text, -1);
- text_pop_suggest_list();
- }
- else
- texttool_suggest_clear();
- }
- else
- texttool_suggest_clear();
- }
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- break;
- case RIGHTARROWKEY:
- if (tools & TOOL_SUGG_LIST) {
- if (qual)
- texttool_suggest_clear();
- else {
- /* Work out which char we are about to pass */
- if (st->text->curl && st->text->curc < st->text->curl->len) {
- char ch = st->text->curl->line[st->text->curc + 1];
- if ((ch == '_' || !ispunct(ch)) && !text_check_whitespace(ch)) {
- get_suggest_prefix(st->text, 1);
- text_pop_suggest_list();
- }
- else
- texttool_suggest_clear();
- }
- else
- texttool_suggest_clear();
- }
- }
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0;
- break;
- case PAGEDOWNKEY:
- scroll = SUGG_LIST_SIZE - 1;
- case WHEELDOWNMOUSE:
- case DOWNARROWKEY:
- if (tools & TOOL_DOCUMENT) {
- doc_scroll++;
- swallow = 1;
- draw = 1;
- break;
- }
- else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- if (!sel) {
- texttool_suggest_select(texttool_suggest_first());
- }
- else {
- while (sel && sel != texttool_suggest_last() && sel->next && scroll--) {
- texttool_suggest_select(sel->next);
- sel = sel->next;
- }
- }
- text_pop_suggest_list();
- swallow = 1;
- draw = 1;
- break;
- }
- case PAGEUPKEY:
- scroll = SUGG_LIST_SIZE - 1;
- case WHEELUPMOUSE:
- case UPARROWKEY:
- if (tools & TOOL_DOCUMENT) {
- if (doc_scroll > 0) doc_scroll--;
- swallow = 1;
- draw = 1;
- break;
- }
- else if (tools & TOOL_SUGG_LIST) {
- SuggItem *sel = texttool_suggest_selected();
- while (sel && sel != texttool_suggest_first() && sel->prev && scroll--) {
- texttool_suggest_select(sel->prev);
- sel = sel->prev;
- }
- text_pop_suggest_list();
- swallow = 1;
- draw = 1;
- break;
- }
- case RIGHTSHIFTKEY:
- case LEFTSHIFTKEY:
- break;
- default:
- if (tools & TOOL_SUGG_LIST) texttool_suggest_clear(), draw = 1;
- if (tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll = 0, draw = 1;
- }
- }
-
- if (draw) {
- // XXX redraw_alltext();
- }
-
- return swallow;
-}
diff --git a/source/blender/editors/space_time/SConscript b/source/blender/editors/space_time/SConscript
index c08339b..32f02bf 100644
--- a/source/blender/editors/space_time/SConscript
+++ b/source/blender/editors/space_time/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_userpref/SConscript b/source/blender/editors/space_userpref/SConscript
index 5c52e6f..d5aa930 100644
--- a/source/blender/editors/space_userpref/SConscript
+++ b/source/blender/editors/space_userpref/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 1ea3876..5ebbebe 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -105,14 +105,16 @@ static SpaceLink *userpref_duplicate(SpaceLink *sl)
/* add handlers, stuff you only do once or on area/region changes */
static void userpref_main_area_init(wmWindowManager *wm, ARegion *ar)
{
+ /* do not use here, the properties changed in userprefs do a system-wide refresh, then scroller jumps back */
+ /* ar->v2d.flag &= ~V2D_IS_INITIALISED; */
+
+ ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
+
ED_region_panels_init(wm, ar);
}
static void userpref_main_area_draw(const bContext *C, ARegion *ar)
{
- /* this solves "vibrating UI" bug #25422 */
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
-
ED_region_panels(C, ar, 1, NULL, -1);
}
diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript
index ffe3501..578f06a 100644
--- a/source/blender/editors/space_view3d/SConscript
+++ b/source/blender/editors/space_view3d/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index 0649edc..5786485 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -139,35 +139,38 @@ void draw_motion_path_instance(Scene *scene,
short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
float intensity; /* how faint */
+ int frame = sfra + i;
+ int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */
+
/* set color
* - more intense for active/selected bones, less intense for unselected bones
* - black for before current frame, green for current frame, blue for after current frame
* - intensity decreases as distance from current frame increases
*/
#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min)
- if ((sfra + i) < CFRA) {
+ if (frame < CFRA) {
/* black - before cfra */
if (sel) {
- // intensity = 0.5f;
+ /* intensity = 0.5f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f);
}
else {
- //intensity = 0.8f;
+ /* intensity = 0.8f; */
intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
+ UI_ThemeColorBlend(TH_WIRE, blend_base, intensity);
}
- else if ((sfra + i) > CFRA) {
+ else if (frame > CFRA) {
/* blue - after cfra */
if (sel) {
- //intensity = 0.5f;
+ /* intensity = 0.5f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f);
}
else {
- //intensity = 0.8f;
+ /* intensity = 0.8f; */
intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f);
}
- UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
+ UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity);
}
else {
/* green - on cfra */
@@ -232,21 +235,22 @@ void draw_motion_path_instance(Scene *scene,
col[3] = 255;
for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
+ int frame = sfra + i;
char numstr[32];
float co[3];
/* only draw framenum if several consecutive highlighted points don't occur on same point */
if (i == 0) {
- sprintf(numstr, "%d", (i + sfra));
+ sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
- else if ((i > stepsize) && (i < len - stepsize)) {
+ else if ((i >= stepsize) && (i < len - stepsize)) {
bMotionPathVert *mpvP = (mpv - stepsize);
bMotionPathVert *mpvN = (mpv + stepsize);
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
- sprintf(numstr, "%d", (sfra + i));
+ sprintf(numstr, " %d", frame);
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
@@ -286,12 +290,13 @@ void draw_motion_path_instance(Scene *scene,
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
col[3] = 255;
- glPointSize(4.0f); // XXX perhaps a bit too big
+ glPointSize(4.0f);
glColor3ubv(col);
glBegin(GL_POINTS);
for (i = 0, mpv = mpv_start; i < len; i++, mpv++) {
- float mframe = (float)(sfra + i);
+ int frame = sfra + i;
+ float mframe = (float)(frame);
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe))
glVertex3fv(mpv->co);
@@ -309,7 +314,7 @@ void draw_motion_path_instance(Scene *scene,
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
char numstr[32];
- sprintf(numstr, "%d", (sfra + i));
+ sprintf(numstr, " %d", (sfra + i));
mul_v3_m4v3(co, ob->imat, mpv->co);
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index beafee3..f37437b 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -637,7 +637,7 @@ static float co[16] = {
/* smat, imat = mat & imat to draw screenaligned */
-static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel *pchan, EditBone *ebone)
+static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone)
{
float head, tail, dist /*, length*/;
float *headvec, *tailvec, dirvec[3];
@@ -755,7 +755,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel
/* smat, imat = mat & imat to draw screenaligned */
-static void draw_sphere_bone_wire(float smat[][4], float imat[][4],
+static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
@@ -1648,7 +1648,7 @@ static void draw_pose_dofs(Object *ob)
}
}
-static void bone_matrix_translate_y(float mat[][4], float y)
+static void bone_matrix_translate_y(float mat[4][4], float y)
{
float trans[3];
@@ -2069,7 +2069,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* in editmode, we don't store the bone matrix... */
-static void get_matrix_editbone(EditBone *eBone, float bmat[][4])
+static void get_matrix_editbone(EditBone *eBone, float bmat[4][4])
{
float delta[3];
float mat[3][3];
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 0ecde35..fa72f28 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -396,6 +396,7 @@ static void draw_textured_end(void)
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
/* XXX, bad patch - GPU_default_lights() calls
* glLightfv(GL_POSITION, ...) which
@@ -415,14 +416,14 @@ static void draw_textured_end(void)
static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
{
Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
- int validtexture = 0;
+ int invalidtexture = 0;
if (ma && (ma->game.flag & GEMAT_INVISIBLE))
return DM_DRAW_OPTION_SKIP;
- validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
+ invalidtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
- if (tface && validtexture) {
+ if (tface && invalidtexture) {
glColor3ub(0xFF, 0x00, 0xFF);
return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
}
@@ -457,25 +458,14 @@ static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mc
return DM_DRAW_OPTION_NO_MCOL;
}
-static DMDrawOption draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
+static DMDrawOption draw_tface__set_draw(MTFace *UNUSED(tface), int UNUSED(has_mcol), int matnr)
{
Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
- if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
- return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
- }
- else if (tface && (tface->mode & TF_OBCOL)) {
- return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
- }
- else if (!has_mcol) {
- /* XXX: this return value looks wrong (and doesn't match comment) */
- return DM_DRAW_OPTION_NORMAL; /* Don't set color */
- }
- else {
- return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
- }
+ /* always use color from mcol, as set in update_tface_color_layer */
+ return DM_DRAW_OPTION_NORMAL;
}
static void update_tface_color_layer(DerivedMesh *dm)
@@ -517,11 +507,11 @@ static void update_tface_color_layer(DerivedMesh *dm)
finalCol[i * 4 + j].r = 255;
}
}
- else if (tface && (tface->mode & TF_OBCOL)) {
+ else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
for (j = 0; j < 4; j++) {
- finalCol[i * 4 + j].b = FTOCHAR(Gtexdraw.obcol[0]);
- finalCol[i * 4 + j].g = FTOCHAR(Gtexdraw.obcol[1]);
- finalCol[i * 4 + j].r = FTOCHAR(Gtexdraw.obcol[2]);
+ finalCol[i * 4 + j].b = Gtexdraw.obcol[0];
+ finalCol[i * 4 + j].g = Gtexdraw.obcol[1];
+ finalCol[i * 4 + j].r = Gtexdraw.obcol[2];
}
}
else if (!mcol) {
@@ -1029,7 +1019,7 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
const short do_light = (v3d->drawtype >= OB_SOLID);
/* hide faces in face select mode */
- if (draw_flags & DRAW_FACE_SELECT)
+ if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL))
facemask = wpaint__setSolidDrawOptions_facemask;
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
@@ -1077,12 +1067,18 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
draw_mesh_face_select(rv3d, me, dm);
}
else if ((do_light == FALSE) || (ob->dtx & OB_DRAWWIRE)) {
+ const int use_depth = (v3d->flag & V3D_ZBUF_SELECT);
/* weight paint in solid mode, special case. focus on making the weights clear
* rather than the shading, this is also forced in wire view */
- bglPolygonOffset(rv3d->dist, 1.0);
- glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
+ if (use_depth) {
+ bglPolygonOffset(rv3d->dist, 1.0);
+ glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
+ }
+ else {
+ glDisable(GL_DEPTH_TEST);
+ }
glEnable(GL_BLEND);
glColor4ub(255, 255, 255, 96);
@@ -1091,8 +1087,14 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
dm->drawEdges(dm, 1, 1);
- bglPolygonOffset(rv3d->dist, 0.0);
- glDepthMask(1);
+ if (use_depth) {
+ bglPolygonOffset(rv3d->dist, 0.0);
+ glDepthMask(1);
+ }
+ else {
+ glEnable(GL_DEPTH_TEST);
+ }
+
glDisable(GL_LINE_STIPPLE);
glDisable(GL_BLEND);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index ede2046..76f73e1 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -101,7 +101,7 @@ typedef enum eWireDrawMode {
} eWireDrawMode;
typedef struct drawDMVerts_userData {
- BMEditMesh *em; /* BMESH BRANCH ONLY */
+ BMEditMesh *em;
int sel;
BMVert *eve_act;
@@ -119,7 +119,7 @@ typedef struct drawDMVerts_userData {
} drawDMVerts_userData;
typedef struct drawDMEdgesSel_userData {
- BMEditMesh *em; /* BMESH BRANCH ONLY */
+ BMEditMesh *em;
unsigned char *baseCol, *selCol, *actCol;
BMEdge *eed_act;
@@ -128,8 +128,8 @@ typedef struct drawDMEdgesSel_userData {
typedef struct drawDMFacesSel_userData {
unsigned char *cols[3];
- DerivedMesh *dm; /* BMESH BRANCH ONLY */
- BMEditMesh *em; /* BMESH BRANCH ONLY */
+ DerivedMesh *dm;
+ BMEditMesh *em;
BMFace *efa_act;
int *orig_index_mf_to_mpoly;
@@ -622,7 +622,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
BKE_image_release_ibuf(ima, ibuf, NULL);
}
-static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4])
+static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[4][4])
{
float vx[3], vy[3];
float *viter = (float *)verts;
@@ -638,7 +638,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3
}
}
-void drawcircball(int mode, const float cent[3], float rad, float tmat[][4])
+void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4])
{
float verts[CIRCLE_RESOL][3];
@@ -739,7 +739,7 @@ void view3d_cached_text_draw_add(const float co[3],
memcpy(++vos, str, alloc_len);
}
-void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
ListBase *strings = &CachedText[CachedTextLevel - 1];
@@ -755,7 +755,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
(vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
(vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
vos->vec, vos->sco,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
tot++;
}
@@ -929,7 +929,7 @@ static void drawcube_size(const float size[3])
}
#endif
-static void drawshadbuflimits(Lamp *la, float mat[][4])
+static void drawshadbuflimits(Lamp *la, float mat[4][4])
{
float sta[3], end[3], lavec[3];
@@ -1286,6 +1286,13 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
glVertex3fv(vvec_clip);
glEnd();
}
+ /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */
+ else {
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(0.0, 0.0, -circrad);
+ glVertex3f(0.0, 0.0, -la->dist);
+ glEnd();
+ }
}
else if (ELEM(la->type, LA_HEMI, LA_SUN)) {
@@ -2584,10 +2591,10 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
/* make the precision of the display value proportionate to the gridsize */
- if (grid < 0.01f) conv_float = "%.6g";
- else if (grid < 0.1f) conv_float = "%.5g";
- else if (grid < 1.0f) conv_float = "%.4g";
- else if (grid < 10.0f) conv_float = "%.3g";
+ if (grid <= 0.01f) conv_float = "%.6g";
+ else if (grid <= 0.1f) conv_float = "%.5g";
+ else if (grid <= 1.0f) conv_float = "%.4g";
+ else if (grid <= 10.0f) conv_float = "%.3g";
else conv_float = "%.2g";
if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
@@ -2838,7 +2845,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
}
}
- EDBM_index_arrays_init(em, 1, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE);
if (dt > OB_WIRE) {
if (check_object_draw_texture(scene, v3d, dt)) {
@@ -2989,8 +2996,6 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
bglPolygonOffset(rv3d->dist, 0.0);
GPU_disable_material();
}
-
- EDBM_index_arrays_free(em);
}
/* Mesh drawing routines */
@@ -3239,11 +3244,15 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
if (is_obact && paint_vertsel_test(ob)) {
-
+ const int use_depth = (v3d->flag & V3D_ZBUF_SELECT);
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
-
+
+ if (!use_depth) glDisable(GL_DEPTH_TEST);
+ else bglPolygonOffset(rv3d->dist, 1.0);
drawSelectedVertices(dm, ob->data);
+ if (!use_depth) glEnable(GL_DEPTH_TEST);
+ else bglPolygonOffset(rv3d->dist, 0.0);
glPointSize(1.0f);
}
@@ -3416,7 +3425,7 @@ static int drawDispListwire(ListBase *dlbase)
#if 0
/* (ton) this code crashes for me when resolv is 86 or higher... no clue */
- glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3*nr);
+ glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr);
if (dl->flag & DL_CYCL_V)
glDrawArrays(GL_LINE_LOOP, 0, dl->parts);
else
@@ -5434,10 +5443,10 @@ static void curve_draw_speed(Scene *scene, Object *ob)
#endif /* XXX old animation system stuff */
-static void draw_textcurs(float textcurs[4][2])
+static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2])
{
cpack(0);
-
+ bglPolygonOffset(rv3d->dist, -1.0);
set_inverted_drawing(1);
glBegin(GL_QUADS);
glVertex2fv(textcurs[0]);
@@ -5446,9 +5455,10 @@ static void draw_textcurs(float textcurs[4][2])
glVertex2fv(textcurs[3]);
glEnd();
set_inverted_drawing(0);
+ bglPolygonOffset(rv3d->dist, 0.0);
}
-static void drawspiral(const float cent[3], float rad, float tmat[][4], int start)
+static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start)
{
float vec[3], vx[3], vy[3];
const float tot_inv = (1.0f / (float)CIRCLE_RESOL);
@@ -5537,7 +5547,7 @@ static void drawcircle_size(float size)
}
/* needs fixing if non-identity matrice used */
-static void drawtube(const float vec[3], float radius, float height, float tmat[][4])
+static void drawtube(const float vec[3], float radius, float height, float tmat[4][4])
{
float cur[3];
drawcircball(GL_LINE_LOOP, vec, radius, tmat);
@@ -5559,7 +5569,7 @@ static void drawtube(const float vec[3], float radius, float height, float tmat[
glEnd();
}
/* needs fixing if non-identity matrice used */
-static void drawcone(const float vec[3], float radius, float height, float tmat[][4])
+static void drawcone(const float vec[3], float radius, float height, float tmat[4][4])
{
float cur[3];
@@ -6366,7 +6376,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
case OB_FONT:
cu = ob->data;
if (cu->editfont) {
- draw_textcurs(cu->editfont->textcurs);
+ draw_textcurs(rv3d, cu->editfont->textcurs);
if (cu->flag & CU_FAST) {
cpack(0xFFFFFF);
@@ -6875,10 +6885,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
UI_make_axis_color(col1, col2, 'Z');
glColor3ubv(col2);
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
for (curcon = list->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(curcon);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -6932,7 +6942,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
}
- constraints_clear_evalob(cob);
+ BKE_constraints_clear_evalob(cob);
}
}
@@ -7093,14 +7103,28 @@ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
return DM_DRAW_OPTION_SKIP;
}
}
-static void bbs_mesh_solid(Scene *scene, Object *ob)
+
+static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
+{
+ Mesh *me = ob->data;
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
+ glColor3ub(0, 0, 0);
+
+ dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
+
+ bbs_obmode_mesh_verts(ob, dm, 1);
+ bm_vertoffs = me->totvert + 1;
+ dm->release(dm);
+}
+
+static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
Mesh *me = (Mesh *)ob->data;
glColor3ub(0, 0, 0);
- if ((me->editflag & ME_EDIT_PAINT_MASK))
+ if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, GPU_enable_material, NULL, me, 0);
else
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, GPU_enable_material, NULL, me, 0);
@@ -7125,7 +7149,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
- EDBM_index_arrays_init(em, 1, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE);
bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
if (ts->selectmode & SCE_SELECT_FACE)
@@ -7151,27 +7175,17 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
bglPolygonOffset(rv3d->dist, 0.0);
dm->release(dm);
-
- EDBM_index_arrays_free(em);
}
else {
Mesh *me = ob->data;
- if ((me->editflag & ME_EDIT_VERT_SEL) &&
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
/* currently vertex select only supports weight paint */
(ob->mode & OB_MODE_WEIGHT_PAINT))
{
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- glColor3ub(0, 0, 0);
-
- dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
-
-
- bbs_obmode_mesh_verts(ob, dm, 1);
- bm_vertoffs = me->totvert + 1;
- dm->release(dm);
+ bbs_mesh_solid_verts(scene, ob);
}
else {
- bbs_mesh_solid(scene, ob);
+ bbs_mesh_solid_faces(scene, ob);
}
}
break;
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index ebb4896..29daee3 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -38,6 +38,7 @@
#include "DNA_screen_types.h"
#include "DNA_smoke_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_property_types.h"
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
@@ -448,8 +449,8 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
* inserting previously found vertex into the plane equation */
/* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */
- ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]);
- dd = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f;
+ ds = (fabsf(viewnormal[0]) * size[0] + fabsf(viewnormal[1]) * size[1] + fabsf(viewnormal[2]) * size[2]);
+ dd = max_fff(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f;
n = 0;
good_index = i;
@@ -569,7 +570,7 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob)
float min[3];
float *cell_size = domain->cell_size;
- float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f;
+ float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f;
float vf = domain->scale / 16.f * 2.f; /* velocity factor */
glLineWidth(1.0f);
@@ -623,7 +624,7 @@ void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob)
float min[3];
float *cell_size = domain->cell_size;
- float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f;
+ float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f;
float vf = domain->scale / 16.f * 2.f; /* velocity factor */
/* set first position so that it doesn't jump when domain moves */
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 1c31cd2..1d87895 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -117,7 +117,7 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
BLI_insertlinkafter(&sa->regionbase, arhead, artool);
artool->regiontype = RGN_TYPE_TOOLS;
- artool->alignment = RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT;
+ artool->alignment = RGN_ALIGN_LEFT;
artool->flag = RGN_FLAG_HIDDEN;
}
@@ -261,14 +261,11 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->gridlines = 16;
v3d->gridsubdiv = 10;
v3d->drawtype = OB_SOLID;
+
+ v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
- v3d->gridflag |= V3D_SHOW_X;
- v3d->gridflag |= V3D_SHOW_Y;
- v3d->gridflag |= V3D_SHOW_FLOOR;
- v3d->gridflag &= ~V3D_SHOW_Z;
-
- v3d->flag |= V3D_SELECT_OUTLINE;
- v3d->flag2 |= V3D_SHOW_RECONSTRUCTION;
+ v3d->flag = V3D_SELECT_OUTLINE;
+ v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
v3d->lens = 35.0f;
v3d->near = 0.01f;
@@ -469,6 +466,16 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSE
return 0;
}
+static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+{
+ if (drag->type == WM_DRAG_ID) {
+ ID *id = (ID *)drag->poin;
+ if (GS(id->name) == ID_GR)
+ return 1;
+ }
+ return 0;
+}
+
static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
@@ -513,14 +520,16 @@ static int view3d_ima_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = (ID *)drag->poin;
- PointerRNA ptr;
- /* need to put name in sub-operator in macro */
- ptr = RNA_pointer_get(drop->ptr, "OBJECT_OT_add_named");
- if (ptr.data)
- RNA_string_set(&ptr, "name", id->name + 2);
- else
- RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_string_set(drop->ptr, "name", id->name + 2);
+}
+
+static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
+{
+ ID *id = (ID *)drag->poin;
+
+ drop->opcontext = WM_OP_EXEC_DEFAULT;
+ RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
@@ -546,10 +555,11 @@ static void view3d_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
- WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_ob_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_ob_drop_poll, view3d_id_path_drop_copy);
WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
+ WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
}
@@ -635,8 +645,7 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
{
- bScreen *sc;
-
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -659,7 +668,8 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case NC_SCENE:
switch (wmn->data) {
case ND_LAYER_CONTENT:
- view3d_recalc_used_layers(ar, wmn, wmn->reference);
+ if (wmn->reference)
+ view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar);
break;
case ND_FRAME:
@@ -787,8 +797,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_SCREENSET:
/* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
/* updates used layers only for View3D in active screen */
- sc = wmn->reference;
- view3d_recalc_used_layers(ar, wmn, sc->scene);
+ if (wmn->reference) {
+ bScreen *sc = wmn->reference;
+ view3d_recalc_used_layers(ar, wmn, sc->scene);
+ }
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index cffc5ed..ec71628 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -179,32 +179,47 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
BMEdge *eed;
BMIter iter;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs;
-
- evedef = eve;
- tot++;
- add_v3_v3(&median[LOC_X], eve->co);
-
- vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs) {
- add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
- totskinradius++;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ if (bm->totvertsel) {
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ evedef = eve;
+ tot++;
+ add_v3_v3(&median[LOC_X], eve->co);
+
+ /* TODO cd_vert_bweight_offset */
+ (void)cd_vert_bweight_offset;
+
+ if (cd_vert_skin_offset != -1) {
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
+ totskinradius++;
+ }
}
}
}
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *f;
+ if ((cd_edge_bweight_offset != -1) ||
+ (cd_edge_crease_offset != -1))
+ {
+ if (bm->totedgesel) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
+ if (cd_edge_bweight_offset != -1) {
+ median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset);
+ }
- totedgedata++;
- f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- median[M_CREASE] += f ? *f : 0.0f;
+ if (cd_edge_crease_offset != -1) {
+ median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset);
+ }
- f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- median[M_WEIGHT] += f ? *f : 0.0f;
+ totedgedata++;
+ }
+ }
}
}
@@ -365,7 +380,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (block) { /* buttons */
uiBut *but;
int yi = 200;
- const int buth = 20 * UI_DPI_ICON_FAC;
+ const int buth = 20 * UI_DPI_FAC;
const int but_margin = 2;
const char *c;
@@ -412,14 +427,26 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
/* Meshes... */
if (meshdata) {
if (totedgedata) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
- totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
- totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMesh *bm = em->bm;
+
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ if (cd_edge_crease_offset != -1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
+ }
+
+ if (cd_edge_bweight_offset != -1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ }
}
if (totskinradius) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
@@ -502,91 +529,85 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (median[M_CREASE] != 0.0f) {
- BMEdge *eed;
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]);
+ BMEdge *eed;
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease = sca;
- }
+ BM_ELEM_CD_SET_FLOAT(eed, cd_edge_crease_offset, sca);
}
}
}
else if (sca > 0.0f) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease *= sca;
- CLAMP(*crease, 0.0f, 1.0f);
- }
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ *crease *= sca;
+ CLAMP(*crease, 0.0f, 1.0f);
}
}
}
else {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- if (crease) {
- *crease = 1.0f + ((1.0f - *crease) * sca);
- CLAMP(*crease, 0.0f, 1.0f);
- }
+ float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset);
+ *crease = 1.0f + ((1.0f - *crease) * sca);
+ CLAMP(*crease, 0.0f, 1.0f);
}
}
}
}
if (median[M_WEIGHT] != 0.0f) {
- BMEdge *eed;
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]);
+ BMEdge *eed;
+
+ BLI_assert(cd_edge_bweight_offset != -1);
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight = sca;
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight = sca;
}
}
}
else if (sca > 0.0f) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight *= sca;
- CLAMP(*bweight, 0.0f, 1.0f);
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight *= sca;
+ CLAMP(*bweight, 0.0f, 1.0f);
}
}
}
else {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- if (bweight) {
- *bweight = 1.0f + ((1.0f - *bweight) * sca);
- CLAMP(*bweight, 0.0f, 1.0f);
- }
+ float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset);
+ *bweight = 1.0f + ((1.0f - *bweight) * sca);
+ CLAMP(*bweight, 0.0f, 1.0f);
}
}
}
}
if (median[M_SKIN_X] != 0.0f) {
- BMVert *eve;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
/* That one is not clamped to [0.0, 1.0]. */
float sca = ve_median[M_SKIN_X];
+ BMVert *eve;
+
+ BLI_assert(cd_vert_skin_offset != -1);
+
if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[0] = sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[0] = sca;
}
}
}
@@ -594,23 +615,25 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[0] *= sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[0] *= sca;
}
}
}
}
if (median[M_SKIN_Y] != 0.0f) {
- BMVert *eve;
+ const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
/* That one is not clamped to [0.0, 1.0]. */
float sca = ve_median[M_SKIN_Y];
+ BMVert *eve;
+
+ BLI_assert(cd_vert_skin_offset != -1);
+
if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[1] = sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[1] = sca;
}
}
}
@@ -618,14 +641,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
- if (vs)
- vs->radius[1] *= sca;
+ MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset);
+ vs->radius[1] *= sca;
}
}
}
}
- EDBM_mesh_normals_update(em);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
@@ -1260,6 +1281,7 @@ void view3d_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
strcpy(pt->idname, "VIEW3D_PT_gpencil");
strcpy(pt->label, "Grease Pencil");
+ pt->draw_header = gpencil_panel_standard_header;
pt->draw = gpencil_panel_standard;
BLI_addtail(&art->paneltypes, pt);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 51261f4..67344a9 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -217,7 +217,7 @@ void ED_view3d_clipping_enable(void)
}
}
-static int view3d_clipping_test(const float vec[3], float clip[][4])
+static int view3d_clipping_test(const float vec[3], float clip[6][4])
{
float view[3];
copy_v3_v3(view, vec);
@@ -315,7 +315,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
UI_ThemeColor(TH_GRID);
if (unit->system) {
- /* Use GRID_MIN_PX*2 for units because very very small grid
+ /* Use GRID_MIN_PX * 2 for units because very very small grid
* items are less useful when dealing with units */
void *usys;
int len, i;
@@ -381,7 +381,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
}
}
- else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10)) */
+ else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
drawgrid_draw(ar, wx, wy, x, y, dx);
@@ -563,41 +563,49 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
if (v3d->zbuf && scene->obedit) glDepthMask(1);
}
+
static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
{
int co[2];
/* we don't want the clipping for cursor */
if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ const float f5 = 0.25f * U.widget_unit;
+ const float f10 = 0.5f * U.widget_unit;
+ const float f20 = U.widget_unit;
+
setlinestyle(0);
cpack(0xFF);
- circ((float)co[0], (float)co[1], 10.0);
- setlinestyle(4);
+ circ((float)co[0], (float)co[1], f10);
+ setlinestyle(4);
cpack(0xFFFFFF);
- circ((float)co[0], (float)co[1], 10.0);
+ circ((float)co[0], (float)co[1], f10);
setlinestyle(0);
cpack(0x0);
- sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]);
- sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]);
- sdrawline(co[0], co[1] - 20, co[0], co[1] - 5);
- sdrawline(co[0], co[1] + 5, co[0], co[1] + 20);
+ sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]);
+ sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]);
+ sdrawline(co[0], co[1] - f20, co[0], co[1] - f5);
+ sdrawline(co[0], co[1] + f5, co[0], co[1] + f20);
}
}
/* Draw a live substitute of the view icon, which is always shown
* colors copied from transform_manipulator.c, we should keep these matching. */
-static void draw_view_axis(RegionView3D *rv3d)
+static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
{
const float k = U.rvisize; /* axis size */
const float toll = 0.5; /* used to see when view is quasi-orthogonal */
- const float start = k + 1.0f; /* axis center in screen coordinates, x=y */
+ float startx = k + 1.0f; /* axis center in screen coordinates, x=y */
+ float starty = k + 1.0f;
float ydisp = 0.0; /* vertical displacement to allow obj info text */
- int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */
-
+ int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
float vec[3];
float dx, dy;
+ startx += rect->xmin;
+ starty += rect->ymin;
+
/* thickness of lines is proportional to k */
glLineWidth(2);
@@ -613,12 +621,12 @@ static void draw_view_axis(RegionView3D *rv3d)
UI_ThemeColorShadeAlpha(TH_AXIS_X, 0, bright);
glBegin(GL_LINES);
- glVertex2f(start, start + ydisp);
- glVertex2f(start + dx, start + dy + ydisp);
+ glVertex2f(startx, starty + ydisp);
+ glVertex2f(startx + dx, starty + dy + ydisp);
glEnd();
if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1);
+ BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "x", 1);
}
/* BLF_draw_default disables blending */
@@ -633,12 +641,12 @@ static void draw_view_axis(RegionView3D *rv3d)
UI_ThemeColorShadeAlpha(TH_AXIS_Y, 0, bright);
glBegin(GL_LINES);
- glVertex2f(start, start + ydisp);
- glVertex2f(start + dx, start + dy + ydisp);
+ glVertex2f(startx, starty + ydisp);
+ glVertex2f(startx + dx, starty + dy + ydisp);
glEnd();
if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1);
+ BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "y", 1);
}
glEnable(GL_BLEND);
@@ -652,12 +660,12 @@ static void draw_view_axis(RegionView3D *rv3d)
UI_ThemeColorShadeAlpha(TH_AXIS_Z, 0, bright);
glBegin(GL_LINES);
- glVertex2f(start, start + ydisp);
- glVertex2f(start + dx, start + dy + ydisp);
+ glVertex2f(startx, starty + ydisp);
+ glVertex2f(startx + dx, starty + dy + ydisp);
glEnd();
if (fabsf(dx) > toll || fabsf(dy) > toll) {
- BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1);
+ BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "z", 1);
}
/* restore line-width */
@@ -770,7 +778,7 @@ static void draw_rotation_guide(RegionView3D *rv3d)
glDepthMask(1);
}
-static void draw_view_icon(RegionView3D *rv3d)
+static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
{
BIFIconID icon;
@@ -785,7 +793,7 @@ static void draw_view_icon(RegionView3D *rv3d)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- UI_icon_draw(5.0, 5.0, icon);
+ UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon);
glDisable(GL_BLEND);
}
@@ -840,7 +848,7 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
return name;
}
-static void draw_viewport_name(ARegion *ar, View3D *v3d)
+static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
const char *name = view3d_get_name(v3d, rv3d);
@@ -853,17 +861,17 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d)
if (name) {
UI_ThemeColor(TH_TEXT_HI);
- BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, name, sizeof(tmpstr));
+ BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr));
}
}
/* draw info beside axes in bottom left-corner:
* framenum, object name, bone name (if available), marker name (if available)
*/
-static void draw_selected_name(Scene *scene, Object *ob)
+static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
{
char info[256], *markern;
- short offset = 30;
+ short offset = 30 + rect->xmin;
/* get name of marker on current frame (if available) */
markern = BKE_scene_find_marker_name(scene, CFRA);
@@ -929,7 +937,7 @@ static void draw_selected_name(Scene *scene, Object *ob)
}
/* color depends on whether there is a keyframe */
- if (id_frame_has_keyframe((ID *)ob, /*BKE_scene_frame_get(scene)*/ (float)(CFRA), ANIMFILTER_KEYS_LOCAL))
+ if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)(CFRA), ANIMFILTER_KEYS_LOCAL))
UI_ThemeColor(TH_VERTEX_SELECT);
else
UI_ThemeColor(TH_TEXT_HI);
@@ -946,9 +954,9 @@ static void draw_selected_name(Scene *scene, Object *ob)
}
if (U.uiflag & USER_SHOW_ROTVIEWICON)
- offset = 14 + (U.rvisize * 2);
+ offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
- BLF_draw_default(offset, 10, 0.0f, info, sizeof(info));
+ BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
@@ -1289,7 +1297,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
RegionView3D *rv3d = ar->regiondata;
struct Base *base = scene->basact;
int multisample_enabled;
- rcti winrct;
BLI_assert(ar->regiontype == RGN_TYPE_WINDOW);
@@ -1338,8 +1345,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if (multisample_enabled)
glDisable(GL_MULTISAMPLE_ARB);
- region_scissor_winrct(ar, &winrct);
- glScissor(winrct.xmin, winrct.ymin, BLI_rcti_size_x(&winrct), BLI_rcti_size_y(&winrct));
+ glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
glClearColor(0.0, 0.0, 0.0, 0.0);
if (v3d->zbuf) {
@@ -2165,7 +2171,9 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
v3d->zbuf = TRUE;
glEnable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, 1);
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ draw_gpencil_view3d(scene, v3d, ar, TRUE);
+ }
v3d->zbuf = zbuf;
@@ -2307,7 +2315,7 @@ typedef struct View3DShadow {
} View3DShadow;
static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par,
- float obmat[][4], ListBase *shadows)
+ float obmat[4][4], ListBase *shadows)
{
GPULamp *lamp;
Lamp *la = (Lamp *)ob->data;
@@ -2385,7 +2393,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE);
+ ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;
@@ -2466,7 +2474,7 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
return mask;
}
-void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4])
+void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
@@ -2509,7 +2517,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
}
}
-static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4])
+static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
@@ -2532,13 +2540,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
/* ED_view3d_draw_offscreen_init should be called before this to initialize
* stuff like shadow buffers
*/
-void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
- int winx, int winy, float viewmat[][4], float winmat[][4],
- int do_bgpic, int colormanage_background)
+void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
+ float viewmat[4][4], float winmat[4][4], int do_bgpic)
{
RegionView3D *rv3d = ar->regiondata;
Base *base;
- float backcol[3];
int bwinx, bwiny;
rcti brect;
@@ -2566,34 +2572,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
* warning! can be slow so only free animated images - campbell */
GPU_free_images_anim();
- /* set background color, fallback on the view background color
- * (if active clip is set but frame is failed to load fallback to horizon color as background) */
- if (scene->world) {
- /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not
- * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc)
- * but due to compatibility issues background is being affected display transform, so we can
- * emulate behavior of disabled color management
- * but this function is also used for sequencer's scene strips which shouldn't be affected by
- * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background
- * we can drop this flag in cost of some compatibility loss -- background wouldn't be
- * color managed in 3d viewport
- * same goes to opengl rendering, where color profile should be applied as very final step
- */
-
- if (colormanage_background) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
- }
- else {
- linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr);
- }
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0);
- }
- else {
- UI_ThemeClearColor(TH_BACK);
- }
-
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -2645,9 +2624,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
}
/* must be before xray draw which clears the depth buffer */
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, 1);
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ draw_gpencil_view3d(scene, v3d, ar, TRUE);
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
/* transp and X-ray afterdraw stuff */
if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
@@ -2671,8 +2652,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
/* draw grease-pencil stuff */
ED_region_pixelspace(ar);
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- draw_gpencil_view3d(scene, v3d, ar, 0);
+
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ draw_gpencil_view3d(scene, v3d, ar, FALSE);
+ }
/* freeing the images again here could be done after the operator runs, leaving for now */
GPU_free_images_anim();
@@ -2690,10 +2674,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
G.f &= ~G_RENDER_OGL;
}
+/* get a color used for offscreen sky, returns color in sRGB space */
+void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3])
+{
+ if (scene->world)
+ linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr);
+ else
+ UI_GetThemeColor3fv(TH_BACK, sky_color);
+}
+
+static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene)
+{
+ float sky_color[3];
+
+ ED_view3d_offscreen_sky_color_get(scene, sky_color);
+
+ if (ibuf->rect_float)
+ IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color);
+ else
+ IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color);
+}
+
/* utility func for ED_view3d_draw_offscreen */
-ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
- int sizex, int sizey, unsigned int flag, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
+ int draw_background, int alpha_mode, char err_out[256])
{
RegionView3D *rv3d = ar->regiondata;
ImBuf *ibuf;
@@ -2720,10 +2724,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(¶ms);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background);
}
else {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background);
+ ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background);
}
/* read in pixels & stamp */
@@ -2734,6 +2738,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
else if (ibuf->rect)
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ if (alpha_mode == R_ADDSKY)
+ offscreen_imbuf_add_sky(ibuf, scene);
+
/* unbind */
GPU_offscreen_unbind(ofs);
GPU_offscreen_free(ofs);
@@ -2747,9 +2754,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar,
}
/* creates own 3d views, used by the sequencer */
-ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height,
- unsigned int flag, int drawtype, int draw_background,
- int colormanage_background, char err_out[256])
+ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype,
+ int use_solid_tex, int draw_background, int alpha_mode, char err_out[256])
{
View3D v3d = {NULL};
ARegion ar = {NULL};
@@ -2765,6 +2771,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
v3d.drawtype = drawtype;
v3d.flag2 = V3D_RENDER_OVERRIDE;
+ if (use_solid_tex)
+ v3d.flag2 |= V3D_SOLID_TEX;
+
rv3d.persp = RV3D_CAMOB;
copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
@@ -2789,7 +2798,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag,
- draw_background, colormanage_background, err_out);
+ draw_background, alpha_mode, err_out);
// seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty);
}
@@ -2798,7 +2807,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
/* NOTE: the info that this uses is updated in ED_refresh_viewport_fps(),
* which currently gets called during SCREEN_OT_animation_step.
*/
-static void draw_viewport_fps(Scene *scene, ARegion *ar)
+static void draw_viewport_fps(Scene *scene, rcti *rect)
{
ScreenFrameRateInfo *fpsi = scene->fps_info;
float fps;
@@ -2843,7 +2852,7 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar)
BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps + 0.5f));
}
- BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable));
+ BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
}
static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit);
@@ -2958,6 +2967,169 @@ static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar)
ED_region_info_draw(ar, rv3d->render_engine->text, 1, 0.25);
}
+/*
+ * Function to clear the view
+ */
+static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ /* clear background */
+ if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */
+ if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
+ int x, y;
+ float col_hor[3];
+ float col_zen[3];
+
+#define VIEWGRAD_RES_X 16
+#define VIEWGRAD_RES_Y 16
+
+ GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
+ static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2];
+ static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
+ static char buf_calculated = FALSE;
+
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* calculate buffers the first time only */
+ if (!buf_calculated) {
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+
+ /* -1..1 range */
+ grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
+ grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
+ }
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X - 1; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) {
+ indices[x][y][0] = x * VIEWGRAD_RES_X + y;
+ indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y;
+ }
+ }
+
+ buf_calculated = TRUE;
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+ const float mval[2] = {xf * (float)ar->winx, yf * ar->winy};
+ const float z_up[3] = {0.0f, 0.0f, 1.0f};
+ float out[3];
+ GLubyte *col_ub = grid_col[x][y];
+
+ float col_fac;
+ float col_fl[3];
+
+ ED_view3d_win_to_vector(ar, mval, out);
+
+ if (scene->world->skytype & WO_SKYPAPER) {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = (float)y / (float)VIEWGRAD_RES_Y;
+ }
+ }
+ else {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI);
+ }
+ }
+
+ interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac);
+
+ rgb_float_to_uchar(col_ub, col_fl);
+ col_ub[3] = 0;
+ }
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, grid_pos);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
+
+ glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glShadeModel(GL_FLAT);
+
+#undef VIEWGRAD_RES_X
+#undef VIEWGRAD_RES_Y
+ }
+ else { /* solid sky */
+ float col_hor[3];
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+ else {
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ /* only clear depth buffer here */
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ UI_ThemeColor(TH_LOW_GRAD);
+ glVertex2f(-1.0, -1.0);
+ glVertex2f(1.0, -1.0);
+ UI_ThemeColor(TH_HIGH_GRAD);
+ glVertex2f(1.0, 1.0);
+ glVertex2f(-1.0, 1.0);
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+ else {
+ UI_ThemeClearColor(TH_HIGH_GRAD);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+}
+
/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */
static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit)
{
@@ -2965,7 +3137,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Base *base;
- float backcol[3];
unsigned int lay_used;
/* shadow buffers, before we setup matrices */
@@ -2978,21 +3149,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
GPU_default_lights();
}
- /* clear background */
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) && scene->world) {
- IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
-
- glClearColor(backcol[0], backcol[1], backcol[2], 0.0);
- }
- else
- UI_ThemeClearColor(TH_BACK);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
/* setup view matrices */
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
+ /* clear the background */
+ view3d_main_area_clear(scene, v3d, ar);
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
if (rv3d->rflag & RV3D_CLIPPING)
@@ -3102,10 +3264,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
// REEB_draw();
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
/* must be before xray draw which clears the depth buffer */
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
- draw_gpencil_view3d(scene, v3d, ar, 1);
+ draw_gpencil_view3d(scene, v3d, ar, TRUE);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
@@ -3152,6 +3314,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ rcti rect;
+
+ /* local coordinate visible rect inside region, to accomodate overlapping ui */
+ ED_region_visible_rect(ar, &rect);
if (rv3d->persp == RV3D_CAMOB) {
drawviewborder(scene, ar, v3d);
@@ -3168,23 +3334,24 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
+ if (v3d->flag2 & V3D_SHOW_GPENCIL) {
+ /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
+ draw_gpencil_view3d(scene, v3d, ar, FALSE);
+ }
+
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
Object *ob;
- /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
- // if (v3d->flag2 & V3D_DISPGP)
- draw_gpencil_view3d(scene, v3d, ar, 0);
-
drawcursor(scene, ar, v3d);
if (U.uiflag & USER_SHOW_ROTVIEWICON)
- draw_view_axis(rv3d);
+ draw_view_axis(rv3d, &rect);
else
- draw_view_icon(rv3d);
+ draw_view_icon(rv3d, &rect);
ob = OBACT;
if (U.uiflag & USER_DRAWVIEWINFO)
- draw_selected_name(scene, ob);
+ draw_selected_name(scene, ob, &rect);
}
if (rv3d->render_engine) {
@@ -3194,10 +3361,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
- draw_viewport_fps(scene, ar);
+ draw_viewport_fps(scene, &rect);
}
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
- draw_viewport_name(ar, v3d);
+ draw_viewport_name(ar, v3d, &rect);
}
if (grid_unit) { /* draw below the viewport name */
@@ -3208,7 +3375,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid);
}
- BLF_draw_default_ascii(22, ar->winy - (USER_SHOW_VIEWPORTNAME ? 40 : 20), 0.0f,
+ BLF_draw_default_ascii(rect.xmin + U.widget_unit,
+ rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f,
numstr[0] ? numstr : grid_unit, sizeof(numstr));
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 17e6558..a1e132c 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -96,7 +96,8 @@ int ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d)
void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d)
{
if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs);
+ /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */
+ rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
}
@@ -908,7 +909,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* changed since 2.4x, use the camera view */
if (vod->v3d->camera) {
- rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs);
+ rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
}
@@ -920,7 +921,8 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
if (event->type == MOUSEPAN) {
- viewrotate_apply(vod, event->prevx, event->prevy);
+ /* invert it, trackpad scroll then follows how you mapped it globally */
+ viewrotate_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
ED_view3d_depth_tag_update(rv3d);
viewops_data_free(C, op);
@@ -1007,17 +1009,20 @@ void ndof_to_quat(struct wmNDOFMotionData *ndof, float q[4])
*/
static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- ViewOpsData *vod = op->customdata;
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
else {
View3D *v3d = CTX_wm_view3d(C);
+ ViewOpsData *vod;
RegionView3D *rv3d = CTX_wm_region_view3d(C);
wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
ED_view3d_camera_lock_init(v3d, rv3d);
+ viewops_data_create(C, op, event);
+ vod = op->customdata;
+
rv3d->rot_angle = 0.f; /* off by default, until changed later this function */
if (ndof->progress != P_FINISHING) {
@@ -1137,8 +1142,10 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
+ viewops_data_free(C, op);
+
ED_view3d_camera_lock_sync(v3d, rv3d);
-
+
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
@@ -1160,6 +1167,181 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
ot->flag = 0;
}
+
+static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+
+ if (event->type != NDOF_MOTION)
+ return OPERATOR_CANCELLED;
+ else {
+ ViewOpsData *vod;
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+
+ ED_view3d_camera_lock_init(v3d, rv3d);
+
+ rv3d->rot_angle = 0.f; /* off by default, until changed later this function */
+
+ viewops_data_create(C, op, event);
+ vod = op->customdata;
+
+ if (ndof->progress != P_FINISHING) {
+ const float dt = ndof->dt;
+
+ /* tune these until everything feels right */
+ const float rot_sensitivity = 1.f;
+
+ const float zoom_sensitivity = 1.f;
+
+ const float pan_sensitivity = 1.f;
+ const int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
+
+ float view_inv[4];
+ invert_qt_qt(view_inv, rv3d->viewquat);
+
+ /* #define DEBUG_NDOF_MOTION */
+ #ifdef DEBUG_NDOF_MOTION
+ printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
+ ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
+ #endif
+
+ if (ndof->tz) {
+ /* Zoom!
+ * velocity should be proportional to the linear velocity attained by rotational motion of same strength
+ * [got that?]
+ * proportional to arclength = radius * angle
+ */
+ float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+
+ if (U.ndof_flag & NDOF_ZOOM_INVERT)
+ zoom_distance = -zoom_distance;
+
+ rv3d->dist += zoom_distance;
+ }
+
+ if (rv3d->viewlock == RV3D_LOCKED) {
+ /* rotation not allowed -- explore panning options instead */
+ float pan_vec[3] = {ndof->tx, ndof->ty, 0.0f};
+ mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+
+ /* transform motion from view to world coordinates */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
+
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
+ }
+
+ if (has_rotation) {
+
+ rv3d->view = RV3D_VIEW_USER;
+
+ if (U.ndof_flag & NDOF_TURNTABLE) {
+
+ /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+ float angle, rot[4];
+ float xvec[3] = {1, 0, 0};
+
+ /* Determine the direction of the x vector (for rotating up and down) */
+ mul_qt_v3(view_inv, xvec);
+
+ /* Perform the up/down rotation */
+ angle = rot_sensitivity * dt * ndof->rx;
+ if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
+ angle = -angle;
+ rot[0] = cos(angle);
+ mul_v3_v3fl(rot + 1, xvec, sin(angle));
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ /* Perform the orbital rotation */
+ angle = rot_sensitivity * dt * ndof->ry;
+ if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
+ angle = -angle;
+
+ /* update the onscreen doo-dad */
+ rv3d->rot_angle = angle;
+ rv3d->rot_axis[0] = 0;
+ rv3d->rot_axis[1] = 0;
+ rv3d->rot_axis[2] = 1;
+
+ rot[0] = cos(angle);
+ rot[1] = rot[2] = 0.0;
+ rot[3] = sin(angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ }
+ else {
+ float rot[4];
+ float axis[3];
+ float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
+
+ if (U.ndof_flag & NDOF_ROLL_INVERT_AXIS)
+ axis[2] = -axis[2];
+
+ if (U.ndof_flag & NDOF_TILT_INVERT_AXIS)
+ axis[0] = -axis[0];
+
+ if (U.ndof_flag & NDOF_ROTATE_INVERT_AXIS)
+ axis[1] = -axis[1];
+
+
+ /* transform rotation axis from view to world coordinates */
+ mul_qt_v3(view_inv, axis);
+
+ /* update the onscreen doo-dad */
+ rv3d->rot_angle = angle;
+ copy_v3_v3(rv3d->rot_axis, axis);
+
+ axis_angle_to_quat(rot, axis, angle);
+
+ /* apply rotation */
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ }
+
+ /* rotate around custom center */
+ if (vod && vod->use_dyn_ofs) {
+ float q1[4];
+
+ /* compute the post multiplication quat, to rotate the offset correctly */
+ conjugate_qt_qt(q1, vod->oldquat);
+ mul_qt_qtqt(q1, q1, rv3d->viewquat);
+
+ conjugate_qt(q1); /* conj == inv for unit quat */
+ copy_v3_v3(rv3d->ofs, vod->ofs);
+ sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
+ mul_qt_v3(q1, rv3d->ofs);
+ add_v3_v3(rv3d->ofs, vod->dyn_ofs);
+ }
+ }
+ }
+
+ viewops_data_free(C, op);
+
+ ED_view3d_camera_lock_sync(v3d, rv3d);
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+ }
+}
+
+void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "NDOF Orbit View with zoom";
+ ot->description = "Explore every angle of an object using the 3D mouse";
+ ot->idname = "VIEW3D_OT_ndof_orbit_zoom";
+
+ /* api callbacks */
+ ot->invoke = ndof_orbit_zoom_invoke;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = 0;
+}
+
/* -- "pan" navigation
* -- zoom or dolly?
*/
@@ -1196,8 +1378,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
#else /* ------------------------------------------------------- dolly with Z */
- float speed = 10.f; /* blender units per second */
- /* ^^ this is ok for default cube scene, but should scale with.. something */
+ float speed = rv3d->dist; /* uses distance from pivot to define dolly */
/* tune these until everything feels right */
const float forward_sensitivity = 1.f;
@@ -1260,8 +1441,9 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
*/
static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- if (event->type != NDOF_MOTION)
+ if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
+ }
else {
ViewOpsData *vod;
@@ -1281,23 +1463,14 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
const float dt = ndof->dt;
float view_inv[4];
- float speed = 10.f; /* blender units per second */
- /* ^^ this is ok for default cube scene, but should scale with.. something */
+ float speed = rv3d->dist; /* uses distance from pivot to define dolly */
/* tune these until everything feels right */
const float forward_sensitivity = 1.f;
const float vertical_sensitivity = 0.4f;
const float lateral_sensitivity = 0.6f;
-
float pan_vec[3];
const float rot_sensitivity = 1.f;
-#if 0
- const float zoom_sensitivity = 1.f;
- const float pan_sensitivity = 1.f;
- float rot[4];
- float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
- float axis[3];
-#endif
/* inverse view */
invert_qt_qt(view_inv, rv3d->viewquat);
@@ -1388,7 +1561,7 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* rotate around custom center */
- if (vod && vod->use_dyn_ofs) {
+ if (vod->use_dyn_ofs) {
float q1[4];
/* compute the post multiplication quat, to rotate the offset correctly */
@@ -1403,10 +1576,13 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
+
+ viewops_data_free(C, op);
+
ED_view3d_camera_lock_sync(v3d, rv3d);
ED_region_tag_redraw(CTX_wm_region(C));
- viewops_data_free(C, op);
+
return OPERATOR_FINISHED;
}
}
@@ -1550,7 +1726,8 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
vod = op->customdata;
if (event->type == MOUSEPAN) {
- viewmove_apply(vod, event->prevx, event->prevy);
+ /* invert it, trackpad scroll follows same principle as 2d windows this way */
+ viewmove_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -1923,17 +2100,16 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
viewzoom_exec(C, op);
}
else {
- if (event->type == MOUSEZOOM) {
- /* Bypass Zoom invert flag for track pads (pass FALSE always) */
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->origx = vod->oldx = event->x;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
ED_view3d_depth_tag_update(vod->rv3d);
@@ -2231,7 +2407,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
float new_dist;
sub_v3_v3v3(afm, max, min);
- size = MAX3(afm[0], afm[1], afm[2]);
+ size = max_fff(afm[0], afm[1], afm[2]);
if (ok_dist) {
/* fix up zoom distance if needed */
@@ -3589,7 +3765,7 @@ static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb)
}
}
-static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float mat[][4])
+static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
{
BoundBox clipbb_local;
float imat[4][4];
@@ -3604,7 +3780,7 @@ static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float m
calc_clipping_plane(clip_local, &clipbb_local);
}
-void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[][4])
+void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
{
if (rv3d->rflag & RV3D_CLIPPING)
calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
@@ -3675,18 +3851,21 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* ***************** 3d cursor cursor op ******************* */
-/* mx my in region coords */
-static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+/* cursor position in vec, result in vec, mval in region coords */
+/* note: cannot use event->mval here (called by object_add() */
+void ED_view3d_cursor3d_position(bContext *C, float *fp, int mx, int my)
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- float *fp = NULL;
float mval_fl[2];
+ int mval[2];
int flip;
- fp = give_cursor(scene, v3d);
+ mval[0] = mx - ar->winrct.xmin;
+ mval[1] = my - ar->winrct.ymin;
+
flip = initgrabz(rv3d, fp[0], fp[1], fp[2]);
/* reset the depth based on the view offset (we _know_ the offset is infront of us) */
@@ -3701,20 +3880,20 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, event->mval, fp))
+ if (ED_view3d_autodist(scene, ar, v3d, mval, fp))
depth_used = TRUE;
}
if (depth_used == FALSE) {
float dvec[3];
- VECSUB2D(mval_fl, mval_fl, event->mval);
+ VECSUB2D(mval_fl, mval_fl, mval);
ED_view3d_win_to_delta(ar, mval_fl, dvec);
sub_v3_v3(fp, dvec);
}
}
else {
- const float dx = ((float)(event->mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2);
- const float dy = ((float)(event->mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2);
+ const float dx = ((float)(mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2);
+ const float dy = ((float)(mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2);
const float fz = (rv3d->persmat[0][3] * fp[0] +
rv3d->persmat[1][3] * fp[1] +
rv3d->persmat[2][3] * fp[2] +
@@ -3725,11 +3904,21 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *
fp[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy + rv3d->persinv[2][2] * fz) - rv3d->ofs[2];
}
+}
+
+static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float *fp = give_cursor(scene, v3d);
+
+ ED_view3d_cursor3d_position(C, fp, event->x, event->y);
+
if (v3d && v3d->localvd)
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
else
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -3990,16 +4179,28 @@ int ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int m
return (*depth == FLT_MAX) ? 0 : 1;
}
-float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) {
+/* problem - ofs[3] can be on same location as camera itself.
+ * Blender needs proper dist value for zoom.
+ * use fallback_dist to override small values
+ */
+float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
+{
float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
-
+ float dist;
+
mul_m4_v4(mat, pos);
add_v3_v3(pos, ofs);
mul_m4_v4(mat, dir);
normalize_v3(dir);
- return dot_v3v3(pos, dir);
+ dist = dot_v3v3(pos, dir);
+
+ if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) {
+ dist = fallback_dist;
+ }
+
+ return dist;
}
/**
@@ -4010,7 +4211,7 @@ float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) {
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist)
+void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
{
/* Offset */
if (ofs)
@@ -4047,7 +4248,7 @@ void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist)
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist)
+void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
{
float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
float dvec[3] = {0.0f, 0.0f, dist};
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index cddfae5..c2e75a1 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -76,7 +76,8 @@ enum {
FLY_MODAL_PRECISION_ENABLE,
FLY_MODAL_PRECISION_DISABLE,
FLY_MODAL_FREELOOK_ENABLE,
- FLY_MODAL_FREELOOK_DISABLE
+ FLY_MODAL_FREELOOK_DISABLE,
+ FLY_MODAL_SPEED, /* mousepan typically */
};
@@ -132,6 +133,8 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED);
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
/* XXX - Bug in the event system, middle mouse release doesnt work */
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE);
@@ -544,7 +547,22 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
case FLY_MODAL_CONFIRM:
fly->state = FLY_CONFIRM;
break;
-
+
+ /* speed adjusting with mousepan (trackpad) */
+ case FLY_MODAL_SPEED:
+ {
+ float fac = 0.02f * (event->prevy - event->y);
+
+ /* allowing to brake immediate */
+ if (fac > 0.0f && fly->speed < 0.0f)
+ fly->speed = 0.0f;
+ else if (fac < 0.0f && fly->speed > 0.0f)
+ fly->speed = 0.0f;
+ else
+ fly->speed += fly->grid * fac;
+
+ break;
+ }
case FLY_MODAL_ACCELERATE:
{
double time_currwheel;
@@ -816,7 +834,7 @@ static int flyApply(bContext *C, FlyInfo *fly)
/* scale the mouse movement by this value - scales mouse movement to the view size
- * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y)
+ * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y)
*
* the mouse moves isn't linear */
@@ -1041,8 +1059,8 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly)
const int flag = U.ndof_flag;
#if 0
- int shouldRotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == FALSE),
- shouldTranslate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM));
+ int shouldRotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == FALSE);
+ int shouldTranslate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM));
#endif
int shouldRotate = (fly->pan_view == FALSE);
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 79bf003..2b30e4e 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -487,11 +487,17 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
block = uiLayoutGetBlock(row);
if (v3d->twflag & V3D_USE_MANIPULATOR) {
- but = uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Translate manipulator - Shift-Click for multiple modes"));
+ but = uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0,
+ TIP_("Translate manipulator - Shift-Click for multiple modes"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Rotate manipulator - Shift-Click for multiple modes"));
+ but = uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0,
+ TIP_("Rotate manipulator - Shift-Click for multiple modes"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Scale manipulator - Shift-Click for multiple modes"));
+ but = uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0,
+ TIP_("Scale manipulator - Shift-Click for multiple modes"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
}
@@ -500,7 +506,8 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
str_menu = BIF_menustringTransformOrientation(C, "Orientation");
- but = uiDefButC(block, MENU, B_MAN_MODE, str_menu, 0, 0, 70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, TIP_("Transform Orientation"));
+ but = uiDefButC(block, MENU, B_MAN_MODE, str_menu, 0, 0, 70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0,
+ TIP_("Transform Orientation"));
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
MEM_freeN((void *)str_menu);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 5beeda9..a6daf61 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -77,6 +77,7 @@ void VIEW3D_OT_zoom_camera_1_to_1(struct wmOperatorType *ot);
void VIEW3D_OT_move(struct wmOperatorType *ot);
void VIEW3D_OT_rotate(struct wmOperatorType *ot);
void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot);
+void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot);
void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot);
void VIEW3D_OT_ndof_all(struct wmOperatorType *ot);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
@@ -125,7 +126,7 @@ void drawaxes(float size, char drawtype);
void view3d_cached_text_draw_begin(void);
void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]);
-void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[][4]);
+void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[4][4]);
enum {
V3D_CACHE_TEXT_ZBUF = (1 << 0),
@@ -172,7 +173,7 @@ void VIEW3D_OT_localview(struct wmOperatorType *ot);
void VIEW3D_OT_game_start(struct wmOperatorType *ot);
-int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[][4], struct BoundBox *bb);
+int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[4][4], struct BoundBox *bb);
void view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *,
float *ofs, float *quat, float *dist, float *lens);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 3760772..81e890c 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -27,6 +27,7 @@
#include "DNA_curve_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meta_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
@@ -47,6 +48,12 @@
#include "ED_object.h"
#include "ED_view3d.h"
+typedef struct foreachScreenObjectVert_userData {
+ void (*func)(void *userData, MVert *mv, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
+} foreachScreenObjectVert_userData;
typedef struct foreachScreenVert_userData {
void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index);
@@ -79,6 +86,46 @@ typedef struct foreachScreenFace_userData {
/* ------------------------------------------------------------------------ */
+
+static void meshobject_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ foreachScreenObjectVert_userData *data = userData;
+ struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index];
+
+ if (!(mv->flag & ME_HIDE)) {
+ float screen_co[2];
+
+ if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) {
+ return;
+ }
+
+ data->func(data->userData, mv, screen_co, index);
+ }
+}
+
+void meshobject_foreachScreenVert(
+ ViewContext *vc,
+ void (*func)(void *userData, MVert *eve, const float screen_co[2], int index),
+ void *userData, eV3DProjTest clip_flag)
+{
+ foreachScreenObjectVert_userData data;
+ DerivedMesh *dm = mesh_get_derived_deform(vc->scene, vc->obact, CD_MASK_BAREMESH);
+
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
+
+ dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data);
+
+ dm->release(dm);
+}
+
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -113,9 +160,8 @@ void mesh_foreachScreenVert(
ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
}
- EDBM_index_arrays_init(vc->em, 1, 0, 0);
+ EDBM_index_arrays_ensure(vc->em, BM_VERT);
dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
dm->release(dm);
}
@@ -172,9 +218,8 @@ void mesh_foreachScreenEdge(
ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
}
- EDBM_index_arrays_init(vc->em, 0, 1, 0);
+ EDBM_index_arrays_ensure(vc->em, BM_EDGE);
dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
dm->release(dm);
}
@@ -209,9 +254,8 @@ void mesh_foreachScreenFace(
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- EDBM_index_arrays_init(vc->em, 0, 0, 1);
+ EDBM_index_arrays_ensure(vc->em, BM_FACE);
dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
dm->release(dm);
}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index b0f7b4f..615ae71 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -39,6 +39,10 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_main.h"
+
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -48,10 +52,75 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_screen.h"
#include "ED_transform.h"
#include "view3d_intern.h"
+/* ************************** copy paste ***************************** */
+
+static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
+{
+ char str[FILE_MAX];
+
+ BKE_copybuffer_begin();
+
+ /* context, selection, could be generalized */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ BKE_copybuffer_tag_ID(&ob->id);
+
+ }
+ CTX_DATA_END;
+
+ BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend");
+ BKE_copybuffer_save(str, op->reports);
+
+ return OPERATOR_FINISHED;
+}
+
+static void VIEW3D_OT_copybuffer(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name = "Copy Selection to Buffer";
+ ot->idname = "VIEW3D_OT_copybuffer";
+ ot->description = "Selected objects are saved in a temp file";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = view3d_copybuffer_exec;
+ ot->poll = ED_operator_view3d_active;
+}
+
+static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
+{
+ char str[FILE_MAX];
+
+ BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend");
+ BKE_copybuffer_paste(C, str, op->reports);
+
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name = "Paste Selection from Buffer";
+ ot->idname = "VIEW3D_OT_pastebuffer";
+ ot->description = "Contents of copy buffer gets pasted";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = view3d_pastebuffer_exec;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
/* ************************** registration **********************************/
@@ -62,6 +131,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1);
WM_operatortype_append(VIEW3D_OT_dolly);
+ WM_operatortype_append(VIEW3D_OT_ndof_orbit_zoom);
WM_operatortype_append(VIEW3D_OT_ndof_orbit);
WM_operatortype_append(VIEW3D_OT_ndof_pan);
WM_operatortype_append(VIEW3D_OT_ndof_all);
@@ -97,6 +167,8 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_game_start);
WM_operatortype_append(VIEW3D_OT_fly);
WM_operatortype_append(VIEW3D_OT_layers);
+ WM_operatortype_append(VIEW3D_OT_copybuffer);
+ WM_operatortype_append(VIEW3D_OT_pastebuffer);
WM_operatortype_append(VIEW3D_OT_properties);
WM_operatortype_append(VIEW3D_OT_toolshelf);
@@ -117,13 +189,13 @@ void view3d_keymap(wmKeyConfig *keyconf)
wmKeyMapItem *kmi;
keymap = WM_keymap_find(keyconf, "3D View Generic", SPACE_VIEW3D, 0);
-
+
WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
-
+
kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
/*
@@ -149,10 +221,11 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
/*numpad +/-*/
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
@@ -228,11 +301,16 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+
+ WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
+ /* NDOF: begin */
+ /* note: positioned here so keymaps show keyboard keys if assigned */
/* 3D mouse */
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit_zoom", NDOF_MOTION, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
@@ -240,7 +318,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
-
+
/* 3D mouse align */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
@@ -251,9 +329,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
-
- WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
+ /* NDOF: end */
+
/* layers, shift + alt are properties set in invoke() */
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ACCENTGRAVEKEY, KM_PRESS, 0, 0)->ptr, "nr", 0);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_layers", ONEKEY, KM_PRESS, KM_ANY, 0)->ptr, "nr", 1);
@@ -361,6 +439,13 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
+#ifdef __APPLE__
+ WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_OSKEY, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_OSKEY, 0);
+#endif
+ WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_CTRL, 0);
+
/* context ops */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 34b983f..c428cb0 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -110,13 +110,13 @@ eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
/* perspmat is typically...
* - 'rv3d->perspmat', is_local == FALSE
- * - 'rv3d->perspmatob', is_local == TRUE
+ * - 'rv3d->persmatob', is_local == TRUE
*/
static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
float perspmat[4][4], const int is_local, /* normally hidden */
const float co[3], float r_co[2], const eV3DProjTest flag)
{
- float fx, fy, vec4[4];
+ float vec4[4];
/* check for bad flags */
BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag);
@@ -134,13 +134,19 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
vec4[3] = 1.0;
mul_m4_v4(perspmat, vec4);
- if (vec4[3] > (float)BL_NEAR_CLIP) {
- fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]);
- if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) {
- fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]);
+ if (((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) || (vec4[3] > (float)BL_NEAR_CLIP)) {
+ const float scalar = (vec4[3] != 0.0f) ? (1.0f / vec4[3]): 0.0f;
+ const float fx = ((float)ar->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
+ if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0.0f && fx < (float)ar->winx)) {
+ const float fy = ((float)ar->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
- r_co[0] = (short)floor(fx);
- r_co[1] = (short)floor(fy);
+ r_co[0] = floorf(fx);
+ r_co[1] = floorf(fy);
+
+ /* check if the point is behind the view, we need to flip in this case */
+ if (UNLIKELY((flag & V3D_PROJ_TEST_CLIP_NEAR) == 0) && (vec4[3] < 0.0f)) {
+ negate_v2(r_co);
+ }
}
else {
return V3D_PROJ_RET_CLIP_WIN;
@@ -166,8 +172,8 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con
if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) &&
(tvec[1] > -32700.0f && tvec[1] < 32700.0f))
{
- r_co[0] = (short)floor(tvec[0]);
- r_co[1] = (short)floor(tvec[1]);
+ r_co[0] = (short)floorf(tvec[0]);
+ r_co[1] = (short)floorf(tvec[1]);
}
else {
ret = V3D_PROJ_RET_OVERFLOW;
@@ -185,8 +191,8 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const
if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) &&
(tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f))
{
- r_co[0] = (int)floor(tvec[0]);
- r_co[1] = (int)floor(tvec[1]);
+ r_co[0] = (int)floorf(tvec[0]);
+ r_co[1] = (int)floorf(tvec[1]);
}
else {
ret = V3D_PROJ_RET_OVERFLOW;
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index cffa53b..dac887f 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -70,6 +70,7 @@
#include "BKE_paint.h"
#include "BKE_tessmesh.h"
#include "BKE_tracking.h"
+#include "BKE_utildefines.h"
#include "BIF_gl.h"
@@ -541,11 +542,11 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -741,67 +742,19 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m
mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
-static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
{
- Mesh *me;
- MVert *mvert;
- struct ImBuf *ibuf;
- unsigned int *rt;
- int a, index;
- char *selar;
- int sx = BLI_rcti_size_x(rect) + 1;
- int sy = BLI_rcti_size_y(rect) + 1;
-
- me = vc->obact->data;
-
- if (me == NULL || me->totvert == 0 || sx * sy <= 0)
- return OPERATOR_CANCELLED;
-
- selar = MEM_callocN(me->totvert + 1, "selar");
-
- if (extend == 0 && select)
- paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE);
-
- view3d_validate_backbuf(vc);
-
- ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
- rt = ibuf->rect;
- glReadPixels(rect->xmin + vc->ar->winrct.xmin, rect->ymin + vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
-
- a = sx * sy;
- while (a--) {
- if (*rt) {
- index = WM_framebuffer_to_index(*rt);
- if (index <= me->totvert) selar[index] = 1;
- }
- rt++;
- }
+ LassoSelectUserData *data = userData;
- mvert = me->mvert;
- for (a = 1; a <= me->totvert; a++, mvert++) {
- if (selar[a]) {
- if ((mvert->flag & ME_HIDE) == 0) {
- if (select) mvert->flag |= SELECT;
- else mvert->flag &= ~SELECT;
- }
- }
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED))
+ {
+ BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
}
-
- IMB_freeImBuf(ibuf);
- MEM_freeN(selar);
-
-#ifdef __APPLE__
- glReadBuffer(GL_BACK);
-#endif
-
- paintvert_flush_flags(vc->obact);
-
- return OPERATOR_FINISHED;
}
-
static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, short extend, short select)
{
+ const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
Object *ob = vc->obact;
Mesh *me = ob ? ob->data : NULL;
rcti rect;
@@ -811,14 +764,31 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
if (extend == 0 && select)
paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
- bm_vertoffs = me->totvert + 1; /* max index array */
BLI_lasso_boundbox(&rect, mcords, moves);
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- edbm_backbuf_check_and_select_verts_obmode(me, select);
+ if (use_zbuf) {
+ bm_vertoffs = me->totvert + 1; /* max index array */
- EDBM_backbuf_free();
+ EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+
+ edbm_backbuf_check_and_select_verts_obmode(me, select);
+
+ EDBM_backbuf_free();
+ }
+ else {
+ LassoSelectUserData data;
+ rcti rect;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
+
+ meshobject_foreachScreenVert(vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+ }
paintvert_flush_flags(ob);
}
@@ -1217,31 +1187,42 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int
}
}
+static int selectbuffer_has_bones(const unsigned int *buffer, const unsigned int hits)
+{
+ unsigned int i;
+ for (i = 0; i < hits; i++) {
+ if (buffer[(4 * i) + 3] & 0xFFFF0000) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2])
{
rcti rect;
int offs;
- short a, hits15, hits9 = 0, hits5 = 0;
- short has_bones15 = 0, has_bones9 = 0, has_bones5 = 0;
+ short hits15, hits9 = 0, hits5 = 0;
+ short has_bones15 = FALSE, has_bones9 = FALSE, has_bones5 = FALSE;
BLI_rcti_init(&rect, mval[0] - 14, mval[0] + 14, mval[1] - 14, mval[1] + 14);
hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
if (hits15 > 0) {
- for (a = 0; a < hits15; a++) if (buffer[4 * a + 3] & 0xFFFF0000) has_bones15 = 1;
+ has_bones15 = selectbuffer_has_bones(buffer, hits15);
offs = 4 * hits15;
BLI_rcti_init(&rect, mval[0] - 9, mval[0] + 9, mval[1] - 9, mval[1] + 9);
hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
if (hits9 > 0) {
- for (a = 0; a < hits9; a++) if (buffer[offs + 4 * a + 3] & 0xFFFF0000) has_bones9 = 1;
+ has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
offs += 4 * hits9;
BLI_rcti_init(&rect, mval[0] - 5, mval[0] + 5, mval[1] - 5, mval[1] + 5);
hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
if (hits5 > 0) {
- for (a = 0; a < hits5; a++) if (buffer[offs + 4 * a + 3] & 0xFFFF0000) has_bones5 = 1;
+ has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
}
}
@@ -1383,10 +1364,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
hits = mixed_bones_object_selectbuffer(&vc, buffer, mval);
if (hits > 0) {
- int a, has_bones = 0;
-
- for (a = 0; a < hits; a++) if (buffer[4 * a + 3] & 0xFFFF0000) has_bones = 1;
-
+ const int has_bones = selectbuffer_has_bones(buffer, hits);
basact = mouse_select_eval_buffer(&vc, buffer, hits, mval, vc.scene->base.first, has_bones);
}
@@ -1420,7 +1398,6 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL;
- int a;
float dist = 100.0f;
int retval = 0;
short hits;
@@ -1448,7 +1425,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
if (BASE_SELECTABLE(v3d, base)) {
float screen_co[2];
if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
if (base == BASACT) dist_temp += 10.0f;
@@ -1473,10 +1450,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
hits = mixed_bones_object_selectbuffer(&vc, buffer, mval);
if (hits > 0) {
- int has_bones = 0;
-
/* note: bundles are handling in the same way as bones */
- for (a = 0; a < hits; a++) if (buffer[4 * a + 3] & 0xFFFF0000) has_bones = 1;
+ const int has_bones = selectbuffer_has_bones(buffer, hits);
/* note; shift+alt goes to group-flush-selecting */
if (has_bones == 0 && enumerate) {
@@ -1502,7 +1477,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
}
/* index of bundle is 1<<16-based. if there's no "bone" index
- * in height word, this buffer value belongs to camera,. not to bundle */
+ * in height word, this buffer value belongs to camera. not to bundle */
if (buffer[4 * i + 3] & 0xFFFF0000) {
MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, 0);
MovieTracking *tracking = &clip->tracking;
@@ -1670,6 +1645,85 @@ int edge_inside_circle(const float cent[2], float radius, const float screen_co_
return FALSE;
}
+static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
+{
+ BoxSelectUserData *data = userData;
+
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
+ BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
+ }
+}
+static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+{
+ const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
+ Mesh *me;
+ MVert *mvert;
+ struct ImBuf *ibuf;
+ unsigned int *rt;
+ int a, index;
+ char *selar;
+ int sx = BLI_rcti_size_x(rect) + 1;
+ int sy = BLI_rcti_size_y(rect) + 1;
+
+ me = vc->obact->data;
+
+ if (me == NULL || me->totvert == 0 || sx * sy <= 0)
+ return OPERATOR_CANCELLED;
+
+
+ if (extend == 0 && select)
+ paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE);
+
+ if (use_zbuf) {
+ selar = MEM_callocN(me->totvert + 1, "selar");
+ view3d_validate_backbuf(vc);
+
+ ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
+ rt = ibuf->rect;
+ glReadPixels(rect->xmin + vc->ar->winrct.xmin, rect->ymin + vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+
+ a = sx * sy;
+ while (a--) {
+ if (*rt) {
+ index = WM_framebuffer_to_index(*rt);
+ if (index <= me->totvert) selar[index] = 1;
+ }
+ rt++;
+ }
+
+ mvert = me->mvert;
+ for (a = 1; a <= me->totvert; a++, mvert++) {
+ if (selar[a]) {
+ if ((mvert->flag & ME_HIDE) == 0) {
+ if (select) mvert->flag |= SELECT;
+ else mvert->flag &= ~SELECT;
+ }
+ }
+ }
+
+ IMB_freeImBuf(ibuf);
+ MEM_freeN(selar);
+
+#ifdef __APPLE__
+ glReadBuffer(GL_BACK);
+#endif
+ }
+ else {
+ BoxSelectUserData data;
+
+ view3d_userdata_boxselect_init(&data, vc, rect, select);
+
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
+
+ meshobject_foreachScreenVert(vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ }
+
+ paintvert_flush_flags(vc->obact);
+
+ return OPERATOR_FINISHED;
+}
+
static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
{
BoxSelectUserData *data = userData;
@@ -1803,11 +1857,11 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -2142,11 +2196,14 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
/* gets called via generic mouse select operator */
static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, short deselect, short toggle, Object *obact)
{
+ View3D *v3d = CTX_wm_view3d(C);
+ const int use_zbuf = (v3d->flag & V3D_ZBUF_SELECT);
+
Mesh *me = obact->data; /* already checked for NULL */
unsigned int index = 0;
MVert *mv;
- if (ED_mesh_pick_vert(C, me, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) {
+ if (ED_mesh_pick_vert(C, obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, use_zbuf)) {
mv = &me->mvert[index];
if (extend) {
mv->flag |= SELECT;
@@ -2333,7 +2390,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f
edbm_backbuf_check_and_select_edges(vc->em, select == LEFTMOUSE);
}
else {
- mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_NOP);
+ mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -2366,22 +2423,39 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m
}
}
+static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, const float screen_co[2], int UNUSED(index))
+{
+ CircleSelectUserData *data = userData;
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
+ BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
+ }
+}
static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
{
+ const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
Object *ob = vc->obact;
- Mesh *me = ob ? ob->data : NULL;
+ Mesh *me = ob->data;
/* int bbsel; */ /* UNUSED */
/* CircleSelectUserData data = {NULL}; */ /* UNUSED */
- if (me) {
+
+ if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
/* bbsel = */ /* UNUSED */ EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
edbm_backbuf_check_and_select_verts_obmode(me, select == LEFTMOUSE);
EDBM_backbuf_free();
+ }
+ else {
+ CircleSelectUserData data;
- paintvert_flush_flags(ob);
+ ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
+
+ view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ meshobject_foreachScreenVert(vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
+
+ paintvert_flush_flags(ob);
}
@@ -2670,7 +2744,7 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2],
if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) {
float screen_co[2];
if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
ED_base_object_select(base, select);
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 7f1bbb2..f570ec3 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -340,9 +340,8 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod
}
if (transvmain && em->derivedCage) {
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata);
- EDBM_index_arrays_free(em);
}
}
else if (obedit->type == OB_ARMATURE) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index ef15c1e..41d092c 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -161,7 +161,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
if (lens) sms.new_lens = *lens;
if (camera) {
- sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs);
+ sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK);
ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens);
sms.to_camera = TRUE; /* restore view3d values in end */
}
@@ -186,7 +186,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
/* original values */
if (oldcamera) {
- sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs);
+ sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f);
ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens);
}
else {
@@ -579,7 +579,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co
}
-int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb)
+int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb)
{
/* return 1: draw */
@@ -1070,11 +1070,9 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
}
}
}
-
- box[0] = (max[0] - min[0]);
- box[1] = (max[1] - min[1]);
- box[2] = (max[2] - min[2]);
- size = MAX3(box[0], box[1], box[2]);
+
+ sub_v3_v3v3(box, max, min);
+ size = max_fff(box[0], box[1], box[2]);
/* do not zoom closer than the near clipping plane */
size = max_ff(size, v3d->near * 1.5f);
@@ -1530,7 +1528,7 @@ float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
rv3d->persmat[0][3] * co[0] +
rv3d->persmat[1][3] * co[1] +
rv3d->persmat[2][3] * co[2])
- ) * rv3d->pixsize;
+ ) * rv3d->pixsize * U.pixelsize;
}
float ED_view3d_radius_to_persp_dist(const float angle, const float radius)
diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript
index 9cf36a2..d579fd7 100644
--- a/source/blender/editors/transform/SConscript
+++ b/source/blender/editors/transform/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 6145fec..5b5e520 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -352,6 +352,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
case SPACE_VIEW3D:
{
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
+ /* allow points behind the view [#33643] */
if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
/* XXX, 2.64 and prior did this, weak! */
adr[0] = t->ar->winx / 2.0f;
@@ -461,7 +462,10 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
else
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
+ if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+
/* for realtime animation record - send notifiers recognised by animation editors */
// XXX: is this notifier a lame duck?
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
@@ -685,6 +689,9 @@ static void view_editmove(unsigned short UNUSED(event))
#define TFM_MODAL_EDGESLIDE_UP 24
#define TFM_MODAL_EDGESLIDE_DOWN 25
+/* for analog input, like trackpad */
+#define TFM_MODAL_PROPSIZE 26
+
/* called in transform_ops.c, on each regeneration of keymaps */
wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{
@@ -714,6 +721,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{TFM_MODAL_AUTOIK_LEN_DEC, "AUTOIK_CHAIN_LEN_DOWN", 0, "Decrease Max AutoIK Chain Length", ""},
{TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""},
{TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""},
+ {TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -749,6 +757,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, PAGEDOWNKEY, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_UP);
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, TFM_MODAL_PROPSIZE);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0, TFM_MODAL_EDGESLIDE_UP);
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ALT, 0, TFM_MODAL_EDGESLIDE_DOWN);
@@ -1023,6 +1032,19 @@ int transformEvent(TransInfo *t, wmEvent *event)
removeSnapPoint(t);
t->redraw |= TREDRAW_HARD;
break;
+
+ case TFM_MODAL_PROPSIZE:
+ /* MOUSEPAN usage... */
+ if (t->flag & T_PROP_EDIT) {
+ float fac = 1.0f + 0.005f *(event->y - event->prevy);
+ t->prop_size *= fac;
+ if (t->spacetype == SPACE_VIEW3D && t->persp != RV3D_ORTHO)
+ t->prop_size = min_ff(t->prop_size, ((View3D *)t->view)->far);
+ calculatePropRatio(t);
+ }
+ t->redraw |= TREDRAW_HARD;
+ break;
+
case TFM_MODAL_PROPSIZE_UP:
if (t->flag & T_PROP_EDIT) {
t->prop_size *= 1.1f;
@@ -1499,7 +1521,6 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
glTranslatef(mval[0], mval[1], 0);
glLineWidth(3.0);
- glBegin(GL_LINES);
drawArrow(UP, 5, 10, 5);
drawArrow(DOWN, 5, 10, 5);
glLineWidth(1.0);
@@ -1585,14 +1606,17 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi
/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */
static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
{
+ rcti rect;
const char printable[] = "Auto Keying On";
float printable_size[2];
int xco, yco;
+ ED_region_visible_rect(ar, &rect);
+
BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]);
- xco = ar->winx - (int)printable_size[0] - 10;
- yco = ar->winy - (int)printable_size[1] - 10;
+ xco = rect.xmax - (int)printable_size[0] - 10;
+ yco = rect.ymax - (int)printable_size[1] - 10;
/* warning text (to clarify meaning of overlays)
* - original color was red to match the icon, but that clashes badly with a less nasty border
@@ -2254,8 +2278,8 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu
static void constraintTransLim(TransInfo *t, TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *ctiLoc = get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
- bConstraintTypeInfo *ctiDist = get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT);
+ bConstraintTypeInfo *ctiLoc = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
+ bConstraintTypeInfo *ctiDist = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
@@ -2305,7 +2329,7 @@ static void constraintTransLim(TransInfo *t, TransData *td)
}
/* get constraint targets if needed */
- get_constraint_targets_for_solving(con, &cob, &targets, ctime);
+ BKE_get_constraint_targets_for_solving(con, &cob, &targets, ctime);
/* do constraint */
cti->evaluate_constraint(con, &cob, &targets);
@@ -2357,7 +2381,7 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
int do_limit = FALSE;
@@ -2424,7 +2448,7 @@ static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
static void constraintSizeLim(TransInfo *t, TransData *td)
{
if (td->con && td->ext) {
- bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
float size_sign[3], size_abs[3];
@@ -2579,7 +2603,8 @@ int handleEventWarp(TransInfo *t, wmEvent *event)
int Warp(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
- float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3];
+ float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3];
+ const float *curs;
int i;
char str[50];
@@ -2716,6 +2741,18 @@ int handleEventShear(TransInfo *t, wmEvent *event)
status = 1;
}
+ else if (event->type == XKEY && event->val == KM_PRESS) {
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+ t->customData = NULL;
+
+ status = 1;
+ }
+ else if (event->type == YKEY && event->val == KM_PRESS) {
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ t->customData = (void *)1;
+
+ status = 1;
+ }
return status;
}
@@ -2749,7 +2786,7 @@ int Shear(TransInfo *t, const int UNUSED(mval[2]))
}
else {
/* default header print */
- sprintf(str, "Shear: %.3f %s", value, t->proptext);
+ sprintf(str, "Shear: %.3f %s (Press X or Y to set shear axis)", value, t->proptext);
}
t->values[0] = value;
@@ -2884,7 +2921,7 @@ BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3])
}
/* smat is reference matrix, only scaled */
-static void TransMat3ToSize(float mat[][3], float smat[][3], float size[3])
+static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3])
{
float vec[3];
@@ -4881,6 +4918,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo
sv->edge_len = len_v3v3(sv->upvec, sv->downvec);
mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co);
+ /* allow points behind the view [#33643] */
if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
dist = len_squared_v2v2(mval, v_proj);
if (dist < min_dist) {
@@ -4903,7 +4941,7 @@ static int createSlideVerts(TransInfo *t)
BMEdge *e, *e1;
BMVert *v, *v2, *first;
TransDataSlideVert *sv_array;
- BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL);
+ BMBVHTree *btree;
SmallHash table;
SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
View3D *v3d = NULL;
@@ -4915,6 +4953,7 @@ static int createSlideVerts(TransInfo *t)
float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */;
float dir[3], maxdist, (*loop_dir)[3], *loop_maxdist;
int numsel, i, j, loop_nr, l_nr;
+ int use_btree_disp;
if (t->spacetype == SPACE_VIEW3D) {
/* background mode support */
@@ -4922,6 +4961,15 @@ static int createSlideVerts(TransInfo *t)
rv3d = t->ar ? t->ar->regiondata : NULL;
}
+ use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
+
+ if (use_btree_disp) {
+ btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL);
+ }
+ else {
+ btree = NULL;
+ }
+
sld->is_proportional = TRUE;
sld->curr_sv_index = 0;
sld->flipped_vtx = FALSE;
@@ -4955,7 +5003,8 @@ static int createSlideVerts(TransInfo *t)
if (numsel == 0 || numsel > 2) {
MEM_freeN(sld);
- BMBVH_FreeBVH(btree);
+ if (btree)
+ BMBVH_FreeBVH(btree);
return 0; /* invalid edge selection */
}
}
@@ -4965,7 +5014,8 @@ static int createSlideVerts(TransInfo *t)
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
if (!BM_edge_is_manifold(e)) {
MEM_freeN(sld);
- BMBVH_FreeBVH(btree);
+ if (btree)
+ BMBVH_FreeBVH(btree);
return 0; /* can only handle exactly 2 faces around each edge */
}
}
@@ -4985,7 +5035,8 @@ static int createSlideVerts(TransInfo *t)
if (!j) {
MEM_freeN(sld);
- BMBVH_FreeBVH(btree);
+ if (btree)
+ BMBVH_FreeBVH(btree);
return 0;
}
@@ -5140,9 +5191,7 @@ static int createSlideVerts(TransInfo *t)
continue;
/* This test is only relevant if object is not wire-drawn! See [#32068]. */
- if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE &&
- !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
- {
+ if (use_btree_disp && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) {
continue;
}
@@ -5216,7 +5265,7 @@ static int createSlideVerts(TransInfo *t)
if (dot_v3v3(loop_dir[l_nr], dir) < 0.0f) {
swap_v3_v3(sv_array->upvec, sv_array->downvec);
SWAP(BMVert, sv_array->vup, sv_array->vdown);
- SWAP(BMVert*, sv_array->up, sv_array->down);
+ SWAP(BMVert *, sv_array->up, sv_array->down);
}
}
@@ -5244,10 +5293,15 @@ static int createSlideVerts(TransInfo *t)
t->customData = sld;
BLI_smallhash_release(&table);
- BMBVH_FreeBVH(btree);
+ if (btree) {
+ BMBVH_FreeBVH(btree);
+ }
MEM_freeN(loop_dir);
MEM_freeN(loop_maxdist);
-
+
+ /* arrays are dirty from copying faces: EDBM_index_arrays_free */
+ EDBM_update_generic(em, FALSE, TRUE);
+
return 1;
}
@@ -5373,7 +5427,7 @@ void projectSVData(TransInfo *t, int final)
}
}
-
+
if (!affected)
continue;
@@ -5419,6 +5473,9 @@ void freeSlideTempFaces(SlideData *sld)
BLI_smallhash_release(&sld->origfaces);
sld->origfaces_init = FALSE;
+
+ /* arrays are dirty from removing faces: EDBM_index_arrays_free */
+ EDBM_update_generic(sld->em, FALSE, TRUE);
}
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index bc959a7..08fe1e7 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -572,7 +572,7 @@ void flushTransTracking(TransInfo *t);
void flushTransMasking(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
-int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */
+int gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
int calc_manipulator_stats(const struct bContext *C);
/*********************** TransData Creation and General Handling *********** */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 33afa4c..d38bdb1 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -113,6 +113,7 @@
#include "WM_types.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "RNA_access.h"
@@ -126,30 +127,24 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list);
/* ************************** Functions *************************** */
-static int trans_data_compare_dist(const void *A, const void *B)
+static int trans_data_compare_dist(const void *a, const void *b)
{
- const TransData *td_A = (const TransData*)A;
- const TransData *td_B = (const TransData*)B;
+ const TransData *td_a = (const TransData *)a;
+ const TransData *td_b = (const TransData *)b;
- if (td_A->dist < td_B->dist)
- return -1;
- else if (td_A->dist > td_B->dist)
- return 1;
-
- return 0;
+ if (td_a->dist < td_b->dist) return -1;
+ else if (td_a->dist > td_b->dist) return 1;
+ else return 0;
}
-static int trans_data_compare_rdist(const void *A, const void *B)
+static int trans_data_compare_rdist(const void *a, const void *b)
{
- const TransData *td_A = (const TransData*)A;
- const TransData *td_B = (const TransData*)B;
+ const TransData *td_a = (const TransData *)a;
+ const TransData *td_b = (const TransData *)b;
- if (td_A->rdist < td_B->rdist)
- return -1;
- else if (td_A->rdist > td_B->rdist)
- return 1;
-
- return 0;
+ if (td_a->rdist < td_b->rdist) return -1;
+ else if (td_a->rdist > td_b->rdist) return 1;
+ else return 0;
}
void sort_trans_data_dist(TransInfo *t)
@@ -271,7 +266,7 @@ static void createTransTexspace(TransInfo *t)
copy_m3_m4(td->mtx, ob->obmat);
copy_m3_m4(td->axismtx, ob->obmat);
normalize_m3(td->axismtx);
- invert_m3_m3(td->smtx, td->mtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) {
ob->dtx |= OB_TEXSPACE;
@@ -294,6 +289,7 @@ static void createTransEdge(TransInfo *t)
float mtx[3][3], smtx[3][3];
int count = 0, countsel = 0;
int propmode = t->flag & T_PROP_EDIT;
+ int cd_edge_float_offset;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -315,10 +311,24 @@ static void createTransEdge(TransInfo *t)
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
+
+ /* create data we need */
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_BWEIGHT);
+ cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
+ }
+ else { //if (t->mode == TFM_CREASE) {
+ BLI_assert(t->mode == TFM_CREASE);
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_CREASE);
+ cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
+ }
+
+ BLI_assert(cd_edge_float_offset != -1);
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) {
+ float *fl_ptr;
/* need to set center for center calculations */
mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
@@ -332,17 +342,10 @@ static void createTransEdge(TransInfo *t)
copy_m3_m3(td->mtx, mtx);
td->ext = NULL;
- if (t->mode == TFM_BWEIGHT) {
- float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT);
- td->val = bweight;
- td->ival = bweight ? *bweight : 1.0f;
- }
- else {
- float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE);
- BLI_assert(t->mode == TFM_CREASE);
- td->val = crease;
- td->ival = crease ? *crease : 0.0f;
- }
+
+ fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
+ td->val = fl_ptr;
+ td->ival = *fl_ptr;
td++;
}
@@ -552,7 +555,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
}
- invert_m3_m3(td->smtx, td->mtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
/* exceptional case: rotate the pose bone which also applies transformation
* when a parentless bone has BONE_NO_LOCAL_LOCATION [] */
@@ -604,7 +607,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
/* only object matrix correction */
copy_m3_m3(td->mtx, omat);
- invert_m3_m3(td->smtx, td->mtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
}
}
@@ -834,7 +837,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
}
}
- con = add_pose_constraint(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
+ con = BKE_add_pose_constraint(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); /* for draw, but also for detecting while pose solving */
data = con->data;
if (targetless) {
@@ -1053,7 +1056,7 @@ static void createTransArmatureVerts(TransInfo *t)
if (!t->total) return;
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone");
@@ -1221,7 +1224,7 @@ static void createTransMBallVerts(TransInfo *t)
tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
for (ml = mb->editelems->first; ml; ml = ml->next) {
if (propmode || (ml->flag & SELECT)) {
@@ -1378,7 +1381,7 @@ static void createTransCurveVerts(TransInfo *t)
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = t->data;
for (nu = nurbs->first; nu; nu = nu->next) {
@@ -1569,7 +1572,7 @@ static void createTransLatticeVerts(TransInfo *t)
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)");
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
td = t->data;
bp = latt->def;
@@ -1769,7 +1772,7 @@ void flushTransParticles(TransInfo *t)
* but instead it's a depth-first search, fudged
* to report shortest distances. I have no idea how fast
* or slow this is. */
-static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists)
+static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists)
{
BMVert **queue = NULL;
float *dqueue = NULL;
@@ -1879,40 +1882,6 @@ static void get_edge_center(float cent_r[3], BMVert *eve)
}
}
-/* local version of #BM_vert_calc_shell_factor which only
- * uses selected faces */
-static float bm_vert_calc_shell_factor_selected(BMVert *v)
-{
- BMIter iter;
- BMLoop *l;
- float accum_shell = 0.0f;
- float accum_angle = 0.0f;
- int tot_sel = 0, tot = 0;
-
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- if (BM_elem_flag_test(l->f, BM_ELEM_SELECT)) { /* <-- only difference to BM_vert_calc_shell_factor! */
- const float face_angle = BM_loop_calc_face_angle(l);
- accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
- accum_angle += face_angle;
- tot_sel++;
- }
- tot++;
- }
-
- if (accum_angle != 0.0f) {
- return accum_shell / accum_angle;
- }
- else {
- if (tot != 0 && tot_sel == 0) {
- /* none selected, so use all */
- return BM_vert_calc_shell_factor(v);
- }
- else {
- return 1.0f;
- }
- }
-}
-
/* way to overwrite what data is edited with transform */
static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx,
BMEditMesh *em, BMVert *eve, float *bweight)
@@ -1946,8 +1915,8 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
td->val = NULL;
td->extra = NULL;
if (t->mode == TFM_BWEIGHT) {
- td->val = bweight;
- td->ival = bweight ? *(bweight) : 1.0f;
+ td->val = bweight;
+ td->ival = *bweight;
}
else if (t->mode == TFM_SKIN_RESIZE) {
MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata,
@@ -1961,7 +1930,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
}
else if (t->mode == TFM_SHRINKFATTEN) {
td->ext = tx;
- tx->isize[0] = bm_vert_calc_shell_factor_selected(eve);
+ tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT);
}
}
@@ -1983,6 +1952,7 @@ static void createTransEditVerts(TransInfo *t)
int mirror = 0;
char *selstate = NULL;
short selectmode = ts->selectmode;
+ int cd_vert_bweight_offset = -1;
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_begin(em, TRUE);
@@ -2064,6 +2034,10 @@ static void createTransEditVerts(TransInfo *t)
}
}
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT);
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ }
if (propmode) {
t->total = count;
@@ -2085,7 +2059,9 @@ static void createTransEditVerts(TransInfo *t)
}
copy_m3_m4(mtx, t->obedit->obmat);
- invert_m3_m3(smtx, mtx);
+ /* we use a pseudoinverse so that when one of the axes is scaled to 0,
+ * matrix inversion still works and we can still moving along the other */
+ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
if (propmode & T_PROP_CONNECTED) {
editmesh_set_connectivity_distance(em, mtx, dists);
@@ -2128,11 +2104,10 @@ static void createTransEditVerts(TransInfo *t)
}
}
- eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
- for (a = 0; eve; eve = BM_iter_step(&iter), a++) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (propmode || selstate[a]) {
- float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
+ float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
VertsToTransData(t, tob, tx, em, eve, bweight);
if (tx)
@@ -2229,7 +2204,12 @@ void flushTransNodes(TransInfo *t)
/* flush to 2d vector from internally used 3d vector */
for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) {
bNode *node = td->extra;
- add_v2_v2v2(&node->locx, td2d->loc, td2d->ih1);
+ float vec[2];
+
+ /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
+ add_v2_v2v2(vec, td2d->loc, td2d->ih1);
+ node->locx = vec[0] / UI_DPI_FAC;
+ node->locy = vec[1] / UI_DPI_FAC;
}
/* handle intersection with noodles */
@@ -4116,7 +4096,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
/* Meta's can only directly be moved between channels since they
* don't have their start and length set directly (children affect that)
* since this Meta is nested we don't need any of its data in fact.
- * calc_sequence() will update its settings when run on the toplevel meta */
+ * BKE_sequence_calc() will update its settings when run on the toplevel meta */
*flag = 0;
*count = 0;
*recursive = TRUE;
@@ -4294,8 +4274,8 @@ static void freeSeqData(TransInfo *t)
{
int overlap = 0;
+ seq_prev = NULL;
for (a = 0; a < t->total; a++, td++) {
- seq_prev = NULL;
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
overlap = 1;
@@ -5125,7 +5105,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
* during cleanup - psy-fi */
freeSlideTempFaces(sld);
}
- EDBM_automerge(t->scene, t->obedit, 1);
+ EDBM_automerge(t->scene, t->obedit, TRUE);
}
else {
if (t->mode == TFM_EDGE_SLIDE) {
@@ -5626,7 +5606,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
/* hold original location */
float locxy[2] = {BLI_rctf_cent_x(&node->totr),
BLI_rctf_cent_y(&node->totr)};
-
+ float nodeloc[2];
+
copy_v2_v2(td2d->loc, locxy);
td2d->loc[2] = 0.0f;
td2d->loc2d = td2d->loc; /* current location */
@@ -5651,7 +5632,10 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
unit_m3(td->mtx);
unit_m3(td->smtx);
- sub_v2_v2v2(td2d->ih1, &node->locx, locxy);
+ /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
+ nodeloc[0] = UI_DPI_FAC * node->locx;
+ nodeloc[1] = UI_DPI_FAC * node->locy;
+ sub_v2_v2v2(td2d->ih1, nodeloc, locxy);
td->extra = node;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 615bb78..2591c61 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -61,6 +61,8 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BIK_api.h"
+
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -847,6 +849,8 @@ static void recalcData_view3d(TransInfo *t)
/* old optimize trick... this enforces to bypass the depgraph */
if (!(arm->flag & ARM_DELAYDEFORM)) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ /* transformation of pose may affect IK tree, make sure it is rebuilt */
+ BIK_clear_data(ob->pose);
}
else
BKE_pose_where_is(t->scene, ob);
@@ -1445,7 +1449,7 @@ void calculateCenter2D(TransInfo *t)
void calculateCenterCursor(TransInfo *t)
{
- float *cursor;
+ const float *cursor;
cursor = give_cursor(t->scene, t->view);
copy_v3_v3(t->center, cursor);
@@ -1529,13 +1533,6 @@ void calculateCenterMedian(TransInfo *t)
total++;
}
}
- else {
- /*
- * All the selected elements are at the head of the array
- * which means we can stop when it finds unselected data
- */
- break;
- }
}
if (i)
mul_v3_fl(partial, 1.0f / total);
@@ -1555,13 +1552,6 @@ void calculateCenterBound(TransInfo *t)
if (!(t->data[i].flag & TD_NOCENTER))
minmax_v3v3_v3(min, max, t->data[i].center);
}
- else {
- /*
- * All the selected elements are at the head of the array
- * which means we can stop when it finds unselected data
- */
- break;
- }
}
else {
copy_v3_v3(max, t->data[i].center);
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 88ed002..6956925 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -399,7 +399,7 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event)
mi->precision = 1;
redraw = TREDRAW_HARD;
}
- else if(event->val == KM_RELEASE) {
+ else if (event->val == KM_RELEASE) {
t->modifiers &= ~MOD_PRECISION;
mi->precision = 0;
redraw = TREDRAW_HARD;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index c890c98..cd6035a 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -197,7 +197,7 @@ static int test_rotmode_euler(short rotmode)
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
}
-int gimbal_axis(Object *ob, float gmat[][3])
+int gimbal_axis(Object *ob, float gmat[3][3])
{
if (ob) {
if (ob->mode & OB_MODE_POSE) {
@@ -687,7 +687,7 @@ static void test_manipulator_axis(const bContext *C)
/* ******************** DRAWING STUFFIES *********** */
-static float screen_aligned(RegionView3D *rv3d, float mat[][4])
+static float screen_aligned(RegionView3D *rv3d, float mat[4][4])
{
glTranslatef(mat[3][0], mat[3][1], mat[3][2]);
@@ -734,8 +734,8 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i
float cos_phi, sin_phi, dist;
phi += side_delta;
- cos_phi = (float)cos(phi);
- sin_phi = (float)sin(phi);
+ cos_phi = cosf(phi);
+ sin_phi = sinf(phi);
dist = radhole + radring * cos_phi;
glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
@@ -749,8 +749,8 @@ static void partial_doughnut(float radring, float radhole, int start, int end, i
float cos_phi, sin_phi, dist;
phi += side_delta;
- cos_phi = (float)cos(phi);
- sin_phi = (float)sin(phi);
+ cos_phi = cosf(phi);
+ sin_phi = sinf(phi);
dist = radhole + radring * cos_phi;
glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi);
@@ -875,7 +875,7 @@ static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode,
}
}
-static void preOrthoFront(int ortho, float twmat[][4], int axis)
+static void preOrthoFront(int ortho, float twmat[4][4], int axis)
{
if (ortho == 0) {
float omat[4][4];
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 8b03e36..4bd6496 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -438,7 +438,7 @@ int BIF_countTransformOrientation(const bContext *C)
return count;
}
-void applyTransformOrientation(const bContext *C, float mat[3][3], char *name)
+void applyTransformOrientation(const bContext *C, float mat[3][3], char name[MAX_NAME])
{
TransformOrientation *ts;
View3D *v3d = CTX_wm_view3d(C);
@@ -449,8 +449,9 @@ void applyTransformOrientation(const bContext *C, float mat[3][3], char *name)
for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) {
if (selected_index == i) {
- if (name)
- strcpy(name, ts->name);
+ if (name) {
+ BLI_strncpy(name, ts->name, MAX_NAME);
+ }
copy_m3_m3(mat, ts->mat);
break;
@@ -763,7 +764,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
EditBone *ebone;
int ok = FALSE;
- /* grr,.but better then duplicate code */
+ /* grr. but better then duplicate code */
#define EBONE_CALC_NORMAL_PLANE { \
float tmat[3][3]; \
float vec[3]; \
@@ -881,7 +882,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
return result;
}
-void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly)
+void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], int activeOnly)
{
float normal[3] = {0.0, 0.0, 0.0};
float plane[3] = {0.0, 0.0, 0.0};
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2d95e2e..5577619 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -1141,7 +1141,7 @@ static void TargetSnapClosest(TransInfo *t)
}
}
-static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[][4], float timat[][3],
+static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3],
const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1228,7 +1228,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh
return retval;
}
-static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], float timat[][3],
+static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3],
const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1276,7 +1276,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4],
return retval;
}
-static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4],
+static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float mval[2],
float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth)
{
@@ -1339,7 +1339,7 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm
return retval;
}
-static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[][4],
+static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1417,7 +1417,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
if (em != NULL) {
index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
- EDBM_index_arrays_init(em, 1, 0, 0);
+ EDBM_index_arrays_ensure(em, BM_VERT);
}
for (i = 0; i < totvert; i++) {
@@ -1452,9 +1452,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
}
}
- if (em != NULL) {
- EDBM_index_arrays_free(em);
- }
break;
}
case SCE_SNAP_MODE_EDGE:
@@ -1468,7 +1465,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
if (em != NULL) {
index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
- EDBM_index_arrays_init(em, 0, 1, 0);
+ EDBM_index_arrays_ensure(em, BM_EDGE);
}
for (i = 0; i < totedge; i++) {
@@ -1505,9 +1502,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
}
}
- if (em != NULL) {
- EDBM_index_arrays_free(em);
- }
break;
}
}
@@ -1517,7 +1511,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
return retval;
}
-static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4],
+static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float mval[2],
float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
@@ -1670,7 +1664,7 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n
peel->flag = 0;
}
-static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4],
+static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
ListBase *depth_peels)
{
diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript
index 74879e5..1c1a8e4 100644
--- a/source/blender/editors/util/SConscript
+++ b/source/blender/editors/util/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 1753a56..1dc7e0c 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -162,15 +162,18 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
}
}
else {
- int do_glob_undo = FALSE;
-
+ /* Note: we used to do a fall-through here where if the
+ * mode-specific undo system had no more steps to undo (or
+ * redo), the global undo would run.
+ *
+ * That was inconsistent with editmode, and also makes for
+ * unecessarily tricky interaction with the other undo
+ * systems. */
if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
- if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname))
- do_glob_undo = TRUE;
+ ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname);
}
else if (obact && obact->mode & OB_MODE_SCULPT) {
- if (!ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname))
- do_glob_undo = TRUE;
+ ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname);
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if (step == 1)
@@ -178,24 +181,17 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
else
PE_redo(CTX_data_scene(C));
}
- else {
- do_glob_undo = TRUE;
- }
-
- if (do_glob_undo) {
- if (U.uiflag & USER_GLOBALUNDO) {
- // note python defines not valid here anymore.
- //#ifdef WITH_PYTHON
- // XXX BPY_scripts_clear_pyobjects();
- //#endif
- if (undoname)
- BKE_undo_name(C, undoname);
- else
- BKE_undo_step(C, step);
+ else if (U.uiflag & USER_GLOBALUNDO) {
+ // note python defines not valid here anymore.
+ //#ifdef WITH_PYTHON
+ // XXX BPY_scripts_clear_pyobjects();
+ //#endif
+ if (undoname)
+ BKE_undo_name(C, undoname);
+ else
+ BKE_undo_step(C, step);
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
- }
-
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
}
}
diff --git a/source/blender/editors/uvedit/SConscript b/source/blender/editors/uvedit/SConscript
index d236b18..0131668 100644
--- a/source/blender/editors/uvedit/SConscript
+++ b/source/blender/editors/uvedit/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.c')
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 9c2c300..023f281 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -60,48 +60,49 @@
#include "ED_uvedit.h"
#include "UI_resources.h"
+#include "UI_interface.h"
+#include "UI_view2d.h"
#include "uvedit_intern.h"
void draw_image_cursor(SpaceImage *sima, ARegion *ar)
{
- float zoomx, zoomy, w, h;
- int width, height;
+ float zoom[2], x_fac, y_fac;
- ED_space_image_get_size(sima, &width, &height);
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ UI_view2d_getscale_inverse(&ar->v2d, &zoom[0], &zoom[1]);
- w = zoomx * width / 256.0f;
- h = zoomy * height / 256.0f;
+ mul_v2_fl(zoom, 256.0f * UI_DPI_FAC);
+ x_fac = zoom[0];
+ y_fac = zoom[1];
cpack(0xFFFFFF);
glTranslatef(sima->cursor[0], sima->cursor[1], 0.0);
- fdrawline(-0.05f / w, 0, 0, 0.05f / h);
- fdrawline(0, 0.05f / h, 0.05f / w, 0.0f);
- fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h);
- fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f);
+ fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac);
+ fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
+ fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
+ fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f);
setlinestyle(4);
cpack(0xFF);
- fdrawline(-0.05f / w, 0.0f, 0.0f, 0.05f / h);
- fdrawline(0.0f, 0.05f / h, 0.05f / w, 0.0f);
- fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h);
- fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f);
+ fdrawline(-0.05f * x_fac, 0.0f, 0.0f, 0.05f * y_fac);
+ fdrawline(0.0f, 0.05f * y_fac, 0.05f * x_fac, 0.0f);
+ fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac);
+ fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f);
setlinestyle(0.0f);
cpack(0x0);
- fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f);
- fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f);
- fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h);
- fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h);
+ fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f);
+ fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f);
+ fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
+ fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
setlinestyle(1);
cpack(0xFFFFFF);
- fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f);
- fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f);
- fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h);
- fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h);
+ fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f);
+ fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f);
+ fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac);
+ fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac);
glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0);
setlinestyle(0);
@@ -169,10 +170,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
MTexPoly *tf;
MLoopUV *luv;
Image *ima = sima->image;
- BLI_array_declare(tf_uv);
- BLI_array_declare(tf_uvorig);
- float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL;
- int i, j, nverts;
+ float aspx, aspy, col[4];
+ int i;
ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
@@ -182,27 +181,20 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ const int efa_len = efa->len;
+ float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
+ float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
-
- BLI_array_empty(tf_uv);
- BLI_array_empty(tf_uvorig);
- BLI_array_grow_items(tf_uv, efa->len);
- BLI_array_grow_items(tf_uvorig, efa->len);
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
copy_v2_v2(tf_uvorig[i], luv->uv);
-
- i++;
}
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
totarea += BM_face_calc_area(efa);
- //totuvarea += tf_area(tf, efa->v4!=0);
- totuvarea += uv_poly_area(tf_uv, efa->len);
+ totuvarea += area_poly_v2(efa->len, tf_uv);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -232,26 +224,20 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
else {
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- area = BM_face_calc_area(efa) / totarea;
+ const int efa_len = efa->len;
+ float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
+ float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
- BLI_array_empty(tf_uv);
- BLI_array_empty(tf_uvorig);
- BLI_array_grow_items(tf_uv, efa->len);
- BLI_array_grow_items(tf_uvorig, efa->len);
+ area = BM_face_calc_area(efa) / totarea;
- i = 0;
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
copy_v2_v2(tf_uvorig[i], luv->uv);
-
- i++;
}
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
- //uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
- uvarea = uv_poly_area(tf_uv, efa->len) / totuvarea;
+ uvarea = area_poly_v2(efa->len, tf_uv) / totuvarea;
if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
areadiff = 1.0f;
@@ -276,18 +262,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
}
case SI_UVDT_STRETCH_ANGLE:
{
- float *uvang = NULL;
- float *ang = NULL;
- float (*av)[3] = NULL; /* use for 2d and 3d angle vectors */
- float (*auv)[2] = NULL;
float a;
- BLI_array_declare(uvang);
- BLI_array_declare(ang);
- BLI_array_declare(av);
- BLI_array_declare(auv);
-
- col[3] = 0.5; /* hard coded alpha, not that nice */
+ col[3] = 0.5f; /* hard coded alpha, not that nice */
glShadeModel(GL_SMOOTH);
@@ -295,44 +272,40 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
- nverts = efa->len;
+ const int efa_len = efa->len;
+ float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
+ float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
+ float *uvang = BLI_array_alloca(uvang, efa_len);
+ float *ang = BLI_array_alloca(ang, efa_len);
+ float (*av)[3] = BLI_array_alloca(av, efa_len); /* use for 2d and 3d angle vectors */
+ float (*auv)[2] = BLI_array_alloca(auv, efa_len);
+ int j;
+
BM_elem_flag_enable(efa, BM_ELEM_TAG);
- BLI_array_empty(tf_uv);
- BLI_array_empty(tf_uvorig);
- BLI_array_empty(uvang);
- BLI_array_empty(ang);
- BLI_array_empty(av);
- BLI_array_empty(auv);
- BLI_array_grow_items(tf_uv, nverts);
- BLI_array_grow_items(tf_uvorig, nverts);
- BLI_array_grow_items(uvang, nverts);
- BLI_array_grow_items(ang, nverts);
- BLI_array_grow_items(av, nverts);
- BLI_array_grow_items(auv, nverts);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
copy_v2_v2(tf_uvorig[i], luv->uv);
}
- uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, nverts);
+ uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa_len);
- j = nverts - 1;
+ j = efa_len - 1;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
sub_v2_v2v2(auv[i], tf_uv[j], tf_uv[i]); normalize_v2(auv[i]);
sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); normalize_v3(av[i]);
j = i;
}
- for (i = 0; i < nverts; i++) {
+ for (i = 0; i < efa_len; i++) {
#if 0
/* Simple but slow, better reuse normalized vectors
* (Not ported to bmesh, copied for reference) */
uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1]));
ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co));
#endif
- uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % nverts]);
- ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % nverts]);
+ uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % efa_len]);
+ ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]);
}
glBegin(GL_POLYGON);
@@ -354,17 +327,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
glShadeModel(GL_FLAT);
- BLI_array_free(uvang);
- BLI_array_free(ang);
- BLI_array_free(av);
- BLI_array_free(auv);
-
break;
}
}
-
- BLI_array_free(tf_uv);
- BLI_array_free(tf_uvorig);
}
static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage)
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index b42875f..b6d8245 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -50,8 +50,7 @@ struct BMVert;
int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa);
/* geometric utilities */
-float uv_poly_area(float uv[][2], int len);
-void uv_poly_copy_aspect(float uv_orig [][2], float uv[][2], float aspx, float aspy, int len);
+void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len);
void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]);
/* find nearest */
@@ -73,6 +72,7 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM
/* utility tool functions */
void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit);
+void uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, float *aspx, float *aspy);
/* operators */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index a384c77..2194ce2 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -575,19 +575,6 @@ void uv_poly_center(BMEditMesh *em, BMFace *f, float r_cent[2])
mul_v2_fl(r_cent, 1.0f / (float)f->len);
}
-float uv_poly_area(float uv[][2], int len)
-{
- //BMESH_TODO: make this not suck
- //maybe use scanfill? I dunno.
-
- if (len >= 4)
- return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]);
- else
- return area_tri_v2(uv[0], uv[1], uv[2]);
-
- return 1.0;
-}
-
void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len)
{
int i;
@@ -999,8 +986,8 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit
int a, looking, nverts, starttotf, select;
/* setup */
- EDBM_index_arrays_init(em, 0, 0, 1);
- vmap = EDBM_uv_vert_map_create(em, 0, 0, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE);
+ vmap = EDBM_uv_vert_map_create(em, 0, limit);
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
@@ -1091,7 +1078,6 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit
/* cleanup */
EDBM_uv_vert_map_free(vmap);
- EDBM_index_arrays_free(em);
return (select) ? 1 : -1;
}
@@ -1111,8 +1097,8 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
unsigned int a;
char *flag;
- EDBM_index_arrays_init(em, 0, 0, 1); /* we can use this too */
- vmap = EDBM_uv_vert_map_create(em, 1, 1, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE); /* we can use this too */
+ vmap = EDBM_uv_vert_map_create(em, 1, limit);
if (vmap == NULL)
return;
@@ -1270,7 +1256,6 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float
MEM_freeN(stack);
MEM_freeN(flag);
EDBM_uv_vert_map_free(vmap);
- EDBM_index_arrays_free(em);
}
/* WATCH IT: this returns first selected UV,
@@ -2608,8 +2593,8 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
uvedit_pixel_to_float(sima, limit, 0.05);
- EDBM_index_arrays_init(em, 0, 0, 1);
- vmap = EDBM_uv_vert_map_create(em, 0, 0, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE);
+ vmap = EDBM_uv_vert_map_create(em, 0, limit);
/* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
if (vmap == NULL) {
@@ -2662,7 +2647,6 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
}
}
}
- EDBM_index_arrays_free(em);
EDBM_uv_vert_map_free(vmap);
}
@@ -3795,8 +3779,8 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op)
}
/* This code sets editvert->tmp.l to the index. This will be useful later on. */
- EDBM_index_arrays_init(em, 0, 0, 1);
- vmap = EDBM_uv_vert_map_create(em, 0, 0, limit);
+ EDBM_index_arrays_ensure(em, BM_FACE);
+ vmap = EDBM_uv_vert_map_create(em, 0, limit);
BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) {
/* flags to determine if we uv is separated from first editface match */
@@ -3875,7 +3859,6 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op)
me->drawflag |= ME_DRAWSEAMS;
EDBM_uv_vert_map_free(vmap);
- EDBM_index_arrays_free(em);
DAG_id_tag_update(&me->id, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 8703234..5d3a598 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -3109,7 +3109,7 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
sina2 = sin(a2);
sina3 = sin(a3);
- sinmax = MAX3(sina1, sina2, sina3);
+ sinmax = max_fff(sina1, sina2, sina3);
/* shift vertices to find most stable order */
if (sina3 != sinmax) {
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 4ca6426..b1bb5c8 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -72,7 +72,7 @@
/* ********************** smart stitch operator *********************** */
-/* object that stores display data for previewing before accepting stitching */
+/* object that stores display data for previewing before confirming stitching */
typedef struct StitchPreviewer {
/* here we'll store the preview triangle indices of the mesh */
float *preview_polys;
@@ -87,7 +87,7 @@ typedef struct StitchPreviewer {
unsigned int num_stitchable;
unsigned int num_unstitchable;
unsigned int preview_uvs;
- /* ...and here we'll store the triangles*/
+ /* ...and here we'll store the static island triangles*/
float *static_tris;
unsigned int num_static_tris;
} StitchPreviewer;
@@ -124,14 +124,19 @@ typedef struct UvEdge {
unsigned int uv1;
unsigned int uv2;
/* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
- char flag;
- /* element that guarantees element->face has the face on element->tfindex and element->tfindex+1 is the second uv */
+ unsigned char flag;
+ /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */
UvElement *element;
+ /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */
+ struct UvEdge *next;
+ /* point to first of common edges. Needed for iteration */
+ struct UvEdge *first;
} UvEdge;
/* stitch state object */
typedef struct StitchState {
+ float aspect;
/* use limit flag */
char use_limit;
/* limit to operator, same as original operator */
@@ -156,19 +161,26 @@ typedef struct StitchState {
float *normals;
/* edge storage */
UvEdge *edges;
+ /* hash for quick lookup of edges */
+ GHash *edge_hash;
/* count of separate uvs and edges */
- int total_boundary_edges;
+ int total_separate_edges;
int total_separate_uvs;
/* hold selection related information */
- UvElement **selection_stack;
+ void **selection_stack;
int selection_size;
/* island that stays in place */
int static_island;
/* store number of primitives per face so that we can allocate the active island buffer later */
unsigned int *tris_per_island;
+ /* vert or edge mode used for stitching */
+ char mode;
+ /* handle for drawing */
void *draw_handle;
+ /* preview data */
+ StitchPreviewer *stitch_preview;
} StitchState;
typedef struct PreviewPosition {
@@ -176,7 +188,7 @@ typedef struct PreviewPosition {
int polycount_position;
} PreviewPosition;
/*
- * defines for UvElement flags
+ * defines for UvElement/UcEdge flags
*/
#define STITCH_SELECTED 1
#define STITCH_STITCHABLE 2
@@ -186,83 +198,79 @@ typedef struct PreviewPosition {
#define STITCH_NO_PREVIEW -1
-/* previewer stuff (see uvedit_intern.h for more info) */
-static StitchPreviewer *_stitch_preview;
+enum StitchModes {
+ STITCH_VERT,
+ STITCH_EDGE
+};
/* constructor */
static StitchPreviewer *stitch_preview_init(void)
{
- _stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
- _stitch_preview->preview_polys = NULL;
- _stitch_preview->preview_stitchable = NULL;
- _stitch_preview->preview_unstitchable = NULL;
- _stitch_preview->uvs_per_polygon = NULL;
+ StitchPreviewer *stitch_preview;
- _stitch_preview->preview_uvs = 0;
- _stitch_preview->num_polys = 0;
- _stitch_preview->num_stitchable = 0;
- _stitch_preview->num_unstitchable = 0;
+ stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
+ stitch_preview->preview_polys = NULL;
+ stitch_preview->preview_stitchable = NULL;
+ stitch_preview->preview_unstitchable = NULL;
+ stitch_preview->uvs_per_polygon = NULL;
- _stitch_preview->static_tris = NULL;
+ stitch_preview->preview_uvs = 0;
+ stitch_preview->num_polys = 0;
+ stitch_preview->num_stitchable = 0;
+ stitch_preview->num_unstitchable = 0;
- _stitch_preview->num_static_tris = 0;
+ stitch_preview->static_tris = NULL;
- return _stitch_preview;
+ stitch_preview->num_static_tris = 0;
+
+ return stitch_preview;
}
/* destructor...yeah this should be C++ :) */
-static void stitch_preview_delete(void)
+static void stitch_preview_delete(StitchPreviewer *stitch_preview)
{
- if (_stitch_preview) {
- if (_stitch_preview->preview_polys) {
- MEM_freeN(_stitch_preview->preview_polys);
- _stitch_preview->preview_polys = NULL;
+ if (stitch_preview) {
+ if (stitch_preview->preview_polys) {
+ MEM_freeN(stitch_preview->preview_polys);
+ stitch_preview->preview_polys = NULL;
}
- if (_stitch_preview->uvs_per_polygon) {
- MEM_freeN(_stitch_preview->uvs_per_polygon);
- _stitch_preview->uvs_per_polygon = NULL;
+ if (stitch_preview->uvs_per_polygon) {
+ MEM_freeN(stitch_preview->uvs_per_polygon);
+ stitch_preview->uvs_per_polygon = NULL;
}
- if (_stitch_preview->preview_stitchable) {
- MEM_freeN(_stitch_preview->preview_stitchable);
- _stitch_preview->preview_stitchable = NULL;
+ if (stitch_preview->preview_stitchable) {
+ MEM_freeN(stitch_preview->preview_stitchable);
+ stitch_preview->preview_stitchable = NULL;
}
- if (_stitch_preview->preview_unstitchable) {
- MEM_freeN(_stitch_preview->preview_unstitchable);
- _stitch_preview->preview_unstitchable = NULL;
+ if (stitch_preview->preview_unstitchable) {
+ MEM_freeN(stitch_preview->preview_unstitchable);
+ stitch_preview->preview_unstitchable = NULL;
}
- if (_stitch_preview->static_tris) {
- MEM_freeN(_stitch_preview->static_tris);
- _stitch_preview->static_tris = NULL;
+ if (stitch_preview->static_tris) {
+ MEM_freeN(stitch_preview->static_tris);
+ stitch_preview->static_tris = NULL;
}
-
- MEM_freeN(_stitch_preview);
- _stitch_preview = NULL;
+ MEM_freeN(stitch_preview);
}
}
-
-/* "getter method" */
-static StitchPreviewer *uv_get_stitch_previewer(void)
-{
- return _stitch_preview;
-}
-
#define HEADER_LENGTH 256
/* This function updates the header of the UV editor when the stitch tool updates its settings */
-static void stitch_update_header(StitchState *stitch_state, bContext *C)
+static void stitch_update_header(StitchState *state, bContext *C)
{
- static char str[] = "(S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices";
+ static char str[] = "Mode(TAB) %s, (S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices";
char msg[HEADER_LENGTH];
ScrArea *sa = CTX_wm_area(C);
if (sa) {
BLI_snprintf(msg, HEADER_LENGTH, str,
- stitch_state->snap_islands ? "On" : "Off",
- stitch_state->midpoints ? "On" : "Off",
- stitch_state->limit_dist,
- stitch_state->use_limit ? "On" : "Off");
+ state->mode == STITCH_VERT ? "Vertex" : "Edge",
+ state->snap_islands ? "On" : "Off",
+ state->midpoints ? "On" : "Off",
+ state->limit_dist,
+ state->use_limit ? "On" : "Off");
ED_area_headerprint(sa, msg);
}
@@ -278,10 +286,12 @@ static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
}
}
-static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2])
+static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2], float aspect)
{
float uv_rotation_result[2];
+ uv[1] /= aspect;
+
uv[0] -= medianPoint[0];
uv[1] -= medianPoint[1];
@@ -290,32 +300,33 @@ static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2])
uv[0] = uv_rotation_result[0] + medianPoint[0];
uv[1] = uv_rotation_result[1] + medianPoint[1];
+
+ uv[1] *= aspect;
}
+/* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */
static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
{
float limit;
- int do_limit;
if (element_iter == element) {
return 0;
}
limit = state->limit_dist;
- do_limit = state->use_limit;
- if (do_limit) {
- MLoopUV *luv_orig, *luv_iter;
- BMLoop *l_orig, *l_iter;
+ if (state->use_limit) {
+ MLoopUV *luv, *luv_iter;
+ BMLoop *l;
- l_orig = element->l;
- luv_orig = CustomData_bmesh_get(&state->em->bm->ldata, l_orig->head.data, CD_MLOOPUV);
- l_iter = element_iter->l;
- luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l_iter->head.data, CD_MLOOPUV);
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = element_iter->l;
+ luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- if (fabsf(luv_orig->uv[0] - luv_iter->uv[0]) < limit &&
- fabsf(luv_orig->uv[1] - luv_iter->uv[1]) < limit)
+ if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit &&
+ fabsf(luv->uv[1] - luv_iter->uv[1]) < limit)
{
return 1;
}
@@ -328,6 +339,46 @@ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_it
}
}
+static int stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+{
+ float limit;
+
+ if (edge_iter == edge) {
+ return 0;
+ }
+
+ limit = state->limit_dist;
+
+ if (state->use_limit) {
+ BMLoop *l;
+ MLoopUV *luv_orig1, *luv_iter1;
+ MLoopUV *luv_orig2, *luv_iter2;
+
+ l = state->uvs[edge->uv1]->l;
+ luv_orig1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge_iter->uv1]->l;
+ luv_iter1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ l = state->uvs[edge->uv2]->l;
+ luv_orig2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge_iter->uv2]->l;
+ luv_iter2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit &&
+ fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit &&
+ fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit &&
+ fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit)
+ {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+ else {
+ return 1;
+ }
+}
static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
{
@@ -341,6 +392,17 @@ static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *elem
}
+static int stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+{
+ if ((state->snap_islands && edge->element->island == edge_iter->element->island) ||
+ (!state->midpoints && edge->element->island == edge_iter->element->island))
+ {
+ return 0;
+ }
+
+ return stitch_check_edges_stitchable(edge, edge_iter, state);
+}
+
/* calculate snapping for islands */
static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final)
{
@@ -356,9 +418,11 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition
island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements;
island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements;
island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements;
+ island_stitch_data[i].medianPoint[1] /= state->aspect;
}
island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
+
numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
element = &state->element_map->buf[state->element_map->islandIndices[i]];
for (j = 0; j < numOfIslandUVs; j++, element++) {
@@ -372,16 +436,16 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition
if (final) {
- stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, luv->uv);
+ stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, luv->uv, state->aspect);
add_v2_v2(luv->uv, island_stitch_data[i].translation);
}
else {
- int face_preview_pos = preview_position[BM_elem_index_get(element->face)].data_position;
+ int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position;
stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint,
- preview->preview_polys + face_preview_pos + 2 * element->tfindex);
+ preview->preview_polys + face_preview_pos + 2 * element->tfindex, state->aspect);
add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex,
island_stitch_data[i].translation);
@@ -404,32 +468,38 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta
int index1, index2;
float rotation;
MLoopUV *luv1, *luv2;
- BMLoop *l1, *l2;
element1 = state->uvs[edge->uv1];
element2 = state->uvs[edge->uv2];
- l1 = element1->l;
- luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l1->head.data, CD_MLOOPUV);
- l2 = element2->l;
- luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l2->head.data, CD_MLOOPUV);
-
- index1 = uvfinal_map[element1 - state->element_map->buf];
- index2 = uvfinal_map[element2 - state->element_map->buf];
+ luv1 = CustomData_bmesh_get(&state->em->bm->ldata, element1->l->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&state->em->bm->ldata, element2->l->head.data, CD_MLOOPUV);
+ if (state->mode == STITCH_VERT) {
+ index1 = uvfinal_map[element1 - state->element_map->buf];
+ index2 = uvfinal_map[element2 - state->element_map->buf];
+ }
+ else {
+ index1 = edge->uv1;
+ index2 = edge->uv2;
+ }
/* the idea here is to take the directions of the edges and find the rotation between final and initial
* direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */
uv1[0] = luv2->uv[0] - luv1->uv[0];
uv1[1] = luv2->uv[1] - luv1->uv[1];
+ uv1[1] /= state->aspect;
+
uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
+ uv2[1] /= state->aspect;
+
normalize_v2(uv1);
normalize_v2(uv2);
- edgecos = uv1[0] * uv2[0] + uv1[1] * uv2[1];
- edgesin = uv1[0] * uv2[1] - uv2[0] * uv1[1];
+ edgecos = dot_v2v2(uv1, uv2);
+ edgesin = cross_v2v2(uv1, uv2);
rotation = (edgesin > 0.0f) ?
+acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))) :
@@ -461,7 +531,10 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
int index_tmp1, index_tmp2;
float normal[2];
- /* easily possible*/
+
+ /* only calculate rotation against static island uv verts */
+ if (!state->midpoints && element_iter->island != state->static_island)
+ continue;
index_tmp1 = element_iter - state->element_map->buf;
index_tmp1 = state->map[index_tmp1];
@@ -471,7 +544,9 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
negate_v2_v2(normal, state->normals + index_tmp2 * 2);
edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2);
edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2);
- rotation += (edgesin > 0.0f) ? acosf(edgecos) : -acosf(edgecos);
+ rotation += (edgesin > 0.0f) ?
+ +acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))) :
+ -acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
}
}
@@ -482,34 +557,114 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
}
-static void stitch_state_delete(StitchState *stitch_state)
+static void state_delete(StitchState *state)
{
- if (stitch_state) {
- if (stitch_state->element_map) {
- EDBM_uv_element_map_free(stitch_state->element_map);
+ if (state) {
+ if (state->element_map) {
+ EDBM_uv_element_map_free(state->element_map);
+ }
+ if (state->uvs) {
+ MEM_freeN(state->uvs);
}
- if (stitch_state->uvs) {
- MEM_freeN(stitch_state->uvs);
+ if (state->selection_stack) {
+ MEM_freeN(state->selection_stack);
}
- if (stitch_state->selection_stack) {
- MEM_freeN(stitch_state->selection_stack);
+ if (state->tris_per_island) {
+ MEM_freeN(state->tris_per_island);
}
- if (stitch_state->tris_per_island) {
- MEM_freeN(stitch_state->tris_per_island);
+ if (state->map) {
+ MEM_freeN(state->map);
}
- if (stitch_state->map) {
- MEM_freeN(stitch_state->map);
+ if (state->normals) {
+ MEM_freeN(state->normals);
}
- if (stitch_state->normals) {
- MEM_freeN(stitch_state->normals);
+ if (state->edges) {
+ MEM_freeN(state->edges);
}
- if (stitch_state->edges) {
- MEM_freeN(stitch_state->edges);
+ if (state->stitch_preview) {
+ stitch_preview_delete(state->stitch_preview);
}
- MEM_freeN(stitch_state);
+ if (state->edge_hash) {
+ BLI_ghash_free(state->edge_hash, NULL, NULL);
+ }
+ MEM_freeN(state);
}
}
+static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
+{
+ UvEdge *edges = state->edges;
+ int *map = state->map;
+ UvElementMap *element_map = state->element_map;
+ UvElement *first_element = element_map->buf;
+ int i;
+
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = edges + i;
+
+ if (edge->first)
+ continue;
+
+ /* only boundary edges can be stitched. Yes. Sorry about that :p */
+ if (edge->flag & STITCH_BOUNDARY) {
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ /* Now iterate through all faces and try to find edges sharing the same vertices */
+ UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)];
+ UvEdge *last_set = edge;
+ int elemindex2 = BM_elem_index_get(element2->l->v);
+
+ edge->first = edge;
+
+ for (; iter1; iter1 = iter1->next) {
+ UvElement *iter2 = NULL;
+
+ /* check to see if other vertex of edge belongs to same vertex as */
+ if (BM_elem_index_get(iter1->l->next->v) == elemindex2)
+ iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->next);
+ else if (BM_elem_index_get(iter1->l->prev->v) == elemindex2)
+ iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->prev);
+
+ if (iter2) {
+ int index1 = map[iter1 - first_element];
+ int index2 = map[iter2 - first_element];
+
+ /* make certain we do not have the same edge! */
+ if (state->uvs[index2] != element2 && state->uvs[index1] != element1) {
+ UvEdge edgetmp;
+ UvEdge *edge2;
+
+
+ /* make sure the indices are well behaved */
+ if (index1 < index2) {
+ edgetmp.uv1 = index1;
+ edgetmp.uv2 = index2;
+ }
+ else {
+ edgetmp.uv1 = index2;
+ edgetmp.uv2 = index1;
+ }
+
+ /* get the edge from the hash */
+ edge2 = BLI_ghash_lookup(edge_hash, &edgetmp);
+
+ /* here I am taking care of non manifold case, assuming more than two matching edges.
+ * I am not too sure we want this though */
+ last_set->next = edge2;
+ last_set = edge2;
+ /* set first, similarly to uv elements. Now we can iterate among common edges easily */
+ edge2->first = edge;
+ }
+ }
+ }
+ }
+ else {
+ /* so stitchability code works */
+ edge->first = edge;
+ }
+ }
+}
/* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
@@ -526,9 +681,6 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
- if (element_iter == element) {
- continue;
- }
if (stitch_check_uvs_stitchable(element, element_iter, state)) {
island_stitch_data[element_iter->island].stitchableCandidate = 1;
island_stitch_data[element->island].stitchableCandidate = 1;
@@ -538,6 +690,19 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I
}
}
+static void determine_uv_edge_stitchability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data)
+{
+ UvEdge *edge_iter = edge->first;
+
+ for (; edge_iter; edge_iter = edge_iter->next) {
+ if (stitch_check_edges_stitchable(edge, edge_iter, state)) {
+ island_stitch_data[edge_iter->element->island].stitchableCandidate = 1;
+ island_stitch_data[edge->element->island].stitchableCandidate = 1;
+ edge->flag |= STITCH_STITCHABLE_CANDIDATE;
+ }
+ }
+}
+
/* set preview buffer position of UV face in editface->tmp.l */
static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position)
@@ -555,7 +720,7 @@ static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer
/* setup face preview for all coincident uvs and their faces */
static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
PreviewPosition *preview_position) {
- StitchPreviewer *preview = uv_get_stitch_previewer();
+ StitchPreviewer *preview = state->stitch_preview;
/* static island does not change so returning immediately */
if (state->snap_islands && !state->midpoints && state->static_island == element->island)
@@ -566,17 +731,17 @@ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchSta
}
do {
- stitch_set_face_preview_buffer_position(element->face, preview, preview_position);
+ stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position);
element = element->next;
} while (element && !element->separate);
}
/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
-static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
+static void stitch_validate_uv_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
PreviewPosition *preview_position) {
UvElement *element_iter;
- StitchPreviewer *preview;
+ StitchPreviewer *preview = state->stitch_preview;
int vert_index;
BMLoop *l;
@@ -584,7 +749,6 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state,
vert_index = BM_elem_index_get(l->v);
- preview = uv_get_stitch_previewer();
element_iter = state->element_map->vert[vert_index];
for (; element_iter; element_iter = element_iter->next) {
@@ -608,6 +772,72 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state,
}
}
+
+static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data,
+ PreviewPosition *preview_position) {
+ UvEdge *edge_iter = edge->first;
+ StitchPreviewer *preview = state->stitch_preview;
+
+ for (; edge_iter; edge_iter = edge_iter->next) {
+ if (edge_iter == edge)
+ continue;
+ if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) {
+ if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) {
+ edge->flag |= STITCH_STITCHABLE;
+ preview->num_stitchable++;
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position);
+ return;
+ }
+ }
+ }
+
+ /* this can happen if the uvs to be stitched are not on a stitchable island */
+ if (!(edge->flag & STITCH_STITCHABLE)) {
+ preview->num_unstitchable++;
+ }
+}
+
+
+static void stitch_propagate_uv_final_position(UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene *scene)
+{
+ StitchPreviewer *preview = state->stitch_preview;
+
+ if (element->flag & STITCH_STITCHABLE) {
+ UvElement *element_iter = element;
+ /* propagate to coincident uvs */
+ do {
+ BMLoop *l;
+ MLoopUV *luv;
+
+ l = element_iter->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ element_iter->flag |= STITCH_PROCESSED;
+ /* either flush to preview or to the MTFace, if final */
+ if (final) {
+ copy_v2_v2(luv->uv, final_position[index].uv);
+
+ uvedit_uv_select_enable(state->em, scene, l, FALSE);
+ }
+ else {
+ int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position;
+ if (face_preview_pos != STITCH_NO_PREVIEW) {
+ copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
+ final_position[index].uv);
+ }
+ }
+
+ /* end of calculations, keep only the selection flag */
+ if ( (!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
+ element_iter->flag &= STITCH_SELECTED;
+ }
+
+ element_iter = element_iter->next;
+ } while (element_iter && !element_iter->separate);
+ }
+}
+
/* main processing function. It calculates preview and final positions. */
static int stitch_process_data(StitchState *state, Scene *scene, int final)
{
@@ -617,16 +847,17 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
int previous_island = state->static_island;
BMFace *efa;
BMIter iter;
- UVVertAverage *final_position;
+ UVVertAverage *final_position = NULL;
+
char stitch_midpoints = state->midpoints;
/* used to map uv indices to uvaverage indices for selection */
- unsigned int *uvfinal_map;
+ unsigned int *uvfinal_map = NULL;
/* per face preview position in preview buffer */
- PreviewPosition *preview_position;
+ PreviewPosition *preview_position = NULL;
/* cleanup previous preview */
- stitch_preview_delete();
- preview = stitch_preview_init();
+ stitch_preview_delete(state->stitch_preview);
+ preview = state->stitch_preview = stitch_preview_init();
if (preview == NULL)
return 0;
@@ -649,8 +880,14 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
*****************************************/
for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- determine_uv_stitchability(element, state, island_stitch_data);
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = (UvElement *)state->selection_stack[i];
+ determine_uv_stitchability(element, state, island_stitch_data);
+ }
+ else {
+ UvEdge *edge = (UvEdge *)state->selection_stack[i];
+ determine_uv_edge_stitchability(edge, state, island_stitch_data);
+ }
}
/* set static island to one that is added for preview */
@@ -664,14 +901,26 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
- element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
- stitch_validate_stichability(element, state, island_stitch_data, preview_position);
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = (UvElement *)state->selection_stack[i];
+ if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
+ element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
+ stitch_validate_uv_stichability(element, state, island_stitch_data, preview_position);
+ }
+ else {
+ /* add to preview for unstitchable */
+ preview->num_unstitchable++;
+ }
}
else {
- /* add to preview for unstitchable */
- preview->num_unstitchable++;
+ UvEdge *edge = (UvEdge *)state->selection_stack[i];
+ if (edge->flag & STITCH_STITCHABLE_CANDIDATE) {
+ edge->flag &= ~STITCH_STITCHABLE_CANDIDATE;
+ stitch_validate_edge_stichability(edge, state, island_stitch_data, preview_position);
+ }
+ else {
+ preview->num_unstitchable++;
+ }
}
}
@@ -686,7 +935,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
element = &state->element_map->buf[state->element_map->islandIndices[i]];
for (j = 0; j < numOfIslandUVs; j++, element++) {
- stitch_set_face_preview_buffer_position(element->face, preview, preview_position);
+ stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position);
}
}
}
@@ -701,11 +950,12 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
MLoopUV *luv;
unsigned int buffer_index = 0;
int stitchBufferIndex = 0, unstitchBufferIndex = 0;
+ int preview_size = (state->mode == STITCH_VERT) ? 2 : 4;
/* initialize the preview buffers */
preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev");
preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
- preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * 2, "stitch_preview_stichable_data");
- preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * 2, "stitch_preview_unstichable_data");
+ preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stichable_data");
+ preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstichable_data");
preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris");
@@ -715,7 +965,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
return 0;
}
- /* copy data from MTFaces to the preview display buffers */
+ /* copy data from MLoopUVs to the preview display buffers */
BM_ITER_MESH (efa, &iter, state->em->bm, BM_FACES_OF_MESH) {
/* just to test if face was added for processing. uvs of inselected vertices will return NULL */
UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
@@ -757,22 +1007,56 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/* fill the appropriate preview buffers */
- for (i = 0; i < state->total_separate_uvs; i++) {
- UvElement *element = (UvElement *)state->uvs[i];
- if (element->flag & STITCH_STITCHABLE) {
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (state->mode == STITCH_VERT) {
+ for (i = 0; i < state->total_separate_uvs; i++) {
+ UvElement *element = (UvElement *)state->uvs[i];
+ if (element->flag & STITCH_STITCHABLE) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
+ stitchBufferIndex++;
+ }
+ else if (element->flag & STITCH_SELECTED) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- stitchBufferIndex++;
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
+ unstitchBufferIndex++;
+ }
}
- else if (element->flag & STITCH_SELECTED) {
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ }
+ else {
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ if (edge->flag & STITCH_STITCHABLE) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
- unstitchBufferIndex++;
+ l = element2->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
+
+ stitchBufferIndex++;
+ BLI_assert(stitchBufferIndex <= preview->num_stitchable);
+ }
+ else if (edge->flag & STITCH_SELECTED) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
+
+ l = element2->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
+
+ unstitchBufferIndex++;
+ BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
+ }
}
}
}
@@ -781,51 +1065,111 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
* Here we calculate the final coordinates of the uvs *
******************************************************/
- final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
- uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
+ if (state->mode == STITCH_VERT) {
+ final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
+ uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
+ }
+ else {
+ final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average");
+ }
/* first pass, calculate final position for stitchable uvs of the static island */
for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE) {
- BMLoop *l;
- MLoopUV *luv;
- UvElement *element_iter;
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = state->selection_stack[i];
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (element->flag & STITCH_STITCHABLE) {
+ BMLoop *l;
+ MLoopUV *luv;
+ UvElement *element_iter;
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- uvfinal_map[element - state->element_map->buf] = i;
+ uvfinal_map[element - state->element_map->buf] = i;
- copy_v2_v2(final_position[i].uv, luv->uv);
- final_position[i].count = 1;
+ copy_v2_v2(final_position[i].uv, luv->uv);
+ final_position[i].count = 1;
- if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
- continue;
+ if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
+ continue;
+
+ element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
+
+ for ( ; element_iter; element_iter = element_iter->next) {
+ if (element_iter->separate) {
+ if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+ l = element_iter->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (stitch_midpoints) {
+ add_v2_v2(final_position[i].uv, luv->uv);
+ final_position[i].count++;
+ }
+ else if (element_iter->island == state->static_island) {
+ /* if multiple uvs on the static island exist,
+ * last checked remains. to disambiguate we need to limit or use
+ * edge stitch */
+ copy_v2_v2(final_position[i].uv, luv->uv);
+ }
+ }
+ }
+ }
+ }
+ if (stitch_midpoints) {
+ final_position[i].uv[0] /= final_position[i].count;
+ final_position[i].uv[1] /= final_position[i].count;
+ }
+ }
+ else {
+ UvEdge *edge = state->selection_stack[i];
- element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
+ if (edge->flag & STITCH_STITCHABLE) {
+ MLoopUV *luv2, *luv1;
+ BMLoop *l;
+ UvEdge *edge_iter;
+
+ l = state->uvs[edge->uv1]->l;
+ luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge->uv2]->l;
+ luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ final_position[edge->uv1].count = 1;
+ final_position[edge->uv2].count = 1;
+
+ state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE;
+ state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE;
+
+ if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints)
+ continue;
+
+ for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) {
+ if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) {
+ l = state->uvs[edge_iter->uv1]->l;
+ luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ l = state->uvs[edge_iter->uv2]->l;
+ luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- for ( ; element_iter; element_iter = element_iter->next) {
- if (element_iter->separate) {
- if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
- l = element_iter->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
if (stitch_midpoints) {
- add_v2_v2(final_position[i].uv, luv->uv);
- final_position[i].count++;
+ add_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ final_position[edge->uv1].count++;
+ add_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ final_position[edge->uv2].count++;
}
- else if (element_iter->island == state->static_island) {
- /* if multiple uvs on the static island exist,
- * last checked remains. to disambiguate we need to limit or use
- * edge stitch */
- copy_v2_v2(final_position[i].uv, luv->uv);
+ else if (edge_iter->element->island == state->static_island) {
+ copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
}
}
}
}
}
- if (stitch_midpoints) {
+ }
+
+ /* take mean position here. For edge case, this can't be done inside the loop for shared uvverts */
+ if (state->mode == STITCH_EDGE && stitch_midpoints) {
+ for (i = 0; i < state->total_separate_uvs; i++) {
final_position[i].uv[0] /= final_position[i].count;
final_position[i].uv[1] /= final_position[i].count;
}
@@ -833,89 +1177,110 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* second pass, calculate island rotation and translation before modifying any uvs */
if (state->snap_islands) {
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE) {
- BMLoop *l;
- MLoopUV *luv;
+ if (state->mode == STITCH_VERT) {
+ for (i = 0; i < state->selection_size; i++) {
+ UvElement *element = state->selection_stack[i];
- l = element->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (element->flag & STITCH_STITCHABLE) {
+ BMLoop *l;
+ MLoopUV *luv;
- /* accumulate each islands' translation from stitchable elements. it is important to do here
- * because in final pass MTFaces get modified and result is zero. */
- island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
- island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
- island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
- island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
- island_stitch_data[element->island].numOfElements++;
- }
- }
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- /* only calculate rotation when an edge has been fully selected */
- for (i = 0; i < state->total_boundary_edges; i++) {
- UvEdge *edge = state->edges + i;
- if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) {
- stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
- island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
+ /* accumulate each islands' translation from stitchable elements. it is important to do here
+ * because in final pass MTFaces get modified and result is zero. */
+ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
+ island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
+ island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
+ island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
+ island_stitch_data[element->island].numOfElements++;
+ }
}
- }
- /* clear seams of stitched edges */
- if (final && state->clear_seams) {
- for (i = 0; i < state->total_boundary_edges; i++) {
+ /* only calculate rotation when an edge has been fully selected */
+ for (i = 0; i < state->total_separate_edges; i++) {
UvEdge *edge = state->edges + i;
- if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
- BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
+ if ((edge->flag & STITCH_BOUNDARY) && (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) {
+ stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
+ island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
+ }
}
- }
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (!island_stitch_data[element->island].use_edge_rotation) {
- if (element->flag & STITCH_STITCHABLE) {
- stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+ /* clear seams of stitched edges */
+ if (final && state->clear_seams) {
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
+ BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
+ }
+ }
+
+ for (i = 0; i < state->selection_size; i++) {
+ UvElement *element = state->selection_stack[i];
+ if (!island_stitch_data[element->island].use_edge_rotation) {
+ if (element->flag & STITCH_STITCHABLE) {
+ stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+ }
}
}
}
+ else {
+ for (i = 0; i < state->total_separate_uvs; i++) {
+ UvElement *element = state->uvs[i];
- }
+ if (element->flag & STITCH_STITCHABLE) {
+ BMLoop *l;
+ MLoopUV *luv;
- /* third pass, propagate changes to coincident uvs */
- for (i = 0; i < state->selection_size; i++) {
- UvElement *element = state->selection_stack[i];
- if (element->flag & STITCH_STITCHABLE) {
- UvElement *element_iter = element;
- /* propagate to coincident uvs */
- do {
- BMLoop *l;
- MLoopUV *luv;
+ l = element->l;
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
- l = element_iter->l;
- luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ /* accumulate each islands' translation from stitchable elements. it is important to do here
+ * because in final pass MTFaces get modified and result is zero. */
+ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
+ island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
+ island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
+ island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
+ island_stitch_data[element->island].numOfElements++;
+ }
+ }
- element_iter->flag |= STITCH_PROCESSED;
- /* either flush to preview or to the MTFace, if final */
- if (final) {
- copy_v2_v2(luv->uv, final_position[i].uv);
+ for (i = 0; i < state->selection_size; i++) {
+ UvEdge *edge = state->selection_stack[i];
- uvedit_uv_select_enable(state->em, scene, l, FALSE);
+ if (edge->flag & STITCH_STITCHABLE) {
+ stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data);
+ island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
}
- else {
- int face_preview_pos = preview_position[BM_elem_index_get(element_iter->face)].data_position;
- if (face_preview_pos != STITCH_NO_PREVIEW) {
- copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
- final_position[i].uv);
+ }
+
+ /* clear seams of stitched edges */
+ if (final && state->clear_seams) {
+ for (i = 0; i < state->selection_size; i++) {
+ UvEdge *edge = state->selection_stack[i];
+ if (edge->flag & STITCH_STITCHABLE) {
+ BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
}
}
+ }
+ }
+ }
- /* end of calculations, keep only the selection flag */
- if ( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) {
- element_iter->flag &= STITCH_SELECTED;
- }
+ /* third pass, propagate changes to coincident uvs */
+ for (i = 0; i < state->selection_size; i++) {
+ if (state->mode == STITCH_VERT) {
+ UvElement *element = state->selection_stack[i];
- element_iter = element_iter->next;
- } while (element_iter && !element_iter->separate);
+ stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene);
+ }
+ else {
+ UvEdge *edge = state->selection_stack[i];
+
+ stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene);
+ stitch_propagate_uv_final_position (state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final, scene);
+
+ edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY);
}
}
@@ -925,7 +1290,9 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
MEM_freeN(final_position);
- MEM_freeN(uvfinal_map);
+ if (state->mode == STITCH_VERT) {
+ MEM_freeN(uvfinal_map);
+ }
MEM_freeN(island_stitch_data);
MEM_freeN(preview_position);
@@ -937,8 +1304,8 @@ static unsigned int uv_edge_hash(const void *key)
{
UvEdge *edge = (UvEdge *)key;
return
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
- BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
+ BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
+ BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
}
static int uv_edge_compare(const void *a, const void *b)
@@ -952,13 +1319,41 @@ static int uv_edge_compare(const void *a, const void *b)
return 1;
}
+/* select all common edges */
+static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_select)
+{
+ UvEdge *eiter;
+ UvEdge **selection_stack = (UvEdge **)state->selection_stack;
+
+ for (eiter = edge->first; eiter; eiter = eiter->next) {
+ if (eiter->flag & STITCH_SELECTED) {
+ int i;
+ if (always_select)
+ continue;
+
+ eiter->flag &= ~STITCH_SELECTED;
+ for (i = 0; i < state->selection_size; i++) {
+ if (selection_stack[i] == eiter) {
+ (state->selection_size)--;
+ selection_stack[i] = selection_stack[state->selection_size];
+ break;
+ }
+ }
+ }
+ else {
+ eiter->flag |= STITCH_SELECTED;
+ selection_stack[state->selection_size++] = eiter;
+ }
+ }
+}
+
/* Select all common uvs */
static void stitch_select_uv(UvElement *element, StitchState *state, int always_select)
{
BMLoop *l;
UvElement *element_iter;
- UvElement **selection_stack = state->selection_stack;
+ UvElement **selection_stack = (UvElement **)state->selection_stack;
l = element->l;
@@ -989,33 +1384,86 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_
}
}
-static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal)
+static void stitch_switch_selection_mode(StitchState *state)
+{
+ void **old_selection_stack = state->selection_stack;
+ int old_selection_size = state->selection_size;
+ state->selection_size = 0;
+
+ if (state->mode == STITCH_VERT) {
+ int i;
+ state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
+ "stitch_new_edge_selection_stack");
+
+ /* check if both elements of an edge are selected */
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ if ((element1->flag & STITCH_SELECTED) && (element2->flag & STITCH_SELECTED))
+ stitch_select_edge(edge, state, TRUE);
+ }
+
+ /* unselect selected uvelements */
+ for (i = 0; i < old_selection_size; i++) {
+ UvElement *element = old_selection_stack[i];
+
+ element->flag &= ~STITCH_SELECTED;
+ }
+ state->mode = STITCH_EDGE;
+ }
+ else {
+ int i;
+ state->selection_stack = MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack),
+ "stitch_new_vert_selection_stack");
+
+ for (i = 0; i < old_selection_size; i++) {
+ UvEdge *edge = old_selection_stack[i];
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ stitch_select_uv(element1, state, TRUE);
+ stitch_select_uv(element2, state, TRUE);
+
+ edge->flag &= ~STITCH_SELECTED;
+ }
+ state->mode = STITCH_VERT;
+ }
+ MEM_freeN(old_selection_stack);
+}
+
+static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
{
BMLoop *l1 = edge->element->l;
- BMLoop *l2 = l1->next;
MLoopUV *luv1, *luv2;
float tangent[2];
luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
- luv2 = CustomData_bmesh_get(&em->bm->ldata, l2->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV);
sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
+ tangent[1] /= aspect;
+
normal[0] = tangent[1];
normal[1] = -tangent[0];
normalize_v2(normal);
}
-static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg))
+static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
int i, index = 0;
float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
- StitchPreviewer *stitch_preview = uv_get_stitch_previewer();
+ StitchState *state = (StitchState *)arg;
+ StitchPreviewer *stitch_preview = state->stitch_preview;
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
+ glPointSize(pointsize * 2.0f);
+
glEnable(GL_BLEND);
UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
@@ -1031,35 +1479,68 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UN
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+ #if 0
+ glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
+ glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+ #endif
index += stitch_preview->uvs_per_polygon[i];
}
- glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
-#if 0
- UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3);
-#endif
glDisable(GL_BLEND);
/* draw vert preview */
- glPointSize(pointsize * 2.0f);
- UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
+ if (state->mode == STITCH_VERT) {
+ UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
+ glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
+
+ UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
+ glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
+ }
+ else {
+ UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
+ glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable);
- UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
+ glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable);
+ }
glPopClientAttrib();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPointSize(1.0);
+}
+
+static UvEdge *uv_edge_get (BMLoop *l, StitchState *state)
+{
+ UvEdge tmp_edge;
+
+ UvElement *element1 = ED_uv_element_get(state->element_map, l->f, l);
+ UvElement *element2 = ED_uv_element_get(state->element_map, l->f, l->next);
+
+ int uv1 = state->map[element1 - state->element_map->buf];
+ int uv2 = state->map[element2 - state->element_map->buf];
+
+ if (uv1 < uv2) {
+ tmp_edge.uv1 = uv1;
+ tmp_edge.uv2 = uv2;
+ }
+ else {
+ tmp_edge.uv1 = uv2;
+ tmp_edge.uv2 = uv1;
+ }
+
+ return BLI_ghash_lookup(state->edge_hash, &tmp_edge);
}
static int stitch_init(bContext *C, wmOperator *op)
{
/* for fast edge lookup... */
- GHash *edgeHash;
+ GHash *edge_hash;
/* ...and actual edge storage */
UvEdge *edges;
int total_edges;
@@ -1076,7 +1557,7 @@ static int stitch_init(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
ARegion *ar = CTX_wm_region(C);
-
+ float aspx, aspy;
Object *obedit = CTX_data_edit_object(C);
if (!ar)
@@ -1097,21 +1578,44 @@ static int stitch_init(bContext *C, wmOperator *op)
state->static_island = RNA_int_get(op->ptr, "static_island");
state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
- state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW);
+ if (RNA_struct_property_is_set(op->ptr, "mode")) {
+ state->mode = RNA_enum_get(op->ptr, "mode");
+ }
+ else {
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode & SCE_SELECT_VERTEX)
+ state->mode = STITCH_VERT;
+ else
+ state->mode = STITCH_EDGE;
+ }
+ else {
+ if (ts->uv_selectmode & UV_SELECT_VERTEX) {
+ state->mode = STITCH_VERT;
+ }
+ else {
+ state->mode = STITCH_EDGE;
+ }
+ }
+ }
+
+ state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW);
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
- state->element_map = EDBM_uv_element_map_create(state->em, 0, 1);
+ state->element_map = EDBM_uv_element_map_create(state->em, FALSE, TRUE);
}
else {
- state->element_map = EDBM_uv_element_map_create(state->em, 1, 1);
+ state->element_map = EDBM_uv_element_map_create(state->em, TRUE, TRUE);
}
if (!state->element_map) {
- stitch_state_delete(state);
+ state_delete(state);
return 0;
}
+ uvedit_get_aspect(scene, obedit, em, &aspx, &aspy);
+ state->aspect = aspx / aspy;
+
/* Entirely possible if redoing last operator that static island is bigger than total number of islands.
- * This ensures we get no hang in the island checking code in stitch_process_data. */
+ * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */
state->static_island %= state->element_map->totalIslands;
/* Count 'unique' uvs */
@@ -1121,22 +1625,21 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
+ /* explicitly set preview to NULL, to avoid deleting an invalid pointer on stitch_process_data */
+ state->stitch_preview = NULL;
/* Allocate the unique uv buffers */
state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs");
/* internal uvs need no normals but it is hard and slow to keep a map of
* normals only for boundary uvs, so allocating for all uvs */
state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals");
state->total_separate_uvs = counter;
- /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only
- * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */
- state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * counter, "uv_stitch_selection_stack");
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map");
/* Allocate the edge stack */
- edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
+ edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges");
- if (!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges) {
- stitch_state_delete(state);
+ if (!state->uvs || !map || !edge_hash || !all_edges) {
+ state_delete(state);
return 0;
}
@@ -1169,6 +1672,8 @@ static int stitch_init(bContext *C, wmOperator *op)
offset1 = map[itmp1];
offset2 = map[itmp2];
+ all_edges[counter].next = NULL;
+ all_edges[counter].first = NULL;
all_edges[counter].flag = 0;
all_edges[counter].element = element;
/* using an order policy, sort uvs according to address space. This avoids
@@ -1182,12 +1687,12 @@ static int stitch_init(bContext *C, wmOperator *op)
all_edges[counter].uv2 = offset1;
}
- if (BLI_ghash_haskey(edgeHash, &all_edges[counter])) {
- char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]);
- *flag = 0;
+ if (BLI_ghash_haskey(edge_hash, &all_edges[counter])) {
+ UvEdge *edge = BLI_ghash_lookup(edge_hash, &all_edges[counter]);
+ edge->flag = 0;
}
else {
- BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag));
+ BLI_ghash_insert(edge_hash, &all_edges[counter], &all_edges[counter]);
all_edges[counter].flag = STITCH_BOUNDARY;
}
counter++;
@@ -1195,55 +1700,56 @@ static int stitch_init(bContext *C, wmOperator *op)
}
- ghi = BLI_ghashIterator_new(edgeHash);
- total_edges = 0;
- /* fill the edges with data */
- for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
- UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
- if (edge->flag & STITCH_BOUNDARY) {
- total_edges++;
- }
- }
+ ghi = BLI_ghashIterator_new(edge_hash);
+ total_edges = BLI_ghash_size(edge_hash);
state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
- if (!ghi || !edges) {
- MEM_freeN(all_edges);
- stitch_state_delete(state);
+
+ /* I assume any system will be able to at least allocate an iterator :p */
+ if (!edges) {
+ BLI_ghashIterator_free(ghi);
+ state_delete(state);
return 0;
}
- state->total_boundary_edges = total_edges;
+ state->total_separate_edges = total_edges;
/* fill the edges with data */
- for (i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
- UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
- if (edge->flag & STITCH_BOUNDARY) {
- edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
- }
+ for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
}
/* cleanup temporary stuff */
BLI_ghashIterator_free(ghi);
MEM_freeN(all_edges);
- /* refill hash with new pointers to cleanup duplicates */
- BLI_ghash_free(edgeHash, NULL, NULL);
+ BLI_ghash_free(edge_hash, NULL, NULL);
+
+ /* refill an edge hash to create edge connnectivity data */
+ state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
+ for (i = 0; i < total_edges; i++) {
+ BLI_ghash_insert(edge_hash, edges + i, edges + i);
+ }
+ stitch_uv_edge_generate_linked_edges(edge_hash, state);
/***** calculate 2D normals for boundary uvs *****/
/* we use boundary edges to calculate 2D normals.
* to disambiguate the direction of the normal, we also need
* a point "inside" the island, that can be provided by
- * the opposite uv for a quad, or the next uv for a triangle. */
+ * the winding of the polygon (assuming counter-clockwise flow). */
for (i = 0; i < total_edges; i++) {
+ UvEdge *edge = edges + i;
float normal[2];
- stitch_calculate_edge_normal(em, edges + i, normal);
+ if (edge->flag & STITCH_BOUNDARY) {
+ stitch_calculate_edge_normal(em, edge, normal, state->aspect);
- add_v2_v2(state->normals + edges[i].uv1 * 2, normal);
- add_v2_v2(state->normals + edges[i].uv2 * 2, normal);
+ add_v2_v2(state->normals + edge->uv1 * 2, normal);
+ add_v2_v2(state->normals + edge->uv2 * 2, normal);
- normalize_v2(state->normals + edges[i].uv1 * 2);
- normalize_v2(state->normals + edges[i].uv2 * 2);
+ normalize_v2(state->normals + edge->uv1 * 2);
+ normalize_v2(state->normals + edge->uv2 * 2);
+ }
}
@@ -1255,31 +1761,89 @@ static int stitch_init(bContext *C, wmOperator *op)
if (RNA_struct_property_is_set(op->ptr, "selection")) {
int faceIndex, elementIndex;
UvElement *element;
+ enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
- EDBM_index_arrays_init(em, 0, 0, 1);
+ EDBM_index_arrays_ensure(em, BM_FACE);
- RNA_BEGIN (op->ptr, itemptr, "selection")
- {
- faceIndex = RNA_int_get(&itemptr, "face_index");
- elementIndex = RNA_int_get(&itemptr, "element_index");
- efa = EDBM_face_at_index(em, faceIndex);
- element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
- stitch_select_uv(element, state, 1);
+ if (stored_mode == STITCH_VERT) {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
+
+ RNA_BEGIN (op->ptr, itemptr, "selection")
+ {
+ faceIndex = RNA_int_get(&itemptr, "face_index");
+ elementIndex = RNA_int_get(&itemptr, "element_index");
+ efa = EDBM_face_at_index(em, faceIndex);
+ element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
+ stitch_select_uv(element, state, 1);
+ }
+ RNA_END;
}
- RNA_END;
+ else {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
+
+ RNA_BEGIN (op->ptr, itemptr, "selection")
+ {
+ UvEdge tmp_edge, *edge;
+ int uv1, uv2;
+ faceIndex = RNA_int_get(&itemptr, "face_index");
+ elementIndex = RNA_int_get(&itemptr, "element_index");
+ efa = EDBM_face_at_index(em, faceIndex);
+ element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
+ uv1 = map[element - state->element_map->buf];
+
+ element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len));
+ uv2 = map[element - state->element_map->buf];
+
+ if (uv1 < uv2) {
+ tmp_edge.uv1 = uv1;
+ tmp_edge.uv2 = uv2;
+ }
+ else {
+ tmp_edge.uv1 = uv2;
+ tmp_edge.uv2 = uv1;
+ }
+
+ edge = BLI_ghash_lookup(edge_hash, &tmp_edge);
- EDBM_index_arrays_free(em);
+ stitch_select_edge(edge, state, TRUE);
+ }
+ RNA_END;
+ }
+ /* if user has switched the operator mode after operation, we need to convert
+ * the stored format */
+ if (state->mode != stored_mode) {
+ state->mode = stored_mode;
+ stitch_switch_selection_mode(state);
+ }
/* Clear the selection */
RNA_collection_clear(op->ptr, "selection");
}
else {
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- if (uvedit_uv_select_test(em, scene, l)) {
- UvElement *element = ED_uv_element_get(state->element_map, efa, l);
- if (element) {
- stitch_select_uv(element, state, 1);
+ if (state->mode == STITCH_VERT) {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ if (uvedit_uv_select_test(em, scene, l)) {
+ UvElement *element = ED_uv_element_get(state->element_map, efa, l);
+ if (element) {
+ stitch_select_uv(element, state, 1);
+ }
+ }
+ }
+ }
+ }
+ else {
+ state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+ if (uvedit_edge_select_test(em, scene, l)) {
+ UvEdge *edge = uv_edge_get(l, state);
+ if (edge) {
+ stitch_select_edge(edge, state, TRUE);
+ }
}
}
}
@@ -1302,8 +1866,9 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
- if (!stitch_process_data(state, scene, 0)) {
- stitch_state_delete(state);
+ if (!stitch_process_data(state, scene, FALSE)) {
+
+ state_delete(state);
return 0;
}
@@ -1324,7 +1889,7 @@ static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
static void stitch_exit(bContext *C, wmOperator *op, int finished)
{
- StitchState *stitch_state;
+ StitchState *state;
Scene *scene;
SpaceImage *sima;
ScrArea *sa = CTX_wm_area(C);
@@ -1334,45 +1899,48 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
obedit = CTX_data_edit_object(C);
sima = CTX_wm_space_image(C);
- stitch_state = (StitchState *)op->customdata;
+ state = (StitchState *)op->customdata;
if (finished) {
int i;
- RNA_float_set(op->ptr, "limit", stitch_state->limit_dist);
- RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit);
- RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands);
- RNA_int_set(op->ptr, "static_island", stitch_state->static_island);
- RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints);
+ RNA_float_set(op->ptr, "limit", state->limit_dist);
+ RNA_boolean_set(op->ptr, "use_limit", state->use_limit);
+ RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands);
+ RNA_int_set(op->ptr, "static_island", state->static_island);
+ RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints);
+ RNA_enum_set(op->ptr, "mode", state->mode);
+ RNA_enum_set(op->ptr, "stored_mode", state->mode);
/* Store selection for re-execution of stitch */
- for (i = 0; i < stitch_state->selection_size; i++) {
+ for (i = 0; i < state->selection_size; i++) {
+ UvElement *element;
PointerRNA itemptr;
- UvElement *element = stitch_state->selection_stack[i];
-
+ if (state->mode == STITCH_VERT) {
+ element = state->selection_stack[i];
+ }
+ else {
+ element = ((UvEdge *)state->selection_stack[i])->element;
+ }
RNA_collection_add(op->ptr, "selection", &itemptr);
- RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face));
-
+ RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
RNA_int_set(&itemptr, "element_index", element->tfindex);
}
-
uvedit_live_unwrap_update(sima, scene, obedit);
}
if (sa)
ED_area_headerprint(sa, NULL);
- ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle);
+ ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- stitch_state_delete(stitch_state);
+ state_delete(state);
op->customdata = NULL;
-
- stitch_preview_delete();
}
@@ -1398,7 +1966,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
}
-static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state)
+static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *state)
{
/* add uv under mouse to processed uv's */
float co[2];
@@ -1407,42 +1975,53 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState
Image *ima = CTX_data_edit_image(C);
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
- uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit);
- if (hit.efa) {
- /* Add vertex to selection, deselect all common uv's of vert other
- * than selected and update the preview. This behavior was decided so that
- * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
+ if (state->mode == STITCH_VERT) {
+ uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit);
+
+ if (hit.efa) {
+ /* Add vertex to selection, deselect all common uv's of vert other
+ * than selected and update the preview. This behavior was decided so that
+ * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
- /* This works due to setting of tmp in find nearest uv vert */
- UvElement *element = ED_uv_element_get(stitch_state->element_map, hit.efa, hit.l);
- stitch_select_uv(element, stitch_state, 0);
+ /* This works due to setting of tmp in find nearest uv vert */
+ UvElement *element = ED_uv_element_get(state->element_map, hit.efa, hit.l);
+ stitch_select_uv(element, state, FALSE);
+ }
+ }
+ else {
+ uv_find_nearest_edge(scene, ima, state->em, co, &hit);
+
+ if (hit.efa) {
+ UvEdge *edge = uv_edge_get(hit.l, state);
+ stitch_select_edge(edge, state, FALSE);
+ }
}
}
static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
{
- StitchState *stitch_state;
+ StitchState *state;
Scene *scene = CTX_data_scene(C);
- stitch_state = (StitchState *)op->customdata;
+ state = (StitchState *)op->customdata;
switch (event->type) {
case MIDDLEMOUSE:
return OPERATOR_PASS_THROUGH;
- /* Cancel */
+ /* Cancel */
case ESCKEY:
return stitch_cancel(C, op);
case LEFTMOUSE:
if (event->shift && (U.flag & USER_LMOUSESELECT)) {
- if (event->val == KM_RELEASE) {
- stitch_select(C, scene, event, stitch_state);
+ if (event->val == KM_PRESS) {
+ stitch_select(C, scene, event, state);
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
}
@@ -1451,7 +2030,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
case PADENTER:
case RETKEY:
if (event->val == KM_PRESS) {
- if (stitch_process_data(stitch_state, scene, 1)) {
+ if (stitch_process_data(state, scene, TRUE)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -1462,12 +2041,12 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
else {
return OPERATOR_PASS_THROUGH;
}
- /* Increase limit */
+ /* Increase limit */
case PADPLUSKEY:
case WHEELUPMOUSE:
if (event->val == KM_PRESS && event->alt) {
- stitch_state->limit_dist += 0.01f;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->limit_dist += 0.01f;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1475,13 +2054,13 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
else {
return OPERATOR_PASS_THROUGH;
}
- /* Decrease limit */
+ /* Decrease limit */
case PADMINUS:
case WHEELDOWNMOUSE:
if (event->val == KM_PRESS && event->alt) {
- stitch_state->limit_dist -= 0.01f;
- stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->limit_dist -= 0.01f;
+ state->limit_dist = MAX2(0.01f, state->limit_dist);
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1490,11 +2069,11 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_PASS_THROUGH;
}
- /* Use Limit (Default off)*/
+ /* Use Limit (Default off)*/
case LKEY:
if (event->val == KM_PRESS) {
- stitch_state->use_limit = !stitch_state->use_limit;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->use_limit = !state->use_limit;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1503,10 +2082,10 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
case IKEY:
if (event->val == KM_PRESS) {
- stitch_state->static_island++;
- stitch_state->static_island %= stitch_state->element_map->totalIslands;
+ state->static_island++;
+ state->static_island %= state->element_map->totalIslands;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1515,33 +2094,33 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
case MKEY:
if (event->val == KM_PRESS) {
- stitch_state->midpoints = !stitch_state->midpoints;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->midpoints = !state->midpoints;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
}
break;
- /* Select geometry*/
+ /* Select geometry*/
case RIGHTMOUSE:
if (!event->shift) {
return stitch_cancel(C, op);
}
- if (event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)) {
- stitch_select(C, scene, event, stitch_state);
+ if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) {
+ stitch_select(C, scene, event, state);
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
}
return OPERATOR_RUNNING_MODAL;
- /* snap islands on/off */
+ /* snap islands on/off */
case SKEY:
if (event->val == KM_PRESS) {
- stitch_state->snap_islands = !stitch_state->snap_islands;
- if (!stitch_process_data(stitch_state, scene, 0)) {
+ state->snap_islands = !state->snap_islands;
+ if (!stitch_process_data(state, scene, FALSE)) {
return stitch_cancel(C, op);
}
break;
@@ -1550,12 +2129,23 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+ /* switch between edge/vertex mode */
+ case TABKEY:
+ if (event->val == KM_PRESS) {
+ stitch_switch_selection_mode(state);
+
+ if (!stitch_process_data(state, scene, FALSE)) {
+ return stitch_cancel(C, op);
+ }
+ }
+ break;
+
default:
return OPERATOR_RUNNING_MODAL;
}
/* if updated settings, renew feedback message */
- stitch_update_header(stitch_state, C);
+ stitch_update_header(state, C);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_RUNNING_MODAL;
}
@@ -1564,6 +2154,12 @@ void UV_OT_stitch(wmOperatorType *ot)
{
PropertyRNA *prop;
+ static EnumPropertyItem stitch_modes[] = {
+ {STITCH_VERT, "VERTEX", 0, "Vertex", ""},
+ {STITCH_EDGE, "EDGE", 0, "Edge", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
/* identifiers */
ot->name = "Stitch";
ot->description = "Stitch selected UV vertices by proximity";
@@ -1590,6 +2186,11 @@ void UV_OT_stitch(wmOperatorType *ot)
"UVs are stitched at midpoint instead of at static island");
RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams",
"Clear seams of stitched edges");
+ RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode",
+ "Use vertex or edge stitching");
+ prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
+ "Use vertex or edge stitching");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
/* Selection should not be editable or viewed in toolbar */
RNA_def_property_flag(prop, PROP_HIDDEN);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 1f3f219..90feaa7 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -87,6 +87,24 @@
#include "uvedit_intern.h"
#include "uvedit_parametrizer.h"
+static void modifier_unwrap_state(Object *obedit, Scene *scene, short *use_subsurf)
+{
+ ModifierData *md;
+ short subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+
+ md = obedit->modifiers.first;
+
+ /* subsurf will take the modifier settings only if modifier is first or right after mirror */
+ if (subsurf) {
+ if (md && md->type == eModifierType_Subsurf)
+ subsurf = TRUE;
+ else
+ subsurf = FALSE;
+ }
+
+ *use_subsurf = subsurf;
+}
+
static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
{
Main *bmain = CTX_data_main(C);
@@ -178,7 +196,7 @@ static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit)
return 0;
}
-static void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
+void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
{
int sloppy = TRUE;
int selected = FALSE;
@@ -220,7 +238,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
if (correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
@@ -379,6 +397,9 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
MEdge *edge;
int i;
+ /* pointers to modifier data for unwrap control */
+ ModifierData *md;
+ SubsurfModifierData *smd_real;
/* modifier initialization data, will control what type of subdivision will happen*/
SubsurfModifierData smd = {{0}};
/* Used to hold subsurfed Mesh */
@@ -402,15 +423,18 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
if (correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
}
/* number of subdivisions to perform */
- smd.levels = scene->toolsettings->uv_subsurf_level;
- smd.subdivType = ME_CC_SUBSURF;
+ md = ob->modifiers.first;
+ smd_real = (SubsurfModifierData *)md;
+
+ smd.levels = smd_real->levels;
+ smd.subdivType = smd_real->subdivType;
initialDerived = CDDM_from_editbmesh(em, FALSE, FALSE);
derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd,
@@ -434,7 +458,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map");
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
- EDBM_index_arrays_init(em, 0, 1, 1);
+ EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE);
/* map subsurfed faces to original editFaces */
for (i = 0; i < numOfFaces; i++)
@@ -445,12 +469,10 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
/* map subsurfed edges to original editEdges */
for (i = 0; i < numOfEdges; i++) {
/* not all edges correspond to an old edge */
- edgeMap[i] = (origEdgeIndices[i] != -1) ?
+ edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ?
EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL;
}
- EDBM_index_arrays_free(em);
-
/* Prepare and feed faces to the solver */
for (i = 0; i < numOfFaces; i++) {
ParamKey key, vkeys[4];
@@ -815,16 +837,18 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
BMEditMesh *em = BMEdit_FromObject(obedit);
short abf = scene->toolsettings->unwrapper == 0;
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
- short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+ short use_subsurf;
+
+ modifier_unwrap_state(obedit, scene, &use_subsurf);
if (!ED_uvedit_test(obedit)) {
return;
}
if (use_subsurf)
- liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, 0, 1);
+ liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, FALSE, TRUE);
else
- liveHandle = construct_param_handle(scene, obedit, em, 0, fillholes, 0, 1);
+ liveHandle = construct_param_handle(scene, obedit, em, FALSE, fillholes, FALSE, TRUE);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
}
@@ -871,16 +895,18 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit)
static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result,
Object *ob, BMEditMesh *em)
{
- BMFace *efa;
- BMLoop *l;
- BMIter iter, liter;
- float min[3], max[3], *cursx;
int around = (v3d) ? v3d->around : V3D_CENTER;
/* only operates on the edit object - this is all that's needed now */
switch (around) {
case V3D_CENTER: /* bounding box center */
+ {
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ float min[3], max[3];
+
INIT_MINMAX(min, max);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -892,22 +918,23 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result,
}
mid_v3_v3v3(result, min, max);
break;
-
+ }
case V3D_CURSOR: /* cursor center */
- cursx = give_cursor(scene, v3d);
+ {
+ const float *curs = give_cursor(scene, v3d);
/* shift to objects world */
- sub_v3_v3v3(result, cursx, ob->obmat[3]);
+ sub_v3_v3v3(result, curs, ob->obmat[3]);
break;
-
+ }
case V3D_LOCAL: /* object center */
case V3D_CENTROID: /* multiple objects centers, only one object here*/
default:
- result[0] = result[1] = result[2] = 0.0;
+ zero_v3(result);
break;
}
}
-static void uv_map_rotation_matrix(float result[][4], RegionView3D *rv3d, Object *ob,
+static void uv_map_rotation_matrix(float result[4][4], RegionView3D *rv3d, Object *ob,
float upangledeg, float sideangledeg, float radius)
{
float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
@@ -938,18 +965,18 @@ static void uv_map_rotation_matrix(float result[][4], RegionView3D *rv3d, Object
/* this is "kanonen gegen spatzen", a few plus minus 1 will do here */
/* i wanted to keep the reason here, so we're rotating*/
sideangle = (float)M_PI * (sideangledeg + 180.0f) / 180.0f;
- rotside[0][0] = (float)cos(sideangle);
- rotside[0][1] = -(float)sin(sideangle);
- rotside[1][0] = (float)sin(sideangle);
- rotside[1][1] = (float)cos(sideangle);
- rotside[2][2] = 1.0f;
+ rotside[0][0] = cosf(sideangle);
+ rotside[0][1] = -sinf(sideangle);
+ rotside[1][0] = sinf(sideangle);
+ rotside[1][1] = cosf(sideangle);
+ rotside[2][2] = 1.0f;
upangle = (float)M_PI * upangledeg / 180.0f;
- rotup[1][1] = (float)cos(upangle) / radius;
- rotup[1][2] = -(float)sin(upangle) / radius;
- rotup[2][1] = (float)sin(upangle) / radius;
- rotup[2][2] = (float)cos(upangle) / radius;
- rotup[0][0] = (float)1.0f / radius;
+ rotup[1][1] = cosf(upangle) / radius;
+ rotup[1][2] = -sinf(upangle) / radius;
+ rotup[2][1] = sinf(upangle) / radius;
+ rotup[2][2] = cosf(upangle) / radius;
+ rotup[0][0] = 1.0f / radius;
/* calculate transforms*/
mul_serie_m4(result, rotup, rotside, viewmatrix, rotobj, NULL, NULL, NULL, NULL);
@@ -1020,7 +1047,7 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
BMFace *efa;
float scale, aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
if (aspx == aspy)
return;
@@ -1139,12 +1166,14 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
const short fill_holes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
const short correct_aspect = !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT);
- const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF;
+ short use_subsurf;
+
+ modifier_unwrap_state(obedit, scene, &use_subsurf);
if (use_subsurf)
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
else
- handle = construct_param_handle(scene, obedit, em, 0, fill_holes, sel, correct_aspect);
+ handle = construct_param_handle(scene, obedit, em, FALSE, fill_holes, sel, correct_aspect);
param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
param_lscm_solve(handle);
@@ -1167,7 +1196,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data");
- int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level");
+ short use_subsurf_final;
float obsize[3];
short implicit = 0;
@@ -1197,8 +1226,6 @@ static int unwrap_exec(bContext *C, wmOperator *op)
else
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
- scene->toolsettings->uv_subsurf_level = subsurf_level;
-
if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES;
else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES;
@@ -1208,6 +1235,12 @@ static int unwrap_exec(bContext *C, wmOperator *op)
if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF;
else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF;
+ /* double up the check here but better keep ED_unwrap_lscm interface simple and not
+ * pass operator for warning append */
+ modifier_unwrap_state(obedit, scene, &use_subsurf_final);
+ if (use_subsurf != use_subsurf_final)
+ BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap");
+
/* execute unwrap */
ED_unwrap_lscm(scene, obedit, TRUE);
@@ -1242,10 +1275,8 @@ void UV_OT_unwrap(wmOperatorType *ot)
"Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry");
RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect",
"Map UVs taking image aspect ratio into account");
- RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data",
+ RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier",
"Map UVs taking vertex position after subsurf into account");
- RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target",
- "Number of times to subdivide before calculating UVs", 1, 6);
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
@@ -1413,8 +1444,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
BMLoop *l;
BMIter liter;
MLoopUV *luv;
- float **uvs = NULL;
- BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__);
+ float **uvs = BLI_array_alloca(uvs, efa->len);
float dx;
int i, mi;
@@ -1436,8 +1466,6 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
if (dx > 0.5f) uvs[i][0] += 1.0f;
}
}
-
- BLI_array_fixedstack_free(uvs);
}
static int sphere_project_exec(bContext *C, wmOperator *op)
@@ -1535,7 +1563,6 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
uv_map_transform(C, op, center, rotmat);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
@@ -1545,6 +1572,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
uv_cylinder_project(luv->uv, l->v->co, center, rotmat);
}
+ tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
uv_map_mirror(em, efa, tf);
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 9ce42d9..6abc417 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -28,6 +28,7 @@ set(INC
../blenkernel
../blenlib
../blenloader
+ ../bmesh
../imbuf
../makesdna
../makesrna
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 36fbd81..9f6f805 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -39,12 +39,15 @@
#define DEBUG_VBO(X)
#endif
+struct BMesh;
struct CCGElem;
struct CCGKey;
struct CustomData;
struct DMFlagMat;
struct DerivedMesh;
+struct GHash;
struct GPUVertPointLink;
+struct PBVH;
typedef struct GPUBuffer {
int size; /* in bytes */
@@ -168,12 +171,21 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
unsigned int **grid_hidden, int gridsize);
+GPU_Buffers *GPU_build_bmesh_buffers(int smooth_shading);
+
+void GPU_update_bmesh_buffers(GPU_Buffers *buffers,
+ struct BMesh *bm,
+ struct GHash *bm_faces,
+ struct GHash *bm_unique_verts,
+ struct GHash *bm_other_verts);
+
void GPU_update_grid_buffers(GPU_Buffers *buffers, struct CCGElem **grids,
const struct DMFlagMat *grid_flag_mats,
int *grid_indices, int totgrid, const struct CCGKey *key,
int show_diffuse_color);
-void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial);
+void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial,
+ int wireframe);
int GPU_buffers_diffuse_changed(GPU_Buffers *buffers, int show_diffuse_color);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index b26c255..974865d 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -93,7 +93,7 @@ int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp);
int GPU_default_lights(void);
int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
- int lay, float viewmat[][4], int ortho);
+ int lay, float viewmat[4][4], int ortho);
/* Text render
* - based on moving uv coordinates */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index c46230d..2079165 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -127,7 +127,7 @@ void GPU_material_free(struct Material *ma);
void GPU_materials_free(void);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap);
-void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale);
+void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material);
@@ -232,10 +232,10 @@ void GPU_lamp_free(struct Object *ob);
int GPU_lamp_has_shadow_buffer(GPULamp *lamp);
void GPU_lamp_update_buffer_mats(GPULamp *lamp);
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]);
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]);
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]);
void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy);
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2);
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index 9b8a86e..f7db3df 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
@@ -7,7 +33,7 @@ sources += env.Glob('shaders/*.c')
defs = [ 'GLEW_STATIC' ]
incs = '../blenlib ../blenkernel ../makesdna ../makesrna ../include ../blenloader ../nodes ../nodes/intern'
-incs += ' #/extern/glew/include #intern/guardedalloc #intern/smoke/extern ../imbuf .'
+incs += ' #/extern/glew/include #intern/guardedalloc #intern/smoke/extern ../imbuf ../bmesh .'
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 6e475ac..5f9f68e 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -45,6 +45,7 @@
#include "BLI_threads.h"
#include "DNA_meshdata_types.h"
+#include "DNA_material_types.h"
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
@@ -56,6 +57,8 @@
#include "GPU_buffers.h"
#include "GPU_draw.h"
+#include "bmesh.h"
+
typedef enum {
GPU_BUFFER_VERTEX_STATE = 1,
GPU_BUFFER_NORMAL_STATE = 2,
@@ -66,8 +69,8 @@ typedef enum {
#define MAX_GPU_ATTRIB_DATA 32
-/* material number is an 16-bit short and the range of short is from -16383 to 16383 (assume material number is non-negative) */
-#define MAX_MATERIALS 16384
+/* material number is an 16-bit signed short and the range (assume material number is non-negative) */
+#define MAX_MATERIALS MAXMAT
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
static int useVBOs = -1;
@@ -1268,6 +1271,8 @@ struct GPU_Buffers {
int totgrid;
int has_hidden;
+ int use_bmesh;
+
unsigned int tot_tri, tot_quad;
/* The PBVH ensures that either all faces in the node are
@@ -1861,6 +1866,254 @@ GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
#undef FILL_QUAD_BUFFER
+/* Output a BMVert into a VertexBufferFormat array
+ *
+ * The vertex is skipped if hidden, otherwise the output goes into
+ * index '*v_index' in the 'vert_data' array and '*v_index' is
+ * incremented.
+ */
+static void gpu_bmesh_vert_to_buffer_copy(BMVert *v, BMesh *bm,
+ VertexBufferFormat *vert_data,
+ int *v_index,
+ const float fno[3],
+ const float *fmask)
+{
+ VertexBufferFormat *vd = &vert_data[*v_index];
+ float *mask;
+
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ /* TODO: should use material color */
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+ /* Set coord, normal, and mask */
+ copy_v3_v3(vd->co, v->co);
+ normal_float_to_short_v3(vd->no, fno ? fno : v->no);
+ mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
+ gpu_color_from_mask_copy(fmask ? *fmask : *mask,
+ diffuse_color,
+ vd->color);
+
+
+ /* Assign index for use in the triangle index buffer */
+ BM_elem_index_set(v, (*v_index)); /* set_dirty! */
+
+ (*v_index)++;
+ }
+}
+
+/* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
+static int gpu_bmesh_vert_visible_count(GHash *bm_unique_verts,
+ GHash *bm_other_verts)
+{
+ GHashIterator gh_iter;
+ int totvert = 0;
+
+ GHASH_ITER (gh_iter, bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ totvert++;
+ }
+ GHASH_ITER (gh_iter, bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ totvert++;
+ }
+
+ return totvert;
+}
+
+/* Return TRUE if all vertices in the face are visible, FALSE otherwise */
+static int gpu_bmesh_face_visible(BMFace *f)
+{
+ BMIter bm_iter;
+ BMVert *v;
+
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ if (BM_elem_flag_test(v, BM_ELEM_HIDDEN))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Return the total number of visible faces */
+static int gpu_bmesh_face_visible_count(GHash *bm_faces)
+{
+ GHashIterator gh_iter;
+ int totface = 0;
+
+ GHASH_ITER (gh_iter, bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ if (gpu_bmesh_face_visible(f))
+ totface++;
+ }
+
+ return totface;
+}
+
+/* Creates a vertex buffer (coordinate, normal, color) and, if smooth
+ shading, an element index buffer. */
+void GPU_update_bmesh_buffers(GPU_Buffers *buffers,
+ BMesh *bm,
+ GHash *bm_faces,
+ GHash *bm_unique_verts,
+ GHash *bm_other_verts)
+{
+ VertexBufferFormat *vert_data;
+ void *tri_data;
+ int tottri, totvert, maxvert = 0;
+
+ if (!buffers->vert_buf || (buffers->smooth && !buffers->index_buf))
+ return;
+
+ /* Count visible triangles */
+ tottri = gpu_bmesh_face_visible_count(bm_faces);
+
+ if (buffers->smooth) {
+ /* Count visible vertices */
+ totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
+ }
+ else
+ totvert = tottri * 3;
+
+ /* Initialize vertex buffer */
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(VertexBufferFormat) * totvert,
+ NULL, GL_STATIC_DRAW_ARB);
+
+ /* Fill vertex buffer */
+ vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ if (vert_data) {
+ GHashIterator gh_iter;
+ int v_index = 0;
+
+ if (buffers->smooth) {
+ /* Vertices get an index assigned for use in the triangle
+ index buffer */
+ bm->elem_index_dirty |= BM_VERT;
+
+ GHASH_ITER (gh_iter, bm_unique_verts) {
+ gpu_bmesh_vert_to_buffer_copy(BLI_ghashIterator_getKey(&gh_iter),
+ bm, vert_data, &v_index, NULL, NULL);
+ }
+
+ GHASH_ITER (gh_iter, bm_other_verts) {
+ gpu_bmesh_vert_to_buffer_copy(BLI_ghashIterator_getKey(&gh_iter),
+ bm, vert_data, &v_index, NULL, NULL);
+ }
+
+ maxvert = v_index;
+ }
+ else {
+ GHASH_ITER (gh_iter, bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ BLI_assert(f->len == 3);
+
+ if (gpu_bmesh_face_visible(f)) {
+ BMVert *v[3];
+ float fmask = 0;
+ int i;
+
+ BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3);
+
+ /* Average mask value */
+ for (i = 0; i < 3; i++) {
+ fmask += *((float*)CustomData_bmesh_get(&bm->vdata,
+ v[i]->head.data,
+ CD_PAINT_MASK));
+ }
+ fmask /= 3.0f;
+
+ for (i = 0; i < 3; i++) {
+ gpu_bmesh_vert_to_buffer_copy(v[i], bm, vert_data,
+ &v_index, f->no, &fmask);
+ }
+ }
+ }
+
+ buffers->tot_tri = tottri;
+ }
+
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+ }
+ else {
+ /* Memory map failed */
+ glDeleteBuffersARB(1, &buffers->vert_buf);
+ buffers->vert_buf = 0;
+ return;
+ }
+
+ if (buffers->smooth) {
+ const int use_short = (maxvert < USHRT_MAX);
+
+ /* Initialize triangle index buffer */
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ (use_short ?
+ sizeof(unsigned short) :
+ sizeof(unsigned int)) * 3 * tottri,
+ NULL, GL_STATIC_DRAW_ARB);
+
+ /* Fill triangle index buffer */
+ tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ if (tri_data) {
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, bm_faces) {
+ BMIter bm_iter;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMVert *v;
+
+ if (gpu_bmesh_face_visible(f)) {
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ if (use_short) {
+ unsigned short *elem = tri_data;
+ (*elem) = BM_elem_index_get(v);
+ elem++;
+ tri_data = elem;
+ }
+ else {
+ unsigned int *elem = tri_data;
+ (*elem) = BM_elem_index_get(v);
+ elem++;
+ tri_data = elem;
+ }
+ }
+ }
+ }
+
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+
+ buffers->tot_tri = tottri;
+ buffers->index_type = (use_short ?
+ GL_UNSIGNED_SHORT :
+ GL_UNSIGNED_INT);
+ }
+ else {
+ /* Memory map failed */
+ glDeleteBuffersARB(1, &buffers->index_buf);
+ buffers->index_buf = 0;
+ }
+ }
+}
+
+GPU_Buffers *GPU_build_bmesh_buffers(int smooth_shading)
+{
+ GPU_Buffers *buffers;
+
+ buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers");
+ if (smooth_shading)
+ glGenBuffersARB(1, &buffers->index_buf);
+ glGenBuffersARB(1, &buffers->vert_buf);
+ buffers->use_bmesh = TRUE;
+ buffers->smooth = smooth_shading;
+
+ return buffers;
+}
+
static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers)
{
const MVert *mvert = buffers->mvert;
@@ -2059,7 +2312,8 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
}
}
-void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
+void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial,
+ int wireframe)
{
if (buffers->totface) {
const MFace *f = &buffers->mface[buffers->face_indices[0]];
@@ -2076,14 +2330,19 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
if (buffers->vert_buf) {
glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- gpu_colors_enable(VBO_ENABLED);
+ if (!wireframe) {
+ glEnableClientState(GL_NORMAL_ARRAY);
+ gpu_colors_enable(VBO_ENABLED);
+ }
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
if (buffers->index_buf)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ if (wireframe)
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
if (buffers->tot_quad) {
char *offset = 0;
int i, last = buffers->has_hidden ? 1 : buffers->totgrid;
@@ -2116,13 +2375,18 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
glDrawArrays(GL_TRIANGLES, 0, totelem);
}
+ if (wireframe)
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
if (buffers->index_buf)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- gpu_colors_disable(VBO_ENABLED);
+ if (!wireframe) {
+ glDisableClientState(GL_NORMAL_ARRAY);
+ gpu_colors_disable(VBO_ENABLED);
+ }
}
/* fallbacks if we are out of memory or VBO is disabled */
else if (buffers->totface) {
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 360d8de..254899e 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -92,7 +92,7 @@ void GPU_render_text(MTFace *tface, int mode,
float *v1, float *v2, float *v3, float *v4, int glattrib)
{
if ((mode & GEMAT_TEXT) && (textlen>0) && tface->tpage) {
- Image* ima = (Image*)tface->tpage;
+ Image* ima = (Image *)tface->tpage;
int index, character;
float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
float advance_tab;
@@ -101,9 +101,9 @@ void GPU_render_text(MTFace *tface, int mode,
float line_start= 0.0f, line_height;
if (v4)
- line_height= MAX4(v1[1], v2[1], v3[1], v4[2]) - MIN4(v1[1], v2[1], v3[1], v4[2]);
+ line_height = max_ffff(v1[1], v2[1], v3[1], v4[2]) - min_ffff(v1[1], v2[1], v3[1], v4[2]);
else
- line_height= MAX3(v1[1], v2[1], v3[1]) - MIN3(v1[1], v2[1], v3[1]);
+ line_height = max_fff(v1[1], v2[1], v3[1]) - min_fff(v1[1], v2[1], v3[1]);
line_height *= 1.2f; /* could be an option? */
/* end multiline */
@@ -556,8 +556,9 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (do_color_management) {
srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
- ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, 0,
+ ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y);
frect= srgb_frect + texwinsy*ibuf->x + texwinsx;
@@ -581,8 +582,9 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (do_color_management) {
frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor");
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
- ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, 0,
+ ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y);
}
@@ -768,11 +770,14 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
return FALSE;
}
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ if (GLEW_EXT_texture_filter_anisotropic)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
+
blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16;
for (i=0; i<ibuf->dds_data.nummipmaps && (width||height); ++i) {
if (width == 0)
@@ -810,7 +815,7 @@ void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x,
glBindTexture(GL_TEXTURE_2D, *bind);
if (GPU_upload_dxt_texture(ibuf) == 0) {
- glDeleteTextures(1, (GLuint*)bind);
+ glDeleteTextures(1, (GLuint *)bind);
GPU_create_gl_tex(bind, pix, NULL, x, y, mipmap, 0, ima);
}
#endif
@@ -1612,7 +1617,7 @@ int GPU_default_lights(void)
return count;
}
-int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho)
+int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][4], int ortho)
{
Base *base;
Lamp *la;
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 7a0ac29..bc859d0 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -134,8 +134,8 @@ void GPU_extensions_init(void)
glGetIntegerv(GL_BLUE_BITS, &b);
GG.colordepth = r+g+b; /* assumes same depth for RGB */
- vendor = (const char*)glGetString(GL_VENDOR);
- renderer = (const char*)glGetString(GL_RENDERER);
+ vendor = (const char *)glGetString(GL_VENDOR);
+ renderer = (const char *)glGetString(GL_RENDERER);
if (strstr(vendor, "ATI")) {
GG.device = GPU_DEVICE_ATI;
@@ -916,7 +916,7 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object);
GPU_shader_bind(blur_shader);
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float*)scaleh);
+ GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scaleh);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex));
@@ -942,7 +942,7 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex));
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float*)scalev);
+ GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scalev);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
GPU_texture_bind(blurtex, 0);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 9c48f74..a2fc1eb 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -282,7 +282,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
}
}
-void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale)
+void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale)
{
if (material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass);
@@ -1035,8 +1035,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, FALSE), &tin, &trgb);
rgbnor= TEX_RGB;
- if (tex->imaflag & TEX_USEALPHA)
- talpha= 1;
+ talpha= 1;
}
else {
continue;
@@ -1526,7 +1525,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
ntreeGPUMaterialNodes(ma->nodetree, mat);
}
else {
- if(BKE_scene_use_new_shading_nodes(scene)) {
+ if (BKE_scene_use_new_shading_nodes(scene)) {
/* create simple diffuse material instead of nodes */
outlink = gpu_material_diffuse_bsdf(mat, ma);
}
@@ -1572,7 +1571,7 @@ void GPU_materials_free(void)
/* Lamps and shadow buffers */
-void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4])
+void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
{
float mat[4][4];
@@ -1854,7 +1853,7 @@ void GPU_lamp_update_buffer_mats(GPULamp *lamp)
mult_m4_m4m4(lamp->persmat, rangemat, persmat);
}
-void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
{
GPU_lamp_update_buffer_mats(lamp);
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 9a238e9..e89be91 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -811,7 +811,7 @@ void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 inc
float facm;
fact *= facg;
- facm = 1.0-facg;
+ facm = 1.0-fact;
incol = (facm + fact*texcol)*outcol;
}
@@ -821,7 +821,7 @@ void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3
float facm;
fact *= facg;
- facm = 1.0-facg;
+ facm = 1.0-fact;
incol = vec3(1.0) - (vec3(facm) + fact*(vec3(1.0) - texcol))*(vec3(1.0) - outcol);
}
@@ -831,7 +831,7 @@ void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3
float facm;
fact *= facg;
- facm = 1.0-facg;
+ facm = 1.0-fact;
if(outcol.r < 0.5)
incol.r = outcol.r*(facm + 2.0*fact*texcol.r);
@@ -888,11 +888,11 @@ void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 in
fact *= facg;
facm = 1.0-fact;
- col = fact*texcol.r;
+ col= texcol.r + ((1.0 -texcol.r)*facm);
if(col < outcol.r) incol.r = col; else incol.r = outcol.r;
- col = fact*texcol.g;
+ col= texcol.g + ((1.0 -texcol.g)*facm);
if(col < outcol.g) incol.g = col; else incol.g = outcol.g;
- col = fact*texcol.b;
+ col= texcol.b + ((1.0 -texcol.b)*facm);
if(col < outcol.b) incol.b = col; else incol.b = outcol.b;
}
@@ -901,7 +901,6 @@ void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 i
float facm, col;
fact *= facg;
- facm = 1.0-fact;
col = fact*texcol.r;
if(col > outcol.r) incol.r = col; else incol.r = outcol.r;
diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript
index 97b1cf1..0d201cb 100644
--- a/source/blender/ikplugin/SConscript
+++ b/source/blender/ikplugin/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
defs = []
sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp')
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index ca81f4c..67f0694 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -206,7 +206,7 @@ static void make_dmats(bPoseChannel *pchan)
/* applies IK matrix to pchan, IK is done separated */
/* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */
/* to make this work, the diffmats have to be precalculated! Stored in chan_mat */
-static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = to detect if this is first bone
+static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr = to detect if this is first bone
{
float vec[3], ikmat[4][4];
@@ -372,7 +372,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
* strictly speaking, it is a posechannel)
*/
- get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+ BKE_get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
/* and set and transform goal */
mult_m4_m4m4(goal, goalinv, rootmat);
@@ -383,7 +383,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* same for pole vector target */
if (data->poletar) {
- get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+ BKE_get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
if (data->flag & CONSTRAINT_IK_SETANGLE) {
/* don't solve IK when we are setting the pole angle */
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 903080d..e1ef7d9 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -370,7 +370,7 @@ static int initialize_chain(Object *ob, bPoseChannel *pchan_tip, bConstraint *co
static bool is_cartesian_constraint(bConstraint *con)
{
- //bKinematicConstraint* data=(bKinematicConstraint*)con->data;
+ //bKinematicConstraint* data=(bKinematicConstraint *)con->data;
return true;
}
@@ -551,7 +551,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram
bConstraint *constraint = (bConstraint *)target->blenderConstraint;
float tarmat[4][4];
- get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
+ BKE_get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
// rootmat contains the target pose in world coordinate
// if enforce is != 1.0, blend the target position with the end effector position
@@ -620,7 +620,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame&
IK_Channel &rootchan = ikscene->channels[0];
// get polar target matrix in world space
- get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
+ BKE_get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
// convert to armature space
mult_m4_m4m4(polemat, imat, mat);
// get the target in world space (was computed before as target object are defined before base object)
@@ -864,7 +864,7 @@ static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintV
}
// build array of joint corresponding to IK chain
-static int convert_channels(IK_Scene *ikscene, PoseTree *tree)
+static int convert_channels(IK_Scene *ikscene, PoseTree *tree, float ctime)
{
IK_Channel *ikchan;
bPoseChannel *pchan;
@@ -877,6 +877,14 @@ static int convert_channels(IK_Scene *ikscene, PoseTree *tree)
ikchan->parent = (a > 0) ? tree->parent[a] : -1;
ikchan->owner = ikscene->blArmature;
+ // the constraint and channels must be applied before we build the iTaSC scene,
+ // this is because some of the pose data (e.g. pose head) don't have corresponding
+ // joint angles and can't be applied to the iTaSC armature dynamically
+ if (!(pchan->flag & POSE_DONE))
+ BKE_pose_where_is_bone(ikscene->blscene, ikscene->blArmature, pchan, ctime, 1);
+ // tell blender that this channel was controlled by IK, it's cleared on each BKE_pose_where_is()
+ pchan->flag |= (POSE_DONE | POSE_CHAIN);
+
/* set DoF flag */
flag = 0;
if (!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP) &&
@@ -1049,7 +1057,7 @@ static void BKE_pose_rest(IK_Scene *ikscene)
}
}
-static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
+static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime)
{
PoseTree *tree = (PoseTree *)pchan->iktree.first;
PoseTarget *target;
@@ -1068,6 +1076,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
float length;
bool ret = true, ingame;
double *rot;
+ float start[3];
if (tree->totchannel == 0)
return NULL;
@@ -1126,7 +1135,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
std::vector<double> weights;
double weight[3];
// build the array of joints corresponding to the IK chain
- convert_channels(ikscene, tree);
+ convert_channels(ikscene, tree, ctime);
if (ingame) {
// in the GE, set the initial joint angle to match the current pose
// this will update the jointArray in ikscene
@@ -1137,17 +1146,37 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
BKE_pose_rest(ikscene);
}
rot = ikscene->jointArray(0);
+
for (a = 0, ikchan = ikscene->channels; a < tree->totchannel; ++a, ++ikchan) {
pchan = ikchan->pchan;
bone = pchan->bone;
KDL::Frame tip(iTaSC::F_identity);
+ // compute the position and rotation of the head from previous segment
Vector3 *fl = bone->bone_mat;
KDL::Rotation brot(
fl[0][0], fl[1][0], fl[2][0],
fl[0][1], fl[1][1], fl[2][1],
fl[0][2], fl[1][2], fl[2][2]);
- KDL::Vector bpos(bone->head[0], bone->head[1], bone->head[2]);
+ // if the bone is disconnected, the head is movable in pose mode
+ // take that into account by using pose matrix instead of bone
+ // Note that pose is expressed in armature space, convert to previous bone space
+ {
+ float R_parmat[3][3];
+ float iR_parmat[3][3];
+ if (pchan->parent)
+ copy_m3_m4(R_parmat, pchan->parent->pose_mat);
+ else
+ unit_m3(R_parmat);
+ if (pchan->parent)
+ sub_v3_v3v3(start, pchan->pose_head, pchan->parent->pose_tail);
+ else
+ start[0] = start[1] = start[2] = 0.0f;
+ invert_m3_m3(iR_parmat, R_parmat);
+ normalize_m3(iR_parmat);
+ mul_m3_v3(iR_parmat, start);
+ }
+ KDL::Vector bpos(start[0], start[1], start[2]);
bpos *= ikscene->blScale;
KDL::Frame head(brot, bpos);
@@ -1155,7 +1184,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
length = bone->length * ikscene->blScale;
parent = (a > 0) ? ikscene->channels[tree->parent[a]].tail : root;
// first the fixed segment to the bone head
- if (head.p.Norm() > KDL::epsilon || head.M.GetRot().Norm() > KDL::epsilon) {
+ if (!(ikchan->pchan->bone->flag & BONE_CONNECTED) || head.M.GetRot().Norm() > KDL::epsilon) {
joint = bone->name;
joint += ":H";
ret = arm->addSegment(joint, parent, KDL::Joint::None, 0.0, head);
@@ -1497,7 +1526,7 @@ static IK_Scene *convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
return ikscene;
}
-static void create_scene(Scene *scene, Object *ob)
+static void create_scene(Scene *scene, Object *ob, float ctime)
{
bPoseChannel *pchan;
@@ -1508,7 +1537,7 @@ static void create_scene(Scene *scene, Object *ob)
if (tree) {
IK_Data *ikdata = get_ikdata(ob->pose);
// convert tree in iTaSC::Scene
- IK_Scene *ikscene = convert_tree(scene, ob, pchan);
+ IK_Scene *ikscene = convert_tree(scene, ob, pchan, ctime);
if (ikscene) {
ikscene->next = ikdata->first;
ikdata->first = ikscene;
@@ -1732,15 +1761,21 @@ void itasc_initialize_tree(struct Scene *scene, Object *ob, float ctime)
count += initialize_scene(ob, pchan);
}
// if at least one tree, create the scenes from the PoseTree stored in the channels
- if (count)
- create_scene(scene, ob);
- itasc_update_param(ob->pose);
+ // postpone until execute_tree: this way the pose constraint are included
+ //if (count)
+ // create_scene(scene, ob, ctime);
+ //itasc_update_param(ob->pose);
// make sure we don't rebuilt until the user changes something important
ob->pose->flag &= ~POSE_WAS_REBUILT;
}
void itasc_execute_tree(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime)
{
+ if (!ob->pose->ikdata) {
+ // IK tree not yet created, no it now
+ create_scene(scene, ob, ctime);
+ itasc_update_param(ob->pose);
+ }
if (ob->pose->ikdata) {
IK_Data *ikdata = (IK_Data *)ob->pose->ikdata;
bItasc *ikparam = (bItasc *) ob->pose->ikparam;
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 0653956..1e33f8d 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -138,6 +138,7 @@ struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const str
const struct ColorManagedDisplaySettings *display_settings);
struct ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace);
void IMB_colormanagement_processor_apply_v4(struct ColormanageProcessor *cm_processor, float pixel[4]);
+void IMB_colormanagement_processor_apply_v4_predivide(struct ColormanageProcessor *cm_processor, float pixel[4]);
void IMB_colormanagement_processor_apply_v3(struct ColormanageProcessor *cm_processor, float pixel[3]);
void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_processor, float *buffer, int width, int height,
int channels, int predivide);
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index d0ac71a..a19433d 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -373,9 +373,6 @@ void IMB_rect_from_float(struct ImBuf *ibuf);
* Changed part will be stored in buffer. This is expected to be used for texture painting updates */
void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data);
void IMB_float_from_rect(struct ImBuf *ibuf);
-void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
-/* note, check that the conversion exists, only some are supported */
-float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
void IMB_color_to_bw(struct ImBuf *ibuf);
void IMB_saturation(struct ImBuf *ibuf, float sat);
@@ -393,6 +390,8 @@ void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect
int profile_to, int profile_from, int predivide,
int width, int height, int stride_to, int stride_from);
void IMB_buffer_float_clamp(float *buf, int width, int height);
+void IMB_buffer_float_unpremultiply(float *buf, int width, int height);
+void IMB_buffer_float_premultiply(float *buf, int width, int height);
/**
* Change the ordering of the color bytes pointed to by rect from
@@ -407,14 +406,17 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf);
* \attention defined in imageprocess.c
*/
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
-void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+void nearest_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
-void neareast_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]);
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]);
+
/**
*
* \attention defined in readimage.c
@@ -467,6 +469,7 @@ void IMB_flipy(struct ImBuf *ibuf);
/* Premultiply alpha */
void IMB_premultiply_alpha(struct ImBuf *ibuf);
+void IMB_unpremultiply_alpha(struct ImBuf *ibuf);
/**
*
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 28e62d4..49e2e7f 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -167,14 +167,15 @@ typedef struct ImBuf {
#define IB_animdeinterlace (1 << 9)
#define IB_tiles (1 << 10)
#define IB_tilecache (1 << 11)
-#define IB_premul (1 << 12)
-#define IB_cm_predivide (1 << 13)
+#define IB_alphamode_premul (1 << 12) /* indicates whether image on disk have premul alpha */
+#define IB_alphamode_detect (1 << 13) /* if this flag is set, alpha mode would be guessed from file */
+#define IB_ignore_alpha (1 << 14) /* ignore alpha on load and substitude it with 1.0f */
/*
* The bit flag is stored in the ImBuf.ftype variable.
- * Note that the lower 10 bits is used for storing custom flags
+ * Note that the lower 11 bits is used for storing custom flags
*/
-#define IB_CUSTOM_FLAGS_MASK 0x3ff
+#define IB_CUSTOM_FLAGS_MASK 0x400
#define PNG (1 << 30)
#define TGA (1 << 28)
@@ -217,8 +218,12 @@ typedef struct ImBuf {
#define JP2_YCC (1 << 15)
#define JP2_CINE (1 << 14)
#define JP2_CINE_48FPS (1 << 13)
+#define JP2_JP2 (1 << 12)
+#define JP2_J2K (1 << 11)
#endif
+#define PNG_16BIT (1 << 10)
+
#define RAWTGA (TGA | 1)
#define JPG_STD (JPG | (0 << 8))
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index a6f3851..9fc075e 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -58,7 +58,7 @@ typedef enum ThumbSource {
} ThumbSource;
/* don't generate thumbs for images bigger then this (100mb) */
-#define THUMB_SIZE_MAX (100 * 1024*1024)
+#define THUMB_SIZE_MAX (100 * 1024 * 1024)
// IB_metadata
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 976108c..f76da8c 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import os
Import ('env')
diff --git a/source/blender/imbuf/intern/IMB_filter.h b/source/blender/imbuf/intern/IMB_filter.h
index eaedb16..6bd5f44 100644
--- a/source/blender/imbuf/intern/IMB_filter.h
+++ b/source/blender/imbuf/intern/IMB_filter.h
@@ -41,6 +41,9 @@ void imb_filterx(struct ImBuf *ibuf);
void IMB_premultiply_rect(unsigned int *rect, char planes, int w, int h);
void IMB_premultiply_rect_float(float *rect_float, char planes, int w, int h);
+void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h);
+void IMB_unpremultiply_rect_float(float *rect_float, char planes, int w, int h);
+
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1);
#endif
diff --git a/source/blender/imbuf/intern/IMB_metadata.h b/source/blender/imbuf/intern/IMB_metadata.h
index a68d7a7..f731fd6 100644
--- a/source/blender/imbuf/intern/IMB_metadata.h
+++ b/source/blender/imbuf/intern/IMB_metadata.h
@@ -42,7 +42,7 @@ typedef struct ImMetaData {
int len;
} ImMetaData;
-/** The metadata is a list of key/value pairs (both char*) that can me
+/** The metadata is a list of key/value pairs (both char *) that can me
* saved in the header of several image formats.
* Apart from some common keys like
* 'Software' and 'Description' (png standard) we'll use keys within the
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 1b3a6d4..ca0b26f 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -355,7 +355,7 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int
ibuf->x = x;
ibuf->y = y;
ibuf->planes = planes;
- ibuf->ftype = TGA;
+ ibuf->ftype = PNG | 90; /* the 90 means, set compression to nearly the maximum */
ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 8dfdbd4..8d79482 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -486,7 +486,7 @@ static int startffmpeg(struct anim *anim)
return -1;
}
- if (av_find_stream_info(pFormatCtx) < 0) {
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
av_close_input_file(pFormatCtx);
return -1;
}
@@ -523,7 +523,7 @@ static int startffmpeg(struct anim *anim)
pCodecCtx->workaround_bugs = 1;
- if (avcodec_open(pCodecCtx, pCodec) < 0) {
+ if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
av_close_input_file(pFormatCtx);
return -1;
}
diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript
index a073346..d8fc250 100644
--- a/source/blender/imbuf/intern/cineon/SConscript
+++ b/source/blender/imbuf/intern/cineon/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
source_files = env.Glob('*.c')
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index c8bc3f8..ba84063 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -95,6 +95,9 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int us
if (flags & IB_rect)
IMB_rect_from_float(ibuf);
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
+
return ibuf;
}
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 3049a5b..b858251 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -50,7 +50,8 @@
static int verbose = 0;
-void cineonSetVerbose(int verbosity) {
+void cineonSetVerbose(int verbosity)
+{
verbose = verbosity;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 4c9b5e6..aeebf46 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -48,7 +48,8 @@
static int verbose = 0;
-void dpxSetVerbose(int verbosity) {
+void dpxSetVerbose(int verbosity)
+{
verbose = verbosity;
}
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 1c68a46..2c6e46c 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -189,7 +189,6 @@ typedef struct ColormnaageCacheData {
int flag; /* view flags of cached buffer */
float exposure; /* exposure value cached buffer is calculated with */
float gamma; /* gamma value cached buffer is calculated with */
- int predivide; /* predivide flag of cached buffer */
CurveMapping *curve_mapping; /* curve mapping used for cached buffer */
int curve_mapping_timestamp; /* time stamp of curve mapping used for cached buffer */
} ColormnaageCacheData;
@@ -323,7 +322,6 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
ColormanageCacheKey key;
ImBuf *cache_ibuf;
int view_flag = 1 << (view_settings->view - 1);
- int predivide = ibuf->flags & IB_cm_predivide;
CurveMapping *curve_mapping = view_settings->curve_mapping;
int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
@@ -353,10 +351,9 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
if (cache_data->exposure != view_settings->exposure ||
cache_data->gamma != view_settings->gamma ||
- cache_data->predivide != predivide ||
- cache_data->flag != view_settings->flag ||
- cache_data->curve_mapping != curve_mapping ||
- cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
+ cache_data->flag != view_settings->flag ||
+ cache_data->curve_mapping != curve_mapping ||
+ cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
{
*cache_handle = NULL;
@@ -379,7 +376,6 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
ImBuf *cache_ibuf;
ColormnaageCacheData *cache_data;
int view_flag = 1 << (view_settings->view - 1);
- int predivide = ibuf->flags & IB_cm_predivide;
struct MovieCache *moviecache = colormanage_moviecache_ensure(ibuf);
CurveMapping *curve_mapping = view_settings->curve_mapping;
int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
@@ -400,7 +396,6 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
cache_data = MEM_callocN(sizeof(ColormnaageCacheData), "color manage cache imbuf data");
cache_data->exposure = view_settings->exposure;
cache_data->gamma = view_settings->gamma;
- cache_data->predivide = predivide;
cache_data->flag = view_settings->flag;
cache_data->curve_mapping = curve_mapping;
cache_data->curve_mapping_timestamp = curve_mapping_timestamp;
@@ -686,7 +681,7 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin
}
static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display,
- float exposure, float gamma)
+ float exposure, float gamma)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_DisplayTransformRcPtr *dt;
@@ -703,7 +698,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
if (exposure != 0.0f) {
OCIO_MatrixTransformRcPtr *mt;
float gain = powf(2.0f, exposure);
- const float scale4f[] = {gain, gain, gain, gain};
+ const float scale4f[] = {gain, gain, gain, 1.0f};
float m44[16], offset4[4];
OCIO_matrixTransformScale(m44, offset4, scale4f);
@@ -736,7 +731,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
}
static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace,
- const char *to_colorspace)
+ const char *to_colorspace)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_ConstProcessorRcPtr *processor;
@@ -897,13 +892,12 @@ void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
if (ibuf->rect_float) {
const char *to_colorspace = global_role_scene_linear;
- int predivide = ibuf->flags & IB_cm_predivide;
if (ibuf->rect)
imb_freerectImBuf(ibuf);
IMB_colormanagement_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -1130,7 +1124,6 @@ typedef struct DisplayBufferThread {
int channels;
float dither;
- int predivide;
int is_data;
const char *byte_colorspace;
@@ -1158,7 +1151,6 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
DisplayBufferInitData *init_data = (DisplayBufferInitData *) init_data_v;
ImBuf *ibuf = init_data->ibuf;
- int predivide = ibuf->flags & IB_cm_predivide;
int channels = ibuf->channels;
float dither = ibuf->dither;
int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
@@ -1189,7 +1181,6 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
handle->channels = channels;
handle->dither = dither;
- handle->predivide = predivide;
handle->is_data = is_data;
handle->byte_colorspace = init_data->byte_colorspace;
@@ -1206,7 +1197,6 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
int buffer_size = channels * width * height;
- int predivide = handle->predivide;
int is_data = handle->is_data;
int is_data_display = handle->cm_processor->is_data_result;
@@ -1224,16 +1214,25 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
/* first convert byte buffer to float, keep in image space */
for (i = 0, fp = linear_buffer, cp = byte_buffer;
- i < channels * width * height;
- i++, fp++, cp++)
+ i < width * height;
+ i++, fp += channels, cp += channels)
{
- *fp = (float)(*cp) / 255.0f;
+ if (channels == 3) {
+ rgb_uchar_to_float(fp, cp);
+ }
+ else if (channels == 4) {
+ rgba_uchar_to_float(fp, cp);
+ straight_to_premul_v4(fp, fp);
+ }
+ else {
+ BLI_assert(!"Buffers of 3 or 4 channels are only supported here");
+ }
}
if (!is_data && !is_data_display) {
/* convert float buffer to scene linear space */
IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
else if (handle->float_colorspace) {
@@ -1249,7 +1248,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
else {
/* some processors would want to modify float original buffer
@@ -1277,13 +1276,12 @@ static void *do_display_buffer_apply_thread(void *handle_v)
int width = handle->width;
int height = handle->tot_line;
float dither = handle->dither;
- int predivide = handle->predivide;
int is_data = handle->is_data;
if (cm_processor == NULL) {
if (display_buffer_byte) {
IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- FALSE, width, height, width, width);
+ FALSE, width, height, width, width);
}
if (display_buffer) {
@@ -1301,7 +1299,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
}
else {
/* apply processor */
- IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, predivide);
+ IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels, TRUE);
}
/* copy result to output buffers */
@@ -1309,7 +1307,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
/* do conversion */
IMB_buffer_byte_from_float(display_buffer_byte, linear_buffer,
channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- predivide, width, height, width, width);
+ TRUE, width, height, width, width);
}
if (display_buffer)
@@ -1593,14 +1591,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in
OCIO_PackedImageDesc *img;
img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float),
- channels * sizeof(float), channels * sizeof(float) * width);
+ channels * sizeof(float), channels * sizeof(float) * width);
if (predivide)
OCIO_processorApply_predivide(processor, img);
else
OCIO_processorApply(processor, img);
- OCIO_OCIO_PackedImageDescRelease(img);
+ OCIO_PackedImageDescRelease(img);
}
}
@@ -1663,7 +1661,7 @@ static void colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorMan
if (global_tot_display == 0 || global_tot_view == 0) {
IMB_buffer_float_from_float(ibuf->rect_float, ibuf->rect_float, ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
- ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
else {
colormanage_display_buffer_process_ex(ibuf, ibuf->rect_float, (unsigned char *)ibuf->rect,
@@ -2326,7 +2324,6 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
{
int x, y;
int channels = ibuf->channels;
- int predivide = ibuf->flags & IB_cm_predivide;
float dither = ibuf->dither;
ColorSpace *rect_colorspace = ibuf->rect_colorspace;
float *display_buffer_float = NULL;
@@ -2350,13 +2347,11 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
else if (byte_buffer) {
rgba_uchar_to_float(pixel, byte_buffer + linear_index);
IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
+ straight_to_premul_v4(pixel, pixel);
}
if (!is_data) {
- if (predivide)
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
- else
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
}
if (display_buffer_float) {
@@ -2365,7 +2360,9 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
copy_v4_v4(display_buffer_float + index, pixel);
}
else {
- rgba_float_to_uchar(display_buffer + display_index, pixel);
+ float pixel_straight[4];
+ premul_to_straight_v4(pixel_straight, pixel);
+ rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
}
}
}
@@ -2389,7 +2386,6 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
/* update byte buffer created by legacy color management */
unsigned char *rect = (unsigned char *) ibuf->rect;
- int predivide = ibuf->flags & IB_cm_predivide;
int channels = ibuf->channels;
int width = xmax - xmin;
int height = ymax - ymin;
@@ -2397,7 +2393,7 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
int linear_index = ((ymin - offset_y) * stride + (xmin - offset_x)) * channels;
IMB_buffer_byte_from_float(rect + rect_index, linear_buffer + linear_index, channels, ibuf->dither,
- IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide, width, height, ibuf->x, stride);
+ IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE, width, height, ibuf->x, stride);
}
if (ibuf->display_buffer_flags) {
@@ -2503,6 +2499,15 @@ void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor,
OCIO_processorApplyRGBA(cm_processor->processor, pixel);
}
+void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_processor, float pixel[4])
+{
+ if (cm_processor->curve_mapping)
+ curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
+
+ if (cm_processor->processor)
+ OCIO_processorApplyRGBA_predivide(cm_processor->processor, pixel);
+}
+
void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, float pixel[3])
{
if (cm_processor->curve_mapping)
@@ -2533,14 +2538,14 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo
/* apply OCIO processor */
img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float),
- channels * sizeof(float), channels * sizeof(float) * width);
+ channels * sizeof(float), channels * sizeof(float) * width);
if (predivide)
OCIO_processorApply_predivide(cm_processor->processor, img);
else
OCIO_processorApply(cm_processor->processor, img);
- OCIO_OCIO_PackedImageDescRelease(img);
+ OCIO_PackedImageDescRelease(img);
}
}
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index f0864f0..730a19d 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -69,7 +69,7 @@ struct ColorBlock
private:
- Color32 m_color[4*4];
+ Color32 m_color[4 * 4];
};
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index 72a524d..11e6d4a 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -172,7 +172,7 @@ public:
void setUserVersion(int version);
void mipmap(Image * img, uint f, uint m);
- void* readData(uint &size);
+ void *readData(uint &size);
// void mipmap(FloatImage * img, uint f, uint m);
void printInfo() const;
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 05821b2..6606435 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -147,10 +147,10 @@ static void FlipDXT5BlockFull(uint8_t *block)
block[2] = line_3_2 & 0xff;
block[3] = (line_3_2 & 0xff00) >> 8;
- block[4] = (line_3_2 & 0xff0000) >> 8;
+ block[4] = (line_3_2 & 0xff0000) >> 16;
block[5] = line_1_0 & 0xff;
block[6] = (line_1_0 & 0xff00) >> 8;
- block[7] = (line_1_0 & 0xff0000) >> 8;
+ block[7] = (line_1_0 & 0xff0000) >> 16;
// And flip the DXT1 block using the above function.
FlipDXT1BlockFull(block + 8);
@@ -165,7 +165,7 @@ static void FlipDXT5BlockHalf(uint8_t *block)
((line_0_1 & 0xfff000) >> 12);
block[2] = line_1_0 & 0xff;
block[3] = (line_1_0 & 0xff00) >> 8;
- block[4] = (line_1_0 & 0xff0000) >> 8;
+ block[4] = (line_1_0 & 0xff0000) >> 16;
FlipDXT1BlockHalf(block + 8);
}
diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript
index 475d211..960e15f 100644
--- a/source/blender/imbuf/intern/dds/SConscript
+++ b/source/blender/imbuf/intern/dds/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp', 'FlipDXT.cpp']
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 5459cff..c41bbd5 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -164,7 +164,7 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags, char colo
}
if (ibuf->dds_data.fourcc != FOURCC_DDS) {
- ibuf->dds_data.data = (unsigned char*)dds.readData(ibuf->dds_data.size);
+ ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size);
/* flip compressed texture */
FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index f049c40..84339b5 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -39,6 +39,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
+#include "IMB_filter.h"
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
@@ -249,11 +250,25 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
uchar *to = rect_to + stride_to * y * 4;
if (profile_to == profile_from) {
+ float straight[4];
+
/* no color space conversion */
- if (dither) {
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4(straight, from);
+ float_to_byte_dither_v4(to, straight, di);
+ }
+ }
+ else if (dither) {
for (x = 0; x < width; x++, from += 4, to += 4)
float_to_byte_dither_v4(to, from, di);
}
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4(straight, from);
+ rgba_float_to_uchar(to, straight);
+ }
+ }
else {
for (x = 0; x < width; x++, from += 4, to += 4)
rgba_float_to_uchar(to, from);
@@ -262,10 +277,12 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
else if (profile_to == IB_PROFILE_SRGB) {
/* convert from linear to sRGB */
unsigned short us[4];
+ float straight[4];
if (dither && predivide) {
for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4_predivide(us, from);
+ premul_to_straight_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
ushort_to_byte_dither_v4(to, us, di);
}
}
@@ -277,7 +294,8 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
}
else if (predivide) {
for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4_predivide(us, from);
+ premul_to_straight_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
ushort_to_byte_v4(to, us);
}
}
@@ -526,7 +544,6 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
void IMB_rect_from_float(ImBuf *ibuf)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
float *buffer;
const char *from_colorspace;
@@ -548,7 +565,10 @@ void IMB_rect_from_float(ImBuf *ibuf)
buffer = MEM_dupallocN(ibuf->rect_float);
/* first make float buffer in byte space */
- IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, predivide);
+ IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, TRUE);
+
+ /* convert from float's premul alpha to byte's straight alpha */
+ IMB_unpremultiply_rect_float(buffer, ibuf->planes, ibuf->x, ibuf->y);
/* convert float to byte */
IMB_buffer_byte_from_float((unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
@@ -565,7 +585,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
{
float *rect_float;
uchar *rect_byte;
- int predivide = (ibuf->flags & IB_cm_predivide);
int profile_from = IB_PROFILE_LINEAR_RGB;
/* verify we have a float buffer */
@@ -588,12 +607,12 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
/* and do color space conversion to byte */
IMB_buffer_byte_from_float(rect_byte, rect_float,
- 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
+ 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, TRUE,
w, h, ibuf->x, w);
}
else {
IMB_buffer_float_from_float(buffer, rect_float,
- ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide,
+ ibuf->channels, IB_PROFILE_SRGB, profile_from, TRUE,
w, h, w, ibuf->x);
/* XXX: need to convert to image buffer's rect space */
@@ -608,8 +627,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
void IMB_float_from_rect(ImBuf *ibuf)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
-
/* verify if we byte and float buffers */
if (ibuf->rect == NULL)
return;
@@ -634,69 +651,12 @@ void IMB_float_from_rect(ImBuf *ibuf)
/* then make float be in linear space */
IMB_colormanagement_colorspace_to_scene_linear(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- ibuf->rect_colorspace, predivide);
-
- BLI_unlock_thread(LOCK_COLORMANAGE);
-}
-
-/* no profile conversion */
-void IMB_float_from_rect_simple(ImBuf *ibuf)
-{
- int predivide = (ibuf->flags & IB_cm_predivide);
-
- if (ibuf->rect_float == NULL)
- imb_addrectfloatImBuf(ibuf);
-
- IMB_buffer_float_from_byte(ibuf->rect_float, (uchar *)ibuf->rect,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
-}
+ ibuf->rect_colorspace, FALSE);
-/* use when you need to get a buffer with a certain profile
- * if the return */
+ /* byte buffer is straight alpha, float should always be premul */
+ IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
-/* OCIO_TODO: used only by Cineon/DPX exporter which is still broken, so can not guarantee
- * this function is working properly
- */
-float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc)
-{
- int predivide = (ibuf->flags & IB_cm_predivide);
- int profile_from = IB_PROFILE_LINEAR_RGB;
- int profile_to;
-
- /* determine profile */
- if (profile == IB_PROFILE_NONE)
- profile_to = IB_PROFILE_LINEAR_RGB;
- else
- profile_to = IB_PROFILE_SRGB;
-
- if (profile_from == profile_to) {
- /* simple case, just allocate the buffer and return */
- *alloc = 0;
-
- if (ibuf->rect_float == NULL)
- IMB_float_from_rect(ibuf);
-
- return ibuf->rect_float;
- }
- else {
- /* conversion is needed, first check */
- float *fbuf = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure");
- *alloc = 1;
-
- if (ibuf->rect_float == NULL) {
- IMB_buffer_float_from_byte(fbuf, (uchar *)ibuf->rect,
- profile_to, profile_from, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
- else {
- IMB_buffer_float_from_float(fbuf, ibuf->rect_float,
- 4, profile_to, profile_from, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
-
- return fbuf;
- }
+ BLI_unlock_thread(LOCK_COLORMANAGE);
}
/**************************** Color to Grayscale *****************************/
@@ -727,6 +687,26 @@ void IMB_buffer_float_clamp(float *buf, int width, int height)
}
}
+void IMB_buffer_float_unpremultiply(float *buf, int width, int height)
+{
+ int total = width * height;
+ float *cp = buf;
+ while (total--) {
+ premul_to_straight_v4(cp, cp);
+ cp += 4;
+ }
+}
+
+void IMB_buffer_float_premultiply(float *buf, int width, int height)
+{
+ int total = width * height;
+ float *cp = buf;
+ while (total--) {
+ straight_to_premul_v4(cp, cp);
+ cp += 4;
+ }
+}
+
/**************************** alter saturation *****************************/
void IMB_saturation(ImBuf *ibuf, float sat)
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 678b290..51fee23 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -599,3 +599,67 @@ void IMB_premultiply_alpha(ImBuf *ibuf)
IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
}
+void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h)
+{
+ char *cp;
+ int x, y;
+ float val;
+
+ if (planes == 24) { /* put alpha at 255 */
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++, cp += 4)
+ cp[3] = 255;
+ }
+ else {
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, cp += 4) {
+ val = cp[3] != 0 ? 1.0f / (float)cp[3] : 1.0f;
+ cp[0] = FTOCHAR(cp[0] * val);
+ cp[1] = FTOCHAR(cp[1] * val);
+ cp[2] = FTOCHAR(cp[2] * val);
+ }
+ }
+ }
+}
+
+void IMB_unpremultiply_rect_float(float *rect_float, char planes, int w, int h)
+{
+ float val, *fp;
+ int x, y;
+
+ if (planes == 24) { /* put alpha at 1.0 */
+ fp = rect_float;
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++, fp += 4)
+ fp[3] = 1.0;
+ }
+ else {
+ fp = rect_float;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, fp += 4) {
+ val = fp[3] != 0.0f ? 1.0f / fp[3] : 1.0f;
+ fp[0] = fp[0] * val;
+ fp[1] = fp[1] * val;
+ fp[2] = fp[2] * val;
+ }
+ }
+ }
+
+}
+
+void IMB_unpremultiply_alpha(ImBuf *ibuf)
+{
+ if (ibuf == NULL)
+ return;
+
+ if (ibuf->rect)
+ IMB_unpremultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
+
+ if (ibuf->rect_float)
+ IMB_unpremultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
+}
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index a185c4e..59282c9 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -104,7 +104,7 @@ void bicubic_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
}
else {
- BLI_bicubic_interpolation_char((unsigned char*) in->rect, outI, in->x, in->y, 4, u, v);
+ BLI_bicubic_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
}
}
@@ -130,7 +130,7 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
}
else {
- BLI_bilinear_interpolation_char((unsigned char*) in->rect, outI, in->x, in->y, 4, u, v);
+ BLI_bilinear_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
}
}
@@ -219,7 +219,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
/* function assumes out to be zero'ed, only does RGBA */
/* NEAREST INTERPOLATION */
-void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
float *dataF;
unsigned char *dataI;
@@ -268,7 +268,7 @@ void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
}
}
-void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
{
unsigned char *outI = NULL;
float *outF = NULL;
@@ -279,7 +279,7 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, i
pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
- neareast_interpolation_color(in, outI, outF, x, y);
+ nearest_interpolation_color(in, outI, outF, x, y);
}
/*********************** Threaded image processing *************************/
@@ -327,3 +327,53 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_
MEM_freeN(handles);
}
+
+/* Alpha-under */
+
+void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ float *fp = rect_float;
+
+ while (a--) {
+ if (fp[3] == 0.0f) {
+ copy_v3_v3(fp, backcol);
+ }
+ else {
+ float mul = 1.0f - fp[3];
+
+ fp[0] += mul * backcol[0];
+ fp[1] += mul * backcol[1];
+ fp[2] += mul * backcol[2];
+ }
+
+ fp[3] = 1.0f;
+
+ fp += 4;
+ }
+}
+
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
+{
+ int a = x * y;
+ unsigned char *cp = rect;
+
+ while (a--) {
+ if (cp[3] == 0) {
+ cp[0] = backcol[0] * 255;
+ cp[1] = backcol[1] * 255;
+ cp[2] = backcol[2] * 255;
+ }
+ else {
+ int mul = 255 - cp[3];
+
+ cp[0] += mul * backcol[0] / 255;
+ cp[1] += mul * backcol[1] / 255;
+ cp[2] += mul * backcol[2] / 255;
+ }
+
+ cp[3] = 255;
+
+ cp += 4;
+ }
+}
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 277f50b..86e451e 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -496,7 +496,9 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
- rv->st = av_new_stream(rv->of, 0);
+ rv->st = avformat_new_stream(rv->of, NULL);
+ rv->st->id = 0;
+
rv->c = rv->st->codec;
rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
rv->c->codec_id = CODEC_ID_MJPEG;
@@ -531,8 +533,8 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
/* there's no way to set JPEG quality in the same way as in AVI JPEG and image sequence,
* but this seems to be giving expected quality result */
ffmpeg_quality = (int)(1.0f + 30.0f * (1.0f - (float)quality / 100.0f) + 0.5f);
- av_set_int(rv->c, "qmin", ffmpeg_quality);
- av_set_int(rv->c, "qmax", ffmpeg_quality);
+ av_opt_set_int(rv->c, "qmin", ffmpeg_quality, 0);
+ av_opt_set_int(rv->c, "qmax", ffmpeg_quality, 0);
if (rv->of->flags & AVFMT_GLOBALHEADER) {
rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
@@ -545,7 +547,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
return 0;
}
- avcodec_open(rv->c, rv->codec);
+ avcodec_open2(rv->c, rv->codec, NULL);
rv->video_buffersize = 2000000;
rv->video_buffer = (uint8_t *)MEM_mallocN(
@@ -758,7 +760,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
return NULL;
}
- if (av_find_stream_info(context->iFormatCtx) < 0) {
+ if (avformat_find_stream_info(context->iFormatCtx, NULL) < 0) {
av_close_input_file(context->iFormatCtx);
MEM_freeN(context);
return NULL;
@@ -797,7 +799,7 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
context->iCodecCtx->workaround_bugs = 1;
- if (avcodec_open(context->iCodecCtx, context->iCodec) < 0) {
+ if (avcodec_open2(context->iCodecCtx, context->iCodec, NULL) < 0) {
av_close_input_file(context->iFormatCtx);
MEM_freeN(context);
return NULL;
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 3a2bf99..8d6218a 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -228,6 +228,10 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char co
}
ibuf->ftype = JP2;
+ if (is_jp2)
+ ibuf->ftype |= JP2_JP2;
+ else
+ ibuf->ftype |= JP2_J2K;
if (use_float) {
float *rect_float = ibuf->rect_float;
@@ -852,9 +856,15 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags)
int codestream_length;
opj_cio_t *cio = NULL;
FILE *f = NULL;
+ opj_cinfo_t *cinfo = NULL;
/* get a JP2 compressor handle */
- opj_cinfo_t *cinfo = opj_create_compress(CODEC_JP2);
+ if (ibuf->ftype & JP2_JP2)
+ cinfo = opj_create_compress(CODEC_JP2);
+ else if (ibuf->ftype & JP2_J2K)
+ cinfo = opj_create_compress(CODEC_J2K);
+ else
+ BLI_assert(!"Unsupported codec was specified in save settings");
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 758617b..6a5b534 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -234,7 +234,7 @@ static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t
* If must suspend, take the specified action (typically "return FALSE").
*/
#define INPUT_BYTE(cinfo, V, action) \
- MAKESTMT(MAKE_BYTE_AVAIL(cinfo,action); \
+ MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V = GETJOCTET(*next_input_byte++); )
@@ -242,7 +242,7 @@ static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, size_t
* V should be declared unsigned int or perhaps INT32.
*/
#define INPUT_2BYTES(cinfo, V, action) \
- MAKESTMT(MAKE_BYTE_AVAIL(cinfo,action); \
+ MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
bytes_in_buffer--; \
V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
MAKE_BYTE_AVAIL(cinfo, action); \
diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript
index a6c5ad9..ac38c04 100644
--- a/source/blender/imbuf/intern/openexr/SConscript
+++ b/source/blender/imbuf/intern/openexr/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
source_files = ['openexr_api.cpp']
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index da7b31c..18b08c9 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1197,6 +1197,9 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
delete file;
}
}
+
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
}
return(ibuf);
}
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index dcfebb9..bbe4313 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -109,10 +109,14 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
unsigned char *pixels = NULL;
unsigned char *from, *to;
+ unsigned short *pixels16 = NULL, *to16;
+ float *from_float, from_straight[4];
png_bytepp row_pointers = NULL;
int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
FILE *fp = NULL;
+ int is_16bit = (ibuf->ftype & PNG_16BIT) && ibuf->rect_float;
+
/* use the jpeg quality setting for compression */
int compression;
compression = (int)(((float)(ibuf->ftype & 0xff) / 11.1111f));
@@ -150,8 +154,12 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
/* copy image data */
- pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "pixels");
- if (pixels == NULL) {
+ if (is_16bit)
+ pixels16 = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned short), "png 16bit pixels");
+ else
+ pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "png 8bit pixels");
+
+ if (pixels == NULL && pixels16 == NULL) {
png_destroy_write_struct(&png_ptr, &info_ptr);
printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name);
return 0;
@@ -159,32 +167,66 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
from = (unsigned char *) ibuf->rect;
to = pixels;
+ from_float = ibuf->rect_float;
+ to16 = pixels16;
switch (bytesperpixel) {
case 4:
color_type = PNG_COLOR_TYPE_RGBA;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = from[3];
- to += 4; from += 4;
+ if (is_16bit) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4(from_straight, from_float);
+ to16[0] = FTOUSHORT(from_straight[0]);
+ to16[1] = FTOUSHORT(from_straight[1]);
+ to16[2] = FTOUSHORT(from_straight[2]);
+ to16[3] = FTOUSHORT(from_straight[3]);
+ to16 += 4; from_float += 4;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to += 4; from += 4;
+ }
}
break;
case 3:
color_type = PNG_COLOR_TYPE_RGB;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to += 3; from += 4;
+ if (is_16bit) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4(from_straight, from_float);
+ to16[0] = FTOUSHORT(from_straight[0]);
+ to16[1] = FTOUSHORT(from_straight[1]);
+ to16[2] = FTOUSHORT(from_straight[2]);
+ to16 += 3; from_float += 4;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to += 3; from += 4;
+ }
}
break;
case 1:
color_type = PNG_COLOR_TYPE_GRAY;
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to++; from += 4;
+ if (is_16bit) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4(from_straight, from_float);
+ to16[0] = FTOUSHORT(from_straight[0]);
+ to16++; from_float += 4;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to++; from += 4;
+ }
}
break;
}
@@ -203,7 +245,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
fp = BLI_fopen(name, "wb");
if (!fp) {
png_destroy_write_struct(&png_ptr, &info_ptr);
- MEM_freeN(pixels);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
return 0;
}
@@ -227,7 +272,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
info_ptr,
ibuf->x,
ibuf->y,
- 8,
+ is_16bit ? 16 : 8,
color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
@@ -268,12 +313,19 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
/* write the file header information */
png_write_info(png_ptr, info_ptr);
+#ifdef __LITTLE_ENDIAN__
+ png_set_swap(png_ptr);
+#endif
+
/* allocate memory for an array of row-pointers */
row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
if (row_pointers == NULL) {
printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
png_destroy_write_struct(&png_ptr, &info_ptr);
- MEM_freeN(pixels);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
if (fp) {
fclose(fp);
}
@@ -281,9 +333,17 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
}
/* set the individual row-pointers to point at the correct offsets */
- for (i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char));
+ if (is_16bit) {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)
+ ((unsigned short *)pixels16 + (i * ibuf->x) * bytesperpixel);
+ }
+ }
+ else {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)
+ ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char));
+ }
}
/* write out the entire image data in one call */
@@ -293,7 +353,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
png_write_end(png_ptr, info_ptr);
/* clean up */
- MEM_freeN(pixels);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
MEM_freeN(row_pointers);
png_destroy_write_struct(&png_ptr, &info_ptr);
@@ -394,6 +457,8 @@ ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags, char colorspace[I
if (ibuf) {
ibuf->ftype = PNG;
+ if (bit_depth == 16)
+ ibuf->ftype |= PNG_16BIT;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
int unit_type;
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 03ed1bb..d09adeb 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -212,6 +212,9 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char color
if (ibuf == NULL) return NULL;
ibuf->ftype = RADHDR;
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
+
if (flags & IB_test) return ibuf;
/* read in and decode the actual data */
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index be20c80..00bc78e 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -86,15 +86,32 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
}
+ if (flags & IB_ignore_alpha) {
+ IMB_rectfill_alpha(ibuf, 1.0f);
+ }
+ else {
+ if (flags & IB_alphamode_premul) {
+ if (ibuf->rect) {
+ IMB_unpremultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, floats are expected to be premul */
+ }
+ }
+ else {
+ if (ibuf->rect_float) {
+ IMB_premultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, bytes are expected to be straight */
+ }
+ }
+ }
+
/* OCIO_TODO: in some cases it's faster to do threaded conversion,
* but how to distinguish such cases */
colormanage_imbuf_make_linear(ibuf, effective_colorspace);
- if (flags & IB_premul) {
- IMB_premultiply_alpha(ibuf);
- ibuf->flags |= IB_premul;
- }
-
return ibuf;
}
}
@@ -230,4 +247,3 @@ void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
close(file);
}
-
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 1e701b8..1050d3f 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -33,6 +33,7 @@
#include "BLI_utildefines.h"
+#include "BLI_math_color.h"
#include "MEM_guardedalloc.h"
#include "imbuf.h"
@@ -291,6 +292,37 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1)
return (ibuf2);
}
+/* pretty much specific functions which converts uchar <-> ushort but assumes
+ * ushort range of 255*255 which is more convenient here
+ */
+MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4], const unsigned char color[4])
+{
+ unsigned short alpha = color[3];
+
+ result[0] = color[0] * alpha;
+ result[1] = color[1] * alpha;
+ result[2] = color[2] * alpha;
+ result[3] = alpha * 255;
+}
+
+MINLINE void premul_ushort_to_straight_uchar(unsigned char *result, const unsigned short color[4])
+{
+ if (color[3] <= 255) {
+ result[0] = color[0] / 255;
+ result[1] = color[1] / 255;
+ result[2] = color[2] / 255;
+ result[3] = color[3] / 255;
+ }
+ else {
+ unsigned short alpha = color[3] / 255;
+
+ result[0] = color[0] / alpha;
+ result[1] = color[1] / alpha;
+ result[2] = color[2] / alpha;
+ result[3] = alpha;
+ }
+}
+
/* result in ibuf2, scaling should be done correctly */
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
@@ -303,23 +335,33 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
}
if (do_rect) {
- char *p1, *p2, *dest;
+ unsigned char *cp1, *cp2, *dest;
- p1 = (char *) ibuf1->rect;
- dest = (char *) ibuf2->rect;
+ cp1 = (unsigned char *) ibuf1->rect;
+ dest = (unsigned char *) ibuf2->rect;
for (y = ibuf2->y; y > 0; y--) {
- p2 = p1 + (ibuf1->x << 2);
+ cp2 = cp1 + (ibuf1->x << 2);
for (x = ibuf2->x; x > 0; x--) {
- dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2;
- dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2;
- dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2;
- dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2;
- p1 += 8;
- p2 += 8;
+ unsigned short p1i[8], p2i[8], desti[4];
+
+ straight_uchar_to_premul_ushort(p1i, cp1);
+ straight_uchar_to_premul_ushort(p2i, cp2);
+ straight_uchar_to_premul_ushort(p1i + 4, cp1 + 4);
+ straight_uchar_to_premul_ushort(p2i + 4, cp2 + 4);
+
+ desti[0] = ((unsigned int) p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2;
+ desti[1] = ((unsigned int) p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2;
+ desti[2] = ((unsigned int) p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2;
+ desti[3] = ((unsigned int) p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2;
+
+ premul_ushort_to_straight_uchar(dest, desti);
+
+ cp1 += 8;
+ cp2 += 8;
dest += 4;
}
- p1 = p2;
- if (ibuf1->x & 1) p1 += 4;
+ cp1 = cp2;
+ if (ibuf1->x & 1) cp1 += 4;
}
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 83830f2..2630aeb 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -376,7 +376,7 @@ static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
* This method is most flexible and can handle multiple different bit depths
* and RGB channel orderings.
*/
-static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
+static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image)
{
ImBuf *tmpibuf;
int success = 0;
@@ -390,6 +390,23 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */
TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
+ if (spp == 4) {
+ /* HACK: this is really tricky hack, which is only needed to force libtiff
+ * do not touch RGB channels when there's alpha channel present
+ * The thing is: libtiff will premul RGB if alpha mode is set to
+ * unassociated, which really conflicts with blender's assumptions
+ *
+ * Alternative would be to unpremul after load, but it'll be really
+ * lossy and unwanted behavior
+ *
+ * So let's keep this thing here for until proper solution is found (sergey)
+ */
+
+ unsigned short extraSampleTypes[1];
+ extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
+ TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes);
+ }
+
imb_read_tiff_resolution(ibuf, image);
scanline = TIFFScanlineSize(image);
@@ -471,10 +488,6 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
if (bitspersample < 16)
if (ENDIAN_ORDER == B_ENDIAN)
IMB_convert_rgba_to_abgr(tmpibuf);
- if (premul) {
- IMB_premultiply_alpha(tmpibuf);
- ibuf->flags |= IB_premul;
- }
/* assign rect last */
if (tmpibuf->rect_float)
@@ -557,6 +570,18 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
return NULL;
}
+ /* get alpha mode from file header */
+ if (flags & IB_alphamode_detect) {
+ if (spp == 4) {
+ unsigned short extra, *extraSampleTypes;
+
+ TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes);
+
+ if (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)
+ ibuf->flags |= IB_alphamode_premul;
+ }
+ }
+
/* if testing, we're done */
if (flags & IB_test) {
TIFFClose(image);
@@ -585,9 +610,6 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
hbuf->miplevel = level;
hbuf->ftype = ibuf->ftype;
ibuf->mipmap[level - 1] = hbuf;
-
- if (flags & IB_premul)
- hbuf->flags |= IB_premul;
}
else
hbuf = ibuf;
@@ -608,7 +630,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
}
/* read pixels */
- if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image, 0)) {
+ if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) {
fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n");
TIFFClose(image);
return NULL;
@@ -644,9 +666,6 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int
if (TIFFReadRGBATile(image, tx * ibuf->tilex, (ibuf->ytiles - 1 - ty) * ibuf->tiley, rect) == 1) {
if (ibuf->tiley > ibuf->y)
memmove(rect, rect + ibuf->tilex * (ibuf->tiley - ibuf->y), sizeof(int) * ibuf->tilex * ibuf->y);
-
- if (ibuf->flags & IB_premul)
- IMB_premultiply_rect(rect, 32, ibuf->tilex, ibuf->tiley);
}
else
printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
@@ -689,8 +708,6 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
float *fromf = NULL;
float xres, yres;
int x, y, from_i, to_i, i;
- int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
-
/* check for a valid number of bytes per pixel. Like the PNG writer,
* the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding
@@ -763,6 +780,13 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
if (samplesperpixel == 4) {
+ unsigned short extraSampleTypes[1];
+
+ if (bitspersample == 16)
+ extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
+ else
+ extraSampleTypes[0] = EXTRASAMPLE_UNASSALPHA;
+
/* RGBA images */
TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
extraSampleTypes);
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 42fb0c7..549a95e 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -306,8 +306,8 @@ static int isffmpeg(const char *filename)
return 0;
}
- if (av_find_stream_info(pFormatCtx) < 0) {
- if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
+ if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
av_close_input_file(pFormatCtx);
return 0;
}
@@ -340,7 +340,7 @@ static int isffmpeg(const char *filename)
return 0;
}
- if (avcodec_open(pCodecCtx, pCodec) < 0) {
+ if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
av_close_input_file(pFormatCtx);
return 0;
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index a769ce7..0c5e17c 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -42,6 +42,7 @@ extern "C" {
struct Library;
struct FileData;
struct ID;
+struct PackedFile;
typedef struct IDPropertyData {
void *pointer;
@@ -136,6 +137,8 @@ typedef struct Library {
* setting 'name' directly and it will be kept in
* sync - campbell */
struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
+
+ struct PackedFile *packedfile;
} Library;
enum eIconSizes {
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index fd68a6d..8fcb079 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -198,7 +198,9 @@ typedef enum eBone_Flag {
BONE_EDITMODE_LOCKED = (1 << 19), /* bone transforms are locked in EditMode */
BONE_TRANSFORM_CHILD = (1 << 20), /* Indicates that a parent is also being transformed */
BONE_UNSELECTABLE = (1 << 21), /* bone cannot be selected */
- BONE_NO_LOCAL_LOCATION = (1 << 22) /* bone location is in armature space */
+ BONE_NO_LOCAL_LOCATION = (1 << 22), /* bone location is in armature space */
+ BONE_RELATIVE_PARENTING = (1 << 23) /* object child will use relative transform (like deform) */
+
} eBone_Flag;
#define MAXBONENAME 64
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index cc26ee4..e3571c7 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -156,10 +156,7 @@ typedef enum BrushSculptTool {
SCULPT_TOOL_THUMB = 12,
SCULPT_TOOL_SNAKE_HOOK = 13,
SCULPT_TOOL_ROTATE = 14,
-
- /* slot 15 is free for use */
- /* SCULPT_TOOL_ = 15, */
-
+ SCULPT_TOOL_SIMPLIFY = 15,
SCULPT_TOOL_CREASE = 16,
SCULPT_TOOL_BLOB = 17,
SCULPT_TOOL_CLAY_STRIPS = 18,
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 6f7bb5a..e28b878 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -46,7 +46,7 @@ typedef struct CustomDataLayer {
int active_clone; /* number of the layer to render*/
int active_mask; /* number of the layer to render*/
int uid; /* shape keyblock unique id reference*/
- char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_AAME */
+ char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_NAME */
void *data; /* layer data */
} CustomDataLayer;
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index fe35503..0f47ee2 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -111,6 +111,9 @@ typedef struct Image {
/* color management */
ColorManagedColorspaceSettings colorspace_settings;
+ char alpha_mode;
+
+ char pad[7];
} Image;
@@ -119,15 +122,16 @@ typedef struct Image {
/* Image.flag */
#define IMA_FIELDS 1
#define IMA_STD_FIELD 2
-#define IMA_DO_PREMUL 4
+#define IMA_DO_PREMUL 4 /* deprecated, should not be used */
#define IMA_REFLECT 16
#define IMA_NOCOLLECT 32
#define IMA_DEPRECATED 64
#define IMA_OLD_PREMUL 128
-#define IMA_CM_PREDIVIDE 256
+/*#define IMA_CM_PREDIVIDE 256*/ /* deprecated, should not be used */
#define IMA_USED_FOR_RENDER 512
#define IMA_USER_FRAME_IN_RANGE 1024 /* for image user, but these flags are mixed */
#define IMA_VIEW_AS_RENDER 2048
+#define IMA_IGNORE_ALPHA 4096
/* Image.tpageflag */
#define IMA_TILES 1
@@ -148,4 +152,10 @@ typedef struct Image {
/* gen_flag */
#define IMA_GEN_FLOAT 1
+/* alpha_mode */
+enum {
+ IMA_ALPHA_STRAIGHT = 0,
+ IMA_ALPHA_PREMUL = 1,
+};
+
#endif
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index dd0845d..0c708dd 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -119,7 +119,10 @@ typedef struct Mesh {
short texflag, drawflag;
short smoothresh, flag;
- short subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED;
+ /* customdata flag, for bevel-weight and crease, which are now optional */
+ char cd_flag, pad;
+
+ char subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED;
char subsurftype DNA_DEPRECATED; /* only kept for backwards compat, not used anymore */
char editflag;
@@ -147,15 +150,15 @@ typedef struct TFace {
#define ME_EDIT_MIRROR_Y (1 << 1) // unused so far
#define ME_EDIT_MIRROR_Z (1 << 2) // unused so far
-#define ME_EDIT_PAINT_MASK (1 << 3)
+#define ME_EDIT_PAINT_FACE_SEL (1 << 3)
#define ME_EDIT_MIRROR_TOPO (1 << 4)
-#define ME_EDIT_VERT_SEL (1 << 5)
+#define ME_EDIT_PAINT_VERT_SEL (1 << 5)
/* we cant have both flags enabled at once,
* flags defined in DNA_scene_types.h */
#define ME_EDIT_PAINT_SEL_MODE(_me) ( \
- (_me->editflag & ME_EDIT_PAINT_MASK) ? SCE_SELECT_FACE : \
- (_me->editflag & ME_EDIT_VERT_SEL) ? SCE_SELECT_VERTEX : \
+ (_me->editflag & ME_EDIT_PAINT_FACE_SEL) ? SCE_SELECT_FACE : \
+ (_me->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : \
0 \
)
@@ -170,6 +173,12 @@ typedef struct TFace {
#define ME_SUBSURF 128
#define ME_OPT_EDGES 256
#define ME_DS_EXPAND 512
+#define ME_SCULPT_DYNAMIC_TOPOLOGY 1024
+
+/* me->cd_flag */
+#define ME_CDFLAG_VERT_BWEIGHT (1 << 0)
+#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1)
+#define ME_CDFLAG_EDGE_CREASE (1 << 2)
/* me->drawflag, short */
#define ME_DRAWEDGES (1 << 0)
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 0c193e9..ffa5e42 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -167,7 +167,7 @@ typedef struct MIntProperty {
int i;
} MIntProperty;
typedef struct MStringProperty {
- char s[256];
+ char s[255], s_len;
} MStringProperty;
typedef struct OrigSpaceFace {
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 3875a0d..089103c 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -76,7 +76,8 @@ typedef enum ModifierType {
eModifierType_Remesh = 41,
eModifierType_Skin = 42,
eModifierType_LaplacianSmooth = 43,
- eModifierType_Triangulate = 44,
+ eModifierType_Triangulate = 44,
+ eModifierType_UVWarp = 45,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -586,7 +587,7 @@ typedef struct MeshDeformModifierData {
/* runtime */
void (*bindfunc)(struct Scene *scene,
struct MeshDeformModifierData *mmd,
- float *vertexcos, int totvert, float cagemat[][4]);
+ float *vertexcos, int totvert, float cagemat[4][4]);
} MeshDeformModifierData;
typedef enum {
@@ -1140,4 +1141,20 @@ typedef struct LaplacianSmoothModifierData {
short flag, repeat;
} LaplacianSmoothModifierData;
-#endif
+typedef struct UVWarpModifierData {
+ ModifierData modifier;
+
+ char axis_u, axis_v;
+ char pad[6];
+ float center[2]; /* used for rotate/scale */
+
+ struct Object *object_src; /* source */
+ char bone_src[64]; /* optional name of bone target, MAX_ID_NAME-2 */
+ struct Object *object_dst; /* target */
+ char bone_dst[64]; /* optional name of bone target, MAX_ID_NAME-2 */
+
+ char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */
+ char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+} UVWarpModifierData;
+
+#endif /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 89328c3..559ba44 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -178,7 +178,7 @@ typedef struct Object {
short ipoflag; // xxx deprecated... old animation system
short scaflag; /* ui state for game logic */
char scavisflag; /* more display settings for game logic */
- char pad5;
+ char depsflag;
int dupon, dupoff, dupsta, dupend;
@@ -530,6 +530,10 @@ typedef struct DupliObject {
#define OB_BODY_TYPE_NAVMESH 7
#define OB_BODY_TYPE_CHARACTER 8
+/* ob->depsflag */
+#define OB_DEPS_EXTRA_OB_RECALC 1
+#define OB_DEPS_EXTRA_DATA_RECALC 2
+
/* ob->scavisflag */
#define OB_VIS_SENS 1
#define OB_VIS_CONT 2
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 5952aa8..1cf16fb 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -116,6 +116,9 @@ typedef struct ParticleData {
float size; /* size and multiplier so that we can update size when ever */
+ float sphdensity; /* density of sph particle */
+ int pad;
+
int hair_index;
short flag;
short alive; /* the life state of a particle */
@@ -130,6 +133,8 @@ typedef struct SPHFluidSettings {
float stiffness_k, stiffness_knear, rest_density;
float buoyancy;
int flag, spring_frames;
+ short solver;
+ short pad[3];
} SPHFluidSettings;
/* fluid->flag */
@@ -141,6 +146,10 @@ typedef struct SPHFluidSettings {
#define SPH_FAC_VISCOSITY 32
#define SPH_FAC_REST_LENGTH 64
+/* fluid->solver (numerical ID field, not bitfield) */
+#define SPH_SOLVER_DDR 0
+#define SPH_SOLVER_CLASSICAL 1
+
typedef struct ParticleSettings {
ID id;
struct AnimData *adt;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 1599b71..c817546 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -271,8 +271,9 @@ typedef struct ImageFormatData {
/* Jpeg2000 */
char jp2_flag;
+ char jp2_codec;
- char pad[7];
+ char pad[6];
/* color management */
ColorManagedViewSettings view_settings;
@@ -341,6 +342,10 @@ typedef struct ImageFormatData {
#define R_IMF_JP2_FLAG_CINE_PRESET (1<<1) /* was R_JPEG2K_CINE_PRESET */
#define R_IMF_JP2_FLAG_CINE_48 (1<<2) /* was R_JPEG2K_CINE_48FPS */
+/* ImageFormatData.jp2_codec */
+#define R_IMF_JP2_CODEC_JP2 0
+#define R_IMF_JP2_CODEC_J2K 1
+
/* ImageFormatData.cineon_flag */
#define R_IMF_CINEON_FLAG_LOG (1<<0) /* was R_CINEON_LOG */
@@ -491,7 +496,8 @@ typedef struct RenderData {
/* Bake Render options */
short bake_osa, bake_filter, bake_mode, bake_flag;
short bake_normal_space, bake_quad_split;
- float bake_maxdist, bake_biasdist, bake_pad;
+ float bake_maxdist, bake_biasdist;
+ short bake_samples, bake_pad;
/* path to render output */
char pic[1024]; /* 1024 = FILE_MAX */
@@ -635,7 +641,8 @@ typedef struct GameData {
short physicsEngine;
short exitkey, pad;
short ticrate, maxlogicstep, physubstep, maxphystep;
- short obstacleSimulation, pad1;
+ short obstacleSimulation;
+ short raster_storage;
float levelHeight;
float deactivationtime, lineardeactthreshold, angulardeactthreshold, pad2;
} GameData;
@@ -662,6 +669,12 @@ typedef struct GameData {
#define OBSTSIMULATION_TOI_rays 1
#define OBSTSIMULATION_TOI_cells 2
+/* Raster storage */
+#define RAS_STORE_AUTO 0
+#define RAS_STORE_IMMEDIATE 1
+#define RAS_STORE_VA 2
+#define RAS_STORE_VBO 3
+
/* GameData.flag */
#define GAME_RESTRICT_ANIM_UPDATES (1 << 0)
#define GAME_ENABLE_ALL_FRAMES (1 << 1)
@@ -680,6 +693,7 @@ typedef struct GameData {
#define GAME_SHOW_MOUSE (1 << 14)
#define GAME_GLSL_NO_COLOR_MANAGEMENT (1 << 15)
#define GAME_SHOW_OBSTACLE_SIMULATION (1 << 16)
+#define GAME_NO_MATERIAL_CACHING (1 << 17)
/* Note: GameData.flag is now an int (max 32 flags). A short could only take 16 flags */
/* GameData.playerflag */
@@ -816,6 +830,12 @@ typedef struct Sculpt {
float special_rotation;
+ /* Maximum edge length for dynamic topology sculpting (in pixels) */
+ int detail_size;
+
+ /* Direction used for SCULPT_OT_symmetrize operator */
+ int symmetrize_direction;
+
int pad;
} Sculpt;
@@ -945,7 +965,7 @@ typedef struct ToolSettings {
short uvcalc_mapalign;
short uvcalc_flag;
short uv_flag, uv_selectmode;
- short uv_subsurf_level;
+ short pad2;
/* Grease Pencil */
short gpencil_flags;
@@ -973,7 +993,7 @@ typedef struct ToolSettings {
/* Multires */
char multires_subdiv_type;
- char pad2[5];
+ char pad3[5];
/* Skeleton generation */
short skgen_resolution;
@@ -1198,6 +1218,7 @@ typedef struct Scene {
/* seq_flag */
#define R_SEQ_GL_PREV 1
// #define R_SEQ_GL_REND 2 // UNUSED, opengl render has its own operator now.
+#define R_SEQ_SOLID_TEX 4
/* displaymode */
@@ -1271,11 +1292,11 @@ typedef struct Scene {
/* alphamode */
#define R_ADDSKY 0
#define R_ALPHAPREMUL 1
-#define R_ALPHAKEY 2
+/*#define R_ALPHAKEY 2*/ /* deprecated, shouldn't be used */
/* color_mgt_flag */
#define R_COLOR_MANAGEMENT (1 << 0) /* deprecated, should only be used in versioning code only */
-#define R_COLOR_MANAGEMENT_PREDIVIDE (1 << 1)
+/*#define R_COLOR_MANAGEMENT_PREDIVIDE (1 << 1)*/ /* deprecated, shouldn't be used */
/* subimtype, flag options for imtype */
#define R_OPENEXR_HALF 1 /*deprecated*/
@@ -1298,6 +1319,7 @@ typedef struct Scene {
#define R_BAKE_NORMALIZE 8
#define R_BAKE_MULTIRES 16
#define R_BAKE_LORES_MESH 32
+#define R_BAKE_VCOL 64
/* bake_normal_space */
#define R_BAKE_SPACE_CAMERA 0
@@ -1464,6 +1486,14 @@ typedef enum SculptFlags {
SCULPT_USE_OPENMP = (1<<7),
SCULPT_ONLY_DEFORM = (1<<8),
SCULPT_SHOW_DIFFUSE = (1<<9),
+
+ /* If set, the mesh will be drawn with smooth-shading in
+ * dynamic-topology mode */
+ SCULPT_DYNTOPO_SMOOTH_SHADING = (1<<10),
+
+ /* If set, dynamic-topology brushes will collapse short edges in
+ * addition to subdividing long ones */
+ SCULPT_DYNTOPO_COLLAPSE = (1<<11)
} SculptFlags;
/* ImagePaintSettings.flag */
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index b1cd549..d6100dc 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -82,7 +82,8 @@ typedef struct bScreen {
typedef struct ScrVert {
struct ScrVert *next, *prev, *newv;
vec2s vec;
- int flag;
+ /* first one used internally, second one for tools */
+ short flag, editflag;
} ScrVert;
typedef struct ScrEdge {
@@ -109,12 +110,26 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
int sortorder; /* panels are aligned according to increasing sortorder */
struct Panel *paneltab; /* this panel is tabbed in *paneltab */
void *activedata; /* runtime for panel manipulation */
-
- int list_scroll, list_size;
- int list_last_len, list_grip_size;
- char list_search[64];
} Panel;
+typedef struct uiList { /* some list UI data need to be saved in file */
+ struct uiList *next, *prev;
+
+ struct uiListType *type; /* runtime */
+ void *padp;
+
+ char list_id[64]; /* defined as UI_MAX_NAME_STR */
+
+ int layout_type; /* How items are layedout in the list */
+ int padi;
+
+ int list_scroll;
+ int list_size;
+ int list_last_len;
+ int list_grip_size;
+/* char list_search[64]; */
+} uiList;
+
typedef struct ScrArea {
struct ScrArea *next, *prev;
@@ -159,14 +174,18 @@ typedef struct ARegion {
short do_draw; /* private, cached notifier events */
short do_draw_overlay; /* private, cached notifier events */
short swap; /* private, indicator to survive swap-exchange */
- short pad[3];
+ short overlap; /* private, set for indicate drawing overlapped */
+ short pad[2];
struct ARegionType *type; /* callbacks for this region type */
ListBase uiblocks; /* uiBlock */
ListBase panels; /* Panel */
+ ListBase ui_lists; /* uiList */
ListBase handlers; /* wmEventHandler */
+ struct wmTimer *regiontimer; /* blend in/out */
+
char *headerstr; /* use this string to draw info */
void *regiondata; /* XXX 2.50, need spacedata equivalent? */
} ARegion;
@@ -212,6 +231,13 @@ typedef struct ARegion {
#define PNL_DEFAULT_CLOSED 1
#define PNL_NO_HEADER 2
+/* uilist layout_type */
+enum {
+ UILST_LAYOUT_DEFAULT = 0,
+ UILST_LAYOUT_COMPACT = 1,
+ UILST_LAYOUT_GRID = 2,
+};
+
/* regiontype, first two are the default set */
/* Do NOT change order, append on end. Types are hardcoded needed */
enum {
@@ -235,10 +261,6 @@ enum {
#define RGN_ALIGN_VSPLIT 6
#define RGN_ALIGN_FLOAT 7
#define RGN_ALIGN_QSPLIT 8
-#define RGN_OVERLAP_TOP 9
-#define RGN_OVERLAP_BOTTOM 10
-#define RGN_OVERLAP_LEFT 11
-#define RGN_OVERLAP_RIGHT 12
#define RGN_SPLIT_PREV 32
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index f106c8f..0aa466f 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -172,7 +172,10 @@ typedef struct Sequence {
float blend_opacity;
/* is sfra needed anymore? - it looks like its only used in one place */
- int sfra, pad; /* starting frame according to the timeline of the scene. */
+ int sfra; /* starting frame according to the timeline of the scene. */
+
+ char alpha_mode;
+ char pad[3];
/* modifiers */
ListBase modifiers;
@@ -315,7 +318,7 @@ typedef struct SequencerScopes {
#define SEQ_OVERLAP (1 << 3)
#define SEQ_FILTERY (1 << 4)
#define SEQ_MUTE (1 << 5)
-#define SEQ_MAKE_PREMUL (1 << 6)
+#define SEQ_MAKE_PREMUL (1 << 6) /* deprecated, used for compatibility code only */
#define SEQ_REVERSE_FRAMES (1 << 7)
#define SEQ_IPO_FRAME_LOCKED (1 << 8)
#define SEQ_EFFECT_NOT_LOADED (1 << 9)
@@ -366,6 +369,12 @@ typedef struct SequencerScopes {
#define SEQ_PROXY_TC_RECORD_RUN_NO_GAPS 8
#define SEQ_PROXY_TC_ALL 15
+/* seq->alpha_mode */
+enum {
+ SEQ_ALPHA_STRAIGHT = 0,
+ SEQ_ALPHA_PREMUL = 1
+};
+
/* seq->type WATCH IT: SEQ_TYPE_EFFECT BIT is used to determine if this is an effect strip!!! */
enum {
SEQ_TYPE_IMAGE = 0,
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index be64647..d632a88 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -494,7 +494,7 @@ typedef enum eSpaceSeq_Flag {
SEQ_MARKER_TRANS = (1 << 1),
SEQ_DRAW_COLOR_SEPARATED = (1 << 2),
SEQ_DRAW_SAFE_MARGINS = (1 << 3),
-/* SEQ_DRAW_GPENCIL = (1 << 4), */ /* DEPRECATED */
+ SEQ_SHOW_GPENCIL = (1 << 4),
SEQ_NO_DRAW_CFRANUM = (1 << 5),
} eSpaceSeq_Flag;
@@ -776,7 +776,7 @@ typedef enum eSpaceImage_Flag {
SI_DRAW_TILE = (1 << 19),
SI_SMOOTH_UV = (1 << 20),
SI_DRAW_STRETCH = (1 << 21),
-/* SI_DISPGP = (1 << 22), */ /* deprecated */
+ SI_SHOW_GPENCIL = (1 << 22),
SI_DRAW_OTHER = (1 << 23),
SI_COLOR_CORRECTION = (1 << 24),
@@ -797,7 +797,7 @@ typedef struct SpaceText {
int top, viewlines;
short flags, menunr;
- short lheight; /* user preference */
+ short lheight; /* user preference, is font_size! */
char cwidth, linenrs_tot; /* runtime computed, character width and the number of chars to use when showing line numbers */
int left;
int showlinenrs;
@@ -816,8 +816,9 @@ typedef struct SpaceText {
char findstr[256]; /* ST_MAX_FIND_STR */
char replacestr[256]; /* ST_MAX_FIND_STR */
- short margin_column; /* column number to show right margin at */
- char pad[6];
+ short margin_column; /* column number to show right margin at */
+ short lheight_dpi; /* actual lineheight, dpi controlled */
+ char pad[4];
void *drawcache; /* cache for faster drawing */
} SpaceText;
@@ -886,7 +887,7 @@ typedef struct SpaceNode {
struct ID *id, *from; /* context, no need to save in file? well... pinning... */
short flag, pad1; /* menunr: browse id block in header */
- float aspect, aspect_sqrt;
+ float aspect, pad2; /* internal state variables */
float xof, yof; /* offset for drawing the backdrop */
float zoom; /* zoom for backdrop */
@@ -906,7 +907,7 @@ typedef struct SpaceNode {
/* snode->flag */
typedef enum eSpaceNode_Flag {
SNODE_BACKDRAW = (1 << 1),
-/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */
+ SNODE_SHOW_GPENCIL = (1 << 2),
SNODE_USE_ALPHA = (1 << 3),
SNODE_SHOW_ALPHA = (1 << 4),
SNODE_SHOW_R = (1 << 7),
@@ -1060,7 +1061,7 @@ typedef enum eSpaceClip_Flag {
SC_SHOW_GRID = (1 << 9),
SC_SHOW_STABLE = (1 << 10),
SC_MANUAL_CALIBRATION = (1 << 11),
-/* SC_SHOW_GPENCIL = (1 << 12),*/ /* UNUSED */
+ SC_SHOW_GPENCIL = (1 << 12),
SC_SHOW_FILTERS = (1 << 13),
SC_SHOW_GRAPH_FRAMES = (1 << 14),
SC_SHOW_GRAPH_TRACKS = (1 << 15),
diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h
index 6ce8839..3194adb 100644
--- a/source/blender/makesdna/DNA_text_types.h
+++ b/source/blender/makesdna/DNA_text_types.h
@@ -75,12 +75,4 @@ typedef struct Text {
#define TXT_FOLLOW 0x0200 /* always follow cursor (console) */
#define TXT_TABSTOSPACES 0x0400 /* use space instead of tabs */
-/* format continuation flags */
-#define TXT_NOCONT 0x00 /* no continuation */
-#define TXT_SNGQUOTSTR 0x01 /* single quotes */
-#define TXT_DBLQUOTSTR 0x02 /* double quotes */
-#define TXT_TRISTR 0x04 /* triplets of quotes: """ or ''' */
-#define TXT_SNGTRISTR 0x05 /*(TXT_TRISTR | TXT_SNGQUOTSTR)*/
-#define TXT_DBLTRISTR 0x06 /*(TXT_TRISTR | TXT_DBLQUOTSTR)*/
-
#endif
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index dd63e6a..ea4f281 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -340,7 +340,7 @@ typedef struct ColorMapping {
/* imaflag */
#define TEX_INTERPOL 1
-#define TEX_USEALPHA 2
+#define TEX_USEALPHA 2 /* deprecated, used for versioning only */
#define TEX_MIPMAP 4
#define TEX_IMAROT 16
#define TEX_CALCALPHA 32
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 1281930..b258fba 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -373,7 +373,7 @@ enum {
/* MovieTrackingStrabilization->filter */
enum {
- TRACKING_FILTER_NEAREAST = 0,
+ TRACKING_FILTER_NEAREST = 0,
TRACKING_FILTER_BILINEAR = 1,
TRACKING_FILTER_BICUBIC = 2
};
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 2e2f65d..3027a3a 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -143,10 +143,19 @@ typedef struct uiWidgetStateColors {
typedef struct uiPanelColors {
char header[4];
+ char back[4];
short show_header;
- short pad;
+ short show_back;
+ int pad;
} uiPanelColors;
+typedef struct uiGradientColors {
+ char gradient[4];
+ char high_gradient[4];
+ int show_grad;
+ int pad2;
+} uiGradientColors;
+
typedef struct ThemeUI {
/* Interface Elements (buttons, menus, icons) */
uiWidgetColors wcol_regular, wcol_tool, wcol_text;
@@ -157,8 +166,14 @@ typedef struct ThemeUI {
uiWidgetStateColors wcol_state;
- uiPanelColors panel;
+ uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */
+ /* fac: 0 - 1 for blend factor, width in pixels */
+ float menu_shadow_fac;
+ short menu_shadow_width;
+
+ short pad;
+
char iconfile[256]; // FILE_MAXFILE length
float icon_alpha;
@@ -172,34 +187,39 @@ typedef struct ThemeUI {
typedef struct ThemeSpace {
/* main window colors */
char back[4];
- char title[4];
+ char title[4]; /* panel title */
char text[4];
char text_hi[4];
/* header colors */
- char header[4];
- char header_title[4];
+ char header[4]; /* region background */
+ char header_title[4]; /* unused */
char header_text[4];
char header_text_hi[4];
/* button/tool regions */
- char button[4];
- char button_title[4];
+ char button[4]; /* region background */
+ char button_title[4]; /* panel title */
char button_text[4];
char button_text_hi[4];
/* listview regions */
- char list[4];
- char list_title[4];
+ char list[4]; /* region background */
+ char list_title[4]; /* panel title */
char list_text[4];
char list_text_hi[4];
/* float panel */
- char panel[4];
- char panel_title[4];
- char panel_text[4];
- char panel_text_hi[4];
+/* char panel[4]; unused */
+/* char panel_title[4]; unused */
+/* char panel_text[4]; unused */
+/* char panel_text_hi[4]; unused */
+ /* note, cannot use name 'panel' because of DNA mapping old files */
+ uiPanelColors panelcolors;
+
+ uiGradientColors gradients;
+
char shade1[4];
char shade2[4];
@@ -235,11 +255,14 @@ typedef struct ThemeSpace {
char vertex_size, outline_width, facedot_size;
char noodle_curving;
- char syntaxl[4], syntaxn[4], syntaxb[4]; /* syntax for textwindow and nodes */
+ /* syntax for textwindow and nodes */
+ char syntaxl[4], syntaxs[4];
+ char syntaxb[4], syntaxn[4];
char syntaxv[4], syntaxc[4];
+ char syntaxd[4], syntaxr[4];
char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; /* for sequence editor */
- char effect[4], hpad0[4], transition[4], meta[4];
+ char effect[4], transition[4], meta[4];
char editmesh_active[4];
char handle_vertex[4];
@@ -332,6 +355,7 @@ typedef struct bTheme {
typedef struct bAddon {
struct bAddon *next, *prev;
char module[64];
+ IDProperty *prop; /* User-Defined Properties on this Addon (for storing preferences) */
} bAddon;
typedef struct SolidLight {
@@ -359,9 +383,10 @@ typedef struct UserDef {
short versions;
short dbl_click_time;
- int gameflags;
- int wheellinescroll;
- int uiflag, language;
+ short gameflags;
+ short wheellinescroll;
+ int uiflag, uiflag2;
+ int language;
short userpref, viewzoom;
int mixbufsize;
@@ -412,7 +437,7 @@ typedef struct UserDef {
short scrcastfps; /* frame rate for screencast to be played back */
short scrcastwait; /* milliseconds between screencast snapshots */
- short widget_unit; /* defaults to 20 for 72 DPI setting */
+ short widget_unit; /* private, defaults to 20 for 72 DPI setting */
short anisotropic_filter;
short use_16bit_textures, use_gpu_mipmap;
@@ -421,6 +446,7 @@ typedef struct UserDef {
int ndof_flag; /* flags for 3D mouse */
short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */
+
short pad4;
float glalphaclip;
@@ -443,7 +469,7 @@ typedef struct UserDef {
int compute_device_id;
float fcu_inactive_alpha; /* opacity of inactive F-Curves in F-Curve Editor */
- float pad;
+ float pixelsize; /* private, set by GHOST, to multiply DPI with */
} UserDef;
extern UserDef U; /* from blenkernel blender.c */
@@ -539,6 +565,12 @@ typedef enum eUserpref_UI_Flag {
USER_HIDE_SYSTEM_BOOKMARKS = (1 << 31)
} eUserpref_UI_Flag;
+/* uiflag2 */
+typedef enum eUserpref_UI_Flag2 {
+ USER_KEEP_SESSION = (1 << 0),
+ USER_REGION_OVERLAP = (1 << 1)
+} eUserpref_UI_Flag2;
+
/* Auto-Keying mode */
typedef enum eAutokey_Mode {
/* AUTOKEY_ON is a bitflag */
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index 0844968..a7921be 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -123,9 +123,9 @@ typedef struct View2D {
/* horizontal scrollbar */
#define V2D_SCROLL_TOP (1<<2)
#define V2D_SCROLL_BOTTOM (1<<3)
- /* special hack for outliner hscroll - prevent hanging older versions of Blender */
-#define V2D_SCROLL_BOTTOM_O (1<<4)
-#define V2D_SCROLL_HORIZONTAL (V2D_SCROLL_TOP|V2D_SCROLL_BOTTOM|V2D_SCROLL_BOTTOM_O)
+
+/* UNUSED (1<<4) */
+#define V2D_SCROLL_HORIZONTAL (V2D_SCROLL_TOP|V2D_SCROLL_BOTTOM)
/* scale markings - vertical */
#define V2D_SCROLL_SCALE_VERTICAL (1<<5)
/* scale markings - horizontal */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index c83b0bc..dbe54a4 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -225,6 +225,7 @@ typedef struct View3D {
#define V3D_DISPBGPICS 2
#define V3D_HIDE_HELPLINES 4
#define V3D_INVALID_BACKBUF 8
+#define V3D_INVALID_BACKBUF 8
#define V3D_ALIGN 1024
#define V3D_SELECT_OUTLINE 2048
@@ -261,7 +262,7 @@ typedef struct View3D {
/* View3d->flag2 (short) */
#define V3D_RENDER_OVERRIDE 4
#define V3D_SOLID_TEX 8
-#define V3D_DISPGP 16
+#define V3D_SHOW_GPENCIL 16
#define V3D_LOCK_CAMERA 32
#define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */
#define V3D_SHOW_RECONSTRUCTION 128
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 2294abc..27aef3b 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -65,19 +65,21 @@ struct uiLayout;
/* keep in sync with 'wm_report_items' in wm_rna.c */
typedef enum ReportType {
- RPT_DEBUG = 1<<0,
- RPT_INFO = 1<<1,
- RPT_OPERATOR = 1<<2,
- RPT_WARNING = 1<<3,
- RPT_ERROR = 1<<4,
- RPT_ERROR_INVALID_INPUT = 1<<5,
- RPT_ERROR_INVALID_CONTEXT = 1<<6,
- RPT_ERROR_OUT_OF_MEMORY = 1<<7
+ RPT_DEBUG = 1 << 0,
+ RPT_INFO = 1 << 1,
+ RPT_OPERATOR = 1 << 2,
+ RPT_PROPERTY = 1 << 3,
+ RPT_WARNING = 1 << 4,
+ RPT_ERROR = 1 << 5,
+ RPT_ERROR_INVALID_INPUT = 1 << 6,
+ RPT_ERROR_INVALID_CONTEXT = 1 << 7,
+ RPT_ERROR_OUT_OF_MEMORY = 1 << 8
} ReportType;
#define RPT_DEBUG_ALL (RPT_DEBUG)
#define RPT_INFO_ALL (RPT_INFO)
#define RPT_OPERATOR_ALL (RPT_OPERATOR)
+#define RPT_PROPERTY_ALL (RPT_PROPERTY)
#define RPT_WARNING_ALL (RPT_WARNING)
#define RPT_ERROR_ALL (RPT_ERROR|RPT_ERROR_INVALID_INPUT|RPT_ERROR_INVALID_CONTEXT|RPT_ERROR_OUT_OF_MEMORY)
diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript
index c3d3978..a6520a6 100644
--- a/source/blender/makesdna/SConscript
+++ b/source/blender/makesdna/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
objs = []
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index c1e6eb5..add9611 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index fa0b313..e131cde 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -208,7 +208,7 @@ static int calculate_structlens(int);
/**
* Construct the DNA.c file
*/
-void dna_write(FILE *file, void *pntr, int size);
+static void dna_write(FILE *file, const void *pntr, const int size);
/**
* Report all structures found so far, and print their lengths.
@@ -892,7 +892,7 @@ static int calculate_structlens(int firststruct)
#define MAX_DNA_LINE_LENGTH 20
-void dna_write(FILE *file, void *pntr, int size)
+static void dna_write(FILE *file, const void *pntr, const int size)
{
static int linelength = 0;
int i;
@@ -934,7 +934,7 @@ void printStructLengths(void)
}
-static int make_structDNA(char *baseDirectory, FILE *file)
+static int make_structDNA(const char *baseDirectory, FILE *file)
{
int len, i;
short *sp;
@@ -984,7 +984,7 @@ static int make_structDNA(char *baseDirectory, FILE *file)
/* little test first... */
/* Mind the breaking condition here! */
if (debugSDNA) printf("\tStart of header scan:\n");
- for (i = 0; strlen(includefiles[i]); i++) {
+ for (i = 0; *(includefiles[i]) != '\0'; i++) {
sprintf(str, "%s%s", baseDirectory, includefiles[i]);
if (debugSDNA) printf("\t|-- Converting %s\n", str);
if (convert_include(str)) {
@@ -1036,12 +1036,10 @@ static int make_structDNA(char *baseDirectory, FILE *file)
/* pass */
}
else {
- strcpy(str, "SDNA");
- dna_write(file, str, 4);
+ dna_write(file, "SDNA", 4);
/* write names */
- strcpy(str, "NAME");
- dna_write(file, str, 4);
+ dna_write(file, "NAME", 4);
len = nr_names;
dna_write(file, &len, 4);
@@ -1053,8 +1051,7 @@ static int make_structDNA(char *baseDirectory, FILE *file)
dna_write(file, names[0], len);
/* write TYPES */
- strcpy(str, "TYPE");
- dna_write(file, str, 4);
+ dna_write(file, "TYPE", 4);
len = nr_types;
dna_write(file, &len, 4);
@@ -1067,16 +1064,14 @@ static int make_structDNA(char *baseDirectory, FILE *file)
dna_write(file, types[0], len);
/* WRITE TYPELENGTHS */
- strcpy(str, "TLEN");
- dna_write(file, str, 4);
+ dna_write(file, "TLEN", 4);
len = 2 * nr_types;
if (nr_types & 1) len += 2;
dna_write(file, typelens_native, len);
/* WRITE STRUCTS */
- strcpy(str, "STRC");
- dna_write(file, str, 4);
+ dna_write(file, "STRC", 4);
len = nr_structs;
dna_write(file, &len, 4);
@@ -1100,7 +1095,7 @@ static int make_structDNA(char *baseDirectory, FILE *file)
else {
/* add all include files defined in the global array */
- for (i = 0; strlen(includefiles[i]); i++) {
+ for (i = 0; *(includefiles[i]) != '\0'; i++) {
fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
}
@@ -1165,13 +1160,13 @@ int main(int argc, char **argv)
return_status = 1;
}
else {
- char baseDirectory[256];
+ const char *baseDirectory;
if (argc == 3) {
- strcpy(baseDirectory, argv[2]);
+ baseDirectory = argv[2];
}
else {
- strcpy(baseDirectory, BASE_HEADER);
+ baseDirectory = BASE_HEADER;
}
fprintf(file, "const unsigned char DNAstr[] = {\n");
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 0e5f9c5..29adb8f 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -54,6 +54,7 @@ extern StructRNA RNA_ActionPoseMarkers;
extern StructRNA RNA_Actuator;
extern StructRNA RNA_ActuatorSensor;
extern StructRNA RNA_Addon;
+extern StructRNA RNA_AddonPreferences;
extern StructRNA RNA_AdjustmentSequence;
extern StructRNA RNA_AlwaysSensor;
extern StructRNA RNA_AndController;
@@ -104,7 +105,8 @@ extern StructRNA RNA_CollectionProperty;
extern StructRNA RNA_CollisionModifier;
extern StructRNA RNA_CollisionSensor;
extern StructRNA RNA_CollisionSettings;
-extern StructRNA RNA_ColorManagedColorspaceSettings;
+extern StructRNA RNA_ColorManagedInputColorspaceSettings;
+extern StructRNA RNA_ColorManagedSequencerColorspaceSettings;
extern StructRNA RNA_ColorManagedDisplaySettings;
extern StructRNA RNA_ColorManagedViewSettings;
extern StructRNA RNA_ColorRamp;
@@ -569,6 +571,7 @@ extern StructRNA RNA_ThemeOutliner;
extern StructRNA RNA_ThemeProperties;
extern StructRNA RNA_ThemeSequenceEditor;
extern StructRNA RNA_ThemeSpaceGeneric;
+extern StructRNA RNA_ThemeSpaceGradient;
extern StructRNA RNA_ThemeSpaceListGeneric;
extern StructRNA RNA_ThemeStyle;
extern StructRNA RNA_ThemeTextEditor;
@@ -586,7 +589,8 @@ extern StructRNA RNA_TrackToConstraint;
extern StructRNA RNA_TransformConstraint;
extern StructRNA RNA_TransformSequence;
extern StructRNA RNA_UILayout;
-extern StructRNA RNA_UIListItem;
+extern StructRNA RNA_UIList;
+extern StructRNA RNA_UVWarpModifier;
extern StructRNA RNA_UVProjectModifier;
extern StructRNA RNA_UVProjector;
extern StructRNA RNA_UnitSettings;
@@ -862,7 +866,12 @@ int RNA_path_resolve_full(PointerRNA *ptr, const char *path,
char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
-char *RNA_path_from_ID_python(struct ID *id);
+
+char *RNA_path_full_ID_py(struct ID *id);
+char *RNA_path_full_struct_py(struct PointerRNA *ptr);
+char *RNA_path_full_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
+char *RNA_path_struct_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
+char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
/* Quick name based property access
*
@@ -970,8 +979,8 @@ int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
int RNA_property_is_idprop(PropertyRNA *prop);
/* python compatible string representation of this property, (must be freed!) */
-char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop);
-char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr);
+char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
+char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop);
char *RNA_pointer_as_string_keywords_ex(struct bContext *C, PointerRNA *ptr, PointerRNA *ptr_default,
const short skip_optional_value, const short all_args,
PropertyRNA *iterprop);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 9939d08..463e0e0 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -49,6 +49,7 @@ void RNA_exit(void);
/* Struct */
+StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom);
StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from);
void RNA_def_struct_sdna(StructRNA *srna, const char *structname);
void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname);
@@ -91,7 +92,6 @@ PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont, const char *ide
PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc);
-void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data);
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
@@ -177,6 +177,17 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con
void RNA_def_property_srna(PropertyRNA *prop, const char *type);
void RNA_def_py_data(PropertyRNA *prop, void *py_data);
+void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc);
+void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc);
+void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc);
+void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc);
+void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc);
+void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc);
+void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc);
+void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc);
+
+void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data);
+
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context);
/* Function */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 0f9a00d..6733d8a 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -70,6 +70,7 @@ extern EnumPropertyItem keyframe_handle_type_items[];
extern EnumPropertyItem keyblock_type_items[];
extern EnumPropertyItem keyingset_path_grouping_items[];
+extern EnumPropertyItem keying_flag_items[];
extern EnumPropertyItem keyframe_paste_offset_items[];
extern EnumPropertyItem keyframe_paste_merge_items[];
@@ -89,6 +90,8 @@ extern EnumPropertyItem brush_sculpt_tool_items[];
extern EnumPropertyItem brush_vertex_tool_items[];
extern EnumPropertyItem brush_image_tool_items[];
+extern EnumPropertyItem symmetrize_direction_items[];
+
extern EnumPropertyItem texture_type_items[];
extern EnumPropertyItem lamp_type_items[];
@@ -132,6 +135,9 @@ extern EnumPropertyItem prop_dynamicpaint_type_items[];
extern EnumPropertyItem clip_editor_mode_items[];
+extern EnumPropertyItem icon_items[];
+extern EnumPropertyItem uilist_layout_type_items[];
+
struct bContext;
struct PointerRNA;
struct PropertyRNA;
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 87504dc..c76f982 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -269,7 +269,27 @@ typedef struct EnumPropertyItem {
const char *description;
} EnumPropertyItem;
-/* this is a copy of 'PropEnumItemFunc' defined in rna_internal_types.h */
+/* extended versions with PropertyRNA argument */
+typedef int (*BooleanPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*BooleanPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*BooleanArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*BooleanArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef int (*IntPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*IntPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*IntArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*IntArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef void (*IntPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax);
+typedef float (*FloatPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*FloatPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value);
+typedef void (*FloatArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values);
+typedef void (*FloatArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values);
+typedef void (*FloatPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax);
+typedef void (*StringPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value);
+typedef int (*StringPropertyLengthFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*StringPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value);
+typedef int (*EnumPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*EnumPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+/* same as PropEnumItemFunc */
typedef EnumPropertyItem *(*EnumPropertyItemFunc)(struct bContext *C, PointerRNA *ptr, struct PropertyRNA *prop, int *free);
typedef struct PropertyRNA PropertyRNA;
@@ -309,9 +329,10 @@ typedef struct ParameterDynAlloc {
typedef enum FunctionFlag {
FUNC_NO_SELF = 1, /* for static functions */
- FUNC_USE_MAIN = 2,
- FUNC_USE_CONTEXT = 4,
- FUNC_USE_REPORTS = 8,
+ FUNC_USE_SELF_TYPE = 2, /* for class methods, only used when FUNC_NO_SELF is set */
+ FUNC_USE_MAIN = 4,
+ FUNC_USE_CONTEXT = 8,
+ FUNC_USE_REPORTS = 16,
FUNC_USE_SELF_ID = 2048,
FUNC_ALLOW_WRITE = 4096,
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index 2991012..aab08a3 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
objs = []
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index d26de50..5d60d41 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
import os
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 6fa53f4..2eacdfd 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -91,7 +91,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
{ \
WRITE_COMMA; \
fprintf(f, param); \
- }
+ } (void)0
static int replace_if_different(char *tmpfile, const char *dep_files[])
{
@@ -415,10 +415,10 @@ static const char *rna_type_type_name(PropertyRNA *prop)
return "float";
case PROP_STRING:
if (prop->flag & PROP_THICK_WRAP) {
- return "char*";
+ return "char *";
}
else {
- return "const char*";
+ return "const char *";
}
default:
return NULL;
@@ -760,7 +760,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
if (prop->type == PROP_INT) {
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
- if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) {
+ if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX || iprop->range) {
if (array) fprintf(f, "CLAMPIS(values[i], ");
else fprintf(f, "CLAMPIS(value, ");
if (iprop->range) {
@@ -776,7 +776,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
else if (prop->type == PROP_FLOAT) {
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
- if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) {
+ if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX || fprop->range) {
if (array) fprintf(f, "CLAMPIS(values[i], ");
else fprintf(f, "CLAMPIS(value, ");
if (fprop->range) {
@@ -870,16 +870,16 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if (prop->flag & PROP_ID_REFCOUNT) {
fprintf(f, "\n if (data->%s)\n", dp->dnaname);
- fprintf(f, " id_us_min((ID*)data->%s);\n", dp->dnaname);
+ fprintf(f, " id_us_min((ID *)data->%s);\n", dp->dnaname);
fprintf(f, " if (value.data)\n");
- fprintf(f, " id_us_plus((ID*)value.data);\n\n");
+ fprintf(f, " id_us_plus((ID *)value.data);\n\n");
}
else {
PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
StructRNA *type = rna_find_struct((const char *)pprop->type);
if (type && (type->flag & STRUCT_ID)) {
fprintf(f, " if (value.data)\n");
- fprintf(f, " id_lib_extern((ID*)value.data);\n\n");
+ fprintf(f, " id_lib_extern((ID *)value.data);\n\n");
}
}
@@ -1084,7 +1084,7 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *
fprintf(f, "\n memset(iter, 0, sizeof(*iter));\n");
fprintf(f, " iter->parent= *ptr;\n");
- fprintf(f, " iter->prop= (PropertyRNA*)&rna_%s_%s;\n", srna->identifier, prop->identifier);
+ fprintf(f, " iter->prop= (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier);
if (dp->dnalengthname || dp->dnalengthfixed) {
if (manualfunc) {
@@ -1768,7 +1768,7 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property
const char *collection_funcs = "DefaultCollectionFunctions";
if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)) && cprop->property.srna)
- collection_funcs = (char*)cprop->property.srna;
+ collection_funcs = (char *)cprop->property.srna;
if (cprop->item_type)
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier,
@@ -1989,6 +1989,10 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func
if (dsrna->dnaname) fprintf(f, "(::%s *) this->ptr.data", dsrna->dnaname);
else fprintf(f, "(::%s *) this->ptr.data", srna->identifier);
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ WRITE_COMMA;
+ fprintf(f, "this->ptr.type");
+ }
if (func->flag & FUNC_USE_MAIN)
WRITE_PARAM("(::Main *) main");
@@ -2112,8 +2116,12 @@ static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, Functio
if (func->flag & FUNC_USE_SELF_ID)
WRITE_PARAM("_selfid");
- if ((func->flag & FUNC_NO_SELF) == 0)
+ if ((func->flag & FUNC_NO_SELF) == 0) {
WRITE_PARAM("_self");
+ }
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ WRITE_PARAM("_type");
+ }
if (func->flag & FUNC_USE_MAIN)
WRITE_PARAM("bmain");
@@ -2174,6 +2182,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
else fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ fprintf(f, "\tstruct StructRNA *_type;\n");
+ }
dparm = dfunc->cont.properties.first;
for (; dparm; dparm = dparm->next) {
@@ -2223,6 +2234,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ fprintf(f, "\t_type= _ptr->type;\n");
+ }
if (has_data) {
fprintf(f, "\t_data= (char *)_parms->data;\n");
@@ -2300,6 +2314,11 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
fprintf(f, "_self");
first = 0;
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ if (!first) fprintf(f, ", ");
+ fprintf(f, "_type");
+ first = 0;
+ }
if (func->flag & FUNC_USE_MAIN) {
if (!first) fprintf(f, ", ");
@@ -2613,6 +2632,11 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
else fprintf(f, "struct %s *_self", srna->identifier);
first = 0;
}
+ else if (func->flag & FUNC_USE_SELF_TYPE) {
+ if (!first) fprintf(f, ", ");
+ fprintf(f, "struct StructRNA *_type");
+ first = 0;
+ }
if (func->flag & FUNC_USE_MAIN) {
if (!first) fprintf(f, ", ");
@@ -2882,9 +2906,9 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
rna_property_structname(prop->type),
srna->identifier, strnest, prop->identifier);
- if (prop->next) fprintf(f, "\t{(PropertyRNA*)&rna_%s%s_%s, ", srna->identifier, strnest, prop->next->identifier);
+ if (prop->next) fprintf(f, "\t{(PropertyRNA *)&rna_%s%s_%s, ", srna->identifier, strnest, prop->next->identifier);
else fprintf(f, "\t{NULL, ");
- if (prop->prev) fprintf(f, "(PropertyRNA*)&rna_%s%s_%s,\n", srna->identifier, strnest, prop->prev->identifier);
+ if (prop->prev) fprintf(f, "(PropertyRNA *)&rna_%s%s_%s,\n", srna->identifier, strnest, prop->prev->identifier);
else fprintf(f, "NULL,\n");
fprintf(f, "\t%d, ", prop->magic);
rna_print_c_string(f, prop->identifier);
@@ -2923,11 +2947,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_BOOLEAN:
{
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %d, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(bprop->get),
rna_function_string(bprop->set),
rna_function_string(bprop->getarray),
rna_function_string(bprop->setarray),
+ rna_function_string(bprop->get_ex),
+ rna_function_string(bprop->set_ex),
+ rna_function_string(bprop->getarray_ex),
+ rna_function_string(bprop->setarray_ex),
bprop->defaultvalue);
if (prop->arraydimension && prop->totarraylength)
fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
@@ -2937,12 +2965,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_INT:
{
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %s,\n\t",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,\n\t",
rna_function_string(iprop->get),
rna_function_string(iprop->set),
rna_function_string(iprop->getarray),
rna_function_string(iprop->setarray),
- rna_function_string(iprop->range));
+ rna_function_string(iprop->range),
+ rna_function_string(iprop->get_ex),
+ rna_function_string(iprop->set_ex),
+ rna_function_string(iprop->getarray_ex),
+ rna_function_string(iprop->setarray_ex),
+ rna_function_string(iprop->range_ex));
rna_int_print(f, iprop->softmin); fprintf(f, ", ");
rna_int_print(f, iprop->softmax); fprintf(f, ", ");
rna_int_print(f, iprop->hardmin); fprintf(f, ", ");
@@ -2957,12 +2990,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_FLOAT:
{
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %s, %s, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ",
rna_function_string(fprop->get),
rna_function_string(fprop->set),
rna_function_string(fprop->getarray),
rna_function_string(fprop->setarray),
- rna_function_string(fprop->range));
+ rna_function_string(fprop->range),
+ rna_function_string(fprop->get_ex),
+ rna_function_string(fprop->set_ex),
+ rna_function_string(fprop->getarray_ex),
+ rna_function_string(fprop->setarray_ex),
+ rna_function_string(fprop->range_ex));
rna_float_print(f, fprop->softmin); fprintf(f, ", ");
rna_float_print(f, fprop->softmax); fprintf(f, ", ");
rna_float_print(f, fprop->hardmin); fprintf(f, ", ");
@@ -2978,10 +3016,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_STRING:
{
StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, %d, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, %s, %d, ",
rna_function_string(sprop->get),
rna_function_string(sprop->length),
rna_function_string(sprop->set),
+ rna_function_string(sprop->get_ex),
+ rna_function_string(sprop->length_ex),
+ rna_function_string(sprop->set_ex),
sprop->maxlength);
rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
break;
@@ -2989,10 +3030,12 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
case PROP_ENUM:
{
EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
- fprintf(f, "\t%s, %s, %s, NULL, ",
+ fprintf(f, "\t%s, %s, %s, %s, %s, NULL, ",
rna_function_string(eprop->get),
rna_function_string(eprop->set),
- rna_function_string(eprop->itemf));
+ rna_function_string(eprop->itemf),
+ rna_function_string(eprop->get_ex),
+ rna_function_string(eprop->set_ex));
if (eprop->item)
fprintf(f, "rna_%s%s_%s_items, ", srna->identifier, strnest, prop->identifier);
else
@@ -3056,12 +3099,12 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "%s%s rna_%s_%s_func = {\n", "", "FunctionRNA", srna->identifier, func->identifier);
if (func->cont.next)
- fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s_func, ", srna->identifier,
+ fprintf(f, "\t{(FunctionRNA *)&rna_%s_%s_func, ", srna->identifier,
((FunctionRNA *)func->cont.next)->identifier);
else
fprintf(f, "\t{NULL, ");
if (func->cont.prev)
- fprintf(f, "(FunctionRNA*)&rna_%s_%s_func,\n", srna->identifier,
+ fprintf(f, "(FunctionRNA *)&rna_%s_%s_func,\n", srna->identifier,
((FunctionRNA *)func->cont.prev)->identifier);
else
fprintf(f, "NULL,\n");
@@ -3069,11 +3112,11 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "\tNULL,\n");
parm = func->cont.properties.first;
- if (parm) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
+ if (parm) fprintf(f, "\t{(PropertyRNA *)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
else fprintf(f, "\t{NULL, ");
parm = func->cont.properties.last;
- if (parm) fprintf(f, "(PropertyRNA*)&rna_%s_%s_%s}},\n", srna->identifier, func->identifier, parm->identifier);
+ if (parm) fprintf(f, "(PropertyRNA *)&rna_%s_%s_%s}},\n", srna->identifier, func->identifier, parm->identifier);
else fprintf(f, "NULL}},\n");
fprintf(f, "\t");
@@ -3086,7 +3129,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
else fprintf(f, "\tNULL,\n");
if (func->c_ret)
- fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier);
+ fprintf(f, "\t(PropertyRNA *)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier);
else
fprintf(f, "\tNULL\n");
@@ -3104,11 +3147,11 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "\tNULL,\n");
prop = srna->cont.properties.first;
- if (prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
+ if (prop) fprintf(f, "\t{(PropertyRNA *)&rna_%s_%s, ", srna->identifier, prop->identifier);
else fprintf(f, "\t{NULL, ");
prop = srna->cont.properties.last;
- if (prop) fprintf(f, "(PropertyRNA*)&rna_%s_%s}},\n", srna->identifier, prop->identifier);
+ if (prop) fprintf(f, "(PropertyRNA *)&rna_%s_%s}},\n", srna->identifier, prop->identifier);
else fprintf(f, "NULL}},\n");
fprintf(f, "\t");
rna_print_c_string(f, srna->identifier);
@@ -3127,7 +3170,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
while (base->base && base->base->nameproperty == prop)
base = base->base;
- fprintf(f, "\t(PropertyRNA*)&rna_%s_%s, ", base->identifier, prop->identifier);
+ fprintf(f, "\t(PropertyRNA *)&rna_%s_%s, ", base->identifier, prop->identifier);
}
else fprintf(f, "\tNULL, ");
@@ -3135,7 +3178,7 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
base = srna;
while (base->base && base->base->iteratorproperty == prop)
base = base->base;
- fprintf(f, "(PropertyRNA*)&rna_%s_rna_properties,\n", base->identifier);
+ fprintf(f, "(PropertyRNA *)&rna_%s_rna_properties,\n", base->identifier);
if (srna->base) fprintf(f, "\t&RNA_%s,\n", srna->base->identifier);
else fprintf(f, "\tNULL,\n");
@@ -3157,11 +3200,11 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
}
func = srna->functions.first;
- if (func) fprintf(f, "\t{(FunctionRNA*)&rna_%s_%s_func, ", srna->identifier, func->identifier);
+ if (func) fprintf(f, "\t{(FunctionRNA *)&rna_%s_%s_func, ", srna->identifier, func->identifier);
else fprintf(f, "\t{NULL, ");
func = srna->functions.last;
- if (func) fprintf(f, "(FunctionRNA*)&rna_%s_%s_func}\n", srna->identifier, func->identifier);
+ if (func) fprintf(f, "(FunctionRNA *)&rna_%s_%s_func}\n", srna->identifier, func->identifier);
else fprintf(f, "NULL}\n");
fprintf(f, "};\n");
@@ -3501,8 +3544,27 @@ static const char *cpp_classes = ""
"#define COLLECTION_PROPERTY_LOOKUP_STRING_FALSE(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
" { \\\n"
-" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
-" return 0; \\\n"
+" CollectionPropertyIterator iter; \\\n"
+" int found = 0; \\\n"
+" PropertyRNA *item_name_prop = RNA_struct_name_property(ptr->type); \\\n"
+" sname##_##identifier##_begin(&iter, ptr); \\\n"
+" while (iter.valid && !found) { \\\n"
+" char name_fixed[32]; \\\n"
+" const char *name; \\\n"
+" int name_length; \\\n"
+" name = RNA_property_string_get_alloc(&iter.ptr, item_name_prop, name_fixed, sizeof(name_fixed), &name_length); \\\n"
+" if (!strncmp(name, key, name_length)) { \\\n"
+" *r_ptr = iter.ptr; \\\n"
+" found = 1; \\\n"
+" } \\\n"
+" if (name_fixed != name) \\\n"
+" MEM_freeN((void *) name); \\\n"
+" sname##_##identifier##_next(&iter); \\\n"
+" } \\\n"
+" sname##_##identifier##_end(&iter); \\\n"
+" if (!found) \\\n"
+" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n"
+" return found; \\\n"
" } \n"
"#define COLLECTION_PROPERTY_LOOKUP_STRING_TRUE(sname, identifier) \\\n"
" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n"
@@ -3551,7 +3613,7 @@ static const char *cpp_classes = ""
" int length;\n"
"\n"
" DynamicArray() : data(NULL), length(0) {}\n"
-" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float*)malloc(sizeof(T) * new_length); }\n"
+" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float *)malloc(sizeof(T) * new_length); }\n"
" DynamicArray(const DynamicArray<T>& other) { copy_from(other); }\n"
" const DynamicArray<T>& operator=(const DynamicArray<T>& other) { copy_from(other); return *this; }\n"
"\n"
@@ -3562,7 +3624,7 @@ static const char *cpp_classes = ""
"protected:\n"
" void copy_from(const DynamicArray<T>& other) {\n"
" if (data) free(data);\n"
-" data = (float*)malloc(sizeof(T) * other.length);\n"
+" data = (float *)malloc(sizeof(T) * other.length);\n"
" memcpy(data, other.data, sizeof(T) * other.length);\n"
" length = other.length;\n"
" }\n"
@@ -3593,7 +3655,7 @@ static const char *cpp_classes = ""
"{ return iter.valid != other.iter.valid; }\n"
"\n"
" void begin(const Pointer &ptr)\n"
-" { if (init) Tend(&iter); Tbegin(&iter, (PointerRNA*)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
+" { if (init) Tend(&iter); Tbegin(&iter, (PointerRNA *)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
"\n"
"private:\n"
" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator="
@@ -3727,13 +3789,13 @@ static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f)
if (first_collection_func_struct == NULL)
first_collection_func_struct = ds->srna->identifier;
- if (!rna_is_collection_functions_struct(collection_func_structs, (char*)prop->srna)) {
+ if (!rna_is_collection_functions_struct(collection_func_structs, (char *)prop->srna)) {
if (all_collection_func_structs >= max_collection_func_structs) {
printf("Array size to store all collection structures names is too small\n");
exit(1);
}
- collection_func_structs[all_collection_func_structs++] = (char*)prop->srna;
+ collection_func_structs[all_collection_func_structs++] = (char *)prop->srna;
}
}
}
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 11ce734..184ee23 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -248,7 +248,7 @@ StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports,
return NULL;
}
- return RNA_def_struct(&BLENDER_RNA, identifier, "PropertyGroup"); /* XXX */
+ return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup); /* XXX */
}
StructRNA *rna_PropertyGroup_refine(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 488dbff..59bcb15 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
+#include "BLI_math.h"
#include "BLF_api.h"
#include "BLF_translation.h"
@@ -937,6 +938,12 @@ void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, in
iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
}
+ else if (iprop->range_ex) {
+ *hardmin = INT_MIN;
+ *hardmax = INT_MAX;
+
+ iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
+ }
else {
*hardmin = iprop->hardmin;
*hardmax = iprop->hardmax;
@@ -977,8 +984,17 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin,
iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
- *softmin = MAX2(*softmin, hardmin);
- *softmax = MIN2(*softmax, hardmax);
+ *softmin = max_ii(*softmin, hardmin);
+ *softmax = min_ii(*softmax, hardmax);
+ }
+ else if (iprop->range_ex) {
+ hardmin = INT_MIN;
+ hardmax = INT_MAX;
+
+ iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
+
+ *softmin = max_ii(*softmin, hardmin);
+ *softmax = min_ii(*softmax, hardmax);
}
*step = iprop->step;
@@ -1012,6 +1028,12 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin
fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
}
+ else if (fprop->range_ex) {
+ *hardmin = -FLT_MAX;
+ *hardmax = FLT_MAX;
+
+ fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax);
+ }
else {
*hardmin = fprop->hardmin;
*hardmax = fprop->hardmax;
@@ -1056,8 +1078,17 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft
fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
- *softmin = MAX2(*softmin, hardmin);
- *softmax = MIN2(*softmax, hardmax);
+ *softmin = max_ff(*softmin, hardmin);
+ *softmax = min_ff(*softmax, hardmax);
+ }
+ else if (fprop->range_ex) {
+ hardmin = -FLT_MAX;
+ hardmax = FLT_MAX;
+
+ fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax);
+
+ *softmin = max_ff(*softmin, hardmin);
+ *softmax = min_ff(*softmax, hardmax);
}
*step = fprop->step;
@@ -1197,11 +1228,16 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
RNA_property_enum_items(C, ptr, prop, item, totitem, free);
#ifdef WITH_INTERNATIONAL
- /* Note: keep directly using BLF_gettext here, has we have already done tests like BLF_translate_iface... */
- if (BLF_translate_iface()) {
+ {
int i;
+ /* Note: Only do those tests once, and then use BLF_pgettext. */
+ int do_iface = BLF_translate_iface();
+ int do_tooltip = BLF_translate_tooltips();
EnumPropertyItem *nitem;
+ if (!(do_iface || do_tooltip))
+ return;
+
if (*free) {
nitem = *item;
}
@@ -1217,18 +1253,17 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
for (i = 0; (*item)[i].identifier; i++)
nitem[i] = (*item)[i];
- *free = 1;
+ *free = TRUE;
}
for (i = 0; nitem[i].identifier; i++) {
- if (nitem[i].name) {
- if (prop->translation_context)
- nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
- else
- nitem[i].name = BLF_pgettext(NULL, nitem[i].name);
+ if (nitem[i].name && do_iface) {
+ /* note: prop->translation_context may be NULL, this just means we use the default "" context */
+ nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
}
- if (nitem[i].description)
+ if (nitem[i].description && do_tooltip) {
nitem[i].description = BLF_pgettext(NULL, nitem[i].description);
+ }
}
*item = nitem;
@@ -1641,6 +1676,8 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (bprop->get)
return bprop->get(ptr);
+ else if (bprop->get_ex)
+ return bprop->get_ex(ptr, prop);
else
return bprop->defaultvalue;
}
@@ -1663,6 +1700,9 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if (bprop->set) {
bprop->set(ptr, value);
}
+ else if (bprop->set_ex) {
+ bprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1693,6 +1733,8 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val
values[0] = RNA_property_boolean_get(ptr, prop);
else if (bprop->getarray)
bprop->getarray(ptr, values);
+ else if (bprop->getarray_ex)
+ bprop->getarray_ex(ptr, prop, values);
else if (bprop->defaultarray)
memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
else
@@ -1743,6 +1785,8 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in
RNA_property_boolean_set(ptr, prop, values[0]);
else if (bprop->setarray)
bprop->setarray(ptr, values);
+ else if (bprop->setarray_ex)
+ bprop->setarray_ex(ptr, prop, values);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1844,6 +1888,8 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (iprop->get)
return iprop->get(ptr);
+ else if (iprop->get_ex)
+ return iprop->get_ex(ptr, prop);
else
return iprop->defaultvalue;
}
@@ -1864,6 +1910,8 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
}
else if (iprop->set)
iprop->set(ptr, value);
+ else if (iprop->set_ex)
+ iprop->set_ex(ptr, prop, value);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -1896,6 +1944,8 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
values[0] = RNA_property_int_get(ptr, prop);
else if (iprop->getarray)
iprop->getarray(ptr, values);
+ else if (iprop->getarray_ex)
+ iprop->getarray_ex(ptr, prop, values);
else if (iprop->defaultarray)
memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
else
@@ -1983,6 +2033,8 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
RNA_property_int_set(ptr, prop, values[0]);
else if (iprop->setarray)
iprop->setarray(ptr, values);
+ else if (iprop->setarray_ex)
+ iprop->setarray_ex(ptr, prop, values);
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2083,6 +2135,8 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
}
else if (fprop->get)
return fprop->get(ptr);
+ else if (fprop->get_ex)
+ return fprop->get_ex(ptr, prop);
else
return fprop->defaultvalue;
}
@@ -2108,6 +2162,9 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
else if (fprop->set) {
fprop->set(ptr, value);
}
+ else if (fprop->set_ex) {
+ fprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2146,6 +2203,8 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
values[0] = RNA_property_float_get(ptr, prop);
else if (fprop->getarray)
fprop->getarray(ptr, values);
+ else if (fprop->getarray_ex)
+ fprop->getarray_ex(ptr, prop, values);
else if (fprop->defaultarray)
memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
else
@@ -2245,6 +2304,9 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
else if (fprop->setarray) {
fprop->setarray(ptr, values);
}
+ else if (fprop->setarray_ex) {
+ fprop->setarray_ex(ptr, prop, values);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -2357,6 +2419,9 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
else if (sprop->get) {
sprop->get(ptr, value);
}
+ else if (sprop->get_ex) {
+ sprop->get_ex(ptr, prop, value);
+ }
else {
strcpy(value, sprop->defaultvalue);
}
@@ -2417,6 +2482,8 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
}
else if (sprop->length)
return sprop->length(ptr);
+ else if (sprop->length_ex)
+ return sprop->length_ex(ptr, prop);
else
return strlen(sprop->defaultvalue);
}
@@ -2435,6 +2502,8 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val
}
else if (sprop->set)
sprop->set(ptr, value); /* set function needs to clamp its self */
+ else if (sprop->set_ex)
+ sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */
else if (prop->flag & PROP_EDITABLE) {
IDProperty *group;
@@ -2493,6 +2562,8 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
return IDP_Int(idprop);
else if (eprop->get)
return eprop->get(ptr);
+ else if (eprop->get_ex)
+ return eprop->get_ex(ptr, prop);
else
return eprop->defaultvalue;
}
@@ -2511,6 +2582,9 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if (eprop->set) {
eprop->set(ptr, value);
}
+ else if (eprop->set_ex) {
+ eprop->set_ex(ptr, prop, value);
+ }
else if (prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val = {0};
IDProperty *group;
@@ -4030,8 +4104,9 @@ static char *rna_idp_path(PointerRNA *ptr, IDProperty *haystack, IDProperty *nee
else {
if (iter->type == IDP_GROUP) {
/* ensure this is RNA */
- PointerRNA child_ptr = RNA_pointer_get(ptr, iter->name);
- if (child_ptr.type) {
+ PropertyRNA *prop = RNA_struct_find_property(ptr, iter->name);
+ if (prop && prop->type == PROP_POINTER) {
+ PointerRNA child_ptr = RNA_property_pointer_get(ptr, prop);
link.name = iter->name;
link.index = -1;
if ((path = rna_idp_path(&child_ptr, iter, needle, &link))) {
@@ -4168,7 +4243,7 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
* Get the ID as a python representation, eg:
* bpy.data.foo["bar"]
*/
-char *RNA_path_from_ID_python(ID *id)
+char *RNA_path_full_ID_py(ID *id)
{
char id_esc[(sizeof(id->name) - 2) * 2];
@@ -4177,6 +4252,122 @@ char *RNA_path_from_ID_python(ID *id)
return BLI_sprintfN("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id_esc);
}
+/**
+ * Get the ID.struct as a python representation, eg:
+ * bpy.data.foo["bar"].some_struct
+ */
+char *RNA_path_full_struct_py(struct PointerRNA *ptr)
+{
+ char *id_path;
+ char *data_path;
+
+ char *ret;
+
+ if (!ptr->id.data) {
+ return NULL;
+ }
+
+ /* never fails */
+ id_path = RNA_path_full_ID_py(ptr->id.data);
+
+ data_path = RNA_path_from_ID_to_struct(ptr);
+
+ ret = BLI_sprintfN("%s.%s",
+ id_path, data_path);
+
+ MEM_freeN(data_path);
+
+ return ret;
+}
+
+/**
+ * Get the ID.struct.property as a python representation, eg:
+ * bpy.data.foo["bar"].some_struct.some_prop[10]
+ */
+char *RNA_path_full_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ char *id_path;
+ char *data_path;
+
+ char *ret;
+
+ if (!ptr->id.data) {
+ return NULL;
+ }
+
+ /* never fails */
+ id_path = RNA_path_full_ID_py(ptr->id.data);
+
+ data_path = RNA_path_from_ID_to_property(ptr, prop);
+
+ if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ ret = BLI_sprintfN("%s.%s",
+ id_path, data_path);
+ }
+ else {
+ ret = BLI_sprintfN("%s.%s[%d]",
+ id_path, data_path, index);
+ }
+ MEM_freeN(id_path);
+ if (data_path) {
+ MEM_freeN(data_path);
+ }
+
+ return ret;
+}
+
+/**
+ * Get the struct.property as a python representation, eg:
+ * some_struct.some_prop[10]
+ */
+char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ char *data_path;
+
+ char *ret;
+
+ if (!ptr->id.data) {
+ return NULL;
+ }
+
+ data_path = RNA_path_from_ID_to_property(ptr, prop);
+
+ if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ ret = BLI_sprintfN("%s",
+ data_path);
+ }
+ else {
+ ret = BLI_sprintfN("%s[%d]",
+ data_path, index);
+ }
+
+ if (data_path) {
+ MEM_freeN(data_path);
+ }
+
+ return ret;
+}
+
+/**
+ * Get the struct.property as a python representation, eg:
+ * some_prop[10]
+ */
+char *RNA_path_property_py(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index)
+{
+ char *ret;
+
+ if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) {
+ ret = BLI_sprintfN("%s",
+ RNA_property_identifier(prop));
+ }
+ else {
+ ret = BLI_sprintfN("%s[%d]",
+ RNA_property_identifier(prop), index);
+ }
+
+ return ret;
+}
+
/* Quick name based property access */
int RNA_boolean_get(PointerRNA *ptr, const char *name)
@@ -4606,7 +4797,7 @@ int RNA_property_is_idprop(PropertyRNA *prop)
/* string representation of a property, python
* compatible but can be used for display too,
* context may be NULL */
-char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
+static char *rna_pointer_as_string__idprop(bContext *C, PointerRNA *ptr)
{
DynStr *dynstr = BLI_dynstr_new();
char *cstring;
@@ -4627,7 +4818,7 @@ char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
BLI_dynstr_append(dynstr, ", ");
first_time = 0;
- cstring = RNA_property_as_string(C, ptr, prop);
+ cstring = RNA_property_as_string(C, ptr, prop, -1);
BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
MEM_freeN(cstring);
}
@@ -4641,6 +4832,28 @@ char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
return cstring;
}
+static char *rna_pointer_as_string__bldata(PointerRNA *ptr)
+{
+ if (ptr->type == NULL) {
+ return BLI_strdup("None");
+ }
+ else if (RNA_struct_is_ID(ptr->type)) {
+ return RNA_path_full_ID_py(ptr->id.data);
+ }
+ else {
+ return RNA_path_full_struct_py(ptr);
+ }
+}
+
+char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop)
+{
+ if (RNA_property_flag(prop_ptr) & PROP_IDPROPERTY) {
+ return rna_pointer_as_string__idprop(C, ptr_prop);
+ }
+ else {
+ return rna_pointer_as_string__bldata(ptr_prop);
+ }
+}
/* context and ptr_default can be NULL */
char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA *ptr_default,
@@ -4693,7 +4906,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA
}
}
else {
- buf = RNA_property_as_string(C, ptr, prop);
+ buf = RNA_property_as_string(C, ptr, prop, -1);
}
ok = TRUE;
@@ -4704,7 +4917,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA
prop_default = RNA_struct_find_property(ptr_default, arg_name);
if (prop_default) {
- buf_default = RNA_property_as_string(C, ptr_default, prop_default);
+ buf_default = RNA_property_as_string(C, ptr_default, prop_default, -1);
if (strcmp(buf, buf_default) == 0)
ok = FALSE; /* values match, don't bother printing */
@@ -4754,7 +4967,12 @@ char *RNA_function_as_string_keywords(bContext *C, FunctionRNA *func, PointerRNA
iterprop);
}
-char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
+static const char *bool_as_py_string(const int var)
+{
+ return var ? "True" : "False";
+}
+
+char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
{
int type = RNA_property_type(prop);
int len = RNA_property_array_length(ptr, prop);
@@ -4768,17 +4986,22 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
switch (type) {
case PROP_BOOLEAN:
if (len == 0) {
- BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
+ BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get(ptr, prop)));
}
else {
- BLI_dynstr_append(dynstr, "(");
- for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s",
- RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
+ if (index != -1) {
+ BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, index)));
+ }
+ else {
+ BLI_dynstr_append(dynstr, "(");
+ for (i = 0; i < len; i++) {
+ BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s",
+ bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, i)));
+ }
+ if (len == 1)
+ BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
+ BLI_dynstr_append(dynstr, ")");
}
- if (len == 1)
- BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
- BLI_dynstr_append(dynstr, ")");
}
break;
case PROP_INT:
@@ -4786,13 +5009,18 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
}
else {
- BLI_dynstr_append(dynstr, "(");
- for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %d" : "%d", RNA_property_int_get_index(ptr, prop, i));
+ if (index != -1) {
+ BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get_index(ptr, prop, index));
+ }
+ else {
+ BLI_dynstr_append(dynstr, "(");
+ for (i = 0; i < len; i++) {
+ BLI_dynstr_appendf(dynstr, i ? ", %d" : "%d", RNA_property_int_get_index(ptr, prop, i));
+ }
+ if (len == 1)
+ BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
+ BLI_dynstr_append(dynstr, ")");
}
- if (len == 1)
- BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
- BLI_dynstr_append(dynstr, ")");
}
break;
case PROP_FLOAT:
@@ -4800,13 +5028,18 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
}
else {
- BLI_dynstr_append(dynstr, "(");
- for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %g" : "%g", RNA_property_float_get_index(ptr, prop, i));
+ if (index != -1) {
+ BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get_index(ptr, prop, index));
+ }
+ else {
+ BLI_dynstr_append(dynstr, "(");
+ for (i = 0; i < len; i++) {
+ BLI_dynstr_appendf(dynstr, i ? ", %g" : "%g", RNA_property_float_get_index(ptr, prop, i));
+ }
+ if (len == 1)
+ BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
+ BLI_dynstr_append(dynstr, ")");
}
- if (len == 1)
- BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
- BLI_dynstr_append(dynstr, ")");
}
break;
case PROP_STRING:
@@ -4872,7 +5105,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
case PROP_POINTER:
{
PointerRNA tptr = RNA_property_pointer_get(ptr, prop);
- cstring = RNA_pointer_as_string(C, &tptr);
+ cstring = RNA_pointer_as_string(C, ptr, prop, &tptr);
BLI_dynstr_append(dynstr, cstring);
MEM_freeN(cstring);
break;
@@ -4893,7 +5126,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
first_time = 0;
/* now get every prop of the collection */
- cstring = RNA_pointer_as_string(C, &itemptr);
+ cstring = RNA_pointer_as_string(C, ptr, prop, &itemptr);
BLI_dynstr_append(dynstr, cstring);
MEM_freeN(cstring);
}
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 1f9503f..07c394a 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -596,7 +596,7 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Action_active_pose_marker_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Pose Marker", "Active pose marker for this action");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "active_marker");
RNA_def_property_int_funcs(prop, "rna_Action_active_pose_marker_index_get",
"rna_Action_active_pose_marker_index_set", "rna_Action_active_pose_marker_index_range");
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 7229ddd..d6ea53f 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -52,6 +52,20 @@ EnumPropertyItem keyingset_path_grouping_items[] = {
{0, NULL, 0, NULL, NULL}
};
+/* It would be cool to get rid of this 'INSERTKEY_' prefix in 'py strings' values, but it would break existing
+ * exported keyingset... :/
+ */
+EnumPropertyItem keying_flag_items[] = {
+ {INSERTKEY_NEEDED, "INSERTKEY_NEEDED", 0, "Only Needed",
+ "Only insert keyframes where they're needed in the relevant F-Curves"},
+ {INSERTKEY_MATRIX, "INSERTKEY_VISUAL", 0, "Visual Keying",
+ "Insert keyframes based on 'visual transforms'"},
+ {INSERTKEY_XYZ2RGB, "INSERTKEY_XYZ_TO_RGB", 0, "XYZ=RGB Colors",
+ "Color for newly added transformation F-Curves (Location, Rotation, Scale) "
+ "and also Color is based on the transform axis"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "BLI_math_base.h"
@@ -184,6 +198,8 @@ static void rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type)
RNA_struct_free_extension(type, &ksi->ext);
RNA_struct_free(&BLENDER_RNA, type);
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
/* unlink Blender-side data */
ANIM_keyingset_info_unregister(bmain, ksi);
}
@@ -220,7 +236,7 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v
memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo));
/* set RNA-extensions info */
- ksi->ext.srna = RNA_def_struct(&BLENDER_RNA, ksi->idname, "KeyingSetInfo");
+ ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
ksi->ext.data = data;
ksi->ext.call = call;
ksi->ext.free = free;
@@ -235,6 +251,8 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v
/* add and register with other info as needed */
ANIM_keyingset_info_register(ksi);
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
/* return the struct-rna added */
return ksi->ext.srna;
}
@@ -518,17 +536,6 @@ static void rna_def_common_keying_flags(StructRNA *srna, short UNUSED(reg))
{
PropertyRNA *prop;
- static EnumPropertyItem keying_flag_items[] = {
- {INSERTKEY_NEEDED, "INSERTKEY_NEEDED", 0, "Only Needed",
- "Only insert keyframes where they're needed in the relevant F-Curves"},
- {INSERTKEY_MATRIX, "INSERTKEY_VISUAL", 0, "Visual Keying",
- "Insert keyframes based on 'visual transforms'"},
- {INSERTKEY_XYZ2RGB, "INSERTKEY_XYZ_TO_RGB", 0, "XYZ=RGB Colors",
- "Color for newly added transformation F-Curves (Location, Rotation, Scale) "
- "and also Color is based on the transform axis"},
- {0, NULL, 0, NULL, NULL}
- };
-
prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "keyingflag");
RNA_def_property_enum_items(prop, keying_flag_items);
@@ -574,7 +581,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
@@ -774,7 +781,7 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 4c566d7..6c48ed2 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -529,6 +529,11 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_LOCAL_LOCATION);
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+ prop = RNA_def_property(srna, "use_relative_parent", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Relative Parenting", "Object children will use relative transform, like deform");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_RELATIVE_PARENTING);
+ RNA_def_property_update(prop, 0, "rna_Armature_update_data");
+
prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
RNA_def_property_ui_text(prop, "Draw Wire",
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 7bdebd6..3d5106b 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -65,6 +65,7 @@ EnumPropertyItem brush_sculpt_tool_items[] = {
{SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_PINCH, "Pinch", ""},
{SCULPT_TOOL_ROTATE, "ROTATE", ICON_BRUSH_ROTATE, "Rotate", ""},
{SCULPT_TOOL_SCRAPE, "SCRAPE", ICON_BRUSH_SCRAPE, "Scrape", ""},
+ {SCULPT_TOOL_SIMPLIFY, "SIMPLIFY", ICON_BRUSH_SUBTRACT /* icon TODO */, "Simplify", ""},
{SCULPT_TOOL_SMOOTH, "SMOOTH", ICON_BRUSH_SMOOTH, "Smooth", ""},
{SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_BRUSH_SNAKE_HOOK, "Snake Hook", ""},
{SCULPT_TOOL_THUMB, "THUMB", ICON_BRUSH_THUMB, "Thumb", ""},
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index b72bba0..0b1e1c2 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -112,8 +112,8 @@ void RNA_def_camera(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem prop_lens_unit_items[] = {
- {0, "MILLIMETERS", 0, "Millimeters", ""},
- {CAM_ANGLETOGGLE, "DEGREES", 0, "Degrees", ""},
+ {0, "MILLIMETERS", 0, "Millimeters", "Specify the lens in millimeters"},
+ {CAM_ANGLETOGGLE, "FOV", 0, "Field of View", "Specify the lens as the field of view's angle"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem sensor_fit_items[] = {
@@ -154,23 +154,23 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
prop = RNA_def_property(srna, "angle_x", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_range(prop, M_PI * (0.367 / 180.0), M_PI * (172.847 / 180.0));
+ RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Horizontal FOV", "Camera lens horizontal field of view in degrees");
+ RNA_def_property_ui_text(prop, "Horizontal FOV", "Camera lens horizontal field of view");
RNA_def_property_float_funcs(prop, "rna_Camera_angle_x_get", "rna_Camera_angle_x_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
prop = RNA_def_property(srna, "angle_y", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_range(prop, M_PI * (0.367 / 180.0), M_PI * (172.847 / 180.0));
+ RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Vertical FOV", "Camera lens vertical field of view in degrees");
+ RNA_def_property_ui_text(prop, "Vertical FOV", "Camera lens vertical field of view");
RNA_def_property_float_funcs(prop, "rna_Camera_angle_y_get", "rna_Camera_angle_y_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_range(prop, M_PI * (0.367 / 180.0), M_PI * (172.847 / 180.0));
+ RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Field of View", "Camera lens field of view in degrees");
+ RNA_def_property_ui_text(prop, "Field of View", "Camera lens field of view");
RNA_def_property_float_funcs(prop, "rna_Camera_angle_get", "rna_Camera_angle_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 5752fd3..9ce3b31 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -424,7 +424,7 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int
}
}
-static EnumPropertyItem* rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
{
Scene *scene = CTX_data_scene(C);
EnumPropertyItem *items = NULL;
@@ -973,15 +973,26 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagement_update");
/* ** Colorspace ** */
- srna = RNA_def_struct(brna, "ColorManagedColorspaceSettings", NULL);
- RNA_def_struct_ui_text(srna, "ColorManagedColorspaceSettings", "Input color space settings");
+ srna = RNA_def_struct(brna, "ColorManagedInputColorspaceSettings", NULL);
+ RNA_def_struct_ui_text(srna, "ColorManagedInputColorspaceSettings", "Input color space settings");
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
"rna_ColorManagedColorspaceSettings_colorspace_itemf");
- RNA_def_property_ui_text(prop, "Color Space", "Input color space name");
+ RNA_def_property_ui_text(prop, "Input Color Space", "Color space of the image or movie on disk");
+ RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagedColorspaceSettings_reload_update");
+
+ srna = RNA_def_struct(brna, "ColorManagedSequencerColorspaceSettings", NULL);
+ RNA_def_struct_ui_text(srna, "ColorManagedSequencerColorspaceSettings", "Input color space settings");
+
+ prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, color_space_items);
+ RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
+ "rna_ColorManagedColorspaceSettings_colorspace_set",
+ "rna_ColorManagedColorspaceSettings_colorspace_itemf");
+ RNA_def_property_ui_text(prop, "Color Space", "Color space that the sequencer operates in");
RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagedColorspaceSettings_reload_update");
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 30a9bfd..0c8fb3d 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -214,7 +214,7 @@ static void rna_Constraint_name_set(PointerRNA *ptr, const char *value)
/* if we have the list, check for unique name, otherwise give up */
if (list)
- unique_constraint_name(con, list);
+ BKE_unique_constraint_name(con, list);
}
/* fix all the animation data which may link to this */
@@ -293,7 +293,7 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSED(C),
PropertyRNA *UNUSED(prop), int *UNUSED(free))
{
bConstraint *con = (bConstraint *)ptr->data;
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1392,19 +1392,19 @@ static void rna_def_constraint_rigid_body_joint(BlenderRNA *brna)
prop = RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "axX");
RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
- RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis in degrees");
+ RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "axis_y", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "axY");
RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
- RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis in degrees");
+ RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "axis_z", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "axZ");
RNA_def_property_range(prop, -M_PI * 2, M_PI * 2);
- RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis in degrees");
+ RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "use_linked_collision", PROP_BOOLEAN, PROP_NONE);
@@ -1528,7 +1528,7 @@ static void rna_def_constraint_clamp_to(BlenderRNA *brna)
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Curve_object_poll");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
+ RNA_def_property_ui_text(prop, "Target", "Target Object (Curves only)");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index bb1ecea..b94d7eb 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -391,7 +391,9 @@ static int rna_validate_identifier(const char *identifier, char *error, int prop
{
int a = 0;
- /* list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
+ /* list is from...
+ * ", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist if kw not in {"False", "None", "True"}])
+ */
static const char *kwlist[] = {
/* "False", "None", "True", */
"and", "as", "assert", "break",
@@ -621,33 +623,20 @@ static StructDefRNA *rna_find_def_struct(StructRNA *srna)
}
/* Struct Definition */
-
-StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
+StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
{
- StructRNA *srna, *srnafrom = NULL;
+ StructRNA *srna;
StructDefRNA *ds = NULL, *dsfrom = NULL;
PropertyRNA *prop;
-
+
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, 0) == 0) {
+ if (rna_validate_identifier(identifier, error, FALSE) == 0) {
fprintf(stderr, "%s: struct identifier \"%s\" error - %s\n", __func__, identifier, error);
DefRNA.error = 1;
}
}
-
- if (from) {
- /* find struct to derive from */
- for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (strcmp(srnafrom->identifier, from) == 0)
- break;
-
- if (!srnafrom) {
- fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
- DefRNA.error = 1;
- }
- }
srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
DefRNA.laststruct = srna;
@@ -668,7 +657,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
else
srna->base = srnafrom;
}
-
+
srna->identifier = identifier;
srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
srna->description = "";
@@ -739,6 +728,28 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
return srna;
}
+StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
+{
+ StructRNA *srnafrom = NULL;
+
+ /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */
+ BLI_assert(DefRNA.preprocess);
+
+ if (from) {
+ /* find struct to derive from */
+ for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
+ if (strcmp(srnafrom->identifier, from) == 0)
+ break;
+
+ if (!srnafrom) {
+ fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
+ DefRNA.error = 1;
+ }
+ }
+
+ return RNA_def_struct_ptr(brna, identifier, srnafrom);
+}
+
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
{
StructDefRNA *ds;
@@ -909,7 +920,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, 1) == 0) {
+ if (rna_validate_identifier(identifier, error, TRUE) == 0) {
fprintf(stderr, "%s: property identifier \"%s.%s\" - %s\n", __func__,
CONTAINER_RNA_ID(cont), identifier, error);
DefRNA.error = 1;
@@ -926,6 +937,16 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
rna_addtail(&dcont->properties, dprop);
}
+ else {
+#ifdef DEBUG
+ char error[512];
+ if (rna_validate_identifier(identifier, error, TRUE) == 0) {
+ fprintf(stderr, "%s: runtime property identifier \"%s.%s\" - %s\n", __func__,
+ CONTAINER_RNA_ID(cont), identifier, error);
+ DefRNA.error = 1;
+ }
+#endif
+ }
prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
@@ -2005,6 +2026,38 @@ void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const ch
}
}
+void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc)
+{
+ BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+
+ if (getfunc) bprop->get_ex = getfunc;
+ if (setfunc) bprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc)
+{
+ BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+
+ if (getfunc) bprop->getarray_ex = getfunc;
+ if (setfunc) bprop->setarray_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2037,6 +2090,38 @@ void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *
}
}
+void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
+{
+ IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+
+ if (getfunc) iprop->get_ex = getfunc;
+ if (setfunc) iprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc)
+{
+ IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
+
+ if (getfunc) iprop->getarray_ex = getfunc;
+ if (setfunc) iprop->setarray_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2069,6 +2154,40 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char
}
}
+void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
+{
+ FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
+
+ if (getfunc) fprop->get_ex = getfunc;
+ if (setfunc) fprop->set_ex = setfunc;
+ if (rangefunc) fprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc)
+{
+ FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
+
+ if (getfunc) fprop->getarray_ex = getfunc;
+ if (setfunc) fprop->setarray_ex = setfunc;
+ if (rangefunc) fprop->range_ex = rangefunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2095,6 +2214,29 @@ void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char
}
}
+void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc)
+{
+ EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+
+ if (getfunc) eprop->get_ex = getfunc;
+ if (setfunc) eprop->set_ex = setfunc;
+ if (itemfunc) eprop->itemf = itemfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
+void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data)
+{
+ EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+ eprop->py_data = py_data;
+}
+
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
{
StructRNA *srna = DefRNA.laststruct;
@@ -2121,6 +2263,23 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha
}
}
+void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc)
+{
+ StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
+
+ if (getfunc) sprop->get_ex = getfunc;
+ if (lengthfunc) sprop->length_ex = lengthfunc;
+ if (setfunc) sprop->set_ex = setfunc;
+
+ if (getfunc || setfunc) {
+ /* don't save in id properties */
+ prop->flag &= ~PROP_IDPROPERTY;
+
+ if (!setfunc)
+ prop->flag &= ~PROP_EDITABLE;
+ }
+}
+
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set,
const char *typef, const char *poll)
{
@@ -2435,12 +2594,6 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
eprop->itemf = itemfunc;
}
-void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data)
-{
- EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
- eprop->py_data = py_data;
-}
-
PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
float hardmin, float hardmax, const char *ui_name, const char *ui_description,
float softmin, float softmax)
@@ -2674,7 +2827,7 @@ static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
if (DefRNA.preprocess) {
char error[512];
- if (rna_validate_identifier(identifier, error, 0) == 0) {
+ if (rna_validate_identifier(identifier, error, FALSE) == 0) {
fprintf(stderr, "%s: function identifier \"%s\" - %s\n", __func__, identifier, error);
DefRNA.error = 1;
}
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 4f9f200..99d2f6d 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -32,6 +32,8 @@
#include "rna_internal.h"
+#include "BLI_math_base.h"
+
#include "BKE_modifier.h"
#include "BKE_dynamicpaint.h"
@@ -219,6 +221,14 @@ static int rna_DynamicPaint_is_cache_user_get(PointerRNA *ptr)
return (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) ? 1 : 0;
}
+/* is some 3D view preview available */
+static int rna_DynamicPaint_use_color_preview_get(PointerRNA *ptr)
+{
+ DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data;
+
+ return dynamicPaint_surfaceHasColorPreview(surface);
+}
+
/* does output layer exist*/
static int rna_DynamicPaint_is_output_exists(DynamicPaintSurface *surface, Object *ob, int index)
{
@@ -239,6 +249,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_PAINT;
tmp.identifier = "PAINT";
tmp.name = "Paint";
+ tmp.icon = ICON_TPAINT_HLT;
RNA_enum_item_add(&item, &totitem, &tmp);
/* Displace */
@@ -248,6 +259,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_DISPLACE;
tmp.identifier = "DISPLACE";
tmp.name = "Displace";
+ tmp.icon = ICON_MOD_DISPLACE;
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -256,6 +268,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_WEIGHT;
tmp.identifier = "WEIGHT";
tmp.name = "Weight";
+ tmp.icon = ICON_MOD_VERTEX_WEIGHT;
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -264,6 +277,7 @@ static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, Pointe
tmp.value = MOD_DPAINT_SURFACE_T_WAVE;
tmp.identifier = "WAVE";
tmp.name = "Waves";
+ tmp.icon = ICON_MOD_WAVE;
RNA_enum_item_add(&item, &totitem, &tmp);
}
@@ -705,6 +719,14 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_DynamicPaint_is_cache_user_get", NULL);
RNA_def_property_ui_text(prop, "Use Cache", "");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+
+ /* whether this surface has preview data for 3D view */
+ RNA_define_verify_sdna(FALSE);
+ prop = RNA_def_property(srna, "use_color_preview", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_DynamicPaint_use_color_preview_get", NULL);
+ RNA_def_property_ui_text(prop, "Use Color Preview", "Whether this surface has some color preview for 3D view");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+ RNA_define_verify_sdna(TRUE);
}
static void rna_def_dynamic_paint_canvas_settings(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 9fedbee..11510b7 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -116,15 +116,6 @@ static void rna_Image_fields_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
BKE_image_release_ibuf(ima, ibuf, lock);
}
-static void rna_Image_free_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
-{
- Image *ima = ptr->id.data;
- BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
- WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id);
- DAG_id_tag_update(&ima->id, 0);
-}
-
-
static void rna_Image_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Image *ima = ptr->id.data;
@@ -139,6 +130,15 @@ static void rna_Image_generated_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
}
+static void rna_Image_colormanage_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ Image *ima = ptr->id.data;
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_COLORMANAGE);
+ DAG_id_tag_update(&ima->id, 0);
+ WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
+ WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id);
+}
+
static void rna_ImageUser_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
ImageUser *iuser = ptr->data;
@@ -377,6 +377,38 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
BKE_image_release_ibuf(ima, ibuf, lock);
}
+static int rna_Image_channels_get(PointerRNA *ptr)
+{
+ Image *im = (Image *)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+ int channels = 0;
+
+ ibuf = BKE_image_acquire_ibuf(im, NULL, &lock);
+ if (ibuf)
+ channels = ibuf->channels;
+
+ BKE_image_release_ibuf(im, ibuf, lock);
+
+ return channels;
+}
+
+static int rna_Image_is_float_get(PointerRNA *ptr)
+{
+ Image *im = (Image *)ptr->data;
+ ImBuf *ibuf;
+ void *lock;
+ int is_float = FALSE;
+
+ ibuf = BKE_image_acquire_ibuf(im, NULL, &lock);
+ if (ibuf)
+ is_float = ibuf->rect_float != NULL;
+
+ BKE_image_release_ibuf(im, ibuf, lock);
+
+ return is_float;
+}
+
#else
static void rna_def_imageuser(BlenderRNA *brna)
@@ -463,6 +495,11 @@ static void rna_def_image(BlenderRNA *brna)
{IMA_STD_FIELD, "ODD", 0, "Lower First", "Lower field first"},
{0, NULL, 0, NULL, NULL}
};
+ static const EnumPropertyItem alpha_mode_items[] = {
+ {IMA_ALPHA_STRAIGHT, "STRAIGHT", 0, "Straight", "Transparent RGB and alpha pixels are unmodified"},
+ {IMA_ALPHA_PREMUL, "PREMUL", 0, "Premultiplied", "Transparent RGB pixels are multiplied by the alpha channel"},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "Image", "ID");
RNA_def_struct_ui_text(srna, "Image", "Image datablock referencing an external or packed image");
@@ -512,23 +549,17 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_fields_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DO_PREMUL);
- RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha");
- RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_free_update");
-
- prop = RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_CM_PREDIVIDE);
- RNA_def_property_ui_text(prop, "Color Unpremultiply",
- "For premultiplied alpha images, do color space conversion on colors without alpha, "
- "to avoid fringing for images with light backgrounds");
- RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_free_update");
prop = RNA_def_property(srna, "view_as_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_VIEW_AS_RENDER);
RNA_def_property_ui_text(prop, "View as Render", "Apply render part of display transformation when displaying this image on the screen");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
+ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMA_IGNORE_ALPHA);
+ RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information from the image or make image fully opaque");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
+
prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -665,6 +696,10 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Duration", "Duration (in frames) of the image (1 when not a video/sequence)");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ /* NOTE about pixels/channels/is_floa:
+ * this properties describes how image is stored internally (inside of ImBuf),
+ * not how it was saved to disk or how it'll be saved on disk
+ */
prop = RNA_def_property(srna, "pixels", PROP_FLOAT, PROP_NONE);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_multi_array(prop, 1, NULL);
@@ -672,11 +707,26 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_dynamic_array_funcs(prop, "rna_Image_pixels_get_length");
RNA_def_property_float_funcs(prop, "rna_Image_pixels_get", "rna_Image_pixels_set", NULL);
+ prop = RNA_def_property(srna, "channels", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop, "rna_Image_channels_get", NULL, NULL);
+ RNA_def_property_ui_text(prop, "Channels", "Number of channels in pixels nuffer");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "is_float", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_Image_is_float_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Is Float", "True if this image is stored in float buffer");
+
prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
+ prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, alpha_mode_items);
+ RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
+
RNA_api_image(srna);
}
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index ccfb83b..43ec09d 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -30,6 +30,8 @@
#include "DNA_listBase.h"
+#include "RNA_types.h"
+
struct BlenderRNA;
struct ContainerRNA;
struct StructRNA;
@@ -64,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
-typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
+typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
@@ -91,7 +93,7 @@ typedef void (*PropEnumSetFunc)(struct PointerRNA *ptr, int value);
typedef EnumPropertyItem *(*PropEnumItemFunc)(struct bContext *C, struct PointerRNA *ptr,
struct PropertyRNA *prop, int *free);
typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr);
-typedef StructRNA* (*PropPointerTypeFunc)(struct PointerRNA *ptr);
+typedef StructRNA *(*PropPointerTypeFunc)(struct PointerRNA *ptr);
typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef int (*PropPointerPollFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef void (*PropCollectionBeginFunc)(struct CollectionPropertyIterator *iter, struct PointerRNA *ptr);
@@ -103,6 +105,27 @@ typedef int (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key, stru
typedef int (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key, struct PointerRNA *r_ptr);
typedef int (*PropCollectionAssignIntFunc)(struct PointerRNA *ptr, int key, const struct PointerRNA *assign_ptr);
+/* extended versions with PropertyRNA argument */
+typedef int (*PropBooleanGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropBooleanSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*PropBooleanArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*PropBooleanArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef int (*PropIntGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropIntSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+typedef void (*PropIntArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values);
+typedef void (*PropIntArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values);
+typedef void (*PropIntRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax);
+typedef float (*PropFloatGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropFloatSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value);
+typedef void (*PropFloatArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values);
+typedef void (*PropFloatArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values);
+typedef void (*PropFloatRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax);
+typedef void (*PropStringGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value);
+typedef int (*PropStringLengthFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropStringSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value);
+typedef int (*PropEnumGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop);
+typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value);
+
/* Container - generic abstracted container of RNA properties */
typedef struct ContainerRNA {
void *next, *prev;
@@ -193,10 +216,14 @@ typedef struct BoolPropertyRNA {
PropBooleanGetFunc get;
PropBooleanSetFunc set;
-
PropBooleanArrayGetFunc getarray;
PropBooleanArraySetFunc setarray;
+ PropBooleanGetFuncEx get_ex;
+ PropBooleanSetFuncEx set_ex;
+ PropBooleanArrayGetFuncEx getarray_ex;
+ PropBooleanArraySetFuncEx setarray_ex;
+
int defaultvalue;
const int *defaultarray;
} BoolPropertyRNA;
@@ -206,12 +233,16 @@ typedef struct IntPropertyRNA {
PropIntGetFunc get;
PropIntSetFunc set;
-
PropIntArrayGetFunc getarray;
PropIntArraySetFunc setarray;
-
PropIntRangeFunc range;
+ PropIntGetFuncEx get_ex;
+ PropIntSetFuncEx set_ex;
+ PropIntArrayGetFuncEx getarray_ex;
+ PropIntArraySetFuncEx setarray_ex;
+ PropIntRangeFuncEx range_ex;
+
int softmin, softmax;
int hardmin, hardmax;
int step;
@@ -225,12 +256,16 @@ typedef struct FloatPropertyRNA {
PropFloatGetFunc get;
PropFloatSetFunc set;
-
PropFloatArrayGetFunc getarray;
PropFloatArraySetFunc setarray;
-
PropFloatRangeFunc range;
+ PropFloatGetFuncEx get_ex;
+ PropFloatSetFuncEx set_ex;
+ PropFloatArrayGetFuncEx getarray_ex;
+ PropFloatArraySetFuncEx setarray_ex;
+ PropFloatRangeFuncEx range_ex;
+
float softmin, softmax;
float hardmin, hardmax;
float step;
@@ -247,6 +282,10 @@ typedef struct StringPropertyRNA {
PropStringLengthFunc length;
PropStringSetFunc set;
+ PropStringGetFuncEx get_ex;
+ PropStringLengthFuncEx length_ex;
+ PropStringSetFuncEx set_ex;
+
int maxlength; /* includes string terminator! */
const char *defaultvalue;
@@ -258,6 +297,9 @@ typedef struct EnumPropertyRNA {
PropEnumGetFunc get;
PropEnumSetFunc set;
PropEnumItemFunc itemf;
+
+ PropEnumGetFuncEx get_ex;
+ PropEnumSetFuncEx set_ex;
void *py_data; /* store py callback here */
EnumPropertyItem *item;
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index af39500..660f6fc 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -54,7 +54,7 @@ static void rna_Lamp_buffer_size_set(PointerRNA *ptr, int value)
{
Lamp *la = (Lamp *)ptr->data;
- CLAMP(value, 512, 10240);
+ CLAMP(value, 128, 10240);
la->bufsize = value;
la->bufsize &= (~15); /* round to multiple of 16 */
}
@@ -540,7 +540,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area)
prop = RNA_def_property(srna, "shadow_buffer_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "bufsize");
- RNA_def_property_range(prop, 512, 10240);
+ RNA_def_property_range(prop, 128, 10240);
RNA_def_property_ui_text(prop, "Shadow Buffer Size",
"Resolution of the shadow buffer, higher values give crisper shadows "
"but use more memory");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index cf9415a..cc74fce 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -118,9 +118,9 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA
}
}
-static Scene *rna_Main_scenes_new(Main *UNUSED(bmain), const char *name)
+static Scene *rna_Main_scenes_new(Main *bmain, const char *name)
{
- return BKE_scene_add(name);
+ return BKE_scene_add(bmain, name);
}
static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr)
{
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 287995e..d5b8e4c 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -152,8 +152,8 @@ void rna_Mesh_update_draw(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Mesh *me = ptr->data;
- if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) {
- me->editflag ^= ME_EDIT_PAINT_MASK;
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
+ me->editflag &= ~ME_EDIT_PAINT_FACE_SEL;
}
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -161,8 +161,8 @@ static void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Mesh *me = ptr->data;
- if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) {
- me->editflag ^= ME_EDIT_VERT_SEL;
+ if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
+ me->editflag &= ~ME_EDIT_PAINT_VERT_SEL;
}
rna_Mesh_update_draw(bmain, scene, ptr);
}
@@ -1233,6 +1233,26 @@ static char *rna_MeshStringProperty_path(PointerRNA *ptr)
return rna_PolyCustomData_data_path(ptr, "layers_string", CD_PROP_STR);
}
+/* XXX, we dont have propper byte string support yet, so for now use the (bytes + 1)
+ * bmesh API exposes correct python/bytestring access */
+void rna_MeshStringProperty_s_get(PointerRNA *ptr, char *value)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ BLI_strncpy(value, ms->s, (int)ms->s_len + 1);
+}
+
+int rna_MeshStringProperty_s_length(PointerRNA *ptr)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ return (int)ms->s_len + 1;
+}
+
+void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value)
+{
+ MStringProperty *ms = (MStringProperty *)ptr->data;
+ BLI_strncpy(ms->s, value, sizeof(ms->s));
+}
+
static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@@ -2161,6 +2181,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
/* low level mesh data access, treat as bytes */
prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING);
RNA_def_property_string_sdna(prop, NULL, "s");
+ RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set");
RNA_def_property_ui_text(prop, "Value", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
@@ -2353,7 +2374,7 @@ static void rna_def_tessface_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_RNAPTR);
RNA_def_function_return(func, parm);
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshColorLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_vertex_color_active_get",
"rna_Mesh_tessface_vertex_color_active_set", NULL, NULL);
@@ -2397,7 +2418,7 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
#endif
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshLoopColorLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_vertex_color_active_get",
"rna_Mesh_vertex_color_active_set", NULL, NULL);
@@ -2425,7 +2446,7 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "UV Loop Layers", "Collection of uv loop layers");
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_active_get",
"rna_Mesh_uv_layer_active_set", NULL, NULL);
@@ -2530,7 +2551,7 @@ static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_uv_texture_active_get",
"rna_Mesh_tessface_uv_texture_active_set", NULL, NULL);
@@ -2575,7 +2596,7 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
#endif
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_active_get",
"rna_Mesh_uv_texture_active_set", NULL, NULL);
@@ -2693,7 +2714,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Loop Layers", "All UV loop layers");
rna_def_uv_layers(brna, prop);
- prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_clone_get",
"rna_Mesh_uv_layer_clone_set", NULL, NULL);
@@ -2705,7 +2726,7 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_Mesh_uv_layer_clone_index_set", "rna_Mesh_uv_layer_index_range");
RNA_def_property_ui_text(prop, "Clone UV loop layer Index", "Clone UV loop layer index");
- prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshUVLoopLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_stencil_get",
"rna_Mesh_uv_layer_stencil_set", NULL, NULL);
@@ -2736,7 +2757,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Maps", "All UV maps");
rna_def_uv_textures(brna, prop);
- prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_clone_get",
"rna_Mesh_uv_texture_clone_set", NULL, NULL);
@@ -2748,7 +2769,7 @@ static void rna_def_mesh(BlenderRNA *brna)
"rna_Mesh_uv_texture_clone_index_set", "rna_Mesh_uv_texture_index_range");
RNA_def_property_ui_text(prop, "Clone UV Map Index", "Clone UV map index");
- prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshTexturePolyLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_stencil_get",
"rna_Mesh_uv_texture_stencil_set", NULL, NULL);
@@ -2928,7 +2949,7 @@ static void rna_def_mesh(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_extra_face_angle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEXTRA_FACEANG);
RNA_def_property_ui_text(prop, "Face Angles",
- "Display the angles in the selected edges in degrees, "
+ "Display the angles in the selected edges, "
"using global values when set in the transform panel");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
@@ -2966,17 +2987,33 @@ static void rna_def_mesh(BlenderRNA *brna)
"(for when both sides of mesh have matching, unique topology)");
prop = RNA_def_property(srna, "use_paint_mask", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_MASK);
+ RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_FACE_SEL);
RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting");
RNA_def_property_ui_icon(prop, ICON_FACESEL_HLT, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_facemask");
prop = RNA_def_property(srna, "use_paint_mask_vertex", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERT_SEL);
+ RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_VERT_SEL);
RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex selection masking for painting (weight paint only)");
RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask");
+
+
+ /* customdata flags */
+ prop = RNA_def_property(srna, "use_customdata_vertex_bevel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_BWEIGHT);
+ RNA_def_property_ui_text(prop, "Store Vertex Bevel Weight", "");
+
+ prop = RNA_def_property(srna, "use_customdata_edge_bevel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_BWEIGHT);
+ RNA_def_property_ui_text(prop, "Store Edge Bevel Weight", "");
+
+ prop = RNA_def_property(srna, "use_customdata_edge_crease", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_CREASE);
+ RNA_def_property_ui_text(prop, "Store Edge Crease", "");
+
+
/* readonly editmesh info - use for extrude menu */
prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index a2b0945..7a576c8 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -59,6 +59,7 @@
EnumPropertyItem modifier_type_items[] = {
{0, "", 0, N_("Modify"), ""},
{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
+ {eModifierType_UVWarp, "UV_WARP", ICON_MOD_UVPROJECT, "UV Warp", ""},
{eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""},
{eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""},
{eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT,
@@ -129,7 +130,7 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
{
ModifierData *md = (ModifierData *)ptr->data;
- switch (md->type) {
+ switch ((ModifierType)md->type) {
case eModifierType_Subsurf:
return &RNA_SubsurfModifier;
case eModifierType_Lattice:
@@ -216,9 +217,16 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_LaplacianSmoothModifier;
case eModifierType_Triangulate:
return &RNA_TriangulateModifier;
- default:
+ case eModifierType_UVWarp:
+ return &RNA_UVWarpModifier;
+ /* Default */
+ case eModifierType_None:
+ case eModifierType_ShapeKey:
+ case NUM_MODIFIER_TYPES:
return &RNA_Modifier;
}
+
+ return &RNA_Modifier;
}
static void rna_Modifier_name_set(PointerRNA *ptr, const char *value)
@@ -738,6 +746,18 @@ static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value)
md->bevel_angle = (int)value;
}
+static void rna_UVWarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
+ rna_object_vgroup_name_set(ptr, value, umd->vgroup_name, sizeof(umd->vgroup_name));
+}
+
+static void rna_UVWarpModifier_uvlayer_set(PointerRNA *ptr, const char *value)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
+ rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name));
+}
+
#else
static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[])
@@ -2773,6 +2793,75 @@ static void rna_def_modifier_screw(BlenderRNA *brna)
#endif
}
+static void rna_def_modifier_uvwarp(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem uvwarp_axis[] = {
+ {0, "X", 0, "X", ""},
+ {1, "Y", 0, "Y", ""},
+ {2, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "UVWarpModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "UVWarp Modifier", "Add target position to uv coordinates");
+ RNA_def_struct_sdna(srna, "UVWarpModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_UVPROJECT);
+
+ prop = RNA_def_property(srna, "axis_u", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "axis_u");
+ RNA_def_property_enum_items(prop, uvwarp_axis);
+ RNA_def_property_ui_text(prop, "U-Axis", "Pole axis for rotation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "axis_v", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "axis_v");
+ RNA_def_property_enum_items(prop, uvwarp_axis);
+ RNA_def_property_ui_text(prop, "V-Axis", "Pole axis for rotation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "center");
+ RNA_def_property_ui_text(prop, "UV Center", "Center point for rotate/scale");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "object_src");
+ RNA_def_property_ui_text(prop, "Target", "Object defining offset");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_property(srna, "bone_from", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bone_src");
+ RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_property(srna, "object_to", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "object_dst");
+ RNA_def_property_ui_text(prop, "Target", "Object defining offset");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_property(srna, "bone_to", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bone_dst");
+ RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "vgroup_name");
+ RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_vgroup_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
+ RNA_def_property_ui_text(prop, "UV Layer", "UV Layer name");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_uvlayer_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *srna)
{
static EnumPropertyItem weightvg_mask_tex_map_items[] = {
@@ -3180,7 +3269,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "size");
- RNA_def_property_ui_text(prop, "Size", "");
+ RNA_def_property_ui_text(prop, "Size", "Surface scale factor (does not affect the height of the waves)");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
@@ -3221,16 +3310,17 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
- prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "spatial_size");
RNA_def_property_ui_range(prop, 1, 512, 2, 0);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Spatial Size", "Physical size of the simulation domain (m)");
+ RNA_def_property_ui_text(prop, "Spatial Size",
+ "Size of the simulation domain (in meters), and of the generated geometry (in BU)");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wind_velocity", PROP_FLOAT, PROP_VELOCITY);
RNA_def_property_float_sdna(prop, NULL, "wind_velocity");
- RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed (m/s)");
+ RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_FACTOR);
@@ -3243,42 +3333,43 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "smallest_wave");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0, FLT_MAX);
- RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength (m)");
+ RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wave_alignment", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "wave_alignment");
RNA_def_property_range(prop, 0.0, 10.0);
- RNA_def_property_ui_text(prop, "Wave Alignment", "");
+ RNA_def_property_ui_text(prop, "Wave Alignment", "How much the waves are aligned to each other");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wave_direction", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "wave_direction");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Wave Direction", "");
+ RNA_def_property_ui_text(prop, "Wave Direction", "Main direction of the waves when they are (partially) aligned");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "wave_scale", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "wave_scale");
- RNA_def_property_ui_text(prop, "Wave Scale", "");
+ RNA_def_property_ui_text(prop, "Wave Scale", "Scale of the displacement effect");
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
- prop = RNA_def_property(srna, "depth", PROP_FLOAT, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "depth", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "depth");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Depth", "");
+ RNA_def_property_ui_text(prop, "Depth", "Depth of the solid ground below the water surface");
RNA_def_property_ui_range(prop, 0, 250, 1, 0);
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "foam_coverage", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "foam_coverage");
- RNA_def_property_ui_text(prop, "Foam Coverage", "");
+ RNA_def_property_ui_text(prop, "Foam Coverage", "Amount of generated foam");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "bake_foam_fade", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "foam_fade");
- RNA_def_property_ui_text(prop, "Foam Fade", "");
- RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Foam Fade", "How much foam accumulates over time (baked ocean only)");
+ RNA_def_property_ui_range(prop, 0.0, 10.0, 1, 0);
RNA_def_property_update(prop, 0, NULL);
prop = RNA_def_property(srna, "foam_layer_name", PROP_STRING, PROP_NONE);
@@ -3288,33 +3379,34 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
prop = RNA_def_property(srna, "choppiness", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "chop_amount");
- RNA_def_property_ui_text(prop, "Choppiness", "");
+ RNA_def_property_ui_text(prop, "Choppiness",
+ "Choppiness of the wave's crest (adds some horizontal component to the displacement)");
RNA_def_property_ui_range(prop, 0.0, 4.0, 3, 0);
RNA_def_property_float_funcs(prop, NULL, "rna_OceanModifier_ocean_chop_set", NULL);
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
prop = RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "time");
- RNA_def_property_ui_text(prop, "Time", "");
+ RNA_def_property_ui_text(prop, "Time", "Current time of the simulation");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
prop = RNA_def_property(srna, "random_seed", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "seed");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Random Seed", "");
+ RNA_def_property_ui_text(prop, "Random Seed", "Seed of the random generator");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bakestart");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Bake Start", "");
+ RNA_def_property_ui_text(prop, "Bake Start", "Start frame of the ocean baking");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bakeend");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Bake End", "");
+ RNA_def_property_ui_text(prop, "Bake End", "End frame of the ocean baking");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "is_cached", PROP_BOOLEAN, PROP_NONE);
@@ -3480,6 +3572,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_smoke(brna);
rna_def_modifier_solidify(brna);
rna_def_modifier_screw(brna);
+ rna_def_modifier_uvwarp(brna);
rna_def_modifier_weightvgedit(brna);
rna_def_modifier_weightvgmix(brna);
rna_def_modifier_weightvgproximity(brna);
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index 99effc9..3b01859 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -308,7 +308,7 @@ static void rna_def_movieclip(BlenderRNA *brna)
/* color management */
prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 1da9a45..eecdf13 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -271,6 +271,64 @@ static char *rna_Node_path(PointerRNA *ptr)
return BLI_sprintfN("nodes[\"%s\"]", node->name);
}
+static const char *rna_Node_get_node_type(StructRNA *type)
+{
+ bNodeType *nodetype = RNA_struct_blender_type_get(type);
+ if (nodetype) {
+ /* XXX hack: with customnodes branch, nodes will use an identifier string instead of integer ID.
+ * Then this can be returned directly instead of doing this ugly include thingy ...
+ */
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (ID == nodetype->type) { \
+ return EnumName; \
+ }
+
+ #include "rna_nodetree_types.h"
+ }
+ return "";
+}
+
+static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value)
+{
+ bNode *node = ptr->data;
+ bNode *parent = value.data;
+
+ if (parent) {
+ /* XXX only Frame node allowed for now,
+ * in the future should have a poll function or so to test possible attachment.
+ */
+ if (parent->type != NODE_FRAME)
+ return;
+
+ /* make sure parent is not attached to the node */
+ if (nodeAttachNodeCheck(parent, node))
+ return;
+ }
+
+ nodeDetachNode(node);
+ if (parent) {
+ nodeAttachNode(node, parent);
+ }
+}
+
+static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
+{
+ bNode *node = ptr->data;
+ bNode *parent = value.data;
+
+ /* XXX only Frame node allowed for now,
+ * in the future should have a poll function or so to test possible attachment.
+ */
+ if (parent->type != NODE_FRAME)
+ return FALSE;
+
+ /* make sure parent is not attached to the node */
+ if (nodeAttachNodeCheck(parent, node))
+ return FALSE;
+
+ return TRUE;
+}
+
static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
@@ -499,6 +557,20 @@ static void rna_Node_name_set(PointerRNA *ptr, const char *value)
BKE_all_animdata_fix_paths_rename(NULL, "nodes", oldname, node->name);
}
+static void rna_Node_width_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ bNode *node = ptr->data;
+ *min = *softmin = node->typeinfo->minwidth;
+ *max = *softmax = node->typeinfo->maxwidth;
+}
+
+static void rna_Node_height_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ bNode *node = ptr->data;
+ *min = *softmin = node->typeinfo->minheight;
+ *max = *softmax = node->typeinfo->maxheight;
+}
+
static void rna_NodeSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -1070,7 +1142,7 @@ static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value)
/* replace text datablock by filepath */
if (node->id) {
- Text *text = (Text*)node->id;
+ Text *text = (Text *)node->id;
if (value == NODE_SCRIPT_EXTERNAL && text->name) {
BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath));
@@ -1251,12 +1323,20 @@ static void init(void)
static StructRNA *def_node(BlenderRNA *brna, int node_id)
{
StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
NodeInfo *node = nodes + node_id;
srna = RNA_def_struct(brna, node->struct_name, node->base_name);
RNA_def_struct_ui_text(srna, node->ui_name, node->ui_desc);
RNA_def_struct_sdna(srna, "bNode");
+ func = RNA_def_function(srna, "get_node_type", "rna_Node_get_node_type");
+ RNA_def_function_ui_description(func, "Get the identifier of the node type");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
+ parm = RNA_def_string(func, "result", "", 0, "Result", "");
+ RNA_def_function_return(func, parm);
+
return srna;
}
@@ -2441,7 +2521,7 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{
PropertyRNA *prop;
- static EnumPropertyItem type_items[] = {
+ static EnumPropertyItem mode_items[] = {
{CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""},
{CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""},
{CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""},
@@ -2449,10 +2529,10 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, type_items);
- RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)");
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Growing/shrinking mode");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE);
@@ -3178,8 +3258,8 @@ static void def_cmp_premul_key(StructRNA *srna)
PropertyRNA *prop;
static EnumPropertyItem type_items[] = {
- {0, "KEY_TO_PREMUL", 0, "Key to Premul", ""},
- {1, "PREMUL_TO_KEY", 0, "Premul to Key", ""},
+ {0, "STRAIGHT_TO_PREMUL", 0, "Straight to Premul", ""},
+ {1, "PREMUL_TO_STRAIGHT", 0, "Premul to Straight", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -4605,10 +4685,28 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "locx");
RNA_def_property_array(prop, 2);
- RNA_def_property_range(prop, -10000.0f, 10000.0f);
+ RNA_def_property_range(prop, -100000.0f, 100000.0f);
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_update(prop, NC_NODE, "rna_Node_update");
+ prop = RNA_def_property(srna, "width", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "width");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
+ RNA_def_property_ui_text(prop, "Width", "Width of the node");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
+ prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "miniwidth");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
+ RNA_def_property_ui_text(prop, "Width Hidden", "Width of the node in hidden state");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
+ prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "height");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_height_range");
+ RNA_def_property_ui_text(prop, "Height", "Height of the node");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Unique node identifier");
RNA_def_struct_name_property(srna, prop);
@@ -4632,8 +4730,9 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "parent");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_parent_set", NULL, "rna_Node_parent_poll");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to");
prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE);
@@ -4874,12 +4973,12 @@ static void rna_def_texture_nodetree(BlenderRNA *brna)
rna_def_texture_nodetree_api(brna, prop);
}
-static void define_specific_node(BlenderRNA *brna, int id, void (*func)(StructRNA *))
+static void define_specific_node(BlenderRNA *brna, int id, void (*def_func)(StructRNA *))
{
StructRNA *srna = def_node(brna, id);
-
- if (func)
- func(srna);
+
+ if (def_func)
+ def_func(srna);
}
void RNA_def_nodetree(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index 14cdbc6..46f2306 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -84,6 +84,7 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI
DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" )
DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" )
DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" )
+DefNode( ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" )
DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", Bump, "Bump", "" )
DefNode( ShaderNode, SH_NODE_NORMAL_MAP, def_sh_normal_map, "NORMAL_MAP", NormalMap, "Normal Map", "" )
DefNode( ShaderNode, SH_NODE_TANGENT, def_sh_tangent, "TANGENT", Tangent, "Tangent", "" )
@@ -104,12 +105,12 @@ DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TE
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
DefNode( CompositorNode, CMP_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
-DefNode( CompositorNode, CMP_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix RGB", "" )
+DefNode( CompositorNode, CMP_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix", "" )
DefNode( CompositorNode, CMP_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
DefNode( CompositorNode, CMP_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
DefNode( CompositorNode, CMP_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
DefNode( CompositorNode, CMP_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", CurveVec, "Vector Curve", "" )
-DefNode( CompositorNode, CMP_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curve", "" )
+DefNode( CompositorNode, CMP_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
DefNode( CompositorNode, CMP_NODE_ALPHAOVER, def_cmp_alpha_over, "ALPHAOVER", AlphaOver, "Alpha Over", "" )
DefNode( CompositorNode, CMP_NODE_BLUR, def_cmp_blur, "BLUR", Blur, "Blur", "" )
DefNode( CompositorNode, CMP_NODE_FILTER, def_cmp_filter, "FILTER", Filter, "Filter", "" )
@@ -120,11 +121,11 @@ DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBL
DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
DefNode( CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
DefNode( CompositorNode, CMP_NODE_SETALPHA, 0, "SETALPHA", SetAlpha, "Set Alpha", "" )
-DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue/Saturation", "" )
+DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue Saturation Value","" )
DefNode( CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" )
DefNode( CompositorNode, CMP_NODE_R_LAYERS, def_cmp_render_layers, "R_LAYERS", RLayers, "Render Layers", "" )
DefNode( CompositorNode, CMP_NODE_COMPOSITE, 0, "COMPOSITE", Composite, "Composite", "" )
-DefNode( CompositorNode, CMP_NODE_OUTPUT_FILE, def_cmp_output_file, "OUTPUT_FILE", OutputFile, "Output File", "" )
+DefNode( CompositorNode, CMP_NODE_OUTPUT_FILE, def_cmp_output_file, "OUTPUT_FILE", OutputFile, "File Output", "" )
DefNode( CompositorNode, CMP_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
DefNode( CompositorNode, CMP_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
DefNode( CompositorNode, CMP_NODE_ZCOMBINE, def_cmp_zcombine, "ZCOMBINE", Zcombine, "Z Combine", "" )
@@ -134,8 +135,8 @@ DefNode( CompositorNode, CMP_NODE_INPAINT, def_cmp_inpaint, "INPAI
DefNode( CompositorNode, CMP_NODE_DESPECKLE, def_cmp_despeckle, "DESPECKLE", Despeckle, "Despeckle", "" )
DefNode( CompositorNode, CMP_NODE_ROTATE, def_cmp_rotate, "ROTATE", Rotate, "Rotate", "" )
DefNode( CompositorNode, CMP_NODE_SCALE, def_cmp_scale, "SCALE", Scale, "Scale", "" )
-DefNode( CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCCA", "" )
-DefNode( CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCCA", "" )
+DefNode( CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
+DefNode( CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
DefNode( CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
DefNode( CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
DefNode( CompositorNode, CMP_NODE_DIFF_MATTE, def_cmp_diff_matte, "DIFF_MATTE", DiffMatte, "Difference Key", "" )
@@ -146,42 +147,43 @@ DefNode( CompositorNode, CMP_NODE_FLIP, def_cmp_flip, "FLIP"
DefNode( CompositorNode, CMP_NODE_SPLITVIEWER, def_cmp_splitviewer, "SPLITVIEWER", SplitViewer, "Split Viewer", "" )
DefNode( CompositorNode, CMP_NODE_MAP_UV, def_cmp_map_uv, "MAP_UV", MapUV, "Map UV", "" )
DefNode( CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MASK", IDMask, "ID Mask", "" )
-DefNode( CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
+DefNode( CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
DefNode( CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" )
DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
DefNode( CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
-DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luma Matte", "" )
-DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" )
+DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
+DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
DefNode( CompositorNode, CMP_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
DefNode( CompositorNode, CMP_NODE_INVERT, def_cmp_invert, "INVERT", Invert, "Invert", "" )
DefNode( CompositorNode, CMP_NODE_NORMALIZE, 0, "NORMALIZE", Normalize, "Normalize", "" )
DefNode( CompositorNode, CMP_NODE_CROP, def_cmp_crop, "CROP", Crop, "Crop", "" )
DefNode( CompositorNode, CMP_NODE_DBLUR, def_cmp_dblur, "DBLUR", DBlur, "Directional Blur", "" )
DefNode( CompositorNode, CMP_NODE_BILATERALBLUR, def_cmp_bilateral_blur, "BILATERALBLUR", Bilateralblur, "Bilateral Blur", "" )
-DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMULKEY", PremulKey, "Premul Key", "" )
+DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMULKEY", PremulKey, "Alpha Convert", "" )
DefNode( CompositorNode, CMP_NODE_GLARE, def_cmp_glare, "GLARE", Glare, "Glare", "" )
DefNode( CompositorNode, CMP_NODE_TONEMAP, def_cmp_tonemap, "TONEMAP", Tonemap, "Tonemap", "" )
-DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lensdist", "" )
+DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lens Distortion", "" )
DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, def_cmp_levels, "LEVELS", Levels, "Levels", "" )
-DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Matte", "" )
-DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" )
+DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Key", "" )
+DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Key", "" )
DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" )
DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECORRECT", HueCorrect, "Hue Correct", "" )
-DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "MovieClip", "" )
+DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "Movie Clip", "" )
DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" )
DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" )
DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" )
-DefNode( CompositorNode, CMP_NODE_MASK_BOX, def_cmp_boxmask, "BOXMASK", BoxMask, "Box mask", "" )
-DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPSEMASK", EllipseMask, "Ellipse mask", "" )
-DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE", BokehImage, "Bokeh image", "" )
+DefNode( CompositorNode, CMP_NODE_MASK_BOX, def_cmp_boxmask, "BOXMASK", BoxMask, "Box Mask", "" )
+DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPSEMASK", EllipseMask, "Ellipse Mask", "" )
+DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE", BokehImage, "Bokeh Image", "" )
DefNode( CompositorNode, CMP_NODE_BOKEHBLUR, def_cmp_bokehblur, "BOKEHBLUR", BokehBlur, "Bokeh Blur", "" )
DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH", Switch, "Switch", "" )
-DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "ColorCorrection", "" )
+DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "Color Correction", "" )
DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" )
-DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "KeyingScreen", "" )
+DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "Keying Screen", "" )
DefNode( CompositorNode, CMP_NODE_KEYING, def_cmp_keying, "KEYING", Keying, "Keying", "" )
DefNode( CompositorNode, CMP_NODE_TRACKPOS, def_cmp_trackpos, "TRACKPOS", TrackPos, "Track Position", "" )
+DefNode( CompositorNode, CMP_NODE_PIXELATE, 0, "PIXELATE", Pixelate, "Pixelate", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 1d08ea9..a617c78 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -48,6 +48,7 @@
#include "BLI_utildefines.h"
+#include "BKE_paint.h"
#include "BKE_tessmesh.h"
#include "BKE_group.h" /* needed for object_in_group() */
@@ -94,6 +95,7 @@ static EnumPropertyItem parent_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifndef RNA_RUNTIME
static EnumPropertyItem dupli_items[] = {
{0, "NONE", 0, "None", ""},
{OB_DUPLIFRAMES, "FRAMES", 0, "Frames", "Make copy of object for every frame"},
@@ -102,6 +104,7 @@ static EnumPropertyItem dupli_items[] = {
{OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing"},
{0, NULL, 0, NULL, NULL}
};
+#endif
static EnumPropertyItem collision_bounds_items[] = {
{OB_BOUND_BOX, "BOX", 0, "Box", ""},
@@ -1121,7 +1124,7 @@ static void rna_GameObjectSettings_used_state_get(PointerRNA *ptr, int *values)
static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i;
for (i = 0; i < OB_MAX_COL_MASKS; i++) {
@@ -1131,7 +1134,7 @@ static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values)
static void rna_GameObjectSettings_col_group_set(PointerRNA *ptr, const int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i, tot = 0;
/* ensure we always have some group selected */
@@ -1150,7 +1153,7 @@ static void rna_GameObjectSettings_col_group_set(PointerRNA *ptr, const int *val
static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i;
for (i = 0; i < OB_MAX_COL_MASKS; i++) {
@@ -1160,7 +1163,7 @@ static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values)
static void rna_GameObjectSettings_col_mask_set(PointerRNA *ptr, const int *values)
{
- Object *ob = (Object*)ptr->data;
+ Object *ob = (Object *)ptr->data;
int i, tot = 0;
/* ensure we always have some mask selected */
@@ -1250,20 +1253,20 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr)
static PointerRNA rna_Object_active_constraint_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
- bConstraint *con = constraints_get_active(&ob->constraints);
+ bConstraint *con = BKE_constraints_get_active(&ob->constraints);
return rna_pointer_inherit_refine(ptr, &RNA_Constraint, con);
}
static void rna_Object_active_constraint_set(PointerRNA *ptr, PointerRNA value)
{
Object *ob = (Object *)ptr->id.data;
- constraints_set_active(&ob->constraints, (bConstraint *)value.data);
+ BKE_constraints_set_active(&ob->constraints, (bConstraint *)value.data);
}
static bConstraint *rna_Object_constraints_new(Object *object, int type)
{
WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_ADDED, object);
- return add_ob_constraint(object, NULL, type);
+ return BKE_add_ob_constraint(object, NULL, type);
}
static void rna_Object_constraints_remove(Object *object, ReportList *reports, PointerRNA *con_ptr)
@@ -1274,7 +1277,7 @@ static void rna_Object_constraints_remove(Object *object, ReportList *reports, P
return;
}
- remove_constraint(&object->constraints, con);
+ BKE_remove_constraint(&object->constraints, con);
RNA_POINTER_INVALIDATE(con_ptr);
ED_object_constraint_update(object);
@@ -1284,7 +1287,7 @@ static void rna_Object_constraints_remove(Object *object, ReportList *reports, P
static void rna_Object_constraints_clear(Object *object)
{
- free_constraints(&object->constraints);
+ BKE_free_constraints(&object->constraints);
ED_object_constraint_update(object);
ED_object_constraint_set_active(object, NULL);
@@ -1434,6 +1437,12 @@ int rna_DupliObject_index_get(PointerRNA *ptr)
return dob->persistent_id[0];
}
+int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
+{
+ SculptSession *ss = ((Object *)ptr->id.data)->sculpt;
+ return (ss && ss->bm);
+}
+
#else
static int rna_matrix_dimsize_4x4[] = {4, 4};
@@ -1961,7 +1970,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "actdef");
RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get",
@@ -2080,6 +2089,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_layer_set");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_layer_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000);
@@ -2459,6 +2469,15 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
+ /* depsgraph hack */
+ prop = RNA_def_property(srna, "extra_recalc_object", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_OB_RECALC);
+ RNA_def_property_ui_text(prop, "Extra Object Update", "Refresh this object again on frame changes, dependency graph hack");
+
+ prop = RNA_def_property(srna, "extra_recalc_data", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_DATA_RECALC);
+ RNA_def_property_ui_text(prop, "Extra Data Update", "Refresh this object's data again on frame changes, dependency graph hack");
+
/* duplicates */
prop = RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag");
@@ -2626,6 +2645,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Active Shape Key Index", "Current shape key index");
RNA_def_property_update(prop, 0, "rna_Object_active_shape_update");
+ /* sculpt */
+ prop = RNA_def_property(srna, "use_dynamic_topology_sculpting", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_Object_use_dynamic_topology_sculpting_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Dynamic Topology Sculpting", NULL);
+
RNA_api_object(srna);
}
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 87fc3be..40b8d4c 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -36,42 +36,79 @@
#include "RNA_define.h"
-#include "DNA_object_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
#include "rna_internal.h" /* own include */
+static EnumPropertyItem space_items[] = {
+ {CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space",
+ "The most gobal space in Blender"},
+ {CONSTRAINT_SPACE_POSE, "POSE", 0, "Pose Space",
+ "The pose space of a bone (its armature's object space)"},
+ {CONSTRAINT_SPACE_PARLOCAL, "LOCAL_WITH_PARENT", 0, "Local With Parent",
+ "The local space of a bone's parent bone"},
+ {CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space",
+ "The local space of an object/bone"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
+
#include "BLI_math.h"
-#include "BKE_main.h"
-#include "BKE_global.h"
-#include "BKE_context.h"
-#include "BKE_report.h"
-#include "BKE_object.h"
-#include "BKE_mesh.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_anim.h"
#include "BKE_bvhutils.h"
-
+#include "BKE_cdderivedmesh.h"
+#include "BKE_constraint.h"
+#include "BKE_context.h"
#include "BKE_customdata.h"
-#include "BKE_anim.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_font.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
-#include "BKE_cdderivedmesh.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_scene_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_constraint_types.h"
+#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
#include "MEM_guardedalloc.h"
+/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */
+static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan,
+ float *mat, float *mat_ret, int from, int to)
+{
+ copy_m4_m4((float (*)[4])mat_ret, (float (*)[4])mat);
+
+ /* Error in case of invalid from/to values when pchan is NULL */
+ if (pchan == NULL) {
+ if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
+ const char *identifier = NULL;
+ RNA_enum_identifier(space_items, from, &identifier);
+ BKE_reportf(reports, RPT_ERROR, "'from_space' '%s' is invalid when no pose bone is given!", identifier);
+ return;
+ }
+ if (ELEM(to, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
+ const char *identifier = NULL;
+ RNA_enum_identifier(space_items, to, &identifier);
+ BKE_reportf(reports, RPT_ERROR, "'to_space' '%s' is invalid when no pose bone is given!", identifier);
+ return;
+ }
+ }
+
+ BKE_constraint_mat_convertspace(ob, pchan, (float (*)[4])mat_ret, from, to);
+}
+
/* copied from Mesh_getFromObject and adapted to RNA interface */
/* settings: 0 - preview, 1 - render */
static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings)
@@ -92,9 +129,6 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int
DerivedMesh *derivedFinal = NULL;
int uv_from_orco;
- int (*orco_index)[4] = NULL;
- float (*orco)[3] = NULL;
-
/* copies object and modifiers (but not the data) */
tmpobj = BKE_object_copy_with_caches(ob);
tmpcu = (Curve *)tmpobj->data;
@@ -121,38 +155,12 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int
tmpobj->derivedFinal = derivedFinal;
- uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
-
- if (uv_from_orco) {
- /* before curve conversion */
- orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj);
- }
-
/* convert object type to mesh */
- BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL);
+ uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
+ BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
tmpmesh = tmpobj->data;
- if (uv_from_orco && orco && orco_index) {
- const char *uvname = "Orco";
- /* add UV's */
- MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname);
- MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname);
-
- BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly,
- tmpmesh->mloop, mloopuvs,
- orco, orco_index);
-
- (void)mtpoly;
- }
-
- if (orco_index) {
- MEM_freeN(orco_index);
- }
- if (orco) {
- MEM_freeN(orco);
- }
-
BKE_displist_free(&dispbase);
/* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */
@@ -570,7 +578,7 @@ void rna_Object_dm_info(struct Object *ob, int type, char *result)
}
#endif /* NDEBUG */
-#else
+#else /* RNA_RUNTIME */
void RNA_api_object(StructRNA *srna)
{
@@ -583,6 +591,8 @@ void RNA_api_object(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
+ static int rna_matrix_dimsize_4x4[] = {4, 4};
+
#ifndef NDEBUG
static EnumPropertyItem mesh_dm_info_items[] = {
{0, "SOURCE", 0, "Source", "Source mesh"},
@@ -592,6 +602,25 @@ void RNA_api_object(StructRNA *srna)
};
#endif
+ /* Matrix space conversion */
+ func = RNA_def_function(srna, "convert_space", "rna_Scene_mat_convert_space");
+ RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "pose_bone", "PoseBone", "",
+ "Bone to use to define spaces (may be None, in which case only the two 'WORLD' and "
+ "'LOCAL' spaces are usable)");
+ parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(parm, "", "The matrix to transform");
+ parm = RNA_def_property(func, "matrix_return", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(parm, "", "The transformed matrix");
+ RNA_def_function_output(func, parm);
+ parm = RNA_def_enum(func, "from_space", space_items, CONSTRAINT_SPACE_WORLD, "",
+ "The space in which 'matrix' is currently");
+ parm = RNA_def_enum(func, "to_space", space_items, CONSTRAINT_SPACE_WORLD, "",
+ "The space to which you want to transform 'matrix'");
+
/* mesh */
func = RNA_def_function(srna, "to_mesh", "rna_Object_to_mesh");
RNA_def_function_ui_description(func, "Create a Mesh datablock with modifiers applied");
@@ -737,5 +766,4 @@ void RNA_api_object_base(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
}
-#endif
-
+#endif /* RNA_RUNTIME */
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 6d7187d..0c2944b 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -763,7 +763,8 @@ static void rna_def_pointcache(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startframe");
- RNA_def_property_range(prop, 1, MAXFRAME);
+ RNA_def_property_range(prop, -MAXFRAME, MAXFRAME);
+ RNA_def_property_ui_range(prop, -1000, MAXFRAME, 1, 1);
RNA_def_property_ui_text(prop, "Start", "Frame on which the simulation starts");
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 6825d3d..4a520cd 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -238,7 +238,329 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float
}
}
-/* property update functions */
+static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, ParticleSystemModifierData *modifier, ParticleData *particle,
+ float n_co[3])
+{
+
+ DerivedMesh *hairdm = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_dm : NULL;
+ if (particle) {
+ if (hairdm) {
+ MVert *mvert = CDDM_get_vert(hairdm, particle->hair_index + (hairkey - particle->hair));
+ copy_v3_v3(n_co, mvert->co);
+ }
+ else {
+ float hairmat[4][4];
+ psys_mat_hair_to_object(object, modifier->dm, modifier->psys->part->from, particle, hairmat);
+ copy_v3_v3(n_co, hairkey->co);
+ mul_m4_v3(hairmat, n_co);
+ }
+ }
+ else {
+ zero_v3(n_co);
+ }
+}
+
+static void rna_Particle_uv_on_emitter(ParticleData *particle, ParticleSystemModifierData *modifier, float n_uv[2])
+{
+ /*psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0);*/
+
+ /* get uvco & mcol */
+ int num = particle->num_dmcache;
+ int from = modifier->psys->part->from;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = particle->num;
+
+ /* get uvco */
+ if (n_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+}
+
+static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *object, ParticleSystemModifierData *modifier, int particle_no, int step,
+ float n_co[3])
+{
+ ParticleSettings *part = 0;
+ ParticleData *pars = 0;
+ ParticleCacheKey *cache = 0;
+ int totchild = 0;
+ int path_nbr = 0;
+ int totpart;
+ int max_k = 0;
+
+ if (particlesystem == NULL)
+ return;
+
+ part = particlesystem->part;
+ pars = particlesystem->particles;
+
+ if (part == NULL || pars == NULL || !psys_check_enabled(object, particlesystem))
+ return;
+
+ if (part->ren_as == PART_DRAW_OB || part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_NOT)
+ return;
+
+ totchild = particlesystem->totchild * part->disp / 100;
+
+ /* can happen for disconnected/global hair */
+ if (part->type == PART_HAIR && !particlesystem->childcache)
+ totchild = 0;
+
+ totpart = particlesystem->totpart;
+
+ if (particle_no >= totpart + totchild)
+ return;
+
+ if (part->ren_as == PART_DRAW_PATH && particlesystem->pathcache)
+ path_nbr = (int)pow(2.0, part->draw_step);
+
+ if (particle_no < totpart) {
+
+ if (path_nbr) {
+ cache = particlesystem->pathcache[particle_no];
+ max_k = (int)cache->steps;
+ }
+
+ }
+ else {
+
+ if (path_nbr) {
+ cache = particlesystem->childcache[particle_no - totpart];
+
+ if (cache->steps < 0)
+ max_k = 0;
+ else
+ max_k = (int)cache->steps;
+ }
+ }
+
+ /*strands key loop data stored in cache + step->co*/
+ if (path_nbr) {
+ if (step >= 0 && step <= path_nbr) {
+ if (step <= max_k)
+ copy_v3_v3(n_co, (cache + step)->co);
+ }
+ }
+
+}
+
+static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no,
+ float n_uv[2])
+{
+ ParticleSettings *part = 0;
+ int totpart;
+ int totchild = 0;
+ int num;
+
+ /* 1. check that everything is ok & updated */
+ if (particlesystem == NULL)
+ return;
+
+ part = particlesystem->part;
+
+ totchild = particlesystem->totchild;
+
+ /* can happen for disconnected/global hair */
+ if (part->type == PART_HAIR && !particlesystem->childcache)
+ totchild = 0;
+
+ totpart = particlesystem->totpart;
+
+ if (particle_no >= totpart + totchild)
+ return;
+
+/* 3. start creating renderable things */
+ /* setup per particle individual stuff */
+ if (particle_no < totpart) {
+
+ /* get uvco & mcol */
+ num = particle->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = particle->num;
+
+ if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+ }
+ else {
+ ChildParticle *cpa = particlesystem->child + particle_no - totpart;
+
+ num = cpa->num;
+
+ /* get uvco & mcol */
+ if (part->childtype == PART_CHILD_FACES) {
+ if (n_uv && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (cpa->num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+ mtface += cpa->num;
+
+ psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+ }
+ else {
+ ParticleData *parent = particlesystem->particles + cpa->parent;
+ num = parent->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (parent->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = parent->num;
+
+ if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, parent->fuv, n_uv);
+ }
+ else {
+ n_uv[0] = 0.0f;
+ n_uv[1] = 0.0f;
+ }
+ }
+ }
+ }
+}
+
+static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int vcol_no,
+ float n_mcol[3])
+{
+ ParticleSettings *part = 0;
+ int totpart;
+ int totchild = 0;
+ int num;
+ MCol mcol = {255, 255, 255, 255};
+
+ /* 1. check that everything is ok & updated */
+ if (particlesystem == NULL)
+ return;
+
+ part = particlesystem->part;
+
+ totchild = particlesystem->totchild;
+
+ /* can happen for disconnected/global hair */
+ if (part->type == PART_HAIR && !particlesystem->childcache)
+ totchild = 0;
+
+ totpart = particlesystem->totpart;
+
+ if (particle_no >= totpart + totchild)
+ return;
+
+/* 3. start creating renderable things */
+ /* setup per particle individual stuff */
+ if (particle_no < totpart) {
+
+ /* get uvco & mcol */
+ num = particle->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = particle->num;
+
+ if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no);
+ mc += num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol);
+ n_mcol[0] = (float)mcol.b / 255.0f;
+ n_mcol[1] = (float)mcol.g / 255.0f;
+ n_mcol[2] = (float)mcol.r / 255.0f;
+ }
+ else {
+ n_mcol[0] = 0.0f;
+ n_mcol[1] = 0.0f;
+ n_mcol[2] = 0.0f;
+ }
+ }
+ }
+ else {
+ ChildParticle *cpa = particlesystem->child + particle_no - totpart;
+
+ num = cpa->num;
+
+ /* get uvco & mcol */
+ if (part->childtype == PART_CHILD_FACES) {
+ if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (cpa->num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0);
+ mc += cpa->num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol);
+ n_mcol[0] = (float)mcol.b / 255.0f;
+ n_mcol[1] = (float)mcol.g / 255.0f;
+ n_mcol[2] = (float)mcol.r / 255.0f;
+ }
+ else {
+ n_mcol[0] = 0.0f;
+ n_mcol[1] = 0.0f;
+ n_mcol[2] = 0.0f;
+ }
+ }
+ }
+ else {
+ ParticleData *parent = particlesystem->particles + cpa->parent;
+ num = parent->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (parent->num < modifier->dm->getNumTessFaces(modifier->dm))
+ num = parent->num;
+
+ if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (num != DMCACHE_NOTFOUND) {
+ MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0);
+ mc += num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol);
+ n_mcol[0] = (float)mcol.b / 255.0f;
+ n_mcol[1] = (float)mcol.g / 255.0f;
+ n_mcol[2] = (float)mcol.r / 255.0f;
+ }
+ else {
+ n_mcol[0] = 0.0f;
+ n_mcol[1] = 0.0f;
+ n_mcol[2] = 0.0f;
+ }
+ }
+ }
+ }
+}
+
static void particle_recalc(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr, short flag)
{
if (ptr->type == &RNA_ParticleSystem) {
@@ -905,6 +1227,7 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
srna = RNA_def_struct(brna, "ParticleHairKey", NULL);
RNA_def_struct_sdna(srna, "HairKey");
@@ -928,6 +1251,19 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Location",
"Location of the hair key in its internal coordinate system, "
"relative to the emitting face");
+
+ /* Aided co func */
+ func = RNA_def_function(srna, "co_object", "rna_ParticleHairKey_co_object");
+ RNA_def_function_ui_description(func, "Obtain hairkey location with particle and modifier data");
+
+ prop = RNA_def_pointer(func, "object", "Object", "", "Object");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_pointer(func, "particle", "Particle", "", "hair particle");
+
+ prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co",
+ "Exported hairkey location", -1e4, 1e4);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
}
static void rna_def_particle_key(BlenderRNA *brna)
@@ -979,6 +1315,7 @@ static void rna_def_particle(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
static EnumPropertyItem alive_items[] = {
/*{PARS_KILLED, "KILLED", 0, "Killed", ""}, */
@@ -1083,6 +1420,15 @@ static void rna_def_particle(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Alive State", "");
/* short rt2; */
+
+/* UVs */
+ func = RNA_def_function(srna, "uv_on_emitter", "rna_Particle_uv_on_emitter");
+ RNA_def_function_ui_description(func, "Obtain uv for particle on derived mesh");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
}
static void rna_def_particle_dupliweight(BlenderRNA *brna)
@@ -1112,12 +1458,25 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
+ static EnumPropertyItem sph_solver_items[] = {
+ {SPH_SOLVER_DDR, "DDR", 0, "Double-Density", "An artistic solver with strong surface tension effects (original)"},
+ {SPH_SOLVER_CLASSICAL, "CLASSICAL", 0, "Classical", "A more physically-accurate solver"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "SPHFluidSettings", NULL);
RNA_def_struct_path_func(srna, "rna_SPHFluidSettings_path");
RNA_def_struct_ui_text(srna, "SPH Fluid Settings", "Settings for particle fluids physics");
-
+
/* Fluid settings */
+ prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "solver");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, sph_solver_items);
+ RNA_def_property_ui_text(prop, "SPH Solver", "The code used to calculate internal forces on particles");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
prop = RNA_def_property(srna, "spring_force", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spring_k");
RNA_def_property_range(prop, 0.0f, 100.0f);
@@ -1186,9 +1545,9 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
/* Double density relaxation */
prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness_k");
- RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is");
+ RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is (speed of sound)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "repulsion", PROP_FLOAT, PROP_NONE);
@@ -1201,7 +1560,7 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "rest_density", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rest_density");
- RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3);
RNA_def_property_ui_text(prop, "Rest Density", "Fluid rest density");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -2129,11 +2488,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "courant_target", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.01, 10);
- RNA_def_property_float_default(prop, 0.2);
+ RNA_def_property_range(prop, 0.0001, 10);
+ RNA_def_property_float_default(prop, 0.1);
RNA_def_property_ui_text(prop, "Adaptive Subframe Threshold",
"The relative distance a particle can move before requiring more subframes "
- "(target Courant number); 0.1-0.3 is the recommended range");
+ "(target Courant number); 0.01-0.3 is the recommended range");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE);
@@ -2281,7 +2640,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
/* physical properties */
prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.001f, 100000.0f);
+ RNA_def_property_range(prop, 0.00000001f, 100000.0f);
RNA_def_property_ui_range(prop, 0.01, 100, 1, 3);
RNA_def_property_ui_text(prop, "Mass", "Mass of the particles");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -2683,6 +3042,7 @@ static void rna_def_particle_system(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
srna = RNA_def_struct(brna, "ParticleSystem", NULL);
RNA_def_struct_ui_text(srna, "Particle System", "Particle system in an object");
@@ -2780,7 +3140,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
"rna_ParticleSystem_active_particle_target_index_range");
RNA_def_property_ui_text(prop, "Active Particle Target Index", "");
-
/* billboard */
prop = RNA_def_property(srna, "billboard_normal_uv", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "bb_uvname[0]");
@@ -2982,6 +3341,44 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_struct_path_func(srna, "rna_ParticleSystem_path");
+
+ /* extract cached hair location data */
+ func = RNA_def_function(srna, "co_hair", "rna_ParticleSystem_co_hair");
+ RNA_def_function_ui_description(func, "Obtain cache hair data");
+
+ prop = RNA_def_pointer(func, "object", "Object", "", "Object");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_int(func, "step", 0, INT_MIN, INT_MAX, "step no", "", INT_MIN, INT_MAX);
+
+ prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co",
+ "Exported hairkey location", -1e4, 1e4);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
+
+ /* extract hair UVs */
+ func = RNA_def_function(srna, "uv_on_emitter", "rna_ParticleSystem_uv_on_emitter");
+ RNA_def_function_ui_description(func, "Obtain uv for all particles");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
+ prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
+
+ /* extract hair mcols */
+ func = RNA_def_function(srna, "mcol_on_emitter", "rna_ParticleSystem_mcol_on_emitter");
+ RNA_def_function_ui_description(func, "Obtain mcol for all particles");
+ prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
+ prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_int(func, "vcol_no", 0, INT_MIN, INT_MAX, "vcol no", "", INT_MIN, INT_MAX);
+ prop = RNA_def_property(func, "mcol", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ RNA_def_function_output(func, prop);
+
}
void RNA_def_particle(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 5c90fb8..23f6128 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -472,14 +472,14 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r
static PointerRNA rna_PoseChannel_active_constraint_get(PointerRNA *ptr)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- bConstraint *con = constraints_get_active(&pchan->constraints);
+ bConstraint *con = BKE_constraints_get_active(&pchan->constraints);
return rna_pointer_inherit_refine(ptr, &RNA_Constraint, con);
}
static void rna_PoseChannel_active_constraint_set(PointerRNA *ptr, PointerRNA value)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- constraints_set_active(&pchan->constraints, (bConstraint *)value.data);
+ BKE_constraints_set_active(&pchan->constraints, (bConstraint *)value.data);
}
static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int type)
@@ -487,7 +487,7 @@ static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int typ
/*WM_main_add_notifier(NC_OBJECT|ND_CONSTRAINT|NA_ADDED, object); */
/* TODO, pass object also */
/* TODO, new pose bones don't have updated draw flags */
- return add_pose_constraint(NULL, pchan, NULL, type);
+ return BKE_add_pose_constraint(NULL, pchan, NULL, type);
}
static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, ReportList *reports, PointerRNA *con_ptr)
@@ -501,12 +501,12 @@ static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, Repo
return;
}
- remove_constraint(&pchan->constraints, con);
+ BKE_remove_constraint(&pchan->constraints, con);
RNA_POINTER_INVALIDATE(con_ptr);
ED_object_constraint_update(ob);
- constraints_set_active(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */
+ BKE_constraints_set_active(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */
WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, id);
@@ -786,14 +786,14 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_location_editable");
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
- RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_scale_editable");
RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
prop = RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
RNA_def_property_float_sdna(prop, NULL, "quat");
@@ -1246,7 +1246,7 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "Active Bone Group", "Active bone group for this pose");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "active_group");
RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set",
"rna_Pose_active_bone_group_index_range");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 46b22cd..5931440 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -137,7 +137,7 @@ static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *nt
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
- RNA_pointer_create((ID*)ntree, &RNA_Node, node, &nodeptr);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &nodeptr);
func = &rna_RenderEngine_update_script_node_func;
RNA_parameter_list_create(&list, &ptr, func);
@@ -196,7 +196,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
et = MEM_callocN(sizeof(RenderEngineType), "python render engine");
memcpy(et, &dummyet, sizeof(dummyet));
- et->ext.srna = RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine");
+ et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine);
et->ext.data = data;
et->ext.call = call;
et->ext.free = free;
@@ -406,13 +406,16 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "resolution_y");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);
+
/* registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->idname");
RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
- prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->name");
RNA_def_property_flag(prop, PROP_REGISTER);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 7355e46..3f03445 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -939,6 +939,12 @@ static int rna_Function_no_self_get(PointerRNA *ptr)
return !(func->flag & FUNC_NO_SELF);
}
+static int rna_Function_use_self_type_get(PointerRNA *ptr)
+{
+ FunctionRNA *func = (FunctionRNA *)ptr->data;
+ return (func->flag & FUNC_USE_SELF_TYPE);
+}
+
/* Blender RNA */
static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -1230,7 +1236,13 @@ static void rna_def_function(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Function_no_self_get", NULL);
RNA_def_property_ui_text(prop, "No Self",
- "Function does not pass its self as an argument (becomes a class method in python)");
+ "Function does not pass its self as an argument (becomes a static method in python)");
+
+ prop = RNA_def_property(srna, "use_self_type", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Function_use_self_type_get", NULL);
+ RNA_def_property_ui_text(prop, "Use Self Type",
+ "Function passes its self type as an argument (becomes a class method in python if use_self is false)");
}
static void rna_def_number_property(StructRNA *srna, PropertyType type)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 6f3a483..663e09e 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -116,7 +116,8 @@ EnumPropertyItem proportional_falloff_curve_only_items[] = {
EnumPropertyItem proportional_editing_items[] = {
{PROP_EDIT_OFF, "DISABLED", ICON_PROP_OFF, "Disable", "Proportional Editing disabled"},
{PROP_EDIT_ON, "ENABLED", ICON_PROP_ON, "Enable", "Proportional Editing enabled"},
- {PROP_EDIT_CONNECTED, "CONNECTED", ICON_PROP_CON, "Connected", "Proportional Editing using connected geometry only"},
+ {PROP_EDIT_CONNECTED, "CONNECTED", ICON_PROP_CON, "Connected",
+ "Proportional Editing using connected geometry only"},
{0, NULL, 0, NULL, NULL}
};
@@ -274,9 +275,11 @@ EnumPropertyItem image_color_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifdef RNA_RUNTIME
#define IMAGE_COLOR_MODE_BW image_color_mode_items[0]
#define IMAGE_COLOR_MODE_RGB image_color_mode_items[1]
#define IMAGE_COLOR_MODE_RGBA image_color_mode_items[2]
+#endif
EnumPropertyItem image_color_depth_items[] = {
/* 1 (monochrome) not used */
@@ -873,7 +876,7 @@ static int rna_SceneRender_file_ext_length(PointerRNA *ptr)
RenderData *rd = (RenderData *)ptr->data;
char ext[8];
ext[0] = '\0';
- BKE_add_image_extension(ext, rd->im_format.imtype);
+ BKE_add_image_extension(ext, &rd->im_format);
return strlen(ext);
}
@@ -881,7 +884,7 @@ static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
{
RenderData *rd = (RenderData *)ptr->data;
str[0] = '\0';
- BKE_add_image_extension(str, rd->im_format.imtype);
+ BKE_add_image_extension(str, &rd->im_format);
}
#ifdef WITH_QUICKTIME
@@ -1130,7 +1133,7 @@ static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
static char *rna_SceneRenderLayer_path(PointerRNA *ptr)
{
- SceneRenderLayer *srl = (SceneRenderLayer*)ptr->data;
+ SceneRenderLayer *srl = (SceneRenderLayer *)ptr->data;
return BLI_sprintfN("render.layers[\"%s\"]", srl->name);
}
@@ -1247,27 +1250,32 @@ static void object_simplify_update(Object *ob)
}
}
-static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
+ Scene *sce = ptr->id.data;
Scene *sce_iter;
Base *base;
- for (SETLOOPER(scene, sce_iter, base))
+ for (SETLOOPER(sce, sce_iter, base))
object_simplify_update(base->object);
DAG_ids_flush_update(bmain, 0);
WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
}
-static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- if (scene->r.mode & R_SIMPLIFY)
- rna_Scene_use_simplify_update(bmain, scene, ptr);
+ Scene *sce = ptr->id.data;
+
+ if (sce->r.mode & R_SIMPLIFY)
+ rna_Scene_use_simplify_update(bmain, sce, ptr);
}
-static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- if (!(scene->r.mode & R_PERSISTENT_DATA))
+ Scene *sce = ptr->id.data;
+
+ if (!(sce->r.mode & R_PERSISTENT_DATA))
RE_FreePersistentData();
}
@@ -1356,7 +1364,8 @@ static void rna_TimeLine_remove(Scene *scene, ReportList *reports, PointerRNA *m
{
TimeMarker *marker = marker_ptr->data;
if (BLI_remlink_safe(&scene->markers, marker) == FALSE) {
- BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2);
+ BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'",
+ marker->name, scene->id.name + 2);
return;
}
@@ -1989,7 +1998,8 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
if (scene) {
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_ui_text(prop, "Samples", "Override number of render samples for this render layer, 0 will use the scene setting");
+ RNA_def_property_ui_text(prop, "Samples", "Override number of render samples for this render layer, "
+ "0 will use the scene setting");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
}
@@ -2318,7 +2328,7 @@ static void rna_def_scene_game_recast_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "slope_max", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "agentmaxslope");
RNA_def_property_range(prop, 0, M_PI / 2);
- RNA_def_property_ui_text(prop, "Max Slope", "Maximum walkable slope angle in degrees");
+ RNA_def_property_ui_text(prop, "Max Slope", "Maximum walkable slope angle");
RNA_def_property_update(prop, NC_SCENE, NULL);
@@ -2439,6 +2449,16 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem storage_items[] = {
+ {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
+ {RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
+ {RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Better performance, requires at least OpenGL 1.1"},
+#if 0 /* XXX VBOS are currently disabled since they cannot beat vertex array with display lists in performance. */
+ {RAS_STORE_VBO, "VERTEX_BUFFER_OBJECT", 0, "Vertex Buffer Objects",
+ "Best performance, requires at least OpenGL 1.4"},
+#endif
+ {0, NULL, 0, NULL, NULL}};
+
srna = RNA_def_struct(brna, "SceneGameData", NULL);
RNA_def_struct_sdna(srna, "GameData");
RNA_def_struct_nested(brna, srna, "Scene");
@@ -2471,7 +2491,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "exitkey");
RNA_def_property_enum_items(prop, event_type_items);
RNA_def_property_enum_funcs(prop, NULL, "rna_GameSettings_exit_key_set", NULL);
- RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine");
+ RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop = RNA_def_property(srna, "raster_storage", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "raster_storage");
+ RNA_def_property_enum_items(prop, storage_items);
+ RNA_def_property_ui_text(prop, "Storage", "Set the storage mode used by the rasterizer");
RNA_def_property_update(prop, NC_SCENE, NULL);
/* Do we need it here ? (since we already have it in World */
@@ -2757,6 +2783,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
"Use extra textures like normal or specular maps for GLSL rendering");
RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_glsl_update");
+ prop = RNA_def_property(srna, "use_material_caching", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_NO_MATERIAL_CACHING);
+ RNA_def_property_ui_text(prop, "Use Material Caching",
+ "Cache materials in the converter (this is faster, but can cause problems with older "
+ "Singletexture and Multitexture games");
+
/* obstacle simulation */
prop = RNA_def_property(srna, "obstacle_simulation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "obstacleSimulation");
@@ -2812,7 +2844,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_sdna(srna, "RenderData");
RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers");
- prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "actlay");
RNA_def_property_int_funcs(prop, "rna_RenderSettings_active_layer_index_get",
"rna_RenderSettings_active_layer_index_set",
@@ -2820,7 +2852,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED);
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "SceneRenderLayer");
RNA_def_property_pointer_funcs(prop, "rna_RenderSettings_active_layer_get",
"rna_RenderSettings_active_layer_set", NULL, NULL);
@@ -2862,6 +2894,14 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
};
#endif
+#ifdef WITH_OPENJPEG
+ static EnumPropertyItem jp2_codec_items[] = {
+ {R_IMF_JP2_CODEC_JP2, "JP2", 0, "JP2", ""},
+ {R_IMF_JP2_CODEC_J2K, "J2K", 0, "J2K", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+#endif
+
StructRNA *srna;
PropertyRNA *prop;
@@ -2949,6 +2989,12 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "jp2_flag", R_IMF_JP2_FLAG_CINE_48);
RNA_def_property_ui_text(prop, "Cinema (48)", "Use Openjpeg Cinema Preset (48fps)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "jpeg2k_codec", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "jp2_codec");
+ RNA_def_property_enum_items(prop, jp2_codec_items);
+ RNA_def_property_ui_text(prop, "Codec", "Codec settings for Jpek2000");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
#endif
/* Cineon and DPX */
@@ -3071,21 +3117,18 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "video_bitrate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 1, 64000);
RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rc_min_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 0, 48000);
RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rc_max_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 1, 96000);
RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -3291,8 +3334,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
static EnumPropertyItem alpha_mode_items[] = {
{R_ADDSKY, "SKY", 0, "Sky", "Transparent pixels are filled with sky color"},
- {R_ALPHAPREMUL, "PREMUL", 0, "Premultiplied", "Transparent RGB pixels are multiplied by the alpha channel"},
- {R_ALPHAKEY, "STRAIGHT", 0, "Straight Alpha", "Transparent RGB and alpha pixels are unmodified"},
+ {R_ALPHAPREMUL, "TRANSPARENT", 0, "Transparent", "World background is transparent with premultiplied alpha"},
{0, NULL, 0, NULL, NULL}
};
@@ -3653,10 +3695,9 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
- prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "blurfac");
- RNA_def_property_range(prop, 0.01f, 10.0f);
- RNA_def_property_ui_range(prop, 0.01, 2.0f, 1, 0);
+ RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 0);
RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
@@ -3727,13 +3768,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"editor pipeline, if sequencer strips exist");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
- prop = RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT_PREDIVIDE);
- RNA_def_property_ui_text(prop, "Color Unpremultiply",
- "For premultiplied alpha render output, do color space conversion on "
- "colors without alpha, to avoid fringing on light backgrounds");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
prop = RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
RNA_def_property_ui_text(prop, "File Extensions",
@@ -3879,6 +3913,19 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Calculate heights against unsubdivided low resolution mesh");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "bake_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "bake_samples");
+ RNA_def_property_range(prop, 64, 1024);
+ RNA_def_property_int_default(prop, 256);
+ RNA_def_property_ui_text(prop, "Samples", "Number of samples used for ambient occlusion baking from multires");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_bake_to_vertex_color", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_VCOL);
+ RNA_def_property_ui_text(prop, "Bake to Vertex Color",
+ "Bake to vertex colors instead of to a UV-mapped image");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
/* stamp */
prop = RNA_def_property(srna, "use_stamp_time", PROP_BOOLEAN, PROP_NONE);
@@ -3992,6 +4039,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_items(prop, viewport_shade_items);
RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view");
+ prop = RNA_def_property(srna, "use_sequencer_gl_textured_solid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_SOLID_TEX);
+ RNA_def_property_ui_text(prop, "Textured Solid", "Draw face-assigned textures in solid draw method");
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update");
+
/* layers */
prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "layers", NULL);
@@ -4623,7 +4675,7 @@ void RNA_def_scene(BlenderRNA *brna)
prop = RNA_def_property(srna, "sequencer_colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "sequencer_colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedSequencerColorspaceSettings");
RNA_def_property_ui_text(prop, "Sequencer Color Space Settings", "Settings of color space sequencer is working in");
/* Nestled Data */
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 012767b..9b5a858 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -84,7 +84,7 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name
if (BKE_imtype_is_movie(rd->im_format.imtype))
BKE_movie_filepath_get(name, rd);
else
- BKE_makepicstring(name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame, rd->im_format.imtype,
+ BKE_makepicstring(name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame, &rd->im_format,
rd->scemode & R_EXTENSION, TRUE);
}
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 84e76fa..cc18955 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -40,6 +40,9 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "BLI_utildefines.h"
+#include "bmesh.h"
+
static EnumPropertyItem particle_edit_hair_brush_items[] = {
{PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush"},
{PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"},
@@ -52,6 +55,18 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem symmetrize_direction_items[] = {
+ {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
+ {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
+
+ {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
+ {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
+
+ {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
+ {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@@ -59,8 +74,7 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
#include "BKE_pointcache.h"
#include "BKE_particle.h"
#include "BKE_depsgraph.h"
-
-#include "BLI_pbvh.h"
+#include "BKE_pbvh.h"
#include "ED_particle.h"
@@ -205,6 +219,11 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU
if (ob) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
+
+ if (ob->sculpt) {
+ ob->sculpt->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
+ }
}
}
@@ -320,6 +339,27 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Diffuse Color",
"Show diffuse color of object and overlay sculpt mask on top of it");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowDiffuseColor_update");
+
+ prop = RNA_def_property(srna, "detail_size", PROP_INT, PROP_DISTANCE);
+ RNA_def_property_ui_range(prop, 2, 100, 0, 0);
+ RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (in pixels)");
+
+ prop = RNA_def_property(srna, "use_smooth_shading", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_SMOOTH_SHADING);
+ RNA_def_property_ui_text(prop, "Smooth Shading",
+ "Show faces in dynamic-topology mode with smooth "
+ "shading rather than flat shaded");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
+
+ prop = RNA_def_property(srna, "use_edge_collapse", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_COLLAPSE);
+ RNA_def_property_ui_text(prop, "Collapse Short Edges",
+ "In dynamic-topology mode, collapse short edges "
+ "in addition to subdividing long ones");
+
+ prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, symmetrize_direction_items);
+ RNA_def_property_ui_text(prop, "Direction", "Source and destination for symmetrize operator");
}
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 18a9b96..a41551f 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -1401,26 +1401,26 @@ static void rna_def_sequence(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_offset_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startofs");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_ui_text(prop, "Start Offset", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "frame_offset_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "endofs");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_ui_text(prop, "End Offset", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "frame_still_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startstill");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "Start Still", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "frame_still_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "endstill");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
+// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "End Still", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1541,14 +1541,20 @@ static void rna_def_filter_video(StructRNA *srna)
{
PropertyRNA *prop;
+ static const EnumPropertyItem alpha_mode_items[] = {
+ {SEQ_ALPHA_STRAIGHT, "STRAIGHT", 0, "Straight", "RGB channels in transparent pixels are unaffected by the alpha channel"},
+ {SEQ_ALPHA_PREMUL, "PREMUL", 0, "Premultiplied", "RGB channels in transparent pixels are multiplied by the alpha channel"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_FILTERY);
RNA_def_property_ui_text(prop, "De-Interlace", "For video movies to remove fields");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update_reopen_files");
- prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MAKE_PREMUL);
- RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha");
+ prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, alpha_mode_items);
+ RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "use_flip_x", PROP_BOOLEAN, PROP_NONE);
@@ -1694,7 +1700,7 @@ static void rna_def_color_management(StructRNA *srna)
prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "strip->colorspace_settings");
- RNA_def_property_struct_type(prop, "ColorManagedColorspaceSettings");
+ RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
}
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 7602ec9..386263c 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -37,6 +37,8 @@
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "BLI_utildefines.h"
+
#ifdef RNA_RUNTIME
//#include "DNA_anim_types.h"
@@ -62,6 +64,16 @@
#include "WM_api.h"
+static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, int do_data)
+{
+ if (do_data) {
+ BKE_sequencer_update_changed_seq_and_deps((Scene *)id, self, true, true);
+ // new_tstripdata(self); // need 2.6x version of this.
+ }
+ BKE_sequence_calc((Scene *)id, self);
+ BKE_sequence_calc_disp((Scene *)id, self);
+}
+
static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, Sequence *seq_other)
{
const char *error_msg;
@@ -70,14 +82,14 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports,
BKE_report(reports, RPT_ERROR, error_msg);
}
-static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start_frame,
+static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int frame_start,
int channel, int type, const char *file)
{
Sequence *seq;
Strip *strip;
StripElem *se;
- seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
+ seq = BKE_sequence_alloc(ed->seqbasep, frame_start, channel);
seq->type = type;
BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2);
@@ -101,12 +113,12 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start
static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed,
const char *name, MovieClip *clip, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIECLIP, clip->name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIECLIP, clip->name);
seq->clip = clip;
seq->len = BKE_movieclip_get_duration(clip);
id_us_plus((ID *)clip);
@@ -120,12 +132,12 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed,
const char *name, Mask *mask, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MASK, mask->id.name);
seq->mask = mask;
seq->len = BKE_mask_get_duration(mask);
id_us_plus((ID *)mask);
@@ -139,15 +151,15 @@ static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed,
const char *name, Scene *sce_seq, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SCENE, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SCENE, NULL);
seq->scene = sce_seq;
seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
- seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
+ seq->scene_sound = sound_scene_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0);
id_us_plus((ID *)sce_seq);
BKE_sequence_calc_disp(scene, seq);
@@ -159,12 +171,12 @@ static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed,
static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *reports,
const char *name, const char *file, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_IMAGE, file);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_IMAGE, file);
seq->len = 1;
if (seq->strip->stripdata->name[0] == '\0') {
@@ -183,12 +195,11 @@ static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *report
static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *reports,
const char *name, const char *file, int channel,
- int start_frame)
+ int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
- /* OCIO_TODO: support configurable color spaces for strips */
struct anim *an = openanim(file, IB_rect, 0, NULL);
if (an == NULL) {
@@ -196,7 +207,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIE, file);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file);
seq->anim = an;
seq->anim_preseek = IMB_anim_get_preseek(an);
seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
@@ -210,7 +221,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
#ifdef WITH_AUDASPACE
static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, ReportList *reports,
- const char *name, const char *file, int channel, int start_frame)
+ const char *name, const char *file, int channel, int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
@@ -222,11 +233,11 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SOUND_RAM, sound->name);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SOUND_RAM, sound->name);
seq->sound = sound;
seq->len = ceil((double)sound_get_length(sound) * FPS);
- seq->scene_sound = sound_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0);
+ seq->scene_sound = sound_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0);
BKE_sequence_calc_disp(scene, seq);
@@ -237,7 +248,7 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor
#else /* WITH_AUDASPACE */
static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports,
const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel),
- int UNUSED(start_frame))
+ int UNUSED(frame_start))
{
BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support");
return NULL;
@@ -246,7 +257,7 @@ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Ma
static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *reports,
const char *name, int type, int channel,
- int start_frame, int end_frame,
+ int frame_start, int frame_end,
Sequence *seq1, Sequence *seq2, Sequence *seq3)
{
Scene *scene = (Scene *)id;
@@ -256,7 +267,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
switch (num_inputs) {
case 0:
- if (end_frame <= start_frame) {
+ if (frame_end <= frame_start) {
BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set");
return NULL;
}
@@ -286,7 +297,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
return NULL;
}
- seq = alloc_generic_sequence(ed, name, start_frame, channel, type, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, type, NULL);
sh = BKE_sequence_get_effect(seq);
@@ -298,7 +309,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
if (!seq1) { /* effect has no deps */
seq->len = 1;
- BKE_sequence_tx_set_final_right(seq, end_frame);
+ BKE_sequence_tx_set_final_right(seq, frame_end);
}
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
@@ -389,7 +400,13 @@ void RNA_api_sequence_strip(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func = RNA_def_function(srna, "getStripElem", "BKE_sequencer_give_stripelem");
+ func = RNA_def_function(srna, "update", "rna_Sequence_update_rnafunc");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Update the strip dimensions");
+ parm = RNA_def_boolean(func, "data", false, "Frame",
+ "Update strip data");
+
+ func = RNA_def_function(srna, "strip_elem_from_frame", "BKE_sequencer_give_stripelem");
RNA_def_function_ui_description(func, "Return the strip element from a given frame or None");
parm = RNA_def_int(func, "frame", 0, -MAXFRAME, MAXFRAME, "Frame",
"The frame to get the strip element from", -MAXFRAME, MAXFRAME);
@@ -470,7 +487,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -487,7 +504,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -504,7 +521,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -521,7 +538,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -538,7 +555,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -555,7 +572,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
+ parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
@@ -572,12 +589,13 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
"The channel for the new sequence", 0, MAXSEQ - 1);
+ /* don't use MAXFRAME since it makes importer scripts fail */
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "",
- "The start frame for the new sequence", -MAXFRAME, MAXFRAME);
+ parm = RNA_def_int(func, "frame_start", 0, INT_MIN, INT_MAX, "",
+ "The start frame for the new sequence", INT_MIN, INT_MAX);
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "",
- "The end frame for the new sequence", -MAXFRAME, MAXFRAME);
+ RNA_def_int(func, "frame_end", 0, INT_MIN, INT_MAX, "",
+ "The end frame for the new sequence", INT_MIN, INT_MAX);
RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect");
RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect");
RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 2b2e8d9..926b141 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -321,7 +321,7 @@ static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values)
View3D *v3d = (View3D *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
Scene *scene = (Scene *)sc->scene;
- float *loc = give_cursor(scene, v3d);
+ const float *loc = give_cursor(scene, v3d);
copy_v3_v3(values, loc);
}
@@ -775,7 +775,7 @@ static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value)
static void rna_ConsoleLine_body_get(PointerRNA *ptr, char *value)
{
ConsoleLine *ci = (ConsoleLine *)ptr->data;
- strcpy(value, ci->line);
+ memcpy(value, ci->line, ci->len + 1);
}
static int rna_ConsoleLine_body_length(PointerRNA *ptr)
@@ -871,6 +871,9 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *UNUSED(bmain), Scene *s
/* show new id-count of action we're replacing */
adt->action = saction->action;
id_us_plus(&adt->action->id);
+
+ /* force update of animdata */
+ adt->recalc |= ADT_RECALC_ANIM;
}
/* force depsgraph flush too */
@@ -1250,9 +1253,9 @@ static void rna_def_space_outliner(BlenderRNA *brna)
{SO_SAME_TYPE, "SAME_TYPES", 0, "Same Types",
"Display datablocks of all objects of same type as selected object"},
{SO_GROUPS, "GROUPS", 0, "Groups", "Display groups and their datablocks"},
- {SO_LIBRARIES, "LIBRARIES", 0, "Libraries", "Display libraries"},
{SO_SEQUENCE, "SEQUENCE", 0, "Sequence", "Display sequence datablocks"},
- {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display raw datablocks"},
+ {SO_LIBRARIES, "LIBRARIES", 0, "Blender File", "Display data of current file and linked libraries"},
+ {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display all raw datablocks"},
{SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display the user preference datablocks"},
{SO_KEYMAP, "KEYMAPS", 0, "Key Maps", "Display keymap datablocks"},
{0, NULL, 0, NULL, NULL}
@@ -1659,6 +1662,12 @@ static void rna_def_space_view3d(BlenderRNA *brna)
"Show dashed lines indicating parent or constraint relationships");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "show_textured_solid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_TEX);
RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view");
@@ -2044,6 +2053,12 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Repeated", "Draw the image repeated outside of the main view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
+
prop = RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, draw_channels_items);
@@ -2209,6 +2224,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
prop = RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "chanshown");
RNA_def_property_ui_text(prop, "Display Channel",
@@ -2353,11 +2374,11 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
/* XXX: action-editor is currently for object-level only actions, so show that using object-icon hint */
static EnumPropertyItem mode_items[] = {
- {SACTCONT_DOPESHEET, "DOPESHEET", ICON_OOPS, "DopeSheet", "DopeSheet Editor"},
- {SACTCONT_ACTION, "ACTION", ICON_OBJECT_DATA, "Action Editor", "Action Editor"},
- {SACTCONT_SHAPEKEY, "SHAPEKEY", ICON_SHAPEKEY_DATA, "ShapeKey Editor", "ShapeKey Editor"},
- {SACTCONT_GPENCIL, "GPENCIL", ICON_GREASEPENCIL, "Grease Pencil", "Grease Pencil"},
- {SACTCONT_MASK, "MASK", ICON_MOD_MASK, "Mask", "Mask Editor"},
+ {SACTCONT_DOPESHEET, "DOPESHEET", ICON_OOPS, "DopeSheet", "Edit all keyframes in scene"},
+ {SACTCONT_ACTION, "ACTION", ICON_OBJECT_DATA, "Action Editor", "Edit keyframes in active object's Object-level action"},
+ {SACTCONT_SHAPEKEY, "SHAPEKEY", ICON_SHAPEKEY_DATA, "ShapeKey Editor", "Edit keyframes in active object's Shape Keys action"},
+ {SACTCONT_GPENCIL, "GPENCIL", ICON_GREASEPENCIL, "Grease Pencil", "Edit timings for all Grease Pencil sketches in file"},
+ {SACTCONT_MASK, "MASK", ICON_MOD_MASK, "Mask", "Edit timings for Mask Editor splines"},
{0, NULL, 0, NULL, NULL}
};
@@ -2701,6 +2722,7 @@ static void rna_def_console_line(BlenderRNA *brna)
"rna_ConsoleLine_body_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CONSOLE, NULL);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
prop = RNA_def_property(srna, "current_character", PROP_INT, PROP_NONE); /* copied from text editor */
RNA_def_property_int_sdna(prop, NULL, "cursor");
@@ -3030,6 +3052,12 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
+
prop = RNA_def_property(srna, "use_auto_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_AUTO_RENDER);
RNA_def_property_ui_text(prop, "Auto Render", "Re-render and composite changed layers on 3D edits");
@@ -3302,6 +3330,13 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Manual Calibration", "Use manual calibration helpers");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
+ /* show grease pencil */
+ prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GPENCIL);
+ RNA_def_property_ui_text(prop, "Show Grease Pencil",
+ "Show grease pencil for this view");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
+
/* show filters */
prop = RNA_def_property(srna, "show_filters", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_FILTERS);
diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c
index 1395821..8a75aa2 100644
--- a/source/blender/makesrna/intern/rna_speaker.c
+++ b/source/blender/makesrna/intern/rna_speaker.c
@@ -62,6 +62,7 @@ static void rna_def_speaker(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_MUTED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Mute", "Mute the speaker");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
#if 0 /* This shouldn't be changed actually, hiding it! */
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index b1637ef..df6181a 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -30,6 +30,8 @@
#include "MEM_guardedalloc.h"
+#include "BLF_translation.h"
+
#include "BKE_text.h"
#include "RNA_define.h"
@@ -127,6 +129,7 @@ static void rna_def_text_line(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_TextLine_body_get", "rna_TextLine_body_length", "rna_TextLine_body_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line");
RNA_def_property_update(prop, NC_TEXT | NA_EDITED, NULL);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_TEXT);
}
static void rna_def_text(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index bdf9fa4..2ab448c 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -71,12 +71,12 @@ EnumPropertyItem texture_type_items[] = {
{TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", "Procedural - highly flexible fractal noise texture"},
{TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise",
"Procedural - random noise, gives a different result every time, for every frame, for every pixel"},
+ {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"},
{TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""},
{TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"},
{TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"},
{TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"},
{TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"},
- {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"},
{0, NULL, 0, NULL, NULL}
};
@@ -1194,11 +1194,6 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Flip Axis", "Flip the texture's X and Y axis");
RNA_def_property_update(prop, 0, "rna_Texture_update");
- prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_USEALPHA);
- RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information in the image");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
-
prop = RNA_def_property(srna, "use_calculate_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_CALCALPHA);
RNA_def_property_ui_text(prop, "Calculate Alpha", "Calculate an alpha channel based on RGB values in the image");
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 4aefaf9..cd646f4 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -280,7 +280,7 @@ static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerR
static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- MovieTrackingObject *object = (MovieTrackingObject * )ptr->data;
+ MovieTrackingObject *object = (MovieTrackingObject *)ptr->data;
if (object->flag & TRACKING_OBJECT_CAMERA) {
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -294,7 +294,7 @@ static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, Po
static PointerRNA rna_trackingObject_reconstruction_get(PointerRNA *ptr)
{
- MovieTrackingObject *object = (MovieTrackingObject * )ptr->data;
+ MovieTrackingObject *object = (MovieTrackingObject *)ptr->data;
if (object->flag & TRACKING_OBJECT_CAMERA) {
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -402,39 +402,52 @@ static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, P
/* API */
-static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number)
+static MovieTrackingTrack *add_track_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, const char *name, int frame)
{
- int a, width, height;
+ int width, height;
MovieClipUser user = {0};
+ MovieTrackingTrack *track;
user.framenr = 1;
BKE_movieclip_get_size(clip, &user, &width, &height);
- for (a = 0; a < number; a++)
- BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height);
+ track = BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height);
+
+ if (name && name[0]) {
+ BLI_strncpy(track->name, name, sizeof(track->name));
+ BKE_tracking_track_unique_name(tracksbase, track);
+ }
+
+ return track;
}
-static void rna_trackingTracks_add(ID *id, MovieTracking *tracking, int frame, int number)
+static MovieTrackingTrack *rna_trackingTracks_new(ID *id, MovieTracking *tracking, const char *name, int frame)
{
MovieClip *clip = (MovieClip *) id;
+ MovieTrackingTrack *track;
- add_tracks_to_base(clip, tracking, &tracking->tracks, frame, number);
+ track = add_track_to_base(clip, tracking, &tracking->tracks, name, frame);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, clip);
+
+ return track;
}
-static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number)
+static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, int frame)
{
MovieClip *clip = (MovieClip *) id;
ListBase *tracksbase = &object->tracks;
+ MovieTrackingTrack *track;
if (object->flag & TRACKING_OBJECT_CAMERA)
tracksbase = &clip->tracking.tracks;
- add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number);
+ track = add_track_to_base(clip, &clip->tracking, tracksbase, name, frame);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
+
+ return track;
}
static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name)
@@ -475,6 +488,14 @@ static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack
marker.framenr = framenr;
copy_v2_v2(marker.pos, co);
+ /* a bit arbitrary, but better than creating markers with zero pattern
+ * which is forbidden actually
+ */
+ copy_v2_v2(marker.pattern_corners[0], track->markers[0].pattern_corners[0]);
+ copy_v2_v2(marker.pattern_corners[1], track->markers[0].pattern_corners[1]);
+ copy_v2_v2(marker.pattern_corners[2], track->markers[0].pattern_corners[2]);
+ copy_v2_v2(marker.pattern_corners[3], track->markers[0].pattern_corners[3]);
+
new_marker = BKE_tracking_marker_insert(track, &marker);
WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL);
@@ -1161,7 +1182,7 @@ static void rna_def_trackingStabilization(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem filter_items[] = {
- {TRACKING_FILTER_NEAREAST, "NEAREST", 0, "Nearest", ""},
+ {TRACKING_FILTER_NEAREST, "NEAREST", 0, "Nearest", ""},
{TRACKING_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""},
{TRACKING_FILTER_BICUBIC, "BICUBIC", 0, "Bicubic", ""},
{0, NULL, 0, NULL, NULL}
@@ -1318,16 +1339,19 @@ static void rna_def_trackingTracks(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "MovieTrackingTracks", NULL);
RNA_def_struct_sdna(srna, "MovieTracking");
RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
- func = RNA_def_function(srna, "add", "rna_trackingTracks_add");
+ func = RNA_def_function(srna, "new", "rna_trackingTracks_new");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
- RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
- RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
- RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+ RNA_def_function_ui_description(func, "Create new motion track in this movie clip");
+ RNA_def_string(func, "name", "", 0, "", "Name of new track");
+ RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add track on", MINFRAME, MAXFRAME);
+ parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track");
+ RNA_def_function_return(func, parm);
/* active track */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
@@ -1342,16 +1366,19 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL);
RNA_def_struct_sdna(srna, "MovieTrackingObject");
RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
- func = RNA_def_function(srna, "add", "rna_trackingObject_tracks_add");
+ func = RNA_def_function(srna, "new", "rna_trackingObject_tracks_new");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
- RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
+ RNA_def_function_ui_description(func, "create new motion track in this movie clip");
+ RNA_def_string(func, "name", "", 0, "", "Name of new track");
RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
- RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+ parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track");
+ RNA_def_function_return(func, parm);
/* active track */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index a0a9f61..00124a8 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -55,6 +55,16 @@ EnumPropertyItem operator_context_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem uilist_layout_type_items[] = {
+ {UILST_LAYOUT_DEFAULT, "DEFAULT", 0, "Default Layout",
+ "Use the default, multi-rows layout"},
+ {UILST_LAYOUT_COMPACT, "COMPACT", 0, "Compact Layout",
+ "Use the compact, single-row layout"},
+ {UILST_LAYOUT_GRID, "GRID", 0, "Grid Layout",
+ "Use the grid-based layout"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include <assert.h>
@@ -155,7 +165,7 @@ static void panel_draw_header(const bContext *C, Panel *pnl)
RNA_parameter_list_free(&list);
}
-static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
+static void rna_Panel_unregister(Main *bmain, StructRNA *type)
{
ARegionType *art;
PanelType *pt = RNA_struct_blender_type_get(type);
@@ -171,7 +181,7 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -215,7 +225,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
memcpy(pt, &dummypt, sizeof(dummypt));
- pt->ext.srna = RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel");
+ pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
pt->ext.data = data;
pt->ext.call = call;
pt->ext.free = free;
@@ -241,7 +251,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
BLI_addtail(&art->paneltypes, pt);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return pt->ext.srna;
}
@@ -252,6 +262,105 @@ static StructRNA *rna_Panel_refine(PointerRNA *ptr)
return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Panel;
}
+/* UIList */
+static void uilist_draw_item(uiList *ui_list, bContext *C, uiLayout *layout, PointerRNA *dataptr, PointerRNA *itemptr,
+ int icon, PointerRNA *active_dataptr, const char *active_propname, int index)
+{
+ extern FunctionRNA rna_UIList_draw_item_func;
+
+ PointerRNA ul_ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
+ func = &rna_UIList_draw_item_func; /* RNA_struct_find_function(&ul_ptr, "draw_item"); */
+
+ RNA_parameter_list_create(&list, &ul_ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ RNA_parameter_set_lookup(&list, "layout", &layout);
+ RNA_parameter_set_lookup(&list, "data", dataptr);
+ RNA_parameter_set_lookup(&list, "item", itemptr);
+ RNA_parameter_set_lookup(&list, "icon", &icon);
+ RNA_parameter_set_lookup(&list, "active_data", active_dataptr);
+ RNA_parameter_set_lookup(&list, "active_property", &active_propname);
+ RNA_parameter_set_lookup(&list, "index", &index);
+ ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ uiListType *ult = RNA_struct_blender_type_get(type);
+
+ if (!ult)
+ return;
+
+ RNA_struct_free_extension(type, &ult->ext);
+
+ WM_uilisttype_freelink(ult);
+
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+}
+
+static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ uiListType *ult, dummyult = {NULL};
+ uiList dummyuilist = {NULL};
+ PointerRNA dummyul_ptr;
+ int have_function[1];
+ size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
+
+ /* setup dummy menu & menu type to store static properties in */
+ dummyuilist.type = &dummyult;
+ RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr);
+
+ /* validate the python class */
+ if (validate(&dummyul_ptr, data, have_function) != 0)
+ return NULL;
+
+ if (strlen(identifier) >= sizeof(dummyult.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummyult.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this uilist type before, and remove it */
+ ult = WM_uilisttype_find(dummyult.idname, TRUE);
+ if (ult && ult->ext.srna)
+ rna_UIList_unregister(bmain, ult->ext.srna);
+
+ /* create a new menu type */
+ ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
+ memcpy(ult, &dummyult, sizeof(dummyult));
+
+ ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
+ ult->ext.data = data;
+ ult->ext.call = call;
+ ult->ext.free = free;
+ RNA_struct_blender_type_set(ult->ext.srna, ult);
+ RNA_def_struct_flag(ult->ext.srna, STRUCT_NO_IDPROPERTIES);
+
+ ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL;
+
+ WM_uilisttype_add(ult);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
+ return ult->ext.srna;
+}
+
+static StructRNA *rna_UIList_refine(PointerRNA *ptr)
+{
+ uiList *ui_list = (uiList *)ptr->data;
+ return (ui_list->type && ui_list->type->ext.srna) ? ui_list->type->ext.srna : &RNA_UIList;
+}
+
/* Header */
static void header_draw(const bContext *C, Header *hdr)
@@ -288,7 +397,7 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -330,7 +439,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
memcpy(ht, &dummyht, sizeof(dummyht));
- ht->ext.srna = RNA_def_struct(&BLENDER_RNA, ht->idname, "Header");
+ ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
ht->ext.data = data;
ht->ext.call = call;
ht->ext.free = free;
@@ -341,7 +450,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
BLI_addtail(&art->headertypes, ht);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return ht->ext.srna;
}
@@ -411,7 +520,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
}
static char _menu_descr[RNA_DYN_DESCR_MAX];
@@ -463,7 +572,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
mt->description = buf;
}
- mt->ext.srna = RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu");
+ mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
mt->ext.data = data;
mt->ext.call = call;
mt->ext.free = free;
@@ -476,7 +585,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
WM_menutype_add(mt);
/* update while blender is running */
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_WINDOW, NULL);
return mt->ext.srna;
}
@@ -495,6 +604,8 @@ static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
else assert(!"setting the bl_description on a non-builtin menu");
}
+/* UILayout */
+
static int rna_UILayout_active_get(PointerRNA *ptr)
{
return uiLayoutGetActive(ptr->data);
@@ -651,8 +762,8 @@ static void rna_def_panel(BlenderRNA *brna)
static EnumPropertyItem panel_flag_items[] = {
{PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
"Defines if the panel has to be open or collapsed at the time of its creation"},
- {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header",
- "If set to True, the panel shows a header, which contains a clickable "
+ {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header",
+ "If set to False, the panel shows a header, which contains a clickable "
"arrow to collapse the panel and the label (see bl_label)"},
{0, NULL, 0, NULL, NULL}
};
@@ -738,6 +849,58 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Options", "Options for this panel type");
}
+static void rna_def_uilist(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ PropertyRNA *parm;
+ FunctionRNA *func;
+
+ srna = RNA_def_struct(brna, "UIList", NULL);
+ RNA_def_struct_ui_text(srna, "UIList", "UI list containing the elements of a collection");
+ RNA_def_struct_sdna(srna, "uiList");
+ RNA_def_struct_refine_func(srna, "rna_UIList_refine");
+ RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL);
+
+ /* draw */
+ func = RNA_def_function(srna, "draw_item", NULL);
+ RNA_def_function_ui_description(func, "Draw an item in the list (NOTE: when you define your own draw_item "
+ "function, you may want to check given 'item' is of the right type...)");
+ RNA_def_function_flag(func, FUNC_REGISTER);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
+ parm = RNA_def_pointer(func, "item", "AnyType", "", "Item of the collection property");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
+ parm = RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Icon of the item in the collection", 0, INT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "active_data", "AnyType", "",
+ "Data from which to take property for the active element");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
+ parm = RNA_def_string(func, "active_property", "", 0, "",
+ "Identifier of property in active_data, for the active element");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the item in the collection", 0, INT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ prop = RNA_def_property(srna, "layout_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, uilist_layout_type_items);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ /* registration */
+ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->idname");
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "ID Name",
+ "If this is set, the uilist gets a custom ID, otherwise it takes the "
+ "name of the class used to define the uilist (for example, if the "
+ "class name is \"OBJECT_UL_vgroups\", and bl_idname is not set by the "
+ "script, then bl_idname = \"OBJECT_UL_vgroups\")");
+}
+
static void rna_def_header(BlenderRNA *brna)
{
StructRNA *srna;
@@ -837,7 +1000,7 @@ static void rna_def_menu(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Label", "The menu label");
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set");
@@ -852,6 +1015,7 @@ void RNA_def_ui(BlenderRNA *brna)
{
rna_def_ui_layout(brna);
rna_def_panel(brna);
+ rna_def_uilist(brna);
rna_def_header(brna);
rna_def_menu(brna);
}
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 548539e..366d0dc 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -33,8 +33,12 @@
#include <stdio.h>
#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "DNA_screen_types.h"
#include "UI_resources.h"
+#include "UI_interface_icons.h"
#include "rna_internal.h"
@@ -70,12 +74,117 @@ static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *
return uiItemFullO(layout, opname, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag);
}
+static void rna_uiItemL(uiLayout *layout, const char *name, int icon, int icon_value)
+{
+ if (icon_value && !icon) {
+ icon = icon_value;
+ }
+
+ uiItemL(layout, name, icon);
+}
+
+static int rna_ui_get_rnaptr_icon(bContext *C, PointerRNA *ptr_icon)
+{
+ return UI_rnaptr_icon_get(C, ptr_icon, RNA_struct_ui_icon(ptr_icon->type), FALSE);
+}
+
+static const char *rna_ui_get_enum_name(bContext *C, PointerRNA *ptr, const char *propname, const char *identifier)
+{
+ PropertyRNA *prop = NULL;
+ EnumPropertyItem *items = NULL, *item;
+ int free;
+ const char *name = "";
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop || (RNA_property_type(prop) != PROP_ENUM)) {
+ RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return name;
+ }
+
+ RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
+
+ if (items) {
+ for (item = items; item->identifier; item++) {
+ if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ name = item->name;
+ break;
+ }
+ }
+ if (free) {
+ MEM_freeN(items);
+ }
+ }
+
+ return name;
+}
+
+static const char *rna_ui_get_enum_description(bContext *C, PointerRNA *ptr, const char *propname,
+ const char *identifier)
+{
+ PropertyRNA *prop = NULL;
+ EnumPropertyItem *items = NULL, *item;
+ int free;
+ const char *desc = "";
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop || (RNA_property_type(prop) != PROP_ENUM)) {
+ RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return desc;
+ }
+
+ RNA_property_enum_items_gettexted(C, ptr, prop, &items, NULL, &free);
+
+ if (items) {
+ for (item = items; item->identifier; item++) {
+ if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ desc = item->description;
+ break;
+ }
+ }
+ if (free) {
+ MEM_freeN(items);
+ }
+ }
+
+ return desc;
+}
+
+static int rna_ui_get_enum_icon(bContext *C, PointerRNA *ptr, const char *propname, const char *identifier)
+{
+ PropertyRNA *prop = NULL;
+ EnumPropertyItem *items = NULL, *item;
+ int free;
+ int icon = ICON_NONE;
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop || (RNA_property_type(prop) != PROP_ENUM)) {
+ RNA_warning("Property not found or not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return icon;
+ }
+
+ RNA_property_enum_items(C, ptr, prop, &items, NULL, &free);
+
+ if (items) {
+ for (item = items; item->identifier; item++) {
+ if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ icon = item->icon;
+ break;
+ }
+ }
+ if (free) {
+ MEM_freeN(items);
+ }
+ }
+
+ return icon;
+}
+
#else
#define DEF_ICON_BLANK_SKIP
#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""},
#define DEF_VICO(name) {VICO_##name, (#name), 0, (#name), ""},
-static EnumPropertyItem icon_items[] = {
+EnumPropertyItem icon_items[] = {
#include "UI_icons.h"
{0, NULL, 0, NULL, NULL}
};
@@ -92,7 +201,6 @@ static void api_ui_item_common(FunctionRNA *func)
prop = RNA_def_property(func, "icon", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, icon_items);
RNA_def_property_ui_text(prop, "Icon", "Override automatic icon of the item");
-
}
static void api_ui_item_op(FunctionRNA *func)
@@ -130,13 +238,6 @@ void RNA_api_ui_layout(StructRNA *srna)
{'h', "HUE", 0, "Hue", ""},
{0, NULL, 0, NULL, NULL}
};
-
- static EnumPropertyItem list_type_items[] = {
- {0, "DEFAULT", 0, "None", ""},
- {'c', "COMPACT", 0, "Compact", ""},
- {'i', "ICONS", 0, "Icons", ""},
- {0, NULL, 0, NULL, NULL}
- };
/* simple layout specifiers */
func = RNA_def_function(srna, "row", "uiLayoutRow");
@@ -175,6 +276,44 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_float(func, "percentage", 0.0f, 0.0f, 1.0f, "Percentage", "Percentage of width to split at", 0.0f, 1.0f);
RNA_def_boolean(func, "align", 0, "", "Align buttons to each other");
+ /* Icon of a rna pointer */
+ func = RNA_def_function(srna, "icon", "rna_ui_get_rnaptr_icon");
+ parm = RNA_def_int(func, "icon_value", ICON_NONE, 0, INT_MAX, "", "Icon identifier", 0, INT_MAX);
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take the icon");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
+ RNA_def_function_ui_description(func, "Return the custom icon for this data, "
+ "use it e.g. to get materials or texture icons");
+
+ /* UI name, description and icon of an enum item */
+ func = RNA_def_function(srna, "enum_item_name", "rna_ui_get_enum_name");
+ parm = RNA_def_string(func, "name", "", 0, "", "UI name of the enum item");
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_string(func, "identifier", "", 0, "", "Identifier of the enum item");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Return the UI name for this enum item");
+
+ func = RNA_def_function(srna, "enum_item_description", "rna_ui_get_enum_description");
+ parm = RNA_def_string(func, "description", "", 0, "", "UI description of the enum item");
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_string(func, "identifier", "", 0, "", "Identifier of the enum item");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Return the UI description for this enum item");
+
+ func = RNA_def_function(srna, "enum_item_icon", "rna_ui_get_enum_icon");
+ parm = RNA_def_int(func, "icon_value", ICON_NONE, 0, INT_MAX, "", "Icon identifier", 0, INT_MAX);
+ RNA_def_function_return(func, parm);
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ parm = RNA_def_string(func, "identifier", "", 0, "", "Identifier of the enum item");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_function_ui_description(func, "Return the icon for this enum item");
+
/* items */
func = RNA_def_function(srna, "prop", "rna_uiItemR");
RNA_def_function_ui_description(func, "Item. Exposes an RNA item and places it into the layout");
@@ -274,9 +413,13 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED);
#endif
- func = RNA_def_function(srna, "label", "uiItemL");
- RNA_def_function_ui_description(func, "Item. Display text in the layout");
+ func = RNA_def_function(srna, "label", "rna_uiItemL");
+ RNA_def_function_ui_description(func, "Item. Display text and/or icon in the layout");
api_ui_item_common(func);
+ parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_ui_text(parm, "Icon Value",
+ "Override automatic icon of the item "
+ "(use it e.g. with custom material icons returned by icon()...)");
func = RNA_def_function(srna, "menu", "uiItemM");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -439,26 +582,29 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_boolean(func, "compact", 0, "", "Use more compact layout");
func = RNA_def_function(srna, "template_list", "uiTemplateList");
- RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups "
- "(WARNING: only one per panel allowed!).");
+ RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
- parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
+ parm = RNA_def_string(func, "listtype_name", "", 0, "", "Identifier of the list type to use");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_string(func, "list_id", "", 0, "",
+ "Identifier of this list widget. "
+ "If this is set, the uilist gets a custom ID, otherwise it takes the "
+ "name of the class used to define the uilist (for example, if the "
+ "class name is \"OBJECT_UL_vgroups\", and list_id is not set by the "
+ "script, then bl_idname = \"OBJECT_UL_vgroups\")");
+ parm = RNA_def_pointer(func, "dataptr", "AnyType", "", "Data from which to take the Collection property");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
- parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data");
+ parm = RNA_def_string(func, "propname", "", 0, "", "Identifier of the Collection property in data");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_pointer(func, "active_data", "AnyType", "",
- "Data from which to take property for the active element");
+ parm = RNA_def_pointer(func, "active_dataptr", "AnyType", "",
+ "Data from which to take the integer property, index of the active item");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
- parm = RNA_def_string(func, "active_property", "", 0, "",
- "Identifier of property in data, for the active element");
+ parm = RNA_def_string(func, "active_propname", "", 0, "",
+ "Identifier of the integer property in active_data, index of the active item");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_string(func, "prop_list", "", 0, "",
- "Identifier of a string property in each data member, specifying which "
- "of its properties should have a widget displayed in its row "
- "(format: \"propname1:propname2:propname3:...\")");
RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display", 0, INT_MAX);
RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Maximum number of rows to display", 0, INT_MAX);
- RNA_def_enum(func, "type", list_type_items, 0, "Type", "Type of list to use");
+ RNA_def_enum(func, "type", uilist_layout_type_items, UILST_LAYOUT_DEFAULT, "Type", "Type of layout to use");
func = RNA_def_function(srna, "template_running_jobs", "uiTemplateRunningJobs");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 7be34c3..28ba7d4 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -47,6 +47,7 @@
#include "BLF_translation.h"
#include "BKE_sound.h"
+#include "BKE_addon.h"
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_type_items[] = {
@@ -62,10 +63,12 @@ static EnumPropertyItem compute_device_type_items[] = {
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
+#include "BKE_blender.h"
#include "BKE_DerivedMesh.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_idprop.h"
#include "GPU_draw.h"
@@ -78,14 +81,17 @@ static EnumPropertyItem compute_device_type_items[] = {
#include "CCL_api.h"
+#include "BKE_addon.h"
+
static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
WM_main_add_notifier(NC_WINDOW, NULL);
}
+/* also used by buffer swap switching */
static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
- U.widget_unit = (U.dpi * 20 + 36) / 72;
+ BKE_userdef_state();
WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */
}
@@ -339,6 +345,11 @@ static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data);
}
+static PointerRNA rna_Theme_space_gradient_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGradient, ptr->data);
+}
+
static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr)
{
return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceListGeneric, ptr->data);
@@ -426,6 +437,103 @@ static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), Poi
}
#endif
+static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, int create)
+{
+ if (create && !ptr->data) {
+ IDPropertyTemplate val = {0};
+ ptr->data = IDP_New(IDP_GROUP, &val, "RNA_AddonPreferences group");
+ }
+
+ return ptr->data;
+}
+
+static PointerRNA rna_Addon_preferences_get(PointerRNA *ptr)
+{
+ bAddon *addon = (bAddon *)ptr->data;
+ bAddonPrefType *apt = BKE_addon_pref_type_find(addon->module, TRUE);
+ if (apt) {
+ if (addon->prop == NULL) {
+ IDPropertyTemplate val = {0};
+ addon->prop = IDP_New(IDP_GROUP, &val, addon->module); /* name is unimportant */
+ }
+ return rna_pointer_inherit_refine(ptr, apt->ext.srna, addon->prop);
+ }
+ else {
+ return PointerRNA_NULL;
+ }
+}
+
+static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ bAddonPrefType *apt = RNA_struct_blender_type_get(type);
+
+ if (!apt)
+ return;
+
+ RNA_struct_free_extension(type, &apt->ext);
+
+ BKE_addon_pref_type_remove(apt);
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+}
+
+static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bAddonPrefType *apt, dummyapt = {{'\0'}};
+ bAddon dummyaddon = {NULL};
+ PointerRNA dummyhtr;
+ // int have_function[1];
+
+ /* setup dummy header & header type to store static properties in */
+ RNA_pointer_create(NULL, &RNA_AddonPreferences, &dummyaddon, &dummyhtr);
+
+ /* validate the python class */
+ if (validate(&dummyhtr, data, NULL /* have_function */ ) != 0)
+ return NULL;
+
+ BLI_strncpy(dummyapt.idname, dummyaddon.module, sizeof(dummyapt.idname));
+ if (strlen(identifier) >= sizeof(dummyapt.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "Registering addon-prefs class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummyapt.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this header type before, and remove it */
+ apt = BKE_addon_pref_type_find(dummyaddon.module, TRUE);
+ if (apt) {
+ if (apt->ext.srna) {
+ rna_AddonPref_unregister(bmain, apt->ext.srna);
+ }
+ }
+
+ /* create a new header type */
+ apt = MEM_mallocN(sizeof(bAddonPrefType), "addonpreftype");
+ memcpy(apt, &dummyapt, sizeof(dummyapt));
+ BKE_addon_pref_type_add(apt);
+
+ apt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_AddonPreferences);
+ apt->ext.data = data;
+ apt->ext.call = call;
+ apt->ext.free = free;
+ RNA_struct_blender_type_set(apt->ext.srna, apt);
+
+// apt->draw = (have_function[0]) ? header_draw : NULL;
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+
+ return apt->ext.srna;
+}
+
+/* placeholder, doesn't do anything useful yet */
+static StructRNA *rna_AddonPref_refine(PointerRNA *ptr)
+{
+ return (ptr->type) ? ptr->type : &RNA_AddonPreferences;
+}
+
#else
static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
@@ -435,7 +543,7 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
static EnumPropertyItem font_kerning_style[] = {
{0, "UNFITTED", 0, "Unfitted", "Use scaled but un-grid-fitted kerning distances"},
- {1, "DEFAULT", 0, "Default", "Use scaled and grid-fitted kerning distances"},
+ {1, "FITTED", 0, "Fitted", "Use scaled and grid-fitted kerning distances"},
{0, NULL, 0, NULL, NULL}
};
@@ -502,13 +610,6 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas");
#endif
- prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NEVER_NULL);
- RNA_def_property_pointer_sdna(prop, NULL, "paneltitle");
- RNA_def_property_struct_type(prop, "ThemeFontStyle");
- RNA_def_property_ui_text(prop, "Panel Style", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
/* (not used yet) */
#if 0
prop = RNA_def_property(srna, "group_label", PROP_POINTER, PROP_NONE);
@@ -648,10 +749,44 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna)
prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Header", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
+ prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_ui_text(prop, "Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "show_header", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Show Header", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "show_back", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+}
+
+static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ThemeGradientColors", NULL);
+ RNA_def_struct_sdna(srna, "uiGradientColors");
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Theme Background Color", "Theme settings for background colors and gradient");
+
+ prop = RNA_def_property(srna, "show_grad", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Use Gradient",
+ "Do a gradient for the background of the viewport working area");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Gradient Low", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "high_gradient", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Gradient High/Off", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_ui(BlenderRNA *brna)
@@ -662,7 +797,8 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
rna_def_userdef_theme_ui_wcol(brna);
rna_def_userdef_theme_ui_wcol_state(brna);
rna_def_userdef_theme_ui_panel(brna);
-
+ rna_def_userdef_theme_ui_gradient(brna);
+
srna = RNA_def_struct(brna, "ThemeUserInterface", NULL);
RNA_def_struct_sdna(srna, "ThemeUI");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
@@ -757,9 +893,14 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "State Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NEVER_NULL);
- RNA_def_property_ui_text(prop, "Panel Colors", "");
+ prop = RNA_def_property(srna, "menu_shadow_fac", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_ui_text(prop, "Menu Shadow Strength", "Blending factor for menu shadows");
+ RNA_def_property_range(prop, 0.01f, 1.0f);
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "menu_shadow_width", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Menu Shadow Width", "Width of menu shadows in standard pixels, set to zero to disable it");
+ RNA_def_property_range(prop, 0.0f, 24.0f);
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH);
@@ -837,10 +978,93 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Header Text Highlight", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ /* panel settings */
+ prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Panel Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
/* buttons */
/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */
prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Region Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text Titles", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Region Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+/* } */
+}
+
+static void rna_def_userdef_theme_space_gradient(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ThemeSpaceGradient", NULL);
+ RNA_def_struct_sdna(srna, "ThemeSpace");
+ RNA_def_struct_ui_text(srna, "Theme Space Settings", "");
+
+ /* window */
+ prop = RNA_def_property(srna, "title", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Title", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* header */
+ prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "header_text", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header Text", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Header Text Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* panel settings */
+ prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Panel Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* gradient/background settings */
+ prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Gradient Colors", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* buttons */
+/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */
+ prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Region Background", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
@@ -903,6 +1127,17 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna)
RNA_def_property_ui_text(prop, "Theme Space", "Settings for space");
}
+static void rna_def_userdef_theme_spaces_gradient(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "space", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "ThemeSpaceGradient");
+ RNA_def_property_pointer_funcs(prop, "rna_Theme_space_gradient_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Theme Space", "Settings for space");
+}
+
static void rna_def_userdef_theme_spaces_list_main(StructRNA *srna)
{
PropertyRNA *prop;
@@ -1107,18 +1342,13 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme 3D View", "Theme settings for the 3D View");
- rna_def_userdef_theme_spaces_main(srna);
+ rna_def_userdef_theme_spaces_gradient(srna);
prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Grid", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 4);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Wire", "");
@@ -1273,11 +1503,6 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Grid", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -1360,12 +1585,6 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Selected File", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
- prop = RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_float_sdna(prop, NULL, "panel");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Tiles", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
-
prop = RNA_def_property(srna, "scrollbar", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -1537,10 +1756,28 @@ static void rna_def_userdef_theme_space_text(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Syntax Built-in", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop = RNA_def_property(srna, "syntax_symbols", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxs");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Syntax Symbols", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "syntax_special", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxv");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Decorator", "");
+ RNA_def_property_ui_text(prop, "Syntax Special", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "syntax_preprocessor", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxd");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Syntax PreProcessor", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "syntax_reserved", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "syntaxr");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Syntax Reserved", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "syntax_comment", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -1654,7 +1891,7 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
static void rna_def_userdef_theme_space_logic(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+// PropertyRNA *prop;
/* space_logic */
@@ -1665,17 +1902,13 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_buts(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
+// PropertyRNA *prop;
/* space_buts */
@@ -1686,10 +1919,6 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
- prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Panel", "");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_time(BlenderRNA *brna)
@@ -2224,6 +2453,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
static EnumPropertyItem active_theme_area[] = {
{0, "USER_INTERFACE", ICON_UI, "User Interface", ""},
+ {19, "STYLE", ICON_FONTPREVIEW, "Text Style", ""},
{18, "BONE_COLOR_SETS", ICON_COLOR, "Bone Color Sets", ""},
{1, "VIEW_3D", ICON_VIEW3D, "3D View", ""},
{2, "TIMELINE", ICON_TIME, "Timeline", ""},
@@ -2390,6 +2620,32 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
prop = RNA_def_property(srna, "module", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Module", "Module name");
RNA_def_struct_name_property(srna, prop);
+
+ /* Collection active property */
+ prop = RNA_def_property(srna, "preferences", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "AddonPreferences");
+ RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
+}
+
+static void rna_def_userdef_addon_pref(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "AddonPreferences", NULL);
+ RNA_def_struct_ui_text(srna, "Addon Preferences", "");
+ RNA_def_struct_sdna(srna, "bAddon"); /* WARNING: only a bAddon during registration */
+
+ RNA_def_struct_refine_func(srna, "rna_AddonPref_refine");
+ RNA_def_struct_register_funcs(srna, "rna_AddonPref_register", "rna_AddonPref_unregister", NULL);
+ RNA_def_struct_idprops_func(srna, "rna_AddonPref_idprops");
+
+ /* registration */
+ RNA_define_verify_sdna(0);
+ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "module");
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_define_verify_sdna(1);
}
@@ -2400,6 +2656,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_ui(brna);
rna_def_userdef_theme_space_generic(brna);
+ rna_def_userdef_theme_space_gradient(brna);
rna_def_userdef_theme_space_list_generic(brna);
rna_def_userdef_theme_space_view3d(brna);
@@ -3027,62 +3284,10 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
-#if 0
- /* hardcoded here, could become dynamic somehow */
- /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */
- /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */
- /* Note: As this list is in alphabetical order, and not defined order,
- * here is the highest define currently in use: 35 (Esperanto). */
static EnumPropertyItem language_items[] = {
- { 0, "", 0, N_("Nearly Done"), ""},
- { 0, "DEFAULT", 0, "Default (Default)", ""},
- /* using the utf8 flipped form of Arabic (العربية) */
- {21, "ARABIC", 0, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG"},
- {32, "BRAZILIANPORTUGUESE", 0, "Brazilian Portuguese (Português do Brasil)", "pt_BR"},
- { 1, "ENGLISH", 0, "English (English)", "en_US"},
- { 8, "FRENCH", 0, "French (Français)", "fr_FR"},
- { 4, "ITALIAN", 0, "Italian (Italiano)", "it_IT"},
- { 2, "JAPANESE", 0, "Japanese (日本語)", "ja_JP"},
- {12, "PORTUGUESE", 0, "Portuguese (Português)", "pt"},
- {15, "RUSSIAN", 0, "Russian (Русский)", "ru_RU"},
- {13, "SIMPLIFIED_CHINESE", 0, "Simplified Chinese (简体中文)", "zh_CN"},
- { 9, "SPANISH", 0, "Spanish (Español)", "es"},
- {14, "TRADITIONAL_CHINESE", 0, "Traditional Chinese (繁體中文)", "zh_TW"},
- {18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"},
- { 0, "", 0, N_("In Progress"), ""},
-/* {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"},*/ /* XXX Not active nor enough translated. */
-/* {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"},*/ /* XXX Not active nor enough translated. */
- {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"},
- {11, "CZECH", 0, "Czech (Český)", "cs_CZ"},
- { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"},
- {35, "ESPERANTO", 0, "Esperanto (Esperanto)", "eo"},
- {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"},
-/* { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"},*/ /* XXX Not active nor enough translated. */
- { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"},
-/* {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"},*/ /* XXX Not active nor enough translated. */
- /* using the utf8 flipped form of Hebrew (עִבְרִית)) */
- {33, "HEBREW", 0, "Hebrew (תירִבְעִ)", "he_IL"},
- {31, "HUNGARIAN", 0, "Hungarian (Magyar)", "hu_HU"},
- {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"},
- {29, "KYRGYZ", 0, "Kyrgyz (Кыргыз тили)", "ky_KG"},
-/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX Not active nor enough translated. */
-/* {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"},*/ /* XXX Not active nor enough translated. */
- /* using the utf8 flipped form of Persian (فارسی) */
- {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"},
-/* {19, "POLISH", 0, "Polish (Polski)", "pl_PL"},*/ /* XXX Not active nor enough translated. */
-/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX Not active nor enough translated. */
- {17, "SERBIAN", 0, "Serbian (Српски)", "sr_RS"},
- {28, "SERBIAN_LATIN", 0, "Serbian Latin (Srpski latinica)", "sr_RS at latin"},
- { 7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"},
- {30, "TURKISH", 0, "Turkish (Türkçe)", "tr_TR"},
- { 0, NULL, 0, NULL, NULL}
- };
-#else
- static EnumPropertyItem language_items[] = {
- { 0, "DEFAULT", 0, "Default (Default)", ""},
- { 0, NULL, 0, NULL, NULL}
+ {0, "DEFAULT", 0, "Default (Default)", ""},
+ {0, NULL, 0, NULL, NULL}
};
-#endif
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_items[] = {
@@ -3275,7 +3480,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "wmdrawmethod");
RNA_def_property_enum_items(prop, draw_method_items);
RNA_def_property_ui_text(prop, "Window Draw Method", "Drawing method used by the window manager");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mixbufsize");
@@ -3329,6 +3534,13 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_enum_items(prop, multi_sample_levels);
RNA_def_property_ui_text(prop, "MultiSample", "Enable OpenGL multi-sampling, only for systems that support it, requires restart");
+ prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP);
+ RNA_def_property_ui_text(prop, "Region Overlap",
+ "Draw tool/property regions over the main region, when using Triple Buffer");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
+
+
#ifdef WITH_CYCLES
prop = RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
@@ -3664,6 +3876,11 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
"The time (in minutes) to wait between automatic temporary saves");
RNA_def_property_update(prop, 0, "rna_userdef_autosave_update");
+ prop = RNA_def_property(srna, "use_keep_session", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_KEEP_SESSION);
+ RNA_def_property_ui_text(prop, "Keep Session",
+ "Always load session recovery and save it after quitting Blender");
+
prop = RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember");
@@ -3785,6 +4002,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_filepaths(brna);
rna_def_userdef_system(brna);
rna_def_userdef_addon(brna);
+ rna_def_userdef_addon_pref(brna);
}
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index f83410e..f416d34 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -416,6 +416,7 @@ EnumPropertyItem wm_report_items[] = {
{RPT_DEBUG, "DEBUG", 0, "Debug", ""},
{RPT_INFO, "INFO", 0, "Info", ""},
{RPT_OPERATOR, "OPERATOR", 0, "Operator", ""},
+ {RPT_PROPERTY, "PROPERTY", 0, "Property", ""},
{RPT_WARNING, "WARNING", 0, "Warning", ""},
{RPT_ERROR, "ERROR", 0, "Error", ""},
{RPT_ERROR_INVALID_INPUT, "ERROR_INVALID_INPUT", 0, "Invalid Input", ""},
@@ -1137,7 +1138,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
* for now just remove from dir(bpy.types) */
/* create a new operator type */
- dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
dummyot.ext.data = data;
dummyot.ext.call = call;
@@ -1218,7 +1219,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
* for now just remove from dir(bpy.types) */
/* create a new operator type */
- dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
+ dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1339,7 +1340,7 @@ static void rna_def_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set");
@@ -1406,7 +1407,7 @@ static void rna_def_macro_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
- prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set");
@@ -1617,6 +1618,26 @@ static void rna_def_window(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_Window_screen_update");
+
+ prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "posx");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "X Position", "Vertical location of the window");
+
+ prop = RNA_def_property(srna, "y", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "posy");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Y Position", "Horizontal location of the window");
+
+ prop = RNA_def_property(srna, "width", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "sizex");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Width", "Window width");
+
+ prop = RNA_def_property(srna, "height", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "sizey");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Height", "Window height");
}
/* curve.splines */
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index a84b112..7a94566 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -529,7 +529,7 @@ void RNA_def_world(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "zenr");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Zenith Color", "Color at the zenith");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "ambr");
@@ -554,17 +554,17 @@ void RNA_def_world(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_sky_blend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYBLEND);
RNA_def_property_ui_text(prop, "Blend Sky", "Render background with natural progression from horizon to zenith");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "use_sky_paper", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYPAPER);
RNA_def_property_ui_text(prop, "Paper Sky", "Flatten blend or texture coordinates");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
prop = RNA_def_property(srna, "use_sky_real", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYREAL);
RNA_def_property_ui_text(prop, "Real Sky", "Render background with a real horizon, relative to the camera angle");
- RNA_def_property_update(prop, 0, "rna_World_update");
+ RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update");
/* nested structs */
prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index cf3bb05..3320909 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -64,8 +64,8 @@ set(SRC
intern/MOD_fluidsim.c
intern/MOD_fluidsim_util.c
intern/MOD_hook.c
- intern/MOD_lattice.c
intern/MOD_laplaciansmooth.c
+ intern/MOD_lattice.c
intern/MOD_mask.c
intern/MOD_meshdeform.c
intern/MOD_mirror.c
@@ -86,7 +86,9 @@ set(SRC
intern/MOD_solidify.c
intern/MOD_subsurf.c
intern/MOD_surface.c
+ intern/MOD_triangulate.c
intern/MOD_util.c
+ intern/MOD_uvwarp.c
intern/MOD_uvproject.c
intern/MOD_warp.c
intern/MOD_wave.c
@@ -94,7 +96,6 @@ set(SRC
intern/MOD_weightvgedit.c
intern/MOD_weightvgmix.c
intern/MOD_weightvgproximity.c
- intern/MOD_triangulate.c
MOD_modifiertypes.h
intern/MOD_boolean_util.h
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 290ba19..17e903e 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -77,6 +77,7 @@ extern ModifierTypeInfo modifierType_Remesh;
extern ModifierTypeInfo modifierType_Skin;
extern ModifierTypeInfo modifierType_LaplacianSmooth;
extern ModifierTypeInfo modifierType_Triangulate;
+extern ModifierTypeInfo modifierType_UVWarp;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript
index 62fd9ba..d3430c6 100644
--- a/source/blender/modifiers/SConscript
+++ b/source/blender/modifiers/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 59befe4..776adb5 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -140,7 +140,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
}
}
- BM_mesh_bevel(bm, bmd->value, segments);
+ BM_mesh_bevel(bm, bmd->value, segments, bmd->flags & BME_BEVEL_VERT);
result = CDDM_from_bmesh(bm, TRUE);
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c
index 2ff9353..0cf4f6a 100644
--- a/source/blender/modifiers/intern/MOD_boolean_util.c
+++ b/source/blender/modifiers/intern/MOD_boolean_util.c
@@ -305,7 +305,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base)
static void InterpCSGFace(
DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr,
- float mapmat[][4])
+ float mapmat[4][4])
{
float obco[3], *co[4], *orig_co[4], w[4][4];
MFace *mface, *orig_mface;
@@ -344,8 +344,8 @@ static void InterpCSGFace(
static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
CSG_FaceIteratorDescriptor *face_it,
CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4],
- float mapmat[][4],
+ float parinv[4][4],
+ float mapmat[4][4],
Material **mat,
int *totmat,
DerivedMesh *dm1,
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 28cdfa8..2d3d5c9 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -63,7 +63,7 @@ static void initData(ModifierData *md)
DecimateModifierData *dmd = (DecimateModifierData *) md;
dmd->percent = 1.0;
- dmd->angle = DEG2RADF(15.0f);
+ dmd->angle = DEG2RADF(5.0f);
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -188,7 +188,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* update for display only */
dmd->face_count = bm->totface;
result = CDDM_from_bmesh(bm, FALSE);
- BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
+ BLI_assert(bm->vtoolflagpool == NULL); /* make sure we never alloc'd this */
+ BLI_assert(bm->etoolflagpool == NULL);
+ BLI_assert(bm->ftoolflagpool == NULL);
BM_mesh_free(bm);
#ifdef USE_TIMEIT
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index ec81c5c..33601c1 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -30,33 +30,24 @@
/** \file blender/modifiers/intern/MOD_edgesplit.c
* \ingroup modifiers
+ *
+ * EdgeSplit modifier
+ *
+ * Splits edges in the mesh according to sharpness flag
+ * or edge angle (can be used to achieve autosmoothing)
*/
-
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing) */
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "MEM_guardedalloc.h"
-
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
-#include "BKE_mesh.h"
#include "bmesh.h"
+#include "tools/bmesh_edgesplit.h"
#include "DNA_object_types.h"
-/* EdgeSplit */
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing)
- *
- * note: this code is very close to MOD_bevel.c
- */
-
-#define EDGE_MARK 1
static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob))
{
@@ -67,7 +58,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
bm = DM_to_bmesh(dm);
- BM_mesh_elem_toolflags_ensure(bm);
if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
@@ -81,7 +71,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
/* 2 face edge - check angle*/
(dot_v3v3(l1->f->no, l2->f->no) < threshold))
{
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
}
}
}
@@ -94,14 +84,13 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
(e->l->next != e->l))
{
if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
}
}
}
}
- BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
- "split_edges edges=%fe", EDGE_MARK);
+ BM_mesh_edgesplit(bm, FALSE, TRUE);
/* BM_mesh_validate(bm); */ /* for troubleshooting */
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index 13d409d..b39ddf6 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -301,7 +301,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam
}
-void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
+void fluid_get_bb(MVert *mvert, int totvert, float obmat[4][4],
/*RET*/ float start[3], /*RET*/ float size[3])
{
float bbsx = 0.0, bbsy = 0.0, bbsz = 0.0;
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 564fa69..c0e529f 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -139,10 +139,10 @@ static void initData(ModifierData *md)
omd->ocean = BKE_add_ocean();
init_ocean_modifier(omd);
simulate_ocean_modifier(omd);
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* unused */
(void)md;
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
}
static void freeData(ModifierData *md)
@@ -153,10 +153,10 @@ static void freeData(ModifierData *md)
BKE_free_ocean(omd->ocean);
if (omd->oceancache)
BKE_free_ocean_cache(omd->oceancache);
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* unused */
(void)md;
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -201,11 +201,11 @@ static void copyData(ModifierData *md, ModifierData *target)
tomd->ocean = BKE_add_ocean();
init_ocean_modifier(tomd);
simulate_ocean_modifier(tomd);
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* unused */
(void)md;
(void)target;
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
}
#ifdef WITH_OCEANSIM
@@ -219,14 +219,14 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
{
/* unused */
(void)md;
return 0;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
#if 0
static void dm_get_bounds(DerivedMesh *dm, float *sx, float *sy, float *ox, float *oy)
@@ -302,11 +302,7 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd)
mpolys = CDDM_get_polys(result);
mloops = CDDM_get_loops(result);
-#if 0 // trunk
- origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
-#else // bmesh
origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX);
-#endif
/* create vertices */
#pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
@@ -443,7 +439,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
cfra = md->scene->r.cfra;
CLAMP(cfra, omd->bakestart, omd->bakeend);
- cfra -= omd->bakestart; // shift to 0 based
+ cfra -= omd->bakestart; /* shift to 0 based */
num_verts = dm->getNumVerts(dm);
num_faces = dm->getNumPolys(dm);
@@ -500,7 +496,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
/* displace the geometry */
- //#pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES)
+ /* #pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES) */
for (i = 0, mv = mverts; i < num_verts; i++, mv++) {
const float u = OCEAN_CO(size_co_inv, mv->co[0]);
const float v = OCEAN_CO(size_co_inv, mv->co[1]);
@@ -522,7 +518,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
return dm;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
DerivedMesh *derivedData,
int UNUSED(useRenderParams))
@@ -531,7 +527,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
(void)md;
return derivedData;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *derivedData,
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 93b5e36..1021620 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -225,7 +225,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* angle */
-#if 0 // cant incluide this, not predictable enough, though quite fun,.
+#if 0 /* cant incluide this, not predictable enough, though quite fun. */
if (ltmd->flag & MOD_SCREW_OBJECT_ANGLE) {
float mtx3_tx[3][3];
copy_m3_m4(mtx3_tx, mtx_tx);
@@ -274,7 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
/* will the screw be closed?
- * Note! smaller then FLT_EPSILON*100 gives problems with float precision so its never closed. */
+ * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */
if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f))
{
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index 7fe8dc6..697ccdc 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -54,13 +54,16 @@ static void deformVerts(ModifierData *md, Object *ob,
int numVerts,
ModifierApplyFlag UNUSED(flag))
{
- KeyBlock *kb = BKE_keyblock_from_object(ob);
+ Key *key = BKE_key_from_object(ob);
float (*deformedVerts)[3];
- if (kb && kb->totelem == numVerts) {
- deformedVerts = (float(*)[3])do_ob_key(md->scene, ob);
+ if (key && key->block.first) {
+ int deformedVerts_tot;
+ deformedVerts = (float(*)[3])BKE_key_evaluate_object(md->scene, ob, &deformedVerts_tot);
if (deformedVerts) {
- memcpy(vertexCos, deformedVerts, sizeof(float) * 3 * numVerts);
+ if (numVerts == deformedVerts_tot) {
+ memcpy(vertexCos, deformedVerts, sizeof(float) * 3 * numVerts);
+ }
MEM_freeN(deformedVerts);
}
}
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 75e54d7..038fb49 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -185,6 +185,8 @@ static void copyData(ModifierData *md, ModifierData *target)
tsmd->crease_outer = smd->crease_outer;
tsmd->crease_rim = smd->crease_rim;
tsmd->flag = smd->flag;
+ tsmd->mat_ofs = smd->mat_ofs;
+ tsmd->mat_ofs_rim = smd->mat_ofs_rim;
BLI_strncpy(tsmd->defgrp_name, smd->defgrp_name, sizeof(tsmd->defgrp_name));
}
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index a27d5e5..6c2f688 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -279,5 +279,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(Skin);
INIT_TYPE(LaplacianSmooth);
INIT_TYPE(Triangulate);
+ INIT_TYPE(UVWarp);
#undef INIT_TYPE
}
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
new file mode 100644
index 0000000..249c3c8
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -0,0 +1,268 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Pawel Kowal, Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_uvwarp.c
+ * \ingroup modifiers
+ */
+
+#include <string.h>
+
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_action.h" /* BKE_pose_channel_find_name */
+#include "BKE_cdderivedmesh.h"
+#include "BKE_deform.h"
+#include "BKE_modifier.h"
+
+#include "depsgraph_private.h"
+
+#include "MOD_util.h"
+
+
+static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4],
+ int axis_u, int axis_v)
+{
+ float tuv[3] = {0.0f};
+
+ tuv[axis_u] = uv_src[0];
+ tuv[axis_v] = uv_src[1];
+
+ mul_m4_v3(warp_mat, tuv);
+
+ uv_dst[0] = tuv[axis_u];
+ uv_dst[1] = tuv[axis_v];
+}
+
+static void initData(ModifierData *md)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+ umd->axis_u = 0;
+ umd->axis_v = 1;
+ copy_v2_fl(umd->center, 0.5f);
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ UVWarpModifierData *tumd = (UVWarpModifierData *)target;
+
+ tumd->axis_u = umd->axis_u;
+ tumd->axis_v = umd->axis_v;
+ copy_v2_v2(tumd->center, umd->center);
+ tumd->object_src = umd->object_src;
+ BLI_strncpy(tumd->bone_src, umd->bone_src, sizeof(tumd->bone_src));
+ tumd->object_dst = umd->object_dst;
+ BLI_strncpy(tumd->bone_dst, umd->bone_dst, sizeof(tumd->bone_dst));
+ BLI_strncpy(tumd->vgroup_name, umd->vgroup_name, sizeof(tumd->vgroup_name));
+ BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name));
+}
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ if (umd->vgroup_name[0])
+ dataMask |= CD_MASK_MDEFORMVERT;
+
+ return dataMask;
+}
+
+static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonename)
+{
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename);
+ if (pchan) {
+ mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
+ }
+ else {
+ copy_m4_m4(mat, ob->obmat);
+ }
+}
+
+#define OMP_LIMIT 1000
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
+ DerivedMesh *dm,
+ ModifierApplyFlag UNUSED(flag))
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+ int i, numPolys, numLoops;
+ MPoly *mpoly;
+ MLoop *mloop;
+ MLoopUV *mloopuv;
+ MDeformVert *dvert;
+ int defgrp_index;
+ char uvname[MAX_CUSTOMDATA_LAYER_NAME];
+ float mat_src[4][4];
+ float mat_dst[4][4];
+ float imat_dst[4][4];
+ float warp_mat[4][4];
+ const int axis_u = umd->axis_u;
+ const int axis_v = umd->axis_v;
+
+ /* make sure there are UV Maps available */
+ if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
+ return dm;
+ }
+ else if (ELEM(NULL, umd->object_src, umd->object_dst)) {
+ modifier_setError(md, "From/To objects must be set");
+ return dm;
+ }
+
+ /* make sure anything moving UVs is available */
+ matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src);
+ matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst);
+
+ invert_m4_m4(imat_dst, mat_dst);
+ mult_m4_m4m4(warp_mat, imat_dst, mat_src);
+
+ /* apply warp */
+ if (!is_zero_v2(umd->center)) {
+ float mat_cent[4][4];
+ float imat_cent[4][4];
+
+ unit_m4(mat_cent);
+ mat_cent[3][axis_u] = umd->center[0];
+ mat_cent[3][axis_v] = umd->center[1];
+
+ invert_m4_m4(imat_cent, mat_cent);
+
+ mult_m4_m4m4(warp_mat, warp_mat, imat_cent);
+ mult_m4_m4m4(warp_mat, mat_cent, warp_mat);
+ }
+
+ /* make sure we're using an existing layer */
+ CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname);
+
+ numPolys = dm->getNumPolys(dm);
+ numLoops = dm->getNumLoops(dm);
+
+ mpoly = dm->getPolyArray(dm);
+ mloop = dm->getLoopArray(dm);
+ /* make sure we are not modifying the original UV map */
+ mloopuv = CustomData_duplicate_referenced_layer_named(&dm->loopData, CD_MLOOPUV, uvname, numLoops);
+ modifier_get_vgroup(ob, dm, umd->vgroup_name, &dvert, &defgrp_index);
+
+ if (dvert) {
+#pragma omp parallel for if (numPolys > OMP_LIMIT)
+ for (i = 0; i < numPolys; i++) {
+ float uv[2];
+ MPoly *mp = &mpoly[i];
+ MLoop *ml = &mloop[mp->loopstart];
+ MLoopUV *mluv = &mloopuv[mp->loopstart];
+ int l;
+ for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
+ const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index);
+ uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v);
+ interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight);
+ }
+ }
+ }
+ else {
+#pragma omp parallel for if (numPolys > OMP_LIMIT)
+ for (i = 0; i < numPolys; i++) {
+ MPoly *mp = &mpoly[i];
+ // MLoop *ml = &mloop[mp->loopstart];
+ MLoopUV *mluv = &mloopuv[mp->loopstart];
+ int l;
+ for (l = 0; l < mp->totloop; l++, /* ml++, */ mluv++) {
+ uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v);
+ }
+ }
+ }
+
+ dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
+
+ return dm;
+}
+
+static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
+ struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *derivedData)
+{
+ return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE);
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+
+ walk(userData, ob, &umd->object_dst);
+ walk(userData, ob, &umd->object_src);
+}
+
+static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode,
+ Object *obj, const char *bonename)
+{
+ if (obj) {
+ DagNode *curNode = dag_get_node(forest, obj);
+
+ if (bonename[0])
+ dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVWarp Modifier");
+ else
+ dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVWarp Modifier");
+ }
+}
+
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Scene *UNUSED(scene),
+ Object *UNUSED(ob),
+ DagNode *obNode)
+{
+ UVWarpModifierData *umd = (UVWarpModifierData *) md;
+
+ uv_warp_deps_object_bone(forest, obNode, umd->object_src, umd->bone_src);
+ uv_warp_deps_object_bone(forest, obNode, umd->object_dst, umd->bone_dst);
+}
+
+ModifierTypeInfo modifierType_UVWarp = {
+ /* name */ "UVWarp",
+ /* structName */ "UVWarpModifierData",
+ /* structSize */ sizeof(UVWarpModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+ /* copyData */ copyData,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ applyModifierEM,
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepgraph */ updateDepgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 5883b17..f025352 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -361,7 +361,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
/* Mix weights. */
for (i = 0; i < numIdx; i++) {
- float weight2 = 0.0;
+ float weight2;
org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a;
weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b;
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index e936e57..71d6d48 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -107,9 +107,9 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3],
/*nearest_v.dist = nearest_e.dist = nearest_f.dist = FLT_MAX;*/
/* Find the nearest vert/edge/face. */
#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest_v,nearest_e,nearest_f) \
- shared(treeData_v,treeData_e,treeData_f,numVerts,v_cos,dist_v,dist_e, \
- dist_f,loc2trgt) \
+#pragma omp parallel for default(none) private(i) firstprivate(nearest_v, nearest_e, nearest_f) \
+ shared(treeData_v, treeData_e, treeData_f, numVerts, v_cos, dist_v, dist_e, \
+ dist_f, loc2trgt) \
schedule(static)
#endif
for (i = 0; i < numVerts; i++) {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 141a368..a7b491c 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -168,6 +168,7 @@ set(SRC
shader/nodes/node_shader_mix_shader.c
shader/nodes/node_shader_normal_map.c
shader/nodes/node_shader_object_info.c
+ shader/nodes/node_shader_hair_info.c
shader/nodes/node_shader_output_lamp.c
shader/nodes/node_shader_output_material.c
shader/nodes/node_shader_output_world.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 7413577..0a7a11e 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -78,6 +78,7 @@ void register_node_type_sh_fresnel(struct bNodeTreeType *ttype);
void register_node_type_sh_layer_weight(struct bNodeTreeType *ttype);
void register_node_type_sh_tex_coord(struct bNodeTreeType *ttype);
void register_node_type_sh_particle_info(struct bNodeTreeType *ttype);
+void register_node_type_sh_hair_info(struct bNodeTreeType *ttype);
void register_node_type_sh_script(struct bNodeTreeType *ttype);
void register_node_type_sh_normal_map(struct bNodeTreeType *ttype);
void register_node_type_sh_tangent(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript
index ec4f00a..cc73590 100644
--- a/source/blender/nodes/SConscript
+++ b/source/blender/nodes/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c
index 57eb990..c4b48b8 100644
--- a/source/blender/nodes/composite/node_composite_util.c
+++ b/source/blender/nodes/composite/node_composite_util.c
@@ -615,7 +615,7 @@ void generate_preview(void *data, bNode *node, CompBuf *stackbuf)
bNodePreview *preview= node->preview;
int xsize, ysize;
int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
- int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
+ int predivide= TRUE;
int dither= 0;
unsigned char *rect;
diff --git a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c
index 72c2204..71b71c9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c
+++ b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c
@@ -149,7 +149,7 @@ void register_node_type_cmp_alphaover(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, CMP_NODE_ALPHAOVER, "AlphaOver", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
+ node_type_base(ttype, &ntype, CMP_NODE_ALPHAOVER, "Alpha Over", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_alphaover_in, cmp_node_alphaover_out);
node_type_size(&ntype, 80, 40, 120);
node_type_init(&ntype, node_alphaover_init);
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 88d78df..7e44210 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -291,7 +291,6 @@ static void cmp_node_image_update(bNodeTree *ntree, bNode *node)
float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
{
float *rect;
- int predivide= (ibuf->flags & IB_cm_predivide);
*alloc= FALSE;
@@ -305,7 +304,7 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image");
IMB_buffer_float_from_float(rect, ibuf->rect_float,
- 4, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, predivide,
+ 4, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, TRUE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
*alloc= TRUE;
diff --git a/source/blender/nodes/composite/nodes/node_composite_lensdist.c b/source/blender/nodes/composite/nodes/node_composite_lensdist.c
index c3f64f0..1ac8c45 100644
--- a/source/blender/nodes/composite/nodes/node_composite_lensdist.c
+++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.c
@@ -85,7 +85,7 @@ static void lensDistort(CompBuf *dst, CompBuf *src, float kr, float kg, float kb
// so in the case of pincushion (kn < 0), corners will be outside window.
// Now also optionally scales image such that black areas are not visible when distort factor is positive
// (makes distorted corners match window corners, but really only valid if mk<=0.5)
- const float mk = MAX3(kr, kg, kb);
+ const float mk = max_fff(kr, kg, kb);
const float sc = (fit && (mk > 0.f)) ? (1.f/(1.f + 2.f*mk)) : (1.f/(1.f + mk));
const float drg = 4.f*(kg - kr), dgb = 4.f*(kb - kg);
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index 214617c..fe23f73 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -269,7 +269,7 @@ static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack
/* get full path */
BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sockdata->path);
- BKE_makepicstring(filename, path, bmain->name, rd->cfra, format->imtype, (rd->scemode & R_EXTENSION), TRUE);
+ BKE_makepicstring(filename, path, bmain->name, rd->cfra, format, (rd->scemode & R_EXTENSION), TRUE);
if (0 == BKE_imbuf_write(ibuf, filename, format))
printf("Cannot save Node File Output to %s\n", filename);
@@ -304,7 +304,7 @@ static void exec_output_file_multilayer(RenderData *rd, bNode *node, bNodeStack
int recty = -1;
int has_preview = 0;
- BKE_makepicstring(filename, nimf->base_path, bmain->name, rd->cfra, R_IMF_IMTYPE_MULTILAYER, (rd->scemode & R_EXTENSION), TRUE);
+ BKE_makepicstring_from_type(filename, nimf->base_path, bmain->name, rd->cfra, R_IMF_IMTYPE_MULTILAYER, (rd->scemode & R_EXTENSION), TRUE);
BLI_make_existing_file(filename);
for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) {
diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c
index 9a76764..50c8b2a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_rotate.c
+++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c
@@ -91,7 +91,7 @@ static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStac
switch (node->custom1) {
case 0:
- neareast_interpolation(ibuf, obuf, u, v, xo, yo);
+ nearest_interpolation(ibuf, obuf, u, v, xo, yo);
break;
case 1:
bilinear_interpolation(ibuf, obuf, u, v, xo, yo);
diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
index 41fb0e8..523f1de 100644
--- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
@@ -157,7 +157,7 @@ void register_node_type_cmp_splitviewer(bNodeTreeType *ttype)
{
static bNodeType ntype;
- node_type_base(ttype, &ntype, CMP_NODE_SPLITVIEWER, "SplitViewer", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS);
+ node_type_base(ttype, &ntype, CMP_NODE_SPLITVIEWER, "Split Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_splitviewer_in, NULL);
node_type_size(&ntype, 140, 100, 320);
node_type_init(&ntype, node_composit_init_splitviewer);
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c
index a8ef028..d6bb545 100644
--- a/source/blender/nodes/composite/nodes/node_composite_transform.c
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.c
@@ -93,7 +93,7 @@ CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, f
switch (filter_type) {
case 0:
- neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
+ nearest_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
break;
case 1:
bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 86ef8a1..dc8d427 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -305,7 +305,7 @@ void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *i
{
/* check inputs and outputs, and remove or insert them */
if (node->id==id) {
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup= (bNodeTree *)node->id;
group_verify_socket_list(ntree, node, &node->inputs, SOCK_IN, &ngroup->inputs);
group_verify_socket_list(ntree, node, &node->outputs, SOCK_OUT, &ngroup->outputs);
}
@@ -314,7 +314,7 @@ void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *i
struct bNodeTree *node_group_edit_get(bNode *node)
{
if (node->flag & NODE_GROUP_EDIT)
- return (bNodeTree*)node->id;
+ return (bNodeTree *)node->id;
else
return NULL;
}
@@ -322,7 +322,7 @@ struct bNodeTree *node_group_edit_get(bNode *node)
struct bNodeTree *node_group_edit_set(bNode *node, int edit)
{
if (edit) {
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup= (bNodeTree *)node->id;
if (ngroup) {
if (ngroup->id.lib)
ntreeMakeLocal(ngroup);
@@ -339,7 +339,7 @@ struct bNodeTree *node_group_edit_set(bNode *node, int edit)
void node_group_edit_clear(bNode *node)
{
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup= (bNodeTree *)node->id;
bNode *inode;
node->flag &= ~NODE_GROUP_EDIT;
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index 3cc7ebf..86f8f4d 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -114,13 +114,13 @@ static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeSocket *sock)
if (sock->default_value) {
switch (sock->type) {
case SOCK_FLOAT:
- ns->vec[0] = ((bNodeSocketValueFloat*)sock->default_value)->value;
+ ns->vec[0] = ((bNodeSocketValueFloat *)sock->default_value)->value;
break;
case SOCK_VECTOR:
- copy_v3_v3(ns->vec, ((bNodeSocketValueVector*)sock->default_value)->value);
+ copy_v3_v3(ns->vec, ((bNodeSocketValueVector *)sock->default_value)->value);
break;
case SOCK_RGBA:
- copy_v4_v4(ns->vec, ((bNodeSocketValueRGBA*)sock->default_value)->value);
+ copy_v4_v4(ns->vec, ((bNodeSocketValueRGBA *)sock->default_value)->value);
break;
}
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 6130fe7..544ccb8 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -139,49 +139,49 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
if (copyto) {
switch (a) {
case MAT_IN_COLOR:
- copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA*)sock->default_value)->value); break;
+ copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
case MAT_IN_SPEC:
- copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break;
+ copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
case MAT_IN_REFL:
- ma->ref= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->ref= ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_MIR:
- copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break;
+ copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
case MAT_IN_AMB:
- ma->amb= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->amb = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_EMIT:
- ma->emit= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->emit = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_SPECTRA:
- ma->spectra= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->spectra = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_RAY_MIRROR:
- ma->ray_mirror= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->ray_mirror = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_ALPHA:
- ma->alpha= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->alpha = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
case MAT_IN_TRANSLUCENCY:
- ma->translucency= ((bNodeSocketValueFloat*)sock->default_value)->value; break;
+ ma->translucency = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
}
}
else {
switch (a) {
case MAT_IN_COLOR:
- copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->r); break;
+ copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->r); break;
case MAT_IN_SPEC:
- copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->specr); break;
+ copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->specr); break;
case MAT_IN_REFL:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ref; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value= ma->ref; break;
case MAT_IN_MIR:
- copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->mirr); break;
+ copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->mirr); break;
case MAT_IN_AMB:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->amb; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->amb; break;
case MAT_IN_EMIT:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->emit; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->emit; break;
case MAT_IN_SPECTRA:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->spectra; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->spectra; break;
case MAT_IN_RAY_MIRROR:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ray_mirror; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->ray_mirror; break;
case MAT_IN_ALPHA:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->alpha; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->alpha; break;
case MAT_IN_TRANSLUCENCY:
- ((bNodeSocketValueFloat*)sock->default_value)->value= ma->translucency; break;
+ ((bNodeSocketValueFloat *)sock->default_value)->value = ma->translucency; break;
}
}
}
@@ -259,7 +259,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
break;
if (node)
- ntree= (bNodeTree*)node->id;
+ ntree = (bNodeTree *)node->id;
for (node= ntree->nodes.first; node; node= node->next)
if (node->flag & NODE_ACTIVE_TEXTURE)
@@ -320,7 +320,7 @@ void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in
float domax= (texmap->flag & TEXMAP_CLIP_MAX) != 0;
if (domin || domax || !(texmap->flag & TEXMAP_UNIT_MATRIX)) {
- GPUNodeLink *tmat = GPU_uniform((float*)texmap->mat);
+ GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat);
GPUNodeLink *tmin = GPU_uniform(texmap->min);
GPUNodeLink *tmax = GPU_uniform(texmap->max);
GPUNodeLink *tdomin = GPU_uniform(&domin);
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index 688d77d..cf6f778 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -70,7 +70,7 @@ static void move_stack(bNodeStack *to, bNodeStack *from)
static void *group_initexec(bNode *node)
{
- bNodeTree *ngroup= (bNodeTree*)node->id;
+ bNodeTree *ngroup = (bNodeTree *)node->id;
bNodeTreeExec *exec;
if (!ngroup)
@@ -84,7 +84,7 @@ static void *group_initexec(bNode *node)
static void group_freeexec(bNode *UNUSED(node), void *nodedata)
{
- bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata;
+ bNodeTreeExec*gexec = (bNodeTreeExec *)nodedata;
ntreeShaderEndExecTree(gexec, 0);
}
@@ -121,7 +121,7 @@ static void group_move_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack
static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
+ bNodeTreeExec *exec = (bNodeTreeExec *)nodedata;
bNodeThreadStack *nts;
if (!exec)
@@ -177,7 +177,7 @@ static void group_gpu_move_outputs(bNode *node, GPUNodeStack *out, bNodeStack *g
static int gpu_group_execute(GPUMaterial *mat, bNode *node, void *nodedata, GPUNodeStack *in, GPUNodeStack *out)
{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
+ bNodeTreeExec *exec = (bNodeTreeExec *)nodedata;
group_gpu_copy_inputs(node, in, exec->stack);
ntreeExecGPUNodes(exec, mat, (node->flag & NODE_GROUP_EDIT));
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 9fa654c..216e10a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -74,7 +74,7 @@ void register_node_type_sh_curve_vec(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
- node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out);
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_shader_init_curve_vec);
@@ -132,7 +132,7 @@ void register_node_type_sh_curve_rgb(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
- node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out);
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_shader_init_curve_rgb);
diff --git a/source/blender/nodes/shader/nodes/node_shader_hair_info.c b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
new file mode 100644
index 0000000..5cd4c8b
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_hair_info.c
@@ -0,0 +1,53 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+static bNodeSocketTemplate outputs[] = {
+ { SOCK_FLOAT, 0, N_("Is Strand"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Intercept"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Thickness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, N_("Tangent Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+/* node type definition */
+void register_node_type_sh_hair_info(bNodeTreeType *ttype)
+{
+ static bNodeType ntype;
+
+ node_type_base(ttype, &ntype, SH_NODE_HAIR_INFO, "Hair Info", NODE_CLASS_INPUT, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, NULL, outputs);
+ node_type_size(&ntype, 150, 60, 200);
+ node_type_init(&ntype, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_exec(&ntype, NULL);
+ node_type_gpu(&ntype, NULL);
+
+ nodeRegisterType(ttype, &ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index cedd3a4..396c1ac 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -77,7 +77,7 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, G
TexMapping *texmap= node->storage;
float domin= (texmap->flag & TEXMAP_CLIP_MIN) != 0;
float domax= (texmap->flag & TEXMAP_CLIP_MAX) != 0;
- GPUNodeLink *tmat = GPU_uniform((float*)texmap->mat);
+ GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat);
GPUNodeLink *tmin = GPU_uniform(texmap->min);
GPUNodeLink *tmax = GPU_uniform(texmap->max);
GPUNodeLink *tdomin = GPU_uniform(&domin);
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
index 2902bf1..a36f35c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_material.c
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -145,7 +145,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
/* make alpha output give results even if transparency is only enabled on
* the material linked in this not and not on the parent material */
mode = shi->mode;
- if(shi->mat->mode & MA_TRANSP)
+ if (shi->mat->mode & MA_TRANSP)
shi->mode |= MA_TRANSP;
shi->nodes= 1; /* temp hack to prevent trashadow recursion */
diff --git a/source/blender/opencl/SConscript b/source/blender/opencl/SConscript
index e91a99d..388789a 100644
--- a/source/blender/opencl/SConscript
+++ b/source/blender/opencl/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/*.c')
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 9bd45d2..13cb11d 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -66,7 +66,7 @@ void BPY_python_end(void);
/* 2.5 UI Scripts */
int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
-int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump);
+int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump);
void BPY_text_free_code(struct Text *text);
void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
void BPY_modules_load_user(struct bContext *C);
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index 012bc27..c28987e 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
# TODO, split into 3 files.
@@ -46,16 +71,103 @@ if env['WITH_BF_PYTHON_SAFETY']:
if env['BF_BUILDINFO']:
defs.append('BUILD_DATE')
-if env['WITH_BF_INTERNATIONAL']:
- defs.append('WITH_INTERNATIONAL')
-if env['WITH_BF_CYCLES']:
- defs.append('WITH_CYCLES')
+# Audaspace is always on currently
+
+if env['WITH_BF_BULLET']:
+ defs.append('WITH_BULLET')
+
+# AVI is always on currently
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
incs += ' ' + env['BF_FFMPEG_INC']
-
+
+if env['WITH_BF_QUICKTIME']:
+ defs.append('WITH_QUICKTIME')
+
+if env['WITH_BF_SNDFILE']:
+ defs.append('WITH_SNDFILE')
+
+if env['WITH_BF_COMPOSITOR']:
+ defs.append('WITH_COMPOSITOR')
+
+if env['WITH_BF_CYCLES']:
+ defs.append('WITH_CYCLES')
+
+if env['WITH_BF_CYCLES_OSL']:
+ defs.append('WITH_CYCLES_OSL')
+
+if env['WITH_BF_GAMEENGINE']:
+ defs.append('WITH_GAMEENGINE')
+
+if env['WITH_BF_CINEON']:
+ defs.append('WITH_CINEON')
+
+if env['WITH_BF_DDS']:
+ defs.append('WITH_DDS')
+
+if env['WITH_BF_FRAMESERVER']:
+ defs.append('WITH_FRAMESERVER')
+
+if env['WITH_BF_HDR']:
+ defs.append('WITH_HDR')
+
+if env['WITH_BF_OPENEXR']:
+ defs.append('WITH_OPENEXR')
+
+if env['WITH_BF_OPENJPEG']:
+ defs.append('WITH_OPENJPEG')
+
+if env['WITH_BF_REDCODE']:
+ defs.append('WITH_REDCODE')
+
+if env['WITH_BF_TIFF']:
+ defs.append('WITH_TIFF')
+
+# NDof is always on currently
+
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
+if env['WITH_BF_OPENAL']:
+ defs.append('WITH_OPENAL')
+
+if env['WITH_BF_SDL']:
+ defs.append('WITH_SDL')
+
+if env['WITH_BF_JACK']:
+ defs.append('WITH_JACK')
+
+if env['WITH_BF_LIBMV']:
+ defs.append('WITH_LIBMV')
+
+if env['WITH_BF_BOOLEAN']:
+ defs.append('WITH_MOD_BOOLEAN')
+
+if env['WITH_BF_FLUID']:
+ defs.append('WITH_MOD_FLUID')
+
+if env['WITH_BF_OCEANSIM']:
+ defs.append('WITH_OCEANSIM')
+
+if env['WITH_BF_REMESH']:
+ defs.append('WITH_MOD_REMESH')
+
+if env['WITH_BF_SMOKE']:
+ defs.append('WITH_SMOKE')
+
+if env['WITH_BF_COLLADA']:
+ defs.append('WITH_COLLADA')
+
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OCIO')
+
+if env['WITH_BF_PLAYER']:
+ defs.append('WITH_PLAYER')
+
+
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c
index 18f5d89..ce8153f 100644
--- a/source/blender/python/bmesh/bmesh_py_api.c
+++ b/source/blender/python/bmesh/bmesh_py_api.c
@@ -98,7 +98,7 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
}
PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
-".. method:: update_edit_mesh(mesh, tessface=True)\n"
+".. method:: update_edit_mesh(mesh, tessface=True, destructive=True)\n"
"\n"
" Update the mesh after changes to the BMesh in editmode, \n"
" optionally recalculating n-gon tessellation.\n"
@@ -107,14 +107,20 @@ PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
" :type mesh: :class:`bpy.types.Mesh`\n"
" :arg tessface: Option to recalculate n-gon tessellation.\n"
" :type tessface: boolean\n"
+" :arg destructive: Use when grometry has been added or removed.\n"
+" :type destructive: boolean\n"
);
-static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
+static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
+ static const char *kwlist[] = {"mesh", "tessface", "destructive", NULL};
PyObject *py_me;
Mesh *me;
int do_tessface = TRUE;
+ int is_destructive = TRUE;
- if (!PyArg_ParseTuple(args, "O|i:update_edit_mesh", &py_me, &do_tessface)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:update_edit_mesh", (char **)kwlist,
+ &py_me, &do_tessface, &is_destructive))
+ {
return NULL;
}
@@ -131,13 +137,8 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
}
{
- /* XXX, not great - infact this function could just not use the context at all
- * postpone that change until after release: BMESH_TODO - campbell */
- extern struct bContext *BPy_GetContext(void);
- extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, const short do_tessface);
-
- struct bContext *C = BPy_GetContext();
- EDBM_update_generic(C, me->edit_btmesh, do_tessface);
+ extern void EDBM_update_generic(BMEditMesh *em, const short do_tessface, const short is_destructive);
+ EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive);
}
Py_RETURN_NONE;
@@ -146,7 +147,7 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
static struct PyMethodDef BPy_BM_methods[] = {
{"new", (PyCFunction)bpy_bm_new, METH_NOARGS, bpy_bm_new_doc},
{"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
- {"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS, bpy_bm_update_edit_mesh_doc},
+ {"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS | METH_KEYWORDS, bpy_bm_update_edit_mesh_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index ded3536..3231519 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -523,7 +523,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
*
* \note Don't throw any exceptions and should always return a valid (PyObject *).
*/
-static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
+static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
{
PyObject *item = NULL;
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 5db9962..ea6e1e2 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1616,6 +1616,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self)
}
+PyDoc_STRVAR(bpy_bmface_normal_flip_doc,
+".. method:: normal_flip()\n"
+"\n"
+" Reverses winding of a face, which flips its normal.\n"
+);
+static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+
+ BM_face_normal_flip(self->bm, self->f);
+
+ Py_RETURN_NONE;
+}
+
+
/* Loop
* ---- */
@@ -2424,6 +2439,7 @@ static struct PyMethodDef bpy_bmface_methods[] = {
{"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc},
{"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc},
+ {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index fd31f3c..4a8f8d4 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
case CD_PROP_STR:
{
MStringProperty *mstring = value;
- ret = PyBytes_FromStringAndSize(mstring->s, BLI_strnlen(mstring->s, sizeof(mstring->s)));
+ ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len);
break;
}
case CD_MTEXPOLY:
@@ -1067,13 +1067,17 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
case CD_PROP_STR:
{
MStringProperty *mstring = value;
- const char *tmp_val = PyBytes_AsString(py_value);
- if (UNLIKELY(tmp_val == NULL)) {
+ char *tmp_val;
+ Py_ssize_t tmp_val_len;
+ if (UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) {
PyErr_Format(PyExc_TypeError, "expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name);
ret = -1;
}
else {
- BLI_strncpy(mstring->s, tmp_val, min_ii(PyBytes_Size(py_value), sizeof(mstring->s)));
+ if (tmp_val_len > sizeof(mstring->s))
+ tmp_val_len = sizeof(mstring->s);
+ memcpy(mstring->s, tmp_val, tmp_val_len);
+ mstring->s_len = tmp_val_len;
}
break;
}
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index 1592ec5..56cdf67 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -48,9 +48,9 @@ struct Text;
void bpy_import_init(PyObject *builtins);
-PyObject* bpy_text_import(struct Text *text);
-PyObject* bpy_text_import_name(const char *name, int *found);
-PyObject* bpy_text_reimport(PyObject *module, int *found);
+PyObject *bpy_text_import(struct Text *text);
+PyObject *bpy_text_import_name(const char *name, int *found);
+PyObject *bpy_text_reimport(PyObject *module, int *found);
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 53112d4..10ca7a9 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -836,6 +836,11 @@ static PyObject *BPy_IDGroup_to_dict(BPy_IDProperty *self)
return BPy_IDGroup_MapDataToPy(self->prop);
}
+static PyObject *BPy_IDGroup_clear(BPy_IDProperty *self)
+{
+ IDP_ClearProperty(self->prop);
+ Py_RETURN_NONE;
+}
/* Matches python dict.get(key, [default]) */
static PyObject *BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args)
@@ -875,6 +880,8 @@ static struct PyMethodDef BPy_IDGroup_methods[] = {
"idprop.get(k[,d]) -> idprop[k] if k in idprop, else d. d defaults to None"},
{"to_dict", (PyCFunction)BPy_IDGroup_to_dict, METH_NOARGS,
"return a purely python version of the group"},
+ {"clear", (PyCFunction)BPy_IDGroup_clear, METH_NOARGS,
+ "clear all members from this group"},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index f62fdaf..56d9e2a 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -33,6 +33,8 @@
#include <Python.h>
#include <frameobject.h>
+#include "BLI_utildefines.h" /* for bool */
+
#include "py_capi_utils.h"
/* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */
@@ -44,7 +46,7 @@
/* array utility function */
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
- const PyTypeObject *type, const short is_double, const char *error_prefix)
+ const PyTypeObject *type, const bool is_double, const char *error_prefix)
{
PyObject *value_fast;
Py_ssize_t value_len;
@@ -112,6 +114,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
return 0;
}
+/* array utility function */
+PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type,
+ const bool is_double, const char *error_prefix)
+{
+ PyObject *tuple;
+ int i;
+
+ tuple = PyTuple_New(length);
+
+ /* for each type */
+ if (type == &PyFloat_Type) {
+ if (is_double) {
+ const double *array_double = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i]));
+ }
+ }
+ else {
+ const float *array_float = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i]));
+ }
+ }
+ }
+ else if (type == &PyLong_Type) {
+ /* could use is_double for 'long int' but no use now */
+ const int *array_int = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i]));
+ }
+ }
+ else if (type == &PyBool_Type) {
+ const int *array_bool = array;
+ for (i = 0; i < length; ++i) {
+ PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i]));
+ }
+ }
+ else {
+ Py_DECREF(tuple);
+ PyErr_Format(PyExc_TypeError,
+ "%s: internal error %s is invalid",
+ error_prefix, type->tp_name);
+ return NULL;
+ }
+
+ return tuple;
+}
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
@@ -241,6 +291,23 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
return item;
}
+PyObject *PyC_FrozenSetFromStrings(const char **strings)
+{
+ const char **str;
+ PyObject *ret;
+
+ ret = PyFrozenSet_New(NULL);
+
+ for (str = strings; *str; str++) {
+ PyObject *py_str = PyUnicode_FromString(*str);
+ PySet_Add(ret, py_str);
+ Py_DECREF(py_str);
+ }
+
+ return ret;
+}
+
+
/* similar to PyErr_Format(),
*
* implementation - we cant actually preprend the existing exception,
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 935a5f9..2398580 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -33,11 +33,14 @@ void PyC_LineSpit(void);
void PyC_StackSpit(void);
PyObject * PyC_ExceptionBuffer(void);
PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
+PyObject * PyC_FrozenSetFromStrings(const char **strings);
PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);
void PyC_FileAndNum(const char **filename, int *lineno);
void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
- const PyTypeObject *type, const short is_double, const char *error_prefix);
+ const PyTypeObject *type, const bool is_double, const char *error_prefix);
+PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type,
+ const bool is_double, const char *error_prefix);
/* follow http://www.python.org/dev/peps/pep-0383/ */
PyObject * PyC_UnicodeFromByte(const char *str);
@@ -53,7 +56,7 @@ void PyC_MainModule_Restore(PyObject *main_mod);
void PyC_SetHomePath(const char *py_path_bundle);
-#define PYC_INTERPRETER_ACTIVE (((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
+#define PYC_INTERPRETER_ACTIVE (((PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL)
void *PyC_RNA_AsPointer(PyObject *value, const char *type_name);
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 61c4902..575185e 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
bpy.c
bpy_app.c
bpy_app_ffmpeg.c
+ bpy_app_build_options.c
bpy_app_handlers.c
bpy_driver.c
bpy_interface.c
@@ -55,6 +56,7 @@ set(SRC
bpy_library.c
bpy_operator.c
bpy_operator_wrap.c
+ bpy_path.c
bpy_props.c
bpy_rna.c
bpy_rna_anim.c
@@ -68,12 +70,14 @@ set(SRC
bpy.h
bpy_app.h
bpy_app_ffmpeg.h
+ bpy_app_build_options.h
bpy_app_handlers.h
bpy_driver.h
bpy_intern_string.h
bpy_library.h
bpy_operator.h
bpy_operator_wrap.h
+ bpy_path.h
bpy_props.h
bpy_rna.h
bpy_rna_anim.h
@@ -96,24 +100,140 @@ if(WITH_PYTHON_SAFETY)
add_definitions(-DWITH_PYTHON_SAFETY)
endif()
+
+
if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE)
endif()
-if(WITH_CYCLES)
- add_definitions(-DWITH_CYCLES)
+if(WITH_BULLET)
+ add_definitions(-DWITH_BULLET)
endif()
-if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+if(WITH_CODEC_AVI)
+ add_definitions(-DWITH_AVI)
endif()
if(WITH_CODEC_FFMPEG)
list(APPEND INC_SYS
${FFMPEG_INCLUDE_DIRS}
)
-
add_definitions(-DWITH_FFMPEG)
endif()
+if(WITH_CODEC_QUICKTIME)
+ add_definitions(-DWITH_QUICKTIME)
+endif()
+
+if(WITH_CODEC_SNDFILE)
+ add_definitions(-DWITH_SNDFILE)
+endif()
+
+if(WITH_COMPOSITOR)
+ add_definitions(-DWITH_COMPOSITOR)
+endif()
+
+if(WITH_CYCLES)
+ add_definitions(-DWITH_CYCLES)
+endif()
+
+if(WITH_CYCLES_OSL)
+ add_definitions(-DWITH_CYCLES_OSL)
+endif()
+
+if(WITH_GAMEENGINE)
+ add_definitions(-DWITH_GAMEENGINE)
+endif()
+
+if(WITH_IMAGE_CINEON)
+ add_definitions(-DWITH_CINEON)
+endif()
+
+if(WITH_IMAGE_DDS)
+ add_definitions(-DWITH_DDS)
+endif()
+
+if(WITH_IMAGE_FRAMESERVER)
+ add_definitions(-DWITH_FRAMESERVER)
+endif()
+
+if(WITH_IMAGE_HDR)
+ add_definitions(-DWITH_HDR)
+endif()
+
+if(WITH_IMAGE_OPENEXR)
+ add_definitions(-DWITH_OPENEXR)
+endif()
+
+if(WITH_IMAGE_OPENJPEG)
+ add_definitions(-DWITH_OPENJPEG)
+endif()
+
+if(WITH_IMAGE_REDCODE)
+ add_definitions(-DWITH_REDCODE)
+endif()
+
+if(WITH_IMAGE_TIFF)
+ add_definitions(-DWITH_TIFF)
+endif()
+
+if(WITH_INPUT_NDOF)
+ add_definitions(-DWITH_INPUT_NDOF)
+endif()
+
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
+if(WITH_OPENAL)
+ add_definitions(-DWITH_OPENAL)
+endif()
+
+if(WITH_SDL)
+ add_definitions(-DWITH_SDL)
+endif()
+
+if(WITH_JACK)
+ add_definitions(-DWITH_JACK)
+endif()
+
+if(WITH_LIBMV)
+ add_definitions(-DWITH_LIBMV)
+endif()
+
+if(WITH_MOD_BOOLEAN)
+ add_definitions(-DWITH_MOD_BOOLEAN)
+endif()
+
+if(WITH_MOD_FLUID)
+ add_definitions(-DWITH_MOD_FLUID)
+endif()
+
+if(WITH_MOD_OCEANSIM)
+ add_definitions(-DWITH_OCEANSIM)
+endif()
+
+if(WITH_MOD_REMESH)
+ add_definitions(-DWITH_MOD_REMESH)
+endif()
+
+if(WITH_MOD_SMOKE)
+ add_definitions(-DWITH_SMOKE)
+endif()
+
+if(WITH_OPENCOLLADA)
+ add_definitions(-DWITH_COLLADA)
+endif()
+
+if(WITH_OPENCOLORIO)
+ add_definitions(-DWITH_OCIO)
+endif()
+
+if(WITH_PLAYER)
+ add_definitions(-DWITH_PLAYER)
+endif()
+
+
+
+
blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 3ed662f..c4d6829 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -35,19 +35,19 @@
#include "RNA_types.h"
#include "RNA_access.h"
-#include "bpy.h"
-#include "bpy_util.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BKE_bpath.h"
+#include "BLI_utildefines.h"
+
+#include "bpy.h"
+#include "bpy_util.h"
#include "bpy_rna.h"
#include "bpy_app.h"
#include "bpy_props.h"
#include "bpy_library.h"
#include "bpy_operator.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-#include "BLI_bpath.h"
-#include "BLI_utildefines.h"
-
#include "BKE_main.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "BKE_blender.h"
@@ -94,7 +94,7 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), cons
PyObject *item = PyUnicode_DecodeFSDefault(path_src);
PyList_Append(list, item);
Py_DECREF(item);
- return FALSE; /* never edits the path */
+ return false; /* never edits the path */
}
PyDoc_STRVAR(bpy_blend_paths_doc,
@@ -116,9 +116,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
int flag = 0;
PyObject *list;
- int absolute = FALSE;
- int packed = FALSE;
- int local = FALSE;
+ int absolute = false;
+ int packed = false;
+ int local = false;
static const char *kwlist[] = {"absolute", "packed", "local", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths",
@@ -127,13 +127,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec
return NULL;
}
- if (absolute) flag |= BLI_BPATH_TRAVERSE_ABS;
- if (!packed) flag |= BLI_BPATH_TRAVERSE_SKIP_PACKED;
- if (local) flag |= BLI_BPATH_TRAVERSE_SKIP_LIBRARY;
+ if (absolute) flag |= BKE_BPATH_TRAVERSE_ABS;
+ if (!packed) flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED;
+ if (local) flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY;
list = PyList_New(0);
- BLI_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
+ BKE_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list);
return list;
}
@@ -205,7 +205,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return NULL;
}
- path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE);
+ path = BLI_get_folder_version(folder_id, (major * 100) + minor, false);
return PyUnicode_DecodeFSDefault(path ? path : "");
}
@@ -234,6 +234,7 @@ static PyObject *bpy_import_test(const char *modname)
return mod;
}
+
/******************************************************************************
* Description: Creates the bpy module and adds it to sys.modules for importing
******************************************************************************/
@@ -293,6 +294,9 @@ void BPy_init_modules(void)
PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
+ /* register bpy/rna classmethod callbacks */
+ BPY_rna_register_cb();
+
/* utility func's that have nowhere else to go */
PyModule_AddObject(mod, meth_bpy_script_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_script_paths, NULL));
PyModule_AddObject(mod, meth_bpy_blend_paths.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_blend_paths, NULL));
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index b1eeff8..3e2353c 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -34,6 +34,7 @@
#include "bpy_app.h"
#include "bpy_app_ffmpeg.h"
+#include "bpy_app_build_options.h"
#include "bpy_app_handlers.h"
#include "bpy_driver.h"
@@ -83,6 +84,7 @@ static PyStructSequence_Field app_info_fields[] = {
/* submodules */
{(char *)"ffmpeg", (char *)"FFmpeg library information backend"},
+ {(char *)"build_options", (char *)"A set containing most important enabled optional build features"},
{(char *)"handlers", (char *)"Application handler callbacks"},
{NULL}
};
@@ -148,6 +150,7 @@ static PyObject *make_app_info(void)
#endif
SetObjItem(BPY_app_ffmpeg_struct());
+ SetObjItem(BPY_app_build_options_struct());
SetObjItem(BPY_app_handlers_struct());
#undef SetIntItem
@@ -179,7 +182,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos
const int flag = GET_INT_FROM_POINTER(closure);
const int param = PyObject_IsTrue(value);
- if (param < 0) {
+ if (param == -1) {
PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
return -1;
}
diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c
new file mode 100644
index 0000000..0036b37
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_build_options.c
@@ -0,0 +1,303 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_app_build_options.c
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include "BLI_utildefines.h"
+
+#include "bpy_app_build_options.h"
+
+static PyTypeObject BlenderAppBuildOptionsType;
+
+static PyStructSequence_Field app_builtopts_info_fields[] = {
+ /* names mostly follow CMake options, lowecases, after WITH_ */
+ {(char *)"bullet", NULL},
+ {(char *)"codec_avi", NULL},
+ {(char *)"codec_ffmpeg", NULL},
+ {(char *)"codec_quicktime", NULL},
+ {(char *)"codec_sndfile", NULL},
+ {(char *)"compositor", NULL},
+ {(char *)"cycles", NULL},
+ {(char *)"cycles_osl", NULL},
+ {(char *)"gameengine", NULL},
+ {(char *)"image_cineon", NULL},
+ {(char *)"image_dds", NULL},
+ {(char *)"image_frameserver", NULL},
+ {(char *)"image_hdr", NULL},
+ {(char *)"image_openexr", NULL},
+ {(char *)"image_openjpeg", NULL},
+ {(char *)"image_redcode", NULL},
+ {(char *)"image_tiff", NULL},
+ {(char *)"input_ndof", NULL},
+ {(char *)"audaspace", NULL},
+ {(char *)"international", NULL},
+ {(char *)"openal", NULL},
+ {(char *)"sdl", NULL},
+ {(char *)"jack", NULL},
+ {(char *)"libmv", NULL},
+ {(char *)"mod_boolean", NULL},
+ {(char *)"mod_fluid", NULL},
+ {(char *)"mod_oceansim", NULL},
+ {(char *)"mod_remesh", NULL},
+ {(char *)"mod_smoke", NULL},
+ {(char *)"collada", NULL},
+ {(char *)"opencolorio", NULL},
+ {(char *)"player", NULL},
+ {NULL}
+};
+
+
+static PyStructSequence_Desc app_builtopts_info_desc = {
+ (char *)"bpy.app.build_options", /* name */
+ (char *)"This module contains information about FFmpeg blender is linked against", /* doc */
+ app_builtopts_info_fields, /* fields */
+ (sizeof(app_builtopts_info_fields) / sizeof(PyStructSequence_Field)) - 1
+};
+
+static PyObject *make_builtopts_info(void)
+{
+ PyObject *builtopts_info;
+ int pos = 0;
+
+ builtopts_info = PyStructSequence_New(&BlenderAppBuildOptionsType);
+ if (builtopts_info == NULL) {
+ return NULL;
+ }
+
+#define SetObjIncref(item) \
+ PyStructSequence_SET_ITEM(builtopts_info, pos++, (Py_IncRef(item), item))
+
+#ifdef WITH_BULLET
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_AVI
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_FFMPEG
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_QUICKTIME
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_SNDFILE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_COMPOSITOR
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_CYCLES
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_CYCLES_OSL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_GAMEENGINE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_CINEON
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_DDS
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_FRAMESERVER
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_HDR
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OPENEXR
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OPENJPEG
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_REDCODE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_TIFF
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_INPUT_NDOF
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_AUDASPACE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_INTERNATIONAL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OPENAL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_SDL
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_JACK
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_LIBMV
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_MOD_BOOLEAN
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_MOD_FLUID
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OCEANSIM
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_MOD_REMESH
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_SMOKE
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_COLLADA
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_OCIO
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#ifdef WITH_PLAYER
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
+#undef SetObjIncref
+
+ return builtopts_info;
+}
+
+PyObject *BPY_app_build_options_struct(void)
+{
+ PyObject *ret;
+
+ PyStructSequence_InitType(&BlenderAppBuildOptionsType, &app_builtopts_info_desc);
+
+ ret = make_builtopts_info();
+
+ /* prevent user from creating new instances */
+ BlenderAppBuildOptionsType.tp_init = NULL;
+ BlenderAppBuildOptionsType.tp_new = NULL;
+ BlenderAppBuildOptionsType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
+
+ return ret;
+}
diff --git a/source/blender/python/intern/bpy_app_build_options.h b/source/blender/python/intern/bpy_app_build_options.h
new file mode 100644
index 0000000..82a1417
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_build_options.h
@@ -0,0 +1,32 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_app_build_options.h
+ * \ingroup pythonintern
+ */
+
+#ifndef __BPY_APP_BUILD_OPTIONS_H__
+#define __BPY_APP_BUILD_OPTIONS_H__
+
+PyObject *BPY_app_build_options_struct(void);
+
+#endif /* __BPY_APP_BUILD_OPTIONS_H__ */
diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c
index 5ae2a11..3bf3dec 100644
--- a/source/blender/python/intern/bpy_app_ffmpeg.c
+++ b/source/blender/python/intern/bpy_app_ffmpeg.c
@@ -41,16 +41,16 @@ static PyTypeObject BlenderAppFFmpegType;
#define DEF_FFMPEG_LIB_VERSION(lib) \
{(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \
- {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")},
+ {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}
static PyStructSequence_Field app_ffmpeg_info_fields[] = {
{(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")},
- DEF_FFMPEG_LIB_VERSION(avcodec)
- DEF_FFMPEG_LIB_VERSION(avdevice)
- DEF_FFMPEG_LIB_VERSION(avformat)
- DEF_FFMPEG_LIB_VERSION(avutil)
- DEF_FFMPEG_LIB_VERSION(swscale)
+ DEF_FFMPEG_LIB_VERSION(avcodec),
+ DEF_FFMPEG_LIB_VERSION(avdevice),
+ DEF_FFMPEG_LIB_VERSION(avformat),
+ DEF_FFMPEG_LIB_VERSION(avutil),
+ DEF_FFMPEG_LIB_VERSION(swscale),
{NULL}
};
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 9a79616..c49794a 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -122,7 +122,7 @@ static void bpy_pydriver_update_dict(const float evaltime)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
- int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ bool use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -175,7 +175,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
PyObject *expr_code;
PyGILState_STATE gilstate;
- int use_gil;
+ bool use_gil;
DriverVar *dvar;
double result = 0.0; /* default return */
@@ -193,7 +193,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
return 0.0f;
}
- use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
if (use_gil)
gilstate = PyGILState_Ensure();
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index cdecf64..e9fa00c 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -39,11 +39,21 @@
#include "MEM_guardedalloc.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_utildefines.h"
+#include "BLI_threads.h"
+
#include "RNA_types.h"
#include "bpy.h"
#include "gpu.h"
#include "bpy_rna.h"
+#include "bpy_path.h"
#include "bpy_util.h"
#include "bpy_traceback.h"
#include "bpy_intern_string.h"
@@ -51,15 +61,6 @@
#include "DNA_space_types.h"
#include "DNA_text_types.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
-#include "BLI_listbase.h"
-#include "BLI_math_base.h"
-#include "BLI_string.h"
-#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
-#include "BLI_threads.h"
-
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_main.h"
@@ -165,7 +166,7 @@ void BPY_text_free_code(Text *text)
{
if (text->compiled) {
PyGILState_STATE gilstate;
- int use_gil = !PYC_INTERPRETER_ACTIVE;
+ bool use_gil = !PYC_INTERPRETER_ACTIVE;
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -212,6 +213,7 @@ static struct _inittab bpy_internal_modules[] = {
{(char *)"mathutils", PyInit_mathutils},
// {(char *)"mathutils.geometry", PyInit_mathutils_geometry},
// {(char *)"mathutils.noise", PyInit_mathutils_noise},
+ {(char *)"_bpy_path", BPyInit__bpy_path},
{(char *)"bgl", BPyInit_bgl},
{(char *)"blf", BPyInit_blf},
{(char *)"bmesh", BPyInit_bmesh},
@@ -269,7 +271,8 @@ void BPY_python_start(int argc, const char **argv)
Py_Initialize();
/* THIS IS BAD: see http://bugs.python.org/issue16129 */
-#if 1
+ /* this clobbers the stdout on exit (no 'MEM_printmemlist_stats') */
+#if 0
/* until python provides a reliable way to set the env var */
PyRun_SimpleString("import sys, io\n"
"sys.__backup_stdio__ = sys.__stdout__, sys.__stderr__\n" /* else we loose the FD's [#32720] */
@@ -375,8 +378,8 @@ static void python_script_error_jump_text(struct Text *text)
python_script_error_jump(text->id.name + 2, &lineno, &offset);
if (lineno != -1) {
/* select the line with the error */
- txt_move_to(text, lineno - 1, INT_MAX, FALSE);
- txt_move_to(text, lineno - 1, offset, TRUE);
+ txt_move_to(text, lineno - 1, INT_MAX, false);
+ txt_move_to(text, lineno - 1, offset, true);
}
}
@@ -394,7 +397,7 @@ typedef struct {
#endif
static int python_script_exec(bContext *C, const char *fn, struct Text *text,
- struct ReportList *reports, const short do_jump)
+ struct ReportList *reports, const bool do_jump)
{
Main *bmain_old = CTX_data_main(C);
PyObject *main_mod = NULL;
@@ -511,11 +514,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text,
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
- return python_script_exec(C, filepath, NULL, reports, FALSE);
+ return python_script_exec(C, filepath, NULL, reports, false);
}
-int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump)
+int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump)
{
return python_script_exec(C, NULL, text, reports, do_jump);
}
@@ -716,12 +719,12 @@ void BPY_modules_load_user(bContext *C)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
{
PyGILState_STATE gilstate;
- int use_gil = !PYC_INTERPRETER_ACTIVE;
+ bool use_gil = !PYC_INTERPRETER_ACTIVE;
PyObject *pyctx;
PyObject *item;
PointerRNA *ptr = NULL;
- int done = FALSE;
+ bool done = false;
if (use_gil)
gilstate = PyGILState_Ensure();
@@ -740,7 +743,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
//result->ptr = ((BPy_StructRNA *)item)->ptr;
CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data);
- done = TRUE;
+ done = true;
}
else if (PySequence_Check(item)) {
PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion");
@@ -771,7 +774,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
}
Py_DECREF(seq_fast);
- done = TRUE;
+ done = true;
}
}
@@ -817,7 +820,7 @@ typedef struct {
} dealloc_obj;
/* call once __file__ is set */
-void bpy_module_delay_init(PyObject *bpy_proxy)
+static void bpy_module_delay_init(PyObject *bpy_proxy)
{
const int argc = 1;
const char *argv[2];
@@ -856,6 +859,9 @@ static void dealloc_obj_dealloc(PyObject *self)
}
PyMODINIT_FUNC
+PyInit_bpy(void);
+
+PyMODINIT_FUNC
PyInit_bpy(void)
{
PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c
index 13d8ced..d1d33a0 100644
--- a/source/blender/python/intern/bpy_interface_atexit.c
+++ b/source/blender/python/intern/bpy_interface_atexit.c
@@ -31,13 +31,13 @@
#include <Python.h>
+#include "BLI_utildefines.h"
+
#include "bpy_util.h"
#include "bpy.h" /* own include */
#include "WM_api.h"
-#include "BLI_utildefines.h"
-
static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw))
{
/* close down enough of blender at least not to crash */
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 7571fe0..ec6322a 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -244,7 +244,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports);
if (self->blo_handle == NULL) {
- if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) {
+ if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) {
PyErr_Format(PyExc_IOError,
"load: %s failed to open blend file",
self->abspath);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 55ef217..ee88568 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -35,6 +35,9 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
#include "BPY_extern.h"
#include "bpy_operator.h"
#include "bpy_operator_wrap.h"
@@ -42,9 +45,6 @@
#include "bpy_util.h"
#include "../generic/bpy_internal_import.h"
-#include "BLI_utildefines.h"
-#include "BLI_string.h"
-
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -85,7 +85,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
return NULL;
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -147,7 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
/* note that context is an int, python does the conversion in this case */
int context = WM_OP_EXEC_DEFAULT;
- int is_undo = FALSE;
+ int is_undo = false;
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
@@ -164,7 +164,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -209,7 +209,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
CTX_py_dict_set(C, (void *)context_dict);
Py_XINCREF(context_dict); /* so we done loose it */
- if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) {
+ if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
const char *msg = CTX_wm_operator_poll_msg_get(C);
PyErr_Format(PyExc_RuntimeError,
"Operator bpy.ops.%.200s.poll() %.200s",
@@ -248,7 +248,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
}
#endif
- error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE);
+ error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);
/* operator output is nice to have in the terminal/console too */
if (reports->list.first) {
@@ -328,7 +328,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args))
return NULL;
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_AttributeError,
@@ -392,7 +392,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument");
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname);
return NULL;
@@ -408,7 +408,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = TRUE;
+ pyrna->freeptr = true;
#endif
return (PyObject *)pyrna;
}
@@ -425,7 +425,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument");
return NULL;
}
- ot = WM_operatortype_find(opname, TRUE);
+ ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname);
return NULL;
@@ -444,7 +444,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = TRUE;
+ pyrna->freeptr = true;
#endif
op->ptr = &pyrna->ptr;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 1caec29..cb2e12b 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -112,7 +112,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname))
return NULL;
- if (WM_operatortype_find(opname, TRUE) == NULL) {
+ if (WM_operatortype_find(opname, true) == NULL) {
PyErr_Format(PyExc_ValueError,
"Macro Define: '%s' is not a valid operator id",
opname);
@@ -123,7 +123,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
srna = srna_from_self(macro, "Macro Define:");
macroname = RNA_struct_identifier(srna);
- ot = WM_operatortype_find(macroname, TRUE);
+ ot = WM_operatortype_find(macroname, true);
if (!ot) {
PyErr_Format(PyExc_ValueError,
diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c
new file mode 100644
index 0000000..1d554b6
--- /dev/null
+++ b/source/blender/python/intern/bpy_path.c
@@ -0,0 +1,67 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_path.c
+ * \ingroup pythonintern
+ *
+ * This file defines '_bpy_path' module, Some 'C' funtionality used by 'bpy.path'
+ */
+
+#include <Python.h>
+
+#include "BLI_utildefines.h"
+
+#include "bpy_path.h"
+
+#include "../generic/py_capi_utils.h"
+
+/* #include "IMB_imbuf_types.h" */
+extern const char *imb_ext_image[];
+extern const char *imb_ext_movie[];
+extern const char *imb_ext_audio[];
+
+/*----------------------------MODULE INIT-------------------------*/
+static struct PyModuleDef _bpy_path_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "_bpy_path", /* m_name */
+ NULL, /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyObject *BPyInit__bpy_path(void)
+{
+ PyObject *submodule;
+
+ submodule = PyModule_Create(&_bpy_path_module_def);
+
+ PyModule_AddObject(submodule, "extensions_image", PyC_FrozenSetFromStrings(imb_ext_image));
+ PyModule_AddObject(submodule, "extensions_movie", PyC_FrozenSetFromStrings(imb_ext_movie));
+ PyModule_AddObject(submodule, "extensions_audio", PyC_FrozenSetFromStrings(imb_ext_audio));
+
+ return submodule;
+}
+
diff --git a/source/blender/python/intern/bpy_path.h b/source/blender/python/intern/bpy_path.h
new file mode 100644
index 0000000..a0f3120
--- /dev/null
+++ b/source/blender/python/intern/bpy_path.h
@@ -0,0 +1,33 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_path.h
+ * \ingroup pythonintern
+ */
+
+
+#ifndef __BPY_PATH_H__
+#define __BPY_PATH_H__
+
+PyObject *BPyInit__bpy_path(void);
+
+#endif
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index bd03373..f3fa0c9 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -33,12 +33,12 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+
#include "bpy_props.h"
#include "bpy_rna.h"
#include "bpy_util.h"
-#include "BLI_utildefines.h"
-
#include "BKE_idprop.h"
#include "RNA_access.h"
@@ -50,9 +50,11 @@
#include "../generic/py_capi_utils.h"
/* initial definition of callback slots we'll probably have more then 1 */
-#define BPY_DATA_CB_SLOT_SIZE 1
+#define BPY_DATA_CB_SLOT_SIZE 3
#define BPY_DATA_CB_SLOT_UPDATE 0
+#define BPY_DATA_CB_SLOT_GET 1
+#define BPY_DATA_CB_SLOT_SET 2
extern BPy_StructRNA *bpy_context_module;
@@ -137,118 +139,1353 @@ static PyObject *pyrna_struct_as_instance(PointerRNA *ptr)
self = *instance;
Py_INCREF(self);
}
- }
- }
+ }
+ }
+
+ /* in most cases this will run */
+ if (self == NULL) {
+ self = pyrna_struct_CreatePyObject(ptr);
+ }
+
+ return self;
+}
+
+/* could be moved into bpy_utils */
+static void printf_func_error(PyObject *py_func)
+{
+ /* since we return to C code we can't leave the error */
+ PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
+ PyErr_Print();
+ PyErr_Clear();
+
+ /* use py style error */
+ fprintf(stderr, "File \"%s\", line %d, in %s\n",
+ _PyUnicode_AsString(f_code->co_filename),
+ f_code->co_firstlineno,
+ _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)
+ );
+}
+
+/* operators and classes use this so it can store the args given but defer
+ * running it until the operator runs where these values are used to setup
+ * the default args for that operator instance */
+static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
+{
+ PyObject *ret = PyTuple_New(2);
+ PyTuple_SET_ITEM(ret, 0, func);
+ Py_INCREF(func);
+
+ if (kw == NULL)
+ kw = PyDict_New();
+ else
+ Py_INCREF(kw);
+
+ PyTuple_SET_ITEM(ret, 1, kw);
+
+ return ret;
+}
+
+/* callbacks */
+static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyGILState_STATE gilstate;
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ py_func = py_data[BPY_DATA_CB_SLOT_UPDATE];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
+ Py_INCREF(bpy_context_module);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ bpy_context_clear(C, &gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = false;
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = false;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = false;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = false;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = 0;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ float value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+ else {
+ value = PyFloat_AsDouble(ret);
+
+ if (value == -1.0f && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = 0.0f;
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int i, len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0.0f;
+ }
+ else {
+ if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) {
+ printf_func_error(py_func);
+
+ for (i = 0; i < len; ++i)
+ values[i] = 0.0f;
+
+ /* PyC_AsArray decrements refcount internally on error */
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyObject *py_values;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int len = RNA_property_array_length(ptr, prop);
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set");
+ if (!py_values) {
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_values);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value[0] = '\0';
+ }
+ else if (!PyUnicode_Check(ret)) {
+ PyErr_Format(PyExc_TypeError,
+ "return value must be a string, not %.200s",
+ Py_TYPE(ret)->tp_name);
+ printf_func_error(py_func);
+ value[0] = '\0';
+ Py_DECREF(ret);
+ }
+ else {
+ Py_ssize_t length;
+ const char *buffer = _PyUnicode_AsStringAndSize(ret, &length);
+ memcpy(value, buffer, length + 1);
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int length;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ length = 0;
+ }
+ else if (!PyUnicode_Check(ret)) {
+ PyErr_Format(PyExc_TypeError,
+ "return value must be a string, not %.200s",
+ Py_TYPE(ret)->tp_name);
+ printf_func_error(py_func);
+ length = 0;
+ Py_DECREF(ret);
+ }
+ else {
+ Py_ssize_t length_ssize_t = 0;
+ _PyUnicode_AsStringAndSize(ret, &length_ssize_t);
+ length = length_ssize_t;
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return length;
+}
+
+static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ PyObject *py_value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ py_value = PyUnicode_FromString(value);
+ if (!py_value) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be a string");
+ printf_func_error(py_func);
+ }
+ else
+ PyTuple_SET_ITEM(args, 1, py_value);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+ int value;
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_GET];
+
+ args = PyTuple_New(1);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ value = RNA_property_enum_get_default(ptr, prop);
+ }
+ else {
+ value = PyLong_AsLong(ret);
+
+ if (value == -1 && PyErr_Occurred()) {
+ printf_func_error(py_func);
+ value = RNA_property_enum_get_default(ptr, prop);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+
+ return value;
+}
+
+static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
+{
+ PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ PyGILState_STATE gilstate;
+ bool use_gil;
+ const int is_write_ok = pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if (!is_write_ok) {
+ pyrna_write_set(true);
+ }
+
+ use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */
+
+ if (use_gil)
+ gilstate = PyGILState_Ensure();
+
+ py_func = py_data[BPY_DATA_CB_SLOT_SET];
+
+ args = PyTuple_New(2);
+ self = pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if (ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ if (use_gil)
+ PyGILState_Release(gilstate);
+
+ if (!is_write_ok) {
+ pyrna_write_set(false);
+ }
+}
+
+/* utility function we need for parsing int's in an if statement */
+static int py_long_as_int(PyObject *py_long, int *r_int)
+{
+ if (PyLong_CheckExact(py_long)) {
+ *r_int = (int)PyLong_AS_LONG(py_long);
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+#if 0
+/* copies orig to buf, then sets orig to buf, returns copy length */
+static size_t strswapbufcpy(char *buf, const char **orig)
+{
+ const char *src = *orig;
+ char *dst = buf;
+ size_t i = 0;
+ *orig = buf;
+ while ((*dst = *src)) { dst++; src++; i++; }
+ return i + 1; /* include '\0' */
+}
+#endif
+
+static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
+{
+ EnumPropertyItem *items;
+ PyObject *item;
+ const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
+ Py_ssize_t totbuf = 0;
+ int i;
+ short def_used = 0;
+ const char *def_cmp = NULL;
+
+ if (is_enum_flag) {
+ if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): maximum "
+ STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
+ " members for a ENUM_FLAG type property");
+ return NULL;
+ }
+ if (def && !PySet_Check(def)) {
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(...): default option must be a 'set' "
+ "type when ENUM_FLAG is enabled, not a '%.200s'",
+ Py_TYPE(def)->tp_name);
+ return NULL;
+ }
+ }
+ else {
+ if (def) {
+ def_cmp = _PyUnicode_AsString(def);
+ if (def_cmp == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(...): default option must be a 'str' "
+ "type when ENUM_FLAG is disabled, not a '%.200s'",
+ Py_TYPE(def)->tp_name);
+ return NULL;
+ }
+ }
+ }
+
+ /* blank value */
+ *defvalue = 0;
+
+ items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
+
+ for (i = 0; i < seq_len; i++) {
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ Py_ssize_t item_size;
+ Py_ssize_t id_str_size;
+ Py_ssize_t name_str_size;
+ Py_ssize_t desc_str_size;
+
+ item = PySequence_Fast_GET_ITEM(seq_fast, i);
+
+ if ((PyTuple_CheckExact(item)) &&
+ (item_size = PyTuple_GET_SIZE(item)) &&
+ (item_size == 3 || item_size == 4) &&
+ (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
+ (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
+ (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
+ /* TODO, number isn't ensured to be unique from the script author */
+ (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1))
+ {
+ if (is_enum_flag) {
+ if (item_size < 4) {
+ tmp.value = 1 << i;
+ }
+
+ if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
+ *defvalue |= tmp.value;
+ def_used++;
+ }
+ }
+ else {
+ if (item_size < 4) {
+ tmp.value = i;
+ }
+
+ if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
+ *defvalue = tmp.value;
+ def_used++; /* only ever 1 */
+ }
+ }
- /* in most cases this will run */
- if (self == NULL) {
- self = pyrna_struct_CreatePyObject(ptr);
- }
+ items[i] = tmp;
- return self;
-}
+ /* calculate combine string length */
+ totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
+ }
+ else {
+ MEM_freeN(items);
+ PyErr_SetString(PyExc_TypeError,
+ "EnumProperty(...): expected a tuple containing "
+ "(identifier, name, description) and optionally a "
+ "unique number");
+ return NULL;
+ }
-/* could be moved into bpy_utils */
-static void printf_func_error(PyObject *py_func)
-{
- /* since we return to C code we can't leave the error */
- PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
- PyErr_Print();
- PyErr_Clear();
+ }
- /* use py style error */
- fprintf(stderr, "File \"%s\", line %d, in %s\n",
- _PyUnicode_AsString(f_code->co_filename),
- f_code->co_firstlineno,
- _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)
- );
-}
+ if (is_enum_flag) {
+ /* strict check that all set members were used */
+ if (def && def_used != PySet_GET_SIZE(def)) {
+ MEM_freeN(items);
-/* operators and classes use this so it can store the args given but defer
- * running it until the operator runs where these values are used to setup
- * the default args for that operator instance */
-static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
-{
- PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, func);
- Py_INCREF(func);
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(..., default={...}): set has %d unused member(s)",
+ PySet_GET_SIZE(def) - def_used);
+ return NULL;
+ }
+ }
+ else {
+ if (def && def_used == 0) {
+ MEM_freeN(items);
- if (kw == NULL)
- kw = PyDict_New();
- else
- Py_INCREF(kw);
+ PyErr_Format(PyExc_TypeError,
+ "EnumProperty(..., default=\'%s\'): not found in enum members",
+ def_cmp);
+ return NULL;
+ }
+ }
- PyTuple_SET_ITEM(ret, 1, kw);
+ /* disabled duplicating strings because the array can still be freed and
+ * the strings from it referenced, for now we can't support dynamically
+ * created strings from python. */
+#if 0
+ /* this would all work perfectly _but_ the python strings may be freed
+ * immediately after use, so we need to duplicate them, ugh.
+ * annoying because it works most of the time without this. */
+ {
+ EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
+ "enum_items_from_py2");
+ EnumPropertyItem *items_ptr = items_dup;
+ char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
+ memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
+ for (i = 0; i < seq_len; i++, items_ptr++) {
+ buf += strswapbufcpy(buf, &items_ptr->identifier);
+ buf += strswapbufcpy(buf, &items_ptr->name);
+ buf += strswapbufcpy(buf, &items_ptr->description);
+ }
+ MEM_freeN(items);
+ items = items_dup;
+ }
+ /* end string duplication */
+#endif
- return ret;
+ return items;
}
-/* callbacks */
-static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop)
+static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
{
PyGILState_STATE gilstate;
- PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
- PyObject *py_func;
- PyObject *args;
- PyObject *self;
- PyObject *ret;
- const int is_write_ok = pyrna_write_check();
- BLI_assert(py_data != NULL);
+ PyObject *py_func = RNA_property_enum_py_data_get(prop);
+ PyObject *self = NULL;
+ PyObject *args;
+ PyObject *items; /* returned from the function call */
- if (!is_write_ok) {
- pyrna_write_set(TRUE);
- }
+ EnumPropertyItem *eitems = NULL;
+ int err = 0;
bpy_context_set(C, &gilstate);
- py_func = py_data[BPY_DATA_CB_SLOT_UPDATE];
-
args = PyTuple_New(2);
self = pyrna_struct_as_instance(ptr);
PyTuple_SET_ITEM(args, 0, self);
+ /* now get the context */
PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
Py_INCREF(bpy_context_module);
- ret = PyObject_CallObject(py_func, args);
+ items = PyObject_CallObject(py_func, args);
Py_DECREF(args);
- if (ret == NULL) {
- printf_func_error(py_func);
+ if (items == NULL) {
+ err = -1;
}
else {
- if (ret != Py_None) {
- PyErr_SetString(PyExc_ValueError, "the return value must be None");
- printf_func_error(py_func);
+ PyObject *items_fast;
+ int defvalue_dummy = 0;
+
+ if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
+ "return value from the callback was not a sequence")))
+ {
+ err = -1;
}
+ else {
+ eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
+ (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
- Py_DECREF(ret);
+ Py_DECREF(items_fast);
+
+ if (!eitems) {
+ err = -1;
+ }
+ }
+
+ Py_DECREF(items);
}
- bpy_context_clear(C, &gilstate);
+ if (err != -1) { /* worked */
+ *free = 1;
+ }
+ else {
+ printf_func_error(py_func);
- if (!is_write_ok) {
- pyrna_write_set(FALSE);
+ eitems = DummyRNA_NULL_items;
}
+
+
+ bpy_context_clear(C, &gilstate);
+ return eitems;
}
-static int bpy_prop_callback_check(PyObject *py_func, int argcount)
+static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
{
if (py_func && py_func != Py_None) {
if (!PyFunction_Check(py_func)) {
PyErr_Format(PyExc_TypeError,
- "update keyword: expected a function type, not a %.200s",
- Py_TYPE(py_func)->tp_name);
+ "%s keyword: expected a function type, not a %.200s",
+ keyword, Py_TYPE(py_func)->tp_name);
return -1;
}
else {
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
if (f_code->co_argcount != argcount) {
PyErr_Format(PyExc_TypeError,
- "update keyword: expected a function taking %d arguments, not %d",
- argcount, f_code->co_argcount);
+ "%s keyword: expected a function taking %d arguments, not %d",
+ keyword, argcount, f_code->co_argcount);
return -1;
}
}
@@ -257,32 +1494,215 @@ static int bpy_prop_callback_check(PyObject *py_func, int argcount)
return 0;
}
+static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop)
+{
+ PyObject **py_data = RNA_property_py_data_get(prop);
+ if (!py_data) {
+ py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
+ RNA_def_py_data(prop, py_data);
+ }
+ return py_data;
+}
-static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
+static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb)
{
/* assume this is already checked for type and arg length */
if (update_cb && update_cb != Py_None) {
- PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
- RNA_def_py_data(prop, py_data);
RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
}
+}
- return 0;
+static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ BooleanPropertyGetFunc rna_get_cb = NULL;
+ BooleanPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_boolean_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_boolean_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb);
}
-/* utility function we need for parsing int's in an if statement */
-static int py_long_as_int(PyObject *py_long, int *r_int)
+static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
{
- if (PyLong_CheckExact(py_long)) {
- *r_int = (int)PyLong_AS_LONG(py_long);
- return 0;
+ BooleanArrayPropertyGetFunc rna_get_cb = NULL;
+ BooleanArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_boolean_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
}
- else {
- return -1;
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_boolean_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb);
+}
+
+static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ IntPropertyGetFunc rna_get_cb = NULL;
+ IntPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_int_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_int_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ IntArrayPropertyGetFunc rna_get_cb = NULL;
+ IntArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_int_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_int_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ FloatPropertyGetFunc rna_get_cb = NULL;
+ FloatPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_float_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_float_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ FloatArrayPropertyGetFunc rna_get_cb = NULL;
+ FloatArrayPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_float_array_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_float_array_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
+}
+
+static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
+{
+ StringPropertyGetFunc rna_get_cb = NULL;
+ StringPropertyLengthFunc rna_length_cb = NULL;
+ StringPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_string_get_cb;
+ rna_length_cb = bpy_prop_string_length_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_string_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb);
+}
+
+static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb)
+{
+ EnumPropertyGetFunc rna_get_cb = NULL;
+ EnumPropertyItemFunc rna_itemf_cb = NULL;
+ EnumPropertySetFunc rna_set_cb = NULL;
+
+ if (get_cb && get_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_get_cb = bpy_prop_enum_get_cb;
+ py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
+ }
+
+ if (set_cb && set_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ rna_set_cb = bpy_prop_enum_set_cb;
+ py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
+ }
+
+ if (itemf_cb && itemf_cb != Py_None) {
+ rna_itemf_cb = bpy_prop_enum_itemf_cb;
+ RNA_def_property_enum_py_data(prop, (void *)itemf_cb);
+
+ /* watch out!, if a user is tricky they can probably crash blender
+ * if they manage to free the callback, take care! */
+ /* Py_INCREF(itemf_cb); */
}
+
+ RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb);
}
/* this define runs at the start of each function and deals with
@@ -386,7 +1806,9 @@ PyDoc_STRVAR(BPy_BoolProperty_doc,
"default=False, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new boolean property definition.\n"
"\n"
@@ -406,7 +1828,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "options", "subtype", "update", NULL};
+ "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int def = 0;
@@ -416,20 +1838,28 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiO!sO:BoolProperty",
+ "s#|ssiO!sOOO:BoolProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -443,7 +1873,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_boolean(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -457,7 +1888,9 @@ PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector boolean property definition.\n"
"\n"
@@ -483,7 +1916,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "options", "subtype", "size", "update", NULL};
+ "options", "subtype", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int def[PYRNA_STACK_ARRAY] = {0};
@@ -495,13 +1928,15 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOO!siO:BoolVectorProperty",
+ "s#|ssOO!siOOO:BoolVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&PySet_Type, &pyopts, &pysubtype, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -515,10 +1950,16 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -534,7 +1975,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -550,7 +1992,9 @@ PyDoc_STRVAR(BPy_IntProperty_doc,
"step=1, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new int property definition.\n"
"\n"
@@ -571,7 +2015,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "options", "subtype", "update", NULL};
+ "step", "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
@@ -581,21 +2025,29 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiiiiiiO!sO:IntProperty",
+ "s#|ssiiiiiiO!sOOO:IntProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -611,7 +2063,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_int(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -626,7 +2079,9 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector int property definition.\n"
"\n"
@@ -653,7 +2108,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "options", "subtype", "size", "update", NULL};
+ "step", "options", "subtype", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1;
@@ -666,15 +2121,17 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOiiiiiO!siO:IntVectorProperty",
+ "s#|ssOiiiiiO!siOOO:IntVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts,
&pysubtype, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -688,10 +2145,16 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -708,7 +2171,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_int_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -726,7 +2190,9 @@ PyDoc_STRVAR(BPy_FloatProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"unit='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new float property definition.\n"
"\n"
@@ -748,7 +2214,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "precision", "options", "subtype", "unit", "update", NULL};
+ "step", "precision", "options", "subtype",
+ "unit", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
@@ -761,15 +2228,17 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssffffffiO!ssO:FloatProperty",
+ "s#|ssffffffiO!ssOOO:FloatProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
&pyopts, &pysubtype, &pyunit,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -781,7 +2250,13 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -797,7 +2272,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_float(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -814,7 +2290,9 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
"options={'ANIMATABLE'}, "
"subtype='NONE', "
"size=3, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new vector float property definition.\n"
"\n"
@@ -842,7 +2320,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
"min", "max", "soft_min", "soft_max",
- "step", "precision", "options", "subtype", "unit", "size", "update", NULL};
+ "step", "precision", "options", "subtype",
+ "unit", "size", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3;
@@ -857,15 +2336,17 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
char *pyunit = NULL;
int unit = PROP_UNIT_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOfffffiO!ssiO:FloatVectorProperty",
+ "s#|ssOfffffiO!ssiOOO:FloatVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
&pyopts, &pysubtype, &pyunit, &size,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
@@ -884,10 +2365,16 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
return NULL;
}
- if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
+ if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") == -1)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -904,7 +2391,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_float_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -917,7 +2405,9 @@ PyDoc_STRVAR(BPy_StringProperty_doc,
"maxlen=0, "
"options={'ANIMATABLE'}, "
"subtype='NONE', "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new string property definition.\n"
"\n"
@@ -937,7 +2427,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (srna) {
static const char *kwlist[] = {"attr", "name", "description", "default",
- "maxlen", "options", "subtype", "update", NULL};
+ "maxlen", "options", "subtype", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "", *def = "";
int id_len;
int maxlen = 0;
@@ -947,20 +2437,28 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
char *pysubtype = NULL;
int subtype = PROP_NONE;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|sssiO!sO:StringProperty",
+ "s#|sssiO!sOOO:StringProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&maxlen, &PySet_Type, &pyopts, &pysubtype,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -975,246 +2473,22 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_string(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
-#if 0
-/* copies orig to buf, then sets orig to buf, returns copy length */
-static size_t strswapbufcpy(char *buf, const char **orig)
-{
- const char *src = *orig;
- char *dst = buf;
- size_t i = 0;
- *orig = buf;
- while ((*dst = *src)) { dst++; src++; i++; }
- return i + 1; /* include '\0' */
-}
-#endif
-
-static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
-{
- EnumPropertyItem *items;
- PyObject *item;
- const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
- Py_ssize_t totbuf = 0;
- int i;
- short def_used = 0;
- const char *def_cmp = NULL;
-
- if (is_enum_flag) {
- if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
- PyErr_SetString(PyExc_TypeError,
- "EnumProperty(...): maximum "
- STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
- " members for a ENUM_FLAG type property");
- return NULL;
- }
- if (def && !PySet_Check(def)) {
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(...): default option must be a 'set' "
- "type when ENUM_FLAG is enabled, not a '%.200s'",
- Py_TYPE(def)->tp_name);
- return NULL;
- }
- }
- else {
- if (def) {
- def_cmp = _PyUnicode_AsString(def);
- if (def_cmp == NULL) {
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(...): default option must be a 'str' "
- "type when ENUM_FLAG is disabled, not a '%.200s'",
- Py_TYPE(def)->tp_name);
- return NULL;
- }
- }
- }
-
- /* blank value */
- *defvalue = 0;
-
- items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
-
- for (i = 0; i < seq_len; i++) {
- EnumPropertyItem tmp = {0, "", 0, "", ""};
- Py_ssize_t item_size;
- Py_ssize_t id_str_size;
- Py_ssize_t name_str_size;
- Py_ssize_t desc_str_size;
-
- item = PySequence_Fast_GET_ITEM(seq_fast, i);
-
- if ((PyTuple_CheckExact(item)) &&
- (item_size = PyTuple_GET_SIZE(item)) &&
- (item_size == 3 || item_size == 4) &&
- (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
- (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
- (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
- /* TODO, number isn't ensured to be unique from the script author */
- (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1))
- {
- if (is_enum_flag) {
- if (item_size < 4) {
- tmp.value = 1 << i;
- }
-
- if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
- *defvalue |= tmp.value;
- def_used++;
- }
- }
- else {
- if (item_size < 4) {
- tmp.value = i;
- }
-
- if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
- *defvalue = tmp.value;
- def_used++; /* only ever 1 */
- }
- }
-
- items[i] = tmp;
-
- /* calculate combine string length */
- totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
- }
- else {
- MEM_freeN(items);
- PyErr_SetString(PyExc_TypeError,
- "EnumProperty(...): expected a tuple containing "
- "(identifier, name, description) and optionally a "
- "unique number");
- return NULL;
- }
-
- }
-
- if (is_enum_flag) {
- /* strict check that all set members were used */
- if (def && def_used != PySet_GET_SIZE(def)) {
- MEM_freeN(items);
-
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(..., default={...}): set has %d unused member(s)",
- PySet_GET_SIZE(def) - def_used);
- return NULL;
- }
- }
- else {
- if (def && def_used == 0) {
- MEM_freeN(items);
-
- PyErr_Format(PyExc_TypeError,
- "EnumProperty(..., default=\'%s\'): not found in enum members",
- def_cmp);
- return NULL;
- }
- }
-
- /* disabled duplicating strings because the array can still be freed and
- * the strings from it referenced, for now we can't support dynamically
- * created strings from python. */
-#if 0
- /* this would all work perfectly _but_ the python strings may be freed
- * immediately after use, so we need to duplicate them, ugh.
- * annoying because it works most of the time without this. */
- {
- EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
- "enum_items_from_py2");
- EnumPropertyItem *items_ptr = items_dup;
- char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
- memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
- for (i = 0; i < seq_len; i++, items_ptr++) {
- buf += strswapbufcpy(buf, &items_ptr->identifier);
- buf += strswapbufcpy(buf, &items_ptr->name);
- buf += strswapbufcpy(buf, &items_ptr->description);
- }
- MEM_freeN(items);
- items = items_dup;
- }
- /* end string duplication */
-#endif
-
- return items;
-}
-
-static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
-{
- PyGILState_STATE gilstate;
-
- PyObject *py_func = RNA_property_enum_py_data_get(prop);
- PyObject *self = NULL;
- PyObject *args;
- PyObject *items; /* returned from the function call */
-
- EnumPropertyItem *eitems = NULL;
- int err = 0;
-
- bpy_context_set(C, &gilstate);
-
- args = PyTuple_New(2);
- self = pyrna_struct_as_instance(ptr);
- PyTuple_SET_ITEM(args, 0, self);
-
- /* now get the context */
- PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
- Py_INCREF(bpy_context_module);
-
- items = PyObject_CallObject(py_func, args);
-
- Py_DECREF(args);
-
- if (items == NULL) {
- err = -1;
- }
- else {
- PyObject *items_fast;
- int defvalue_dummy = 0;
-
- if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
- "return value from the callback was not a sequence")))
- {
- err = -1;
- }
- else {
- eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
- (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
-
- Py_DECREF(items_fast);
-
- if (!eitems) {
- err = -1;
- }
- }
-
- Py_DECREF(items);
- }
-
- if (err != -1) { /* worked */
- *free = 1;
- }
- else {
- printf_func_error(py_func);
-
- eitems = DummyRNA_NULL_items;
- }
-
-
- bpy_context_clear(C, &gilstate);
- return eitems;
-}
-
PyDoc_STRVAR(BPy_EnumProperty_doc,
".. function:: EnumProperty(items, "
"name=\"\", "
"description=\"\", "
"default=\"\", "
"options={'ANIMATABLE'}, "
- "update=None)\n"
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
"\n"
" Returns a new enumerator property definition.\n"
"\n"
@@ -1233,6 +2507,8 @@ BPY_PROPDEF_DESC_DOC
" For dynamic values a callback can be passed which returns a list in\n"
" the same format as the static list.\n"
" This function must take 2 arguments (self, context)\n"
+" WARNING: Do not use generators here (they will work the first time, but will lead to empty values\n"
+" in some unload/reload scenarii)!\n"
" :type items: sequence of string triplets or a function\n"
BPY_PROPDEF_UPDATE_DOC
);
@@ -1244,7 +2520,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (srna) {
static const char *kwlist[] = {"attr", "items", "name", "description", "default",
- "options", "update", NULL};
+ "options", "update", "get", "set", NULL};
const char *id = NULL, *name = NULL, *description = "";
PyObject *def = NULL;
int id_len;
@@ -1254,22 +2530,30 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
- short is_itemf = FALSE;
+ bool is_itemf = false;
PyObject *update_cb = NULL;
+ PyObject *get_cb = NULL;
+ PyObject *set_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#O|ssOO!O:EnumProperty",
+ "s#O|ssOO!OOO:EnumProperty",
(char **)kwlist, &id, &id_len,
&items, &name, &description,
&def, &PySet_Type, &pyopts,
- &update_cb))
+ &update_cb, &get_cb, &set_cb))
{
return NULL;
}
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items);
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
+ return NULL;
+ }
+ if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
return NULL;
}
@@ -1290,7 +2574,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- is_itemf = TRUE;
+ is_itemf = true;
eitems = DummyRNA_NULL_items;
}
else {
@@ -1312,25 +2596,17 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description);
else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description);
- if (is_itemf) {
- RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
- RNA_def_enum_py_data(prop, (void *)items);
-
- /* watch out!, if a user is tricky they can probably crash blender
- * if they manage to free the callback, take care! */
- /* Py_INCREF(items); */
- }
-
if (pyopts) {
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL));
RNA_def_property_duplicate_pointers(srna, prop);
- if (is_itemf == FALSE) {
+ if (is_itemf == false) {
/* note: this must be postponed until after #RNA_def_property_duplicate_pointers
* otherwise if this is a generator it may free the strings before we copy them */
Py_DECREF(items_fast);
@@ -1422,7 +2698,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (!ptype)
return NULL;
- if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
}
@@ -1433,7 +2709,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
}
- bpy_prop_callback_assign(prop, update_cb);
+ bpy_prop_callback_assign_update(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a0df898..94f262f 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -37,6 +37,12 @@
#include "RNA_types.h"
+#include "BLI_dynstr.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+#include "BLI_math_rotation.h"
+#include "BLI_utildefines.h"
+
#include "BPY_extern.h"
#include "bpy_rna.h"
@@ -50,12 +56,6 @@
# include "MEM_guardedalloc.h"
#endif
-#include "BLI_dynstr.h"
-#include "BLI_string.h"
-#include "BLI_listbase.h"
-#include "BLI_math_rotation.h"
-#include "BLI_utildefines.h"
-
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
# include "BLI_ghash.h"
#endif
@@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id)
}
#ifdef USE_PEDANTIC_WRITE
-static short rna_disallow_writes = FALSE;
+static bool rna_disallow_writes = false;
-static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
+static bool rna_id_write_error(PointerRNA *ptr, PyObject *key)
{
ID *id = ptr->id.data;
if (id) {
@@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key)
"%.200s, %.200s datablock, error setting %.200s.%.200s",
id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
#endif /* USE_PEDANTIC_WRITE */
#ifdef USE_PEDANTIC_WRITE
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
return !rna_disallow_writes;
}
-void pyrna_write_set(int val)
+void pyrna_write_set(bool val)
{
rna_disallow_writes = !val;
}
#else /* USE_PEDANTIC_WRITE */
-int pyrna_write_check(void)
+bool pyrna_write_check(void)
{
- return TRUE;
+ return true;
}
-void pyrna_write_set(int UNUSED(val))
+void pyrna_write_set(bool UNUSED(val))
{
/* nothing */
}
@@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
- PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE);
+ PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret = mat_cb; /* return the matrix instead */
}
@@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
{
EnumPropertyItem *item;
const char *result;
- int free = FALSE;
+ int free = false;
RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free);
if (item) {
@@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
return -1;
}
- if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) {
+ if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
return -1;
}
@@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj
{
EnumPropertyItem *item;
int ret;
- int free = FALSE;
+ int free = false;
*r_value = 0;
@@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
}
else {
EnumPropertyItem *enum_item;
- int free = FALSE;
+ int free = false;
/* don't throw error here, can't trust blender 100% to give the
* right values, python code should not generate error for that */
@@ -1478,7 +1478,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
}
-static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
+static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func)
{
BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
pyfunc->ptr = *ptr;
@@ -1510,12 +1510,18 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* prefer not to have an exception here
* however so many poll functions return None or a valid Object.
* its a hassle to convert these into a bool before returning, */
- if (RNA_property_flag(prop) & PROP_OUTPUT)
+ if (RNA_property_flag(prop) & PROP_OUTPUT) {
param = PyObject_IsTrue(value);
- else
+ }
+ else {
param = PyLong_AsLong(value);
- if (param < 0) {
+ if (UNLIKELY(param & ~1)) { /* only accept 0/1 */
+ param = -1; /* error out below */
+ }
+ }
+
+ if (param == -1) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s expected True/False or 0/1, not %.200s",
error_prefix, RNA_struct_identifier(ptr->type),
@@ -1676,13 +1682,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
/* type checkins is done by each function */
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
/* set of enum items, concatenate all values with OR */
- if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) {
+ if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) {
return -1;
}
}
else {
/* simple enum string */
- if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) {
+ if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) {
return -1;
}
}
@@ -1771,7 +1777,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
}
else {
BPy_StructRNA *param = (BPy_StructRNA *)value;
- int raise_error = FALSE;
+ bool raise_error = false;
if (data) {
if (flag & PROP_RNAPTR) {
@@ -1798,7 +1804,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
*((void **)data) = param->ptr.data;
}
else {
- raise_error = TRUE;
+ raise_error = true;
}
}
else {
@@ -2189,7 +2195,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
else {
PyObject *keylib = PyTuple_GET_ITEM(key, 1);
Library *lib;
- int found = FALSE;
+ bool found = false;
if (keylib == Py_None) {
lib = NULL;
@@ -2226,7 +2232,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
{
ID *id = itemptr.data; /* always an ID */
if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
- found = TRUE;
+ found = true;
if (r_ptr) {
*r_ptr = itemptr;
}
@@ -2236,7 +2242,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_END;
/* we may want to fail silently as with collection.get() */
- if ((found == FALSE) && err_not_found) {
+ if ((found == false) && err_not_found) {
/* only runs for getitem access so use fixed string */
PyErr_SetString(PyExc_KeyError,
"bpy_prop_collection[key, lib]: not found");
@@ -2249,7 +2255,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
}
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key,
- const char *err_prefix, const short err_not_found)
+ const char *err_prefix, const bool err_not_found)
{
PointerRNA ptr;
const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr);
@@ -2442,7 +2448,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
else if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair(self, key,
- "bpy_prop_collection[id, lib]", TRUE);
+ "bpy_prop_collection[id, lib]", true);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2859,7 +2865,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
if (PyTuple_Check(key)) {
/* special case, for ID datablocks we */
return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key,
- "(id, lib) in bpy_prop_collection", FALSE, NULL);
+ "(id, lib) in bpy_prop_collection", false, NULL);
}
else {
@@ -4199,7 +4205,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
}
else if (PyTuple_Check(key_ob)) {
PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob,
- "bpy_prop_collection.get((id, lib))", FALSE);
+ "bpy_prop_collection.get((id, lib))", false);
if (ret) {
return ret;
}
@@ -4261,12 +4267,12 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
/* values to assign */
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed)
{
PropertyRNA *prop;
*raw_type = PROP_RAW_UNSET;
*attr_tot = 0;
- *attr_signed = FALSE;
+ *attr_signed = false;
/* note: this is fail with zero length lists, so don't let this get caled in that case */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
@@ -4274,7 +4280,7 @@ static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
prop = RNA_struct_find_property(&itemptr, attr);
*raw_type = RNA_property_raw_type(prop);
*attr_tot = RNA_property_array_length(&itemptr, prop);
- *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE;
+ *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? false : true;
break;
}
RNA_PROP_END;
@@ -4285,7 +4291,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
/* values to assign */
const char **attr, PyObject **seq, int *tot, int *size,
- RawPropertyType *raw_type, int *attr_tot, int *attr_signed
+ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed
)
{
#if 0
@@ -4293,7 +4299,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
int target_tot;
#endif
- *size = *attr_tot = *attr_signed = FALSE;
+ *size = *attr_tot = 0;
+ *attr_signed = false;
*raw_type = PROP_RAW_UNSET;
if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) {
@@ -4338,7 +4345,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args,
return 0;
}
-static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
+static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
{
char f = format ? *format : 'B'; /* B is assumed when not set */
@@ -4366,16 +4373,18 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons
static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
{
PyObject *item = NULL;
- int i = 0, ok = 0, buffer_is_compat;
+ int i = 0, ok = 0;
+ bool buffer_is_compat;
void *array = NULL;
/* get/set both take the same args currently */
const char *attr;
PyObject *seq;
- int tot, size, attr_tot, attr_signed;
+ int tot, size, attr_tot;
+ bool attr_signed;
RawPropertyType raw_type;
- if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0)
+ if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1)
return NULL;
if (tot == 0)
@@ -4384,7 +4393,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
if (set) { /* get the array from python */
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4435,7 +4444,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
}
}
else {
- buffer_is_compat = FALSE;
+ buffer_is_compat = false;
if (PyObject_CheckBuffer(seq)) {
Py_buffer buf;
PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT);
@@ -4618,8 +4627,14 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
/* experimental */
+ /* unused for now */
+#if 0
{"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
{"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
+
+ {"callback_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_CLASS, NULL},
+ {"callback_remove", (PyCFunction)pyrna_callback_classmethod_remove, METH_VARARGS | METH_CLASS, NULL},
+#endif
{NULL, NULL, 0, NULL}
};
@@ -4933,7 +4948,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
ParameterIterator iter;
PropertyRNA *parm;
PyObject *ret, *item;
- int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg;
+ int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0;
+ bool kw_arg;
PropertyRNA *pret_single = NULL;
void *retdata_single = NULL;
@@ -5014,7 +5030,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (i < pyargs_len) {
item = PyTuple_GET_ITEM(args, i);
- kw_arg = FALSE;
+ kw_arg = false;
}
else if (kw != NULL) {
#if 0
@@ -5025,7 +5041,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
if (item)
kw_tot++; /* make sure invalid keywords are not given */
- kw_arg = TRUE;
+ kw_arg = true;
}
i++; /* current argument */
@@ -5062,7 +5078,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
char error_prefix[512];
PyErr_Clear(); /* re-raise */
- if (kw_arg == TRUE)
+ if (kw_arg == true)
BLI_snprintf(error_prefix, sizeof(error_prefix),
"%.200s.%.200s(): error with keyword argument \"%.200s\" - ",
RNA_struct_identifier(self_ptr->type),
@@ -5097,12 +5113,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
DynStr *good_args = BLI_dynstr_new();
const char *arg_name, *bad_args_str, *good_args_str;
- int found = FALSE, first = TRUE;
+ bool found = false, first = true;
while (PyDict_Next(kw, &pos, &key, &value)) {
arg_name = _PyUnicode_AsString(key);
- found = FALSE;
+ found = false;
if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/
PyErr_Clear();
@@ -5113,22 +5129,22 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm = iter.parm;
if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
RNA_parameter_list_end(&iter);
- if (found == FALSE) {
+ if (found == false) {
BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name);
- first = FALSE;
+ first = false;
}
}
}
/* list good args */
- first = TRUE;
+ first = true;
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
@@ -5137,7 +5153,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
continue;
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
- first = FALSE;
+ first = false;
}
RNA_parameter_list_end(&iter);
@@ -5167,7 +5183,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
- err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE));
+ err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
/* return value */
if (err != -1) {
@@ -5230,7 +5246,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure)
PyObject *ret;
char *args;
- args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE);
+ args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true);
ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s",
RNA_struct_identifier(self->ptr.type),
@@ -5962,7 +5978,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self)
{
- if (self->iter.valid == FALSE) {
+ if (self->iter.valid == false) {
PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop");
return NULL;
}
@@ -6029,6 +6045,27 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item);
Py_DECREF(item);
+ /* add staticmethods and classmethods */
+ {
+ const PointerRNA func_ptr = {{NULL}, srna, NULL};
+ const ListBase *lb;
+ Link *link;
+
+ lb = RNA_struct_type_functions(srna);
+ for (link = lb->first; link; link = link->next) {
+ FunctionRNA *func = (FunctionRNA *)link;
+ const int flag = RNA_function_flag(func);
+ if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */
+ (flag & FUNC_REGISTER) == false) /* is not for registration */
+ {
+ /* we may want to set the type of this later */
+ PyObject *func_py = pyrna_func_to_py(&func_ptr, func);
+ PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py);
+ Py_DECREF(func_py);
+ }
+ }
+ }
+
/* done with rna instance */
}
@@ -6229,7 +6266,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
pyrna->ptr = *ptr;
#ifdef PYRNA_FREE_SUPPORT
- pyrna->freeptr = FALSE;
+ pyrna->freeptr = false;
#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
@@ -6309,15 +6346,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
}
}
-int pyrna_id_FromPyObject(PyObject *obj, ID **id)
+bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
{
if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) {
*id = ((BPy_StructRNA *)obj)->ptr.id.data;
- return TRUE;
+ return true;
}
else {
*id = NULL;
- return FALSE;
+ return false;
}
}
@@ -6528,7 +6565,7 @@ PyObject *BPY_rna_types(void)
return (PyObject *)self;
}
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix)
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
{
BPy_StructRNA *py_srna = NULL;
StructRNA *srna;
@@ -6602,7 +6639,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
PyErr_Fetch(&error_type, &error_value, &error_traceback);
PyErr_Clear();
- srna = pyrna_struct_as_srna(self, 0, error_prefix);
+ srna = pyrna_struct_as_srna(self, false, error_prefix);
if (!PyErr_Occurred()) {
PyErr_Restore(error_type, error_value, error_traceback);
@@ -6759,7 +6796,9 @@ static int rna_function_arg_count(FunctionRNA *func)
const ListBase *lb = RNA_function_defined_parameters(func);
PropertyRNA *parm;
Link *link;
- int count = (RNA_function_flag(func) & FUNC_NO_SELF) ? 0 : 1;
+ int flag = RNA_function_flag(func);
+ int is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ int count = is_staticmethod ? 0 : 1;
for (link = lb->first; link; link = link->next) {
parm = (PropertyRNA *)link;
@@ -6781,7 +6820,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
PyObject *py_class = (PyObject *)py_data;
PyObject *base_class = RNA_struct_py_type_get(srna);
PyObject *item;
- int i, flag, arg_count, func_arg_count;
+ int i, flag, is_staticmethod, arg_count, func_arg_count;
const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */
if (srna_base) {
@@ -6804,6 +6843,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
for (link = lb->first; link; link = link->next) {
func = (FunctionRNA *)link;
flag = RNA_function_flag(func);
+ is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
if (!(flag & FUNC_REGISTER))
continue;
@@ -6826,7 +6866,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
}
else {
Py_DECREF(item); /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */
- if (flag & FUNC_NO_SELF) {
+ if (is_staticmethod) {
if (PyMethod_Check(item) == 0) {
PyErr_Format(PyExc_TypeError,
"expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s",
@@ -6850,9 +6890,9 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
/* note, the number of args we check for and the number of args we give to
- * @classmethods are different (quirk of python),
+ * @staticmethods are different (quirk of python),
* this is why rna_function_arg_count() doesn't return the value -1*/
- if (flag & FUNC_NO_SELF)
+ if (is_staticmethod)
func_arg_count++;
if (arg_count != func_arg_count) {
@@ -6937,8 +6977,10 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
PropertyRNA *parm;
ParameterIterator iter;
PointerRNA funcptr;
- int err = 0, i, flag, ret_len = 0;
- const char is_static = (RNA_function_flag(func) & FUNC_NO_SELF) != 0;
+ int err = 0, i, ret_len = 0;
+ int flag = RNA_function_flag(func);
+ const char is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ const char is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE);
/* annoying!, need to check if the screen gets set to NULL which is a
* hint that the file was actually re-loaded. */
@@ -6973,7 +7015,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
bpy_context_set(C, &gilstate);
- if (!is_static) {
+ if (!(is_staticmethod || is_classmethod)) {
/* some datatypes (operator, render engine) can store PyObjects for re-use */
if (ptr->data) {
void **instance = RNA_struct_instance(ptr);
@@ -7013,7 +7055,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (py_class->tp_init) {
#ifdef USE_PEDANTIC_WRITE
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */
+ rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */
#endif
/* true in most cases even when the class its self doesn't define an __init__ function. */
@@ -7032,7 +7074,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
#else
const int prev_write = rna_disallow_writes;
- rna_disallow_writes = TRUE;
+ rna_disallow_writes = true;
/* 'almost' all the time calling the class isn't needed.
* We could just do... */
@@ -7064,18 +7106,21 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
}
- if (err != -1 && (is_static || py_class_instance)) { /* Initializing the class worked, now run its invoke function */
+ if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { /* Initializing the class worked, now run its invoke function */
PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func));
-// flag = RNA_function_flag(func);
if (item) {
RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */
- if (is_static) {
+ if (is_staticmethod) {
i = 0;
}
+ else if (is_classmethod) {
+ PyTuple_SET_ITEM(args, 0, (PyObject *)py_class);
+ i = 1;
+ }
else {
PyTuple_SET_ITEM(args, 0, py_class_instance);
i = 1;
@@ -7105,7 +7150,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
}
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = is_readonly ? TRUE : FALSE;
+ rna_disallow_writes = is_readonly ? true : false;
#endif
/* *** Main Caller *** */
@@ -7114,7 +7159,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* *** Done Calling *** */
#ifdef USE_PEDANTIC_WRITE
- rna_disallow_writes = FALSE;
+ rna_disallow_writes = false;
#endif
RNA_parameter_list_end(&iter);
@@ -7209,7 +7254,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
if (err != 0) {
ReportList *reports;
/* alert the user, else they wont know unless they see the console. */
- if ((!is_static) &&
+ if ((!is_staticmethod) && (!is_classmethod) &&
(ptr->data) &&
(RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
(is_valid_wm == (CTX_wm_manager(C) != NULL)))
@@ -7332,8 +7377,9 @@ PyDoc_STRVAR(pyrna_register_class_doc,
".. method:: register_class(cls)\n"
"\n"
" Register a subclass of a blender type in (:class:`bpy.types.Panel`,\n"
-" :class:`bpy.types.Menu`, :class:`bpy.types.Header`, :class:`bpy.types.Operator`,\n"
-" :class:`bpy.types.KeyingSetInfo`, :class:`bpy.types.RenderEngine`).\n"
+" :class:`bpy.types.UIList`, :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
+" :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
+" :class:`bpy.types.RenderEngine`).\n"
"\n"
" If the class has a *register* class method it will be called\n"
" before registration.\n"
@@ -7378,7 +7424,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
}
/* warning: gets parent classes srna, only for the register function */
- srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):");
+ srna = pyrna_struct_as_srna(py_class, true, "register_class(...):");
if (srna == NULL)
return NULL;
@@ -7414,7 +7460,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna_new = reg(CTX_data_main(C), &reports, py_class, identifier,
bpy_class_validate, bpy_class_call, bpy_class_free);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
/* python errors validating are not converted into reports so the check above will fail.
@@ -7521,7 +7567,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
return NULL;
}
- srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):");
+ srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):");
if (srna == NULL)
return NULL;
@@ -7592,3 +7638,39 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
Py_RETURN_NONE;
}
+
+/* currently this is fairly limited, we would need to make some way to split up
+ * pyrna_callback_classmethod_... if we want more then one callback per type */
+typedef struct BPyRNA_CallBack {
+ PyMethodDef py_method;
+ StructRNA *bpy_srna;
+} PyRNA_CallBack;
+
+static struct BPyRNA_CallBack pyrna_cb_methods[] = {
+ {{"draw_handler_add", (PyCFunction)pyrna_callback_classmethod_add, METH_VARARGS | METH_STATIC, ""}, &RNA_Space},
+ {{"draw_handler_remove", (PyCFunction)pyrna_callback_classmethod_remove, METH_VARARGS | METH_STATIC, ""}, &RNA_Space},
+ {{NULL, NULL, 0, NULL}, NULL}
+};
+
+void BPY_rna_register_cb(void)
+{
+ int i;
+
+ for (i = 0; pyrna_cb_methods[i].bpy_srna; i++) {
+ PyObject *cls;
+ PyObject *func;
+ PyObject *classmethod;
+ PyObject *args = PyTuple_New(1);
+
+ cls = pyrna_srna_Subtype(pyrna_cb_methods[i].bpy_srna);
+ func = PyCFunction_New(&pyrna_cb_methods[i].py_method, NULL);
+ PyTuple_SET_ITEM(args, 0, func);
+ classmethod = PyObject_CallObject((PyObject *)&PyClassMethod_Type, args);
+
+ PyObject_SetAttrString(cls, pyrna_cb_methods[i].py_method.ml_name, classmethod);
+
+ Py_DECREF(classmethod);
+ Py_DECREF(args); /* clears 'func' too */
+ Py_DECREF(cls);
+ }
+}
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 880ef4c..424452e 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -115,7 +115,7 @@ typedef struct {
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
#ifdef PYRNA_FREE_SUPPORT
- int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
+ bool freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
#endif /* PYRNA_FREE_SUPPORT */
} BPy_StructRNA;
@@ -164,20 +164,21 @@ typedef struct {
#define BPy_BaseTypeRNA BPy_PropertyRNA
StructRNA *srna_from_self(PyObject *self, const char *error_prefix);
-StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix);
+StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix);
void BPY_rna_init(void);
PyObject *BPY_rna_module(void);
void BPY_update_rna_module(void);
/*PyObject *BPY_rna_doc(void);*/
PyObject *BPY_rna_types(void);
+void BPY_rna_register_cb(void);
PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr);
PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop);
/* extern'd by other modules which don't deal closely with RNA */
PyObject *pyrna_id_CreatePyObject(struct ID *id);
-int pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
+bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
/* operators also need this to set args */
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix);
@@ -204,8 +205,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value);
-int pyrna_write_check(void);
-void pyrna_write_set(int val);
+bool pyrna_write_check(void);
+void pyrna_write_set(bool val);
void pyrna_invalidate(BPy_DummyPointerRNA *self);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 6983951..a19f8e2 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -44,6 +44,7 @@
#include "BKE_fcurve.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -147,21 +148,28 @@ static int pyrna_struct_anim_args_parse(
/* internal use for insert and delete */
static int pyrna_struct_keyframe_parse(
PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
- const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
+ const char **path_full, int *index, float *cfra, const char **group_name, int *options) /* return values */
{
- static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
+ static const char *kwlist[] = {"data_path", "index", "frame", "group", "options", NULL};
+ PyObject *pyoptions = NULL;
const char *path;
- /* note, parse_str MUST start with 's|ifs' */
- if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
+ /* note, parse_str MUST start with 's|ifsO!' */
+ if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name,
+ &PySet_Type, &pyoptions)) {
return -1;
+ }
- if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
+ if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1)
return -1;
if (*cfra == FLT_MAX)
*cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
+ /* flag may be null (no option currently for remove keyframes e.g.). */
+ if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1))
+ return -1;
+
return 0; /* success */
}
@@ -172,12 +180,19 @@ char pyrna_struct_keyframe_insert_doc[] =
"\n"
" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
" :type data_path: string\n"
-" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel if the property is not an array.\n"
+" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel "
+ "if the property is not an array.\n"
" :type index: int\n"
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
" :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
+" :arg options: Some optional flags:\n"
+" 'NEEDED': Only insert keyframes where they're needed in the relevant F-Curves.\n"
+" 'VISUAL': Insert keyframes based on 'visual transforms'.\n"
+" 'XYZ_TO_RGB': Color for newly added transformation F-Curves (Location, Rotation, Scale) "
+ "and also Color is based on the transform axis.\n"
+" :type flag: set\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean\n"
;
@@ -188,12 +203,13 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
int index = -1;
float cfra = FLT_MAX;
const char *group_name = NULL;
+ int options = 0;
PYRNA_STRUCT_CHECK_OBJ(self);
if (pyrna_struct_keyframe_parse(&self->ptr, args, kw,
- "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
- &path_full, &index, &cfra, &group_name) == -1)
+ "s|ifsO!:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
+ &path_full, &index, &cfra, &group_name, &options) == -1)
{
return NULL;
}
@@ -203,10 +219,10 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
BKE_reports_init(&reports, RPT_STORE);
- result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
+ result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options);
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -240,9 +256,9 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
PYRNA_STRUCT_CHECK_OBJ(self);
if (pyrna_struct_keyframe_parse(&self->ptr, args, kw,
- "s|ifs:bpy_struct.keyframe_delete()",
+ "s|ifsO!:bpy_struct.keyframe_delete()",
"bpy_struct.keyframe_insert()",
- &path_full, &index, &cfra, &group_name) == -1)
+ &path_full, &index, &cfra, &group_name, NULL) == -1)
{
return NULL;
}
@@ -255,7 +271,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -285,7 +301,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
+ if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
return NULL;
}
else {
@@ -297,7 +313,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
if (result) {
@@ -361,7 +377,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
return NULL;
- if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
+ if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
return NULL;
}
else {
@@ -374,7 +390,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index f711411..1043f68 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -32,23 +32,34 @@
#include "RNA_types.h"
+#include "BLI_utildefines.h"
+
#include "bpy_rna.h"
#include "bpy_rna_callback.h"
#include "bpy_util.h"
-#include "BLI_utildefines.h"
-
+#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
#include "BKE_context.h"
+#include "BKE_screen.h"
+
#include "ED_space_api.h"
/* use this to stop other capsules from being mis-used */
#define RNA_CAPSULE_ID "RNA_HANDLE"
#define RNA_CAPSULE_ID_INVALID "RNA_HANDLE_REMOVED"
+static EnumPropertyItem region_draw_mode_items[] = {
+ {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
+ {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
+ {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customdata)
{
PyObject *cb_func, *cb_args, *result;
@@ -56,8 +67,8 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customd
bpy_context_set((bContext *)C, &gilstate);
- cb_func = PyTuple_GET_ITEM((PyObject *)customdata, 0);
- cb_args = PyTuple_GET_ITEM((PyObject *)customdata, 1);
+ cb_func = PyTuple_GET_ITEM((PyObject *)customdata, 1);
+ cb_args = PyTuple_GET_ITEM((PyObject *)customdata, 2);
result = PyObject_CallObject(cb_func, cb_args);
if (result) {
@@ -71,6 +82,7 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(ar), void *customd
bpy_context_clear((bContext *)C, &gilstate);
}
+#if 0
PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
{
void *handle;
@@ -89,13 +101,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
if (cb_event_str) {
- static EnumPropertyItem region_draw_mode_items[] = {
- {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
- {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Post View", ""},
- {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
- {0, NULL, 0, NULL, NULL}};
-
- if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) {
+ if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) {
return NULL;
}
}
@@ -136,6 +142,163 @@ PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
}
+ else {
+ PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks");
+ return NULL;
+ }
+
+ /* don't allow reuse */
+ PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
+
+ Py_RETURN_NONE;
+}
+#endif
+
+/* reverse of rna_Space_refine() */
+static eSpace_Type rna_Space_refine_reverse(StructRNA *srna)
+{
+ if (srna == &RNA_SpaceView3D) return SPACE_VIEW3D;
+ if (srna == &RNA_SpaceGraphEditor) return SPACE_IPO;
+ if (srna == &RNA_SpaceOutliner) return SPACE_OUTLINER;
+ if (srna == &RNA_SpaceProperties) return SPACE_BUTS;
+ if (srna == &RNA_SpaceFileBrowser) return SPACE_FILE;
+ if (srna == &RNA_SpaceImageEditor) return SPACE_IMAGE;
+ if (srna == &RNA_SpaceInfo) return SPACE_INFO;
+ if (srna == &RNA_SpaceSequenceEditor) return SPACE_SEQ;
+ if (srna == &RNA_SpaceTextEditor) return SPACE_TEXT;
+ if (srna == &RNA_SpaceDopeSheetEditor) return SPACE_ACTION;
+ if (srna == &RNA_SpaceNLA) return SPACE_NLA;
+ if (srna == &RNA_SpaceTimeline) return SPACE_TIME;
+ if (srna == &RNA_SpaceNodeEditor) return SPACE_NODE;
+ if (srna == &RNA_SpaceLogicEditor) return SPACE_LOGIC;
+ if (srna == &RNA_SpaceConsole) return SPACE_CONSOLE;
+ if (srna == &RNA_SpaceUserPreferences) return SPACE_USERPREF;
+ if (srna == &RNA_SpaceClipEditor) return SPACE_CLIP;
+ return -1;
+}
+
+PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
+{
+ void *handle;
+ PyObject *cls;
+ PyObject *cb_func, *cb_args;
+ char *cb_regiontype_str;
+ char *cb_event_str;
+ int cb_event;
+ int cb_regiontype;
+ StructRNA *srna;
+
+ if (PyTuple_GET_SIZE(args) < 2) {
+ PyErr_SetString(PyExc_ValueError, "handler_add(handle): expected at least 2 args");
+ return NULL;
+ }
+
+ cls = PyTuple_GET_ITEM(args, 0);
+ if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) {
+ return NULL;
+ }
+ cb_func = PyTuple_GET_ITEM(args, 1);
+ if (!PyCallable_Check(cb_func)) {
+ PyErr_SetString(PyExc_TypeError, "first argument isn't callable");
+ return NULL;
+ }
+
+ /* class spesific callbacks */
+ if (RNA_struct_is_a(srna, &RNA_Space)) {
+ if (!PyArg_ParseTuple(args, "OOO!ss:Space.draw_handler_add",
+ &cls, &cb_func, /* already assigned, no matter */
+ &PyTuple_Type, &cb_args, &cb_regiontype_str, &cb_event_str))
+ {
+ return NULL;
+ }
+
+ if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) {
+ return NULL;
+ }
+ else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) {
+ return NULL;
+ }
+ else {
+ const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
+ if (spaceid == -1) {
+ PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
+ return NULL;
+ }
+ else {
+ SpaceType *st = BKE_spacetype_from_id(spaceid);
+ ARegionType *art = BKE_regiontype_from_id(st, cb_regiontype);
+
+ handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, cb_event);
+ Py_INCREF(args);
+ }
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "callback_add(): type does not support callbacks");
+ return NULL;
+ }
+
+ return PyCapsule_New((void *)handle, RNA_CAPSULE_ID, NULL);
+}
+
+PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *args)
+{
+ PyObject *cls;
+ PyObject *py_handle;
+ void *handle;
+ void *customdata;
+ StructRNA *srna;
+ char *cb_regiontype_str;
+ int cb_regiontype;
+
+ if (PyTuple_GET_SIZE(args) < 2) {
+ PyErr_SetString(PyExc_ValueError, "callback_remove(handle): expected at least 2 args");
+ return NULL;
+ }
+
+ cls = PyTuple_GET_ITEM(args, 0);
+ if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) {
+ return NULL;
+ }
+ py_handle = PyTuple_GET_ITEM(args, 1);
+ handle = PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
+ if (handle == NULL) {
+ PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed");
+ return NULL;
+ }
+
+ if (RNA_struct_is_a(srna, &RNA_Space)) {
+ if (!PyArg_ParseTuple(args, "OO!s:Space.draw_handler_remove",
+ &cls, &PyCapsule_Type, &py_handle, /* already assigned, no matter */
+ &cb_regiontype_str))
+ {
+ return NULL;
+ }
+
+ customdata = ED_region_draw_cb_customdata(handle);
+ Py_DECREF((PyObject *)customdata);
+
+ if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) {
+ return NULL;
+ }
+ else {
+ const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
+ if (spaceid == -1) {
+ PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
+ return NULL;
+ }
+ else {
+ SpaceType *st = BKE_spacetype_from_id(spaceid);
+ ARegionType *art = BKE_regiontype_from_id(st, cb_regiontype);
+
+ ED_region_draw_cb_exit(art, handle);
+ }
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks");
+ return NULL;
+ }
/* don't allow reuse */
PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
diff --git a/source/blender/python/intern/bpy_rna_callback.h b/source/blender/python/intern/bpy_rna_callback.h
index 7824d2b..4b801f3 100644
--- a/source/blender/python/intern/bpy_rna_callback.h
+++ b/source/blender/python/intern/bpy_rna_callback.h
@@ -28,5 +28,10 @@
struct BPy_StructRNA;
struct PyObject;
+#if 0
PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args);
PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args);
+#endif
+
+PyObject *pyrna_callback_classmethod_add(PyObject *cls, PyObject *args);
+PyObject *pyrna_callback_classmethod_remove(PyObject *cls, PyObject *args);
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index b7994ee..b0b0f34 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -29,9 +29,13 @@
#include <Python.h>
-#include "bpy_util.h"
+#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
+
+#include "bpy_util.h"
+
#include "MEM_guardedalloc.h"
+
#include "BKE_report.h"
#include "BKE_context.h"
@@ -59,13 +63,13 @@ char *BPy_enum_as_string(EnumPropertyItem *item)
return cstring;
}
-short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear)
+short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
{
char *report_str;
report_str = BKE_reports_string(reports, RPT_ERROR);
- if (clear) {
+ if (clear == true) {
BKE_reports_clear(reports);
}
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index b5f679b..b007e12 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -39,7 +39,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
/* error reporting */
-short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear);
+short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
short BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 05306f2..da28880 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -1025,13 +1025,13 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
int col;
if (self->wrapped == Py_WRAP) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.resize_4x4(): "
"cannot resize wrapped data - make a copy and resize that");
return NULL;
}
if (self->cb_user) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.resize_4x4(): "
"cannot resize owned data - make a copy and resize that");
return NULL;
@@ -1080,7 +1080,7 @@ static PyObject *Matrix_to_4x4(MatrixObject *self)
}
/* TODO, 2x2 matrix */
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_4x4(): "
"inappropriate matrix size");
return NULL;
@@ -1102,7 +1102,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self)
return NULL;
if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_3x3(): inappropriate matrix size");
return NULL;
}
@@ -1126,7 +1126,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
return NULL;
if ((self->num_row < 3) || self->num_col < 4) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_translation(): "
"inappropriate matrix size");
return NULL;
@@ -1156,7 +1156,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
/*must be 3-4 cols, 3-4 rows, square matrix */
if ((self->num_row < 3) || (self->num_col < 3)) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.to_scale(): "
"inappropriate matrix size, 3x3 minimum size");
return NULL;
@@ -1194,7 +1194,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.invert(ed): "
"only square matrices are supported");
return NULL;
@@ -1222,7 +1222,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
break;
}
default:
- PyErr_Format(PyExc_TypeError,
+ PyErr_Format(PyExc_ValueError,
"Matrix invert(ed): size (%d) unsupported",
(int)self->num_col);
return NULL;
@@ -1281,7 +1281,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.adjugate(d): "
"only square matrices are supported");
return NULL;
@@ -1311,7 +1311,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self)
break;
}
default:
- PyErr_Format(PyExc_TypeError,
+ PyErr_Format(PyExc_ValueError,
"Matrix adjugate(d): size (%d) unsupported",
(int)self->num_col);
return NULL;
@@ -1357,7 +1357,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
return NULL;
if (self->num_row != 3 || self->num_col != 3) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.rotate(): "
"must have 3x3 dimensions");
return NULL;
@@ -1390,7 +1390,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
float size[3];
if (self->num_row != 4 || self->num_col != 4) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.decompose(): "
"inappropriate matrix size - expects 4x4 matrix");
return NULL;
@@ -1476,7 +1476,7 @@ static PyObject *Matrix_determinant(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.determinant(): "
"only square matrices are supported");
return NULL;
@@ -1498,7 +1498,7 @@ static PyObject *Matrix_transpose(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.transpose(d): "
"only square matrices are supported");
return NULL;
@@ -1533,6 +1533,53 @@ static PyObject *Matrix_transposed(MatrixObject *self)
return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self);
}
+/*---------------------------matrix.normalize() ------------------*/
+PyDoc_STRVAR(Matrix_normalize_doc,
+".. method:: normalize()\n"
+"\n"
+" Normalize each of the matrix columns.\n"
+);
+static PyObject *Matrix_normalize(MatrixObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ if (self->num_col != self->num_row) {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.normalize(): "
+ "only square matrices are supported");
+ return NULL;
+ }
+
+ if (self->num_col == 3) {
+ normalize_m3((float (*)[3])self->matrix);
+ }
+ else if (self->num_col == 4) {
+ normalize_m4((float (*)[4])self->matrix);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "Matrix.normalize(): "
+ "can only use a 3x3 or 4x4 matrix");
+ }
+
+ (void)BaseMath_WriteCallback(self);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(Matrix_normalized_doc,
+".. method:: normalized()\n"
+"\n"
+" Return a column normalized matrix\n"
+"\n"
+" :return: a column normalized matrix\n"
+" :rtype: :class:`Matrix`\n"
+);
+static PyObject *Matrix_normalized(MatrixObject *self)
+{
+ return matrix__apply_to_copy((PyNoArgsFunction)Matrix_normalize, self);
+}
+
/*---------------------------matrix.zero() -----------------------*/
PyDoc_STRVAR(Matrix_zero_doc,
".. method:: zero()\n"
@@ -1568,7 +1615,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
return NULL;
if (self->num_col != self->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix.identity(): "
"only square matrices are supported");
return NULL;
@@ -1924,7 +1971,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
return NULL;
if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
@@ -1956,7 +2003,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
return NULL;
if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_ValueError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
@@ -2371,6 +2418,8 @@ static struct PyMethodDef Matrix_methods[] = {
/* operate on original or copy */
{"transpose", (PyCFunction) Matrix_transpose, METH_NOARGS, Matrix_transpose_doc},
{"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc},
+ {"normalize", (PyCFunction) Matrix_normalize, METH_NOARGS, Matrix_normalize_doc},
+ {"normalized", (PyCFunction) Matrix_normalized, METH_NOARGS, Matrix_normalized_doc},
{"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc},
{"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc},
{"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc},
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 1db0538..3d05f51 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -1102,7 +1102,7 @@ static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject
return NULL;
}
- dims = MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
+ dims = max_iiii(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
for (i = 0; i < vec_k1->size; i++) k1[i] = vec_k1->vec[i];
for (i = 0; i < vec_h1->size; i++) h1[i] = vec_h1->vec[i];
diff --git a/source/blender/quicktime/SConscript b/source/blender/quicktime/SConscript
index db1d4a4..a32f325 100644
--- a/source/blender/quicktime/SConscript
+++ b/source/blender/quicktime/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index e0858cd..4a8a061 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -61,8 +61,8 @@
#import <QTKit/QTKit.h>
#include <AudioToolbox/AudioToolbox.h>
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) || !__LP64__
-#error 64 bit build & OSX 10.5 minimum are needed for QTKit
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040
+#error OSX 10.5 minimum is needed for QTKit
#endif
#include "quicktime_import.h"
@@ -557,7 +557,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
[qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute];
[qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute];
- qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000);
+ qtexport->frameDuration = QTMakeTime(rd->frs_sec_base * 1000, rd->frs_sec * 1000);
/* specifying the codec attributes : try to retrieve them from render data first*/
if (rd->qtcodecsettings.codecType) {
diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h
index a3469dd..55323c0 100644
--- a/source/blender/quicktime/quicktime_export.h
+++ b/source/blender/quicktime/quicktime_export.h
@@ -65,14 +65,14 @@ void filepath_qt(char *string, struct RenderData *rd);
void quicktime_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); //used by RNA for defaults values init, if needed
/*Video codec type*/
int quicktime_get_num_videocodecs(void);
-QuicktimeCodecTypeDesc* quicktime_get_videocodecType_desc(int indexValue);
+QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue);
int quicktime_rnatmpvalue_from_videocodectype(int codecType);
int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue);
#ifdef USE_QTKIT
/*Audio codec type*/
int quicktime_get_num_audiocodecs(void);
-QuicktimeCodecTypeDesc* quicktime_get_audiocodecType_desc(int indexValue);
+QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue);
int quicktime_rnatmpvalue_from_audiocodectype(int codecType);
int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue);
#endif
@@ -87,7 +87,7 @@ void makeqtstring(struct RenderData *rd, char *string); //for playanim.c
-#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 && __LP64__)
+#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__)
//Include the quicktime codec types constants that are missing in QTKitDefines.h
enum {
kRawCodecType = 'raw ',
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index a2d6e27..7deecb9 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -60,6 +60,7 @@ set(SRC
intern/source/gammaCorrectionTables.c
intern/source/imagetexture.c
intern/source/initrender.c
+ intern/source/multires_bake.c
intern/source/occlusion.c
intern/source/pipeline.c
intern/source/pixelblending.c
@@ -83,6 +84,7 @@ set(SRC
intern/source/zbuf.c
extern/include/RE_engine.h
+ extern/include/RE_multires_bake.h
extern/include/RE_pipeline.h
extern/include/RE_render_ext.h
extern/include/RE_shader_ext.h
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index 8a044b1..992dd8c 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('intern/source/*.c')
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index d2ffc3a..64135a1 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -61,6 +61,7 @@ struct Scene;
#define RE_ENGINE_DO_DRAW 4
#define RE_ENGINE_DO_UPDATE 8
#define RE_ENGINE_RENDERING 16
+#define RE_ENGINE_HIGHLIGHT_TILES 32
extern ListBase R_engines;
@@ -130,5 +131,7 @@ void RE_engines_exit(void);
RenderEngineType *RE_engines_find(const char *idname);
+void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
+
#endif /* __RE_ENGINE_H__ */
diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h
new file mode 100644
index 0000000..04cfe55
--- /dev/null
+++ b/source/blender/render/extern/include/RE_multires_bake.h
@@ -0,0 +1,62 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2010 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Morten Mikkelsen,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file RE_multires_bake.h
+ * \ingroup render
+ */
+
+#ifndef __RE_MULTIRES_BAKE_H__
+#define __RE_MULTIRES_BAKE_H__
+
+struct MultiresBakeRender;
+
+typedef struct MultiresBakeRender {
+ DerivedMesh *lores_dm, *hires_dm;
+ int simple, lvl, tot_lvl, bake_filter;
+ short mode, use_lores_mesh;
+
+ int number_of_rays;
+ float bias;
+
+ int tot_obj, tot_image;
+ ListBase image;
+
+ int baked_objects, baked_faces;
+
+ int raytrace_structure;
+ int octree_resolution;
+ int threads;
+
+ short *stop;
+ short *do_update;
+ float *progress;
+} MultiresBakeRender;
+
+void RE_multires_bake_images(struct MultiresBakeRender *bkr);
+
+#endif
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index ecdd177..f97e5ac 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -198,7 +198,7 @@ void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipe
void RE_SetPixelSize(struct Render *re, float pixsize);
/* option to set viewmatrix before making dbase */
-void RE_SetView (struct Render *re, float mat[][4]);
+void RE_SetView (struct Render *re, float mat[4][4]);
/* make or free the dbase */
void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view);
@@ -273,8 +273,8 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd);
void RE_Database_Baking(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, const int type, struct Object *actob);
-void RE_DataBase_GetView(struct Render *re, float mat[][4]);
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]);
+void RE_DataBase_GetView(struct Render *re, float mat[4][4]);
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]);
struct Scene *RE_GetScene(struct Render *re);
int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports);
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
index bb2e7e7..19759bf 100644
--- a/source/blender/render/intern/include/pixelblending.h
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -38,8 +38,8 @@
*/
void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w);
void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
-void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y);
-void mask_array(unsigned int mask, float filt[][3]);
+void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y);
+void mask_array(unsigned int mask, float filt[3][3]);
/**
* Alpha-over blending for floats.
diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h
index 07fc7d7..e9514b8 100644
--- a/source/blender/render/intern/include/rayobject.h
+++ b/source/blender/render/intern/include/rayobject.h
@@ -56,7 +56,7 @@ int RE_rayobject_raycast(RayObject *r, struct Isect *i);
/* Acceleration Structures */
RayObject *RE_rayobject_octree_create(int ocres, int size);
-RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob);
+RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob);
RayObject *RE_rayobject_empty_create(void);
RayObject *RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */
@@ -87,6 +87,8 @@ typedef struct RayFace {
RayObject *RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr);
+RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4);
+
/* RayObject representing faces directly from a given VlakRen structure. Thus
* allowing to save memory, but making code triangle intersection dependent on
* render structures. */
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 5d61417..61b39a5 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -91,7 +91,7 @@ void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd
struct ImBuf *ibuf);
void render_result_rect_fill_zero(struct RenderResult *rr);
-void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd,
+void render_result_rect_get_pixels(struct RenderResult *rr,
unsigned int *rect, int rectx, int recty,
const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 7422416..905b4b4 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -104,13 +104,19 @@ typedef struct RenderPart {
rcti disprect; /* part coordinates within total picture */
int rectx, recty; /* the size */
- short crop, ready; /* crop is amount of pixels we crop, for filter */
+ short crop, status; /* crop is amount of pixels we crop, for filter */
short sample, nr; /* sample can be used by zbuffers, nr is partnr */
short thread; /* thread id */
char *clipflag; /* clipflags for part zbuffering */
} RenderPart;
+enum {
+ PART_STATUS_NONE = 0,
+ PART_STATUS_IN_PROGRESS = 1,
+ PART_STATUS_READY = 2
+};
+
/* controls state of render, everything that's read-only during render stage */
struct Render
{
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 3071225..88b639c 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -83,6 +83,8 @@ int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct Rend
/* -------- ray.c ------- */
+struct RayObject *RE_rayobject_create(int type, int size, int octree_resolution);
+
extern void freeraytree(Render *re);
extern void makeraytree(Render *re);
struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi);
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index 5213f14..1e81ca2 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -59,12 +59,16 @@ typedef struct VertTableNode {
float *tangent;
float *stress;
float *winspeed;
+ /* Index of vertex in source mesh (before modifiers). */
+ int *origindex;
} VertTableNode;
typedef struct VlakTableNode {
struct VlakRen *vlak;
struct MTFace *mtface;
struct MCol *mcol;
+ /* Index of mpoly in source mesh (before tessellation). */
+ int *origindex;
int totmtface, totmcol;
float *surfnor;
float *tangent;
@@ -87,8 +91,8 @@ void free_renderdata_tables(struct Render *re);
void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
-void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets);
-int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]);
+void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), int do_pano, float xoffs, int do_buckets);
+int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]);
/* functions are not exported... so wrong names */
@@ -106,7 +110,7 @@ struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, s
struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay);
-struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4], int lay);
+struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay);
void RE_makeRenderInstances(struct Render *re);
float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify);
@@ -114,9 +118,11 @@ float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify
float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify);
float *RE_vertren_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify);
float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify);
+int *RE_vertren_get_origindex(struct ObjectRen *obr, VertRen *ver, int verify);
struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
+int *RE_vlakren_get_origindex(struct ObjectRen *obr, VlakRen *vlak, int verify);
float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
float *RE_vlakren_get_nmap_tangent(struct ObjectRen *obr, VlakRen *ren, int verify);
RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify);
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
index 7203542..d959486 100644
--- a/source/blender/render/intern/include/strand.h
+++ b/source/blender/render/intern/include/strand.h
@@ -92,10 +92,10 @@ struct StrandShadeCache;
typedef struct StrandShadeCache StrandShadeCache;
void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
-void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
+void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width);
-struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
+struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset);
void free_strand_surface(struct Render *re);
struct StrandShadeCache *strand_shade_cache_create(void);
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index e873111..162fa3b 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -49,17 +49,17 @@ void fillrect(int *rect, int x, int y, int val);
* Converts a world coordinate into a homogeneous coordinate in view
* coordinates.
*/
-void projectvert(const float v1[3], float winmat[][4], float adr[4]);
-void projectverto(const float v1[3], float winmat[][4], float adr[4]);
+void projectvert(const float v1[3], float winmat[4][4], float adr[4]);
+void projectverto(const float v1[3], float winmat[4][4], float adr[4]);
int testclip(const float v[3]);
-void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
-void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]);
+void zbuffer_shadow(struct Render *re, float winmat[4][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
+void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[4][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]);
void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void*), void *data);
unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist);
void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int));
-int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache);
+int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache);
typedef struct APixstr {
unsigned short mask[4]; /* jitter mask */
@@ -136,8 +136,8 @@ void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec,
float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4);
/* exported to shadeinput.c */
-void zbuf_make_winmat(Render *re, float winmat[][4]);
-void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]);
+void zbuf_make_winmat(Render *re, float winmat[4][4]);
+void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]);
/* sould not really be exposed, bad! */
void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]);
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index c3babf9..b31aff8 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -90,6 +90,11 @@ RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRe
return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
}
+RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
+{
+ return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4);
+}
+
/* VlakPrimitive */
RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp
index f797f7a..01e592c 100644
--- a/source/blender/render/intern/raytrace/rayobject_instance.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp
@@ -75,7 +75,7 @@ typedef struct InstanceRayObject {
} InstanceRayObject;
-RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob)
+RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob)
{
InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */
@@ -173,13 +173,13 @@ static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
static void RE_rayobject_instance_free(RayObject *o)
{
- InstanceRayObject *obj = (InstanceRayObject*)o;
+ InstanceRayObject *obj = (InstanceRayObject *)o;
MEM_freeN(obj);
}
static float RE_rayobject_instance_cost(RayObject *o)
{
- InstanceRayObject *obj = (InstanceRayObject*)o;
+ InstanceRayObject *obj = (InstanceRayObject *)o;
return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE;
}
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index afb8fe6..658ab9d 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -223,7 +223,7 @@ static Node *addnode(Octree *oc)
return oc->adrnode[index] + (oc->nodecount & 4095);
}
-static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3])
+static int face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3])
{
static float nor[3], d;
float fx, fy, fz;
@@ -321,12 +321,12 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short
calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]);
}
-static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3])
+static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3])
{
int ocx1, ocx2, ocy1, ocy2;
int x, y, dx = 0, dy = 0;
float ox1, ox2, oy1, oy2;
- float labda, labdao, labdax, labday, ldx, ldy;
+ float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy;
ocx1 = rts[b1][c1];
ocy1 = rts[b1][c2];
@@ -345,40 +345,40 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa
if (ox1 != ox2) {
if (ox2 - ox1 > 0.0f) {
- labdax = (ox1 - ocx1 - 1.0f) / (ox1 - ox2);
+ lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2);
ldx = -1.0f / (ox1 - ox2);
dx = 1;
}
else {
- labdax = (ox1 - ocx1) / (ox1 - ox2);
+ lambda_x = (ox1 - ocx1) / (ox1 - ox2);
ldx = 1.0f / (ox1 - ox2);
dx = -1;
}
}
else {
- labdax = 1.0f;
+ lambda_x = 1.0f;
ldx = 0;
}
if (oy1 != oy2) {
if (oy2 - oy1 > 0.0f) {
- labday = (oy1 - ocy1 - 1.0f) / (oy1 - oy2);
+ lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2);
ldy = -1.0f / (oy1 - oy2);
dy = 1;
}
else {
- labday = (oy1 - ocy1) / (oy1 - oy2);
+ lambda_y = (oy1 - ocy1) / (oy1 - oy2);
ldy = 1.0f / (oy1 - oy2);
dy = -1;
}
}
else {
- labday = 1.0f;
+ lambda_y = 1.0f;
ldy = 0;
}
x = ocx1; y = ocy1;
- labda = MIN2(labdax, labday);
+ lambda = MIN2(lambda_x, lambda_y);
while (TRUE) {
@@ -389,26 +389,26 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa
ocface[oc->ocres * x + y] = 1;
}
- labdao = labda;
- if (labdax == labday) {
- labdax += ldx;
+ lambda_o = lambda;
+ if (lambda_x == lambda_y) {
+ lambda_x += ldx;
x += dx;
- labday += ldy;
+ lambda_y += ldy;
y += dy;
}
else {
- if (labdax < labday) {
- labdax += ldx;
+ if (lambda_x < lambda_y) {
+ lambda_x += ldx;
x += dx;
}
else {
- labday += ldy;
+ lambda_y += ldy;
y += dy;
}
}
- labda = MIN2(labdax, labday);
- if (labda == labdao) break;
- if (labda >= 1.0f) break;
+ lambda = MIN2(lambda_x, lambda_y);
+ if (lambda == lambda_o) break;
+ if (lambda >= 1.0f) break;
}
ocface[oc->ocres * ocx2 + ocy2] = 1;
}
@@ -542,13 +542,13 @@ static void octree_fill_rayface(Octree *oc, RayFace *face)
oc2 = rts[1][c];
oc3 = rts[2][c];
if (!RE_rayface_isQuad(face)) {
- ocmin[c] = MIN3(oc1, oc2, oc3);
- ocmax[c] = MAX3(oc1, oc2, oc3);
+ ocmin[c] = min_iii(oc1, oc2, oc3);
+ ocmax[c] = max_iii(oc1, oc2, oc3);
}
else {
oc4 = rts[3][c];
- ocmin[c] = MIN4(oc1, oc2, oc3, oc4);
- ocmax[c] = MAX4(oc1, oc2, oc3, oc4);
+ ocmin[c] = min_iiii(oc1, oc2, oc3, oc4);
+ ocmax[c] = max_iiii(oc1, oc2, oc3, oc4);
}
if (ocmax[c] > oc->ocres - 1) ocmax[c] = oc->ocres - 1;
if (ocmin[c] < 0) ocmin[c] = 0;
@@ -851,8 +851,8 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
OcVal ocval;
float vec1[3], vec2[3], start[3], end[3];
float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2;
- float labdao, labdax, ldx, labday, ldy, labdaz, ldz, ddalabda;
- float olabda = 0;
+ float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda;
+ float o_lambda = 0;
int dx, dy, dz;
int xo, yo, zo, c1 = 0;
int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2;
@@ -871,7 +871,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
copy_v3_v3(start, is->start);
madd_v3_v3v3fl(end, is->start, is->dir, is->dist);
ldx = is->dir[0] * is->dist;
- olabda = is->dist;
+ o_lambda = is->dist;
u1 = 0.0f;
u2 = 1.0f;
@@ -939,68 +939,68 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
float dox, doy, doz;
int eqval;
- /* calc labda en ld */
+ /* calc lambda en ld */
dox = ox1 - ox2;
doy = oy1 - oy2;
doz = oz1 - oz2;
if (dox < -FLT_EPSILON) {
ldx = -1.0f / dox;
- labdax = (ocx1 - ox1 + 1.0f) * ldx;
+ lambda_x = (ocx1 - ox1 + 1.0f) * ldx;
dx = 1;
}
else if (dox > FLT_EPSILON) {
ldx = 1.0f / dox;
- labdax = (ox1 - ocx1) * ldx;
+ lambda_x = (ox1 - ocx1) * ldx;
dx = -1;
}
else {
- labdax = 1.0f;
+ lambda_x = 1.0f;
ldx = 0;
dx = 0;
}
if (doy < -FLT_EPSILON) {
ldy = -1.0f / doy;
- labday = (ocy1 - oy1 + 1.0f) * ldy;
+ lambda_y = (ocy1 - oy1 + 1.0f) * ldy;
dy = 1;
}
else if (doy > FLT_EPSILON) {
ldy = 1.0f / doy;
- labday = (oy1 - ocy1) * ldy;
+ lambda_y = (oy1 - ocy1) * ldy;
dy = -1;
}
else {
- labday = 1.0f;
+ lambda_y = 1.0f;
ldy = 0;
dy = 0;
}
if (doz < -FLT_EPSILON) {
ldz = -1.0f / doz;
- labdaz = (ocz1 - oz1 + 1.0f) * ldz;
+ lambda_z = (ocz1 - oz1 + 1.0f) * ldz;
dz = 1;
}
else if (doz > FLT_EPSILON) {
ldz = 1.0f / doz;
- labdaz = (oz1 - ocz1) * ldz;
+ lambda_z = (oz1 - ocz1) * ldz;
dz = -1;
}
else {
- labdaz = 1.0f;
+ lambda_z = 1.0f;
ldz = 0;
dz = 0;
}
xo = ocx1; yo = ocy1; zo = ocz1;
- ddalabda = MIN3(labdax, labday, labdaz);
+ dda_lambda = min_fff(lambda_x, lambda_y, lambda_z);
vec2[0] = ox1;
vec2[1] = oy1;
vec2[2] = oz1;
/* this loop has been constructed to make sure the first and last node of ray
- * are always included, even when ddalabda==1.0f or larger */
+ * are always included, even when dda_lambda==1.0f or larger */
while (TRUE) {
@@ -1010,83 +1010,83 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
/* calculate ray intersection with octree node */
copy_v3_v3(vec1, vec2);
// dox, y, z is negative
- vec2[0] = ox1 - ddalabda * dox;
- vec2[1] = oy1 - ddalabda * doy;
- vec2[2] = oz1 - ddalabda * doz;
+ vec2[0] = ox1 - dda_lambda * dox;
+ vec2[1] = oy1 - dda_lambda * doy;
+ vec2[2] = oz1 - dda_lambda * doz;
calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
- //is->dist = (u1+ddalabda*(u2-u1))*olabda;
+ //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda;
if (testnode(oc, is, no, ocval) )
found = 1;
- if (is->dist < (u1 + ddalabda * (u2 - u1)) * olabda)
+ if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda)
return found;
}
- labdao = ddalabda;
+ lambda_o = dda_lambda;
/* traversing octree nodes need careful detection of smallest values, with proper
- * exceptions for equal labdas */
- eqval = (labdax == labday);
- if (labday == labdaz) eqval += 2;
- if (labdax == labdaz) eqval += 4;
+ * exceptions for equal lambdas */
+ eqval = (lambda_x == lambda_y);
+ if (lambda_y == lambda_z) eqval += 2;
+ if (lambda_x == lambda_z) eqval += 4;
if (eqval) { // only 4 cases exist!
if (eqval == 7) { // x=y=z
- xo += dx; labdax += ldx;
- yo += dy; labday += ldy;
- zo += dz; labdaz += ldz;
+ xo += dx; lambda_x += ldx;
+ yo += dy; lambda_y += ldy;
+ zo += dz; lambda_z += ldz;
}
else if (eqval == 1) { // x=y
- if (labday < labdaz) {
- xo += dx; labdax += ldx;
- yo += dy; labday += ldy;
+ if (lambda_y < lambda_z) {
+ xo += dx; lambda_x += ldx;
+ yo += dy; lambda_y += ldy;
}
else {
- zo += dz; labdaz += ldz;
+ zo += dz; lambda_z += ldz;
}
}
else if (eqval == 2) { // y=z
- if (labdax < labday) {
- xo += dx; labdax += ldx;
+ if (lambda_x < lambda_y) {
+ xo += dx; lambda_x += ldx;
}
else {
- yo += dy; labday += ldy;
- zo += dz; labdaz += ldz;
+ yo += dy; lambda_y += ldy;
+ zo += dz; lambda_z += ldz;
}
}
else { // x=z
- if (labday < labdax) {
- yo += dy; labday += ldy;
+ if (lambda_y < lambda_x) {
+ yo += dy; lambda_y += ldy;
}
else {
- xo += dx; labdax += ldx;
- zo += dz; labdaz += ldz;
+ xo += dx; lambda_x += ldx;
+ zo += dz; lambda_z += ldz;
}
}
}
else { // all three different, just three cases exist
- eqval = (labdax < labday);
- if (labday < labdaz) eqval += 2;
- if (labdax < labdaz) eqval += 4;
+ eqval = (lambda_x < lambda_y);
+ if (lambda_y < lambda_z) eqval += 2;
+ if (lambda_x < lambda_z) eqval += 4;
if (eqval == 7 || eqval == 5) { // x smallest
- xo += dx; labdax += ldx;
+ xo += dx; lambda_x += ldx;
}
else if (eqval == 2 || eqval == 6) { // y smallest
- yo += dy; labday += ldy;
+ yo += dy; lambda_y += ldy;
}
else { // z smallest
- zo += dz; labdaz += ldz;
+ zo += dz; lambda_z += ldz;
}
}
- ddalabda = MIN3(labdax, labday, labdaz);
- if (ddalabda == labdao) break;
+ dda_lambda = min_fff(lambda_x, lambda_y, lambda_z);
+ if (dda_lambda == lambda_o) break;
/* to make sure the last node is always checked */
- if (labdao >= 1.0f) break;
+ if (lambda_o >= 1.0f) break;
}
}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 1906f97..6c5e558 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -161,7 +161,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
*/
void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
- void (*vertexfunc)(float*), void (*termfunc)(void))
+ void (*vertexfunc)(float *), void (*termfunc)(void))
{
extern unsigned char hash[512];
ObjectRen *obr= NULL;
@@ -759,7 +759,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, f
/* note; autosmooth happens in object space still, after applying autosmooth we rotate */
/* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
-static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr)
+static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr)
{
ASvert *asv, *asverts;
ASface *asf;
@@ -2186,7 +2186,7 @@ static short test_for_displace(Render *re, Object *ob)
return 0;
}
-static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3])
+static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3])
{
MTFace *tface;
short texco= shi->mat->texco;
@@ -2285,7 +2285,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
return;
}
-static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3])
+static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3])
{
ShadeInput shi;
@@ -2340,7 +2340,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
}
}
-static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3])
+static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3])
{
VertRen *vr;
VlakRen *vlr;
@@ -2820,7 +2820,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
ListBase disp={NULL, NULL};
Material **matar;
float *data, *fp, *orco=NULL;
- float n[3], mat[4][4];
+ float n[3], mat[4][4], nmat[4][4];
int nr, startvert, a, b;
int need_orco=0, totmat;
@@ -2835,6 +2835,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
mult_m4_m4m4(mat, re->viewmat, ob->obmat);
invert_m4_m4(ob->imat, mat);
+ /* local object -> world space transform for normals */
+ copy_m4_m4(nmat, mat);
+ transpose_m4(nmat);
+ invert_m4(nmat);
+
/* material array */
totmat= ob->totcol+1;
matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
@@ -2859,7 +2864,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
}
else {
if (need_orco) {
- orco= get_object_orco(re, ob);
+ orco = get_object_orco(re, ob);
}
while (dl) {
@@ -2891,13 +2896,20 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
zero_v3(n);
index= dl->index;
for (a=0; a<dl->parts; a++, index+=3) {
+ int v1 = index[0], v2 = index[1], v3 = index[2];
+ float *co1 = &dl->verts[v1 * 3],
+ *co2 = &dl->verts[v2 * 3],
+ *co3 = &dl->verts[v3 * 3];
+
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
- vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
- vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
- vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
+ vlr->v1= RE_findOrAddVert(obr, startvert + v1);
+ vlr->v2= RE_findOrAddVert(obr, startvert + v2);
+ vlr->v3= RE_findOrAddVert(obr, startvert + v3);
vlr->v4= NULL;
- if (area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON10) {
- normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ /* to prevent float accuracy issues, we calculate normal in local object space (not world) */
+ if (area_tri_v3(co3, co2, co1)>FLT_EPSILON10) {
+ normal_tri_v3(tmp, co3, co2, co1);
add_v3_v3(n, tmp);
}
@@ -2906,6 +2918,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
vlr->ec= 0;
}
+ /* transform normal to world space */
+ mul_m4_v3(nmat, n);
normalize_v3(n);
/* vertex normals */
@@ -3217,7 +3231,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataMask mask;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *orco=0;
- int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0;
+ int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0;
int a, a1, ok, vertofs;
int end, do_autosmooth = FALSE, totvert = 0;
int use_original_normals = FALSE;
@@ -3267,6 +3281,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
need_nmap_tangent= 1;
}
+ /* origindex currently only used when baking to vertex colors */
+ if(re->flag & R_BAKING && re->r.bake_flag & R_BAKE_VCOL)
+ need_origindex= 1;
+
/* check autosmooth and displacement, we then have to skip only-verts optimize */
do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
if (do_autosmooth)
@@ -3304,6 +3322,15 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
make_render_halos(re, obr, me, totvert, mvert, ma, orco);
}
else {
+ const int *index_vert_orig = NULL;
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+ if (need_origindex) {
+ index_vert_orig = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ /* double lookup for faces -> polys */
+ index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ }
for (a=0; a<totvert; a++, mvert++) {
ver= RE_findOrAddVert(obr, obr->totvert++);
@@ -3320,6 +3347,18 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
ver->orco= orco;
orco+=3;
}
+
+ if (need_origindex) {
+ int *origindex;
+ origindex = RE_vertren_get_origindex(obr, ver, 1);
+
+ /* Use orig index array if it's available (e.g. in the presence
+ * of modifiers). */
+ if (index_vert_orig)
+ *origindex = index_vert_orig[a];
+ else
+ *origindex = a;
+ }
}
if (!timeoffset) {
@@ -3441,6 +3480,21 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
}
}
+
+ if (need_origindex) {
+ /* Find original index of mpoly for this tessface. Options:
+ - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
+ - OR Tesselated mesh; look up from tessface -> mpoly
+ - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
+ int *origindex;
+ origindex = RE_vlakren_get_origindex(obr, vlr, 1);
+ if (index_mf_to_mpoly && index_mp_to_orig)
+ *origindex = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a);
+ else if (index_mf_to_mpoly)
+ *origindex = index_mf_to_mpoly[a];
+ else
+ *origindex = a;
+ }
}
}
}
@@ -3525,7 +3579,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
/* Lamps and Shadowbuffers */
/* ------------------------------------------------------------------------- */
-static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
+static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4])
{
struct ShadBuf *shb;
float viewinv[4][4];
@@ -5141,7 +5195,7 @@ void RE_DataBase_ApplyWindow(Render *re)
project_renderdata(re, projectverto, 0, 0, 0);
}
-void RE_DataBase_GetView(Render *re, float mat[][4])
+void RE_DataBase_GetView(Render *re, float mat[4][4])
{
copy_m4_m4(mat, re->viewmat);
}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index c3126e5..be8b7f6 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -210,7 +210,7 @@ static void envmap_free_render_copy(Render *envre)
/* ------------------------------------------------------------------------- */
-static void envmap_transmatrix(float mat[][4], int part)
+static void envmap_transmatrix(float mat[4][4], int part)
{
float tmat[4][4], eul[3], rotmat[4][4];
@@ -247,7 +247,7 @@ static void envmap_transmatrix(float mat[][4], int part)
/* ------------------------------------------------------------------------- */
-static void env_rotate_scene(Render *re, float mat[][4], int mode)
+static void env_rotate_scene(Render *re, float mat[4][4], int mode)
{
GroupObject *go;
ObjectRen *obr;
@@ -587,53 +587,53 @@ void make_envmaps(Render *re)
static int envcube_isect(EnvMap *env, const float vec[3], float answ[2])
{
- float labda;
+ float lambda;
int face;
if (env->type == ENV_PLANE) {
face = 1;
- labda = 1.0f / vec[2];
- answ[0] = env->viewscale * labda * vec[0];
- answ[1] = -env->viewscale * labda * vec[1];
+ lambda = 1.0f / vec[2];
+ answ[0] = env->viewscale * lambda * vec[0];
+ answ[1] = -env->viewscale * lambda * vec[1];
}
else {
/* which face */
if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) {
face = 0;
- labda = -1.0f / vec[2];
- answ[0] = labda * vec[0];
- answ[1] = labda * vec[1];
+ lambda = -1.0f / vec[2];
+ answ[0] = lambda * vec[0];
+ answ[1] = lambda * vec[1];
}
else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) {
face = 1;
- labda = 1.0f / vec[2];
- answ[0] = labda * vec[0];
- answ[1] = -labda * vec[1];
+ lambda = 1.0f / vec[2];
+ answ[0] = lambda * vec[0];
+ answ[1] = -lambda * vec[1];
}
else if (vec[1] >= fabsf(vec[0])) {
face = 2;
- labda = 1.0f / vec[1];
- answ[0] = labda * vec[0];
- answ[1] = labda * vec[2];
+ lambda = 1.0f / vec[1];
+ answ[0] = lambda * vec[0];
+ answ[1] = lambda * vec[2];
}
else if (vec[0] <= -fabsf(vec[1])) {
face = 3;
- labda = -1.0f / vec[0];
- answ[0] = labda * vec[1];
- answ[1] = labda * vec[2];
+ lambda = -1.0f / vec[0];
+ answ[0] = lambda * vec[1];
+ answ[1] = lambda * vec[2];
}
else if (vec[1] <= -fabsf(vec[0])) {
face = 4;
- labda = -1.0f / vec[1];
- answ[0] = -labda * vec[0];
- answ[1] = labda * vec[2];
+ lambda = -1.0f / vec[1];
+ answ[0] = -lambda * vec[0];
+ answ[1] = lambda * vec[2];
}
else {
face = 5;
- labda = 1.0f / vec[0];
- answ[0] = -labda * vec[1];
- answ[1] = labda * vec[2];
+ lambda = 1.0f / vec[0];
+ answ[0] = -lambda * vec[1];
+ answ[1] = lambda * vec[2];
}
}
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 6fdf11b..296c8b6 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -150,6 +150,23 @@ void RE_engine_free(RenderEngine *engine)
/* Render Results */
+static RenderPart *get_part_from_result(Render *re, RenderResult *result)
+{
+ RenderPart *pa;
+
+ for (pa = re->parts.first; pa; pa = pa->next) {
+ if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin &&
+ result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin &&
+ result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin &&
+ result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin)
+ {
+ return pa;
+ }
+ }
+
+ return NULL;
+}
+
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername)
{
Render *re = engine->re;
@@ -179,12 +196,19 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
/* can be NULL if we CLAMP the width or height to 0 */
if (result) {
+ RenderPart *pa;
+
BLI_addtail(&engine->fullresult, result);
result->tilerect.xmin += re->disprect.xmin;
result->tilerect.xmax += re->disprect.xmin;
result->tilerect.ymin += re->disprect.ymin;
result->tilerect.ymax += re->disprect.ymin;
+
+ pa = get_part_from_result(re, result);
+
+ if (pa)
+ pa->status = PART_STATUS_IN_PROGRESS;
}
return result;
@@ -203,7 +227,6 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel)
{
Render *re = engine->re;
- RenderPart *pa;
if (!result) {
return;
@@ -212,15 +235,10 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel
/* merge. on break, don't merge in result for preview renders, looks nicer */
if (!cancel) {
/* for exr tile render, detect tiles that are done */
- for (pa = re->parts.first; pa; pa = pa->next) {
- if (result->tilerect.xmin == pa->disprect.xmin &&
- result->tilerect.ymin == pa->disprect.ymin &&
- result->tilerect.xmax == pa->disprect.xmax &&
- result->tilerect.ymax == pa->disprect.ymax)
- {
- pa->ready = 1;
- }
- }
+ RenderPart *pa = get_part_from_result(re, result);
+
+ if (pa)
+ pa->status = PART_STATUS_READY;
if (re->result->do_exr_tile)
render_result_exr_file_merge(re->result, result);
@@ -310,6 +328,47 @@ void RE_engine_report(RenderEngine *engine, int type, const char *msg)
BKE_report(engine->reports, type, msg);
}
+void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
+{
+ RenderPart *pa;
+ int total_tiles = 0;
+ rcti *tiles = NULL;
+ int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS;
+
+ if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
+ *total_tiles_r = 0;
+ *tiles_r = NULL;
+ return;
+ }
+
+ for (pa = re->parts.first; pa; pa = pa->next) {
+ if (pa->status == PART_STATUS_IN_PROGRESS) {
+ if (total_tiles >= allocation_size) {
+ if (tiles == NULL)
+ tiles = MEM_mallocN(allocation_step * sizeof(rcti), "current engine tiles");
+ else
+ tiles = MEM_reallocN(tiles, (total_tiles + allocation_step) * sizeof(rcti));
+
+ allocation_size += allocation_step;
+ }
+
+ tiles[total_tiles] = pa->disprect;
+
+ if (pa->crop) {
+ tiles[total_tiles].xmin += pa->crop;
+ tiles[total_tiles].ymin += pa->crop;
+ tiles[total_tiles].xmax -= pa->crop;
+ tiles[total_tiles].ymax -= pa->crop;
+ }
+
+ total_tiles++;
+ }
+ }
+
+ *total_tiles_r = total_tiles;
+ *tiles_r = tiles;
+}
+
/* Render */
int RE_engine_render(Render *re, int do_all)
@@ -354,9 +413,7 @@ int RE_engine_render(Render *re, int do_all)
if (!engine) {
engine = RE_engine_create(type);
-
- if (persistent_data)
- re->engine = engine;
+ re->engine = engine;
}
engine->flag |= RE_ENGINE_RENDERING;
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index cd06839..4aaa624 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -102,6 +102,11 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
col[1] = ((float)rect[1])*(1.0f/255.0f);
col[2] = ((float)rect[2])*(1.0f/255.0f);
col[3] = ((float)rect[3])*(1.0f/255.0f);
+
+ /* bytes are internally straight, however render pipeline seems to expect premul */
+ col[0] *= col[3];
+ col[1] *= col[3];
+ col[2] *= col[3];
}
}
@@ -219,10 +224,8 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
/* keep this before interpolation [#29761] */
- if (tex->imaflag & TEX_USEALPHA) {
- if ((tex->imaflag & TEX_CALCALPHA) == 0) {
- texres->talpha = TRUE;
- }
+ if ((tex->imaflag & TEX_CALCALPHA) == 0) {
+ texres->talpha = TRUE;
}
/* interpolate */
@@ -286,7 +289,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (texres->talpha) texres->tin= texres->ta;
else if (tex->imaflag & TEX_CALCALPHA) {
- texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb);
+ texres->ta = texres->tin = max_fff(texres->tr, texres->tg, texres->tb);
}
else texres->ta= texres->tin= 1.0;
@@ -710,9 +713,10 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf
}
else {
char *rect = (char *)(ibuf->rect + x + y*ibuf->x);
- col[0] = rect[0]*(1.f/255.f);
- col[1] = rect[1]*(1.f/255.f);
- col[2] = rect[2]*(1.f/255.f);
+ float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
+ col[0] = rect[0] * inv_alpha_fac;
+ col[1] = rect[1] * inv_alpha_fac;
+ col[2] = rect[2] * inv_alpha_fac;
col[3] = clip ? 0.f : rect[3]*(1.f/255.f);
}
return clip;
@@ -1088,7 +1092,8 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
+ if ((tex->imaflag & TEX_CALCALPHA) == 0)
+ texres->talpha = 1;
texr.talpha = texres->talpha;
if (tex->imaflag & TEX_IMAROT) {
@@ -1112,10 +1117,10 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
/* pixel coordinates */
- minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
- maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
/* tex_sharper has been removed */
minx = (maxx - minx)*0.5f;
@@ -1416,7 +1421,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
if (tex->imaflag & TEX_CALCALPHA)
- texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb);
+ texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
else
texres->tin = texres->ta;
if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
@@ -1501,13 +1506,8 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if (tex->imaflag & TEX_USEALPHA) {
- if (tex->imaflag & TEX_CALCALPHA) {
- /* pass */
- }
- else {
- texres->talpha = TRUE;
- }
+ if ((tex->imaflag & TEX_CALCALPHA) == 0) {
+ texres->talpha = TRUE;
}
texr.talpha= texres->talpha;
@@ -1535,10 +1535,10 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* pixel coordinates */
- minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
- miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
- maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
+ miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
+ maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
/* tex_sharper has been removed */
minx= (maxx-minx)/2.0f;
@@ -1826,7 +1826,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
if (tex->imaflag & TEX_CALCALPHA) {
- texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
+ texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
}
else texres->tin= texres->ta;
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 3ea74ab..0d957f8 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -515,7 +515,7 @@ void RE_SetPixelSize(Render *re, float pixsize)
re->viewdy = re->ycor * pixsize;
}
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4])
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4])
{
re->r.cfra = frame;
RE_SetCamera(re, camera);
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
new file mode 100644
index 0000000..091ba95
--- /dev/null
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -0,0 +1,1276 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2012 by Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Morten Mikkelsen,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/multires_bake.c
+ * \ingroup render
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
+
+#include "BKE_ccg.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_multires.h"
+#include "BKE_modifier.h"
+#include "BKE_subsurf.h"
+
+#include "RE_multires_bake.h"
+#include "RE_pipeline.h"
+#include "RE_shader_ext.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "rendercore.h"
+
+typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
+ float tangmat[3][3], const int x, const int y);
+
+typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
+typedef void (*MApplyBakeData)(void *bake_data);
+typedef void (*MFreeBakeData)(void *bake_data);
+
+typedef struct {
+ MVert *mvert;
+ MFace *mface;
+ MTFace *mtface;
+ float *pvtangent;
+ float *precomputed_normals;
+ int w, h;
+ int face_index;
+ int i0, i1, i2;
+ DerivedMesh *lores_dm, *hires_dm;
+ int lvl;
+ void *bake_data;
+ ImBuf *ibuf;
+ MPassKnownData pass_data;
+} MResolvePixelData;
+
+typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
+
+typedef struct {
+ int w, h;
+ char *texels;
+ const MResolvePixelData *data;
+ MFlushPixel flush_pixel;
+} MBakeRast;
+
+typedef struct {
+ float *heights;
+ float height_min, height_max;
+ Image *ima;
+ DerivedMesh *ssdm;
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
+} MHeightBakeData;
+
+typedef struct {
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
+} MNormalBakeData;
+
+typedef struct {
+ int number_of_rays;
+ float bias;
+
+ unsigned short *permutation_table_1;
+ unsigned short *permutation_table_2;
+
+ RayObject *raytree;
+ RayFace *rayfaces;
+
+ const int *orig_index_mf_to_mpoly;
+ const int *orig_index_mp_to_orig;
+} MAOBakeData;
+
+static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
+{
+ unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2,
+ data->mface[face_num].v3, data->mface[face_num].v4};
+ const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH);
+
+ if (!smoothnormal) { /* flat */
+ if (data->precomputed_normals) {
+ copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]);
+ }
+ else {
+ float nor[3];
+ float *p0, *p1, *p2;
+ const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3;
+
+ p0 = data->mvert[indices[0]].co;
+ p1 = data->mvert[indices[1]].co;
+ p2 = data->mvert[indices[2]].co;
+
+ if (iGetNrVerts == 4) {
+ float *p3 = data->mvert[indices[3]].co;
+ normal_quad_v3(nor, p0, p1, p2, p3);
+ }
+ else {
+ normal_tri_v3(nor, p0, p1, p2);
+ }
+
+ copy_v3_v3(norm, nor);
+ }
+ }
+ else {
+ short *no = data->mvert[indices[vert_index]].no;
+
+ normal_short_to_float_v3(norm, no);
+ normalize_v3(norm);
+ }
+}
+
+static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
+{
+ memset(bake_rast, 0, sizeof(MBakeRast));
+
+ bake_rast->texels = ibuf->userdata;
+ bake_rast->w = ibuf->x;
+ bake_rast->h = ibuf->y;
+ bake_rast->data = data;
+ bake_rast->flush_pixel = flush_pixel;
+}
+
+static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
+{
+ float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
+ float *st0, *st1, *st2;
+ float *tang0, *tang1, *tang2;
+ float no0[3], no1[3], no2[3];
+ float fUV[2], from_tang[3][3], to_tang[3][3];
+ float u, v, w, sign;
+ int r;
+
+ const int i0 = data->i0;
+ const int i1 = data->i1;
+ const int i2 = data->i2;
+
+ st0 = data->mtface[data->face_index].uv[i0];
+ st1 = data->mtface[data->face_index].uv[i1];
+ st2 = data->mtface[data->face_index].uv[i2];
+
+ multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */
+ multiresbake_get_normal(data, no1, data->face_index, i1);
+ multiresbake_get_normal(data, no2, data->face_index, i2);
+
+ resolve_tri_uv(fUV, st, st0, st1, st2);
+
+ u = fUV[0];
+ v = fUV[1];
+ w = 1 - u - v;
+
+ if (data->pvtangent) {
+ tang0 = data->pvtangent + data->face_index * 16 + i0 * 4;
+ tang1 = data->pvtangent + data->face_index * 16 + i1 * 4;
+ tang2 = data->pvtangent + data->face_index * 16 + i2 * 4;
+
+ /* the sign is the same at all face vertices for any non degenerate face.
+ * Just in case we clamp the interpolated value though. */
+ sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f;
+
+ /* this sequence of math is designed specifically as is with great care
+ * to be compatible with our shader. Please don't change without good reason. */
+ for (r = 0; r < 3; r++) {
+ from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w;
+ from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w;
+ }
+
+ cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */
+ mul_v3_fl(from_tang[1], sign);
+ invert_m3_m3(to_tang, from_tang);
+ }
+ else {
+ zero_m3(to_tang);
+ }
+
+ data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
+ data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
+}
+
+static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
+{
+ const int w = bake_rast->w;
+ const int h = bake_rast->h;
+
+ if (x >= 0 && x < w && y >= 0 && y < h) {
+ if ((bake_rast->texels[y * w + x]) == 0) {
+ bake_rast->texels[y * w + x] = FILTER_MASK_USED;
+ flush_pixel(bake_rast->data, x, y);
+ }
+ }
+}
+
+static void rasterize_half(const MBakeRast *bake_rast,
+ const float s0_s, const float t0_s, const float s1_s, const float t1_s,
+ const float s0_l, const float t0_l, const float s1_l, const float t1_l,
+ const int y0_in, const int y1_in, const int is_mid_right)
+{
+ const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
+ const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
+ const int w = bake_rast->w;
+ const int h = bake_rast->h;
+ int y, y0, y1;
+
+ if (y1_in <= 0 || y0_in >= h)
+ return;
+
+ y0 = y0_in < 0 ? 0 : y0_in;
+ y1 = y1_in >= h ? h : y1_in;
+
+ for (y = y0; y < y1; y++) {
+ /*-b(x-x0) + a(y-y0) = 0 */
+ int iXl, iXr, x;
+ float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
+ float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
+
+ if (is_mid_right != 0)
+ SWAP(float, x_l, x_r);
+
+ iXl = (int)ceilf(x_l);
+ iXr = (int)ceilf(x_r);
+
+ if (iXr > 0 && iXl < w) {
+ iXl = iXl < 0 ? 0 : iXl;
+ iXr = iXr >= w ? w : iXr;
+
+ for (x = iXl; x < iXr; x++)
+ set_rast_triangle(bake_rast, x, y);
+ }
+ }
+}
+
+static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
+{
+ const int w = bake_rast->w;
+ const int h = bake_rast->h;
+ float slo = st0_in[0] * w - 0.5f;
+ float tlo = st0_in[1] * h - 0.5f;
+ float smi = st1_in[0] * w - 0.5f;
+ float tmi = st1_in[1] * h - 0.5f;
+ float shi = st2_in[0] * w - 0.5f;
+ float thi = st2_in[1] * h - 0.5f;
+ int is_mid_right = 0, ylo, yhi, yhi_beg;
+
+ /* skip degenerates */
+ if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi))
+ return;
+
+ /* sort by T */
+ if (tlo > tmi && tlo > thi) {
+ SWAP(float, shi, slo);
+ SWAP(float, thi, tlo);
+ }
+ else if (tmi > thi) {
+ SWAP(float, shi, smi);
+ SWAP(float, thi, tmi);
+ }
+
+ if (tlo > tmi) {
+ SWAP(float, slo, smi);
+ SWAP(float, tlo, tmi);
+ }
+
+ /* check if mid point is to the left or to the right of the lo-hi edge */
+ is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
+ ylo = (int) ceilf(tlo);
+ yhi_beg = (int) ceilf(tmi);
+ yhi = (int) ceilf(thi);
+
+ /*if (fTmi>ceilf(fTlo))*/
+ rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
+ rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
+}
+
+static int multiresbake_test_break(MultiresBakeRender *bkr)
+{
+ if (!bkr->stop) {
+ /* this means baker is executed outside from job system */
+ return 0;
+ }
+
+ return *bkr->stop || G.is_break;
+}
+
+/* **** Threading routines **** */
+
+typedef struct MultiresBakeQueue {
+ int cur_face;
+ int tot_face;
+ SpinLock spin;
+} MultiresBakeQueue;
+
+typedef struct MultiresBakeThread {
+ /* this data is actually shared between all the threads */
+ MultiresBakeQueue *queue;
+ MultiresBakeRender *bkr;
+ Image *image;
+ void *bake_data;
+
+ /* thread-specific data */
+ MBakeRast bake_rast;
+ MResolvePixelData data;
+} MultiresBakeThread;
+
+static int multires_bake_queue_next_face(MultiresBakeQueue *queue)
+{
+ int face = -1;
+
+ /* TODO: it could worth making it so thread will handle neighbor faces
+ * for better memory cache utilization
+ */
+
+ BLI_spin_lock(&queue->spin);
+ if (queue->cur_face < queue->tot_face) {
+ face = queue->cur_face;
+ queue->cur_face++;
+ }
+ BLI_spin_unlock(&queue->spin);
+
+ return face;
+}
+
+static void *do_multires_bake_thread(void *data_v)
+{
+ MultiresBakeThread *handle = (MultiresBakeThread *) data_v;
+ MResolvePixelData *data = &handle->data;
+ MBakeRast *bake_rast = &handle->bake_rast;
+ MultiresBakeRender *bkr = handle->bkr;
+ int f;
+
+ while ((f = multires_bake_queue_next_face(handle->queue)) >= 0) {
+ MTFace *mtfate = &data->mtface[f];
+ int verts[3][2], nr_tris, t;
+
+ if (multiresbake_test_break(bkr))
+ break;
+
+ if (mtfate->tpage != handle->image)
+ continue;
+
+ data->face_index = f;
+
+ /* might support other forms of diagonal splits later on such as
+ * split by shortest diagonal.*/
+ verts[0][0] = 0;
+ verts[1][0] = 1;
+ verts[2][0] = 2;
+
+ verts[0][1] = 0;
+ verts[1][1] = 2;
+ verts[2][1] = 3;
+
+ nr_tris = data->mface[f].v4 != 0 ? 2 : 1;
+ for (t = 0; t < nr_tris; t++) {
+ data->i0 = verts[0][t];
+ data->i1 = verts[1][t];
+ data->i2 = verts[2][t];
+
+ bake_rasterize(bake_rast, mtfate->uv[data->i0], mtfate->uv[data->i1], mtfate->uv[data->i2]);
+
+ /* tag image buffer for refresh */
+ if (data->ibuf->rect_float)
+ data->ibuf->userflags |= IB_RECT_INVALID;
+
+ data->ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+
+ /* update progress */
+ BLI_spin_lock(&handle->queue->spin);
+ bkr->baked_faces++;
+
+ if (bkr->do_update)
+ *bkr->do_update = TRUE;
+
+ if (bkr->progress)
+ *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / handle->queue->tot_face) / bkr->tot_obj;
+ BLI_spin_unlock(&handle->queue->spin);
+ }
+
+ return NULL;
+}
+
+static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_tangent, MPassKnownData passKnownData,
+ MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
+{
+ DerivedMesh *dm = bkr->lores_dm;
+ const int lvl = bkr->lvl;
+ const int tot_face = dm->getNumTessFaces(dm);
+
+ if (tot_face > 0) {
+ MultiresBakeThread *handles;
+ MultiresBakeQueue queue;
+
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ MVert *mvert = dm->getVertArray(dm);
+ MFace *mface = dm->getTessFaceArray(dm);
+ MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
+ float *precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ float *pvtangent = NULL;
+
+ ListBase threads;
+ int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count();
+
+ void *bake_data = NULL;
+
+ if (require_tangent) {
+ if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
+ DM_add_tangent_layer(dm);
+
+ pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT);
+ }
+
+ /* all threads shares the same custom bake data */
+ if (initBakeData)
+ bake_data = initBakeData(bkr, ima);
+
+ if (tot_thread > 1)
+ BLI_init_threads(&threads, do_multires_bake_thread, tot_thread);
+
+ handles = MEM_callocN(tot_thread * sizeof(MultiresBakeThread), "do_multires_bake handles");
+
+ /* faces queue */
+ queue.cur_face = 0;
+ queue.tot_face = tot_face;
+ BLI_spin_init(&queue.spin);
+
+ /* fill in threads handles */
+ for (i = 0; i < tot_thread; i++) {
+ MultiresBakeThread *handle = &handles[i];
+
+ handle->bkr = bkr;
+ handle->image = ima;
+ handle->queue = &queue;
+
+ handle->data.mface = mface;
+ handle->data.mvert = mvert;
+ handle->data.mtface = mtface;
+ handle->data.pvtangent = pvtangent;
+ handle->data.precomputed_normals = precomputed_normals; /* don't strictly need this */
+ handle->data.w = ibuf->x;
+ handle->data.h = ibuf->y;
+ handle->data.lores_dm = dm;
+ handle->data.hires_dm = bkr->hires_dm;
+ handle->data.lvl = lvl;
+ handle->data.pass_data = passKnownData;
+ handle->data.bake_data = bake_data;
+ handle->data.ibuf = ibuf;
+
+ init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel);
+
+ if (tot_thread > 1)
+ BLI_insert_thread(&threads, handle);
+ }
+
+ /* run threads */
+ if (tot_thread > 1)
+ BLI_end_threads(&threads);
+ else
+ do_multires_bake_thread(&handles[0]);
+
+ BLI_spin_end(&queue.spin);
+
+ /* finalize baking */
+ if (applyBakeData)
+ applyBakeData(bake_data);
+
+ if (freeBakeData)
+ freeBakeData(bake_data);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+}
+
+/* mode = 0: interpolate normals,
+ * mode = 1: interpolate coord */
+static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
+{
+ int x0, x1, y0, y1;
+ float u, v;
+ float data[4][3];
+
+ x0 = (int) crn_x;
+ x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);
+
+ y0 = (int) crn_y;
+ y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);
+
+ u = crn_x - x0;
+ v = crn_y - y0;
+
+ if (mode == 0) {
+ copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
+ copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
+ copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
+ copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
+ }
+ else {
+ copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
+ copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
+ copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
+ copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
+ }
+
+ interp_bilinear_quad_v3(data, u, v, res);
+}
+
+static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,
+ const int *index_mf_to_mpoly, const int *index_mp_to_orig,
+ const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
+{
+ MFace mface;
+ CCGElem **grid_data;
+ CCGKey key;
+ float crn_x, crn_y;
+ int grid_size, S, face_side;
+ int *grid_offset, g_index;
+
+ lodm->getTessFace(lodm, face_index, &mface);
+
+ grid_size = hidm->getGridSize(hidm);
+ grid_data = hidm->getGridData(hidm);
+ grid_offset = hidm->getGridOffset(hidm);
+ hidm->getGridKey(hidm, &key);
+
+ face_side = (grid_size << 1) - 1;
+
+ if (lvl == 0) {
+ g_index = grid_offset[face_index];
+ S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y);
+ }
+ else {
+ int side = (1 << (lvl - 1)) + 1;
+ int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index);
+ int loc_offs = face_index % (1 << (2 * lvl));
+ int cell_index = loc_offs % ((side - 1) * (side - 1));
+ int cell_side = (grid_size - 1) / (side - 1);
+ int row = cell_index / (side - 1);
+ int col = cell_index % (side - 1);
+
+ S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index];
+ g_index = grid_offset[grid_index];
+
+ crn_y = (row * cell_side) + u * cell_side;
+ crn_x = (col * cell_side) + v * cell_side;
+ }
+
+ CLAMP(crn_x, 0.0f, grid_size);
+ CLAMP(crn_y, 0.0f, grid_size);
+
+ if (n != NULL)
+ interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n);
+
+ if (co != NULL)
+ interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co);
+}
+
+/* mode = 0: interpolate normals,
+ * mode = 1: interpolate coord */
+static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+ float data[4][3];
+
+ if (mode == 0) {
+ dm->getVertNo(dm, mface->v1, data[0]);
+ dm->getVertNo(dm, mface->v2, data[1]);
+ dm->getVertNo(dm, mface->v3, data[2]);
+ dm->getVertNo(dm, mface->v4, data[3]);
+ }
+ else {
+ dm->getVertCo(dm, mface->v1, data[0]);
+ dm->getVertCo(dm, mface->v2, data[1]);
+ dm->getVertCo(dm, mface->v3, data[2]);
+ dm->getVertCo(dm, mface->v4, data[3]);
+ }
+
+ interp_bilinear_quad_v3(data, u, v, res);
+}
+
+/* mode = 0: interpolate normals,
+ * mode = 1: interpolate coord */
+static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+ float data[3][3];
+
+ if (mode == 0) {
+ dm->getVertNo(dm, mface->v1, data[0]);
+ dm->getVertNo(dm, mface->v2, data[1]);
+ dm->getVertNo(dm, mface->v3, data[2]);
+ }
+ else {
+ dm->getVertCo(dm, mface->v1, data[0]);
+ dm->getVertCo(dm, mface->v2, data[1]);
+ dm->getVertCo(dm, mface->v3, data[2]);
+ }
+
+ interp_barycentric_tri_v3(data, u, v, res);
+}
+
+/* **************** Displacement Baker **************** */
+
+static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
+{
+ MHeightBakeData *height_data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ DerivedMesh *lodm = bkr->lores_dm;
+
+ height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
+
+ height_data->ima = ima;
+ height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
+ height_data->height_max = -FLT_MAX;
+ height_data->height_min = FLT_MAX;
+
+ if (!bkr->use_lores_mesh) {
+ SubsurfModifierData smd = {{NULL}};
+ int ss_lvl = bkr->tot_lvl - bkr->lvl;
+
+ CLAMP(ss_lvl, 0, 6);
+
+ if (ss_lvl > 0) {
+ smd.levels = smd.renderLevels = ss_lvl;
+ smd.flags |= eSubsurfModifierFlag_SubsurfUv;
+
+ if (bkr->simple)
+ smd.subdivType = ME_SIMPLE_SUBSURF;
+
+ height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0);
+ }
+ }
+
+ height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+ height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ return (void *)height_data;
+}
+
+static void apply_heights_data(void *bake_data)
+{
+ MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
+ int x, y, i;
+ float height, *heights = height_data->heights;
+ float min = height_data->height_min, max = height_data->height_max;
+
+ for (x = 0; x < ibuf->x; x++) {
+ for (y = 0; y < ibuf->y; y++) {
+ i = ibuf->x * y + x;
+
+ if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED)
+ continue;
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + i * 4;
+
+ if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
+ else height = 0;
+
+ rrgbf[0] = rrgbf[1] = rrgbf[2] = height;
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + i * 4;
+
+ if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
+ else height = 0;
+
+ rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height);
+ }
+ }
+ }
+
+ if (ibuf->rect_float)
+ ibuf->userflags |= IB_RECT_INVALID;
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
+}
+
+static void free_heights_data(void *bake_data)
+{
+ MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
+
+ if (height_data->ssdm)
+ height_data->ssdm->release(height_data->ssdm);
+
+ MEM_freeN(height_data->heights);
+ MEM_freeN(height_data);
+}
+
+/* MultiresBake callback for heights baking
+ * general idea:
+ * - find coord of point with specified UV in hi-res mesh (let's call it p1)
+ * - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
+ * mesh to make texture smoother) let's call this point p0 and n.
+ * - height wound be dot(n, p1-p0) */
+static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
+ float UNUSED(tangmat[3][3]), const int x, const int y)
+{
+ MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+ MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
+ float uv[2], *st0, *st1, *st2, *st3;
+ int pixel = ibuf->x * y + x;
+ float vec[3], p0[3], p1[3], n[3], len;
+
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ st0 = mtface[face_index].uv[0];
+ st1 = mtface[face_index].uv[1];
+ st2 = mtface[face_index].uv[2];
+
+ if (mface.v4) {
+ st3 = mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ }
+ else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm,
+ height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
+ lvl, face_index, uv[0], uv[1], p1, 0);
+
+ if (height_data->ssdm) {
+ get_ccgdm_data(lores_dm, height_data->ssdm,
+ height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
+ 0, face_index, uv[0], uv[1], p0, n);
+ }
+ else {
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ if (mface.v4) {
+ interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+ interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+ }
+ else {
+ interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+ interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+ }
+ }
+
+ sub_v3_v3v3(vec, p1, p0);
+ len = dot_v3v3(n, vec);
+
+ height_data->heights[pixel] = len;
+ if (len < height_data->height_min) height_data->height_min = len;
+ if (len > height_data->height_max) height_data->height_max = len;
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + pixel * 4;
+ rrgb[3] = 255;
+ }
+}
+
+/* **************** Normal Maps Baker **************** */
+
+static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+{
+ MNormalBakeData *normal_data;
+ DerivedMesh *lodm = bkr->lores_dm;
+
+ normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
+
+ normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+ normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+
+ return (void *)normal_data;
+}
+
+static void free_normal_data(void *bake_data)
+{
+ MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
+
+ MEM_freeN(normal_data);
+}
+
+/* MultiresBake callback for normals' baking
+ * general idea:
+ * - find coord and normal of point with specified UV in hi-res mesh
+ * - multiply it by tangmat
+ * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
+static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
+ float tangmat[3][3], const int x, const int y)
+{
+ MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+ MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
+ float uv[2], *st0, *st1, *st2, *st3;
+ int pixel = ibuf->x * y + x;
+ float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
+
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ st0 = mtface[face_index].uv[0];
+ st1 = mtface[face_index].uv[1];
+ st2 = mtface[face_index].uv[2];
+
+ if (mface.v4) {
+ st3 = mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ }
+ else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm,
+ normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig,
+ lvl, face_index, uv[0], uv[1], NULL, n);
+
+ mul_v3_m3v3(vec, tangmat, n);
+ normalize_v3(vec);
+ mul_v3_fl(vec, 0.5);
+ add_v3_v3(vec, tmp);
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[0] = vec[0];
+ rrgbf[1] = vec[1];
+ rrgbf[2] = vec[2];
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
+ rgb_float_to_uchar(rrgb, vec);
+ rrgb[3] = 255;
+ }
+}
+
+/* **************** Ambient Occlusion Baker **************** */
+
+// must be a power of two
+#define MAX_NUMBER_OF_AO_RAYS 1024
+
+static unsigned short ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
+static unsigned short ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
+
+static void init_ao_random(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUMBER_OF_AO_RAYS; i++) {
+ ao_random_table_1[i] = rand() & 0xffff;
+ ao_random_table_2[i] = rand() & 0xffff;
+ }
+}
+
+static unsigned short get_ao_random1(const int i)
+{
+ return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
+}
+
+static unsigned short get_ao_random2(const int i)
+{
+ return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
+}
+
+static void build_permutation_table(unsigned short permutation[], unsigned short temp_permutation[],
+ const int number_of_rays, const int is_first_perm_table)
+{
+ int i, k;
+
+ for (i = 0; i < number_of_rays; i++)
+ temp_permutation[i] = i;
+
+ for (i = 0; i < number_of_rays; i++) {
+ const unsigned int nr_entries_left = number_of_rays - i;
+ unsigned short rnd = is_first_perm_table != FALSE ? get_ao_random1(i) : get_ao_random2(i);
+ const unsigned short entry = rnd % nr_entries_left;
+
+ /* pull entry */
+ permutation[i] = temp_permutation[entry];
+
+ /* delete entry */
+ for(k = entry; k < nr_entries_left - 1; k++)
+ temp_permutation[k] = temp_permutation[k + 1];
+ }
+
+ /* verify permutation table
+ * every entry must appear exactly once
+ */
+#if 0
+ for(i = 0; i < number_of_rays; i++) temp_permutation[i] = 0;
+ for(i = 0; i < number_of_rays; i++) ++temp_permutation[permutation[i]];
+ for(i = 0; i < number_of_rays; i++) BLI_assert(temp_permutation[i] == 1);
+#endif
+}
+
+static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
+{
+ DerivedMesh *hidm = bkr->hires_dm;
+ RayObject *raytree;
+ RayFace *face;
+ CCGElem **grid_data;
+ CCGKey key;
+ int num_grids, grid_size /*, face_side */, num_faces;
+ int i;
+
+ num_grids = hidm->getNumGrids(hidm);
+ grid_size = hidm->getGridSize(hidm);
+ grid_data = hidm->getGridData(hidm);
+ hidm->getGridKey(hidm, &key);
+
+ /* face_side = (grid_size << 1) - 1; */ /* UNUSED */
+ num_faces = num_grids * (grid_size - 1) * (grid_size - 1);
+
+ raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution);
+ face = ao_data->rayfaces = (RayFace *) MEM_callocN(num_faces * sizeof(RayFace), "ObjectRen faces");
+
+ for (i = 0; i < num_grids; i++) {
+ int x, y;
+ for (x = 0; x < grid_size - 1; x++) {
+ for (y = 0; y < grid_size - 1; y++) {
+ float co[4][3];
+
+ copy_v3_v3(co[0], CCG_grid_elem_co(&key, grid_data[i], x, y));
+ copy_v3_v3(co[1], CCG_grid_elem_co(&key, grid_data[i], x, y + 1));
+ copy_v3_v3(co[2], CCG_grid_elem_co(&key, grid_data[i], x + 1, y + 1));
+ copy_v3_v3(co[3], CCG_grid_elem_co(&key, grid_data[i], x + 1, y));
+
+ RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]);
+ RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
+
+ face++;
+ }
+ }
+ }
+
+ RE_rayobject_done(raytree);
+}
+
+static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+{
+ MAOBakeData *ao_data;
+ DerivedMesh *lodm = bkr->lores_dm;
+ unsigned short *temp_permutation_table;
+ size_t permutation_size;
+
+ init_ao_random();
+
+ ao_data = MEM_callocN(sizeof(MAOBakeData), "MultiresBake aoData");
+
+ ao_data->number_of_rays = bkr->number_of_rays;
+ ao_data->bias = bkr->bias;
+
+ ao_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
+ ao_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+
+ create_ao_raytree(bkr, ao_data);
+
+ /* initialize permutation tables */
+ permutation_size = sizeof(unsigned short) * bkr->number_of_rays;
+ ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1");
+ ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2");
+ temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm");
+
+ build_permutation_table(ao_data->permutation_table_1, temp_permutation_table, bkr->number_of_rays, 1);
+ build_permutation_table(ao_data->permutation_table_2, temp_permutation_table, bkr->number_of_rays, 0);
+
+ MEM_freeN(temp_permutation_table);
+
+ return (void *)ao_data;
+}
+
+static void free_ao_data(void *bake_data)
+{
+ MAOBakeData *ao_data = (MAOBakeData *) bake_data;
+
+ RE_rayobject_free(ao_data->raytree);
+ MEM_freeN(ao_data->rayfaces);
+
+ MEM_freeN(ao_data->permutation_table_1);
+ MEM_freeN(ao_data->permutation_table_2);
+
+ MEM_freeN(ao_data);
+}
+
+/* builds an X and a Y axis from the given Z axis */
+static void build_coordinate_frame(float axisX[3], float axisY[3], const float axisZ[3])
+{
+ const float faX = fabsf(axisZ[0]);
+ const float faY = fabsf(axisZ[1]);
+ const float faZ = fabsf(axisZ[2]);
+
+ if (faX <= faY && faX <= faZ) {
+ const float len = sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]);
+ axisY[0] = 0; axisY[1] = axisZ[2] / len; axisY[2] = -axisZ[1] / len;
+ cross_v3_v3v3(axisX, axisY, axisZ);
+ }
+ else if (faY <= faZ) {
+ const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]);
+ axisX[0] = axisZ[2] / len; axisX[1] = 0; axisX[2] = -axisZ[0] / len;
+ cross_v3_v3v3(axisY, axisZ, axisX);
+ }
+ else {
+ const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]);
+ axisX[0] = axisZ[1] / len; axisX[1] = -axisZ[0] / len; axisX[2] = 0;
+ cross_v3_v3v3(axisY, axisZ, axisX);
+ }
+}
+
+/* return FALSE if nothing was hit and TRUE otherwise */
+static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_direction[3])
+{
+ Isect isect = {{0}};
+
+ isect.dist = RE_RAYTRACE_MAXDIST;
+ copy_v3_v3(isect.start, ray_start);
+ copy_v3_v3(isect.dir, ray_direction);
+ isect.lay = -1;
+
+ normalize_v3(isect.dir);
+
+ return RE_rayobject_raycast(ao_data->raytree, &isect);
+}
+
+static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
+ float UNUSED(tangmat[3][3]), const int x, const int y)
+{
+ MAOBakeData *ao_data = (MAOBakeData *) bake_data;
+ MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+
+ int i, k, perm_offs;
+ float pos[3], nrm[3];
+ float cen[3];
+ float axisX[3], axisY[3], axisZ[3];
+ float shadow = 0;
+ float value;
+ int pixel = ibuf->x * y + x;
+ float uv[2], *st0, *st1, *st2, *st3;
+
+ lores_dm->getTessFace(lores_dm, face_index, &mface);
+
+ st0 = mtface[face_index].uv[0];
+ st1 = mtface[face_index].uv[1];
+ st2 = mtface[face_index].uv[2];
+
+ if (mface.v4) {
+ st3 = mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ }
+ else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm,
+ ao_data->orig_index_mf_to_mpoly, ao_data->orig_index_mp_to_orig,
+ lvl, face_index, uv[0], uv[1], pos, nrm);
+
+ /* offset ray origin by user bias along normal */
+ for (i = 0; i < 3; i++)
+ cen[i] = pos[i] + ao_data->bias * nrm[i];
+
+ /* build tangent frame */
+ for (i = 0; i < 3; i++)
+ axisZ[i] = nrm[i];
+
+ build_coordinate_frame(axisX, axisY, axisZ);
+
+ /* static noise */
+ perm_offs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1);
+
+ /* importance sample shadow rays (cosine weighted) */
+ for (i = 0; i < ao_data->number_of_rays; i++) {
+ int hit_something;
+
+ /* use N-Rooks to distribute our N ray samples across
+ * a multi-dimensional domain (2D)
+ */
+ const unsigned short I = ao_data->permutation_table_1[(i + perm_offs) % ao_data->number_of_rays];
+ const unsigned short J = ao_data->permutation_table_2[i];
+
+ const float JitPh = (get_ao_random2(I + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS);
+ const float JitTh = (get_ao_random1(J + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS);
+ const float SiSqPhi = (I + JitPh) / ao_data->number_of_rays;
+ const float Theta = (float)(2 * M_PI) * ((J + JitTh) / ao_data->number_of_rays);
+
+ /* this gives results identical to the so-called cosine
+ * weighted distribution relative to the north pole.
+ */
+ float SiPhi = sqrt(SiSqPhi);
+ float CoPhi = SiSqPhi < 1.0f ? sqrtf(1.0f - SiSqPhi) : 0;
+ float CoThe = cos(Theta);
+ float SiThe = sin(Theta);
+
+ const float dx = CoThe * CoPhi;
+ const float dy = SiThe * CoPhi;
+ const float dz = SiPhi;
+
+ /* transform ray direction out of tangent frame */
+ float dv[3];
+ for (k = 0; k < 3; k++)
+ dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz;
+
+ hit_something = trace_ao_ray(ao_data, cen, dv);
+
+ if (hit_something != 0)
+ shadow += 1;
+ }
+
+ value = 1.0f - (shadow / ao_data->number_of_rays);
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[0] = rrgbf[1] = rrgbf[2] = value;
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ unsigned char *rrgb = (unsigned char *) ibuf->rect + pixel * 4;
+ rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(value);
+ rrgb[3] = 255;
+ }
+}
+
+/* **************** Common functions public API relates on **************** */
+
+static void count_images(MultiresBakeRender *bkr)
+{
+ int a, totface;
+ DerivedMesh *dm = bkr->lores_dm;
+ MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+ bkr->image.first = bkr->image.last = NULL;
+ bkr->tot_image = 0;
+
+ totface = dm->getNumTessFaces(dm);
+
+ for (a = 0; a < totface; a++)
+ mtface[a].tpage->id.flag &= ~LIB_DOIT;
+
+ for (a = 0; a < totface; a++) {
+ Image *ima = mtface[a].tpage;
+ if ((ima->id.flag & LIB_DOIT) == 0) {
+ LinkData *data = BLI_genericNodeN(ima);
+ BLI_addtail(&bkr->image, data);
+ bkr->tot_image++;
+ ima->id.flag |= LIB_DOIT;
+ }
+ }
+
+ for (a = 0; a < totface; a++)
+ mtface[a].tpage->id.flag &= ~LIB_DOIT;
+}
+
+static void bake_images(MultiresBakeRender *bkr)
+{
+ LinkData *link;
+
+ for (link = bkr->image.first; link; link = link->next) {
+ Image *ima = (Image *)link->data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
+ if (ibuf->x > 0 && ibuf->y > 0) {
+ ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
+
+ switch (bkr->mode) {
+ case RE_BAKE_NORMALS:
+ do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
+ break;
+ case RE_BAKE_DISPLACEMENT:
+ do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data,
+ apply_heights_data, free_heights_data);
+ break;
+ case RE_BAKE_AO:
+ do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, NULL, free_ao_data);
+ break;
+ }
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ ima->id.flag |= LIB_DOIT;
+ }
+}
+
+static void finish_images(MultiresBakeRender *bkr)
+{
+ LinkData *link;
+
+ for (link = bkr->image.first; link; link = link->next) {
+ Image *ima = (Image *)link->data;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
+ if (ibuf->x <= 0 || ibuf->y <= 0)
+ continue;
+
+ RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
+
+ ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
+
+ if (ibuf->rect_float)
+ ibuf->userflags |= IB_RECT_INVALID;
+
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ imb_freemipmapImBuf(ibuf);
+ }
+
+ if (ibuf->userdata) {
+ MEM_freeN(ibuf->userdata);
+ ibuf->userdata = NULL;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+}
+
+void RE_multires_bake_images(MultiresBakeRender *bkr)
+{
+ count_images(bkr);
+ bake_images(bkr);
+ finish_images(bkr);
+}
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index a730882..747362a 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -1520,8 +1520,8 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
return 0;
/* require intensities not being too different */
- mino = MIN4(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
- maxo = MAX4(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+ mino = min_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+ maxo = max_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
if (maxo - mino > 0.05f)
return 0;
@@ -1793,9 +1793,9 @@ void sample_occ(Render *re, ShadeInput *shi)
copy_v3_v3(sample->ao, shi->ao);
copy_v3_v3(sample->env, shi->env);
copy_v3_v3(sample->indirect, shi->indirect);
- sample->intensity = MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
- sample->intensity = MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2]));
- sample->intensity = MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
+ sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2]));
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco);
sample->filled = 1;
}
@@ -1888,9 +1888,9 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
copy_v3_v3(sample->ao, shi->ao);
copy_v3_v3(sample->env, shi->env);
copy_v3_v3(sample->indirect, shi->indirect);
- sample->intensity = MAX3(sample->ao[0], sample->ao[1], sample->ao[2]);
- sample->intensity = MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2]));
- sample->intensity = MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
+ sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2]));
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco);
sample->x = shi->xs;
sample->y = shi->ys;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index f241e0e..dec11f0 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -45,6 +45,16 @@
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_rect.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
+#include "BLI_threads.h"
+#include "BLI_rand.h"
+#include "BLI_callbacks.h"
+
#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "BKE_camera.h"
#include "BKE_global.h"
@@ -57,16 +67,6 @@
#include "BKE_sequencer.h"
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
-#include "BLI_math.h"
-#include "BLI_rect.h"
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-#include "BLI_path_util.h"
-#include "BLI_fileops.h"
-#include "BLI_threads.h"
-#include "BLI_rand.h"
-#include "BLI_callbacks.h"
-
#include "PIL_time.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -336,7 +336,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
RenderResult rres;
RE_AcquireResultImage(re, &rres);
- render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
+ render_result_rect_get_pixels(&rres, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
RE_ReleaseResultImage(re);
}
@@ -582,7 +582,7 @@ void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend)
re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend);
}
-void RE_SetView(Render *re, float mat[][4])
+void RE_SetView(Render *re, float mat[4][4])
{
/* re->ok flag? */
copy_m4_m4(re->viewmat, mat);
@@ -655,7 +655,9 @@ static int render_display_draw_enabled(Render *re)
static void *do_part_thread(void *pa_v)
{
RenderPart *pa = pa_v;
-
+
+ pa->status = PART_STATUS_IN_PROGRESS;
+
/* need to return nicely all parts on esc */
if (R.test_break(R.tbh) == 0) {
@@ -686,7 +688,7 @@ static void *do_part_thread(void *pa_v)
}
}
- pa->ready = 1;
+ pa->status = PART_STATUS_READY;
return NULL;
}
@@ -727,7 +729,7 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
/* most left part of the non-rendering parts */
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready == 0 && pa->nr == 0) {
+ if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
if (pa->disprect.xmin < *minx) {
best = pa;
*minx = pa->disprect.xmin;
@@ -765,7 +767,7 @@ static RenderPart *find_next_part(Render *re, int minx)
/* find center of rendered parts, image center counts for 1 too */
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready) {
+ if (pa->status == PART_STATUS_READY) {
centx += BLI_rcti_cent_x(&pa->disprect);
centy += BLI_rcti_cent_y(&pa->disprect);
tot++;
@@ -776,7 +778,7 @@ static RenderPart *find_next_part(Render *re, int minx)
/* closest of the non-rendering parts */
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready == 0 && pa->nr == 0) {
+ if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
long long int distx = centx - BLI_rcti_cent_x(&pa->disprect);
long long int disty = centy - BLI_rcti_cent_y(&pa->disprect);
distx = (long long int)sqrt(distx * distx + disty * disty);
@@ -833,7 +835,7 @@ static void threaded_tile_processor(Render *re)
if (re->result == NULL)
return;
-
+
/* warning; no return here without closing exr file */
RE_parts_init(re, TRUE);
@@ -884,7 +886,7 @@ static void threaded_tile_processor(Render *re)
rendering = 0;
hasdrawn = 0;
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready) {
+ if (pa->status == PART_STATUS_READY) {
BLI_remove_thread(&threads, pa);
@@ -1092,7 +1094,7 @@ static void do_render_blur_3d(Render *re)
blurfac = 1.0f / (float)(re->r.mblur_samples - blur);
- merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY);
+ merge_renderresult_blur(rres, re->result, blurfac, FALSE);
if (re->test_break(re->tbh)) break;
}
@@ -1237,7 +1239,7 @@ static void do_render_fields_blur_3d(Render *re)
Object *camera = RE_GetCamera(re);
/* also check for camera here */
if (camera == NULL) {
- printf("ERROR: Cannot render, no camera\n");
+ BKE_report(re->reports, RPT_ERROR, "Cannot render, no camera");
G.is_break = TRUE;
return;
}
@@ -2117,7 +2119,7 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
}
else {
char name[FILE_MAX];
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, FALSE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, FALSE);
/* reports only used for Movie */
do_write_image_or_movie(re, bmain, scene, NULL, name);
@@ -2176,7 +2178,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
if (name_override)
BLI_strncpy(name, name_override, sizeof(name));
else
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if (re->r.im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
if (re->result) {
@@ -2204,7 +2206,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
if (BLI_testextensie(name, ".exr"))
name[strlen(name) - 4] = 0;
- BKE_add_image_extension(name, R_IMF_IMTYPE_JPEG90);
+ BKE_add_image_extension(name, &imf);
ibuf->planes = 24;
IMB_colormanagement_imbuf_for_write(ibuf, TRUE, FALSE, &scene->view_settings,
@@ -2309,7 +2311,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* Touch/NoOverwrite options are only valid for image's */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, scene->r.im_format.imtype, scene->r.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if (scene->r.mode & R_NO_OVERWRITE && BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index 74de8a1..21ff115 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -206,7 +206,7 @@ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int ro
}
-void mask_array(unsigned int mask, float filt[][3])
+void mask_array(unsigned int mask, float filt[3][3])
{
float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2;
unsigned int maskand = (mask & 255);
@@ -244,7 +244,7 @@ void mask_array(unsigned int mask, float filt[][3])
* </pre>
*/
-void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y)
+void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y)
{
float *fpoin[3][3];
float val, r, g, b, al, lfilt[3][3];
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 127e0bc..bef5902 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -81,7 +81,7 @@ extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
static int test_break(void *data)
{
- Render *re = (Render*)data;
+ Render *re = (Render *)data;
return re->test_break(re->tbh);
}
@@ -94,7 +94,7 @@ static void RE_rayobject_config_control(RayObject *r, Render *re)
}
}
-static RayObject* RE_rayobject_create(Render *re, int type, int size)
+RayObject *RE_rayobject_create(int type, int size, int octree_resolution)
{
RayObject * res = NULL;
@@ -117,7 +117,7 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size)
if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres
- res = RE_rayobject_octree_create(re->r.ocres, size);
+ res = RE_rayobject_octree_create(octree_resolution, size);
else if (type == R_RAYSTRUCTURE_BLIBVH)
res = RE_rayobject_blibvh_create(size);
else if (type == R_RAYSTRUCTURE_VBVH)
@@ -129,10 +129,18 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size)
else
res = RE_rayobject_vbvh_create(size); //Fallback
+ return res;
+}
+
+static RayObject* rayobject_create(Render *re, int type, int size)
+{
+ RayObject * res = NULL;
+
+ res = RE_rayobject_create(type, size, re->r.ocres);
if (res)
RE_rayobject_config_control(res, re);
-
+
return res;
}
@@ -240,11 +248,11 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
return NULL;
//Create Ray cast accelaration structure
- raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces );
+ raytree = rayobject_create( re, re->r.raytrace_structure, faces );
if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
- vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
+ vlakprimitive = obr->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "ObjectRen primitives");
else
- face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
+ face = obr->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "ObjectRen faces");
obr->rayobi = obi;
@@ -334,13 +342,13 @@ static void makeraytree_single(Render *re)
}
//Create raytree
- raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special );
+ raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special );
if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) {
- vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives");
+ vlakprimitive = re->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "Raytrace vlak-primitives");
}
else {
- face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
+ face = re->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "Render ray faces");
}
for (obi=re->instancetable.first; obi; obi=obi->next)
@@ -488,8 +496,8 @@ static void shade_ray_set_derivative(ShadeInput *shi)
void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
{
- ObjectInstanceRen *obi= (ObjectInstanceRen*)is->hit.ob;
- VlakRen *vlr= (VlakRen*)is->hit.face;
+ ObjectInstanceRen *obi = (ObjectInstanceRen *)is->hit.ob;
+ VlakRen *vlr = (VlakRen *)is->hit.face;
/* set up view vector */
copy_v3_v3(shi->view, is->dir);
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index f828158..35b0638 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -35,11 +35,6 @@
#include "MEM_guardedalloc.h"
-#include "BKE_image.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_report.h"
-
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
@@ -48,6 +43,11 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BKE_image.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
@@ -434,7 +434,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop;
/* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
rr->crop = crop;
-
+
/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
@@ -924,7 +924,7 @@ static void save_empty_result_tiles(Render *re)
IMB_exrtile_clear_channels(rl->exrhandle);
for (pa = re->parts.first; pa; pa = pa->next) {
- if (pa->ready == 0) {
+ if (pa->status != PART_STATUS_READY) {
int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
@@ -1077,8 +1077,7 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
{
- int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) ? IB_cm_predivide : 0;
- ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
+ ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, 0);
/* if not exists, BKE_imbuf_write makes one */
ibuf->rect = (unsigned int *)rr->rect32;
@@ -1148,17 +1147,15 @@ void render_result_rect_fill_zero(RenderResult *rr)
rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
}
-void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty,
+void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rectx, int recty,
const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
{
if (rr->rect32) {
memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
}
else if (rr->rectf) {
- int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
-
IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4,
- view_settings, display_settings, predivide);
+ view_settings, display_settings, TRUE);
}
else
/* else fill with black */
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index e6daa5f..e3bfd53 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1339,7 +1339,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_MUL:
fact*= facg;
- facm= 1.0f-facg;
+ facm= 1.0f-fact;
in[0]= (facm+fact*tex[0])*out[0];
in[1]= (facm+fact*tex[1])*out[1];
in[2]= (facm+fact*tex[2])*out[2];
@@ -1347,7 +1347,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_SCREEN:
fact*= facg;
- facm= 1.0f-facg;
+ facm= 1.0f-fact;
in[0]= 1.0f - (facm+fact*(1.0f-tex[0])) * (1.0f-out[0]);
in[1]= 1.0f - (facm+fact*(1.0f-tex[1])) * (1.0f-out[1]);
in[2]= 1.0f - (facm+fact*(1.0f-tex[2])) * (1.0f-out[2]);
@@ -1355,7 +1355,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_OVERLAY:
fact*= facg;
- facm= 1.0f-facg;
+ facm= 1.0f-fact;
if (out[0] < 0.5f)
in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
@@ -1745,8 +1745,8 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
else { /* 3d procedural, estimate from all dx/dy elems */
const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
- du = MAX3(adx[0], adx[1], adx[2]);
- dv = MAX3(ady[0], ady[1], ady[2]);
+ du = max_fff(adx[0], adx[1], adx[2]);
+ dv = max_fff(ady[0], ady[1], ady[2]);
}
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 3431c3f..14586f1 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -20,6 +20,7 @@
*
* Contributors: Hos, Robert Wenzlaff.
* Contributors: 2004/2005/2006 Blender Foundation, full recode
+ * Contributors: Vertex color baking, Copyright 2011 AutoCRC
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -51,9 +52,12 @@
#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_group_types.h"
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -710,9 +714,11 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
if (pass[3]==0.0f) {
copy_v4_v4(pass, col);
+ pass[3] = 1.0f;
}
else {
addAlphaUnderFloat(pass, col);
+ pass[3] = 1.0f;
}
}
}
@@ -981,29 +987,6 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
}
}
-static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
-{
- RenderLayer *rlpp[RE_MAX_OSA];
- int y, sample, totsample;
-
- totsample= get_sample_layers(pa, rl, rlpp);
-
- for (sample= 0; sample<totsample; sample++) {
- float *rectf= rlpp[sample]->rectf;
-
- for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
- if (rectf[3] >= 1.0f) {
- /* pass */
- }
- else if (rectf[3] > 0.0f) {
- rectf[0] /= rectf[3];
- rectf[1] /= rectf[3];
- rectf[2] /= rectf[3];
- }
- }
- }
-}
-
/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
{
@@ -1172,7 +1155,7 @@ typedef struct ZbufSolidData {
static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
{
- ZbufSolidData *sdata= (ZbufSolidData*)data;
+ ZbufSolidData *sdata = (ZbufSolidData *)data;
ListBase *lb= sdata->psmlist;
intptr_t *rd= pa->rectdaps;
int *ro= zspan->recto;
@@ -1312,10 +1295,6 @@ void zbufshadeDA_tile(RenderPart *pa)
/* clamp alpha to 0..1 range, can go outside due to filter */
clamp_alpha_rgb_range(pa, rl);
- /* de-premul alpha */
- if (R.r.alphamode & R_ALPHAKEY)
- convert_to_key_alpha(pa, rl);
-
/* free stuff within loop! */
MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
freeps(&psmlist);
@@ -1476,10 +1455,6 @@ void zbufshade_tile(RenderPart *pa)
if (rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
- /* de-premul alpha */
- if (R.r.alphamode & R_ALPHAKEY)
- convert_to_key_alpha(pa, rl);
-
if (edgerect) MEM_freeN(edgerect);
edgerect= NULL;
@@ -1740,7 +1715,7 @@ void zbufshade_sss_tile(RenderPart *pa)
#if 0
if (rs) {
/* for each sample in this pixel, shade it */
- for (ps=(PixStr*)*rs; ps; ps=ps->next) {
+ for (ps = (PixStr *)(*rs); ps; ps=ps->next) {
ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
ObjectRen *obr= obi->obr;
vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
@@ -2032,6 +2007,12 @@ typedef struct BakeShade {
float dir[3];
Object *actob;
+
+ /* Output: vertex color or image data. If vcol is not NULL, rect and
+ * rect_float should be NULL. */
+ MPoly *mpoly;
+ MLoop *mloop;
+ MLoopCol *vcol;
unsigned int *rect;
float *rect_float;
@@ -2208,7 +2189,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
}
}
- if (bs->rect_float) {
+ if (bs->rect_float && !bs->vcol) {
float *col= bs->rect_float + 4*(bs->rectx*y + x);
copy_v3_v3(col, shr.combined);
if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
@@ -2219,7 +2200,8 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
}
}
else {
- unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x);
+ /* Target is char (LDR). */
+ unsigned char col[4];
if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
float rgb[3];
@@ -2239,6 +2221,19 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
else {
col[3]= 255;
}
+
+ if (bs->vcol) {
+ /* Vertex colour baking. Vcol has no useful alpha channel (it exists
+ * but is used only for vertex painting). */
+ bs->vcol->r = col[0];
+ bs->vcol->g = col[1];
+ bs->vcol->b = col[2];
+ }
+ else {
+ unsigned char *imcol= (unsigned char *)(bs->rect + bs->rectx*y + x);
+ copy_v4_v4_char((char *)imcol, (char *)col);
+ }
+
}
if (bs->rect_mask) {
@@ -2258,15 +2253,28 @@ static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist,
disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
}
- if (bs->rect_float) {
+ if (bs->rect_float && !bs->vcol) {
float *col= bs->rect_float + 4*(bs->rectx*y + x);
col[0] = col[1] = col[2] = disp;
col[3]= 1.0f;
}
else {
- char *col= (char *)(bs->rect + bs->rectx*y + x);
+ /* Target is char (LDR). */
+ unsigned char col[4];
col[0] = col[1] = col[2] = FTOCHAR(disp);
- col[3]= 255;
+ col[3] = 255;
+
+ if(bs->vcol) {
+ /* Vertex colour baking. Vcol has no useful alpha channel (it exists
+ * but is used only for vertex painting). */
+ bs->vcol->r = col[0];
+ bs->vcol->g = col[1];
+ bs->vcol->b = col[2];
+ }
+ else {
+ char *imcol= (char *)(bs->rect + bs->rectx*y + x);
+ copy_v4_v4_char((char *)imcol, (char *)col);
+ }
}
if (bs->rect_mask) {
bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
@@ -2461,8 +2469,8 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
/* if hit, we shade from the new point, otherwise from point one starting face */
if (hit) {
- obi= (ObjectInstanceRen*)minisec.hit.ob;
- vlr= (VlakRen*)minisec.hit.face;
+ obi = (ObjectInstanceRen *)minisec.hit.ob;
+ vlr = (VlakRen *)minisec.hit.face;
quad= (minisec.isect == 2);
copy_v3_v3(shi->co, minco);
@@ -2502,13 +2510,55 @@ static int get_next_bake_face(BakeShade *bs)
vlr= RE_findOrAddVlak(obr, v);
if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
- tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+ if(R.r.bake_flag & R_BAKE_VCOL) {
+ /* Gather face data for vertex colour bake */
+ Mesh *me;
+ int *origindex, vcollayer;
+ CustomDataLayer *cdl;
+
+ if(obr->ob->type != OB_MESH)
+ continue;
+ me = obr->ob->data;
+
+ origindex = RE_vlakren_get_origindex(obr, vlr, 0);
+ if(origindex == NULL)
+ continue;
+ if (*origindex >= me->totpoly) {
+ /* Small hack for Array modifier, which gives false
+ original indices - z0r */
+ continue;
+ }
+#if 0
+ /* Only shade selected faces. */
+ if((me->mface[*origindex].flag & ME_FACE_SEL) == 0)
+ continue;
+#endif
- if (tface && tface->tpage) {
- Image *ima= tface->tpage;
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
+ vcollayer = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL);
+ if(vcollayer == -1)
+ continue;
+
+ cdl = &me->ldata.layers[vcollayer];
+ bs->mpoly = me->mpoly + *origindex;
+ bs->vcol = ((MLoopCol*)cdl->data) + bs->mpoly->loopstart;
+ bs->mloop = me->mloop + bs->mpoly->loopstart;
+
+ /* Tag mesh for reevaluation. */
+ DAG_id_tag_update(&me->id, 0);
+ }
+ else {
+ Image *ima = NULL;
+ ImBuf *ibuf = NULL;
const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
+
+ tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+
+ if (!tface || !tface->tpage)
+ continue;
+
+ ima = tface->tpage;
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf==NULL)
continue;
@@ -2544,20 +2594,17 @@ static int get_next_bake_face(BakeShade *bs)
R.bakebuf= ima;
}
+ /* Tag image for redraw. */
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- bs->obi= obi;
- bs->vlr= vlr;
-
- bs->vdone++; /* only for error message if nothing was rendered */
- v++;
-
- BLI_unlock_thread(LOCK_CUSTOM1);
-
BKE_image_release_ibuf(ima, ibuf, NULL);
-
- return 1;
}
+
+ bs->obi = obi;
+ bs->vlr = vlr;
+ bs->vdone++; /* only for error message if nothing was rendered */
+ v++;
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return 1;
}
}
}
@@ -2566,6 +2613,73 @@ static int get_next_bake_face(BakeShade *bs)
return 0;
}
+static void bake_single_vertex(BakeShade *bs, VertRen *vert, float u, float v)
+{
+ int *origindex, i;
+ MLoopCol *basevcol;
+ MLoop *mloop;
+
+ origindex = RE_vertren_get_origindex(bs->obi->obr, vert, 0);
+ if (!origindex || *origindex == ORIGINDEX_NONE)
+ return;
+
+ /* Search for matching vertex index and apply shading. */
+ for (i = 0; i < bs->mpoly->totloop; i++) {
+ mloop = bs->mloop + i;
+ if (mloop->v != *origindex)
+ continue;
+ basevcol = bs->vcol;
+ bs->vcol = basevcol + i;
+ do_bake_shade(bs, 0, 0, u, v);
+ bs->vcol = basevcol;
+ break;
+ }
+}
+
+/* Bake all vertices of a face. Actually, this still works on a face-by-face
+ basis, and each vertex on each face is shaded. Vertex colors are a property
+ of loops, not vertices. */
+static void shade_verts(BakeShade *bs)
+{
+ VlakRen *vlr = bs->vlr;
+
+ /* Disable baking to image; write to vcol instead. vcol pointer is set in
+ * bake_single_vertex. */
+ bs->ima = NULL;
+ bs->rect = NULL;
+ bs->rect_float = NULL;
+
+ bs->quad = 0;
+
+ /* No anti-aliasing for vertices. */
+ zero_v3(bs->dxco);
+ zero_v3(bs->dyco);
+
+ /* Shade each vertex of the face. u and v are barycentric coordinates; since
+ we're only interested in vertices, these will be 0 or 1. */
+ if ((vlr->flag & R_FACE_SPLIT) == 0) {
+ /* Processing triangle face, whole quad, or first half of split quad. */
+
+ bake_single_vertex(bs, bs->vlr->v1, 1.0f, 0.0f);
+ bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
+ bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
+
+ if (vlr->v4) {
+ bs->quad = 1;
+ bake_single_vertex(bs, bs->vlr->v4, 0.0f, 0.0f);
+ }
+ }
+ else {
+ /* Processing second half of split quad. Only one vertex to go. */
+ if (vlr->flag & R_DIVIDE_24) {
+ bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
+ }
+ else {
+ bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
+ }
+ }
+}
+
/* already have tested for tface and ima and zspan */
static void shade_tface(BakeShade *bs)
{
@@ -2593,6 +2707,7 @@ static void shade_tface(BakeShade *bs)
bs->rect= bs->ibuf->rect;
bs->rect_colorspace= bs->ibuf->rect_colorspace;
bs->rect_float= bs->ibuf->rect_float;
+ bs->vcol = NULL;
bs->quad= 0;
if (bs->use_mask) {
@@ -2636,7 +2751,10 @@ static void *do_bake_thread(void *bs_v)
BakeShade *bs= bs_v;
while (get_next_bake_face(bs)) {
- shade_tface(bs);
+ if (R.r.bake_flag & R_BAKE_VCOL)
+ shade_verts(bs);
+ else
+ shade_tface(bs);
/* fast threadsafe break test */
if (R.test_break(R.tbh))
@@ -2700,14 +2818,16 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
use_mask = TRUE;
/* baker uses this flag to detect if image was initialized */
- for (ima= G.main->image.first; ima; ima= ima->id.next) {
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
- ima->id.flag |= LIB_DOIT;
- ima->flag&= ~IMA_USED_FOR_RENDER;
- if (ibuf) {
- ibuf->userdata = NULL; /* use for masking if needed */
+ if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
+ for (ima = G.main->image.first; ima; ima = ima->id.next) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ ima->id.flag |= LIB_DOIT;
+ ima->flag &= ~IMA_USED_FOR_RENDER;
+ if (ibuf) {
+ ibuf->userdata = NULL; /* use for masking if needed */
+ }
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
- BKE_image_release_ibuf(ima, ibuf, NULL);
}
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
@@ -2731,7 +2851,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
handles[a].type= type;
handles[a].actob= actob;
- handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
+ if (R.r.bake_flag & R_BAKE_VCOL)
+ handles[a].zspan = NULL;
+ else
+ handles[a].zspan = MEM_callocN(sizeof(ZSpan), "zspan for bake");
handles[a].use_mask = use_mask;
@@ -2758,27 +2881,29 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
}
/* filter and refresh images */
- for (ima= G.main->image.first; ima; ima= ima->id.next) {
- if ((ima->id.flag & LIB_DOIT)==0) {
- ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
+ if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
+ for (ima = G.main->image.first; ima; ima = ima->id.next) {
+ if ((ima->id.flag & LIB_DOIT)==0) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- if (ima->flag & IMA_USED_FOR_RENDER)
- result= BAKE_RESULT_FEEDBACK_LOOP;
+ if (ima->flag & IMA_USED_FOR_RENDER)
+ result = BAKE_RESULT_FEEDBACK_LOOP;
- if (!ibuf)
- continue;
+ if (!ibuf)
+ continue;
- RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
+ RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
- ibuf->userflags |= IB_BITMAPDIRTY;
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ }
+
+ /* calculate return value */
+ for (a = 0; a < re->r.threads; a++) {
+ zbuf_free_span(handles[a].zspan);
+ MEM_freeN(handles[a].zspan);
}
- }
-
- /* calculate return value */
- for (a=0; a<re->r.threads; a++) {
- zbuf_free_span(handles[a].zspan);
- MEM_freeN(handles[a].zspan);
}
MEM_freeN(handles);
@@ -2795,4 +2920,3 @@ struct Image *RE_bake_shade_get_image(void)
{
return R.bakebuf;
}
-
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 44daaf5..7ca4f01 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -105,6 +105,8 @@
#define RE_MTFACE_ELEMS 1
#define RE_MCOL_ELEMS 4
#define RE_UV_ELEMS 2
+#define RE_VLAK_ORIGINDEX_ELEMS 1
+#define RE_VERT_ORIGINDEX_ELEMS 1
#define RE_SURFNOR_ELEMS 3
#define RE_RADFACE_ELEMS 1
#define RE_SIMPLIFY_ELEMS 2
@@ -192,10 +194,26 @@ float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
return winspeed + ver->index*RE_WINSPEED_ELEMS;
}
+int *RE_vertren_get_origindex(ObjectRen *obr, VertRen *ver, int verify)
+{
+ int *origindex;
+ int nr= ver->index>>8;
+
+ origindex= obr->vertnodes[nr].origindex;
+ if (origindex==NULL) {
+ if (verify)
+ origindex= obr->vertnodes[nr].origindex= MEM_mallocN(256*RE_VERT_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
+ else
+ return NULL;
+ }
+ return origindex + (ver->index & 255)*RE_VERT_ORIGINDEX_ELEMS;
+}
+
VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
{
VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
float *fp1, *fp2;
+ int *int1, *int2;
int index= v1->index;
*v1= *ver;
@@ -221,6 +239,11 @@ VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
fp2= RE_vertren_get_tangent(obr, v1, 1);
memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
}
+ int1= RE_vertren_get_origindex(obr, ver, 0);
+ if (int1) {
+ int2= RE_vertren_get_origindex(obr, v1, 1);
+ memcpy(int2, int1, RE_VERT_ORIGINDEX_ELEMS*sizeof(int));
+ }
return v1;
}
@@ -332,6 +355,21 @@ MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int
return node->mcol + index*RE_MCOL_ELEMS;
}
+int *RE_vlakren_get_origindex(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ int *origindex;
+ int nr= vlak->index>>8;
+
+ origindex= obr->vlaknodes[nr].origindex;
+ if(origindex==NULL) {
+ if(verify)
+ origindex= obr->vlaknodes[nr].origindex= MEM_callocN(256*RE_VLAK_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
+ else
+ return NULL;
+ }
+ return origindex + (vlak->index & 255)*RE_VLAK_ORIGINDEX_ELEMS;
+}
+
float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
{
float *surfnor;
@@ -370,7 +408,7 @@ RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
radface= obr->vlaknodes[nr].radface;
if (radface==NULL) {
if (verify)
- radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
+ radface = obr->vlaknodes[nr].radface= MEM_callocN(256 * RE_RADFACE_ELEMS * sizeof(void *), "radface table");
else
return NULL;
}
@@ -383,6 +421,7 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
MTFace *mtface, *mtface1;
MCol *mcol, *mcol1;
float *surfnor, *surfnor1, *tangent, *tangent1;
+ int *origindex, *origindex1;
RadFace **radface, **radface1;
int i, index = vlr1->index;
char *name;
@@ -400,6 +439,13 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
}
+ origindex= RE_vlakren_get_origindex(obr, vlr, 0);
+ if(origindex) {
+ origindex1= RE_vlakren_get_origindex(obr, vlr1, 1);
+ /* Just an int, but memcpy for consistency. */
+ memcpy(origindex1, origindex, sizeof(int)*RE_VLAK_ORIGINDEX_ELEMS);
+ }
+
surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
if (surfnor) {
surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
@@ -725,6 +771,8 @@ void free_renderdata_vertnodes(VertTableNode *vertnodes)
MEM_freeN(vertnodes[a].stress);
if (vertnodes[a].winspeed)
MEM_freeN(vertnodes[a].winspeed);
+ if (vertnodes[a].origindex)
+ MEM_freeN(vertnodes[a].origindex);
}
MEM_freeN(vertnodes);
@@ -743,6 +791,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
MEM_freeN(vlaknodes[a].mtface);
if (vlaknodes[a].mcol)
MEM_freeN(vlaknodes[a].mcol);
+ if(vlaknodes[a].origindex)
+ MEM_freeN(vlaknodes[a].origindex);
if (vlaknodes[a].surfnor)
MEM_freeN(vlaknodes[a].surfnor);
if (vlaknodes[a].tangent)
@@ -888,9 +938,9 @@ HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
// TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
temp=obr->bloha;
- obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE), "Bloha");
- if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*));
- memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
+ obr->bloha = (HaloRen**)MEM_callocN(sizeof(void *) * (obr->blohalen + TABLEINITSIZE), "Bloha");
+ if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void *));
+ memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE * sizeof(void *));
obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
if (temp) MEM_freeN(temp);
}
@@ -1221,7 +1271,9 @@ static int panotestclip(Render *re, int do_pano, float v[4])
* - shadow buffering (shadbuf.c)
*/
-void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets))
+void project_renderdata(Render *re,
+ void (*projectfunc)(const float *, float mat[4][4], float *),
+ int do_pano, float xoffs, int UNUSED(do_buckets))
{
ObjectRen *obr;
HaloRen *har = NULL;
@@ -1308,7 +1360,7 @@ void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat
/* ------------------------------------------------------------------------- */
-ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay)
+ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[4][4], int lay)
{
ObjectInstanceRen *obi;
float mat3[3][3];
@@ -1363,7 +1415,7 @@ void RE_makeRenderInstances(Render *re)
re->instancetable= newlist;
}
-int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4])
+int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4])
{
float mat[4][4], vec[4];
int a, fl, flag = -1;
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index a7f6b40..87912f5 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -812,7 +812,7 @@ void makeshadowbuf(Render *re, LampRen *lar)
static void *do_shadow_thread(void *re_v)
{
- Render *re= (Render*)re_v;
+ Render *re = (Render *)re_v;
LampRen *lar;
do {
@@ -1302,7 +1302,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
ShadBuf *shb= lar->shb;
ShadSampleBuf *shsample;
float co[4], siz;
- float labda, labdao, labdax, labday, ldx, ldy;
+ float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy;
float zf, xf1, yf1, zf1, xf2, yf2, zf2;
float count, lightcount;
int x, y, z, xs1, ys1;
@@ -1336,68 +1336,68 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
if (xf1 != xf2) {
if (xf2-xf1 > 0.0f) {
- labdax= (xf1-xs1-1.0f)/(xf1-xf2);
+ lambda_x= (xf1-xs1-1.0f)/(xf1-xf2);
ldx= -shb->shadhalostep/(xf1-xf2);
dx= shb->shadhalostep;
}
else {
- labdax= (xf1-xs1)/(xf1-xf2);
+ lambda_x= (xf1-xs1)/(xf1-xf2);
ldx= shb->shadhalostep/(xf1-xf2);
dx= -shb->shadhalostep;
}
}
else {
- labdax= 1.0;
+ lambda_x= 1.0;
ldx= 0.0;
}
if (yf1 != yf2) {
if (yf2-yf1 > 0.0f) {
- labday= (yf1-ys1-1.0f)/(yf1-yf2);
+ lambda_y= (yf1-ys1-1.0f)/(yf1-yf2);
ldy= -shb->shadhalostep/(yf1-yf2);
dy= shb->shadhalostep;
}
else {
- labday= (yf1-ys1)/(yf1-yf2);
+ lambda_y= (yf1-ys1)/(yf1-yf2);
ldy= shb->shadhalostep/(yf1-yf2);
dy= -shb->shadhalostep;
}
}
else {
- labday= 1.0;
+ lambda_y= 1.0;
ldy= 0.0;
}
x= xs1;
y= ys1;
- labda= count= lightcount= 0.0;
+ lambda= count= lightcount= 0.0;
/* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */
while (1) {
- labdao= labda;
+ lambda_o= lambda;
- if (labdax==labday) {
- labdax+= ldx;
+ if (lambda_x==lambda_y) {
+ lambda_x+= ldx;
x+= dx;
- labday+= ldy;
+ lambda_y+= ldy;
y+= dy;
}
else {
- if (labdax<labday) {
- labdax+= ldx;
+ if (lambda_x<lambda_y) {
+ lambda_x+= ldx;
x+= dx;
}
else {
- labday+= ldy;
+ lambda_y+= ldy;
y+= dy;
}
}
- labda = min_ff(labdax, labday);
- if (labda==labdao || labda>=1.0f) break;
+ lambda = min_ff(lambda_x, lambda_y);
+ if (lambda==lambda_o || lambda>=1.0f) break;
- zf= zf1 + labda*(zf2-zf1);
+ zf= zf1 + lambda*(zf2-zf1);
count+= (float)shb->totbuf;
if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */
@@ -1686,21 +1686,21 @@ static int point_behind_strand(const float p[3], BSPFace *face)
return 1;
}
else {
- float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
+ float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
- if (labda > -face->radline_end && labda < 1.0f+face->radline_end) {
+ if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) {
/* hesse for dist: */
//dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len);
- pt[0]= labda*face->rc[0]+face->vec1[0];
- pt[1]= labda*face->rc[1]+face->vec1[1];
+ pt[0]= lambda*face->rc[0]+face->vec1[0];
+ pt[1]= lambda*face->rc[1]+face->vec1[1];
rc[0]= pt[0]-p[0];
rc[1]= pt[1]-p[1];
dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]);
if (dist < face->radline) {
- float zval= face->vec1[2] + labda*face->rc[2];
+ float zval= face->vec1[2] + lambda*face->rc[2];
if (p[2] > zval)
return 1;
}
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 597196f..2d26ebe 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -1884,7 +1884,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* note: shi->mode! */
if (shi->mode & MA_TRANSP && (shi->mode & (MA_ZTRANSP|MA_RAYTRANSP))) {
if (shi->spectra!=0.0f) {
- float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ float t = max_fff(shr->spec[0], shr->spec[1], shr->spec[2]);
t *= shi->spectra;
if (t>1.0f) t= 1.0f;
shi->alpha= (1.0f-t)*shi->alpha+t;
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 2fe8ada..a37ffb1 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -476,13 +476,13 @@ static int compare_strand_segment(const void *poin1, const void *poin2)
return 1;
}
-static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
+static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco)
{
projectvert(co, winmat, hoco);
hoco_to_zco(zspan, zco, hoco);
}
-static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint)
+static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint)
{
float div;
@@ -522,7 +522,7 @@ static APixstrand *addpsAstrand(ZSpan *zspan)
static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z)
{
- StrandPart *spart= (StrandPart*)handle;
+ StrandPart *spart= (StrandPart *)handle;
StrandShadeCache *cache= spart->cache;
StrandSegment *sseg= spart->segment;
APixstrand *apn, *apnew;
@@ -603,7 +603,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float
}
/* width is calculated in hoco space, to ensure strands are visible */
-static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
+static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
{
float hoco[4];
int clipflag= 0;
@@ -663,7 +663,7 @@ static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan *
zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac);
}
-static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
+static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
{
if (spart) {
float t= p2->t;
@@ -696,7 +696,7 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St
}
}
-static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
+static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
{
StrandPoint p;
StrandBuffer *buffer= sseg->buffer;
@@ -745,7 +745,7 @@ static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *s
return 1;
}
-void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
+void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
{
StrandBuffer *buffer= sseg->buffer;
StrandPoint *p1= &sseg->point1;
@@ -783,7 +783,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp
}
/* render call to fill in strands */
-int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
+int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
{
ObjectRen *obr;
ObjectInstanceRen *obi;
@@ -976,7 +976,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
/* *************** */
-StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset)
+StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset)
{
StrandSurface *mesh;
MFace *mface;
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 8757be7..a9db197 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -354,7 +354,7 @@ static void ms_diffuse(Render *re, int do_test_break, float *x0, float *x, float
static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
{
const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */
- const int simframes = (int)(ma->vol.ms_spread * (float)MAX3(vp->res[0], vp->res[1], vp->res[2]));
+ const int simframes = (int)(ma->vol.ms_spread * (float)max_iii(vp->res[0], vp->res[1], vp->res[2]));
const int shade_type = ma->vol.shade_type;
float fac = ma->vol.ms_intensity;
@@ -493,7 +493,7 @@ typedef struct VolPrecacheQueue {
*/
static void *vol_precache_part(void *data)
{
- VolPrecacheQueue *queue = (VolPrecacheQueue*)data;
+ VolPrecacheQueue *queue = (VolPrecacheQueue *)data;
VolPrecachePart *pa;
while ((pa = BLI_thread_queue_pop(queue->work))) {
@@ -652,7 +652,7 @@ static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen
global_bounds_obi(re, obi, bbmin, bbmax);
sub_v3_v3v3(dim, bbmax, bbmin);
- div = MAX3(dim[0], dim[1], dim[2]);
+ div = max_fff(dim[0], dim[1], dim[2]);
dim[0] /= div;
dim[1] /= div;
dim[2] /= div;
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index c52fb84..a0267cd 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -1600,8 +1600,8 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
/**
* (clip pyramid)
- * Sets labda: flag, and parametrize the clipping of vertices in
- * viewspace coordinates. labda = -1 means no clipping, labda in [0, 1] means a clipping.
+ * Sets lambda: flag, and parametrize the clipping of vertices in
+ * viewspace coordinates. lambda = -1 means no clipping, lambda in [0, 1] means a clipping.
* Note: uses globals.
* \param v1 start coordinate s
* \param v2 target coordinate t
@@ -1611,13 +1611,13 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
* \param a index for coordinate (x, y, or z)
*/
-static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop)
+static void clippyra(float *lambda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop)
{
float da, dw, u1=0.0, u2=1.0;
float v13;
- labda[0]= -1.0;
- labda[1]= -1.0;
+ lambda[0]= -1.0;
+ lambda[1]= -1.0;
da= v2[a]-v1[a];
/* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */
@@ -1641,16 +1641,16 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
if (cliptestf(da, -dw, v13, -v1[a], &u1, &u2)) {
*b3=1;
if (u2<1.0f) {
- labda[1]= u2;
+ lambda[1]= u2;
*b2=1;
}
- else labda[1]=1.0; /* u2 */
+ else lambda[1]=1.0; /* u2 */
if (u1>0.0f) {
- labda[0] = u1;
+ lambda[0] = u1;
*b2 = 1;
}
else {
- labda[0] = 0.0;
+ lambda[0] = 0.0;
}
}
}
@@ -1658,8 +1658,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
/**
* (make vertex pyramide clip)
- * Checks labda and uses this to make decision about clipping the line
- * segment from v1 to v2. labda is the factor by which the vector is
+ * Checks lambda and uses this to make decision about clipping the line
+ * segment from v1 to v2. lambda is the factor by which the vector is
* cut. ( calculate s + l * ( t - s )). The result is appended to the
* vertex list of this face.
*
@@ -1671,12 +1671,12 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
* \param clve vertex vector.
*/
-static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve)
+static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, float *v2, int *b1, int *clve)
{
float l1, l2, *adr;
- l1= labda[0];
- l2= labda[1];
+ l1= lambda[0];
+ l2= lambda[1];
if (l1!= -1.0f) {
if (l1!= 0.0f) {
@@ -1708,7 +1708,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo
/* ------------------------------------------------------------------------- */
-void projectverto(const float v1[3], float winmat[][4], float adr[4])
+void projectverto(const float v1[3], float winmat[4][4], float adr[4])
{
/* calcs homogenic coord of vertex v1 */
float x, y, z;
@@ -1726,7 +1726,7 @@ void projectverto(const float v1[3], float winmat[][4], float adr[4])
/* ------------------------------------------------------------------------- */
-void projectvert(const float v1[3], float winmat[][4], float adr[4])
+void projectvert(const float v1[3], float winmat[4][4], float adr[4])
{
/* calcs homogenic coord of vertex v1 */
float x, y, z;
@@ -1761,7 +1761,7 @@ static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size)
cache[i].index= -1;
}
-static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho)
+static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *co, float *ho)
{
int cindex= index & 255;
@@ -1790,7 +1790,7 @@ static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bound
bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy;
}
-static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho)
+static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *bounds, float *co, float *ho)
{
float vec[3];
int cindex= index & 255;
@@ -1819,7 +1819,7 @@ static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][
}
}
-void zbuf_render_project(float winmat[][4], const float co[3], float ho[4])
+void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4])
{
float vec[3];
@@ -1827,7 +1827,7 @@ void zbuf_render_project(float winmat[][4], const float co[3], float ho[4])
projectvert(vec, winmat, ho);
}
-void zbuf_make_winmat(Render *re, float winmat[][4])
+void zbuf_make_winmat(Render *re, float winmat[4][4])
{
if (re->r.mode & R_PANORAMA) {
float panomat[4][4]= MAT4_UNITY;
@@ -1847,7 +1847,7 @@ void zbuf_make_winmat(Render *re, float winmat[][4])
void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
{
- float *vlzp[32][3], labda[3][2];
+ float *vlzp[32][3], lambda[3][2];
float vez[400], *trias[40];
if (c1 | c2 | c3) { /* not in middle */
@@ -1887,9 +1887,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
else if (b==1) arg= 0;
else arg= 1;
- clippyra(labda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop);
- clippyra(labda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop);
- clippyra(labda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop);
+ clippyra(lambda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop);
+ clippyra(lambda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop);
+ clippyra(lambda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop);
if (b2==0 && b3==1) {
/* completely 'in', but we copy because of last for () loop in this section */;
@@ -1905,9 +1905,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
}
else {
b1=0;
- makevertpyra(vez, labda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve);
- makevertpyra(vez, labda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve);
- makevertpyra(vez, labda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve);
+ makevertpyra(vez, lambda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve);
+ makevertpyra(vez, lambda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve);
+ makevertpyra(vez, lambda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve);
/* after front clip done: now set clip flags */
if (b==0) {
@@ -2296,7 +2296,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
}
}
-void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity)
+void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, int size, float jitx, float jity)
{
ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspan;
@@ -3261,7 +3261,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample)
* Do accumulation z buffering.
*/
-static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow)
+static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow)
{
ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspans[16], *zspan; /* MAX_OSA */
@@ -3459,7 +3459,7 @@ static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APi
return doztra;
}
-void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2])
+void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[4][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2])
{
RenderPart pa;
int lay= -1;
@@ -4148,8 +4148,17 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
}
if (addpassflag & SCE_PASS_INDEXMA) {
ObjectRen *obr = R.objectinstance[zrow[totface-1].obi].obr;
- VlakRen *vr = obr->vlaknodes->vlak;
- Material *mat = vr->mat;
+ Material *mat = NULL;
+
+ if (zrow[totface-1].segment == -1) {
+ if (obr->vlaknodes)
+ mat = obr->vlaknodes->vlak->mat;
+ }
+ else {
+ if (obr->strandbuf)
+ mat = obr->strandbuf->ma;
+ }
+
if (mat) {
for (a= 0; a<totfullsample; a++)
add_transp_material_index(rlpp[a], od, mat);
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript
index 68fdbec..6db0e14 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import os
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 8d885bf..eb1aad7 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -56,11 +56,13 @@ struct wmOperatorType;
struct wmOperator;
struct rcti;
struct PointerRNA;
+struct PropertyRNA;
struct EnumPropertyItem;
struct MenuType;
struct wmDropBox;
struct wmDrag;
struct ImBuf;
+struct ImageFormatData;
typedef struct wmJob wmJob;
@@ -68,6 +70,7 @@ typedef struct wmJob wmJob;
void WM_init_state_size_set (int stax, int stay, int sizx, int sizy);
void WM_init_state_fullscreen_set(void);
void WM_init_state_normal_set(void);
+void WM_init_native_pixels(int do_it);
void WM_init (struct bContext *C, int argc, const char **argv);
void WM_exit_ext (struct bContext *C, const short do_python);
@@ -92,21 +95,23 @@ void WM_check (struct bContext *C);
struct wmWindow *WM_window_open (struct bContext *C, struct rcti *rect);
+int WM_window_pixels_x (struct wmWindow *win);
+int WM_window_pixels_y (struct wmWindow *win);
+
/* defines for 'type' WM_window_open_temp */
#define WM_WINDOW_RENDER 0
#define WM_WINDOW_USERPREFS 1
#define WM_WINDOW_FILESEL 2
void WM_window_open_temp (struct bContext *C, struct rcti *position, int type);
+
+ /* returns true if draw method is triple buffer */
+int WM_is_draw_triple(struct wmWindow *win);
/* files */
-int WM_homefile_read_exec(struct bContext *C, struct wmOperator *op);
-int WM_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory);
-int WM_homefile_write_exec(struct bContext *C, struct wmOperator *op);
void WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
-int WM_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports);
void WM_autosave_init(struct wmWindowManager *wm);
/* mouse cursors */
@@ -140,12 +145,15 @@ struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers,
void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap);
-struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBase *handlers,
- int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
- void (*remove)(struct bContext *C, void *userdata), void *userdata);
+struct wmEventHandler *WM_event_add_ui_handler(
+ const struct bContext *C, ListBase *handlers,
+ int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
+ void (*remove)(struct bContext *C, void *userdata), void *userdata);
+
void WM_event_remove_ui_handler(ListBase *handlers,
- int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
- void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone);
+ int (*func)(struct bContext *C, struct wmEvent *event, void *userdata),
+ void (*remove)(struct bContext *C, void *userdata),
+ void *userdata, int postpone);
void WM_event_remove_area_handler(struct ListBase *handlers, void *area);
struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op);
@@ -178,7 +186,7 @@ int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wm
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
/* invoke callback, file selector "filepath" unset + exec */
int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const char imtype);
+int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
@@ -196,9 +204,9 @@ void WM_operator_stack_clear(struct wmWindowManager *wm);
struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
struct GHashIterator *WM_operatortype_iter(void);
-void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*));
-void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
-void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
+void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *));
+void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
+void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
int WM_operatortype_remove(const char *idname);
struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag);
@@ -253,9 +261,17 @@ int WM_operator_last_properties_store(struct wmOperator *op);
/* operator as a python command (resultuing string must be freed) */
char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args);
+char *WM_prop_pystring_assign(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int index);
void WM_operator_bl_idname(char *to, const char *from);
void WM_operator_py_idname(char *to, const char *from);
+/* *************** uilist types ******************** */
+void WM_uilisttype_init(void);
+struct uiListType *WM_uilisttype_find(const char *idname, int quiet);
+int WM_uilisttype_add(struct uiListType *ult);
+void WM_uilisttype_freelink(struct uiListType *ult);
+void WM_uilisttype_free(void);
+
/* *************** menu types ******************** */
void WM_menutype_init(void);
struct MenuType *WM_menutype_find(const char *idname, int quiet);
@@ -298,7 +314,7 @@ struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);
struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, struct wmEvent *event),
- void (*copy)(struct wmDrag *, struct wmDropBox *));
+ void (*copy)(struct wmDrag *, struct wmDropBox *));
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
/* Set a subwindow active in pixelspace view, with optional scissor subset */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 347f46c..96a7b15 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -407,6 +407,9 @@ typedef struct wmGesture {
/* customdata for circle is recti, (xmin, ymin) is center, xmax radius */
/* customdata for lasso is short array */
/* customdata for straight line is a recti: (xmin,ymin) is start, (xmax, ymax) is end */
+
+ /* free pointer to use for operator allocs (if set, its freed on exit)*/
+ void *userdata;
} wmGesture;
/* ************** wmEvent ************************ */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 8fe3877..53e67e9 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -149,7 +149,63 @@ void WM_operator_stack_clear(wmWindowManager *wm)
WM_main_add_notifier(NC_WM | ND_HISTORY, NULL);
}
-/* ****************************************** */
+
+/* ************ uiListType handling ************** */
+
+static GHash *uilisttypes_hash = NULL;
+
+uiListType *WM_uilisttype_find(const char *idname, int quiet)
+{
+ uiListType *ult;
+
+ if (idname[0]) {
+ ult = BLI_ghash_lookup(uilisttypes_hash, idname);
+ if (ult) {
+ return ult;
+ }
+ }
+
+ if (!quiet) {
+ printf("search for unknown uilisttype %s\n", idname);
+ }
+
+ return NULL;
+}
+
+int WM_uilisttype_add(uiListType *ult)
+{
+ BLI_ghash_insert(uilisttypes_hash, (void *)ult->idname, ult);
+ return 1;
+}
+
+void WM_uilisttype_freelink(uiListType *ult)
+{
+ BLI_ghash_remove(uilisttypes_hash, ult->idname, NULL, (GHashValFreeFP)MEM_freeN);
+}
+
+/* called on initialize WM_init() */
+void WM_uilisttype_init(void)
+{
+ uilisttypes_hash = BLI_ghash_str_new("uilisttypes_hash gh");
+}
+
+void WM_uilisttype_free(void)
+{
+ GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash);
+
+ for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ uiListType *ult = BLI_ghashIterator_getValue(iter);
+ if (ult->ext.free) {
+ ult->ext.free(ult->ext.data);
+ }
+ }
+ BLI_ghashIterator_free(iter);
+
+ BLI_ghash_free(uilisttypes_hash, NULL, (GHashValFreeFP)MEM_freeN);
+ uilisttypes_hash = NULL;
+}
+
+/* ************ MenuType handling ************** */
static GHash *menutypes_hash = NULL;
diff --git a/source/blender/windowmanager/intern/wm_apple.c b/source/blender/windowmanager/intern/wm_apple.c
index a7bd439..842fc35 100644
--- a/source/blender/windowmanager/intern/wm_apple.c
+++ b/source/blender/windowmanager/intern/wm_apple.c
@@ -77,7 +77,7 @@ static int checkAppleVideoCard(void)
if ((theErr == 0) && (value != 0)) {
theErr = CGLDescribeRenderer(rend, j, kCGLRPCompliant, &value);
if ((theErr == 0) && (value != 0)) {
- /*fprintf(stderr,"make it big\n");*/
+ /*fprintf(stderr, "make it big\n");*/
CGLDestroyRendererInfo(rend);
macPrefState = 8;
return 1;
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index a92ed65..91be039 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -49,6 +49,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_screen.h"
#include "GHOST_C-api.h"
@@ -431,22 +432,22 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
triple->target = GL_TEXTURE_RECTANGLE_ARB;
triple->nx = 1;
triple->ny = 1;
- triple->x[0] = win->sizex;
- triple->y[0] = win->sizey;
+ triple->x[0] = WM_window_pixels_x(win);
+ triple->y[0] = WM_window_pixels_y(win);
}
else if (GPU_non_power_of_two_support()) {
triple->target = GL_TEXTURE_2D;
triple->nx = 1;
triple->ny = 1;
- triple->x[0] = win->sizex;
- triple->y[0] = win->sizey;
+ triple->x[0] = WM_window_pixels_x(win);
+ triple->y[0] = WM_window_pixels_y(win);
}
else {
triple->target = GL_TEXTURE_2D;
triple->nx = 0;
triple->ny = 0;
- split_width(win->sizex, MAX_N_TEX, triple->x, &triple->nx);
- split_width(win->sizey, MAX_N_TEX, triple->y, &triple->ny);
+ split_width(WM_window_pixels_x(win), MAX_N_TEX, triple->x, &triple->nx);
+ split_width(WM_window_pixels_y(win), MAX_N_TEX, triple->y, &triple->ny);
}
/* generate texture names */
@@ -491,7 +492,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
return 1;
}
-static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple)
+static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
{
float halfx, halfy, ratiox, ratioy;
int x, y, sizex, sizey, offx, offy;
@@ -500,8 +501,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple)
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
- sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x];
- sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y];
+ sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x];
+ sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y];
/* wmOrtho for the screen has this same offset */
ratiox = sizex;
@@ -519,7 +520,7 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple)
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
- glColor3f(1.0f, 1.0f, 1.0f);
+ glColor4f(1.0f, 1.0f, 1.0f, alpha);
glBegin(GL_QUADS);
glTexCoord2f(halfx, halfy);
glVertex2f(offx, offy);
@@ -546,8 +547,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) {
for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) {
- sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x];
- sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y];
+ sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x];
+ sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y];
glBindTexture(triple->target, triple->bind[x + y * triple->nx]);
glCopyTexSubImage2D(triple->target, 0, 0, 0, offx, offy, sizex, sizey);
@@ -557,6 +558,20 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
glBindTexture(triple->target, 0);
}
+static void wm_draw_region_blend(wmWindow *win, ARegion *ar)
+{
+ float fac = ED_region_blend_factor(ar);
+
+ /* region blend always is 1, except when blend timer is running */
+ if (fac < 1.0f) {
+ wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct);
+
+ glEnable(GL_BLEND);
+ wm_triple_draw_textures(win, win->drawdata, 1.0f - fac);
+ glDisable(GL_BLEND);
+ }
+}
+
static void wm_method_draw_triple(bContext *C, wmWindow *win)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -572,7 +587,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
wmSubWindowSet(win, screen->mainwin);
- wm_triple_draw_textures(win, win->drawdata);
+ wm_triple_draw_textures(win, win->drawdata, 1.0f);
}
else {
win->drawdata = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
@@ -591,11 +606,14 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->swinid && ar->do_draw) {
- CTX_wm_region_set(C, ar);
- ED_region_do_draw(C, ar);
- ED_area_overdraw_flush(sa, ar);
- CTX_wm_region_set(C, NULL);
- copytex = 1;
+
+ if (ar->overlap == 0) {
+ CTX_wm_region_set(C, ar);
+ ED_region_do_draw(C, ar);
+ ED_area_overdraw_flush(sa, ar);
+ CTX_wm_region_set(C, NULL);
+ copytex = 1;
+ }
}
}
@@ -610,10 +628,27 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
wm_triple_copy_textures(win, triple);
}
+ /* draw overlapping area regions (always like popups) */
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ CTX_wm_area_set(C, sa);
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->swinid && ar->overlap) {
+ CTX_wm_region_set(C, ar);
+ ED_region_do_draw(C, ar);
+ CTX_wm_region_set(C, NULL);
+
+ wm_draw_region_blend(win, ar);
+ }
+ }
+
+ CTX_wm_area_set(C, NULL);
+ }
+
/* after area regions so we can do area 'overlay' drawing */
ED_screen_draw(win);
- /* draw overlapping regions */
+ /* draw floating regions (menus) */
for (ar = screen->regionbase.first; ar; ar = ar->next) {
if (ar->swinid) {
CTX_wm_menu_set(C, ar);
@@ -652,9 +687,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
if (wm->drags.first) {
wm_drags_draw(C, win, NULL);
}
-
}
+
/****************** main update call **********************/
/* quick test to prevent changing window drawable */
@@ -734,6 +769,14 @@ static int wm_automatic_draw_method(wmWindow *win)
return win->drawmethod;
}
+int WM_is_draw_triple(wmWindow *win)
+{
+ /* function can get called before this variable is set in drawing code below */
+ if (win->drawmethod != U.wmdrawmethod)
+ win->drawmethod = U.wmdrawmethod;
+ return USER_DRAW_TRIPLE == wm_automatic_draw_method(win);
+}
+
void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar)
{
/* for draw triple gestures, paint cursors don't need region redraw */
@@ -753,7 +796,7 @@ void wm_draw_update(bContext *C)
GPU_free_unused_buffers();
for (win = wm->windows.first; win; win = win->next) {
- int state = GHOST_GetWindowState(win->ghostwin);;
+ int state = GHOST_GetWindowState(win->ghostwin);
if (state == GHOST_kWindowStateMinimized) {
/* do not update minimized windows, it gives issues on intel drivers (see [#33223])
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index c0e3b19..48cad9e 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -66,6 +66,8 @@
#include "RNA_access.h"
+#include "BIF_gl.h"
+
#include "UI_interface.h"
#include "PIL_time.h"
@@ -338,7 +340,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
ARegion *region = CTX_wm_region(C);
ARegion *menu = CTX_wm_menu(C);
static int do_wheel_ui = TRUE;
- int is_wheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
+ int is_wheel = ELEM3(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN);
int retval;
/* UI code doesn't handle return values - it just always returns break.
@@ -1343,6 +1345,15 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve
}
}
}
+ else {
+ /* modal keymap checking returns handled events fine, but all hardcoded modal
+ handling typically swallows all events (OPERATOR_RUNNING_MODAL).
+ This bypass just disables support for double clicks in hardcoded modal handlers */
+ if (event->val == KM_DBL_CLICK) {
+ event->prevval = event->val;
+ event->val = KM_PRESS;
+ }
+ }
}
/* bad hacking event system... better restore event type for checking of KM_CLICK for example */
@@ -1355,6 +1366,8 @@ static void wm_event_modalmap_end(wmEvent *event)
event->val = event->prevval;
event->prevval = 0;
}
+ else if (event->prevval == KM_DBL_CLICK)
+ event->val = KM_DBL_CLICK;
}
@@ -1640,9 +1653,9 @@ static int wm_action_not_handled(int action)
static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers)
{
#ifndef NDEBUG
- const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS)
+ const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) &&
/* comment this out to flood the console! (if you really want to test) */
- && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
+ !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
;
#endif
wmWindowManager *wm = CTX_wm_manager(C);
@@ -2180,6 +2193,13 @@ void wm_event_do_handlers(bContext *C)
/* update key configuration after handling events */
WM_keyconfig_update(wm);
+
+ if (G.debug) {
+ GLenum error = glGetError();
+ if (error != GL_NO_ERROR) {
+ printf("GL error: %s\n", gluErrorString(error));
+ }
+ }
}
/* ********** filesector handling ************ */
@@ -2689,8 +2709,10 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
if (wm->windows.first == wm->windows.last)
return NULL;
- /* top window bar... */
- if (mx < 0 || my < 0 || mx > win->sizex || my > win->sizey + 30) {
+ /* in order to use window size and mouse position (pixels), we have to use a WM function */
+
+ /* check if outside, include top window bar... */
+ if (mx < 0 || my < 0 || mx > WM_window_pixels_x(win) || my > WM_window_pixels_y(win) + 30) {
wmWindow *owin;
wmEventHandler *handler;
@@ -2701,18 +2723,21 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
return NULL;
/* to desktop space */
- mx += (int)win->posx;
- my += (int)win->posy;
+ mx += (int) (U.pixelsize * win->posx);
+ my += (int) (U.pixelsize * win->posy);
/* check other windows to see if it has mouse inside */
for (owin = wm->windows.first; owin; owin = owin->next) {
if (owin != win) {
- if (mx - owin->posx >= 0 && my - owin->posy >= 0 &&
- mx - owin->posx <= owin->sizex && my - owin->posy <= owin->sizey)
+ int posx = (int) (U.pixelsize * owin->posx);
+ int posy = (int) (U.pixelsize * owin->posy);
+
+ if (mx - posx >= 0 && owin->posy >= 0 &&
+ mx - posx <= WM_window_pixels_x(owin) && my - posy <= WM_window_pixels_y(owin))
{
- evt->x = mx - (int)owin->posx;
- evt->y = my - (int)owin->posy;
+ evt->x = mx - (int)(U.pixelsize * owin->posx);
+ evt->y = my - (int)(U.pixelsize * owin->posy);
return owin;
}
@@ -2738,11 +2763,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
{
GHOST_TEventCursorData *cd = customdata;
wmEvent *lastevent = win->queue.last;
- int cx, cy;
- GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy);
- evt->x = cx;
- evt->y = (win->sizey - 1) - cy;
+ evt->x = cd->x;
+ evt->y = cd->y;
event.x = evt->x;
event.y = evt->y;
@@ -2780,6 +2803,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
switch (pd->subtype) {
case GHOST_kTrackpadEventMagnify:
event.type = MOUSEZOOM;
+ pd->deltaX = -pd->deltaX;
+ pd->deltaY = -pd->deltaY;
break;
case GHOST_kTrackpadEventRotate:
event.type = MOUSEROTATE;
@@ -2790,13 +2815,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
break;
}
- {
- int cx, cy;
- GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy);
- event.x = evt->x = cx;
- event.y = evt->y = (win->sizey - 1) - cy;
- }
-
+ event.x = evt->x = pd->x;
+ event.y = evt->y = pd->y;
event.val = 0;
/* Use prevx/prevy so we can calculate the delta later */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 0e4af46..a9b3e42 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -283,7 +283,9 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
/* in case UserDef was read, we re-initialize all, and do versioning */
static void wm_init_userdef(bContext *C)
{
+ /* versioning is here */
UI_init_userdef();
+
MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024);
sound_init(CTX_data_main(C));
@@ -300,6 +302,13 @@ static void wm_init_userdef(bContext *C)
/* update tempdir from user preferences */
BLI_init_temporary_dir(U.tempdir);
+
+ /* displays with larger native pixels, like Macbook. Used to scale dpi with */
+ if (G.background == FALSE)
+ U.pixelsize = GHOST_GetNativePixelSize();
+ if (U.pixelsize == 0) U.pixelsize = 1;
+
+ BKE_userdef_state();
}
@@ -388,6 +397,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* also exit screens and editors */
wm_window_match_init(C, &wmbase);
+ /* confusing this global... */
+ G.relbase_valid = 1;
retval = BKE_read_file(C, filepath, reports);
G.save_over = 1;
@@ -408,7 +419,6 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
}
if (retval != BKE_READ_FILE_FAIL) {
- G.relbase_valid = 1;
if (do_history) {
write_history();
}
@@ -485,11 +495,12 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* called on startup, (context entirely filled with NULLs) */
/* or called for 'New File' */
-/* op can be NULL */
-int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory)
+/* both startup.blend and userpref.blend are checked */
+int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory)
{
ListBase wmbase;
- char tstr[FILE_MAX];
+ char startstr[FILE_MAX];
+ char prefstr[FILE_MAX];
int success = 0;
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
@@ -498,10 +509,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
if (!from_memory) {
char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
- BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE);
+ BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE);
+ BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE);
}
else {
- tstr[0] = '\0';
+ startstr[0] = '\0';
+ prefstr[0] = '\0';
from_memory = 1;
}
}
@@ -512,14 +525,16 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
/* put aside screens to match with persistent windows later */
wm_window_match_init(C, &wmbase);
- if (!from_memory && BLI_exists(tstr)) {
- success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL);
+ if (!from_memory && BLI_exists(startstr)) {
+ success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL);
- if (U.themes.first == NULL) {
- printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n");
- success = 0;
- }
}
+
+ if (U.themes.first == NULL) {
+ printf("\nNote: No (valid) "STRINGIFY (BLENDER_STARTUP_FILE)" found, fall back to built-in default.\n\n");
+ success = 0;
+ }
+
if (success == 0) {
success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL);
if (wmbase.first == NULL) wm_clear_default_size(C);
@@ -531,6 +546,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
#endif
}
+ /* check new prefs only after startup.blend was finished */
+ if (!from_memory && BLI_exists(prefstr)) {
+ int done = BKE_read_file_userdef(prefstr, NULL);
+ if (done) printf("Read new prefs: %s\n", prefstr);
+ }
+
/* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise
* can remove this eventually, only in a 2.53 and older, now its not written */
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
@@ -584,13 +605,13 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
return TRUE;
}
-int WM_homefile_read_exec(bContext *C, wmOperator *op)
+int wm_homefile_read_exec(bContext *C, wmOperator *op)
{
int from_memory = strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0;
- return WM_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return wm_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
-void WM_read_history(void)
+void wm_read_history(void)
{
char name[FILE_MAX];
LinkNode *l, *lines;
@@ -630,6 +651,10 @@ static void write_history(void)
FILE *fp;
int i;
+ /* no write history for recovered startup files */
+ if (G.main->name[0] == 0)
+ return;
+
/* will be NULL in background mode */
user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL);
if (!user_config_dir)
@@ -708,11 +733,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt)
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, OB_SOLID, FALSE, FALSE, err_out);
+ IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, FALSE, FALSE, err_out);
+ IB_rect, FALSE, R_ADDSKY, err_out);
}
if (ibuf) {
@@ -762,12 +787,11 @@ int write_crash_blend(void)
}
}
-int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports)
+int wm_file_write(bContext *C, const char *target, int fileflags, ReportList *reports)
{
Library *li;
int len;
char filepath[FILE_MAX];
-
int *thumb = NULL;
ImBuf *ibuf_thumb = NULL;
@@ -817,6 +841,14 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re
fileflags |= G_FILE_HISTORY; /* write file history */
+ /* first time saving */
+ /* XXX temp solution to solve bug, real fix coming (ton) */
+ if (G.main->name[0] == 0)
+ BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));
+
+ /* XXX temp solution to solve bug, real fix coming (ton) */
+ G.main->recovered = 0;
+
if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
if (!(fileflags & G_FILE_SAVE_COPY)) {
G.relbase_valid = 1;
@@ -861,7 +893,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re
}
/* operator entry */
-int WM_homefile_write_exec(bContext *C, wmOperator *op)
+int wm_homefile_write_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -881,7 +913,7 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op)
/* force save as regular blend file */
fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
- if (BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) {
+ if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) {
printf("fail\n");
return OPERATOR_CANCELLED;
}
@@ -893,6 +925,28 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+/* Only save the prefs block. operator entry */
+int wm_userpref_write_exec(bContext *C, wmOperator *op)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ char filepath[FILE_MAX];
+
+ /* update keymaps in user preferences */
+ WM_keyconfig_update(wm);
+
+ BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE);
+ printf("trying to save userpref at %s ", filepath);
+
+ if (BKE_write_file_userdef(filepath, op->reports) == 0) {
+ printf("fail\n");
+ return OPERATOR_CANCELLED;
+ }
+
+ printf("ok\n");
+
+ return OPERATOR_FINISHED;
+}
+
/************************ autosave ****************************/
void wm_autosave_location(char *filepath)
@@ -936,7 +990,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
wmWindow *win;
wmEventHandler *handler;
char filepath[FILE_MAX];
- int fileflags;
+
Scene *scene = CTX_data_scene(C);
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
@@ -960,12 +1014,17 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
wm_autosave_location(filepath);
- /* force save as regular blend file */
- fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
-
- /* no error reporting to console */
- BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
+ if (U.uiflag & USER_GLOBALUNDO) {
+ /* fast save of last undobuffer, now with UI */
+ BKE_undo_save_file(filepath);
+ }
+ else {
+ /* save as regular blend file */
+ int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
+ /* no error reporting to console */
+ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
+ }
/* do timer after file write, just in case file write takes a long time */
wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0);
}
@@ -986,7 +1045,7 @@ void wm_autosave_delete(void)
if (BLI_exists(filename)) {
char str[FILE_MAX];
- BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend");
+ BLI_make_file_string("/", str, BLI_temporary_dir(), BLENDER_QUIT_FILE);
/* if global undo; remove tempsave, otherwise rename */
if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0);
@@ -1002,3 +1061,6 @@ void wm_autosave_read(bContext *C, ReportList *reports)
WM_file_read(C, filename, reports);
}
+
+
+
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index a80386e..168c231 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -113,6 +113,9 @@ void WM_gesture_end(bContext *C, wmGesture *gesture)
win->tweak = NULL;
BLI_remlink(&win->gesture, gesture);
MEM_freeN(gesture->customdata);
+ if (gesture->userdata) {
+ MEM_freeN(gesture->userdata);
+ }
MEM_freeN(gesture);
}
@@ -255,7 +258,7 @@ static void draw_filled_lasso(wmGesture *gt)
if (sf_vert_first) {
const float zvec[3] = {0.0f, 0.0f, 1.0f};
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
- BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES, zvec);
+ BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES, zvec);
glEnable(GL_BLEND);
glColor4f(1.0, 1.0, 1.0, 0.05);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index c9f0bbf..de0da3d 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -48,6 +48,7 @@
#include "DNA_windowmanager_types.h"
#include "BLI_listbase.h"
+#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -65,6 +66,7 @@
#include "BKE_node.h"
#include "BKE_report.h"
+#include "BKE_addon.h"
#include "BKE_packedFile.h"
#include "BKE_sequencer.h" /* free seq clipboard */
#include "BKE_material.h" /* clear_matcopybuf */
@@ -128,13 +130,18 @@ int wm_start_with_console = 0; /* used in creator.c */
/* only called once, for startup */
void WM_init(bContext *C, int argc, const char **argv)
{
+
if (!G.background) {
wm_ghost_init(C); /* note: it assigns C to ghost! */
wm_init_cursor_data();
}
GHOST_CreateSystemPaths();
+
+ BKE_addon_pref_type_init();
+
wm_operatortype_init();
WM_menutype_init();
+ WM_uilisttype_init();
set_free_windowmanager_cb(wm_close_and_free); /* library.c */
set_blender_test_break_cb(wm_window_testbreak); /* blender.c */
@@ -149,8 +156,8 @@ void WM_init(bContext *C, int argc, const char **argv)
BLF_lang_init();
/* get the default database, plus a wm */
- WM_homefile_read(C, NULL, G.factory_startup);
-
+ wm_homefile_read(C, NULL, G.factory_startup);
+
BLF_lang_set(NULL);
/* note: there is a bug where python needs initializing before loading the
@@ -158,7 +165,7 @@ void WM_init(bContext *C, int argc, const char **argv)
* initializing space types and other internal data.
*
* However cant redo this at the moment. Solution is to load python
- * before WM_homefile_read() or make py-drivers check if python is running.
+ * before wm_homefile_read() or make py-drivers check if python is running.
* Will try fix when the crash can be repeated. - campbell. */
#ifdef WITH_PYTHON
@@ -195,7 +202,7 @@ void WM_init(bContext *C, int argc, const char **argv)
ED_preview_init_dbase();
- WM_read_history();
+ wm_read_history();
/* allow a path of "", this is what happens when making a new file */
#if 0
@@ -211,6 +218,10 @@ void WM_init(bContext *C, int argc, const char **argv)
COM_linker_hack = COM_execute;
}
#endif
+
+ /* load last session, uses regular file reading so it has to be in end (after init py etc) */
+ if (U.uiflag2 & USER_KEEP_SESSION)
+ wm_recover_last_session(C, NULL);
}
void WM_init_splash(bContext *C)
@@ -372,6 +383,18 @@ void WM_exit_ext(bContext *C, const short do_python)
if (C && wm) {
wmWindow *win;
+ if (!G.background) {
+ if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) {
+ /* save the undo state as quit.blend */
+ char filename[FILE_MAX];
+
+ BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);
+
+ if (BKE_undo_save_file(filename))
+ printf("Saved session recovery to '%s'\n", filename);
+ }
+ }
+
WM_jobs_kill_all(wm);
for (win = wm->windows.first; win; win = win->next) {
@@ -382,9 +405,12 @@ void WM_exit_ext(bContext *C, const short do_python)
ED_screen_exit(C, win, win->screen);
}
}
+
+ BKE_addon_pref_type_free();
wm_operatortype_free();
wm_dropbox_free();
WM_menutype_free();
+ WM_uilisttype_free();
/* all non-screen and non-space stuff editors did, like editmode */
if (C)
@@ -454,9 +480,6 @@ void WM_exit_ext(bContext *C, const short do_python)
GPU_free_unused_buffers();
GPU_extensions_exit();
- if (!G.background) {
- BKE_undo_save_quit(); /* saves quit.blend if global undo is on */
- }
BKE_reset_undo();
ED_file_exit(); /* for fsmenu */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 8a0701b..b2c3c93 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -103,6 +103,7 @@
#include "wm_draw.h"
#include "wm_event_system.h"
#include "wm_event_types.h"
+#include "wm_files.h"
#include "wm_subwindow.h"
#include "wm_window.h"
@@ -150,7 +151,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *))
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
opfunc(ot);
@@ -172,7 +173,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void *
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
/* Set the default i18n context now, so that opfunc can redefine it if needed! */
RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
opfunc(ot, userdata);
@@ -359,7 +360,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
}
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
ot->idname = idname;
ot->name = name;
@@ -389,7 +390,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *),
wmOperatorType *ot;
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
- ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+ ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
ot->flag = OPTYPE_MACRO;
ot->exec = wm_macro_exec;
@@ -559,6 +560,98 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i
return cstring;
}
+/* return NULL if no match is found */
+static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+
+ /* loop over all context items and do 2 checks
+ *
+ * - see if the pointer is in the context.
+ * - see if the pointers ID is in the context.
+ */
+
+ /* don't get from the context store since this is normally set only for the UI and not usable elsewhere */
+ ListBase lb = CTX_data_dir_get_ex(C, FALSE, TRUE, TRUE);
+ LinkData *link;
+
+ const char *member_found = NULL;
+ const char *member_id = NULL;
+
+ char *prop_str = NULL;
+ char *ret = NULL;
+
+
+ for (link = lb.first; link; link = link->next) {
+ const char *identifier = link->data;
+ PointerRNA ctx_item_ptr = {{0}}; // CTX_data_pointer_get(C, identifier);
+
+ if (ctx_item_ptr.type == NULL) {
+ continue;
+ }
+
+ if (ptr->id.data == ctx_item_ptr.id.data) {
+ if ((ptr->data == ctx_item_ptr.data) &&
+ (ptr->type == ctx_item_ptr.type))
+ {
+ /* found! */
+ member_found = identifier;
+ break;
+ }
+ else if (RNA_struct_is_ID(ctx_item_ptr.type)) {
+ /* we found a reference to this ID,
+ * so fallback to it if there is no direct reference */
+ member_id = identifier;
+ }
+ }
+ }
+
+ if (member_found) {
+ prop_str = RNA_path_property_py(ptr, prop, index);
+ if (prop_str) {
+ ret = BLI_sprintfN("bpy.context.%s.%s", member_found, prop_str);
+ MEM_freeN(prop_str);
+ }
+ }
+ else if (member_id) {
+ prop_str = RNA_path_struct_property_py(ptr, prop, index);
+ if (prop_str) {
+ ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str);
+ MEM_freeN(prop_str);
+ }
+ }
+
+ BLI_freelistN(&lb);
+
+ return ret;
+}
+
+char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ char *lhs, *rhs, *ret;
+
+ lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : NULL;
+
+ if (lhs == NULL) {
+ /* fallback to bpy.data.foo[id] if we dont find in the context */
+ lhs = RNA_path_full_property_py(ptr, prop, index);
+ }
+
+ if (!lhs) {
+ return NULL;
+ }
+
+ rhs = RNA_property_as_string(C, ptr, prop, index);
+ if (!rhs) {
+ MEM_freeN(lhs);
+ return NULL;
+ }
+
+ ret = BLI_sprintfN("%s = %s", lhs, rhs);
+ MEM_freeN(lhs);
+ MEM_freeN(rhs);
+ return ret;
+}
+
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
{
RNA_pointer_create(NULL, ot->srna, NULL, ptr);
@@ -883,14 +976,14 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
}
}
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const char imtype)
+int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
{
PropertyRNA *prop;
char filepath[FILE_MAX];
/* dont NULL check prop, this can only run on ops with a 'filepath' */
prop = RNA_struct_find_property(op->ptr, "filepath");
RNA_property_string_get(op->ptr, prop, filepath);
- if (BKE_add_image_extension(filepath, imtype)) {
+ if (BKE_add_image_extension(filepath, im_format)) {
RNA_property_string_set(op->ptr, prop, filepath);
/* note, we could check for and update 'filename' here,
* but so far nothing needs this. */
@@ -1078,7 +1171,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
uiBlock *block;
uiLayout *layout;
uiStyle *style = UI_GetStyle();
- int width = 300;
+ int width = 15 * UI_UNIT_X;
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
uiBlockClearFlag(block, UI_BLOCK_LOOP);
@@ -1262,7 +1355,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_
/* if we don't have global undo, we can't do undo push for automatic redo,
* so we require manual OK clicking in this popup */
if (!(U.uiflag & USER_GLOBALUNDO))
- return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y);
+ return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
uiPupBlock(C, wm_block_create_redo, op);
@@ -1429,7 +1522,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
int i;
MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE);
char url[96];
- char file [FILE_MAX];
+ char file[FILE_MAX];
#ifndef WITH_HEADLESS
extern char datatoc_splash_png[];
@@ -1452,9 +1545,9 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
"%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev);
- BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.dpi);
- ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 5;
- rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 5;
+ BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi);
+ ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit;
+ rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit;
#endif /* WITH_BUILDINFO */
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
@@ -1464,16 +1557,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
* ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
- but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 10, 501, 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
+ /* XXX splash scales with pixelsize, should become widget-units */
+ but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
uiButSetFunc(but, wm_block_splash_close, block, NULL);
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
#ifdef WITH_BUILDINFO
- uiDefBut(block, LABEL, 0, version_buf, 494 - ver_width, 282 - 24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
- uiDefBut(block, LABEL, 0, revision_buf, 494 - rev_width, 282 - 36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
#endif /* WITH_BUILDINFO */
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style);
+ layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style);
uiBlockSetEmboss(block, UI_EMBOSS);
/* show the splash menu (containing interaction presets), using python */
@@ -1675,12 +1769,23 @@ static void WM_OT_window_duplicate(wmOperatorType *ot)
static void WM_OT_save_homefile(wmOperatorType *ot)
{
- ot->name = "Save User Settings";
+ ot->name = "Save Startup File";
ot->idname = "WM_OT_save_homefile";
- ot->description = "Make the current file the default .blend file";
+ ot->description = "Make the current file the default .blend file, includes preferences";
ot->invoke = WM_operator_confirm;
- ot->exec = WM_homefile_write_exec;
+ ot->exec = wm_homefile_write_exec;
+ ot->poll = WM_operator_winactive;
+}
+
+static void WM_OT_save_userpref(wmOperatorType *ot)
+{
+ ot->name = "Save User Settings";
+ ot->idname = "WM_OT_save_userpref";
+ ot->description = "Save user preferences separately, overrides startup file preferences";
+
+ ot->invoke = WM_operator_confirm;
+ ot->exec = wm_userpref_write_exec;
ot->poll = WM_operator_winactive;
}
@@ -1691,7 +1796,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot)
ot->description = "Open the default file (doesn't save the current file)";
ot->invoke = WM_operator_confirm;
- ot->exec = WM_homefile_read_exec;
+ ot->exec = wm_homefile_read_exec;
/* ommit poll to run in background mode */
}
@@ -1702,7 +1807,7 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot)
ot->description = "Load default file and user preferences";
ot->invoke = WM_operator_confirm;
- ot->exec = WM_homefile_read_exec;
+ ot->exec = wm_homefile_read_exec;
/* ommit poll to run in background mode */
}
@@ -2003,21 +2108,38 @@ static void WM_OT_link_append(wmOperatorType *ot)
/* *************** recover last session **************** */
-static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
+void wm_recover_last_session(bContext *C, ReportList *reports)
{
char filename[FILE_MAX];
+
+ BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);
+ /* if reports==NULL, it's called directly without operator, we add a quick check here */
+ if (reports || BLI_exists(filename)) {
+ G.fileflags |= G_FILE_RECOVER;
+
+ /* XXX wm in context is not set correctly after WM_file_read -> crash */
+ /* do it before for now, but is this correct with multiple windows? */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ /* load file */
+ WM_file_read(C, filename, reports);
+
+ G.fileflags &= ~G_FILE_RECOVER;
+
+ /* XXX bad global... fixme */
+ if (G.main->name[0])
+ G.file_loaded = 1; /* prevents splash to show */
+ else {
+ G.relbase_valid = 0;
+ G.save_over = 0; /* start with save preference untitled.blend */
+ }
- G.fileflags |= G_FILE_RECOVER;
-
- /* XXX wm in context is not set correctly after WM_file_read -> crash */
- /* do it before for now, but is this correct with multiple windows? */
- WM_event_add_notifier(C, NC_WINDOW, NULL);
-
- /* load file */
- BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend");
- WM_file_read(C, filename, op->reports);
+ }
+}
- G.fileflags &= ~G_FILE_RECOVER;
+static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
+{
+ wm_recover_last_session(C, op->reports);
return OPERATOR_FINISHED;
}
@@ -2025,7 +2147,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot)
{
ot->name = "Recover Last Session";
ot->idname = "WM_OT_recover_last_session";
- ot->description = "Open the last closed file (\"quit.blend\")";
+ ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")";
ot->exec = wm_recover_last_session_exec;
ot->poll = WM_operator_winactive;
@@ -2049,7 +2171,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
WM_file_read(C, path, op->reports);
G.fileflags &= ~G_FILE_RECOVER;
-
+
return OPERATOR_FINISHED;
}
@@ -2139,7 +2261,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
untitled(path);
}
- fileflags = G.fileflags;
+ fileflags = G.fileflags & ~G_FILE_USERPREFS;
/* set compression flag */
BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"),
@@ -2158,7 +2280,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
G_FILE_MESH_COMPAT);
#endif
- if (WM_file_write(C, path, fileflags, op->reports) != 0)
+ if (wm_file_write(C, path, fileflags, op->reports) != 0)
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL);
@@ -2307,9 +2429,8 @@ static int wm_console_toggle_op(bContext *UNUSED(C), wmOperator *UNUSED(op))
static void WM_OT_console_toggle(wmOperatorType *ot)
{
- /* XXX Have to mark these for xgettext, as under linux they do not exists...
- * And even worth, have to give the context as text, as xgettext doesn't expand macros. :( */
- ot->name = CTX_N_("Operator" /* BLF_I18NCONTEXT_OPERATOR_DEFAULT */, "Toggle System Console");
+ /* XXX Have to mark these for xgettext, as under linux they do not exists... */
+ ot->name = CTX_N_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Toggle System Console");
ot->idname = "WM_OT_console_toggle";
ot->description = N_("Toggle System Console");
@@ -3787,6 +3908,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_read_homefile);
WM_operatortype_append(WM_OT_read_factory_settings);
WM_operatortype_append(WM_OT_save_homefile);
+ WM_operatortype_append(WM_OT_save_userpref);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
WM_operatortype_append(WM_OT_quit_blender);
WM_operatortype_append(WM_OT_open_mainfile);
@@ -3891,6 +4013,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
/* assign map to operators */
WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line");
+ WM_modalkeymap_assign(keymap, "PAINT_OT_weight_gradient");
}
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 8533494..1ed9ffb 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -131,7 +131,7 @@ void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y)
}
}
-void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4])
+void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4])
{
wmSubWindow *swin = swin_from_swinid(win, swinid);
@@ -217,10 +217,10 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
* fixed it). - zr (2001!)
*/
- if (swin->winrct.xmax > win->sizex)
- swin->winrct.xmax = win->sizex;
- if (swin->winrct.ymax > win->sizey)
- swin->winrct.ymax = win->sizey;
+ if (swin->winrct.xmax > WM_window_pixels_x(win))
+ swin->winrct.xmax = WM_window_pixels_x(win);
+ if (swin->winrct.ymax > WM_window_pixels_y(win))
+ swin->winrct.ymax = WM_window_pixels_y(win);
/* extra service */
wmSubWindowSet(win, swinid);
@@ -257,8 +257,8 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
if (srct) {
- width = BLI_rcti_size_x(srct) + 1;
- height = BLI_rcti_size_y(srct) + 1;
+ int width = BLI_rcti_size_x(srct) + 1; /* only here */
+ int height = BLI_rcti_size_y(srct) + 1;
glScissor(srct->xmin, srct->ymin, width, height);
}
else
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index d80536b..9e0f861 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -91,7 +91,9 @@ static struct WMInitStruct {
int windowstate;
WinOverrideFlag override_flag;
-} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0};
+
+ int native_pixels;
+} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0, 1};
/* ******** win open & close ************ */
@@ -241,7 +243,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
win->screen->do_refresh = TRUE;
win->screen->do_draw = TRUE;
- win->drawmethod = -1;
+ win->drawmethod = U.wmdrawmethod;
win->drawdata = NULL;
return win;
@@ -251,51 +253,50 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmWindow *tmpwin;
- bScreen *screen = win->screen;
+ int do_exit = 0;
+
+ /* first check if we have to quit (there are non-temp remaining windows) */
+ for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
+ if (tmpwin == win)
+ continue;
+ if (tmpwin->screen->temp == 0)
+ break;
+ }
+
+ if (tmpwin == NULL)
+ do_exit = 1;
- /* first check if we have any non-temp remaining windows */
if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) {
- if (wm->windows.first) {
- for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
- if (tmpwin == win)
- continue;
- if (tmpwin->screen->temp == 0)
- break;
- }
- if (tmpwin == NULL) {
- if (!GHOST_confirmQuit(win->ghostwin))
- return;
- }
+ if (do_exit) {
+ if (!GHOST_confirmQuit(win->ghostwin))
+ return;
}
}
- BLI_remlink(&wm->windows, win);
-
- wm_draw_window_clear(win);
- CTX_wm_window_set(C, win); /* needed by handlers */
- WM_event_remove_handlers(C, &win->handlers);
- WM_event_remove_handlers(C, &win->modalhandlers);
- ED_screen_exit(C, win, win->screen);
-
- wm_window_free(C, wm, win);
-
- /* if temp screen, delete it after window free (it stops jobs that can access it) */
- if (screen->temp) {
- Main *bmain = CTX_data_main(C);
- BKE_libblock_free(&bmain->screen, screen);
+ /* let WM_exit do all freeing, for correct quit.blend save */
+ if (do_exit) {
+ WM_exit(C);
}
+ else {
+ bScreen *screen = win->screen;
+
+ BLI_remlink(&wm->windows, win);
+
+ wm_draw_window_clear(win);
+
+ CTX_wm_window_set(C, win); /* needed by handlers */
+ WM_event_remove_handlers(C, &win->handlers);
+ WM_event_remove_handlers(C, &win->modalhandlers);
+ ED_screen_exit(C, win, win->screen);
+
+ wm_window_free(C, wm, win);
- /* check remaining windows */
- if (wm->windows.first) {
- for (win = wm->windows.first; win; win = win->next)
- if (win->screen->temp == 0)
- break;
- /* in this case we close all */
- if (win == NULL)
- WM_exit(C);
- }
- else
- WM_exit(C);
+ /* if temp screen, delete it after window free (it stops jobs that can access it) */
+ if (screen->temp) {
+ Main *bmain = CTX_data_main(C);
+ BKE_libblock_free(&bmain->screen, screen);
+ }
+ }
}
void wm_window_title(wmWindowManager *wm, wmWindow *win)
@@ -308,8 +309,9 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
/* this is set to 1 if you don't have startup.blend open */
if (G.save_over && G.main->name[0]) {
- char str[sizeof(G.main->name) + 12];
- BLI_snprintf(str, sizeof(str), "Blender%s [%s]", wm->file_saved ? "" : "*", G.main->name);
+ char str[sizeof(G.main->name) + 24];
+ BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name,
+ G.main->recovered ? " (Recovered)" : "");
GHOST_SetTitle(win->ghostwin, str);
}
else
@@ -344,8 +346,6 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
- /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select)
- * doesn't work well when AA is initialized, even if not used. */
ghostwin = GHOST_CreateWindow(g_system, title,
win->posx, posy, win->sizex, win->sizey,
(GHOST_TWindowState)win->windowstate,
@@ -354,6 +354,8 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
multisamples /* AA */);
if (ghostwin) {
+ GHOST_RectangleHandle bounds;
+
/* needed so we can detect the graphics card below */
GPU_extensions_init();
@@ -372,7 +374,19 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
glClear(GL_COLOR_BUFFER_BIT);
}
+
+ /* displays with larger native pixels, like Macbook. Used to scale dpi with */
+ /* needed here, because it's used before it reads userdef */
+ U.pixelsize = GHOST_GetNativePixelSize();
+ BKE_userdef_state();
+
+ /* store actual window size in blender window */
+ bounds = GHOST_GetClientBounds(win->ghostwin);
+ win->sizex = GHOST_GetWidthRectangle(bounds);
+ win->sizey = GHOST_GetHeightRectangle(bounds);
+ GHOST_DisposeRectangle(bounds);
+
wm_window_swap_buffers(win);
//GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
@@ -468,7 +482,7 @@ wmWindow *WM_window_open(bContext *C, rcti *rect)
win->sizex = BLI_rcti_size_x(rect);
win->sizey = BLI_rcti_size_y(rect);
- win->drawmethod = -1;
+ win->drawmethod = U.wmdrawmethod;
win->drawdata = NULL;
WM_check(C);
@@ -530,6 +544,7 @@ void WM_window_open_temp(bContext *C, rcti *position, int type)
}
ED_screen_set(C, win->screen);
+ ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */
if (sa->spacetype == SPACE_IMAGE)
GHOST_SetTitle(win->ghostwin, IFACE_("Blender Render"));
@@ -578,6 +593,23 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
/* ************ events *************** */
+static void wm_convert_cursor_position(wmWindow *win, int *x, int *y)
+{
+
+ GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
+ *x *= GHOST_GetNativePixelSize();
+
+ *y = (win->sizey - 1) - *y;
+ *y *= GHOST_GetNativePixelSize();
+}
+
+
+void wm_get_cursor_position(wmWindow *win, int *x, int *y)
+{
+ GHOST_GetCursorPosition(g_system, x, y);
+ wm_convert_cursor_position(win, x, y);
+}
+
typedef enum {
SHIFT = 's',
CONTROL = 'c',
@@ -633,6 +665,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win)
}
/* called by ghost, here we handle events for windows themselves or send to event system */
+/* mouse coordinate converversion happens here */
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
bContext *C = C_void_ptr;
@@ -668,12 +701,20 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventWindowDeactivate:
wm_event_add_ghostevent(wm, win, type, time, data);
win->active = 0; /* XXX */
+
+ /* clear modifiers for inactive windows */
+ win->eventstate->alt = 0;
+ win->eventstate->ctrl = 0;
+ win->eventstate->shift = 0;
+ win->eventstate->oskey = 0;
+ win->eventstate->keymodifier = 0;
+
break;
case GHOST_kEventWindowActivate:
{
GHOST_TEventKeyData kdata;
wmEvent event;
- int cx, cy, wx, wy;
+ int wx, wy;
wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
@@ -703,11 +744,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->eventstate->keymodifier = 0;
/* entering window, update mouse pos. but no event */
- GHOST_GetCursorPosition(g_system, &wx, &wy);
-
- GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
- win->eventstate->x = cx;
- win->eventstate->y = (win->sizey - 1) - cy;
+ wm_get_cursor_position(win, &wx, &wy);
+
+ win->eventstate->x = wx;
+ win->eventstate->y = wy;
win->addmousemove = 1; /* enables highlighted buttons */
@@ -857,14 +897,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
{
wmEvent event;
GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
- int cx, cy, wx, wy;
+ int wx, wy;
/* entering window, update mouse pos */
- GHOST_GetCursorPosition(g_system, &wx, &wy);
-
- GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
- win->eventstate->x = cx;
- win->eventstate->y = (win->sizey - 1) - cy;
+ wm_get_cursor_position(win, &wx, &wy);
+ win->eventstate->x = wx;
+ win->eventstate->y = wy;
event = *(win->eventstate); /* copy last state, like mouse coords */
@@ -907,11 +945,24 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
}
}
+ break;
+ }
+ case GHOST_kEventTrackpad:
+ {
+ GHOST_TEventTrackpadData *pd = data;
+ wm_convert_cursor_position(win, &pd->x, &pd->y);
+ wm_event_add_ghostevent(wm, win, type, time, data);
+ break;
+ }
+ case GHOST_kEventCursorMove:
+ {
+ GHOST_TEventCursorData *cd = data;
+ wm_convert_cursor_position(win, &cd->x, &cd->y);
+ wm_event_add_ghostevent(wm, win, type, time, data);
break;
}
-
default:
wm_event_add_ghostevent(wm, win, type, time, data);
break;
@@ -1017,6 +1068,10 @@ void wm_ghost_init(bContext *C)
g_system = GHOST_CreateSystem();
GHOST_AddEventConsumer(g_system, consumer);
+
+ if (wm_init_state.native_pixels) {
+ GHOST_UseNativePixels();
+ }
}
}
@@ -1171,23 +1226,6 @@ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r)
*posy_r = win->posy;
}
-void wm_window_get_size(wmWindow *win, int *width_r, int *height_r)
-{
- *width_r = win->sizex;
- *height_r = win->sizey;
-}
-
-/* exceptional case: - splash is called before events are processed
- * this means we don't actually know the window size so get this from GHOST */
-void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r)
-{
- GHOST_RectangleHandle bounds = GHOST_GetClientBounds(win->ghostwin);
- *width_r = GHOST_GetWidthRectangle(bounds);
- *height_r = GHOST_GetHeightRectangle(bounds);
-
- GHOST_DisposeRectangle(bounds);
-}
-
void wm_window_set_size(wmWindow *win, int width, int height)
{
GHOST_SetClientSize(win->ghostwin, width, height);
@@ -1215,12 +1253,6 @@ void wm_window_swap_buffers(wmWindow *win)
#endif
}
-void wm_get_cursor_position(wmWindow *win, int *x, int *y)
-{
- GHOST_GetCursorPosition(g_system, x, y);
- GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
- *y = (win->sizey - 1) - *y;
-}
/* ******************* exported api ***************** */
@@ -1230,8 +1262,8 @@ void WM_init_state_size_set(int stax, int stay, int sizx, int sizy)
{
wm_init_state.start_x = stax; /* left hand pos */
wm_init_state.start_y = stay; /* bottom pos */
- wm_init_state.size_x = sizx;
- wm_init_state.size_y = sizy;
+ wm_init_state.size_x = sizx < 640 ? 640 : sizx;
+ wm_init_state.size_y = sizy < 480 ? 480 : sizy;
wm_init_state.override_flag |= WIN_OVERRIDE_GEOM;
}
@@ -1248,12 +1280,20 @@ void WM_init_state_normal_set(void)
wm_init_state.override_flag |= WIN_OVERRIDE_WINSTATE;
}
+void WM_init_native_pixels(int do_it)
+{
+ wm_init_state.native_pixels = do_it;
+}
+
/* This function requires access to the GHOST_SystemHandle (g_system) */
void WM_cursor_warp(wmWindow *win, int x, int y)
{
if (win && win->ghostwin) {
+ float f = GHOST_GetNativePixelSize();
int oldx = x, oldy = y;
+ x = x / f;
+ y = y / f;
y = win->sizey - y - 1;
GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y);
@@ -1264,3 +1304,19 @@ void WM_cursor_warp(wmWindow *win, int x, int y)
}
}
+/* support for native pixel size */
+/* mac retina opens window in size X, but it has up to 2 x more pixels */
+int WM_window_pixels_x(wmWindow *win)
+{
+ float f = GHOST_GetNativePixelSize();
+
+ return (int)(f * (float)win->sizex);
+}
+
+int WM_window_pixels_y(wmWindow *win)
+{
+ float f = GHOST_GetNativePixelSize();
+
+ return (int)(f * (float)win->sizey);
+
+}
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 2d0dd2e..2fbfdc4 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -107,5 +107,8 @@ void wm_dropbox_free(void);
void wm_drags_check_ops(bContext *C, wmEvent *event);
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
+/* wm_operators.c */
+void wm_recover_last_session(bContext *C, ReportList *reports);
+
#endif /* __WM_EVENT_SYSTEM_H__ */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index ac43510..78a67a3 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -53,6 +53,9 @@
#define MOUSEX 4
#define MOUSEY 5
+
+/* *** wmEvent.type *** */
+
/* non-event, for example disabled timer */
#define EVENT_NONE 0
/* MOUSE : 0x00x */
@@ -150,11 +153,11 @@ enum {
#define TIMERJOBS 0x0114 /* timer event, jobs system */
#define TIMERAUTOSAVE 0x0115 /* timer event, autosave */
#define TIMERREPORT 0x0116 /* timer event, reports */
+#define TIMERREGION 0x0117 /* timer event, region slide in/out */
#define TIMERF 0x011F /* last timer */
/* test whether the event is timer event */
-#define ISTIMER(event) (event >= TIMER && event <= TIMERF)
-
+#define ISTIMER(event_type) (event_type >= TIMER && event_type <= TIMERF)
/* standard keyboard */
#define AKEY 'a'
@@ -288,29 +291,30 @@ enum {
/* for event checks */
/* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */
/* UNUSED - see wm_eventmatch - BUG [#30479] */
-// #define ISTEXTINPUT(event) (event >= ' ' && event <= 255)
+// #define ISTEXTINPUT(event_type) (event_type >= ' ' && event_type <= 255)
+/* note, an alternative could be to check 'event->utf8_buf' */
/* test whether the event is a key on the keyboard */
-#define ISKEYBOARD(event) (event >= ' ' && event <= 320)
+#define ISKEYBOARD(event_type) (event_type >= ' ' && event_type <= 320)
/* test whether the event is a modifier key */
-#define ISKEYMODIFIER(event) ((event >= LEFTCTRLKEY && event <= LEFTSHIFTKEY) || event == OSKEY)
+#define ISKEYMODIFIER(event_type) ((event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) || event_type == OSKEY)
/* test whether the event is a mouse button */
-#define ISMOUSE(event) (event >= LEFTMOUSE && event <= MOUSEROTATE)
+#define ISMOUSE(event_type) (event_type >= LEFTMOUSE && event_type <= MOUSEROTATE)
/* test whether the event is tweak event */
-#define ISTWEAK(event) (event >= EVT_TWEAK_L && event <= EVT_GESTURE)
+#define ISTWEAK(event_type) (event_type >= EVT_TWEAK_L && event_type <= EVT_GESTURE)
/* test whether the event is a NDOF event */
-#define ISNDOF(event) (event >= NDOF_MOTION && event < NDOF_LAST)
+#define ISNDOF(event_type) (event_type >= NDOF_MOTION && event_type < NDOF_LAST)
/* test whether event type is acceptable as hotkey, excluding modifiers */
-#define ISHOTKEY(event) \
- ((ISKEYBOARD(event) || ISMOUSE(event) || ISNDOF(event)) && \
- (event != ESCKEY) && \
- (event >= LEFTCTRLKEY && event <= LEFTSHIFTKEY) == FALSE && \
- (event >= UNKNOWNKEY && event <= GRLESSKEY) == FALSE)
+#define ISHOTKEY(event_type) \
+ ((ISKEYBOARD(event_type) || ISMOUSE(event_type) || ISNDOF(event_type)) && \
+ (event_type != ESCKEY) && \
+ (event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) == FALSE && \
+ (event_type >= UNKNOWNKEY && event_type <= GRLESSKEY) == FALSE)
/* **************** BLENDER GESTURE EVENTS (0x5000) **************** */
diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h
index f373530..fe007e7 100644
--- a/source/blender/windowmanager/wm_files.h
+++ b/source/blender/windowmanager/wm_files.h
@@ -31,7 +31,13 @@
#ifndef __WM_FILES_H__
#define __WM_FILES_H__
-void WM_read_history(void);
+void wm_read_history(void);
+int wm_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports);
+int wm_homefile_read_exec(struct bContext *C, struct wmOperator *op);
+int wm_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory);
+int wm_homefile_write_exec(struct bContext *C, struct wmOperator *op);
+int wm_userpref_write_exec(struct bContext *C, struct wmOperator *op);
+
#endif /* __WM_FILES_H__ */
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
index 5017977..b584d01 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -46,7 +46,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct);
void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y);
void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y);
-void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]);
+void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]);
unsigned int index_to_framebuffer(int index);
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 6360cfd..ce360f5 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -55,8 +55,6 @@ void wm_window_make_drawable(bContext *C, wmWindow *win);
void wm_window_raise (wmWindow *win);
void wm_window_lower (wmWindow *win);
void wm_window_set_size (wmWindow *win, int width, int height);
-void wm_window_get_size (wmWindow *win, int *width_r, int *height_r);
-void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r);
void wm_window_get_position (wmWindow *win, int *posx_r, int *posy_r);
void wm_window_swap_buffers (wmWindow *win);
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 85bb07d..d606605 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -149,6 +149,7 @@ endif()
bf_intern_raskter
bf_intern_opencolorio
bf_intern_opennl
+ extern_rangetree
)
if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blenderplayer/bad_level_call_stubs/SConscript b/source/blenderplayer/bad_level_call_stubs/SConscript
index 5efe9aa..f26f4df 100644
--- a/source/blenderplayer/bad_level_call_stubs/SConscript
+++ b/source/blenderplayer/bad_level_call_stubs/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'stubs.c'
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 5e38dad..e457b57 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -176,7 +176,7 @@ int RE_RenderInProgress(struct Render *re) {return 0;}
struct Scene *RE_GetScene(struct Render *re) {return (struct Scene *) NULL;}
void RE_Database_Free(struct Render *re) {}
void RE_FreeRender(struct Render *re) {}
-void RE_DataBase_GetView(struct Render *re, float mat[][4]) {}
+void RE_DataBase_GetView(struct Render *re, float mat[4][4]) {}
int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta) {return 0;}
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip) {return 0.0f;}
void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype) {}
@@ -200,9 +200,15 @@ void WM_operator_stack_clear(struct bContext *C) {}
void WM_autosave_init(struct bContext *C) {}
void WM_jobs_kill_all_except(struct wmWindowManager *wm) {}
-char *WM_clipboard_text_get(int selection) {return (char*)0;}
+char *WM_clipboard_text_get(int selection) {return (char *)0;}
void WM_clipboard_text_set(char *buf, int selection) {}
+void WM_uilisttype_init(void) {}
+struct uiListType *WM_uilisttype_find(const char *idname, int quiet) {return (struct uiListType *)NULL;}
+int WM_uilisttype_add(struct uiListType *ult) {return 0;}
+void WM_uilisttype_freelink(struct uiListType *ult) {}
+void WM_uilisttype_free(void) {}
+
struct wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id) {return (struct wmKeyMapItem *) NULL;}
int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event) {return 0;}
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference) {}
@@ -299,13 +305,13 @@ void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene) {}
void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene) {}
int ED_view3d_scene_layer_set(int lay, const int *values) {return 0;}
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar) {}
-void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) {}
+void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) {}
struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) {return (struct BGpic *) NULL;}
void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) {}
void ED_view3D_background_image_clear(struct View3D *v3d) {}
-void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]) {}
+void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]) {}
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {return 0.0f;}
-void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist) {}
+void view3d_apply_mat4(float mat[4][4], float *ofs, float *quat, float *dist) {}
int text_file_modified(struct Text *text) {return 0;}
void ED_node_shader_default(struct Material *ma) {}
void ED_screen_animation_timer_update(struct bContext *C, int redraws) {}
@@ -400,6 +406,7 @@ void uiItemFullR(struct uiLayout *layout, struct PointerRNA *ptr, struct Propert
void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct PointerRNA *ptr) {}
char *uiLayoutIntrospect(struct uiLayout *layout) {return (char *)NULL;}
void UI_reinit_font(void) {}
+int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big) {return 0;}
/* rna template */
void uiTemplateAnyID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *text) {}
@@ -414,7 +421,9 @@ void uiTemplateCurveMapping(struct uiLayout *layout, struct CurveMapping *cumap,
void uiTemplateColorRamp(struct uiLayout *layout, struct ColorBand *coba, int expand) {}
void uiTemplateLayers(struct uiLayout *layout, struct PointerRNA *ptr, char *propname) {}
void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser) {}
-ListBase uiTemplateList(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activepropname, int rows, int listtype) {struct ListBase b = {0,0}; return b;}
+void uiTemplateList(struct uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id,
+ PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr,
+ const char *active_propname, int rows, int maxrows, int layout_type) {}
void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C) {}
void uiTemplateOperatorSearch(struct uiLayout *layout) {}
void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C) {}
@@ -502,6 +511,7 @@ float sculpt_get_brush_alpha(struct Brush *brush) {return 0.0f;}
void sculpt_set_brush_alpha(struct Brush *brush, float alpha) {}
void ED_sculpt_modifiers_changed(struct Object *ob) {}
void ED_mesh_calc_tessface(struct Mesh *mesh) {}
+void BKE_brush_gen_texture_cache(struct Brush *br, int half_side) {}
/* bpy/python internal api */
void operator_wrapper(struct wmOperatorType *ot, void *userdata) {}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index b66c000..72f1132 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -779,8 +779,7 @@ add_dependencies(blender makesdna)
get_property(BLENDER_LINK_LIBS GLOBAL PROPERTY BLENDER_LINK_LIBS)
-set(BLENDER_LINK_LIBS
- ${BLENDER_LINK_LIBS}
+list(APPEND BLENDER_LINK_LIBS
bf_windowmanager
bf_render
)
@@ -893,7 +892,6 @@ endif()
ge_scenegraph
ge_logic_network
ge_logic_ngnetwork
- extern_bullet
ge_logic_loopbacknetwork
bf_intern_moto
extern_openjpeg
@@ -914,6 +912,7 @@ endif()
cycles_subd
bf_intern_raskter
bf_intern_opencolorio
+ extern_rangetree
)
if(WITH_COMPOSITOR)
@@ -971,6 +970,10 @@ endif()
list(APPEND BLENDER_SORTED_LIBS bf_intern_locale)
endif()
+ if(WITH_BULLET AND NOT WITH_BULLET_SYSTEM)
+ list_insert_after(BLENDER_SORTED_LIBS "ge_logic_ngnetwork" "extern_bullet")
+ endif()
+
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
set(REMLIB ${SORTLIB})
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 0f1207a..7012318 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -40,6 +40,17 @@
# include <xmmintrin.h>
#endif
+/* crash handler */
+#ifdef WIN32
+# include <process.h> /* getpid */
+#else
+# include <unistd.h> /* getpid */
+#endif
+/* for backtrace */
+#ifndef WIN32
+# include <execinfo.h>
+#endif
+
#ifdef WIN32
# include <Windows.h>
# include "utfconv.h"
@@ -48,6 +59,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
+#include <errno.h>
/* This little block needed for linking to Blender... */
@@ -157,6 +169,8 @@ static int print_version(int argc, const char **argv, void *data);
/* Initialize callbacks for the modules that need them */
static void setCallbacks(void);
+static bool use_crash_handler = true;
+
#ifndef WITH_PYTHON_MODULE
/* set breakpoints here when running in debug mode, useful to catch floating point errors */
@@ -246,6 +260,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
printf("Misc Options:\n");
BLI_argsPrintArgDoc(ba, "--debug");
BLI_argsPrintArgDoc(ba, "--debug-fpe");
+ BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
#ifdef WITH_FFMPEG
BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
@@ -350,6 +365,12 @@ static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNU
return 0;
}
+static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ use_crash_handler = false;
+ return 0;
+}
+
static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.background = 1;
@@ -423,6 +444,102 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat
return 0;
}
+static void blender_crash_handler_backtrace(FILE *fp)
+{
+#ifndef WIN32
+#define SIZE 100
+ void *buffer[SIZE];
+ int nptrs;
+ char **strings;
+ int i;
+
+ fputs("\n# backtrace\n", fp);
+
+ /* include a backtrace for good measure */
+ nptrs = backtrace(buffer, SIZE);
+ strings = backtrace_symbols(buffer, nptrs);
+ for (i = 0; i < nptrs; i++) {
+ fputs(strings[i], fp);
+ fputc('\n', fp);
+ }
+
+ free(strings);
+#undef SIZE
+#else /* WIN32 */
+ /* TODO */
+ (void)fp;
+#endif
+}
+static void blender_crash_handler(int signum)
+{
+
+#if 0
+ {
+ char fname[FILE_MAX];
+
+ if (!G.main->name[0]) {
+ BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
+ }
+ else {
+ BLI_strncpy(fname, G.main->name, sizeof(fname));
+ BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
+ }
+
+ printf("Writing: %s\n", fname);
+ fflush(stdout);
+
+ BKE_undo_save_file(fname);
+ }
+#endif
+
+ FILE *fp;
+ char header[512];
+ wmWindowManager *wm = G.main->wm.first;
+
+ char fname[FILE_MAX];
+
+ if (!G.main->name[0]) {
+ BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt");
+ }
+ else {
+ BLI_strncpy(fname, G.main->name, sizeof(fname));
+ BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
+ }
+
+ printf("Writing: %s\n", fname);
+ fflush(stdout);
+
+ BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT);
+
+ /* open the crash log */
+ errno = 0;
+ fp = BLI_fopen(fname, "wb");
+ if (fp == NULL) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ fname, errno ? strerror(errno) : "Unknown error opening file");
+ }
+ else {
+ if (wm) {
+ BKE_report_write_file_fp(fp, &wm->reports, header);
+ }
+
+ blender_crash_handler_backtrace(fp);
+
+ fclose(fp);
+ }
+
+
+ /* really crash */
+ signal(signum, SIG_DFL);
+#ifndef WIN32
+ kill(getpid(), signum);
+#else
+ /* force crash on windows for now */
+ *((void **)NULL) = NULL;
+#endif
+}
+
+
static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.factory_startup = 1;
@@ -481,6 +598,12 @@ static int prefsize(int argc, const char **argv, void *UNUSED(data))
return 4;
}
+static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ WM_init_native_pixels(0);
+ return 0;
+}
+
static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
WM_init_state_normal_set();
@@ -1116,6 +1239,8 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
+ BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
+
#undef PY_ENABLE_AUTO
#undef PY_DISABLE_AUTO
@@ -1159,6 +1284,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
+ BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba);
/* third pass: disabling things and forcing settings */
BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
@@ -1294,6 +1420,10 @@ int main(int argc, const char **argv)
BLI_argsParse(ba, 1, NULL, NULL);
#endif
+ if (use_crash_handler) {
+ /* after parsing args */
+ signal(SIGSEGV, blender_crash_handler);
+ }
/* after level 1 args, this is so playanim skips RNA init */
RNA_init();
@@ -1398,7 +1528,7 @@ int main(int argc, const char **argv)
WM_main(C);
return 0;
-} /* end of int main(argc,argv) */
+} /* end of int main(argc, argv) */
#ifdef WITH_PYTHON_MODULE
void main_python_exit(void)
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 6807f53..176dc33 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -58,7 +58,6 @@
#include "RAS_GLExtensionManager.h"
#include "RAS_OpenGLRasterizer.h"
-#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_ListRasterizer.h"
#include "NG_LoopBackNetworkDeviceInterface.h"
@@ -270,7 +269,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
#ifdef WITH_PYTHON
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
#endif
- bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
+ // bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE;
bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES;
@@ -287,16 +286,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
- if (displaylists) {
- if (GLEW_VERSION_1_1 && !novertexarrays)
- rasterizer = new RAS_ListRasterizer(canvas, true, true);
- else
- rasterizer = new RAS_ListRasterizer(canvas);
- }
- else if (GLEW_VERSION_1_1 && !novertexarrays)
- rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
+ //Don't use displaylists with VBOs
+ //If auto starts using VBOs, make sure to check for that here
+ if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO)
+ rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage);
else
- rasterizer = new RAS_OpenGLRasterizer(canvas);
+ rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage);
// create the inputdevices
KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
@@ -473,6 +468,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
sceneconverter->SetMaterials(true);
if (useglslmat && (gs.matmode == GAME_MAT_GLSL))
sceneconverter->SetGLSLMaterials(true);
+ if (scene->gm.flag & GAME_NO_MATERIAL_CACHING)
+ sceneconverter->SetCacheMaterials(false);
KX_Scene* startscene = new KX_Scene(keyboarddevice,
mousedevice,
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index 9a47d22..d833534 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -30,7 +30,6 @@ set(INC
)
set(INC_SYS
- ../../../extern/bullet2/src
${PTHREADS_INCLUDE_DIRS}
${GLEW_INCLUDE_PATH}
${BOOST_INCLUDE_DIR}
@@ -70,4 +69,12 @@ if(WITH_CODEC_FFMPEG)
add_definitions(-DWITH_FFMPEG)
endif()
+if(WITH_BULLET)
+ list(APPEND INC_SYS
+ ${BULLET_INCLUDE_DIRS}
+ )
+ add_definitions(-DUSE_BULLET)
+endif()
+
+
blender_add_lib(ge_blen_routines "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
index 346d201..719041e 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -178,6 +178,18 @@ SetViewPort(
glScissor(minx + x1, miny + y1, vp_width, vp_height);
}
+ void
+KX_BlenderCanvas::
+UpdateViewPort(
+ int x1, int y1,
+ int x2, int y2
+) {
+ m_viewport[0] = x1;
+ m_viewport[1] = y1;
+ m_viewport[2] = x2;
+ m_viewport[3] = y2;
+}
+
const int*
KX_BlenderCanvas::
GetViewPort() {
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
index 244394a..4117c13 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
@@ -151,6 +151,13 @@ public:
int x1, int y1,
int x2, int y2
);
+
+ void
+ UpdateViewPort(
+ int x1, int y1,
+ int x2, int y2
+ );
+
const int*
GetViewPort();
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 00836fa..f8ad887 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -259,7 +259,7 @@ void BL_MakeScreenShot(ScrArea *curarea, const char* filename)
ImBuf *ibuf;
BLI_path_abs(path, G.main->name);
/* BKE_add_image_extension() checks for if extension was already set */
- BKE_add_image_extension(path, R_IMF_IMTYPE_PNG); /* scene->r.im_format.imtype */
+ BKE_add_image_extension_from_type(path, R_IMF_IMTYPE_PNG); /* scene->r.im_format.imtype */
ibuf= IMB_allocImBuf(dumpsx, dumpsy, 24, 0);
ibuf->rect= dumprect;
ibuf->ftype= PNG;
diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript
index 04dbe27..e2417d7 100644
--- a/source/gameengine/BlenderRoutines/SConscript
+++ b/source/gameengine/BlenderRoutines/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index 1f1c404..395a57d 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -112,7 +112,8 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
if (copy_constraint) {
ListBase listb;
// copy all constraint for backward compatibility
- copy_constraints(&listb, &pchan->constraints, FALSE); // copy_constraints NULLs listb, no need to make extern for this operation.
+ // BKE_copy_constraints NULLs listb, no need to make extern for this operation.
+ BKE_copy_constraints(&listb, &pchan->constraints, FALSE);
pchan->constraints= listb;
} else {
pchan->constraints.first = NULL;
@@ -304,7 +305,7 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
case CONSTRAINT_TYPE_TRANSFORM:
case CONSTRAINT_TYPE_DISTLIMIT:
case CONSTRAINT_TYPE_TRANSLIKE:
- cti = constraint_get_typeinfo(pcon);
+ cti = BKE_constraint_get_typeinfo(pcon);
gametarget = gamesubtarget = NULL;
if (cti && cti->get_constraint_targets) {
ListBase listb = { NULL, NULL };
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index ab0630b..9267b2b 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -192,6 +192,8 @@ extern "C" {
}
#endif
+#include "BLI_threads.h"
+
static bool default_light_mode = 0;
static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table()
@@ -423,55 +425,61 @@ static void SetDefaultLightMode(Scene* scene)
// --
-static void GetRGB(
- const bool use_mcol,
- MFace *mface,
- MCol *mmcol,
- Material *mat,
- unsigned int &c0,
- unsigned int &c1,
- unsigned int &c2,
- unsigned int &c3)
+static void GetRGB(short type,
+ MFace* mface,
+ MCol* mmcol,
+ Material *mat,
+ unsigned int c[4])
{
unsigned int color = 0xFFFFFFFFL;
- if (use_mcol) {
- // vertex colors
-
- if (mmcol) {
- c0 = KX_Mcol2uint_new(mmcol[0]);
- c1 = KX_Mcol2uint_new(mmcol[1]);
- c2 = KX_Mcol2uint_new(mmcol[2]);
+ switch (type) {
+ case 0: // vertex colors
+ {
+ if (mmcol) {
+ c[0] = KX_Mcol2uint_new(mmcol[0]);
+ c[1] = KX_Mcol2uint_new(mmcol[1]);
+ c[2] = KX_Mcol2uint_new(mmcol[2]);
+ if (mface->v4)
+ c[3] = KX_Mcol2uint_new(mmcol[3]);
+ }
+ else { // backup white
+ c[0] = KX_rgbaint2uint_new(color);
+ c[1] = KX_rgbaint2uint_new(color);
+ c[2] = KX_rgbaint2uint_new(color);
+ if (mface->v4)
+ c[3] = KX_rgbaint2uint_new( color );
+ }
+ } break;
+
+
+ case 1: // material rgba
+ {
+ if (mat) {
+ union {
+ unsigned char cp[4];
+ unsigned int integer;
+ } col_converter;
+ col_converter.cp[3] = (unsigned char) (mat->r * 255.0f);
+ col_converter.cp[2] = (unsigned char) (mat->g * 255.0f);
+ col_converter.cp[1] = (unsigned char) (mat->b * 255.0f);
+ col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
+ color = col_converter.integer;
+ }
+ c[0] = KX_rgbaint2uint_new(color);
+ c[1] = KX_rgbaint2uint_new(color);
+ c[2] = KX_rgbaint2uint_new(color);
if (mface->v4)
- c3 = KX_Mcol2uint_new(mmcol[3]);
- }
- else { // backup white
- c0 = KX_rgbaint2uint_new(color);
- c1 = KX_rgbaint2uint_new(color);
- c2 = KX_rgbaint2uint_new(color);
+ c[3] = KX_rgbaint2uint_new(color);
+ } break;
+
+ default: // white
+ {
+ c[0] = KX_rgbaint2uint_new(color);
+ c[1] = KX_rgbaint2uint_new(color);
+ c[2] = KX_rgbaint2uint_new(color);
if (mface->v4)
- c3 = KX_rgbaint2uint_new( color );
- }
- }
- else {
- // material rgba
- if (mat) {
- union {
- unsigned char cp[4];
- unsigned int integer;
- } col_converter;
- col_converter.cp[3] = (unsigned char) (mat->r * 255.0f);
- col_converter.cp[2] = (unsigned char) (mat->g * 255.0f);
- col_converter.cp[1] = (unsigned char) (mat->b * 255.0f);
- col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f);
- color = col_converter.integer;
- }
- // backup white is fallback
-
- c0 = KX_rgbaint2uint_new(color);
- c1 = KX_rgbaint2uint_new(color);
- c2 = KX_rgbaint2uint_new(color);
- if (mface->v4)
- c3 = KX_rgbaint2uint_new(color);
+ c[3] = KX_rgbaint2uint_new(color);
+ } break;
}
}
@@ -480,42 +488,65 @@ typedef struct MTF_localLayer {
const char *name;
} MTF_localLayer;
-static void tface_to_uv_bge(const MFace *mface, const MTFace *tface, MT_Point2 uv[4])
+static void GetUVs(BL_Material *material, MTF_localLayer *layers, MFace *mface, MTFace *tface, MT_Point2 uvs[4][MAXTEX])
{
- uv[0].setValue(tface->uv[0]);
- uv[1].setValue(tface->uv[1]);
- uv[2].setValue(tface->uv[2]);
- if (mface->v4) {
- uv[3].setValue(tface->uv[3]);
+ int unit = 0;
+ if (tface)
+ {
+
+ uvs[0][0].setValue(tface->uv[0]);
+ uvs[1][0].setValue(tface->uv[1]);
+ uvs[2][0].setValue(tface->uv[2]);
+
+ if (mface->v4)
+ uvs[3][0].setValue(tface->uv[3]);
}
-}
+ else
+ {
+ uvs[0][0] = uvs[1][0] = uvs[2][0] = uvs[3][0] = MT_Point2(0.f, 0.f);
+ }
+
+ for (int vind = 0; vind<MAXTEX; vind++)
+ {
+ BL_Mapping &map = material->mapping[vind];
-static void GetUV(
- MFace *mface,
- MTFace *tface,
- MTF_localLayer *layers,
- const int layer_uv[2],
- MT_Point2 uv[4],
- MT_Point2 uv2[4])
-{
- bool validface = (tface != NULL);
+ if (!(map.mapping & USEUV)) continue;
- uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f);
+ //If no UVSet is specified, try grabbing one from the UV/Image editor
+ if (map.uvCoName.IsEmpty() && tface)
+ {
+ uvs[0][unit].setValue(tface->uv[0]);
+ uvs[1][unit].setValue(tface->uv[1]);
+ uvs[2][unit].setValue(tface->uv[2]);
- /* No material, what to do? let's see what is in the UV and set the material accordingly
- * light and visible is always on */
- if (layer_uv[0] != -1) {
- tface_to_uv_bge(mface, layers[layer_uv[0]].face, uv);
- if (layer_uv[1] != -1) {
- tface_to_uv_bge(mface, layers[layer_uv[1]].face, uv2);
+ if (mface->v4)
+ uvs[3][unit].setValue(tface->uv[3]);
+
+ ++unit;
+ continue;
+ }
+
+
+ for (int lay=0; lay<MAX_MTFACE; lay++)
+ {
+ MTF_localLayer& layer = layers[lay];
+ if (layer.face == 0) break;
+
+ if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
+ {
+ uvs[0][unit].setValue(layer.face->uv[0]);
+ uvs[1][unit].setValue(layer.face->uv[1]);
+ uvs[2][unit].setValue(layer.face->uv[2]);
+
+ if (mface->v4)
+ uvs[3][unit].setValue(layer.face->uv[3]);
+ else
+ uvs[3][unit].setValue(0.0f, 0.0f);
+
+ ++unit;
+ break;
+ }
}
- }
- else if (validface) {
- tface_to_uv_bge(mface, tface, uv);
- }
- else {
- // nothing at all
- uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f);
}
}
@@ -526,25 +557,29 @@ static bool ConvertMaterial(
MTFace* tface,
const char *tfaceName,
MFace* mface,
- MCol* mmcol, /* only for text, use first mcol, weak */
- MTF_localLayer *layers,
- int layer_uv[2],
- const bool glslmat)
+ MCol* mmcol,
+ bool glslmat)
{
material->Initialize();
- int numchan = -1, texalpha = 0;
+ int texalpha = 0;
bool validmat = (mat!=0);
bool validface = (tface!=0);
+ short type = 0;
+ if ( validmat )
+ type = 1; // material color
+
material->IdMode = DEFAULT_BLENDER;
material->glslmat = (validmat)? glslmat: false;
material->materialindex = mface->mat_nr;
- /* default value for being unset */
- layer_uv[0] = layer_uv[1] = -1;
-
// --------------------------------
if (validmat) {
+
+ // use vertex colors by explicitly setting
+ if (mat->mode &MA_VERTEXCOLP || glslmat)
+ type = 0;
+
// use lighting?
material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED;
@@ -552,7 +587,6 @@ static bool ConvertMaterial(
// cast shadows?
material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0;
MTex *mttmp = 0;
- numchan = getNumTexChannels(mat);
int valid_index = 0;
/* In Multitexture use the face texture if and only if
@@ -561,12 +595,9 @@ static bool ConvertMaterial(
bool facetex = false;
if (validface && mat->mode &MA_FACETEXTURE)
facetex = true;
-
- numchan = numchan>MAXTEX?MAXTEX:numchan;
- if (facetex && numchan == 0) numchan = 1;
// foreach MTex
- for (int i=0; i<numchan; i++) {
+ for (int i=0; i<MAXTEX; i++) {
// use face tex
if (i==0 && facetex ) {
@@ -619,11 +650,10 @@ static bool ConvertMaterial(
material->texname[i] = material->img[i]->id.name;
material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
// -----------------------
- if ( mttmp->tex->imaflag &TEX_USEALPHA ) {
+ if (material->img[i] && (material->img[i]->flag & IMA_IGNORE_ALPHA) == 0)
material->flag[i] |= USEALPHA;
- }
// -----------------------
- else if ( mttmp->tex->imaflag &TEX_CALCALPHA ) {
+ if ( mttmp->tex->imaflag &TEX_CALCALPHA ) {
material->flag[i] |= CALCALPHA;
}
else if (mttmp->tex->flag &TEX_NEGALPHA) {
@@ -798,14 +828,11 @@ static bool ConvertMaterial(
material->ras_mode |= USE_LIGHT;
}
- const char *uvName = "", *uv2Name = "";
-
/* No material, what to do? let's see what is in the UV and set the material accordingly
* light and visible is always on */
if ( validface ) {
material->tile = tface->tile;
- uvName = tfaceName;
- }
+ }
else {
// nothing at all
material->alphablend = GEMAT_SOLID;
@@ -826,45 +853,19 @@ static bool ConvertMaterial(
material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0;
}
- // get uv sets
- if (validmat) {
- bool isFirstSet = true;
-
- // only two sets implemented, but any of the eight
- // sets can make up the two layers
- for (int vind = 0; vind<material->num_enabled; vind++) {
- BL_Mapping &map = material->mapping[vind];
-
- if (map.uvCoName.IsEmpty()) {
- isFirstSet = false;
- }
- else {
- for (int lay=0; lay<MAX_MTFACE; lay++) {
- MTF_localLayer& layer = layers[lay];
- if (layer.face == 0) break;
-
- if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) {
- if (isFirstSet) {
- layer_uv[0] = lay;
- isFirstSet = false;
- uvName = layer.name;
- }
- else if (strcmp(layer.name, uvName) != 0) {
- layer_uv[1] = lay;
- map.mapping |= USECUSTOMUV;
- uv2Name = layer.name;
- }
- }
- }
- }
- }
- }
+ // XXX The RGB values here were meant to be temporary storage for the conversion process,
+ // but fonts now make use of them too, so we leave them in for now.
+ unsigned int rgb[4];
+ GetRGB(type,mface,mmcol,mat,rgb);
- if (validmat && mmcol) { /* color is only for text */
- material->m_mcol = *(unsigned int *)mmcol;
+ // swap the material color, so MCol on bitmap font works
+ if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT))
+ {
+ rgb[0] = KX_rgbaint2uint_new(rgb[0]);
+ rgb[1] = KX_rgbaint2uint_new(rgb[1]);
+ rgb[2] = KX_rgbaint2uint_new(rgb[2]);
+ rgb[3] = KX_rgbaint2uint_new(rgb[3]);
}
- material->SetUVLayerName(uvName);
- material->SetUVLayerName2(uv2Name);
if (validmat)
material->matname =(mat->id.name);
@@ -879,8 +880,193 @@ static bool ConvertMaterial(
return true;
}
+static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace *tface, MCol *mcol, MTF_localLayer *layers, int lightlayer, unsigned int *rgb, MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT], const char *tfaceName, KX_Scene* scene, KX_BlenderSceneConverter *converter)
+{
+ RAS_IPolyMaterial* polymat = converter->FindCachedPolyMaterial(ma);
+ BL_Material* bl_mat = converter->FindCachedBlenderMaterial(ma);
+ KX_BlenderMaterial* kx_blmat = NULL;
+ KX_PolygonMaterial* kx_polymat = NULL;
+
+ if (converter->GetMaterials()) {
+ /* do Blender Multitexture and Blender GLSL materials */
+
+ /* first is the BL_Material */
+ if (!bl_mat)
+ {
+ bl_mat = new BL_Material();
+
+ ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
+ converter->GetGLSLMaterials());
+
+ converter->CacheBlenderMaterial(ma, bl_mat);
+ }
+
+
+ short type = (ma) ? ((ma->mode & MA_VERTEXCOLP || bl_mat->glslmat) ? 0 : 1) : 0;
+ GetRGB(type,mface,mcol,ma,rgb);
+
+ GetUVs(bl_mat, layers, mface, tface, uvs);
+
+ /* then the KX_BlenderMaterial */
+ if (polymat == NULL)
+ {
+ kx_blmat = new KX_BlenderMaterial();
+
+ kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer);
+ polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
+ converter->CachePolyMaterial(ma, polymat);
+ }
+ }
+ else {
+ /* do Texture Face materials */
+ Image* bima = (tface)? (Image*)tface->tpage: NULL;
+ STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
+
+ if (!converter->GetCacheMaterials())
+ polymat = NULL;
+
+ char alpha_blend=0;
+ short tile=0;
+ int tilexrep=4,tileyrep = 4;
+
+ /* set material properties - old TexFace */
+ if (ma) {
+ alpha_blend = ma->game.alpha_blend;
+ /* Commented out for now. If we ever get rid of
+ * "Texture Face/Singletexture" we can then think about it */
+
+ /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
+ #if 0
+ if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
+ bima = NULL;
+ imastr = "";
+ alpha_blend = GEMAT_SOLID;
+ }
+ else {
+ alpha_blend = ma->game.alpha_blend;
+ }
+ #endif
+ }
+ /* check for tface tex to fallback on */
+ else {
+ if (bima) {
+ /* see if depth of the image is 32 */
+ if (BKE_image_has_alpha(bima))
+ alpha_blend = GEMAT_ALPHA;
+ else
+ alpha_blend = GEMAT_SOLID;
+ }
+ else {
+ alpha_blend = GEMAT_SOLID;
+ }
+ }
+
+ if (bima) {
+ tilexrep = bima->xrep;
+ tileyrep = bima->yrep;
+ }
+
+ /* set UV properties */
+ if (tface) {
+ uvs[0][0].setValue(tface->uv[0]);
+ uvs[1][0].setValue(tface->uv[1]);
+ uvs[2][0].setValue(tface->uv[2]);
+
+ if (mface->v4)
+ uvs[3][0].setValue(tface->uv[3]);
+
+ tile = tface->tile;
+ }
+ else {
+ /* no texfaces */
+ tile = 0;
+ }
+
+ /* get vertex colors */
+ if (mcol) {
+ /* we have vertex colors */
+ rgb[0] = KX_Mcol2uint_new(mcol[0]);
+ rgb[1] = KX_Mcol2uint_new(mcol[1]);
+ rgb[2] = KX_Mcol2uint_new(mcol[2]);
+
+ if (mface->v4)
+ rgb[3] = KX_Mcol2uint_new(mcol[3]);
+ }
+ else {
+ /* no vertex colors, take from material, otherwise white */
+ unsigned int color = 0xFFFFFFFFL;
+
+ if (ma)
+ {
+ union
+ {
+ unsigned char cp[4];
+ unsigned int integer;
+ } col_converter;
+
+ col_converter.cp[3] = (unsigned char) (ma->r*255.0);
+ col_converter.cp[2] = (unsigned char) (ma->g*255.0);
+ col_converter.cp[1] = (unsigned char) (ma->b*255.0);
+ col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
+
+ color = col_converter.integer;
+ }
+
+ rgb[0] = KX_rgbaint2uint_new(color);
+ rgb[1] = KX_rgbaint2uint_new(color);
+ rgb[2] = KX_rgbaint2uint_new(color);
+
+ if (mface->v4)
+ rgb[3] = KX_rgbaint2uint_new(color);
+ }
+
+ // only zsort alpha + add
+ bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
+ bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
+ bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
+
+ // don't need zort anymore, deal as if it it's alpha blend
+ if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
+
+ if (polymat == NULL)
+ {
+ kx_polymat = new KX_PolygonMaterial();
+ kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
+ tile, tilexrep, tileyrep,
+ alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
+ polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
+
+ if (ma) {
+ polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
+ polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
+ polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
+ }
+ else {
+ polymat->m_specular.setValue(0.0f,0.0f,0.0f);
+ polymat->m_shininess = 35.0;
+ }
+
+ if (converter->GetCacheMaterials())
+ converter->CachePolyMaterial(ma, polymat);
+ }
+ }
+
+ // see if a bucket was reused or a new one was created
+ // this way only one KX_BlenderMaterial object has to exist per bucket
+ bool bucketCreated;
+ RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
+ if (bucketCreated) {
+ // this is needed to free up memory afterwards
+ converter->RegisterPolyMaterial(polymat);
+ if (converter->GetMaterials())
+ converter->RegisterBlenderMaterial(bl_mat);
+ }
+
+ return bucket;
+}
+
/* blenderobj can be NULL, make sure its checked for */
-RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
+RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter, bool libloading)
{
RAS_MeshObject *meshobj;
int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
@@ -910,7 +1096,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
// Extract avaiable layers
MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
- int layer_uv[2]; /* store uv1, uv2 layers */
for (int lay=0; lay<MAX_MTFACE; lay++) {
layers[lay].face = 0;
layers[lay].name = "";
@@ -933,31 +1118,23 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
meshobj->SetName(mesh->id.name + 2);
meshobj->m_sharedvertex_map.resize(totvert);
- RAS_IPolyMaterial* polymat = NULL;
- STR_String imastr;
- // These pointers will hold persistent material structure during the conversion
- // to avoid countless allocation/deallocation of memory.
- BL_Material* bl_mat = NULL;
- KX_BlenderMaterial* kx_blmat = NULL;
- KX_PolygonMaterial* kx_polymat = NULL;
- for (int f=0;f<totface;f++,mface++)
- {
- Material* ma = 0;
- bool collider = true;
- MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
- MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
- unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
+ Material* ma = 0;
+ bool collider = true;
+ MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT];
+ unsigned int rgb[4] = {0};
- MT_Point3 pt0, pt1, pt2, pt3;
- MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
- MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
+ MT_Point3 pt[4];
+ MT_Vector3 no[4];
+ MT_Vector4 tan[4];
+ for (int f=0;f<totface;f++,mface++)
+ {
/* get coordinates, normals and tangents */
- pt0.setValue(mvert[mface->v1].co);
- pt1.setValue(mvert[mface->v2].co);
- pt2.setValue(mvert[mface->v3].co);
- if (mface->v4) pt3.setValue(mvert[mface->v4].co);
+ pt[0].setValue(mvert[mface->v1].co);
+ pt[1].setValue(mvert[mface->v2].co);
+ pt[2].setValue(mvert[mface->v3].co);
+ if (mface->v4) pt[3].setValue(mvert[mface->v4].co);
if (mface->flag & ME_SMOOTH) {
float n0[3], n1[3], n2[3], n3[3];
@@ -965,13 +1142,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
normal_short_to_float_v3(n0, mvert[mface->v1].no);
normal_short_to_float_v3(n1, mvert[mface->v2].no);
normal_short_to_float_v3(n2, mvert[mface->v3].no);
- no0 = n0;
- no1 = n1;
- no2 = n2;
+ no[0] = n0;
+ no[1] = n1;
+ no[2] = n2;
if (mface->v4) {
normal_short_to_float_v3(n3, mvert[mface->v4].no);
- no3 = n3;
+ no[3] = n3;
}
}
else {
@@ -982,16 +1159,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
else
normal_tri_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
- no0 = no1 = no2 = no3 = MT_Vector3(fno);
+ no[0] = no[1] = no[2] = no[3] = MT_Vector3(fno);
}
if (tangent) {
- tan0 = tangent[f*4 + 0];
- tan1 = tangent[f*4 + 1];
- tan2 = tangent[f*4 + 2];
+ tan[0] = tangent[f*4 + 0];
+ tan[1] = tangent[f*4 + 1];
+ tan[2] = tangent[f*4 + 2];
if (mface->v4)
- tan3 = tangent[f*4 + 3];
+ tan[3] = tangent[f*4 + 3];
}
if (blenderobj)
ma = give_current_material(blenderobj, mface->mat_nr+1);
@@ -1007,171 +1184,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
bool visible = true;
bool twoside = false;
- if (converter->GetMaterials()) {
- const bool is_bl_mat_new = (bl_mat == NULL);
- //const bool is_kx_blmat_new = (kx_blmat == NULL);
- const bool glslmat = converter->GetGLSLMaterials();
- const bool use_mcol = ma ? (ma->mode & MA_VERTEXCOLP || glslmat) : true;
- /* do Blender Multitexture and Blender GLSL materials */
- MT_Point2 uv_1[4];
- MT_Point2 uv_2[4];
-
- /* first is the BL_Material */
- if (!bl_mat) {
- bl_mat = new BL_Material();
- }
-
- /* only */
- if (is_bl_mat_new || (bl_mat->material != ma)) {
- ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
- layers, layer_uv, glslmat);
- }
-
- /* vertex colors and uv's from the faces */
- GetRGB(use_mcol, mface, mcol, ma, rgb0, rgb1, rgb2, rgb3);
- GetUV(mface, tface, layers, layer_uv, uv_1, uv_2);
-
- uv0 = uv_1[0]; uv1 = uv_1[1];
- uv2 = uv_1[2]; uv3 = uv_1[3];
-
- uv20 = uv_2[0]; uv21 = uv_2[1];
- uv22 = uv_2[2]; uv23 = uv_2[3];
-
- /* then the KX_BlenderMaterial */
- if (kx_blmat == NULL)
- kx_blmat = new KX_BlenderMaterial();
-
- //if (is_kx_blmat_new || !kx_blmat->IsMaterial(bl_mat)) {
- kx_blmat->Initialize(scene, bl_mat, (ma ? &ma->game : NULL));
- //}
-
- polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
- }
- else {
- /* do Texture Face materials */
- Image* bima = (tface)? (Image*)tface->tpage: NULL;
- imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
-
- char alpha_blend=0;
- short tile=0;
- int tilexrep=4,tileyrep = 4;
-
- /* set material properties - old TexFace */
- if (ma) {
- alpha_blend = ma->game.alpha_blend;
- /* Commented out for now. If we ever get rid of
- * "Texture Face/Singletexture" we can then think about it */
-
- /* Texture Face mode ignores texture but requires "Face Textures to be True "*/
-#if 0
- if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) {
- bima = NULL;
- imastr = "";
- alpha_blend = GEMAT_SOLID;
- }
- else {
- alpha_blend = ma->game.alpha_blend;
- }
-#endif
- }
- /* check for tface tex to fallback on */
- else {
- if (bima) {
- /* see if depth of the image is 32 */
- if (BKE_image_has_alpha(bima))
- alpha_blend = GEMAT_ALPHA;
- else
- alpha_blend = GEMAT_SOLID;
- }
- else {
- alpha_blend = GEMAT_SOLID;
- }
- }
-
- if (bima) {
- tilexrep = bima->xrep;
- tileyrep = bima->yrep;
- }
-
- /* set UV properties */
- if (tface) {
- uv0.setValue(tface->uv[0]);
- uv1.setValue(tface->uv[1]);
- uv2.setValue(tface->uv[2]);
-
- if (mface->v4)
- uv3.setValue(tface->uv[3]);
-
- tile = tface->tile;
- }
- else {
- /* no texfaces */
- tile = 0;
- }
-
- /* get vertex colors */
- if (mcol) {
- /* we have vertex colors */
- rgb0 = KX_Mcol2uint_new(mcol[0]);
- rgb1 = KX_Mcol2uint_new(mcol[1]);
- rgb2 = KX_Mcol2uint_new(mcol[2]);
-
- if (mface->v4)
- rgb3 = KX_Mcol2uint_new(mcol[3]);
- }
- else {
- /* no vertex colors, take from material, otherwise white */
- unsigned int color = 0xFFFFFFFFL;
-
- if (ma)
- {
- union
- {
- unsigned char cp[4];
- unsigned int integer;
- } col_converter;
-
- col_converter.cp[3] = (unsigned char) (ma->r * 255.0f);
- col_converter.cp[2] = (unsigned char) (ma->g * 255.0f);
- col_converter.cp[1] = (unsigned char) (ma->b * 255.0f);
- col_converter.cp[0] = (unsigned char) (ma->alpha * 255.0f);
-
- color = col_converter.integer;
- }
-
- rgb0 = KX_rgbaint2uint_new(color);
- rgb1 = KX_rgbaint2uint_new(color);
- rgb2 = KX_rgbaint2uint_new(color);
-
- if (mface->v4)
- rgb3 = KX_rgbaint2uint_new(color);
- }
-
- // only zsort alpha + add
- bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT);
- bool zsort = (alpha_blend == GEMAT_ALPHA_SORT);
- bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode;
-
- // don't need zort anymore, deal as if it it's alpha blend
- if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA;
-
- if (kx_polymat == NULL)
- kx_polymat = new KX_PolygonMaterial();
- kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
- tile, tilexrep, tileyrep,
- alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol);
- polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
-
- if (ma) {
- polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
- polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
- polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
- }
- else {
- polymat->m_specular.setValue(0.0f,0.0f,0.0f);
- polymat->m_shininess = 35.0;
- }
- }
+ RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter);
// set render flags
if (ma)
@@ -1188,30 +1201,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
/* mark face as flat, so vertices are split */
bool flat = (mface->flag & ME_SMOOTH) == 0;
-
- // see if a bucket was reused or a new one was created
- // this way only one KX_BlenderMaterial object has to exist per bucket
- bool bucketCreated;
- RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
- if (bucketCreated) {
- // this is needed to free up memory afterwards
- converter->RegisterPolyMaterial(polymat);
- if (converter->GetMaterials()) {
- converter->RegisterBlenderMaterial(bl_mat);
- // the poly material has been stored in the bucket, next time we must create a new one
- bl_mat = NULL;
- kx_blmat = NULL;
- } else {
- // the poly material has been stored in the bucket, next time we must create a new one
- kx_polymat = NULL;
- }
- } else {
- // from now on, use the polygon material from the material bucket
- polymat = bucket->GetPolyMaterial();
- // keep the material pointers, they will be reused for next face
- }
-
+
int nverts = (mface->v4)? 4: 3;
+
RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
poly->SetVisible(visible);
@@ -1219,12 +1211,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
poly->SetTwoside(twoside);
//poly->SetEdgeCode(mface->edcode);
- meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
- meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
- meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
+ meshobj->AddVertex(poly,0,pt[0],uvs[0],tan[0],rgb[0],no[0],flat,mface->v1);
+ meshobj->AddVertex(poly,1,pt[1],uvs[1],tan[1],rgb[1],no[1],flat,mface->v2);
+ meshobj->AddVertex(poly,2,pt[2],uvs[2],tan[2],rgb[2],no[2],flat,mface->v3);
if (nverts==4)
- meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
+ meshobj->AddVertex(poly,3,pt[3],uvs[3],tan[3],rgb[3],no[3],flat,mface->v4);
}
if (tface)
@@ -1246,22 +1238,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
meshobj->EndConversion();
// pre calculate texture generation
- for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
- mit != meshobj->GetLastMaterial(); ++ mit) {
- mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer);
+ // However, we want to delay this if we're libloading so we can make sure we have the right scene.
+ if (!libloading) {
+ for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
+ mit != meshobj->GetLastMaterial(); ++ mit) {
+ mit->m_bucket->GetPolyMaterial()->OnConstruction();
+ }
}
if (layers)
delete []layers;
dm->release(dm);
- // cleanup material
- if (bl_mat)
- delete bl_mat;
- if (kx_blmat)
- delete kx_blmat;
- if (kx_polymat)
- delete kx_polymat;
+
converter->RegisterGameMesh(meshobj, mesh);
return meshobj;
}
@@ -1274,7 +1263,7 @@ static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blender
MT_assert(materialProps && "Create physics material properties failed");
- Material* blendermat = give_current_material(blenderobject, 0);
+ Material* blendermat = give_current_material(blenderobject, 1);
if (blendermat)
{
@@ -1358,7 +1347,9 @@ static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
float radius=0.0f, vert_radius, *co;
int a;
- if (me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
+ if (me->bb==0) {
+ me->bb = BKE_boundbox_alloc_unit();
+ }
bb= me->bb;
INIT_MINMAX(min, max);
@@ -1921,7 +1912,8 @@ static KX_GameObject *gameobject_from_blenderobject(
Object *ob,
KX_Scene *kxscene,
RAS_IRenderTools *rendertools,
- KX_BlenderSceneConverter *converter)
+ KX_BlenderSceneConverter *converter,
+ bool libloading)
{
KX_GameObject *gameobj = NULL;
Scene *blenderscene = kxscene->GetBlenderScene();
@@ -1958,7 +1950,7 @@ static KX_GameObject *gameobject_from_blenderobject(
Mesh* mesh = static_cast<Mesh*>(ob->data);
float center[3], extents[3];
float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
- RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter);
+ RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter, libloading);
// needed for python scripting
kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
@@ -2332,7 +2324,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
RAS_IRenderTools* rendertools,
RAS_ICanvas* canvas,
KX_BlenderSceneConverter* converter,
- bool alwaysUseExpandFraming
+ bool alwaysUseExpandFraming,
+ bool libloading
)
{
@@ -2366,6 +2359,10 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
set<Object*> allblobj; // all objects converted
set<Object*> groupobj; // objects from groups (never in active layer)
+ // This is bad, but we use this to make sure the first time this is called
+ // is not in a separate thread.
+ BL_Texture::GetMaxUnits();
+
if (alwaysUseExpandFraming) {
frame_type = RAS_FrameSettings::e_frame_extend;
aspect_width = canvas->GetWidth();
@@ -2442,7 +2439,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
base->object,
kxscene,
rendertools,
- converter);
+ converter,
+ libloading);
bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
bool addobj=true;
@@ -2501,7 +2499,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
blenderobject,
kxscene,
rendertools,
- converter);
+ converter,
+ libloading);
// this code is copied from above except that
// object from groups are never in active layer
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
index 2a7efaa..f3a6809 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.h
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.h
@@ -38,7 +38,7 @@
#include "KX_PhysicsEngineEnums.h"
#include "SCA_IInputDevice.h"
-class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
+class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter, bool libloading);
void BL_ConvertBlenderObjects(struct Main* maggie,
class KX_Scene* kxscene,
@@ -47,7 +47,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas,
class KX_BlenderSceneConverter* sceneconverter,
- bool alwaysUseExpandFraming
+ bool alwaysUseExpandFraming,
+ bool libloading=false
);
SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code);
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index e9dd97f..8ac9e52 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -83,6 +83,7 @@ set(SRC
KX_ConvertProperties.cpp
KX_ConvertSensors.cpp
KX_IpoConvert.cpp
+ KX_LibLoadStatus.cpp
KX_SoftBodyDeformer.cpp
BL_ActionActuator.h
@@ -105,12 +106,13 @@ set(SRC
KX_ConvertProperties.h
KX_ConvertSensors.h
KX_IpoConvert.h
+ KX_LibLoadStatus.h
KX_SoftBodyDeformer.h
)
if(WITH_BULLET)
list(APPEND INC_SYS
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
)
add_definitions(-DUSE_BULLET)
endif()
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index d1684db..5524612 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -60,6 +60,7 @@
#endif
#include "KX_BlenderSceneConverter.h"
+#include "KX_LibLoadStatus.h"
#include "KX_BlenderScalarInterpolator.h"
#include "BL_BlenderDataConversion.h"
#include "BlenderWorldInfo.h"
@@ -113,6 +114,14 @@ extern "C" {
#include "../../blender/blenlib/BLI_linklist.h"
}
+#include <pthread.h>
+
+/* This is used to avoid including pthread.h in KX_BlenderSceneConverter.h */
+typedef struct ThreadInfo {
+ vector<pthread_t> threads;
+ pthread_mutex_t merge_lock;
+} ThreadInfo;
+
KX_BlenderSceneConverter::KX_BlenderSceneConverter(
struct Main* maggie,
class KX_KetsjiEngine* engine
@@ -122,10 +131,13 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter(
m_ketsjiEngine(engine),
m_alwaysUseExpandFraming(false),
m_usemat(false),
- m_useglslmat(false)
+ m_useglslmat(false),
+ m_use_mat_cache(true)
{
tag_main(maggie, 0); /* avoid re-tagging later on */
m_newfilename = "";
+ m_threadinfo = new ThreadInfo();
+ pthread_mutex_init(&m_threadinfo->merge_lock, NULL);
}
@@ -135,6 +147,16 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
int i;
// delete sumoshapes
+ if (m_threadinfo) {
+ vector<pthread_t>::iterator pit = m_threadinfo->threads.begin();
+ while (pit != m_threadinfo->threads.end()) {
+ pthread_join((*pit), NULL);
+ pit++;
+ }
+
+ pthread_mutex_destroy(&m_threadinfo->merge_lock);
+ delete m_threadinfo;
+ }
int numAdtLists = m_map_blender_to_gameAdtList.size();
for (i=0; i<numAdtLists; i++) {
@@ -151,6 +173,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
while (itp != m_polymaterials.end()) {
+ m_polymat_cache.erase((*itp).second->GetBlenderMaterial());
delete (*itp).second;
itp++;
}
@@ -158,6 +181,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
// delete after RAS_IPolyMaterial
vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
while (itmat != m_materials.end()) {
+ m_mat_cache.erase((*itmat).second->material);
delete (*itmat).second;
itmat++;
}
@@ -286,7 +310,8 @@ struct BlenderDebugDraw : public btIDebugDraw
void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
class RAS_IRenderTools* rendertools,
- class RAS_ICanvas* canvas)
+ class RAS_ICanvas* canvas,
+ bool libloading)
{
//find out which physics engine
Scene *blenderscene = destinationscene->GetBlenderScene();
@@ -296,7 +321,10 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
// hook for registration function during conversion.
m_currentScene = destinationscene;
destinationscene->SetSceneConverter(this);
- SG_SetActiveStage(SG_STAGE_CONVERTER);
+
+ // This doesn't really seem to do anything except cause potential issues
+ // when doing threaded conversion, so it's disabled for now.
+ // SG_SetActiveStage(SG_STAGE_CONVERTER);
if (blenderscene)
{
@@ -355,7 +383,8 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
rendertools,
canvas,
this,
- m_alwaysUseExpandFraming
+ m_alwaysUseExpandFraming,
+ libloading
);
//These lookup are not needed during game
@@ -406,6 +435,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
size = m_polymaterials.size();
for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
if ((*polymit).first == scene) {
+ m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
@@ -420,6 +450,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
size = m_materials.size();
for (i=0, matit=m_materials.begin(); i<size; ) {
if ((*matit).first == scene) {
+ m_mat_cache.erase((*matit).second->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
@@ -458,6 +489,11 @@ void KX_BlenderSceneConverter::SetGLSLMaterials(bool val)
m_useglslmat = val;
}
+void KX_BlenderSceneConverter::SetCacheMaterials(bool val)
+{
+ m_use_mat_cache = val;
+}
+
bool KX_BlenderSceneConverter::GetMaterials()
{
return m_usemat;
@@ -468,8 +504,19 @@ bool KX_BlenderSceneConverter::GetGLSLMaterials()
return m_useglslmat;
}
+bool KX_BlenderSceneConverter::GetCacheMaterials()
+{
+ return m_use_mat_cache;
+}
+
void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
{
+ // First make sure we don't register the material twice
+ vector<pair<KX_Scene*,BL_Material*> >::iterator it;
+ for (it = m_materials.begin(); it != m_materials.end(); ++it)
+ if (it->second == mat)
+ return;
+
m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
}
@@ -540,19 +587,37 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
} else {
return NULL;
}
-}
-
-
-
-
-
+}
void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
{
+ // First make sure we don't register the material twice
+ vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator it;
+ for (it = m_polymaterials.begin(); it != m_polymaterials.end(); ++it)
+ if (it->second == polymat)
+ return;
m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
}
+void KX_BlenderSceneConverter::CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat)
+{
+ m_polymat_cache[mat] = polymat;
+}
+
+RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(struct Material *mat)
+{
+ return m_polymat_cache[mat];
+}
+void KX_BlenderSceneConverter::CacheBlenderMaterial(struct Material *mat, BL_Material *blmat)
+{
+ m_mat_cache[mat] = blmat;
+}
+
+BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(struct Material *mat)
+{
+ return m_mat_cache[mat];
+}
void KX_BlenderSceneConverter::RegisterInterpolatorList(
BL_InterpolatorList *actList,
@@ -915,7 +980,67 @@ Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
return NULL;
}
-bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
+void KX_BlenderSceneConverter::MergeAsyncLoads()
+{
+ vector<KX_Scene*> *merge_scenes;
+
+ vector<KX_LibLoadStatus*>::iterator mit;
+ vector<KX_Scene*>::iterator sit;
+
+ pthread_mutex_lock(&m_threadinfo->merge_lock);
+
+ for (mit=m_mergequeue.begin(); mit!=m_mergequeue.end(); ++mit) {
+ merge_scenes = (vector<KX_Scene*>*)(*mit)->GetData();
+
+ for (sit=merge_scenes->begin(); sit!=merge_scenes->end(); ++sit) {
+ (*mit)->GetMergeScene()->MergeScene(*sit);
+ delete (*sit);
+ }
+
+
+ delete merge_scenes;
+ (*mit)->SetData(NULL);
+
+ (*mit)->Finish();
+ }
+
+ m_mergequeue.clear();
+
+ pthread_mutex_unlock(&m_threadinfo->merge_lock);
+}
+
+void KX_BlenderSceneConverter::AddScenesToMergeQueue(KX_LibLoadStatus *status)
+{
+ pthread_mutex_lock(&m_threadinfo->merge_lock);
+ m_mergequeue.push_back(status);
+ pthread_mutex_unlock(&m_threadinfo->merge_lock);
+}
+
+static void *async_convert(void *ptr)
+{
+ KX_Scene *new_scene = NULL;
+ KX_LibLoadStatus *status = (KX_LibLoadStatus*)ptr;
+ vector<Scene*> *scenes = (vector<Scene*>*)status->GetData();
+ vector<KX_Scene*> *merge_scenes = new vector<KX_Scene*>(); // Deleted in MergeAsyncLoads
+
+ for (unsigned int i=0; i<scenes->size(); ++i) {
+ new_scene = status->GetEngine()->CreateScene((*scenes)[i], true);
+
+ if (new_scene)
+ merge_scenes->push_back(new_scene);
+
+ status->AddProgress((1.f/scenes->size())*0.9f); // We'll call conversion 90% and merging 10% for now
+ }
+
+ delete scenes;
+ status->SetData(merge_scenes);
+
+ status->GetConverter()->AddScenesToMergeQueue(status);
+
+ return NULL;
+}
+
+KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
BlendHandle *bpy_openlib = BLO_blendhandle_from_memory(data, length);
@@ -923,7 +1048,7 @@ bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const
return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options);
}
-bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
+KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
BlendHandle *bpy_openlib = BLO_blendhandle_from_file((char *)path, NULL);
@@ -955,7 +1080,7 @@ static void load_datablocks(Main *main_newlib, BlendHandle *bpy_openlib, const c
BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
}
-bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
+KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
Main *main_newlib; /* stored as a dynamic 'main' until we free it */
const int idcode = BKE_idcode_from_name(group);
@@ -964,25 +1089,27 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
// TIMEIT_START(bge_link_blend_file);
+ KX_LibLoadStatus *status;
+
/* only scene and mesh supported right now */
if (idcode!=ID_SCE && idcode!=ID_ME &&idcode!=ID_AC) {
snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group);
*err_str= err_local;
BLO_blendhandle_close(bpy_openlib);
- return false;
+ return NULL;
}
if (GetMainDynamicPath(path)) {
snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path);
*err_str= err_local;
BLO_blendhandle_close(bpy_openlib);
- return false;
+ return NULL;
}
if (bpy_openlib==NULL) {
snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path);
*err_str= err_local;
- return false;
+ return NULL;
}
main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
@@ -1009,6 +1136,8 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
strncpy(main_newlib->name, path, sizeof(main_newlib->name));
+ status = new KX_LibLoadStatus(this, m_ketsjiEngine, scene_merge, path);
+
if (idcode==ID_ME) {
/* Convert all new meshes into BGE meshes */
ID* mesh;
@@ -1016,7 +1145,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
if (options & LIB_LOAD_VERBOSE)
printf("MeshName: %s\n", mesh->name+2);
- RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this);
+ RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders
scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
}
}
@@ -1033,16 +1162,30 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
else if (idcode==ID_SCE) {
/* Merge all new linked in scene into the existing one */
ID *scene;
+ // scenes gets deleted by the thread when it's done using it (look in async_convert())
+ vector<Scene*> *scenes = (options & LIB_LOAD_ASYNC) ? new vector<Scene*>() : NULL;
+
for (scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) {
if (options & LIB_LOAD_VERBOSE)
printf("SceneName: %s\n", scene->name+2);
- /* merge into the base scene */
- KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
- scene_merge->MergeScene(other);
+ if (options & LIB_LOAD_ASYNC) {
+ scenes->push_back((Scene*)scene);
+ } else {
+ /* merge into the base scene */
+ KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, true);
+ scene_merge->MergeScene(other);
- // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
- delete other;
+ // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
+ delete other;
+ }
+ }
+
+ if (options & LIB_LOAD_ASYNC) {
+ pthread_t id;
+ status->SetData(scenes);
+ pthread_create(&id, NULL, &async_convert, (void*)status);
+ m_threadinfo->threads.push_back(id);
}
#ifdef WITH_PYTHON
@@ -1063,9 +1206,14 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
}
}
+ if (!(options & LIB_LOAD_ASYNC))
+ status->Finish();
+
+
// TIMEIT_END(bge_link_blend_file);
- return true;
+ m_status_map[main_newlib->name] = status;
+ return status;
}
/* Note m_map_*** are all ok and don't need to be freed
@@ -1302,7 +1450,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
}
if (IS_TAGGED(bmat)) {
-
+ m_polymat_cache.erase((*polymit).second->GetBlenderMaterial());
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
@@ -1320,6 +1468,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
for (i=0, matit=m_materials.begin(); i<size; ) {
BL_Material *mat= (*matit).second;
if (IS_TAGGED(mat->material)) {
+ m_mat_cache.erase((*matit).second->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
@@ -1351,6 +1500,9 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
removeImportMain(maggie);
#endif
+ delete m_status_map[maggie->name];
+ m_status_map.erase(maggie->name);
+
free_main(maggie);
return true;
@@ -1469,7 +1621,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
}
}
- RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
+ RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false);
kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
return meshobj;
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index 34a1117..06dac17 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -39,6 +39,8 @@
#include "KX_ISceneConverter.h"
#include "KX_IpoConvert.h"
+#include <map>
+
using namespace std;
class KX_WorldInfo;
@@ -50,6 +52,7 @@ class BL_InterpolatorList;
class BL_Material;
struct Main;
struct Scene;
+struct ThreadInfo;
class KX_BlenderSceneConverter : public KX_ISceneConverter
{
@@ -58,6 +61,17 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials;
vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects;
vector<pair<KX_Scene*,BL_Material *> > m_materials;
+
+ vector<class KX_LibLoadStatus*> m_mergequeue;
+ ThreadInfo *m_threadinfo;
+
+ // Cached material conversions
+ map<struct Material*, BL_Material*> m_mat_cache;
+ map<struct Material*, RAS_IPolyMaterial*> m_polymat_cache;
+
+ // Saved KX_LibLoadStatus objects
+ map<char *, class KX_LibLoadStatus*> m_status_map;
+
// Should also have a list of collision shapes.
// For the time being this is held in KX_Scene::m_shapes
@@ -77,6 +91,7 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
bool m_alwaysUseExpandFraming;
bool m_usemat;
bool m_useglslmat;
+ bool m_use_mat_cache;
public:
KX_BlenderSceneConverter(
@@ -93,7 +108,8 @@ public:
virtual void ConvertScene(
class KX_Scene* destinationscene,
class RAS_IRenderTools* rendertools,
- class RAS_ICanvas* canvas
+ class RAS_ICanvas* canvas,
+ bool libloading=false
);
virtual void RemoveScene(class KX_Scene *scene);
@@ -110,8 +126,12 @@ public:
RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/);
void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
+ void CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat);
+ RAS_IPolyMaterial *FindCachedPolyMaterial(struct Material *mat);
void RegisterBlenderMaterial(BL_Material *mat);
+ void CacheBlenderMaterial(struct Material *mat, BL_Material *blmat);
+ BL_Material *FindCachedBlenderMaterial(struct Material *mat);
void RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act);
BL_InterpolatorList *FindInterpolatorList(struct bAction *for_act);
@@ -141,19 +161,26 @@ public:
virtual void SetGLSLMaterials(bool val);
virtual bool GetGLSLMaterials();
+ // cache materials during conversion
+ virtual void SetCacheMaterials(bool val);
+ virtual bool GetCacheMaterials();
+
struct Scene* GetBlenderSceneForName(const STR_String& name);
// struct Main* GetMain() { return m_maggie; }
struct Main* GetMainDynamicPath(const char *path);
vector<struct Main*> &GetMainDynamic();
- bool LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
- bool LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
- bool LinkBlendFile(struct BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
+ class KX_LibLoadStatus *LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
+ class KX_LibLoadStatus *LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
+ class KX_LibLoadStatus *LinkBlendFile(struct BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
bool MergeScene(KX_Scene *to, KX_Scene *from);
RAS_MeshObject *ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name);
bool FreeBlendFile(struct Main *maggie);
bool FreeBlendFile(const char *path);
+
+ virtual void MergeAsyncLoads();
+ void AddScenesToMergeQueue(class KX_LibLoadStatus *status);
void PrintStats() {
printf("BGE STATS!\n");
@@ -183,6 +210,7 @@ public:
LIB_LOAD_LOAD_ACTIONS = 1,
LIB_LOAD_VERBOSE = 2,
LIB_LOAD_LOAD_SCRIPTS = 4,
+ LIB_LOAD_ASYNC = 8,
};
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 0639964..695bf0c 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -523,7 +523,8 @@ void BL_ConvertActuators(const char* maggiename,
editobact->me,
blenderobject,
scene,
- converter
+ converter,
+ false
);
KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index 769abd0..5d3d0f3 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -157,7 +157,7 @@ void BL_ConvertControllers(
SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
gamecontroller = pyctrl;
#ifdef WITH_PYTHON
-
+ PyGILState_STATE gstate = PyGILState_Ensure();
pyctrl->SetNamespace(converter->GetPyNamespace());
if (pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
@@ -186,6 +186,7 @@ void BL_ConvertControllers(
}
}
+ PyGILState_Release(gstate);
#endif // WITH_PYTHON
break;
@@ -218,6 +219,7 @@ void BL_ConvertControllers(
converter->RegisterGameController(gamecontroller, bcontr);
#ifdef WITH_PYTHON
+ PyGILState_STATE gstate = PyGILState_Ensure();
if (bcontr->type==CONT_PYTHON) {
SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
/* not strictly needed but gives syntax errors early on and
@@ -232,6 +234,8 @@ void BL_ConvertControllers(
// pyctrl->Import();
}
}
+
+ PyGILState_Release(gstate);
#endif // WITH_PYTHON
//done with gamecontroller
diff --git a/source/gameengine/Converter/KX_LibLoadStatus.cpp b/source/gameengine/Converter/KX_LibLoadStatus.cpp
new file mode 100644
index 0000000..fb36f23
--- /dev/null
+++ b/source/gameengine/Converter/KX_LibLoadStatus.cpp
@@ -0,0 +1,251 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file KX_LibLoadStatus.cpp
+ * \ingroup bgeconv
+ */
+
+#include "KX_LibLoadStatus.h"
+#include "PIL_time.h"
+
+KX_LibLoadStatus::KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter,
+ class KX_KetsjiEngine* kx_engine,
+ class KX_Scene* merge_scene,
+ const char *path) :
+ m_converter(kx_converter),
+ m_engine(kx_engine),
+ m_mergescene(merge_scene),
+ m_data(NULL),
+ m_libname(path),
+ m_progress(0.f),
+#ifdef WITH_PYTHON
+ m_finish_cb(NULL),
+ m_progress_cb(NULL)
+#endif
+{
+ m_endtime = m_starttime = PIL_check_seconds_timer();
+}
+
+void KX_LibLoadStatus::Finish()
+{
+ m_progress = 1.f;
+ m_endtime = PIL_check_seconds_timer();
+
+ RunFinishCallback();
+ RunProgressCallback();
+}
+
+void KX_LibLoadStatus::RunFinishCallback()
+{
+#ifdef WITH_PYTHON
+ if (m_finish_cb) {
+ PyObject* args = Py_BuildValue("(O)", GetProxy());
+
+ if (!PyObject_Call(m_finish_cb, args, NULL)) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ Py_DECREF(args);
+ }
+#endif
+}
+
+void KX_LibLoadStatus::RunProgressCallback()
+{
+// Progess callbacks are causing threading problems with Python, so they're disabled for now
+#if 0
+#ifdef WITH_PYTHON
+ if (m_progress_cb) {
+ //PyGILState_STATE gstate = PyGILState_Ensure();
+ PyObject* args = Py_BuildValue("(O)", GetProxy());
+
+ if (!PyObject_Call(m_progress_cb, args, NULL)) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ Py_DECREF(args);
+ //PyGILState_Release(gstate);
+ }
+#endif
+#endif
+}
+
+class KX_BlenderSceneConverter *KX_LibLoadStatus::GetConverter()
+{
+ return m_converter;
+}
+
+class KX_KetsjiEngine *KX_LibLoadStatus::GetEngine()
+{
+ return m_engine;
+}
+
+class KX_Scene *KX_LibLoadStatus::GetMergeScene()
+{
+ return m_mergescene;
+}
+
+void KX_LibLoadStatus::SetLibName(const char *name)
+{
+ m_libname = name;
+}
+
+const char *KX_LibLoadStatus::GetLibName()
+{
+ return m_libname;
+}
+
+void KX_LibLoadStatus::SetData(void *data)
+{
+ m_data = data;
+}
+
+void *KX_LibLoadStatus::GetData()
+{
+ return m_data;
+}
+
+void KX_LibLoadStatus::SetProgress(float progress)
+{
+ m_progress = progress;
+ RunProgressCallback();
+}
+
+float KX_LibLoadStatus::GetProgress()
+{
+ return m_progress;
+}
+
+void KX_LibLoadStatus::AddProgress(float progress)
+{
+ m_progress += progress;
+ RunProgressCallback();
+}
+
+#ifdef WITH_PYTHON
+
+PyMethodDef KX_LibLoadStatus::Methods[] =
+{
+ {NULL} //Sentinel
+};
+
+PyAttributeDef KX_LibLoadStatus::Attributes[] = {
+ KX_PYATTRIBUTE_RW_FUNCTION("onFinish", KX_LibLoadStatus, pyattr_get_onfinish, pyattr_set_onfinish),
+ // KX_PYATTRIBUTE_RW_FUNCTION("onProgress", KX_LibLoadStatus, pyattr_get_onprogress, pyattr_set_onprogress),
+ KX_PYATTRIBUTE_FLOAT_RO("progress", KX_LibLoadStatus, m_progress),
+ KX_PYATTRIBUTE_STRING_RO("libraryName", KX_LibLoadStatus, m_libname),
+ KX_PYATTRIBUTE_RO_FUNCTION("timeTaken", KX_LibLoadStatus, pyattr_get_timetaken),
+ { NULL } //Sentinel
+};
+
+PyTypeObject KX_LibLoadStatus::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "KX_LibLoadStatus",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &PyObjectPlus::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+
+PyObject* KX_LibLoadStatus::pyattr_get_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (self->m_finish_cb) {
+ Py_INCREF(self->m_finish_cb);
+ return self->m_finish_cb;
+ }
+
+ Py_RETURN_NONE;
+}
+
+int KX_LibLoadStatus::pyattr_set_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (!PyCallable_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "KX_LibLoadStatus.onFinished requires a callable object");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (self->m_finish_cb)
+ Py_DECREF(self->m_finish_cb);
+
+ Py_INCREF(value);
+ self->m_finish_cb = value;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject* KX_LibLoadStatus::pyattr_get_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (self->m_progress_cb) {
+ Py_INCREF(self->m_progress_cb);
+ return self->m_progress_cb;
+ }
+
+ Py_RETURN_NONE;
+}
+
+int KX_LibLoadStatus::pyattr_set_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ if (!PyCallable_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "KX_LibLoadStatus.onProgress requires a callable object");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (self->m_progress_cb)
+ Py_DECREF(self->m_progress_cb);
+
+ Py_INCREF(value);
+ self->m_progress_cb = value;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject* KX_LibLoadStatus::pyattr_get_timetaken(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
+
+ return PyFloat_FromDouble(self->m_endtime - self->m_starttime);
+}
+#endif // WITH_PYTHON
diff --git a/source/gameengine/Converter/KX_LibLoadStatus.h b/source/gameengine/Converter/KX_LibLoadStatus.h
new file mode 100644
index 0000000..3da7329
--- /dev/null
+++ b/source/gameengine/Converter/KX_LibLoadStatus.h
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file KX_LibLoadStatus.h
+ * \ingroup bgeconv
+ */
+
+#ifndef __KX_LIBLOADSTATUS_H__
+#define __KX_LIBLOADSTATUS_H__
+
+#include "PyObjectPlus.h"
+
+class KX_LibLoadStatus : public PyObjectPlus
+{
+ Py_Header
+private:
+ class KX_BlenderSceneConverter* m_converter;
+ class KX_KetsjiEngine* m_engine;
+ class KX_Scene* m_mergescene;
+ void* m_data;
+ STR_String m_libname;
+
+ float m_progress;
+ double m_starttime;
+ double m_endtime;
+
+#ifdef WITH_PYTHON
+ PyObject* m_finish_cb;
+ PyObject* m_progress_cb;
+#endif
+
+public:
+ KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter,
+ class KX_KetsjiEngine* kx_engine,
+ class KX_Scene* merge_scene,
+ const char *path);
+
+ void Finish(); // Called when the libload is done
+ void RunFinishCallback();
+ void RunProgressCallback();
+
+ class KX_BlenderSceneConverter *GetConverter();
+ class KX_KetsjiEngine *GetEngine();
+ class KX_Scene *GetMergeScene();
+
+ void SetLibName(const char *name);
+ const char *GetLibName();
+
+ void SetData(void *data);
+ void *GetData();
+
+ void SetProgress(float progress);
+ float GetProgress();
+ void AddProgress(float progress);
+
+#ifdef WITH_PYTHON
+ static PyObject* pyattr_get_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+ static PyObject* pyattr_get_timetaken(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
+};
+
+#endif // __KX_LIBLOADSTATUS_H__
diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript
index b9c7091..28ad742 100644
--- a/source/gameengine/Converter/SConscript
+++ b/source/gameengine/Converter/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp
index 0a5af4a..5a2075d 100644
--- a/source/gameengine/Expressions/InputParser.cpp
+++ b/source/gameengine/Expressions/InputParser.cpp
@@ -354,7 +354,7 @@ int CParser::MakeInt()
}
#endif
-STR_String CParser::Symbol2Str(int s)
+const char *CParser::Symbol2Str(int s)
{
// returns a string representation of of symbol s,
// for use in Term when generating an error
@@ -370,18 +370,20 @@ STR_String CParser::Symbol2Str(int s)
case whocodedsym: return "WHOMADE";
case eolsym: return "end of line";
case idsym: return "identifier";
- default: return "unknown"; // should not happen
}
+ return "unknown"; // should not happen
}
void CParser::Term(int s)
{
// generates an error if the next symbol isn't the specified symbol s
// otherwise, skip the symbol
- if (s == sym) NextSym();
+ if (s == sym) {
+ NextSym();
+ }
else {
STR_String msg;
- msg.Format("Warning: " + Symbol2Str(s) + " expected\ncontinuing without it");
+ msg.Format("Warning: %s expected\ncontinuing without it", Symbol2Str(s));
// AfxMessageBox(msg,MB_ICONERROR);
diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h
index 6dfeff5..50bb1ae 100644
--- a/source/gameengine/Expressions/InputParser.h
+++ b/source/gameengine/Expressions/InputParser.h
@@ -102,7 +102,7 @@ private:
#if 0 /* not used yet */
int MakeInt();
#endif
- STR_String Symbol2Str(int s);
+ const char *Symbol2Str(int s);
void Term(int s);
int Priority(int optor);
CExpression *Ex(int i);
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 11b00b7..4e910a8 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -118,16 +118,16 @@ PyTypeObject PyObjectPlus::Type = {
0, /* setattrfunc tp_setattr; */
0, /* tp_compare */ /* DEPRECATED in python 3.0! */
py_base_repr, /* tp_repr */
- 0,0,0,0,0,0,0,0,0, /* Method suites for standard classes */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* long tp_flags; */
- 0,0,0,0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Method suites for standard classes */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* long tp_flags; */
+ 0, 0, 0, 0,
/* weak reference enabler */
#ifdef USE_WEAKREFS
offsetof(PyObjectPlus_Proxy, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
- 0,0,
+ 0, 0,
Methods,
0,
0,
@@ -311,14 +311,14 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
{
bool *val = reinterpret_cast<bool*>(ptr);
ptr += sizeof(bool);
- PyList_SET_ITEM(resultlist,i,PyBool_FromLong(*val));
+ PyList_SET_ITEM(resultlist, i, PyBool_FromLong(*val));
break;
}
case KX_PYATTRIBUTE_TYPE_SHORT:
{
short int *val = reinterpret_cast<short int*>(ptr);
ptr += sizeof(short int);
- PyList_SET_ITEM(resultlist,i,PyLong_FromLong(*val));
+ PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
break;
}
case KX_PYATTRIBUTE_TYPE_ENUM:
@@ -333,14 +333,14 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
{
int *val = reinterpret_cast<int*>(ptr);
ptr += sizeof(int);
- PyList_SET_ITEM(resultlist,i,PyLong_FromLong(*val));
+ PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
break;
}
case KX_PYATTRIBUTE_TYPE_FLOAT:
{
float *val = reinterpret_cast<float*>(ptr);
ptr += sizeof(float);
- PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(*val));
+ PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(*val));
break;
}
default:
@@ -423,7 +423,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
PyObject *resultlist = PyList_New(attrdef->m_imax);
for (unsigned int i=0; i<attrdef->m_imax; i++)
{
- PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(val[i]));
+ PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(val[i]));
}
return resultlist;
#endif
@@ -443,9 +443,9 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
PyObject *col = PyList_New(attrdef->m_imax);
for (unsigned int j=0; j<attrdef->m_imax; j++)
{
- PyList_SET_ITEM(col,j,PyFloat_FromDouble(val[j]));
+ PyList_SET_ITEM(col, j, PyFloat_FromDouble(val[j]));
}
- PyList_SET_ITEM(collist,i,col);
+ PyList_SET_ITEM(collist, i, col);
val += attrdef->m_imax;
}
return collist;
@@ -463,7 +463,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
PyObject *resultlist = PyList_New(3);
for (unsigned int i=0; i<3; i++)
{
- PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i]));
+ PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble((*val)[i]));
}
return resultlist;
#endif
@@ -1110,7 +1110,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt
------------------------------*/
PyObject *PyObjectPlus::py_repr(void)
{
- PyErr_SetString(PyExc_SystemError, "Representation not overridden by object.");
+ PyErr_SetString(PyExc_SystemError, "Representation not overridden by object.");
return NULL;
}
@@ -1187,7 +1187,7 @@ void PyObjectPlus::SetDeprecationWarnings(bool ignoreDeprecationWarnings)
m_ignore_deprecation_warnings = ignoreDeprecationWarnings;
}
-void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* new_way)
+void PyObjectPlus::ShowDeprecationWarning_func(const char *old_way, const char *new_way)
{
printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way);
PyC_LineSpit();
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 37e26e8..e2e7c24 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -389,139 +389,139 @@ typedef struct KX_PYATTRIBUTE_DEF {
} m_typeCheck;
} PyAttributeDef;
-#define KX_PYATTRIBUTE_BOOL_RW(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_BOOL_RW_CHECK(name,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_BOOL_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_BOOL_RW(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_BOOL_RW_CHECK(name, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RW, 0, 1, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_BOOL_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_BOOL, KX_PYATTRIBUTE_RO, 0, 1, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {&((object *)0)->field, NULL, NULL, NULL, NULL, NULL, NULL} }
/* attribute points to a single bit of an integer field, attribute=true if bit is set */
-#define KX_PYATTRIBUTE_FLAG_RW(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_RW_CHECK(name,object,field,bit,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_RO(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_RW(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_RW_CHECK(name, object, field, bit, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_RO(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
/* attribute points to a single bit of an integer field, attribute=true if bit is set*/
-#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW_CHECK(name,object,field,bit,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RO(name,object,field,bit) \
- { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 1, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RW_CHECK(name, object, field, bit, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RW, bit, 1, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLAG_NEGATIVE_RO(name, object, field, bit) \
+ { name, KX_PYATTRIBUTE_TYPE_FLAG, KX_PYATTRIBUTE_RO, bit, 1, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
// enum field cannot be mapped to pointer (because we would need a pointer for each enum)
// use field size to verify mapping at runtime only, assuming enum size is equal to int size.
-#define KX_PYATTRIBUTE_ENUM_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ENUM_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ENUM_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-
-#define KX_PYATTRIBUTE_SHORT_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ENUM_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ENUM_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ENUM_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_ENUM, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+
+#define KX_PYATTRIBUTE_SHORT_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
// SHORT_LIST
-#define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
-
-#define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL, NULL, NULL} }
+
+#define KX_PYATTRIBUTE_INT_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_ARRAY_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_ARRAY_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL, NULL, NULL} }
// INT_LIST
-#define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RW(name, min, max, clamp, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name, min, max, clamp, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL, NULL, NULL} }
// always clamp for float
-#define KX_PYATTRIBUTE_FLOAT_RW(name,min,max,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name,min,max,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_RW(name, min, max, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_RW_CHECK(name, min, max, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL, NULL, NULL} }
// field must be float[n], returns a sequence
-#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name, min, max, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name, min, max, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, length, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, length, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
// field must be float[n], returns a vector
-#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_VECTOR_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW(name, min, max, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_VECTOR_RW_CHECK(name, min, max, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_VECTOR_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, length, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL, NULL, NULL} }
// field must be float[n][n], returns a matrix
-#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_FLOAT_MATRIX_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, length, length, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW(name, min, max, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_MATRIX_RW_CHECK(name, min, max, object, field, length, function) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, length, length, min, max, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_FLOAT_MATRIX_RO(name, object, field, length) \
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, length, length, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, ((object *)0)->field[0], NULL, NULL, NULL} }
// only for STR_String member
-#define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
-#define KX_PYATTRIBUTE_STRING_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
-#define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_STRING_RW(name, min, max, clamp, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_STRING_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_STRING_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field, NULL, NULL} }
// only for char [] array
-#define KX_PYATTRIBUTE_CHAR_RW(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
-#define KX_PYATTRIBUTE_CHAR_RW_CHECK(name,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object,field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
-#define KX_PYATTRIBUTE_CHAR_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), sizeof(((object *)0)->field), 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
+#define KX_PYATTRIBUTE_CHAR_RW(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
+#define KX_PYATTRIBUTE_CHAR_RW_CHECK(name, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, true, false, offsetof(object, field), sizeof(((object *)0)->field), 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
+#define KX_PYATTRIBUTE_CHAR_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_CHAR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), sizeof(((object *)0)->field), 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, NULL, ((object *)0)->field} }
// for MT_Vector3 member
-#define KX_PYATTRIBUTE_VECTOR_RW(name,min,max,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
-#define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name,min,max,clamp,object,field,function) \
- { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object,field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
-#define KX_PYATTRIBUTE_VECTOR_RO(name,object,field) \
- { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object,field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
-
-#define KX_PYATTRIBUTE_RW_FUNCTION(name,object,getfunction,setfunction) \
+#define KX_PYATTRIBUTE_VECTOR_RW(name, min, max, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+#define KX_PYATTRIBUTE_VECTOR_RW_CHECK(name, min, max, clamp, object, field, function) \
+ { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, false, offsetof(object, field), 0, 1, &object::function, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+#define KX_PYATTRIBUTE_VECTOR_RO(name, object, field) \
+ { name, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, offsetof(object, field), 0, 1 , NULL, NULL, NULL, {NULL, NULL, NULL, NULL, NULL, &((object *)0)->field, NULL} }
+
+#define KX_PYATTRIBUTE_RW_FUNCTION(name, object, getfunction, setfunction) \
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_RO_FUNCTION(name,object,getfunction) \
+#define KX_PYATTRIBUTE_RO_FUNCTION(name, object, getfunction) \
{ name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, false, 0, 0, 1, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name,object,length,getfunction,setfunction) \
- { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
-#define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name,object,length,getfunction) \
- { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0,f, false, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ARRAY_RW_FUNCTION(name, object, length, getfunction, setfunction) \
+ { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RW, 0, 0, 0.f, 0, f, false, false, 0, 0, length, NULL, &object::setfunction, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_ARRAY_RO_FUNCTION(name, object, length, getfunction) \
+ { name, KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0, f, false, false, 0, 0, length, NULL, NULL, &object::getfunction, {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
/*------------------------------
@@ -614,7 +614,7 @@ public:
/** enable/disable display of deprecation warnings */
static void SetDeprecationWarnings(bool ignoreDeprecationWarnings);
/** Shows a deprecation warning */
- static void ShowDeprecationWarning_func(const char* method,const char* prop);
+ static void ShowDeprecationWarning_func(const char *method, const char *prop);
static void ClearDeprecationWarning();
#endif
diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript
index 4dc165a..a6d82a4 100644
--- a/source/gameengine/Expressions/SConscript
+++ b/source/gameengine/Expressions/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index e511704..ad357bd 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SRC
SCA_PropertyEventManager.cpp
SCA_PropertySensor.cpp
SCA_PythonController.cpp
+ SCA_PythonJoystick.cpp
SCA_PythonKeyboard.cpp
SCA_PythonMouse.cpp
SCA_RandomActuator.cpp
@@ -114,6 +115,7 @@ set(SRC
SCA_PropertyEventManager.h
SCA_PropertySensor.h
SCA_PythonController.h
+ SCA_PythonJoystick.h
SCA_PythonKeyboard.h
SCA_PythonMouse.h
SCA_RandomActuator.h
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 8b343be..dce62ad 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -307,8 +307,11 @@ int SCA_Joystick::pGetAxis(int axisnum, int udlr)
int SCA_Joystick::pAxisTest(int axisnum)
{
#ifdef WITH_SDL
- short i1 = m_axis_array[(axisnum * 2)];
- short i2 = m_axis_array[(axisnum * 2) + 1];
+ /* Use ints instead of shorts here to avoid problems when we get -32768.
+ * When we take the negative of that later, we should get 32768, which is greater
+ * than what a short can hold. In other words, abs(MIN_SHORT) > MAX_SHRT. */
+ int i1 = m_axis_array[(axisnum * 2)];
+ int i2 = m_axis_array[(axisnum * 2) + 1];
/* long winded way to do:
* return max_ff(absf(i1), absf(i2))
@@ -321,3 +324,12 @@ int SCA_Joystick::pAxisTest(int axisnum)
return 0;
#endif /* WITH_SDL */
}
+
+const char *SCA_Joystick::GetName()
+{
+#ifdef WITH_SDL
+ return SDL_JoystickName(m_joyindex);
+#else /* WITH_SDL */
+ return "";
+#endif /* WITH_SDL */
+}
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
index 912484a..dd9fbef 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
@@ -192,6 +192,11 @@ public:
* Test if the joystick is connected
*/
int Connected(void);
+
+ /**
+ * Name of the joytsick
+ */
+ const char *GetName();
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 5ad5aed..6a87d3c 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -97,6 +97,11 @@ bool SCA_2DFilterActuator::Update()
}
+void SCA_2DFilterActuator::SetScene(SCA_IScene *scene)
+{
+ m_scene = scene;
+}
+
void SCA_2DFilterActuator::SetShaderText(const char *text)
{
m_shaderText = text;
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index a754d95..4635a8a 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -64,6 +64,8 @@ public:
virtual ~SCA_2DFilterActuator();
virtual bool Update();
+ void SetScene(SCA_IScene *scene);
+
virtual CValue* GetReplica();
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index c21db79..780e4e9 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -60,14 +60,16 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
+ // We should always handle events in case we want to grab them with Python
+#ifdef WITH_SDL
+ SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
+#endif
+
if (m_sensors.Empty()) {
return;
}
else {
;
-#ifdef WITH_SDL
- SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
-#endif
SG_DList::iterator<SCA_JoystickSensor> it(m_sensors);
for (it.begin();!it.end();++it)
{
diff --git a/source/gameengine/GameLogic/SCA_PythonJoystick.cpp b/source/gameengine/GameLogic/SCA_PythonJoystick.cpp
new file mode 100644
index 0000000..9b24ad7
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonJoystick.cpp
@@ -0,0 +1,188 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gameengine/GameLogic/SCA_PythonJoystick.cpp
+ * \ingroup gamelogic
+ */
+
+
+#include "SCA_PythonJoystick.h"
+#include "./Joystick/SCA_Joystick.h"
+#include "SCA_IInputDevice.h"
+
+//#include "GHOST_C-api.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_PythonJoystick::SCA_PythonJoystick(SCA_Joystick* joystick)
+: PyObjectPlus(),
+m_joystick(joystick)
+{
+#ifdef WITH_PYTHON
+ m_event_dict = PyDict_New();
+#endif
+}
+
+SCA_PythonJoystick::~SCA_PythonJoystick()
+{
+ // The joystick reference we got in the constructor was a new instance,
+ // so we release it here
+ m_joystick->ReleaseInstance();
+
+#ifdef WITH_PYTHON
+ PyDict_Clear(m_event_dict);
+ Py_DECREF(m_event_dict);
+#endif
+}
+
+#ifdef WITH_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+PyObject* SCA_PythonJoystick::py_repr(void)
+{
+ return PyUnicode_FromString(m_joystick->GetName());
+}
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_PythonJoystick::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "SCA_PythonJoystick",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &PyObjectPlus::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef SCA_PythonJoystick::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef SCA_PythonJoystick::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("numAxis", SCA_PythonJoystick, pyattr_get_num_x),
+ KX_PYATTRIBUTE_RO_FUNCTION("activeButtons", SCA_PythonJoystick, pyattr_get_active_buttons),
+ KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_PythonJoystick, pyattr_get_hat_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("axisValues", SCA_PythonJoystick, pyattr_get_axis_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("name", SCA_PythonJoystick, pyattr_get_name),
+ { NULL } //Sentinel
+};
+
+// Use one function for numAxis, numButtons, and numHats
+PyObject* SCA_PythonJoystick::pyattr_get_num_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ if (strcmp(attrdef->m_name, "numButtons") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfButtons());
+ else if (strcmp(attrdef->m_name, "numAxis") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfAxes());
+ else if (strcmp(attrdef->m_name, "numHats") == 0)
+ return PyLong_FromLong(self->m_joystick->GetNumberOfHats());
+
+ // If we got here, we have a problem...
+ PyErr_SetString(PyExc_AttributeError, "invalid attribute");
+ return NULL;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_active_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ const int button_number = self->m_joystick->GetNumberOfButtons();
+
+ PyObject *list = PyList_New(0);
+ PyObject *value;
+
+ for (int i=0; i < button_number; i++) {
+ if (self->m_joystick->aButtonPressIsPositive(i)) {
+ value = PyLong_FromLong(i);
+ PyList_Append(list, value);
+ Py_DECREF(value);
+ }
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int hat_index = self->m_joystick->GetNumberOfHats();
+ PyObject *list = PyList_New(hat_index);
+
+ while (hat_index--) {
+ PyList_SET_ITEM(list, hat_index, PyLong_FromLong(self->m_joystick->GetHat(hat_index)));
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ int axis_index = self->m_joystick->GetNumberOfAxes();
+ PyObject *list = PyList_New(axis_index);
+ int position;
+
+ while (axis_index--) {
+ position = self->m_joystick->GetAxisPosition(axis_index);
+
+ // We get back a range from -32768 to 32767, so we use an if here to
+ // get a perfect -1.0 to 1.0 mapping. Some oddball system might have an
+ // actual min of -32767 for shorts, so we use SHRT_MIN/MAX to be safe.
+ if (position < 0)
+ PyList_SET_ITEM(list, axis_index, PyFloat_FromDouble(position/((double)-SHRT_MIN)));
+ else
+ PyList_SET_ITEM(list, axis_index, PyFloat_FromDouble(position/(double)SHRT_MAX));
+ }
+
+ return list;
+}
+
+PyObject* SCA_PythonJoystick::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_PythonJoystick* self = static_cast<SCA_PythonJoystick*>(self_v);
+
+ return PyUnicode_FromString(self->m_joystick->GetName());
+}
+#endif
diff --git a/source/gameengine/GameLogic/SCA_PythonJoystick.h b/source/gameengine/GameLogic/SCA_PythonJoystick.h
new file mode 100644
index 0000000..15c6285
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_PythonJoystick.h
@@ -0,0 +1,56 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Mitchell Stokes.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file SCA_PythonJoystick.h
+ * \ingroup gamelogic
+ */
+
+#ifndef __SCA_PYTHONJOYSTICK_H__
+#define __SCA_PYTHONJOYSTICK_H__
+
+#include "PyObjectPlus.h"
+
+class SCA_PythonJoystick : public PyObjectPlus
+{
+ Py_Header
+private:
+ class SCA_Joystick *m_joystick;
+#ifdef WITH_PYTHON
+ PyObject* m_event_dict;
+#endif
+public:
+ SCA_PythonJoystick(class SCA_Joystick* joystick);
+ virtual ~SCA_PythonJoystick();
+
+#ifdef WITH_PYTHON
+ virtual PyObject* py_repr(void);
+
+ static PyObject* pyattr_get_num_x(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_active_buttons(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hat_values(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_axis_values(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+#endif
+};
+
+#endif //__SCA_PYTHONJOYSTICK_H__
+
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index da3c0fa..b274e51 100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp')
diff --git a/source/gameengine/GamePlayer/SConscript b/source/gameengine/GamePlayer/SConscript
index 0b140bb..d1930ac 100644
--- a/source/gameengine/GamePlayer/SConscript
+++ b/source/gameengine/GamePlayer/SConscript
@@ -1,3 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
SConscript(['common/SConscript',
'ghost/SConscript'])
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
index b5c1c29..058454c 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
@@ -131,7 +131,15 @@ void GPC_Canvas::SetViewPort(int x1, int y1, int x2, int y2)
glViewport(x1,y1,x2-x1 + 1,y2-y1 + 1);
glScissor(x1,y1,x2-x1 + 1,y2-y1 + 1);
-};
+}
+
+void GPC_Canvas::UpdateViewPort(int x1, int y1, int x2, int y2)
+{
+ m_viewport[0] = x1;
+ m_viewport[1] = y1;
+ m_viewport[2] = x2;
+ m_viewport[3] = y2;
+}
const int *GPC_Canvas::GetViewPort()
{
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
index ec5375c..00c5911 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.h
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -155,6 +155,7 @@ public:
);
void SetViewPort(int x1, int y1, int x2, int y2);
+ void UpdateViewPort(int x1, int y1, int x2, int y2);
const int *GetViewPort();
void ClearColor(float r, float g, float b, float a);
diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript
index 6a1f47c..1648d8a 100644
--- a/source/gameengine/GamePlayer/common/SConscript
+++ b/source/gameengine/GamePlayer/common/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 92db1fe..89d1151 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -76,7 +76,6 @@ extern "C"
#include "SCA_IActuator.h"
#include "RAS_MeshObject.h"
#include "RAS_OpenGLRasterizer.h"
-#include "RAS_VAOpenGLRasterizer.h"
#include "RAS_ListRasterizer.h"
#include "RAS_GLExtensionManager.h"
#include "KX_PythonInit.h"
@@ -582,16 +581,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
if (!m_rendertools)
goto initFailed;
- if (useLists) {
- if (GLEW_VERSION_1_1)
- m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
- else
- m_rasterizer = new RAS_ListRasterizer(m_canvas);
- }
- else if (GLEW_VERSION_1_1)
- m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
+ //Don't use displaylists with VBOs
+ //If auto starts using VBOs, make sure to check for that here
+ if (useLists && gm->raster_storage != RAS_STORE_VBO)
+ m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage);
else
- m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
+ m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage);
/* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
@@ -708,6 +703,8 @@ bool GPG_Application::startEngine(void)
m_sceneconverter->SetMaterials(true);
if (m_blenderglslmat && (m_globalSettings->matmode == GAME_MAT_GLSL))
m_sceneconverter->SetGLSLMaterials(true);
+ if (m_startScene->gm.flag & GAME_NO_MATERIAL_CACHING)
+ m_sceneconverter->SetCacheMaterials(false);
KX_Scene* startscene = new KX_Scene(m_keyboard,
m_mouse,
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index ba7d313..26e9bcb 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -1004,7 +1004,7 @@ int main(int argc, char** argv)
// Enter main loop
bool run = true;
- char *python_main = NULL;
+ char *python_main = NULL;
pynextframestate.state = NULL;
pynextframestate.func = NULL;
#ifdef WITH_PYTHON
@@ -1015,24 +1015,24 @@ int main(int argc, char** argv)
char *python_code = KX_GetPythonCode(maggie, python_main);
if (python_code)
{
-#ifdef WITH_PYTHON
+#ifdef WITH_PYTHON
gpg_nextframestate.system = system;
gpg_nextframestate.app = &app;
gpg_nextframestate.gs = &gs;
pynextframestate.state = &gpg_nextframestate;
pynextframestate.func = &GPG_PyNextFrame;
- printf("Yielding control to Python script '%s'...\n", python_main);
- PyRun_SimpleString(python_code);
- printf("Exit Python script '%s'\n", python_main);
+ printf("Yielding control to Python script '%s'...\n", python_main);
+ PyRun_SimpleString(python_code);
+ printf("Exit Python script '%s'\n", python_main);
#endif // WITH_PYTHON
- MEM_freeN(python_code);
- }
- else {
- fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
- }
- }
- else
+ MEM_freeN(python_code);
+ }
+ else {
+ fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
+ }
+ }
+ else
{
while (run)
{
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index fb046d0..64bd58a 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/GamePlayer/xembed/UnixShell.c b/source/gameengine/GamePlayer/xembed/UnixShell.c
index ed6dd65..7d4b249 100644
--- a/source/gameengine/GamePlayer/xembed/UnixShell.c
+++ b/source/gameengine/GamePlayer/xembed/UnixShell.c
@@ -310,7 +310,7 @@ NPP_NewStream(
return NPERR_INVALID_INSTANCE_ERROR;
printf("Loading main file %s (%s)\n", stream->url, type);
- if ( strcmp(type,"text/html") == 0 ) /* original HTML file */
+ if (strcmp(type, "text/html") == 0) /* original HTML file */
return NPERR_NO_ERROR;
This->stream_total = stream->end;
@@ -541,7 +541,7 @@ static void
log_entry(char* msg)
{
#ifdef NZC_GENERATE_LOG
- FILE* fp = fopen("/tmp/plugin_log","a");
+ FILE* fp = fopen("/tmp/plugin_log", "a");
if (!fp) return;
fprintf(fp, "--> Unixshell:: %s\n",
msg);
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 23bfd7a..64e191f 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -95,21 +95,15 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
ras->SetTexCoordNum(0);
ras->SetAttribNum(attrib_num);
- for (i=0; i<attrib_num; i++)
+ for (i = 0; i < attrib_num; i++)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i);
for (i = 0; i < attribs.totlayer; i++) {
if (attribs.layer[i].glindex > attrib_num)
continue;
- if (attribs.layer[i].type == CD_MTFACE) {
- if (!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
- else if (!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
- else
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
- }
+ if (attribs.layer[i].type == CD_MTFACE)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex);
else if (attribs.layer[i].type == CD_TANGENT)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
else if (attribs.layer[i].type == CD_ORCO)
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 0954aa0..461a8c5 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -20,15 +20,6 @@ MTex* getImageFromMaterial(Material *mat, int index)
return m?m:0;
}
-int getNumTexChannels( Material *mat )
-{
- int count = -1;
- if (!mat) return -1;
-
- for (count =0; (count < 10) && mat->mtex[count] != 0; count++) {}
- return count;
-}
-
BL_Material::BL_Material()
{
Initialize();
@@ -36,7 +27,10 @@ BL_Material::BL_Material()
void BL_Material::Initialize()
{
- m_mcol = 0xFFFFFFFFL;
+ rgb[0] = 0;
+ rgb[1] = 0;
+ rgb[2] = 0;
+ rgb[3] = 0;
IdMode = 0;
ras_mode = 0;
glslmat = 0;
@@ -64,7 +58,7 @@ void BL_Material::Initialize()
int i;
- for (i=0; i<MAXTEX; i++) // :(
+ for (i = 0; i < MAXTEX; i++) // :(
{
mapping[i].mapping = 0;
mapping[i].offsets[0] = 0.f;
@@ -90,15 +84,6 @@ void BL_Material::Initialize()
}
}
-void BL_Material::SetUVLayerName(const STR_String& name)
-{
- uvName = name;
-}
-void BL_Material::SetUVLayerName2(const STR_String& name)
-{
- uv2Name = name;
-}
-
void BL_Material::SetSharedMaterial(bool v)
{
if ((v && num_users == -1) || num_users > 1 )
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index ef180ed..0383c08 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -87,13 +87,8 @@ public:
MTFace tface; /* copy of the derived meshes tface */
Image* img[MAXTEX];
EnvMap* cubemap[MAXTEX];
- unsigned int m_mcol; /* for text color (only) */
- STR_String uvName;
- STR_String uv2Name;
-
- void SetUVLayerName(const STR_String &name);
- void SetUVLayerName2(const STR_String &name);
+ unsigned int rgb[4];
void SetSharedMaterial(bool v);
bool IsShared();
@@ -180,7 +175,6 @@ enum BL_MappingProj
// ------------------------------------
//extern void initBL_Material(BL_Material* mat);
extern MTex* getImageFromMaterial(Material *mat, int index);
-extern int getNumTexChannels( Material *mat );
// ------------------------------------
#endif
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 66423ed..98fff5c 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -60,6 +60,7 @@ public:
typedef std::map<char*, BL_TextureObject> BL_TextureMap;
static BL_TextureMap g_textureManager;
+static GLint g_max_units = -1;
BL_Texture::BL_Texture()
@@ -379,14 +380,17 @@ unsigned int BL_Texture::GetTextureType() const
int BL_Texture::GetMaxUnits()
{
- GLint unit=0;
-
- if (GLEW_ARB_multitexture) {
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
- return (MAXTEX>=unit?unit:MAXTEX);
+ if (g_max_units < 0) {
+ GLint unit;
+ if (GLEW_ARB_multitexture) {
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit);
+ g_max_units = (MAXTEX>=unit)?unit:MAXTEX;
+ } else {
+ g_max_units = 0;
+ }
}
- return 0;
+ return g_max_units;
}
void BL_Texture::ActivateFirst()
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 524a38a..e42c2a7 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -252,7 +252,7 @@ if(WITH_BULLET)
../Physics/Bullet
)
list(APPEND INC
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
)
add_definitions(-DUSE_BULLET)
endif()
diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript
index 3d69650..40a1ec1 100644
--- a/source/gameengine/Ketsji/KXNetwork/SConscript
+++ b/source/gameengine/Ketsji/KXNetwork/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 20c36c2..a55dd70 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -60,7 +60,8 @@ KX_BlenderMaterial::KX_BlenderMaterial()
void KX_BlenderMaterial::Initialize(
KX_Scene *scene,
BL_Material *data,
- GameSettings *game)
+ GameSettings *game,
+ int lightlayer)
{
RAS_IPolyMaterial::Initialize(
data->texname[0],
@@ -84,6 +85,7 @@ void KX_BlenderMaterial::Initialize(
mModified = 0;
mConstructed = false;
mPass = 0;
+ mLightLayer = lightlayer;
// --------------------------------
// RAS_IPolyMaterial variables...
m_flag |= RAS_BLENDERMAT;
@@ -92,16 +94,11 @@ void KX_BlenderMaterial::Initialize(
m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0;
m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0;
- // figure max
- int enabled = mMaterial->num_enabled;
- int max = BL_Texture::GetMaxUnits();
- mMaterial->num_enabled = enabled>=max?max:enabled;
-
// test the sum of the various modes for equality
// so we can ether accept or reject this material
// as being equal, this is rather important to
// prevent material bleeding
- for (int i=0; i<mMaterial->num_enabled; i++) {
+ for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]);
}
m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT));
@@ -124,7 +121,7 @@ MTFace* KX_BlenderMaterial::GetMTFace(void) const
unsigned int* KX_BlenderMaterial::GetMCol(void) const
{
// fonts on polys
- return &mMaterial->m_mcol;
+ return mMaterial->rgb;
}
void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
@@ -138,11 +135,6 @@ void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
}
-bool KX_BlenderMaterial::IsMaterial(const BL_Material *bl_mat) const
-{
- return (mMaterial == bl_mat);
-}
-
Material *KX_BlenderMaterial::GetBlenderMaterial() const
{
return mMaterial->material;
@@ -163,7 +155,7 @@ void KX_BlenderMaterial::InitTextures()
{
// for each unique material...
int i;
- for (i=0; i<mMaterial->num_enabled; i++) {
+ for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
if ( mMaterial->mapping[i].mapping & USEENV ) {
if (!GLEW_ARB_texture_cube_map) {
spit("CubeMap textures not supported");
@@ -185,14 +177,14 @@ void KX_BlenderMaterial::InitTextures()
}
}
-void KX_BlenderMaterial::OnConstruction(int layer)
+void KX_BlenderMaterial::OnConstruction()
{
if (mConstructed)
// when material are reused between objects
return;
if (mMaterial->glslmat)
- SetBlenderGLSLShader(layer);
+ SetBlenderGLSLShader();
InitTextures();
@@ -239,7 +231,8 @@ void KX_BlenderMaterial::OnExit()
}
BL_Texture::ActivateFirst();
- for (int i=0; i<mMaterial->num_enabled; i++) {
+ for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
+ if (!mTextures[i].Ok()) continue;
BL_Texture::ActivateUnit(i);
mTextures[i].DeleteTex();
mTextures[i].DisableUnit();
@@ -278,7 +271,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
mShader->ApplyShader();
// for each enabled unit
- for (i=0; i<mMaterial->num_enabled; i++) {
+ for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
if (!mTextures[i].Ok()) continue;
mTextures[i].ActivateTexture();
mTextures[0].SetMapping(mMaterial->mapping[i].mapping);
@@ -354,7 +347,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
}
int mode = 0,i=0;
- for (i=0; (i<mMaterial->num_enabled && i<MAXTEX); i++) {
+ for (i=0; i<BL_Texture::GetMaxUnits(); i++) {
if ( !mTextures[i].Ok() ) continue;
mTextures[i].ActivateTexture();
@@ -647,16 +640,9 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
ras->SetTexCoordNum(mMaterial->num_enabled);
- for (int i=0; i<mMaterial->num_enabled; i++) {
+ for (int i=0; i<BL_Texture::GetMaxUnits(); i++) {
int mode = mMaterial->mapping[i].mapping;
- if (mode &USECUSTOMUV)
- {
- if (!mMaterial->mapping[i].uvCoName.IsEmpty())
- ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
- continue;
- }
-
if ( mode &(USEREFL|USEOBJ))
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i);
else if (mode &USEORCO)
@@ -664,7 +650,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
else if (mode &USENORM)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i);
else if (mode &USEUV)
- ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i);
+ ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i);
else if (mode &USETANG)
ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i);
else
@@ -790,10 +776,19 @@ void KX_BlenderMaterial::UpdateIPO(
mMaterial->ref = (float)(ref);
}
-void KX_BlenderMaterial::SetBlenderGLSLShader(int layer)
+void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
+{
+ mScene= static_cast<KX_Scene *>(val);
+ if (mBlenderShader)
+ mBlenderShader->SetScene(mScene);
+
+ OnConstruction();
+}
+
+void KX_BlenderMaterial::SetBlenderGLSLShader()
{
if (!mBlenderShader)
- mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer);
+ mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, mLightLayer);
if (!mBlenderShader->Ok()) {
delete mBlenderShader;
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 7bc9c7c..c34a49e 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -39,7 +39,8 @@ public:
void Initialize(
class KX_Scene* scene,
BL_Material* mat,
- GameSettings* game
+ GameSettings* game,
+ int lightlayer
);
virtual ~KX_BlenderMaterial();
@@ -76,8 +77,6 @@ public:
TCachingInfo& cachingInfo
)const;
- /* mMaterial is private, but need this for conversion */
- bool IsMaterial(const BL_Material *bl_mat) const;
Material* GetBlenderMaterial() const;
MTFace* GetMTFace(void) const;
unsigned int* GetMCol(void) const;
@@ -97,14 +96,7 @@ public:
MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
);
- virtual void Replace_IScene(SCA_IScene *val)
- {
- mScene= static_cast<KX_Scene *>(val);
- if (mBlenderShader)
- {
- mBlenderShader->SetScene(mScene);
- }
- };
+ virtual void Replace_IScene(SCA_IScene *val);
#ifdef WITH_PYTHON
// --------------------------------
@@ -125,7 +117,7 @@ public:
// --------------------------------
// pre calculate to avoid pops/lag at startup
- virtual void OnConstruction(int layer);
+ virtual void OnConstruction();
static void EndFrame();
@@ -139,10 +131,11 @@ private:
unsigned int mBlendFunc[2];
bool mModified;
bool mConstructed; // if false, don't clean on exit
+ int mLightLayer;
void InitTextures();
- void SetBlenderGLSLShader(int layer);
+ void SetBlenderGLSLShader();
void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
void ActivateTexGen( RAS_IRasterizer *ras ) const;
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 59ca0d8..792a075 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -115,7 +115,7 @@ void KX_CameraActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
/* copied from blender BLI_math ... don't know if there's an equivalent */
-static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis)
+static void Kx_VecUpMat3(float vec[3], float mat[3][3], short axis)
{
// Construct a camera matrix s.t. the specified axis
diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
index ce208f3..64bbbb7 100644
--- a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp
@@ -45,6 +45,8 @@ PyTypeObject KX_CharacterWrapper::Type = {
PyAttributeDef KX_CharacterWrapper::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("onGround", KX_CharacterWrapper, pyattr_get_onground),
KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_CharacterWrapper, pyattr_get_gravity, pyattr_set_gravity),
+ KX_PYATTRIBUTE_RW_FUNCTION("maxJumps", KX_CharacterWrapper, pyattr_get_max_jumps, pyattr_set_max_jumps),
+ KX_PYATTRIBUTE_RO_FUNCTION("jumpCount", KX_CharacterWrapper, pyattr_get_jump_count),
{ NULL } //Sentinel
};
@@ -77,6 +79,35 @@ int KX_CharacterWrapper::pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_D
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_CharacterWrapper::pyattr_get_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+
+ return PyLong_FromLong(self->m_character->GetMaxJumps());
+}
+
+int KX_CharacterWrapper::pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+ long param = PyLong_AsLong(value);
+
+ if (param == -1)
+ {
+ PyErr_SetString(PyExc_ValueError, "KX_CharacterWrapper.maxJumps: expected an integer");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ self->m_character->SetMaxJumps((int)param);
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject *KX_CharacterWrapper::pyattr_get_jump_count(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_CharacterWrapper* self = static_cast<KX_CharacterWrapper*>(self_v);
+
+ return PyLong_FromLong(self->m_character->GetJumpCount());
+}
+
PyMethodDef KX_CharacterWrapper::Methods[] = {
KX_PYMETHODTABLE_NOARGS(KX_CharacterWrapper, jump),
{NULL,NULL} //Sentinel
diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.h b/source/gameengine/Ketsji/KX_CharacterWrapper.h
index 3b0058a..f1c977f 100644
--- a/source/gameengine/Ketsji/KX_CharacterWrapper.h
+++ b/source/gameengine/Ketsji/KX_CharacterWrapper.h
@@ -26,6 +26,9 @@ public:
static PyObject* pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_max_jumps(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_jump_count(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
#endif // WITH_PYTHON
private:
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index c7f6954..eec4566 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -42,7 +42,6 @@ typedef unsigned __int64 uint_ptr;
typedef unsigned long uint_ptr;
#endif
-#define KX_INERTIA_INFINITE 10000
#include "RAS_IPolygonMaterial.h"
#include "KX_BlenderMaterial.h"
#include "KX_GameObject.h"
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
index 18fb336..616895a 100644
--- a/source/gameengine/Ketsji/KX_ISceneConverter.h
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -57,10 +57,14 @@ public:
virtual void ConvertScene(
class KX_Scene* destinationscene,
class RAS_IRenderTools* rendertools,
- class RAS_ICanvas* canvas)=0;
+ class RAS_ICanvas* canvas,
+ bool libloading=false)=0;
virtual void RemoveScene(class KX_Scene *scene)=0;
+ // handle any pending merges from asynchronous loads
+ virtual void MergeAsyncLoads()=0;
+
virtual void SetAlwaysUseExpandFraming(bool to_what) = 0;
virtual void SetNewFileName(const STR_String& filename) = 0;
@@ -85,6 +89,10 @@ public:
virtual void SetGLSLMaterials(bool val) =0;
virtual bool GetGLSLMaterials()=0;
+ // cache materials during conversion
+ virtual void SetCacheMaterials(bool val) =0;
+ virtual bool GetCacheMaterials()=0;
+
virtual struct Scene* GetBlenderSceneForName(const STR_String& name)=0;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index a12e12c..87683f8 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -83,7 +83,7 @@
// not valid, skip rendering this frame.
//#define NZC_GUARDED_OUTPUT
#define DEFAULT_LOGIC_TIC_RATE 60.0
-#define DEFAULT_PHYSICS_TIC_RATE 60.0
+//#define DEFAULT_PHYSICS_TIC_RATE 60.0
#ifdef FREE_WINDOWS /* XXX mingw64 (gcc 4.7.0) defines a macro for DrawText that translates to DrawTextA. Not good */
#ifdef DrawText
@@ -592,6 +592,8 @@ bool KX_KetsjiEngine::NextFrame()
m_frameTime += framestep;
+ m_sceneconverter->MergeAsyncLoads();
+
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
// for each scene, call the proceed functions
{
@@ -1165,7 +1167,7 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
/* binds framebuffer object, sets up camera .. */
- light->BindShadowBuffer(m_rasterizer, cam, camtrans);
+ light->BindShadowBuffer(m_rasterizer, m_canvas, cam, camtrans);
/* update scene */
scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
@@ -1686,7 +1688,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
}
}
-KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
+KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
{
KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
m_mousedevice,
@@ -1697,7 +1699,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
m_sceneconverter->ConvertScene(tmpscene,
m_rendertools,
- m_canvas);
+ m_canvas,
+ libloading);
return tmpscene;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 972594b..92ffaf4 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -413,7 +413,7 @@ public:
void GetOverrideFrameColor(float& r, float& g, float& b) const;
KX_Scene* CreateScene(const STR_String& scenename);
- KX_Scene* CreateScene(Scene *scene);
+ KX_Scene* CreateScene(Scene *scene, bool libloading=false);
GlobalSettings* GetGlobalSettings(void);
void SetGlobalSettings(GlobalSettings* gs);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index cf58d18..5414a4d 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -236,7 +236,7 @@ int KX_LightObject::GetShadowLayer()
return 0;
}
-void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans)
+void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans)
{
GPULamp *lamp;
float viewmat[4][4], winmat[4][4];
@@ -246,6 +246,9 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T
lamp = GetGPULamp();
GPU_lamp_shadow_buffer_bind(lamp, viewmat, &winsize, winmat);
+ /* GPU_lamp_shadow_buffer_bind() changes the viewport, so update the canvas */
+ canvas->UpdateViewPort(0, 0, winsize, winsize);
+
/* setup camera transformation */
MT_Matrix4x4 modelviewmat((float*)viewmat);
MT_Matrix4x4 projectionmat((float*)winmat);
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 52f076c..f88fc7f 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -64,7 +64,7 @@ public:
struct GPULamp *GetGPULamp();
bool HasShadowBuffer();
int GetShadowLayer();
- void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
+ void BindShadowBuffer(class RAS_IRasterizer *ras, class RAS_ICanvas *canvas, class KX_Camera *cam, class MT_Transform& camtrans);
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
struct Image *GetTextureImage(short texslot);
void Update();
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index d83e98d..57695df 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -338,20 +338,20 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds)
for (i = it.startvertex; i < it.endvertex; i++) {
RAS_TexVert *vert = &it.vertex[i];
if (uvindex_from != -1) {
- if (uvindex_from == 0) vert->SetUV2(vert->getUV1());
- else vert->SetUV1(vert->getUV2());
+ if (uvindex_from == 0) vert->SetUV(1, vert->getUV(0));
+ else vert->SetUV(0, vert->getUV(1));
}
switch (uvindex) {
case 0:
- vert->TransformUV1(transform);
+ vert->TransformUV(0, transform);
break;
case 1:
- vert->TransformUV2(transform);
+ vert->TransformUV(1, transform);
break;
case -1:
- vert->TransformUV1(transform);
- vert->TransformUV2(transform);
+ vert->TransformUV(0, transform);
+ vert->TransformUV(1, transform);
break;
}
}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index f157d9e..5ce370c 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -109,7 +109,7 @@ void KX_PolygonMaterial::Initialize(
m_mcol = *mcol;
}
else {
- m_mcol = 0;
+ memset(&m_mcol, 0, sizeof(m_mcol));
}
m_material = ma;
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index 2ce8f48..89bfb4f 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -60,7 +60,7 @@ class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial
private:
/** Blender texture face structure. */
mutable MTFace m_tface;
- mutable unsigned int m_mcol; /* for text color (only) */
+ mutable unsigned int m_mcol;
Material* m_material;
#ifdef WITH_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 996be97..a54d490 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -92,6 +92,8 @@ extern "C" {
#include "SCA_PropertySensor.h"
#include "SCA_RandomActuator.h"
#include "SCA_KeyboardSensor.h" /* IsPrintable, ToCharacter */
+#include "SCA_JoystickManager.h" /* JOYINDEX_MAX */
+#include "SCA_PythonJoystick.h"
#include "SCA_PythonKeyboard.h"
#include "SCA_PythonMouse.h"
#include "KX_ConstraintActuator.h"
@@ -134,6 +136,7 @@ extern "C" {
/* for converting new scenes */
#include "KX_BlenderSceneConverter.h"
+#include "KX_LibLoadStatus.h"
#include "KX_MeshProxy.h" /* for creating a new library of mesh objects */
extern "C" {
#include "BKE_idcode.h"
@@ -151,6 +154,7 @@ static char gp_GamePythonPathOrig[FILE_MAX] = ""; // not super happy about this,
static SCA_PythonKeyboard* gp_PythonKeyboard = NULL;
static SCA_PythonMouse* gp_PythonMouse = NULL;
+static SCA_PythonJoystick* gp_PythonJoysticks[JOYINDEX_MAX] = {NULL};
#endif // WITH_PYTHON
static KX_Scene* gp_KetsjiScene = NULL;
@@ -194,7 +198,7 @@ static PyObject *gp_OrigPythonSysModules= NULL;
/* Macro for building the keyboard translation */
//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromLong(SCA_IInputDevice::KX_##name))
-#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item)
+//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item)
/* For the defines for types from logic bricks, we do stuff explicitly... */
#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name2)); Py_DECREF(item)
@@ -667,14 +671,15 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
Py_buffer py_buffer;
py_buffer.buf = NULL;
char *err_str= NULL;
+ KX_LibLoadStatus *status = NULL;
short options=0;
- int load_actions=0, verbose=0, load_scripts=1;
+ int load_actions=0, verbose=0, load_scripts=1, async=0;
- static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", NULL};
+ static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", "load_scripts", "async", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iii:LibLoad", const_cast<char**>(kwlist),
- &path, &group, &py_buffer, &load_actions, &verbose, &load_scripts))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*iiIi:LibLoad", const_cast<char**>(kwlist),
+ &path, &group, &py_buffer, &load_actions, &verbose, &load_scripts, &async))
return NULL;
/* setup options */
@@ -684,6 +689,8 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
options |= KX_BlenderSceneConverter::LIB_LOAD_VERBOSE;
if (load_scripts != 0)
options |= KX_BlenderSceneConverter::LIB_LOAD_LOAD_SCRIPTS;
+ if (async != 0)
+ options |= KX_BlenderSceneConverter::LIB_LOAD_ASYNC;
if (!py_buffer.buf)
{
@@ -692,16 +699,16 @@ static PyObject *gLibLoad(PyObject *, PyObject *args, PyObject *kwds)
BLI_strncpy(abs_path, path, sizeof(abs_path));
BLI_path_abs(abs_path, gp_GamePythonPath);
- if (kx_scene->GetSceneConverter()->LinkBlendFilePath(abs_path, group, kx_scene, &err_str, options)) {
- Py_RETURN_TRUE;
+ if ((status=kx_scene->GetSceneConverter()->LinkBlendFilePath(abs_path, group, kx_scene, &err_str, options))) {
+ return status->GetProxy();
}
}
else
{
- if (kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str, options)) {
+ if ((status=kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str, options))) {
PyBuffer_Release(&py_buffer);
- Py_RETURN_TRUE;
+ return status->GetProxy();
}
PyBuffer_Release(&py_buffer);
@@ -1420,6 +1427,22 @@ PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
gp_PythonMouse = new SCA_PythonMouse(gp_KetsjiEngine->GetMouseDevice(), gp_Canvas);
PyDict_SetItemString(d, "mouse", gp_PythonMouse->NewProxy(true));
+ PyObject* joylist = PyList_New(JOYINDEX_MAX);
+ for (int i=0; i<JOYINDEX_MAX; ++i) {
+ SCA_Joystick* joy = SCA_Joystick::GetInstance(i);
+ if (joy && joy->Connected()) {
+ gp_PythonJoysticks[i] = new SCA_PythonJoystick(joy);
+ PyObject* tmp = gp_PythonJoysticks[i]->NewProxy(true);
+ Py_INCREF(tmp);
+ PyList_SET_ITEM(joylist, i, tmp);
+ } else {
+ joy->ReleaseInstance();
+ Py_INCREF(Py_None);
+ PyList_SET_ITEM(joylist, i, Py_None);
+ }
+ }
+ PyDict_SetItemString(d, "joysticks", joylist);
+
ErrorObject = PyUnicode_FromString("GameLogic.error");
PyDict_SetItemString(d, "error", ErrorObject);
Py_DECREF(ErrorObject);
@@ -1898,6 +1921,9 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
PySys_SetObject("argv", py_argv);
Py_DECREF(py_argv);
}
+
+ /* Initialize thread support (also acquires lock) */
+ PyEval_InitThreads();
bpy_import_init(PyEval_GetBuiltins());
@@ -1937,6 +1963,13 @@ void exitGamePlayerPythonScripting()
delete gp_PythonMouse;
gp_PythonMouse = NULL;
+ for (int i=0; i<JOYINDEX_MAX; ++i) {
+ if (gp_PythonJoysticks[i]) {
+ delete gp_PythonJoysticks[i];
+ gp_PythonJoysticks[i] = NULL;
+ }
+ }
+
/* since python restarts we cant let the python backup of the sys.path hang around in a global pointer */
restorePySysObjects(); /* get back the original sys.path and clear the backup */
@@ -1985,6 +2018,13 @@ void exitGamePythonScripting()
delete gp_PythonMouse;
gp_PythonMouse = NULL;
+ for (int i=0; i<JOYINDEX_MAX; ++i) {
+ if (gp_PythonJoysticks[i]) {
+ delete gp_PythonJoysticks[i];
+ gp_PythonJoysticks[i] = NULL;
+ }
+ }
+
restorePySysObjects(); /* get back the original sys.path and clear the backup */
bpy_import_main_set(NULL);
PyObjectPlus::ClearDeprecationWarning();
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index 9717306..c6aa436 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -47,6 +47,7 @@
#include "KX_ConstraintActuator.h"
#include "KX_ConstraintWrapper.h"
#include "KX_GameActuator.h"
+#include "KX_LibLoadStatus.h"
#include "KX_Light.h"
#include "KX_FontObject.h"
#include "KX_MeshProxy.h"
@@ -81,6 +82,7 @@
#include "SCA_RandomSensor.h"
#include "SCA_XNORController.h"
#include "SCA_XORController.h"
+#include "SCA_PythonJoystick.h"
#include "SCA_PythonKeyboard.h"
#include "SCA_PythonMouse.h"
#include "KX_IpoActuator.h"
@@ -198,6 +200,7 @@ void initPyTypes(void)
PyType_Ready_Attr(dict, KX_GameActuator, init_getset);
PyType_Ready_Attr(dict, KX_GameObject, init_getset);
PyType_Ready_Attr(dict, KX_IpoActuator, init_getset);
+ PyType_Ready_Attr(dict, KX_LibLoadStatus, init_getset);
PyType_Ready_Attr(dict, KX_LightObject, init_getset);
PyType_Ready_Attr(dict, KX_FontObject, init_getset);
PyType_Ready_Attr(dict, KX_MeshProxy, init_getset);
@@ -250,6 +253,7 @@ void initPyTypes(void)
PyType_Ready_Attr(dict, SCA_XNORController, init_getset);
PyType_Ready_Attr(dict, SCA_XORController, init_getset);
PyType_Ready_Attr(dict, SCA_IController, init_getset);
+ PyType_Ready_Attr(dict, SCA_PythonJoystick, init_getset);
PyType_Ready_Attr(dict, SCA_PythonKeyboard, init_getset);
PyType_Ready_Attr(dict, SCA_PythonMouse, init_getset);
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 72be5f5..55c9ff5 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -47,6 +47,7 @@
//#include "SCA_AlwaysEventManager.h"
//#include "SCA_RandomEventManager.h"
//#include "KX_RayEventManager.h"
+#include "SCA_2DFilterActuator.h"
#include "KX_TouchEventManager.h"
#include "SCA_KeyboardManager.h"
#include "SCA_MouseManager.h"
@@ -227,7 +228,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
}
#ifdef WITH_PYTHON
- m_attr_dict = PyDict_New(); /* new ref */
+ m_attr_dict = NULL;
m_draw_call_pre = NULL;
m_draw_call_post = NULL;
#endif
@@ -287,9 +288,11 @@ KX_Scene::~KX_Scene()
}
#ifdef WITH_PYTHON
- PyDict_Clear(m_attr_dict);
- /* Py_CLEAR: Py_DECREF's and NULL's */
- Py_CLEAR(m_attr_dict);
+ if (m_attr_dict) {
+ PyDict_Clear(m_attr_dict);
+ /* Py_CLEAR: Py_DECREF's and NULL's */
+ Py_CLEAR(m_attr_dict);
+ }
/* these may be NULL but the macro checks */
Py_CLEAR(m_draw_call_pre);
@@ -1779,6 +1782,11 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
if (sensor) {
sensor->Replace_EventManager(logicmgr);
}
+
+ SCA_2DFilterActuator *filter_actuator = dynamic_cast<class SCA_2DFilterActuator*>(brick);
+ if (filter_actuator) {
+ filter_actuator->SetScene(to);
+ }
}
#ifdef USE_BULLET
@@ -2062,6 +2070,9 @@ static PyObject *Map_GetItem(PyObject *self_v, PyObject *item)
PyErr_SetString(PyExc_SystemError, "val = scene[key]: KX_Scene, "BGE_PROXY_ERROR_MSG);
return NULL;
}
+
+ if (!self->m_attr_dict)
+ self->m_attr_dict = PyDict_New();
if (self->m_attr_dict && (pyconvert=PyDict_GetItem(self->m_attr_dict, item))) {
@@ -2089,7 +2100,10 @@ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
PyErr_SetString(PyExc_SystemError, "scene[key] = value: KX_Scene, "BGE_PROXY_ERROR_MSG);
return -1;
}
-
+
+ if (!self->m_attr_dict)
+ self->m_attr_dict = PyDict_New();
+
if (val==NULL) { /* del ob["key"] */
int del= 0;
@@ -2133,7 +2147,10 @@ static int Seq_Contains(PyObject *self_v, PyObject *value)
PyErr_SetString(PyExc_SystemError, "val in scene: KX_Scene, "BGE_PROXY_ERROR_MSG);
return -1;
}
-
+
+ if (!self->m_attr_dict)
+ self->m_attr_dict = PyDict_New();
+
if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value))
return 1;
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index 2354359..ab73ba1 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -94,6 +94,7 @@ PyAttributeDef KX_VertexProxy::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("XYZ", KX_VertexProxy, pyattr_get_XYZ, pyattr_set_XYZ),
KX_PYATTRIBUTE_RW_FUNCTION("UV", KX_VertexProxy, pyattr_get_UV, pyattr_set_UV),
+ KX_PYATTRIBUTE_RW_FUNCTION("uvs", KX_VertexProxy, pyattr_get_uvs, pyattr_set_uvs),
KX_PYATTRIBUTE_RW_FUNCTION("color", KX_VertexProxy, pyattr_get_color, pyattr_set_color),
KX_PYATTRIBUTE_RW_FUNCTION("normal", KX_VertexProxy, pyattr_get_normal, pyattr_set_normal),
@@ -146,25 +147,25 @@ PyObject *KX_VertexProxy::pyattr_get_a(void *self_v, const KX_PYATTRIBUTE_DEF *a
PyObject *KX_VertexProxy::pyattr_get_u(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV1()[0]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(0)[0]);
}
PyObject *KX_VertexProxy::pyattr_get_v(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV1()[1]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(0)[1]);
}
PyObject *KX_VertexProxy::pyattr_get_u2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV2()[0]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(1)[0]);
}
PyObject *KX_VertexProxy::pyattr_get_v2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyFloat_FromDouble(self->m_vertex->getUV2()[1]);
+ return PyFloat_FromDouble(self->m_vertex->getUV(1)[1]);
}
PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -176,7 +177,20 @@ PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF
PyObject *KX_VertexProxy::pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
- return PyObjectFrom(MT_Point2(self->m_vertex->getUV1()));
+ return PyObjectFrom(MT_Point2(self->m_vertex->getUV(0)));
+}
+
+PyObject *KX_VertexProxy::pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
+
+ PyObject* uvlist = PyList_New(RAS_TexVert::MAX_UNIT);
+ for (int i=0; i<RAS_TexVert::MAX_UNIT; ++i)
+ {
+ PyList_SET_ITEM(uvlist, i, PyObjectFrom(MT_Point2(self->m_vertex->getUV(i))));
+ }
+
+ return uvlist;
}
PyObject *KX_VertexProxy::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -245,9 +259,9 @@ int KX_VertexProxy::pyattr_set_u(void *self_v, const struct KX_PYATTRIBUTE_DEF *
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV1();
+ MT_Point2 uv = self->m_vertex->getUV(0);
uv[0] = val;
- self->m_vertex->SetUV1(uv);
+ self->m_vertex->SetUV(0, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -260,9 +274,9 @@ int KX_VertexProxy::pyattr_set_v(void *self_v, const struct KX_PYATTRIBUTE_DEF *
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV1();
+ MT_Point2 uv = self->m_vertex->getUV(0);
uv[1] = val;
- self->m_vertex->SetUV1(uv);
+ self->m_vertex->SetUV(0, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -275,9 +289,9 @@ int KX_VertexProxy::pyattr_set_u2(void *self_v, const struct KX_PYATTRIBUTE_DEF
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV2();
+ MT_Point2 uv = self->m_vertex->getUV(1);
uv[0] = val;
- self->m_vertex->SetUV2(uv);
+ self->m_vertex->SetUV(1, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -290,9 +304,9 @@ int KX_VertexProxy::pyattr_set_v2(void *self_v, const struct KX_PYATTRIBUTE_DEF
if (PyFloat_Check(value))
{
float val = PyFloat_AsDouble(value);
- MT_Point2 uv = self->m_vertex->getUV2();
+ MT_Point2 uv = self->m_vertex->getUV(1);
uv[1] = val;
- self->m_vertex->SetUV2(uv);
+ self->m_vertex->SetUV(1, uv);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -390,7 +404,7 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
{
MT_Point2 vec;
if (PyVecTo(value, vec)) {
- self->m_vertex->SetUV1(vec);
+ self->m_vertex->SetUV(0, vec);
self->m_mesh->SetMeshModified(true);
return PY_SET_ATTR_SUCCESS;
}
@@ -398,6 +412,32 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF
return PY_SET_ATTR_FAIL;
}
+int KX_VertexProxy::pyattr_set_uvs(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v);
+ if (PySequence_Check(value))
+ {
+ MT_Point2 vec;
+ for (int i=0; i<PySequence_Size(value) && i<RAS_TexVert::MAX_UNIT; ++i)
+ {
+ if (PyVecTo(PySequence_GetItem(value, i), vec))
+ {
+ self->m_vertex->SetUV(i, vec);
+ self->m_mesh->SetMeshModified(true);
+ }
+ else
+ {
+ PyErr_SetString(PyExc_AttributeError, STR_String().Format("list[%d] was not a vector", i).ReadPtr());
+ return PY_SET_ATTR_FAIL;
+ }
+ }
+
+ self->m_mesh->SetMeshModified(true);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ return PY_SET_ATTR_FAIL;
+}
+
int KX_VertexProxy::pyattr_set_color(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v);
@@ -522,7 +562,7 @@ PyObject *KX_VertexProxy::PySetRGBA(PyObject *value)
PyObject *KX_VertexProxy::PyGetUV1()
{
- return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
+ return PyObjectFrom(MT_Vector2(m_vertex->getUV(0)));
}
PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
@@ -531,31 +571,23 @@ PyObject *KX_VertexProxy::PySetUV1(PyObject *value)
if (!PyVecTo(value, vec))
return NULL;
- m_vertex->SetUV1(vec);
+ m_vertex->SetUV(0, vec);
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}
PyObject *KX_VertexProxy::PyGetUV2()
{
- return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
+ return PyObjectFrom(MT_Vector2(m_vertex->getUV(1)));
}
PyObject *KX_VertexProxy::PySetUV2(PyObject *args)
{
MT_Point2 vec;
- unsigned int unit= RAS_TexVert::SECOND_UV;
-
- PyObject *list = NULL;
- if (!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit))
- return NULL;
-
- if (!PyVecTo(list, vec))
+ if (!PyVecTo(args, vec))
return NULL;
- m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
- m_vertex->SetUnit(unit);
- m_vertex->SetUV2(vec);
+ m_vertex->SetUV(1, vec);
m_mesh->SetMeshModified(true);
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index 4247d13..8070825 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -74,6 +74,7 @@ public:
static PyObject *pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject *pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject *pyattr_get_normal(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject *pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_x(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_y(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_z(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
@@ -89,6 +90,7 @@ public:
static int pyattr_set_UV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_color(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_set_normal(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static int pyattr_set_uvs(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
KX_PYMETHOD_O(KX_VertexProxy,SetXYZ);
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 88689a5..da1a72b 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript
index 7ca0a64..b183634 100644
--- a/source/gameengine/Network/LoopBackNetwork/SConscript
+++ b/source/gameengine/Network/LoopBackNetwork/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'NG_LoopBackNetworkDeviceInterface.cpp'
diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript
index bbf7143..7365db5 100644
--- a/source/gameengine/Network/SConscript
+++ b/source/gameengine/Network/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_NetworkScene.cpp'
diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt
index 43b1bfe..afb166e 100644
--- a/source/gameengine/Physics/Bullet/CMakeLists.txt
+++ b/source/gameengine/Physics/Bullet/CMakeLists.txt
@@ -44,7 +44,6 @@ set(INC
)
set(INC_SYS
- ../../../../extern/bullet2/src
${GLEW_INCLUDE_PATH}
${PYTHON_INCLUDE_DIRS}
)
@@ -60,6 +59,9 @@ set(SRC
)
if(WITH_BULLET)
+ list(APPEND INC
+ ${BULLET_INCLUDE_DIRS}
+ )
add_definitions(-DUSE_BULLET)
endif()
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 6c6ce94..cf96f22 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -24,7 +24,7 @@ subject to the following restrictions:
#include "btBulletDynamicsCommon.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
-
+#include "BulletCollision/Gimpact/btCompoundFromGimpact.h"
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
#include "PHY_IMotionState.h"
@@ -68,6 +68,53 @@ float gAngularSleepingTreshold;
btVector3 startVel(0,0,0);//-10000);
+BlenderBulletCharacterController::BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
+ : btKinematicCharacterController(ghost,shape,stepHeight,2),
+ m_motionState(motionState),
+ m_jumps(0),
+ m_maxJumps(1)
+{
+}
+
+void BlenderBulletCharacterController::updateAction(btCollisionWorld *collisionWorld, btScalar dt)
+{
+ btKinematicCharacterController::updateAction(collisionWorld,dt);
+ m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
+}
+
+int BlenderBulletCharacterController::getMaxJumps() const
+{
+ return m_maxJumps;
+}
+
+void BlenderBulletCharacterController::setMaxJumps(int maxJumps)
+{
+ m_maxJumps = maxJumps;
+}
+
+int BlenderBulletCharacterController::getJumpCount() const
+{
+ return m_jumps;
+}
+
+bool BlenderBulletCharacterController::canJump() const
+{
+ return onGround() || m_jumps < m_maxJumps;
+}
+
+void BlenderBulletCharacterController::jump()
+{
+ if (onGround())
+ m_jumps = 0;
+
+ if (!canJump())
+ return;
+
+ m_verticalVelocity = m_jumpSpeed;
+ m_wasJumping = true;
+ m_jumps++;
+}
+
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
@@ -154,25 +201,6 @@ public:
};
-class BlenderBulletCharacterController : public btKinematicCharacterController
-{
-private:
- btMotionState* m_motionState;
-
-public:
- BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
- : btKinematicCharacterController(ghost,shape,stepHeight,2),
- m_motionState(motionState)
- {
- }
-
- virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt)
- {
- btKinematicCharacterController::updateAction(collisionWorld,dt);
- m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
- }
-};
-
btRigidBody* CcdPhysicsController::GetRigidBody()
{
return btRigidBody::upcast(m_object);
@@ -463,9 +491,6 @@ bool CcdPhysicsController::CreateCharacterController()
m_characterController = new BlenderBulletCharacterController(m_bulletMotionState,(btPairCachingGhostObject*)m_object,(btConvexShape*)m_collisionShape,m_cci.m_stepHeight);
- PHY__Vector3 gravity;
- m_cci.m_physicsEnv->getGravity(gravity);
- m_characterController->setGravity(-gravity.m_vec[2]); // need positive gravity
m_characterController->setJumpSpeed(m_cci.m_jumpSpeed);
m_characterController->setFallSpeed(m_cci.m_fallSpeed);
@@ -2169,9 +2194,16 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, b
);
btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays);
gimpactShape->setMargin(margin);
- collisionShape = gimpactShape;
gimpactShape->updateBound();
+ //the depth value is how far along the triangle normal, the centroid is moved inwards
+ //to create surface tetrahedra for the btCompoundShape
+ //would be nice to expose this in the Blender user interfaceb
+ btScalar depth=btScalar(0.2);
+ collisionShape = btCreateCompoundFromGimpactShape(gimpactShape,depth);
+ delete gimpactShape;
+
+
} else
{
if (!m_unscaledShape || m_forceReInstance)
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 6df5c85..b151c2f 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -391,10 +391,33 @@ struct CcdConstructionInfo
};
-
class btRigidBody;
class btCollisionObject;
class btSoftBody;
+class btPairCachingGhostObject;
+
+class BlenderBulletCharacterController : public btKinematicCharacterController
+{
+private:
+ btMotionState* m_motionState;
+ int m_jumps;
+ int m_maxJumps;
+
+public:
+ BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight);
+
+ virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt);
+
+ int getMaxJumps() const;
+
+ void setMaxJumps(int maxJumps);
+
+ int getJumpCount() const;
+
+ virtual bool canJump() const;
+
+ virtual void jump();
+};
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
class CcdPhysicsController : public PHY_IPhysicsController
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 486411d..cadba97 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -270,10 +270,10 @@ public:
class CharacterWrapper : public PHY_ICharacter
{
private:
- btKinematicCharacterController* m_controller;
+ BlenderBulletCharacterController* m_controller;
public:
- CharacterWrapper(btKinematicCharacterController* cont)
+ CharacterWrapper(BlenderBulletCharacterController* cont)
: m_controller(cont)
{}
@@ -295,6 +295,21 @@ public:
{
m_controller->setGravity(gravity);
}
+
+ virtual int GetMaxJumps()
+ {
+ return m_controller->getMaxJumps();
+ }
+
+ virtual void SetMaxJumps(int maxJumps)
+ {
+ m_controller->setMaxJumps(maxJumps);
+ }
+
+ virtual int GetJumpCount()
+ {
+ return m_controller->getJumpCount();
+ }
};
class CcdOverlapFilterCallBack : public btOverlapFilterCallback
@@ -2320,7 +2335,7 @@ PHY_ICharacter* CcdPhysicsEnvironment::getCharacterController(KX_GameObject *ob)
{
CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController()->GetUserData();
if (controller->GetCharacterController())
- return new CharacterWrapper(controller->GetCharacterController());
+ return new CharacterWrapper((BlenderBulletCharacterController*)controller->GetCharacterController());
return NULL;
}
diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript
index ba4db00..83239cf 100644
--- a/source/gameengine/Physics/Bullet/SConscript
+++ b/source/gameengine/Physics/Bullet/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp'
diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript
index 13d1a89..95b777b 100644
--- a/source/gameengine/Physics/Dummy/SConscript
+++ b/source/gameengine/Physics/Dummy/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'DummyPhysicsEnvironment.cpp'
diff --git a/source/gameengine/Physics/common/PHY_ICharacter.h b/source/gameengine/Physics/common/PHY_ICharacter.h
index e2fc5e4..63f6c0b 100644
--- a/source/gameengine/Physics/common/PHY_ICharacter.h
+++ b/source/gameengine/Physics/common/PHY_ICharacter.h
@@ -21,6 +21,11 @@ public:
virtual float GetGravity()= 0;
virtual void SetGravity(float gravity)= 0;
+
+ virtual int GetMaxJumps()= 0;
+ virtual void SetMaxJumps(int maxJumps)= 0;
+
+ virtual int GetJumpCount()= 0;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_ICharacter")
diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript
index abff3e3..aee5e44 100644
--- a/source/gameengine/Physics/common/SConscript
+++ b/source/gameengine/Physics/common/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp PHY_IGraphicController.cpp PHY_IPhysicsEnvironment.cpp PHY_IVehicle.cpp'
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index cf869e7..ab0f62c 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -428,8 +428,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
// reverting to texunit 0, without this we get bug [#28462]
glActiveTextureARB(GL_TEXTURE0);
-
- glViewport(rect.GetLeft(), rect.GetBottom(), rect_width, rect_height);
+ canvas->SetViewPort(0, 0, rect_width-1, rect_height-1);
glDisable(GL_DEPTH_TEST);
// in case the previous material was wire
@@ -466,7 +465,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
glEnable(GL_DEPTH_TEST);
- glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
+ canvas->SetViewPort(viewport[0],viewport[1],viewport[2],viewport[3]);
EndShaderProgram();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index f24e339..df72056 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -232,6 +232,24 @@ void RAS_BucketManager::Renderbuckets(
RenderSolidBuckets(cameratrans, rasty, rendertools);
RenderAlphaBuckets(cameratrans, rasty, rendertools);
+ /* All meshes should be up to date now */
+ /* Don't do this while processing buckets because some meshes are split between buckets */
+ BucketList::iterator bit;
+ list<RAS_MeshSlot>::iterator mit;
+ for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
+ // RAS_MaterialBucket *bucket = *bit; /* UNUSED */
+ for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+ mit->m_mesh->SetMeshModified(false);
+ }
+ }
+ for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
+ // RAS_MaterialBucket* bucket = *bit; /* UNUSED */
+ for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+ mit->m_mesh->SetMeshModified(false);
+ }
+ }
+
+
rendertools->SetClientObject(rasty, NULL);
}
diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h
index 60b9f05..63ad789 100644
--- a/source/gameengine/Rasterizer/RAS_ICanvas.h
+++ b/source/gameengine/Rasterizer/RAS_ICanvas.h
@@ -178,7 +178,19 @@ public:
SetViewPort(
int x1, int y1,
int x2, int y2
- ) = 0;
+ ) = 0;
+
+ /**
+ * Update the Canvas' viewport (used when the viewport changes without using SetViewPort()
+ * eg: Shadow buffers and FBOs
+ */
+
+ virtual
+ void
+ UpdateViewPort(
+ int x1, int y1,
+ int x2, int y2
+ ) = 0;
/**
* Get the visible viewport
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 9fffc8b..b267879 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -184,7 +184,7 @@ public:
/*
* PreCalculate texture gen
*/
- virtual void OnConstruction(int layer) {}
+ virtual void OnConstruction() {}
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index e694802..5a72085 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -52,6 +52,7 @@ using namespace std;
class RAS_ICanvas;
class RAS_IPolyMaterial;
+class RAS_MeshSlot;
typedef vector<unsigned short> KX_IndexArray;
typedef vector<RAS_TexVert> KX_VertexArray;
@@ -129,7 +130,7 @@ public:
RAS_TEXCO_GEN, //< GPU will generate texture coordinates
RAS_TEXCO_ORCO, //< Vertex coordinates (object space)
RAS_TEXCO_GLOB, //< Vertex coordinates (world space)
- RAS_TEXCO_UV1, //< UV coordinates
+ RAS_TEXCO_UV, //< UV coordinates
RAS_TEXCO_OBJECT, //< Use another object's position as coordinates
RAS_TEXCO_LAVECTOR, //< Light vector as coordinates
RAS_TEXCO_VIEW, //< View vector as coordinates
@@ -137,7 +138,6 @@ public:
RAS_TEXCO_WINDOW, //< Window coordinates
RAS_TEXCO_NORM, //< Normal coordinates
RAS_TEXTANGENT, //<
- RAS_TEXCO_UV2, //<
RAS_TEXCO_VCOL, //< Vertex Color
RAS_TEXCO_DISABLE //< Disable this texture unit (cached)
};
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index 9fb4711..8ea0902 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -605,7 +605,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
if (ms.m_pDeformer)
{
- ms.m_pDeformer->Apply(m_material);
+ if (ms.m_pDeformer->Apply(m_material))
+ ms.m_mesh->SetMeshModified(true);
// KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_)
}
@@ -648,10 +649,6 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
else
rasty->IndexPrimitives(ms);
- if (rasty->QueryLists())
- if (ms.m_DisplayList)
- ms.m_mesh->SetMeshModified(false);
-
rendertools->PopMatrix();
}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 2ccb945..49b7489 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i,
const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
bool flat,
int origindex)
{
- RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex);
+ RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex);
RAS_MeshMaterial *mmat;
RAS_DisplayArray *darray;
RAS_MeshSlot *slot;
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 281eae8..d77d048 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -116,8 +116,7 @@ public:
virtual RAS_Polygon* AddPolygon(RAS_MaterialBucket *bucket, int numverts);
virtual void AddVertex(RAS_Polygon *poly, int i,
const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[RAS_TexVert::MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgbacolor,
const MT_Vector3& normal,
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
index 189c4f7..11cb4b1 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
@@ -46,12 +46,17 @@ set(SRC
RAS_GLExtensionManager.cpp
RAS_ListRasterizer.cpp
RAS_OpenGLRasterizer.cpp
- RAS_VAOpenGLRasterizer.cpp
+ RAS_StorageIM.cpp
+ RAS_StorageVA.cpp
+ RAS_StorageVBO.cpp
RAS_GLExtensionManager.h
+ RAS_IStorage.h
RAS_ListRasterizer.h
RAS_OpenGLRasterizer.h
- RAS_VAOpenGLRasterizer.h
+ RAS_StorageIM.h
+ RAS_StorageVA.h
+ RAS_StorageVBO.h
)
add_definitions(-DGLEW_STATIC)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h
new file mode 100644
index 0000000..f5c16bc
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h
@@ -0,0 +1,62 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_STORAGE
+#define __KX_STORAGE
+
+#include "RAS_MaterialBucket.h"
+
+enum RAS_STORAGE_TYPE {
+ RAS_AUTO_STORAGE,
+ RAS_IMMEDIATE,
+ RAS_VA,
+ RAS_VBO
+};
+
+class RAS_IStorage
+{
+
+public:
+ virtual ~RAS_IStorage() {};
+
+ virtual bool Init()=0;
+ virtual void Exit()=0;
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms)=0;
+ virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0;
+
+ virtual void SetDrawingMode(int drawingmode)=0;
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_STORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index d74aa13..3a60643 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -106,9 +106,8 @@ bool RAS_ListSlot::End()
-RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock)
-: RAS_VAOpenGLRasterizer(canvas, lock),
- mUseVertexArrays(useVertexArrays),
+RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage)
+: RAS_OpenGLRasterizer(canvas, storage),
mATI(false)
{
if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc."))
@@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
return;
}
}
- // derived mesh cannot use vertex array
- if (mUseVertexArrays && !ms.m_pDerivedMesh)
- RAS_VAOpenGLRasterizer::IndexPrimitives(ms);
- else
- RAS_OpenGLRasterizer::IndexPrimitives(ms);
+
+ RAS_OpenGLRasterizer::IndexPrimitives(ms);
if (ms.m_bDisplayList) {
localSlot->EndList();
@@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
}
}
- // workaround: note how we do not use vertex arrays for making display
- // lists, since glVertexAttribPointerARB doesn't seem to work correct
- // in display lists on ATI? either a bug in the driver or in Blender ..
- if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh)
- RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
- else
- RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
+ RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
if (ms.m_bDisplayList) {
localSlot->EndList();
@@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
bool RAS_ListRasterizer::Init(void)
{
- if (mUseVertexArrays) {
- return RAS_VAOpenGLRasterizer::Init();
- } else {
- return RAS_OpenGLRasterizer::Init();
- }
+ return RAS_OpenGLRasterizer::Init();
}
void RAS_ListRasterizer::SetDrawingMode(int drawingmode)
{
- if (mUseVertexArrays) {
- RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode);
- } else {
- RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
- }
+ RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
}
void RAS_ListRasterizer::Exit()
{
- if (mUseVertexArrays) {
- RAS_VAOpenGLRasterizer::Exit();
- } else {
- RAS_OpenGLRasterizer::Exit();
- }
+ RAS_OpenGLRasterizer::Exit();
}
// eof
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index a8eb2d5..558850a 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -7,7 +7,7 @@
#define __RAS_LISTRASTERIZER_H__
#include "RAS_MaterialBucket.h"
-#include "RAS_VAOpenGLRasterizer.h"
+#include "RAS_OpenGLRasterizer.h"
#include <vector>
#include <map>
@@ -49,9 +49,8 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
typedef std::vector<RAS_ListSlot*> RAS_ListSlots; // indexed by material slot number
typedef std::map<DerivedMesh*, RAS_ListSlots*> RAS_DerivedMeshLists;
-class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
+class RAS_ListRasterizer : public RAS_OpenGLRasterizer
{
- bool mUseVertexArrays;
bool mATI;
RAS_ArrayLists mArrayLists;
RAS_DerivedMeshLists mDerivedMeshLists;
@@ -61,7 +60,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
public:
void RemoveListSlot(RAS_ListSlot* list);
- RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
+ RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE);
virtual ~RAS_ListRasterizer();
virtual void IndexPrimitives(class RAS_MeshSlot& ms);
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 22a700c..a9609a2 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -43,6 +43,10 @@
#include "MT_CmMatrix4x4.h"
#include "RAS_IRenderTools.h" // rendering text
+#include "RAS_StorageIM.h"
+#include "RAS_StorageVA.h"
+#include "RAS_StorageVBO.h"
+
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
@@ -74,7 +78,7 @@ static GLuint right_eye_vinterlace_mask[32];
*/
static GLuint hinterlace_mask[33];
-RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
+RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage)
:RAS_IRasterizer(canvas),
m_2DCanvas(canvas),
m_fogenabled(false),
@@ -93,7 +97,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_attrib_num(0),
//m_last_alphablend(GPU_BLEND_SOLID),
m_last_frontface(true),
- m_materialCachingInfo(0)
+ m_materialCachingInfo(0),
+ m_storage_type(storage)
{
m_viewmatrix.setIdentity();
m_viewinvmatrix.setIdentity();
@@ -107,6 +112,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
hinterlace_mask[32] = 0;
m_prevafvalue = GPU_get_anisotropic();
+
+ if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/)
+ {
+ m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_storage_type = RAS_VBO;
+ }
+ else if ((m_storage_type == RAS_VA) || (m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1))
+ {
+ m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_storage_type = RAS_VA;
+ }
+ else
+ {
+ m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib);
+ m_storage_type = RAS_IMMEDIATE;
+ }
}
@@ -115,10 +138,16 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
{
// Restore the previous AF value
GPU_set_anisotropic(m_prevafvalue);
+ if (m_failsafe_storage && m_failsafe_storage != m_storage)
+ delete m_failsafe_storage;
+
+ if (m_storage)
+ delete m_storage;
}
bool RAS_OpenGLRasterizer::Init()
{
+ bool storage_init;
GPU_state_init();
@@ -146,7 +175,9 @@ bool RAS_OpenGLRasterizer::Init()
glShadeModel(GL_SMOOTH);
- return true;
+ storage_init = m_storage->Init();
+
+ return true && storage_init;
}
@@ -267,6 +298,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
void RAS_OpenGLRasterizer::Exit()
{
+ m_storage->Exit();
+
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);
@@ -289,7 +322,7 @@ void RAS_OpenGLRasterizer::Exit()
bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
{
m_time = time;
- m_drawingmode = drawingmode;
+ SetDrawingMode(drawingmode);
// Blender camera routine destroys the settings
if (m_drawingmode < KX_SOLID)
@@ -328,6 +361,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
if (m_drawingmode == KX_WIREFRAME)
glDisable(GL_CULL_FACE);
+
+ m_storage->SetDrawingMode(drawingmode);
}
int RAS_OpenGLRasterizer::GetDrawingMode()
@@ -666,7 +701,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
glattrib = -1;
if (GLEW_ARB_vertex_program)
for (unit=0; unit<m_attrib_num; unit++)
- if (m_attrib[unit] == RAS_TEXCO_UV1)
+ if (m_attrib[unit] == RAS_TEXCO_UV)
glattrib = unit;
rendertools->RenderText(polymat->GetDrawingMode(), polymat,
@@ -708,257 +743,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
m_attrib[unit] = coords;
}
-void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
-{
- int unit;
-
- if (GLEW_ARB_multitexture) {
- for (unit=0; unit<m_texco_num; unit++) {
- if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
- continue;
- }
- switch (m_texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
- break;
- case RAS_TEXCO_NORM:
- glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
- break;
- case RAS_TEXTANGENT:
- glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
- break;
- case RAS_TEXCO_UV2:
- glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
- break;
- default:
- break;
- }
- }
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<m_attrib_num; unit++) {
- switch (m_attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glVertexAttrib3fvARB(unit, tv.getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glVertexAttrib2fvARB(unit, tv.getUV1());
- break;
- case RAS_TEXCO_NORM:
- glVertexAttrib3fvARB(unit, tv.getNormal());
- break;
- case RAS_TEXTANGENT:
- glVertexAttrib4fvARB(unit, tv.getTangent());
- break;
- case RAS_TEXCO_UV2:
- glVertexAttrib2fvARB(unit, tv.getUV2());
- break;
- case RAS_TEXCO_VCOL:
- glVertexAttrib4ubvARB(unit, tv.getRGBA());
- break;
- default:
- break;
- }
- }
- }
-
-}
-
void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
{
- IndexPrimitivesInternal(ms, false);
+ if (ms.m_pDerivedMesh)
+ m_failsafe_storage->IndexPrimitives(ms);
+ else
+ m_storage->IndexPrimitives(ms);
}
void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
{
- IndexPrimitivesInternal(ms, true);
-}
-
-static bool current_wireframe;
-static RAS_MaterialBucket *current_bucket;
-static RAS_IPolyMaterial *current_polymat;
-static RAS_MeshSlot *current_ms;
-static RAS_MeshObject *current_mesh;
-static int current_blmat_nr;
-static GPUVertexAttribs current_gpu_attribs;
-static Image *current_image;
-static int CheckMaterialDM(int matnr, void *attribs)
-{
- // only draw the current material
- if (matnr != current_blmat_nr)
- return 0;
- GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
- if (gattribs)
- memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs));
- return 1;
-}
-
-/*
-static int CheckTexfaceDM(void *mcol, int index)
-{
-
- // index is the original face index, retrieve the polygon
- RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
- current_mesh->GetPolygon(index) : NULL;
- if (polygon && polygon->GetMaterial() == current_bucket) {
- // must handle color.
- if (current_wireframe)
- return 2;
- if (current_ms->m_bObjectColor) {
- MT_Vector4& rgba = current_ms->m_RGBAcolor;
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- // don't use mcol
- return 2;
- }
- if (!mcol) {
- // we have to set the color from the material
- unsigned char rgba[4];
- current_polymat->GetMaterialRGBAColor(rgba);
- glColor4ubv((const GLubyte *)rgba);
- return 2;
- }
- return 1;
- }
- return 0;
-}
-*/
-
-static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
-{
-
- // index is the original face index, retrieve the polygon
- if (matnr == current_blmat_nr &&
- (tface == NULL || tface->tpage == current_image)) {
- // must handle color.
- if (current_wireframe)
- return DM_DRAW_OPTION_NO_MCOL;
- if (current_ms->m_bObjectColor) {
- MT_Vector4& rgba = current_ms->m_RGBAcolor;
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- // don't use mcol
- return DM_DRAW_OPTION_NO_MCOL;
- }
- if (!has_mcol) {
- // we have to set the color from the material
- unsigned char rgba[4];
- current_polymat->GetMaterialRGBAColor(rgba);
- glColor4ubv((const GLubyte *)rgba);
- return DM_DRAW_OPTION_NO_MCOL;
- }
- return DM_DRAW_OPTION_NORMAL;
- }
- return DM_DRAW_OPTION_SKIP;
-}
-
-void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
-{
- bool obcolor = ms.m_bObjectColor;
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
- MT_Vector4& rgba = ms.m_RGBAcolor;
- RAS_MeshSlot::iterator it;
-
- if (ms.m_pDerivedMesh) {
- // mesh data is in derived mesh,
- current_bucket = ms.m_bucket;
- current_polymat = current_bucket->GetPolyMaterial();
- current_ms = &ms;
- current_mesh = ms.m_mesh;
- current_wireframe = wireframe;
- // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
-
- // handle two-side
- if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
- this->SetCullFace(true);
- else
- this->SetCullFace(false);
-
- if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
- // GetMaterialIndex return the original mface material index,
- // increment by 1 to match what derived mesh is doing
- current_blmat_nr = current_polymat->GetMaterialIndex()+1;
- // For GLSL we need to retrieve the GPU material attribute
- Material* blmat = current_polymat->GetBlenderMaterial();
- Scene* blscene = current_polymat->GetBlenderScene();
- if (!wireframe && blscene && blmat)
- GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
- else
- memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
- // DM draw can mess up blending mode, restore at the end
- int current_blend_mode = GPU_get_material_alpha_blend();
- ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
- GPU_set_material_alpha_blend(current_blend_mode);
- }
- else {
- //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
- current_blmat_nr = current_polymat->GetMaterialIndex();
- current_image = current_polymat->GetBlenderImage();
- ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
- }
- return;
- }
- // iterate over display arrays, each containing an index + vertex array
- for (ms.begin(it); !ms.end(it); ms.next(it)) {
- RAS_TexVert *vertex;
- size_t i, j, numvert;
-
- numvert = it.array->m_type;
-
- if (it.array->m_type == RAS_DisplayArray::LINE) {
- // line drawing
- glBegin(GL_LINES);
-
- for (i=0; i<it.totindex; i+=2)
- {
- vertex = &it.vertex[it.index[i]];
- glVertex3fv(vertex->getXYZ());
-
- vertex = &it.vertex[it.index[i+1]];
- glVertex3fv(vertex->getXYZ());
- }
-
- glEnd();
- }
- else {
- // triangle and quad drawing
- if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
- glBegin(GL_TRIANGLES);
- else
- glBegin(GL_QUADS);
-
- for (i=0; i<it.totindex; i+=numvert)
- {
- if (obcolor)
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
-
- for (j=0; j<numvert; j++) {
- vertex = &it.vertex[it.index[i+j]];
-
- if (!wireframe) {
- if (!obcolor)
- glColor4ubv((const GLubyte *)(vertex->getRGBA()));
-
- glNormal3fv(vertex->getNormal());
-
- if (multi)
- TexCoord(*vertex);
- else
- glTexCoord2fv(vertex->getUV1());
- }
-
- glVertex3fv(vertex->getXYZ());
- }
- }
-
- glEnd();
- }
- }
+ if (ms.m_pDerivedMesh)
+ m_failsafe_storage->IndexPrimitivesMulti(ms);
+ else
+ m_storage->IndexPrimitivesMulti(ms);
}
void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 88bb0be..c156ee5 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -41,6 +41,7 @@
using namespace std;
#include "RAS_IRasterizer.h"
+#include "RAS_IStorage.h"
#include "RAS_MaterialBucket.h"
#include "RAS_ICanvas.h"
@@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
float m_ambr;
float m_ambg;
float m_ambb;
-
double m_time;
MT_Matrix4x4 m_viewmatrix;
MT_Matrix4x4 m_viewinvmatrix;
@@ -115,9 +115,15 @@ protected:
/** Stores the caching information for the last material activated. */
RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
+ /** Making use of a Strategy desing pattern for storage behavior.
+ Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/
+ int m_storage_type;
+ RAS_IStorage* m_storage;
+ RAS_IStorage* m_failsafe_storage; //So derived mesh can use immediate mode
+
public:
double GetTime();
- RAS_OpenGLRasterizer(RAS_ICanvas* canv);
+ RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE);
virtual ~RAS_OpenGLRasterizer();
/*enum DrawType
@@ -166,8 +172,6 @@ public:
class RAS_IPolyMaterial* polymat,
class RAS_IRenderTools* rendertools);
- void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
-
virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat);
virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat);
virtual void SetViewMatrix(
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
new file mode 100644
index 0000000..490c26a
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
@@ -0,0 +1,310 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "RAS_StorageIM.h"
+
+#include "GL/glew.h"
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+#include "GPU_material.h"
+
+#include "DNA_meshdata_types.h"
+
+extern "C"{
+ #include "BLI_utildefines.h"
+ #include "BKE_DerivedMesh.h"
+}
+
+RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+ m_texco_num(texco_num),
+ m_attrib_num(attrib_num),
+ m_texco(texco),
+ m_attrib(attrib)
+{
+}
+RAS_StorageIM::~RAS_StorageIM()
+{
+}
+
+bool RAS_StorageIM::Init()
+{
+ return true;
+}
+void RAS_StorageIM::Exit()
+{
+}
+
+void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, false);
+}
+
+void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, true);
+}
+
+void RAS_StorageIM::TexCoord(const RAS_TexVert &tv)
+{
+ int unit;
+
+ if (GLEW_ARB_multitexture) {
+ for (unit = 0; unit < *m_texco_num; unit++) {
+ switch(m_texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (GLEW_ARB_vertex_program) {
+ int uv = 0;
+ for (unit = 0; unit < *m_attrib_num; unit++) {
+ switch(m_attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glVertexAttrib3fvARB(unit, tv.getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glVertexAttrib2fvARB(unit, tv.getUV(uv++));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glVertexAttrib3fvARB(unit, tv.getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glVertexAttrib4fvARB(unit, tv.getTangent());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ glVertexAttrib4ubvARB(unit, tv.getRGBA());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+}
+
+void RAS_StorageIM::SetCullFace(bool enable)
+{
+ if (enable)
+ glEnable(GL_CULL_FACE);
+ else
+ glDisable(GL_CULL_FACE);
+}
+
+static bool current_wireframe;
+static RAS_MaterialBucket *current_bucket;
+static RAS_IPolyMaterial *current_polymat;
+static RAS_MeshSlot *current_ms;
+static RAS_MeshObject *current_mesh;
+static int current_blmat_nr;
+static GPUVertexAttribs current_gpu_attribs;
+static Image *current_image;
+static int CheckMaterialDM(int matnr, void *attribs)
+{
+ // only draw the current material
+ if (matnr != current_blmat_nr)
+ return 0;
+ GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
+ if (gattribs)
+ memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs));
+ return 1;
+}
+
+/*
+static int CheckTexfaceDM(void *mcol, int index)
+{
+
+ // index is the original face index, retrieve the polygon
+ RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
+ current_mesh->GetPolygon(index) : NULL;
+ if (polygon && polygon->GetMaterial() == current_bucket) {
+ // must handle color.
+ if (current_wireframe)
+ return 2;
+ if (current_ms->m_bObjectColor) {
+ MT_Vector4& rgba = current_ms->m_RGBAcolor;
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ // don't use mcol
+ return 2;
+ }
+ if (!mcol) {
+ // we have to set the color from the material
+ unsigned char rgba[4];
+ current_polymat->GetMaterialRGBAColor(rgba);
+ glColor4ubv((const GLubyte *)rgba);
+ return 2;
+ }
+ return 1;
+ }
+ return 0;
+}
+*/
+
+static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr)
+{
+
+ // index is the original face index, retrieve the polygon
+ if (matnr == current_blmat_nr &&
+ (tface == NULL || tface->tpage == current_image)) {
+ // must handle color.
+ if (current_wireframe)
+ return DM_DRAW_OPTION_NO_MCOL;
+ if (current_ms->m_bObjectColor) {
+ MT_Vector4& rgba = current_ms->m_RGBAcolor;
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ // don't use mcol
+ return DM_DRAW_OPTION_NO_MCOL;
+ }
+ if (!has_mcol) {
+ // we have to set the color from the material
+ unsigned char rgba[4];
+ current_polymat->GetMaterialRGBAColor(rgba);
+ glColor4ubv((const GLubyte *)rgba);
+ return DM_DRAW_OPTION_NO_MCOL;
+ }
+ return DM_DRAW_OPTION_NORMAL;
+ }
+ return DM_DRAW_OPTION_SKIP;
+}
+
+void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
+{
+ bool obcolor = ms.m_bObjectColor;
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+ MT_Vector4& rgba = ms.m_RGBAcolor;
+ RAS_MeshSlot::iterator it;
+
+ if (ms.m_pDerivedMesh) {
+ // mesh data is in derived mesh,
+ current_bucket = ms.m_bucket;
+ current_polymat = current_bucket->GetPolyMaterial();
+ current_ms = &ms;
+ current_mesh = ms.m_mesh;
+ current_wireframe = wireframe;
+ // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
+
+ // handle two-side
+ if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL)
+ this->SetCullFace(true);
+ else
+ this->SetCullFace(false);
+
+ if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
+ // GetMaterialIndex return the original mface material index,
+ // increment by 1 to match what derived mesh is doing
+ current_blmat_nr = current_polymat->GetMaterialIndex()+1;
+ // For GLSL we need to retrieve the GPU material attribute
+ Material* blmat = current_polymat->GetBlenderMaterial();
+ Scene* blscene = current_polymat->GetBlenderScene();
+ if (!wireframe && blscene && blmat)
+ GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
+ else
+ memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
+ // DM draw can mess up blending mode, restore at the end
+ int current_blend_mode = GPU_get_material_alpha_blend();
+ ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
+ GPU_set_material_alpha_blend(current_blend_mode);
+ } else {
+ //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
+ current_blmat_nr = current_polymat->GetMaterialIndex();
+ current_image = current_polymat->GetBlenderImage();
+ ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL);
+ }
+ return;
+ }
+ // iterate over display arrays, each containing an index + vertex array
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ RAS_TexVert *vertex;
+ size_t i, j, numvert;
+
+ numvert = it.array->m_type;
+
+ if (it.array->m_type == RAS_DisplayArray::LINE) {
+ // line drawing
+ glBegin(GL_LINES);
+
+ for (i = 0; i < it.totindex; i += 2)
+ {
+ vertex = &it.vertex[it.index[i]];
+ glVertex3fv(vertex->getXYZ());
+
+ vertex = &it.vertex[it.index[i+1]];
+ glVertex3fv(vertex->getXYZ());
+ }
+
+ glEnd();
+ }
+ else {
+ // triangle and quad drawing
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ glBegin(GL_TRIANGLES);
+ else
+ glBegin(GL_QUADS);
+
+ for (i = 0; i < it.totindex; i += numvert)
+ {
+ if (obcolor)
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+
+ for (j = 0; j < numvert; j++) {
+ vertex = &it.vertex[it.index[i+j]];
+
+ if (!wireframe) {
+ if (!obcolor)
+ glColor4ubv((const GLubyte *)(vertex->getRGBA()));
+
+ glNormal3fv(vertex->getNormal());
+
+ if (multi)
+ TexCoord(*vertex);
+ else
+ glTexCoord2fv(vertex->getUV(0));
+ }
+
+ glVertex3fv(vertex->getXYZ());
+ }
+ }
+
+ glEnd();
+ }
+ }
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h
new file mode 100644
index 0000000..de4ff30
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h
@@ -0,0 +1,68 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_IMMEDIATEMODESTORAGE
+#define __KX_IMMEDIATEMODESTORAGE
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+class RAS_StorageIM : public RAS_IStorage
+{
+public:
+ RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+ virtual ~RAS_StorageIM();
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
+ virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
+
+ virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+ int m_drawingmode;
+ int* m_texco_num;
+ int* m_attrib_num;
+ RAS_IRasterizer::TexCoGen* m_texco;
+ RAS_IRasterizer::TexCoGen* m_attrib;
+
+ void TexCoord(const RAS_TexVert &tv);
+ void SetCullFace(bool enable);
+
+ void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_IMMEDIATEMODESTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
new file mode 100644
index 0000000..7182525
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -0,0 +1,320 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "RAS_StorageVA.h"
+
+#include "GL/glew.h"
+
+RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+ m_texco_num(texco_num),
+ m_attrib_num(attrib_num),
+ m_last_texco_num(0),
+ m_last_attrib_num(0),
+ m_texco(texco),
+ m_attrib(attrib)
+{
+}
+
+RAS_StorageVA::~RAS_StorageVA()
+{
+}
+
+bool RAS_StorageVA::Init()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ return true;
+}
+
+void RAS_StorageVA::Exit()
+{
+}
+
+void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ if (!wireframe)
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ }
+ else
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+ if (!wireframe) {
+ glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
+ if (glIsEnabled(GL_COLOR_ARRAY))
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+}
+
+void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ if (!wireframe)
+ EnableTextures(true);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ use_color_array = false;
+ }
+ else {
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ glEnableClientState(GL_COLOR_ARRAY);
+ use_color_array = true;
+ }
+ }
+ else
+ glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+
+ if (!wireframe) {
+ TexCoordPtr(it.vertex);
+ if (use_color_array)
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_COLOR_ARRAY);
+ EnableTextures(false);
+ }
+}
+
+void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv)
+{
+ /* note: this function must closely match EnableTextures to enable/disable
+ * the right arrays, otherwise coordinate and attribute pointers from other
+ * materials can still be used and cause crashes */
+ int unit;
+
+ if (GLEW_ARB_multitexture)
+ {
+ for (unit = 0; unit < *m_texco_num; unit++)
+ {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
+ switch (m_texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
+ break;
+ default:
+ break;
+ }
+ }
+
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+
+ if (GLEW_ARB_vertex_program) {
+ int uv = 0;
+ for (unit = 0; unit < *m_attrib_num; unit++) {
+ switch (m_attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void RAS_StorageVA::EnableTextures(bool enable)
+{
+ RAS_IRasterizer::TexCoGen *texco, *attrib;
+ int unit, texco_num, attrib_num;
+
+ /* we cache last texcoords and attribs to ensure we disable the ones that
+ * were actually last set */
+ if (enable) {
+ texco = m_texco;
+ texco_num = *m_texco_num;
+ attrib = m_attrib;
+ attrib_num = *m_attrib_num;
+
+ memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num));
+ m_last_texco_num = *m_texco_num;
+ memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num));
+ m_last_attrib_num = *m_attrib_num;
+ }
+ else {
+ texco = m_last_texco;
+ texco_num = m_last_texco_num;
+ attrib = m_last_attrib;
+ attrib_num = m_last_attrib_num;
+ }
+
+ if (GLEW_ARB_multitexture) {
+ for (unit = 0; unit < texco_num; unit++) {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
+
+ switch (texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ default:
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ }
+ }
+
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ else {
+ if (texco_num) {
+ if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+
+ if (GLEW_ARB_vertex_program) {
+ for (unit = 0; unit < attrib_num; unit++) {
+ switch (attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ if (enable) glEnableVertexAttribArrayARB(unit);
+ else glDisableVertexAttribArrayARB(unit);
+ break;
+ default:
+ glDisableVertexAttribArrayARB(unit);
+ break;
+ }
+ }
+ }
+
+ if (!enable) {
+ m_last_texco_num = 0;
+ m_last_attrib_num = 0;
+ }
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
new file mode 100644
index 0000000..da7766e
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h
@@ -0,0 +1,77 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_VERTEXARRAYSTORAGE
+#define __KX_VERTEXARRAYSTORAGE
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+#include "RAS_OpenGLRasterizer.h"
+
+class RAS_StorageVA : public RAS_IStorage
+{
+
+public:
+ RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+ virtual ~RAS_StorageVA();
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
+ virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
+
+ virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+ int m_drawingmode;
+
+ int* m_texco_num;
+ int* m_attrib_num;
+
+ int m_last_texco_num;
+ int m_last_attrib_num;
+
+ RAS_IRasterizer::TexCoGen* m_texco;
+ RAS_IRasterizer::TexCoGen* m_attrib;
+
+ RAS_IRasterizer::TexCoGen m_last_texco[RAS_MAX_TEXCO];
+ RAS_IRasterizer::TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
+
+ virtual void EnableTextures(bool enable);
+ virtual void TexCoordPtr(const RAS_TexVert *tv);
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_VERTEXARRAYSTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
new file mode 100644
index 0000000..077dfad
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
@@ -0,0 +1,259 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "RAS_StorageVBO.h"
+#include "RAS_MeshObject.h"
+
+#include "GL/glew.h"
+
+VBO::VBO(RAS_DisplayArray *data, unsigned int indices)
+{
+ this->data = data;
+ this->size = data->m_vertex.size();
+ this->indices = indices;
+ this->stride = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding
+
+ // Determine drawmode
+ if (data->m_type == data->QUAD)
+ this->mode = GL_QUADS;
+ else if (data->m_type == data->TRIANGLE)
+ this->mode = GL_TRIANGLES;
+ else
+ this->mode = GL_LINE;
+
+ // Generate Buffers
+ glGenBuffersARB(1, &this->ibo);
+ glGenBuffersARB(1, &this->vbo_id);
+
+ // Fill the buffers with initial data
+ UpdateIndices();
+ UpdateData();
+
+ // Establish offsets
+ this->vertex_offset = 0;
+ this->normal_offset = (void*)(3*sizeof(GLfloat));
+ this->tangent_offset = (void*)(6*sizeof(GLfloat));
+ this->color_offset = (void*)(10*sizeof(GLfloat));
+ this->uv_offset = (void*)(11*sizeof(GLfloat));
+}
+
+VBO::~VBO()
+{
+ glDeleteBuffersARB(1, &this->ibo);
+ glDeleteBuffersARB(1, &this->vbo_id);
+}
+
+void VBO::UpdateData()
+{
+ unsigned int i, j, k;
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+ glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW);
+
+ // Map the buffer
+ GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ // Gather data
+ for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat))
+ {
+ memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3);
+ memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3);
+ memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4);
+ memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4);
+
+ for (k = 0; k < RAS_TexVert::MAX_UNIT; k++)
+ memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2);
+ }
+
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+}
+
+void VBO::UpdateIndices()
+{
+ int space = data->m_index.size() * sizeof(GLushort);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+
+ // Upload Data to VBO
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW);
+}
+
+void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi)
+{
+ int unit;
+
+ // Bind buffers
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id);
+
+ // Vertexes
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
+
+ // Normals
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(GL_FLOAT, this->stride, this->normal_offset);
+
+ // Colors
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset);
+
+ if (multi)
+ {
+ for (unit = 0; unit < texco_num; ++unit)
+ {
+ glClientActiveTexture(GL_TEXTURE0_ARB + unit);
+ switch (texco[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset);
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit)));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset);
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset);
+ break;
+ default:
+ break;
+ }
+ }
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ else //TexFace
+ {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset);
+ }
+
+ if (GLEW_ARB_vertex_program)
+ {
+ int uv = 0;
+ for (unit = 0; unit < attrib_num; ++unit)
+ {
+ switch (attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset);
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv));
+ uv += sizeof(GLfloat)*2;
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset);
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset);
+ glEnableVertexAttribArrayARB(unit);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ if (GLEW_ARB_vertex_program)
+ {
+ for (int i = 0; i < attrib_num; ++i)
+ glDisableVertexAttribArrayARB(i);
+ }
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+}
+
+RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib):
+ m_texco_num(texco_num),
+ m_attrib_num(attrib_num),
+ m_texco(texco),
+ m_attrib(attrib)
+{
+}
+
+RAS_StorageVBO::~RAS_StorageVBO()
+{
+}
+
+bool RAS_StorageVBO::Init()
+{
+ return true;
+}
+
+void RAS_StorageVBO::Exit()
+{
+ m_vbo_lookup.clear();
+}
+
+void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, false);
+}
+
+void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms)
+{
+ IndexPrimitivesInternal(ms, true);
+}
+
+void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
+{
+ RAS_MeshSlot::iterator it;
+ VBO *vbo;
+
+ for (ms.begin(it); !ms.end(it); ms.next(it))
+ {
+ vbo = m_vbo_lookup[it.array];
+
+ if (vbo == 0)
+ m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex);
+
+ // Update the vbo
+ if (ms.m_mesh->MeshModified())
+ {
+ vbo->UpdateData();
+ }
+
+ vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi);
+ }
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
new file mode 100644
index 0000000..d8d8192
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h
@@ -0,0 +1,100 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_VERTEXBUFFEROBJECTSTORAGE
+#define __KX_VERTEXBUFFEROBJECTSTORAGE
+
+#include <map>
+#include "GL/glew.h"
+
+#include "RAS_IStorage.h"
+#include "RAS_IRasterizer.h"
+
+#include "RAS_OpenGLRasterizer.h"
+
+class VBO
+{
+public:
+ VBO(RAS_DisplayArray *data, unsigned int indices);
+ ~VBO();
+
+ void Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi);
+
+ void UpdateData();
+ void UpdateIndices();
+private:
+ RAS_DisplayArray* data;
+ GLuint size;
+ GLuint stride;
+ GLuint indices;
+ GLenum mode;
+ GLuint ibo;
+ GLuint vbo_id;
+
+ void* vertex_offset;
+ void* normal_offset;
+ void* color_offset;
+ void* tangent_offset;
+ void* uv_offset;
+};
+
+class RAS_StorageVBO : public RAS_IStorage
+{
+
+public:
+ RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib);
+ virtual ~RAS_StorageVBO();
+
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual void IndexPrimitives(RAS_MeshSlot& ms);
+ virtual void IndexPrimitivesMulti(RAS_MeshSlot& ms);
+
+ virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;};
+
+protected:
+ int m_drawingmode;
+
+ int* m_texco_num;
+ int* m_attrib_num;
+
+ RAS_IRasterizer::TexCoGen* m_texco;
+ RAS_IRasterizer::TexCoGen* m_attrib;
+
+ std::map<RAS_DisplayArray*, class VBO*> m_vbo_lookup;
+
+ virtual void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //__KX_VERTEXBUFFEROBJECTSTORAGE
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
deleted file mode 100644
index 076acb0..0000000
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
- * \ingroup bgerastogl
- */
-
-#include "RAS_VAOpenGLRasterizer.h"
-#include <stdlib.h>
-
-#include "GL/glew.h"
-#include "GPU_extensions.h"
-
-#include "STR_String.h"
-#include "RAS_TexVert.h"
-#include "MT_CmMatrix4x4.h"
-#include "RAS_IRenderTools.h" // rendering text
-
-RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock)
-: RAS_OpenGLRasterizer(canvas),
- /* m_Lock(lock && GLEW_EXT_compiled_vertex_array), */ /* UNUSED */
- m_last_texco_num(0),
- m_last_attrib_num(0)
-{
-}
-
-RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
-{
-}
-
-bool RAS_VAOpenGLRasterizer::Init(void)
-{
-
- bool result = RAS_OpenGLRasterizer::Init();
-
- if (result)
- {
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
-
- return result;
-}
-
-void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
-{
- m_drawingmode = drawingmode;
-
- switch (m_drawingmode)
- {
- case KX_BOUNDINGBOX:
- case KX_WIREFRAME:
- //glDisableClientState(GL_COLOR_ARRAY);
- //glDisable(GL_CULL_FACE);
- break;
- case KX_SOLID:
- //glDisableClientState(GL_COLOR_ARRAY);
- break;
- case KX_TEXTURED:
- case KX_SHADED:
- case KX_SHADOW:
- //glEnableClientState(GL_COLOR_ARRAY);
- default:
- break;
- }
-}
-
-void RAS_VAOpenGLRasterizer::Exit()
-{
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
- RAS_OpenGLRasterizer::Exit();
-}
-
-void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
-{
- static const GLsizei stride = sizeof(RAS_TexVert);
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
- RAS_MeshSlot::iterator it;
- GLenum drawmode;
-
- if (ms.m_pDerivedMesh) {
- // cannot be handled here, pass to RAS_OpenGLRasterizer
- RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false);
- return;
- }
-
- if (!wireframe)
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- // use glDrawElements to draw each vertexarray
- for (ms.begin(it); !ms.end(it); ms.next(it)) {
- if (it.totindex == 0)
- continue;
-
- // drawing mode
- if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
- drawmode = GL_TRIANGLES;
- else if (it.array->m_type == RAS_DisplayArray::QUAD)
- drawmode = GL_QUADS;
- else
- drawmode = GL_LINES;
-
- // colors
- if (drawmode != GL_LINES && !wireframe) {
- if (ms.m_bObjectColor) {
- const MT_Vector4& rgba = ms.m_RGBAcolor;
-
- glDisableClientState(GL_COLOR_ARRAY);
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- }
- else {
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- glEnableClientState(GL_COLOR_ARRAY);
- }
- }
- else
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
- glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
- glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
- if (!wireframe) {
- glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1());
- if (glIsEnabled(GL_COLOR_ARRAY))
- glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
- }
-
- // here the actual drawing takes places
- glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
- }
-
- if (!wireframe) {
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- }
-}
-
-void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
-{
- static const GLsizei stride = sizeof(RAS_TexVert);
- bool wireframe = m_drawingmode <= KX_WIREFRAME;
- RAS_MeshSlot::iterator it;
- GLenum drawmode;
-
- if (ms.m_pDerivedMesh) {
- // cannot be handled here, pass to RAS_OpenGLRasterizer
- RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true);
- return;
- }
-
- if (!wireframe)
- EnableTextures(true);
-
- // use glDrawElements to draw each vertexarray
- for (ms.begin(it); !ms.end(it); ms.next(it)) {
- if (it.totindex == 0)
- continue;
-
- // drawing mode
- if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
- drawmode = GL_TRIANGLES;
- else if (it.array->m_type == RAS_DisplayArray::QUAD)
- drawmode = GL_QUADS;
- else
- drawmode = GL_LINES;
-
- // colors
- if (drawmode != GL_LINES && !wireframe) {
- if (ms.m_bObjectColor) {
- const MT_Vector4& rgba = ms.m_RGBAcolor;
-
- glDisableClientState(GL_COLOR_ARRAY);
- glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
- }
- else {
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- glEnableClientState(GL_COLOR_ARRAY);
- }
- }
- else
- glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
- glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
- glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
- if (!wireframe) {
- TexCoordPtr(it.vertex);
- if (glIsEnabled(GL_COLOR_ARRAY))
- glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
- }
-
- // here the actual drawing takes places
- glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
- }
-
- if (!wireframe) {
- glDisableClientState(GL_COLOR_ARRAY);
- EnableTextures(false);
- }
-}
-
-void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
-{
- /* note: this function must closely match EnableTextures to enable/disable
- * the right arrays, otherwise coordinate and attribute pointers from other
- * materials can still be used and cause crashes */
- int unit;
-
- if (GLEW_ARB_multitexture)
- {
- for (unit=0; unit<m_texco_num; unit++)
- {
- glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
- if (tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) {
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2());
- continue;
- }
- switch (m_texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1());
- break;
- case RAS_TEXCO_NORM:
- glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
- break;
- case RAS_TEXTANGENT:
- glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
- break;
- case RAS_TEXCO_UV2:
- glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2());
- break;
- default:
- break;
- }
- }
-
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<m_attrib_num; unit++) {
- switch (m_attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
- break;
- case RAS_TEXCO_UV1:
- glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
- break;
- case RAS_TEXCO_NORM:
- glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
- break;
- case RAS_TEXTANGENT:
- glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
- break;
- case RAS_TEXCO_UV2:
- glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
- break;
- case RAS_TEXCO_VCOL:
- glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
- break;
- default:
- break;
- }
- }
- }
-}
-
-void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
-{
- TexCoGen *texco, *attrib;
- int unit, texco_num, attrib_num;
-
- /* we cache last texcoords and attribs to ensure we disable the ones that
- * were actually last set */
- if (enable) {
- texco = m_texco;
- texco_num = m_texco_num;
- attrib = m_attrib;
- attrib_num = m_attrib_num;
-
- memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num);
- m_last_texco_num = m_texco_num;
- memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num);
- m_last_attrib_num = m_attrib_num;
- }
- else {
- texco = m_last_texco;
- texco_num = m_last_texco_num;
- attrib = m_last_attrib;
- attrib_num = m_last_attrib_num;
- }
-
- if (GLEW_ARB_multitexture) {
- for (unit=0; unit<texco_num; unit++) {
- glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
-
- switch (texco[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- case RAS_TEXCO_UV1:
- case RAS_TEXCO_NORM:
- case RAS_TEXTANGENT:
- case RAS_TEXCO_UV2:
- if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- break;
- default:
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- break;
- }
- }
-
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- else {
- if (texco_num) {
- if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- }
-
- if (GLEW_ARB_vertex_program) {
- for (unit=0; unit<attrib_num; unit++) {
- switch (attrib[unit]) {
- case RAS_TEXCO_ORCO:
- case RAS_TEXCO_GLOB:
- case RAS_TEXCO_UV1:
- case RAS_TEXCO_NORM:
- case RAS_TEXTANGENT:
- case RAS_TEXCO_UV2:
- case RAS_TEXCO_VCOL:
- if (enable) glEnableVertexAttribArrayARB(unit);
- else glDisableVertexAttribArrayARB(unit);
- break;
- default:
- glDisableVertexAttribArrayARB(unit);
- break;
- }
- }
- }
-
- if (!enable) {
- m_last_texco_num = 0;
- m_last_attrib_num = 0;
- }
-}
-
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
deleted file mode 100644
index 6b159db..0000000
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file RAS_VAOpenGLRasterizer.h
- * \ingroup bgerastogl
- */
-
-#ifndef __RAS_VAOPENGLRASTERIZER_H__
-#define __RAS_VAOPENGLRASTERIZER_H__
-
-#include "RAS_OpenGLRasterizer.h"
-
-class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer
-{
- void TexCoordPtr(const RAS_TexVert *tv);
- /* bool m_Lock; */ /* UNUSED */
-
- TexCoGen m_last_texco[RAS_MAX_TEXCO];
- TexCoGen m_last_attrib[RAS_MAX_ATTRIB];
- int m_last_texco_num;
- int m_last_attrib_num;
-
-public:
- RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false);
- virtual ~RAS_VAOpenGLRasterizer();
-
- virtual bool Init();
- virtual void Exit();
-
- virtual void SetDrawingMode(int drawingmode);
-
- virtual void IndexPrimitives(class RAS_MeshSlot& ms);
- virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms);
-
-private:
- virtual void EnableTextures(bool enable);
- //virtual bool QueryArrays() {return true;}
- //virtual bool QueryLists() {return m_Lock;}
-
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_VAOpenGLRasterizer")
-#endif
-};
-
-#endif /* __RAS_VAOPENGLRASTERIZER_H__ */
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index 945644f..0a90054 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -34,8 +34,7 @@
#include "MT_Matrix4x4.h"
RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
@@ -43,8 +42,6 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
const unsigned int origindex)
{
xyz.getValue(m_localxyz);
- uv.getValue(m_uv1);
- uv2.getValue(m_uv2);
SetRGBA(rgba);
SetNormal(normal);
tangent.getValue(m_tangent);
@@ -52,6 +49,11 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
m_origindex = origindex;
m_unit = 2;
m_softBodyIndex = -1;
+
+ for (int i = 0; i < MAX_UNIT; ++i)
+ {
+ uvs[i].getValue(m_uvs[i]);
+ }
}
const MT_Point3& RAS_TexVert::xyz()
@@ -80,26 +82,15 @@ void RAS_TexVert::SetXYZ(const float xyz[3])
m_localxyz[0] = xyz[0]; m_localxyz[1] = xyz[1]; m_localxyz[2] = xyz[2];
}
-void RAS_TexVert::SetUV1(const MT_Point2& uv)
-{
- uv.getValue(m_uv1);
-}
-
-void RAS_TexVert::SetUV1(const float uv[3])
+void RAS_TexVert::SetUV(int index, const MT_Point2& uv)
{
- m_uv1[0] = uv[0];
- m_uv1[1] = uv[1];
+ uv.getValue(m_uvs[index]);
}
-void RAS_TexVert::SetUV2(const MT_Point2& uv)
+void RAS_TexVert::SetUV(int index, const float uv[2])
{
- uv.getValue(m_uv2);
-}
-
-void RAS_TexVert::SetUV2(const float uv[3])
-{
- m_uv2[0] = uv[0];
- m_uv2[1] = uv[1];
+ m_uvs[index][0] = uv[0];
+ m_uvs[index][1] = uv[1];
}
void RAS_TexVert::SetRGBA(const unsigned int rgba)
@@ -132,14 +123,17 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
+ bool uv_match = true;
+ for (int i=0; i<MAX_UNIT; i++)
+ uv_match = uv_match && MT_fuzzyEqual(MT_Vector2(m_uvs[i]), MT_Vector2(other->m_uvs[i]));
+
return (
/* m_flag == other->m_flag && */
/* at the moment the face only stores the smooth/flat setting so don't bother comparing it */
m_rgba == other->m_rgba &&
MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) &&
MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) &&
- MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) &&
- MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* &&
+ uv_match /* &&
MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/);
/* don't bother comparing m_localxyz since we know there from the same vert */
}
@@ -162,12 +156,7 @@ void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat)
SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue());
}
-void RAS_TexVert::TransformUV1(const MT_Matrix4x4& mat)
-{
- SetUV1((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue());
-}
-
-void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat)
+void RAS_TexVert::TransformUV(int index, const MT_Matrix4x4& mat)
{
- SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue());
+ SetUV(index, (mat * MT_Vector4(m_uvs[index][0], m_uvs[index][1], 0.0, 1.0)).getValue());
}
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
index 98ea4dd..a91d2c7 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.h
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -48,23 +48,21 @@ class RAS_TexVert
{
float m_localxyz[3]; // 3*4 = 12
- float m_uv1[2]; // 2*4 = 8
- float m_uv2[2]; // 2*4 = 8
+ float m_uvs[8][2]; // 8*2*4=64 //8 = MAX_UNIT
unsigned int m_rgba; // 4
- float m_tangent[4]; // 4*4 = 16
- float m_normal[3]; // 3*4 = 12
+ float m_tangent[4]; // 4*4 = 16
+ float m_normal[3]; // 3*4 = 12
short m_flag; // 2
short m_softBodyIndex; //2
unsigned int m_unit; // 4
unsigned int m_origindex; // 4
//---------
- // 56+6+8+2=72
- // 32 bytes total size, fits nice = 56 = not fit nice.
+ // 120
+ // 32 bytes total size, fits nice = 120 = not fit nice.
public:
enum {
FLAT = 1,
- SECOND_UV = 2,
MAX_UNIT = 8
};
@@ -74,8 +72,7 @@ public:
RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0)
{}
RAS_TexVert(const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
+ const MT_Point2 uvs[MAX_UNIT],
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
@@ -83,12 +80,8 @@ public:
const unsigned int origindex);
~RAS_TexVert() {};
- const float* getUV1 () const {
- return m_uv1;
- };
-
- const float* getUV2 () const {
- return m_uv2;
+ const float* getUV (int unit) const {
+ return m_uvs[unit];
};
const float* getXYZ() const {
@@ -123,10 +116,8 @@ public:
void SetXYZ(const MT_Point3& xyz);
void SetXYZ(const float xyz[3]);
- void SetUV1(const MT_Point2& uv);
- void SetUV2(const MT_Point2& uv);
- void SetUV1(const float uv[2]);
- void SetUV2(const float uv[2]);
+ void SetUV(int index, const MT_Point2& uv);
+ void SetUV(int index, const float uv[2]);
void SetRGBA(const unsigned int rgba);
void SetNormal(const MT_Vector3& normal);
@@ -139,8 +130,7 @@ public:
void Transform(const class MT_Matrix4x4& mat,
const class MT_Matrix4x4& nmat);
- void TransformUV1(const MT_Matrix4x4& mat);
- void TransformUV2(const MT_Matrix4x4& mat);
+ void TransformUV(int index, const MT_Matrix4x4& mat);
// compare two vertices, to test if they can be shared, used for
// splitting up based on uv's, colors, etc
diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
index d335a38..3203fcf 100644
--- a/source/gameengine/Rasterizer/RAS_texmatrix.cpp
+++ b/source/gameengine/Rasterizer/RAS_texmatrix.cpp
@@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve
MT_Scalar d = -p[0].xyz().dot(normal);
- MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1,
- p[1].getUV1()[0],p[1].getUV1()[1], 1,
- p[2].getUV1()[0],p[2].getUV1()[1], 1);
+ MT_Matrix3x3 mat3( p[0].getUV(0)[0],p[0].getUV(0)[1], 1,
+ p[1].getUV(0)[0],p[1].getUV(0)[1], 1,
+ p[2].getUV(0)[0],p[2].getUV(0)[1], 1);
MT_Matrix3x3 mat3inv = mat3.inverse();
diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript
index 4164271..438e953 100644
--- a/source/gameengine/Rasterizer/SConscript
+++ b/source/gameengine/Rasterizer/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
sources = env.Glob('*.cpp')
diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript
index aebbf4d..3db973d 100644
--- a/source/gameengine/SConscript
+++ b/source/gameengine/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
SConscript(['BlenderRoutines/SConscript',
diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript
index 9270169..c88a2d6 100644
--- a/source/gameengine/SceneGraph/SConscript
+++ b/source/gameengine/SceneGraph/SConscript
@@ -1,4 +1,29 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
Import ('env')
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
index e662849..ac8082e 100644
--- a/source/gameengine/VideoTexture/SConscript
+++ b/source/gameengine/VideoTexture/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
import sys
Import ('env')
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 8976a21..10eef9e 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -174,7 +174,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
if (avformat_open_input(&formatCtx, filename, inputFormat, formatParams)!=0)
return -1;
- if (av_find_stream_info(formatCtx)<0)
+ if (avformat_find_stream_info(formatCtx, NULL) < 0)
{
av_close_input_file(formatCtx);
return -1;
@@ -209,7 +209,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
return -1;
}
codecCtx->workaround_bugs = 1;
- if (avcodec_open(codecCtx, codec)<0)
+ if (avcodec_open2(codecCtx, codec, NULL) < 0)
{
av_close_input_file(formatCtx);
return -1;
diff --git a/source/icons/SConscript b/source/icons/SConscript
index 4bb27a7..443f645 100644
--- a/source/icons/SConscript
+++ b/source/icons/SConscript
@@ -1,4 +1,30 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+#
+# ***** 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.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Nathan Letwory.
+#
+# ***** END GPL LICENSE BLOCK *****
+
Import ('env')
import btools
diff --git a/source/tests/bl_load_addons.py b/source/tests/bl_load_addons.py
index 5d9ac75..fab2e2e 100644
--- a/source/tests/bl_load_addons.py
+++ b/source/tests/bl_load_addons.py
@@ -26,17 +26,46 @@ import addon_utils
import sys
import imp
+def disable_addons():
+ # first disable all
+ addons = bpy.context.user_preferences.addons
+ for mod_name in list(addons.keys()):
+ addon_utils.disable(mod_name)
+ assert(bool(addons) is False)
-def reload_addons(do_reload=True, do_reverse=True):
+
+def test_load_addons():
modules = addon_utils.modules({})
modules.sort(key=lambda mod: mod.__name__)
+
+ disable_addons()
+
addons = bpy.context.user_preferences.addons
- # first disable all
- for mod_name in list(addons.keys()):
- addon_utils.disable(mod_name)
+ addons_fail = []
- assert(bool(addons) is False)
+ for mod in modules:
+ mod_name = mod.__name__
+ print("\tenabling:", mod_name)
+ addon_utils.enable(mod_name)
+ if mod_name not in addons:
+ addons_fail.append(mod_name)
+
+ if addons_fail:
+ print("addons failed to load (%d):" % len(addons_fail))
+ for mod_name in addons_fail:
+ print(" %s" % mod_name)
+ else:
+ print("addons all loaded without errors!")
+ print("")
+
+
+def reload_addons(do_reload=True, do_reverse=True):
+ modules = addon_utils.modules({})
+ modules.sort(key=lambda mod: mod.__name__)
+ addons = bpy.context.user_preferences.addons
+
+ disable_addons()
# Run twice each time.
for i in (0, 1):
@@ -62,6 +91,9 @@ def reload_addons(do_reload=True, do_reverse=True):
def main():
+ # first load addons, print a list of all addons that fail
+ test_load_addons()
+
reload_addons(do_reload=False, do_reverse=False)
reload_addons(do_reload=False, do_reverse=True)
reload_addons(do_reload=True, do_reverse=True)
diff --git a/source/tests/check_deprecated.py b/source/tests/check_deprecated.py
index c5c7bdc..bb9fcd8 100644
--- a/source/tests/check_deprecated.py
+++ b/source/tests/check_deprecated.py
@@ -31,12 +31,12 @@ SKIP_DIRS = ("extern",
def is_c_header(filename):
ext = splitext(filename)[1]
- return (ext in (".h", ".hpp", ".hxx"))
+ return (ext in {".h", ".hpp", ".hxx", ".hh"})
def is_c(filename):
ext = splitext(filename)[1]
- return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"))
+ return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
def is_c_any(filename):
diff --git a/source/tools/check_style_c.py b/source/tools/check_style_c.py
index 3c8903b..21819dd 100755
--- a/source/tools/check_style_c.py
+++ b/source/tools/check_style_c.py
@@ -91,16 +91,18 @@ def tk_range_to_str(a, b):
def tk_item_is_newline(tok):
- return tok.type == Token.Text and tok.text == "\n"
+ return tok.type == Token.Text and tok.text.strip("\t ") == "\n"
def tk_item_is_ws_newline(tok):
- return (tok.type == Token.Text and tok.text.isspace()) or \
+ return (tok.text == "") or \
+ (tok.type == Token.Text and tok.text.isspace()) or \
(tok.type in Token.Comment)
def tk_item_is_ws(tok):
- return (tok.type == Token.Text and tok.text != "\n" and tok.text.isspace()) or \
+ return (tok.text == "") or \
+ (tok.type == Token.Text and tok.text.strip("\t ") != "\n" and tok.text.isspace()) or \
(tok.type in Token.Comment)
@@ -110,6 +112,11 @@ def tk_advance_ws(index, direction):
index += direction
return index
+def tk_advance_no_ws(index, direction):
+ index += direction
+ while tk_item_is_ws(tokens[index]) and index > 0:
+ index += direction
+ return index
def tk_advance_ws_newline(index, direction):
while tk_item_is_ws_newline(tokens[index + direction]) and index > 0:
@@ -187,6 +194,80 @@ def extract_operator(index_op):
return op_text, index_op + (i - 1)
+def extract_cast(index):
+ # to detect a cast is quite involved... sigh
+ # assert(tokens[index].text == "(")
+
+ # TODO, comment within cast, but thats rare
+ i_start = index
+ i_end = tk_match_backet(index)
+
+ # first check we are not '()'
+ if i_start + 1 == i_end:
+ return None
+
+ # check we have punctuation before the cast
+ i = i_start - 1
+ while tokens[i].text.isspace():
+ i -= 1
+ i_prev_no_ws = i
+ if tokens[i].type in {Token.Keyword, Token.Name}:
+ # avoids 'foo(bar)test'
+ # but not ' = (bar)test'
+ return None
+
+ # validate types
+ tokens_cast = [tokens[i] for i in range(i_start + 1, i_end)]
+ for t in tokens_cast:
+ if t.type == Token.Keyword:
+ return None
+ elif t.type == Token.Operator and t.text != "*":
+ # prevent '(a + b)'
+ # note, we could have '(float(*)[1+2])' but this is unlikely
+ return None
+ elif t.type == Token.Punctuation and t.text not in '()[]':
+ # prevent '(a, b)'
+ return None
+ tokens_cast_strip = []
+ for t in tokens_cast:
+ if t.type in Token.Comment:
+ pass
+ elif t.type == Token.Text and t.text.isspace():
+ pass
+ else:
+ tokens_cast_strip.append(t)
+ # check token order and types
+ if not tokens_cast_strip:
+ return None
+ if tokens_cast_strip[0].type not in {Token.Name, Token.Type, Token.Keyword.Type}:
+ return None
+ t_prev = None
+ for t in tokens_cast_strip[1:]:
+ # prevent identifiers after the first: '(a b)'
+ if t.type in {Token.Keyword.Type, Token.Name, Token.Text}:
+ return None
+ # prevent: '(a * 4)'
+ # allow: '(a (*)[4])'
+ if t_prev is not None and t_prev.text == "*" and t.type != Token.Punctuation:
+ return None
+ t_prev = t
+ del t_prev
+
+ # debug only
+ '''
+ string = "".join(tokens[i].text for i in range(i_start, i_end + 1))
+ #string = "".join(tokens[i].text for i in range(i_start + 1, i_end))
+ #types = [tokens[i].type for i in range(i_start + 1, i_end)]
+ types = [t.type for t in tokens_cast_strip]
+
+ print("STRING:", string)
+ print("TYPES: ", types)
+ print()
+ '''
+
+ return (i_start, i_end)
+
+
def warning(message, index_kw_start, index_kw_end):
if PRINT_QTC_TASKFORMAT:
print("%s\t%d\t%s\t%s" % (filepath, tokens[index_kw_start].line, "comment", message))
@@ -272,6 +353,35 @@ def blender_check_kw_else(index_kw):
if tokens[index_kw].line < tokens[i_next].line:
warning("else if is split by a new line 'else\\nif'", index_kw, i_next)
+ # check
+ # } else
+ # ... which is never OK
+ i_prev = tk_advance_no_ws(index_kw, -1)
+ if tokens[i_prev].type == Token.Punctuation and tokens[i_prev].text == "}":
+ if tokens[index_kw].line == tokens[i_prev].line:
+ warning("else has no newline before the brace '} else'", i_prev, index_kw)
+
+
+def blender_check_cast(index_kw_start, index_kw_end):
+ # detect: '( float...'
+ if tokens[index_kw_start + 1].text.isspace():
+ warning("cast has space after first bracket '( type...'", index_kw_start, index_kw_end)
+ # detect: '...float )'
+ if tokens[index_kw_end - 1].text.isspace():
+ warning("cast has space before last bracket '... )'", index_kw_start, index_kw_end)
+ # detect no space before operator: '(float*)'
+
+ for i in range(index_kw_start + 1, index_kw_end):
+ if tokens[i].text == "*":
+ # allow: '(*)'
+ if tokens[i - 1].type == Token.Punctuation:
+ pass
+ elif tokens[i - 1].text.isspace():
+ pass
+ else:
+ warning("cast has no preceeding whitespace '(type*)'", index_kw_start, index_kw_end)
+
+
def blender_check_comma(index_kw):
i_next = tk_advance_ws_newline(index_kw, 1)
@@ -284,6 +394,17 @@ def blender_check_comma(index_kw):
warning("comma space before it 'sometext ,", index_kw, i_next)
+def blender_check_period(index_kw):
+ # check we're now apart of ...
+ if (tokens[index_kw - 1].text == ".") or (tokens[index_kw + 1].text == "."):
+ return
+
+ # 'a.b'
+ if tokens[index_kw - 1].type == Token.Text and tokens[index_kw - 1].text.isspace():
+ warning("period space before it 'sometext .", index_kw, index_kw)
+ if tokens[index_kw + 1].type == Token.Text and tokens[index_kw + 1].text.isspace():
+ warning("period space after it '. sometext", index_kw, index_kw)
+
def _is_ws_pad(index_start, index_end):
return (tokens[index_start - 1].text.isspace() and
tokens[index_end + 1].text.isspace())
@@ -313,7 +434,12 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp):
elif op_text == "&":
pass # TODO, check if this is a pointer reference or not
elif op_text == "*":
- pass # TODO, check if this is a pointer reference or not
+ # This check could be improved, its a bit fuzzy
+ if ((tokens[index_start - 1].type in Token.Number) or
+ (tokens[index_start + 1].type in Token.Number)):
+ warning("no space around operator '%s'" % op_text, index_start, index_end)
+ elif not (tokens[index_start - 1].text.isspace() or tokens[index_start - 1].text in {"(", "[", "{"}):
+ warning("no space before operator '%s'" % op_text, index_start, index_end)
elif len(op_text) == 2:
# todo, remove operator check from `if`
if op_text in {"+=", "-=", "*=", "/=", "&=", "|=", "^=",
@@ -322,7 +448,7 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp):
"<<", ">>",
"%=",
# not operators, pointer mix-ins
- ">*", "<*", "-*", "+*", "=*", "/*", "%*", "^*", "!*", "|*",
+ ">*", "<*", "-*", "+*", "=*", "/*", "%*", "^*", "|*",
}:
if not _is_ws_pad(index_start, index_end):
if not (is_cpp and ("<" in op_text or ">" in op_text)):
@@ -335,7 +461,9 @@ def blender_check_operator(index_start, index_end, op_text, is_cpp):
tokens[index_end + 1].text.isspace()):
warning("spaces surrounding operator '%s'" % op_text, index_start, index_end)
'''
- elif op_text == "!!":
+ elif op_text in {"!!", "!*"}:
+ # operators we _dont_ want whitespace after (pointers mainly)
+ # we can assume these are pointers
if tokens[index_end + 1].text.isspace():
warning("spaces after operator '%s'" % op_text, index_start, index_end)
@@ -400,6 +528,74 @@ def blender_check_linelength(index_start, index_end, length):
warning("line length %d > %d" % (len(l), LIN_SIZE), index_start, index_end)
+def blender_check_function_definition(i):
+ # Warning, this is a fairly slow check and guesses
+ # based on some fuzzy rules
+
+ # assert(tokens[index] == "{")
+
+ # check function declaraction is not:
+ # 'void myfunc() {'
+ # ... other uses are handled by checks for statements
+ # this check is rather simplistic but tends to work well enough.
+
+ i_prev = i - 1
+ while tokens[i_prev].text == "":
+ i_prev -= 1
+
+ # ensure this isnt '{' in its own line
+ if tokens[i_prev].line == tokens[i].line:
+
+ # check we '}' isnt on same line...
+ i_next = i + 1
+ found = False
+ while tokens[i_next].line == tokens[i].line:
+ if tokens[i_next].text == "}":
+ found = True
+ break
+ i_next += 1
+ del i_next
+
+ if found is False:
+
+ # First check this isnt an assignment
+ i_prev = tk_advance_no_ws(i, -1)
+ # avoid '= {'
+ #if tokens(index_prev).text != "="
+ # print(tokens[i_prev].text)
+ # allow:
+ # - 'func()[] {'
+ # - 'func() {'
+
+ if tokens[i_prev].text in {")", "]"}:
+ i_prev = i - 1
+ while tokens[i_prev].line == tokens[i].line:
+ i_prev -= 1
+ split = tokens[i_prev].text.rsplit("\n", 1)
+ if len(split) > 1 and split[-1] != "":
+ split_line = split[-1]
+ else:
+ split_line = tokens[i_prev + 1].text
+
+ if split_line and split_line[0].isspace():
+ pass
+ else:
+ # no whitespace!
+ i_begin = i_prev + 1
+
+ # skip blank
+ if tokens[i_begin].text == "":
+ i_begin += 1
+ # skip static
+ if tokens[i_begin].text == "static":
+ i_begin += 1
+ while tokens[i_begin].text.isspace():
+ i_begin += 1
+ # now we are done skipping stuff
+
+ warning("function's '{' must be on a newline", i_begin, i)
+
+
def quick_check_indentation(code):
"""
Quick check for multiple tab indents.
@@ -460,6 +656,10 @@ def scan_source(fp, args):
is_cpp = fp.endswith((".cpp", ".cxx"))
filepath = fp
+
+ #if "displist.c" not in filepath:
+ # return
+
filepath_base = os.path.basename(filepath)
#print(highlight(code, CLexer(), RawTokenFormatter()).decode('utf-8'))
@@ -472,8 +672,9 @@ def scan_source(fp, args):
line = 1
for ttype, text in lex(code, CLexer()):
- tokens.append(TokStore(ttype, text, line))
- line += text.count("\n")
+ if text:
+ tokens.append(TokStore(ttype, text, line))
+ line += text.count("\n")
col = 0 # track line length
index_line_start = 0
@@ -490,6 +691,26 @@ def scan_source(fp, args):
elif tok.type == Token.Punctuation:
if tok.text == ",":
blender_check_comma(i)
+ elif tok.text == ".":
+ blender_check_period(i)
+ elif tok.text == "[":
+ # note, we're quite relaxed about this but
+ # disallow 'foo ['
+ if tokens[i - 1].text.isspace():
+ if is_cpp and tokens[i + 1].text == "]":
+ # c++ can do delete []
+ pass
+ else:
+ warning("space before '[' %s" % filepath_base, i, i)
+ elif tok.text == "(":
+ # check if this is a cast, eg:
+ # (char), (char **), (float (*)[3])
+ item_range = extract_cast(i)
+ if item_range is not None:
+ blender_check_cast(item_range[0], item_range[1])
+ elif tok.text == "{":
+ blender_check_function_definition(i);
+
elif tok.type == Token.Operator:
# we check these in pairs, only want first
if tokens[i - 1].type != Token.Operator:
--
blender packaging
More information about the pkg-multimedia-commits
mailing list